diff --git a/README.md b/README.md index 208b9b14..ce34f2a6 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ const chromeless = new Chromeless({ **Chrome methods** - [`goto(url: string)`](docs/api.md#api-goto) - [`setUserAgent(useragent: string)`](docs/api.md#api-setUserAgent) -- [`click(selector: string)`](docs/api.md#api-click) +- [`click(selector: string, x?: number, y?: number)`](docs/api.md#api-click) - [`wait(timeout: number)`](docs/api.md#api-wait-timeout) - [`wait(selector: string)`](docs/api.md#api-wait-selector) - [`wait(fn: (...args: any[]) => boolean, ...args: any[])`] - Not implemented yet diff --git a/docs/api.md b/docs/api.md index 35ca0af0..a5c3b716 100644 --- a/docs/api.md +++ b/docs/api.md @@ -21,7 +21,7 @@ Chromeless provides TypeScript typings. ### Chrome methods - [`goto(url: string)`](#api-goto) - [`setUserAgent(useragent: string)`](#api-setuseragent) -- [`click(selector: string)`](#api-click) +- [`click(selector: string, x?: number, y?: number)`](#api-click) - [`wait(timeout: number)`](#api-wait-timeout) - [`wait(selector: string, timeout?: number)`](#api-wait-selector) - [`wait(fn: (...args: any[]) => boolean, ...args: any[])`] - Not implemented yet @@ -107,17 +107,20 @@ await chromeless.setUserAgent('Custom Chromeless UserAgent x.x.x') -### click(selector: string): Chromeless +### click(selector: string, x?: number, y?: number): Chromeless Click on something in the DOM. __Arguments__ - `selector` - DOM selector for element to click +- `x` - Offset from the left of the element, default width/2 +- `y` - Offset from the top of the element, default height/2 __Example__ ```js await chromeless.click('#button') +await chromeless.click('#button', 20, 100) ``` --------------------------------------- @@ -173,7 +176,7 @@ __Arguments__ __Example__ ```js -await chromeless.wait(() => { +await chromeless.wait(() => { return new Promise((resolve, reject) => { // do something async, setTimeout... resolve(); diff --git a/src/api.ts b/src/api.ts index 840a977e..09964ac4 100644 --- a/src/api.ts +++ b/src/api.ts @@ -85,8 +85,8 @@ export default class Chromeless implements Promise { return this } - click(selector: string): Chromeless { - this.queue.enqueue({ type: 'click', selector }) + click(selector: string, x?: number, y?: number): Chromeless { + this.queue.enqueue({ type: 'click', selector, x, y }) return this } diff --git a/src/chrome/local-runtime.ts b/src/chrome/local-runtime.ts index af1f7392..6007ac70 100644 --- a/src/chrome/local-runtime.ts +++ b/src/chrome/local-runtime.ts @@ -74,7 +74,7 @@ export default class LocalRuntime { case 'setUserAgent': return this.setUserAgent(command.useragent) case 'click': - return this.click(command.selector) + return this.click(command.selector, command.x, command.y) case 'returnCode': return this.returnCode(command.fn, ...command.args) case 'returnExists': @@ -180,7 +180,7 @@ export default class LocalRuntime { this.log(`Waited for ${selector}`) } - private async click(selector: string): Promise { + private async click(selector: string, x?: number, y?: number): Promise { if (this.chromelessOptions.implicitWait) { this.log(`click(): Waiting for ${selector}`) await waitForNode( @@ -199,8 +199,8 @@ export default class LocalRuntime { if (this.chromelessOptions.scrollBeforeClick) { await scrollToElement(this.client, selector) } - await click(this.client, selector, scale) - this.log(`Clicked on ${selector}`) + await click(this.client, selector, scale, x, y) + this.log(`Clicked on ${selector} at (${x}, ${y})`) } private async returnCode(fn: string, ...args: any[]): Promise { diff --git a/src/types.ts b/src/types.ts index 5f5c7f97..efe485d4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -86,6 +86,8 @@ export type Command = | { type: 'click' selector: string + x?: number + y?: number } | { type: 'returnCode' diff --git a/src/util.ts b/src/util.ts index f46f9eb0..93eb9134 100644 --- a/src/util.ts +++ b/src/util.ts @@ -154,13 +154,20 @@ export async function getClientRect(client, selector): Promise { return JSON.parse(result.result.value) as ClientRect } -export async function click(client: Client, selector: string, scale: number) { +export async function click( + client: Client, + selector: string, + scale: number, + x?: number, + y?: number, +) { const clientRect = await getClientRect(client, selector) const { Input } = client - + if (x === undefined) x = clientRect.width / 2 + if (y === undefined) y = clientRect.height / 2 const options = { - x: Math.round((clientRect.left + clientRect.width / 2) * scale), - y: Math.round((clientRect.top + clientRect.height / 2) * scale), + x: Math.round((clientRect.left + x) * scale), + y: Math.round((clientRect.top + y) * scale), button: 'left', clickCount: 1, }