mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(Airtop Node): Implement double-click and right click variants (#18306)
This commit is contained in:
@@ -25,6 +25,33 @@ export const description: INodeProperties[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Click Type',
|
||||||
|
name: 'clickType',
|
||||||
|
type: 'options',
|
||||||
|
default: 'click',
|
||||||
|
description: 'The type of click to perform. Defaults to left click.',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Left Click',
|
||||||
|
value: 'click',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Double Click',
|
||||||
|
value: 'doubleClick',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Right Click',
|
||||||
|
value: 'rightClick',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['interaction'],
|
||||||
|
operation: ['click'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -39,8 +66,13 @@ export async function execute(
|
|||||||
'Element Description',
|
'Element Description',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const clickType = validateRequiredStringField.call(this, index, 'clickType', 'Click Type');
|
||||||
|
|
||||||
const request = constructInteractionRequest.call(this, index, {
|
const request = constructInteractionRequest.call(this, index, {
|
||||||
elementDescription,
|
elementDescription,
|
||||||
|
configuration: {
|
||||||
|
clickType,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await apiRequest.call(
|
const response = await apiRequest.call(
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ export function constructInteractionRequest(
|
|||||||
): IAirtopInteractionRequest {
|
): IAirtopInteractionRequest {
|
||||||
const additionalFields = this.getNodeParameter('additionalFields', index);
|
const additionalFields = this.getNodeParameter('additionalFields', index);
|
||||||
const request: IAirtopInteractionRequest = {
|
const request: IAirtopInteractionRequest = {
|
||||||
configuration: {},
|
...parameters,
|
||||||
|
configuration: {
|
||||||
|
...(parameters.configuration ?? {}),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (additionalFields.visualScope) {
|
if (additionalFields.visualScope) {
|
||||||
@@ -25,7 +28,5 @@ export function constructInteractionRequest(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(request, parameters);
|
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ export const getN8NVersion = (): string => {
|
|||||||
export const N8N_VERSION = getN8NVersion();
|
export const N8N_VERSION = getN8NVersion();
|
||||||
|
|
||||||
export const BASE_URL = process.env.AIRTOP_BASE_URL ?? 'https://api.airtop.ai/api/v1';
|
export const BASE_URL = process.env.AIRTOP_BASE_URL ?? 'https://api.airtop.ai/api/v1';
|
||||||
export const INTEGRATION_URL =
|
|
||||||
process.env.AIRTOP_INTEGRATION_URL ?? 'https://portal-api.airtop.ai/integrations/v1/no-code';
|
|
||||||
|
|
||||||
// Session operations
|
// Session operations
|
||||||
export const DEFAULT_TIMEOUT_MINUTES = 10;
|
export const DEFAULT_TIMEOUT_MINUTES = 10;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const baseNodeParameters = {
|
|||||||
sessionId: 'test-session-123',
|
sessionId: 'test-session-123',
|
||||||
windowId: 'win-123',
|
windowId: 'win-123',
|
||||||
elementDescription: 'the login button',
|
elementDescription: 'the login button',
|
||||||
|
clickType: 'click',
|
||||||
additionalFields: {},
|
additionalFields: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,7 +56,9 @@ describe('Test Airtop, click operation', () => {
|
|||||||
'/sessions/test-session-123/windows/win-123/click',
|
'/sessions/test-session-123/windows/win-123/click',
|
||||||
{
|
{
|
||||||
elementDescription: 'the login button',
|
elementDescription: 'the login button',
|
||||||
configuration: {},
|
configuration: {
|
||||||
|
clickType: 'click',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -104,6 +107,7 @@ describe('Test Airtop, click operation', () => {
|
|||||||
visualAnalysis: {
|
visualAnalysis: {
|
||||||
scope: 'viewport',
|
scope: 'viewport',
|
||||||
},
|
},
|
||||||
|
clickType: 'click',
|
||||||
},
|
},
|
||||||
elementDescription: 'the login button',
|
elementDescription: 'the login button',
|
||||||
},
|
},
|
||||||
@@ -125,6 +129,7 @@ describe('Test Airtop, click operation', () => {
|
|||||||
'/sessions/test-session-123/windows/win-123/click',
|
'/sessions/test-session-123/windows/win-123/click',
|
||||||
{
|
{
|
||||||
configuration: {
|
configuration: {
|
||||||
|
clickType: 'click',
|
||||||
waitForNavigationConfig: {
|
waitForNavigationConfig: {
|
||||||
waitUntil: 'load',
|
waitUntil: 'load',
|
||||||
},
|
},
|
||||||
@@ -134,4 +139,44 @@ describe('Test Airtop, click operation', () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should execute double click when 'clickType' is 'doubleClick'", async () => {
|
||||||
|
const nodeParameters = {
|
||||||
|
...baseNodeParameters,
|
||||||
|
clickType: 'doubleClick',
|
||||||
|
};
|
||||||
|
|
||||||
|
await click.execute.call(createMockExecuteFunction(nodeParameters), 0);
|
||||||
|
|
||||||
|
expect(transport.apiRequest).toHaveBeenCalledWith(
|
||||||
|
'POST',
|
||||||
|
'/sessions/test-session-123/windows/win-123/click',
|
||||||
|
{
|
||||||
|
elementDescription: 'the login button',
|
||||||
|
configuration: {
|
||||||
|
clickType: 'doubleClick',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should execute right click when 'clickType' is 'rightClick'", async () => {
|
||||||
|
const nodeParameters = {
|
||||||
|
...baseNodeParameters,
|
||||||
|
clickType: 'rightClick',
|
||||||
|
};
|
||||||
|
|
||||||
|
await click.execute.call(createMockExecuteFunction(nodeParameters), 0);
|
||||||
|
|
||||||
|
expect(transport.apiRequest).toHaveBeenCalledWith(
|
||||||
|
'POST',
|
||||||
|
'/sessions/test-session-123/windows/win-123/click',
|
||||||
|
{
|
||||||
|
elementDescription: 'the login button',
|
||||||
|
configuration: {
|
||||||
|
clickType: 'rightClick',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,19 +15,19 @@ const defaultHeaders = {
|
|||||||
'x-airtop-sdk-version': N8N_VERSION,
|
'x-airtop-sdk-version': N8N_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function apiRequest(
|
export async function apiRequest<T extends IAirtopResponse = IAirtopResponse>(
|
||||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
method: IHttpRequestMethods,
|
method: IHttpRequestMethods,
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
body: IDataObject = {},
|
body: IDataObject = {},
|
||||||
query: IDataObject = {},
|
query: IDataObject = {},
|
||||||
) {
|
): Promise<T> {
|
||||||
const options: IHttpRequestOptions = {
|
const options: IHttpRequestOptions = {
|
||||||
headers: defaultHeaders,
|
headers: defaultHeaders,
|
||||||
method,
|
method,
|
||||||
body,
|
body,
|
||||||
qs: query,
|
qs: query,
|
||||||
url: endpoint.startsWith('http') ? endpoint : `${BASE_URL}${endpoint}`,
|
url: `${BASE_URL}${endpoint}`,
|
||||||
json: true,
|
json: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,9 +35,9 @@ export async function apiRequest(
|
|||||||
delete options.body;
|
delete options.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (await this.helpers.httpRequestWithAuthentication.call(
|
return await this.helpers.httpRequestWithAuthentication.call<
|
||||||
this,
|
IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
'airtopApi',
|
[string, IHttpRequestOptions],
|
||||||
options,
|
Promise<T>
|
||||||
)) as IAirtopResponse;
|
>(this, 'airtopApi', options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ export interface IAirtopInteractionRequest extends IDataObject {
|
|||||||
waitForNavigationConfig?: {
|
waitForNavigationConfig?: {
|
||||||
waitUntil: string;
|
waitUntil: string;
|
||||||
};
|
};
|
||||||
|
clickType?: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user