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,
}