Skip to content

Commit bf92ffe

Browse files
authored
feat(locator): click mouse movement steps (#38036)
1 parent cdf2c22 commit bf92ffe

File tree

11 files changed

+124
-10
lines changed

11 files changed

+124
-10
lines changed

docs/src/api/class-elementhandle.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ When all steps combined have not finished during the specified [`option: timeout
234234
### option: ElementHandle.click.trial = %%-input-trial-%%
235235
* since: v1.11
236236

237+
### option: ElementHandle.click.steps = %%-input-mousemove-steps-%%
238+
* since: v1.57
239+
237240
## async method: ElementHandle.contentFrame
238241
* since: v1.8
239242
- returns: <[null]|[Frame]>
@@ -287,6 +290,9 @@ When all steps combined have not finished during the specified [`option: timeout
287290
### option: ElementHandle.dblclick.trial = %%-input-trial-%%
288291
* since: v1.11
289292

293+
### option: ElementHandle.dblclick.steps = %%-input-mousemove-steps-%%
294+
* since: v1.57
295+
290296
## async method: ElementHandle.dispatchEvent
291297
* since: v1.8
292298
* discouraged: Use locator-based [`method: Locator.dispatchEvent`] instead. Read more about [locators](../locators.md).

docs/src/api/class-locator.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,9 @@ await page.Locator("canvas").ClickAsync(new() {
497497
### option: Locator.click.trial = %%-input-trial-with-modifiers-%%
498498
* since: v1.14
499499

500+
### option: Locator.click.steps = %%-input-mousemove-steps-%%
501+
* since: v1.57
502+
500503
## async method: Locator.count
501504
* since: v1.14
502505
- returns: <[int]>
@@ -580,6 +583,9 @@ When all steps combined have not finished during the specified [`option: timeout
580583
### option: Locator.dblclick.trial = %%-input-trial-with-modifiers-%%
581584
* since: v1.14
582585

586+
### option: Locator.dblclick.steps = %%-input-mousemove-steps-%%
587+
* since: v1.57
588+
583589
## method: Locator.describe
584590
* since: v1.53
585591
- returns: <[Locator]>

docs/src/api/class-mouse.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,8 @@ X coordinate relative to the main frame's viewport in CSS pixels.
143143

144144
Y coordinate relative to the main frame's viewport in CSS pixels.
145145

146-
### option: Mouse.move.steps
146+
### option: Mouse.move.steps = %%-input-mousemove-steps-%%
147147
* since: v1.8
148-
- `steps` <[int]>
149-
150-
Defaults to 1. Sends intermediate `mousemove` events.
151148

152149
## async method: Mouse.up
153150
* since: v1.8

docs/src/api/params.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ A selector to search for an element to drop onto. If there are multiple elements
103103
A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
104104
element.
105105

106+
## input-mousemove-steps
107+
- `steps` <[int]>
108+
109+
Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
110+
106111
## input-modifiers
107112
- `modifiers` <[Array]<[KeyboardModifier]<"Alt"|"Control"|"ControlOrMeta"|"Meta"|"Shift">>>
108113

packages/playwright-client/types/types.d.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11211,6 +11211,12 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
1121111211
y: number;
1121211212
};
1121311213

11214+
/**
11215+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
11216+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
11217+
*/
11218+
steps?: number;
11219+
1121411220
/**
1121511221
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1121611222
* option in the config, or by using the
@@ -11294,6 +11300,12 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
1129411300
y: number;
1129511301
};
1129611302

11303+
/**
11304+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
11305+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
11306+
*/
11307+
steps?: number;
11308+
1129711309
/**
1129811310
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1129911311
* option in the config, or by using the
@@ -12788,6 +12800,12 @@ export interface Locator {
1278812800
y: number;
1278912801
};
1279012802

12803+
/**
12804+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
12805+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
12806+
*/
12807+
steps?: number;
12808+
1279112809
/**
1279212810
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1279312811
* option in the config, or by using the
@@ -12905,6 +12923,12 @@ export interface Locator {
1290512923
y: number;
1290612924
};
1290712925

12926+
/**
12927+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
12928+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
12929+
*/
12930+
steps?: number;
12931+
1290812932
/**
1290912933
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1291012934
* option in the config, or by using the
@@ -20293,7 +20317,8 @@ export interface Mouse {
2029320317
*/
2029420318
move(x: number, y: number, options?: {
2029520319
/**
20296-
* Defaults to 1. Sends intermediate `mousemove` events.
20320+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
20321+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
2029720322
*/
2029820323
steps?: number;
2029920324
}): Promise<void>;

packages/playwright-core/src/protocol/validator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,7 @@ scheme.FrameClickParams = tObject({
16021602
clickCount: tOptional(tInt),
16031603
timeout: tFloat,
16041604
trial: tOptional(tBoolean),
1605+
steps: tOptional(tInt),
16051606
});
16061607
scheme.FrameClickResult = tOptional(tObject({}));
16071608
scheme.FrameContentParams = tOptional(tObject({}));
@@ -1629,6 +1630,7 @@ scheme.FrameDblclickParams = tObject({
16291630
button: tOptional(tEnum(['left', 'right', 'middle'])),
16301631
timeout: tFloat,
16311632
trial: tOptional(tBoolean),
1633+
steps: tOptional(tInt),
16321634
});
16331635
scheme.FrameDblclickResult = tOptional(tObject({}));
16341636
scheme.FrameDispatchEventParams = tObject({
@@ -2044,6 +2046,7 @@ scheme.ElementHandleClickParams = tObject({
20442046
clickCount: tOptional(tInt),
20452047
timeout: tFloat,
20462048
trial: tOptional(tBoolean),
2049+
steps: tOptional(tInt),
20472050
});
20482051
scheme.ElementHandleClickResult = tOptional(tObject({}));
20492052
scheme.ElementHandleContentFrameParams = tOptional(tObject({}));
@@ -2058,6 +2061,7 @@ scheme.ElementHandleDblclickParams = tObject({
20582061
button: tOptional(tEnum(['left', 'right', 'middle'])),
20592062
timeout: tFloat,
20602063
trial: tOptional(tBoolean),
2064+
steps: tOptional(tInt),
20612065
});
20622066
scheme.ElementHandleDblclickResult = tOptional(tObject({}));
20632067
scheme.ElementHandleDispatchEventParams = tObject({

packages/playwright-core/src/server/input.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,10 @@ export class Mouse {
215215
await this._raw.up(progress, this._x, this._y, button, this._buttons, this._keyboard._modifiers(), clickCount);
216216
}
217217

218-
async click(progress: Progress, x: number, y: number, options: { delay?: number, button?: types.MouseButton, clickCount?: number } = {}) {
219-
const { delay = null, clickCount = 1 } = options;
218+
async click(progress: Progress, x: number, y: number, options: { delay?: number, button?: types.MouseButton, clickCount?: number, steps?: number } = {}) {
219+
const { delay = null, clickCount = 1, steps } = options;
220220
if (delay) {
221-
this.move(progress, x, y, { forClick: true });
221+
await this.move(progress, x, y, { forClick: true, steps });
222222
for (let cc = 1; cc <= clickCount; ++cc) {
223223
await this.down(progress, { ...options, clickCount: cc });
224224
await progress.wait(delay);
@@ -228,7 +228,11 @@ export class Mouse {
228228
}
229229
} else {
230230
const promises = [];
231-
promises.push(this.move(progress, x, y, { forClick: true }));
231+
const movePromise = this.move(progress, x, y, { forClick: true, steps });
232+
if (steps !== undefined && steps > 1)
233+
await movePromise;
234+
else
235+
promises.push(movePromise);
232236
for (let cc = 1; cc <= clickCount; ++cc) {
233237
promises.push(this.down(progress, { ...options, clickCount: cc }));
234238
promises.push(this.up(progress, { ...options, clickCount: cc }));

packages/playwright-core/types/types.d.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11211,6 +11211,12 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
1121111211
y: number;
1121211212
};
1121311213

11214+
/**
11215+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
11216+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
11217+
*/
11218+
steps?: number;
11219+
1121411220
/**
1121511221
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1121611222
* option in the config, or by using the
@@ -11294,6 +11300,12 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
1129411300
y: number;
1129511301
};
1129611302

11303+
/**
11304+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
11305+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
11306+
*/
11307+
steps?: number;
11308+
1129711309
/**
1129811310
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1129911311
* option in the config, or by using the
@@ -12788,6 +12800,12 @@ export interface Locator {
1278812800
y: number;
1278912801
};
1279012802

12803+
/**
12804+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
12805+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
12806+
*/
12807+
steps?: number;
12808+
1279112809
/**
1279212810
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1279312811
* option in the config, or by using the
@@ -12905,6 +12923,12 @@ export interface Locator {
1290512923
y: number;
1290612924
};
1290712925

12926+
/**
12927+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
12928+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
12929+
*/
12930+
steps?: number;
12931+
1290812932
/**
1290912933
* Maximum time in milliseconds. Defaults to `0` - no timeout. The default value can be changed via `actionTimeout`
1291012934
* option in the config, or by using the
@@ -20293,7 +20317,8 @@ export interface Mouse {
2029320317
*/
2029420318
move(x: number, y: number, options?: {
2029520319
/**
20296-
* Defaults to 1. Sends intermediate `mousemove` events.
20320+
* Defaults to 1. Sends `n` interpolated `mousemove` events to represent travel between Playwright's current cursor
20321+
* position and the provided destination. When set to 1, emits a single `mousemove` event at the destination location.
2029720322
*/
2029820323
steps?: number;
2029920324
}): Promise<void>;

packages/protocol/src/channels.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,6 +2803,7 @@ export type FrameClickParams = {
28032803
clickCount?: number,
28042804
timeout: number,
28052805
trial?: boolean,
2806+
steps?: number,
28062807
};
28072808
export type FrameClickOptions = {
28082809
strict?: boolean,
@@ -2814,6 +2815,7 @@ export type FrameClickOptions = {
28142815
button?: 'left' | 'right' | 'middle',
28152816
clickCount?: number,
28162817
trial?: boolean,
2818+
steps?: number,
28172819
};
28182820
export type FrameClickResult = void;
28192821
export type FrameContentParams = {};
@@ -2849,6 +2851,7 @@ export type FrameDblclickParams = {
28492851
button?: 'left' | 'right' | 'middle',
28502852
timeout: number,
28512853
trial?: boolean,
2854+
steps?: number,
28522855
};
28532856
export type FrameDblclickOptions = {
28542857
strict?: boolean,
@@ -2858,6 +2861,7 @@ export type FrameDblclickOptions = {
28582861
delay?: number,
28592862
button?: 'left' | 'right' | 'middle',
28602863
trial?: boolean,
2864+
steps?: number,
28612865
};
28622866
export type FrameDblclickResult = void;
28632867
export type FrameDispatchEventParams = {
@@ -3514,6 +3518,7 @@ export type ElementHandleClickParams = {
35143518
clickCount?: number,
35153519
timeout: number,
35163520
trial?: boolean,
3521+
steps?: number,
35173522
};
35183523
export type ElementHandleClickOptions = {
35193524
force?: boolean,
@@ -3524,6 +3529,7 @@ export type ElementHandleClickOptions = {
35243529
button?: 'left' | 'right' | 'middle',
35253530
clickCount?: number,
35263531
trial?: boolean,
3532+
steps?: number,
35273533
};
35283534
export type ElementHandleClickResult = void;
35293535
export type ElementHandleContentFrameParams = {};
@@ -3539,6 +3545,7 @@ export type ElementHandleDblclickParams = {
35393545
button?: 'left' | 'right' | 'middle',
35403546
timeout: number,
35413547
trial?: boolean,
3548+
steps?: number,
35423549
};
35433550
export type ElementHandleDblclickOptions = {
35443551
force?: boolean,
@@ -3547,6 +3554,7 @@ export type ElementHandleDblclickOptions = {
35473554
delay?: number,
35483555
button?: 'left' | 'right' | 'middle',
35493556
trial?: boolean,
3557+
steps?: number,
35503558
};
35513559
export type ElementHandleDblclickResult = void;
35523560
export type ElementHandleDispatchEventParams = {

packages/protocol/src/protocol.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,6 +2256,7 @@ Frame:
22562256
clickCount: int?
22572257
timeout: float
22582258
trial: boolean?
2259+
steps: int?
22592260
flags:
22602261
slowMo: true
22612262
snapshot: true
@@ -2311,6 +2312,7 @@ Frame:
23112312
- middle
23122313
timeout: float
23132314
trial: boolean?
2315+
steps: int?
23142316
flags:
23152317
slowMo: true
23162318
snapshot: true
@@ -3012,6 +3014,7 @@ ElementHandle:
30123014
clickCount: int?
30133015
timeout: float
30143016
trial: boolean?
3017+
steps: int?
30153018
flags:
30163019
slowMo: true
30173020
snapshot: true
@@ -3047,6 +3050,7 @@ ElementHandle:
30473050
- middle
30483051
timeout: float
30493052
trial: boolean?
3053+
steps: int?
30503054
flags:
30513055
slowMo: true
30523056
snapshot: true

0 commit comments

Comments
 (0)