first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
import type {
|
||||
IDataObject,
|
||||
IExecuteFunctions,
|
||||
INodeExecutionData,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { constructInteractionRequest } from './helpers';
|
||||
import {
|
||||
validateRequiredStringField,
|
||||
validateSessionAndWindowId,
|
||||
validateAirtopApiResponse,
|
||||
validateScrollByAmount,
|
||||
validateScrollingMode,
|
||||
} from '../../GenericFunctions';
|
||||
import { apiRequest } from '../../transport';
|
||||
|
||||
export const description: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Scroll Mode',
|
||||
name: 'scrollingMode',
|
||||
type: 'options',
|
||||
description: 'Choose the mode of scrolling',
|
||||
options: [
|
||||
{
|
||||
name: 'Automatic',
|
||||
value: 'automatic',
|
||||
description: 'Describe with natural language the element to scroll to',
|
||||
},
|
||||
{
|
||||
name: 'Manual',
|
||||
value: 'manual',
|
||||
description: 'Define the direction and amount to scroll by',
|
||||
},
|
||||
],
|
||||
default: 'automatic',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['interaction'],
|
||||
operation: ['scroll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Element Description',
|
||||
default: '',
|
||||
description: 'A natural language description of the element to scroll to',
|
||||
name: 'scrollToElement',
|
||||
type: 'string',
|
||||
placeholder: 'e.g. the page section titled "Contact Us"',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['interaction'],
|
||||
operation: ['scroll'],
|
||||
scrollingMode: ['automatic'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Scroll To Edge',
|
||||
name: 'scrollToEdge',
|
||||
type: 'fixedCollection',
|
||||
default: {},
|
||||
placeholder: 'Add Edge Direction',
|
||||
description:
|
||||
"The direction to scroll to. When 'Scroll By' is defined, 'Scroll To Edge' action will be executed first, then 'Scroll By' action.",
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['interaction'],
|
||||
operation: ['scroll'],
|
||||
scrollingMode: ['manual'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Page Edges',
|
||||
name: 'edgeValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Vertically',
|
||||
name: 'yAxis',
|
||||
type: 'options',
|
||||
default: '',
|
||||
options: [
|
||||
{
|
||||
name: 'Empty',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
name: 'Top',
|
||||
value: 'top',
|
||||
},
|
||||
{
|
||||
name: 'Bottom',
|
||||
value: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Horizontally',
|
||||
name: 'xAxis',
|
||||
type: 'options',
|
||||
default: '',
|
||||
options: [
|
||||
{
|
||||
name: 'Empty',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
name: 'Left',
|
||||
value: 'left',
|
||||
},
|
||||
{
|
||||
name: 'Right',
|
||||
value: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Scroll By',
|
||||
name: 'scrollBy',
|
||||
type: 'fixedCollection',
|
||||
default: {},
|
||||
description:
|
||||
"The amount to scroll by. When 'Scroll To Edge' is defined, 'Scroll By' action will be executed after 'Scroll To Edge'.",
|
||||
placeholder: 'Add Scroll Amount',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['interaction'],
|
||||
operation: ['scroll'],
|
||||
scrollingMode: ['manual'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'scrollValues',
|
||||
displayName: 'Scroll Values',
|
||||
description: 'The amount in pixels or percentage to scroll by',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Vertically',
|
||||
name: 'yAxis',
|
||||
type: 'string',
|
||||
default: '',
|
||||
placeholder: 'e.g. 200px, 50%, -100px',
|
||||
},
|
||||
{
|
||||
displayName: 'Horizontally',
|
||||
name: 'xAxis',
|
||||
type: 'string',
|
||||
default: '',
|
||||
placeholder: 'e.g. 50px, 10%, -200px',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Scrollable Area',
|
||||
name: 'scrollWithin',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Scroll within an element on the page',
|
||||
placeholder: 'e.g. the left sidebar',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['interaction'],
|
||||
operation: ['scroll'],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const { sessionId, windowId } = validateSessionAndWindowId.call(this, index);
|
||||
|
||||
const scrollingMode = validateScrollingMode.call(this, index);
|
||||
const isAutomatic = scrollingMode === 'automatic';
|
||||
|
||||
const scrollToElement = isAutomatic
|
||||
? validateRequiredStringField.call(this, index, 'scrollToElement', 'Element Description')
|
||||
: '';
|
||||
|
||||
const scrollToEdge = this.getNodeParameter('scrollToEdge.edgeValues', index, {}) as {
|
||||
xAxis?: string;
|
||||
yAxis?: string;
|
||||
};
|
||||
|
||||
const scrollBy = validateScrollByAmount.call(this, index, 'scrollBy.scrollValues');
|
||||
|
||||
const scrollWithin = this.getNodeParameter('scrollWithin', index, '') as string;
|
||||
|
||||
const request: IDataObject = {
|
||||
// when scrollingMode is 'Manual'
|
||||
...(!isAutomatic ? { scrollToEdge } : {}),
|
||||
...(!isAutomatic ? { scrollBy } : {}),
|
||||
// when scrollingMode is 'Automatic'
|
||||
...(isAutomatic ? { scrollToElement } : {}),
|
||||
// when scrollWithin is defined
|
||||
...(scrollWithin ? { scrollWithin } : {}),
|
||||
};
|
||||
|
||||
const fullRequest = constructInteractionRequest.call(this, index, request);
|
||||
|
||||
const response = await apiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
`/sessions/${sessionId}/windows/${windowId}/scroll`,
|
||||
fullRequest,
|
||||
);
|
||||
|
||||
validateAirtopApiResponse(this.getNode(), response);
|
||||
|
||||
return this.helpers.returnJsonArray({ sessionId, windowId, ...response });
|
||||
}
|
||||
Reference in New Issue
Block a user