feat(drag): sourcePosition and targetPosition (#7803)
This commit is contained in:
parent
a2cbba9c1c
commit
4fabe5e6e4
|
|
@ -371,6 +371,10 @@ Optional event-specific initialization properties.
|
||||||
### option: Frame.dragAndDrop.timeout = %%-input-timeout-%%
|
### option: Frame.dragAndDrop.timeout = %%-input-timeout-%%
|
||||||
### option: Frame.dragAndDrop.trial = %%-input-trial-%%
|
### option: Frame.dragAndDrop.trial = %%-input-trial-%%
|
||||||
|
|
||||||
|
### option: Frame.dragAndDrop.sourcePosition = %%-input-source-position-%%
|
||||||
|
|
||||||
|
### option: Frame.dragAndDrop.targetPosition = %%-input-target-position-%%
|
||||||
|
|
||||||
## async method: Frame.evalOnSelector
|
## async method: Frame.evalOnSelector
|
||||||
* langs:
|
* langs:
|
||||||
- alias-python: eval_on_selector
|
- alias-python: eval_on_selector
|
||||||
|
|
|
||||||
|
|
@ -807,6 +807,10 @@ Optional event-specific initialization properties.
|
||||||
### option: Page.dragAndDrop.timeout = %%-input-timeout-%%
|
### option: Page.dragAndDrop.timeout = %%-input-timeout-%%
|
||||||
### option: Page.dragAndDrop.trial = %%-input-trial-%%
|
### option: Page.dragAndDrop.trial = %%-input-trial-%%
|
||||||
|
|
||||||
|
### option: Page.dragAndDrop.sourcePosition = %%-input-source-position-%%
|
||||||
|
|
||||||
|
### option: Page.dragAndDrop.targetPosition = %%-input-target-position-%%
|
||||||
|
|
||||||
## async method: Page.emulateMedia
|
## async method: Page.emulateMedia
|
||||||
|
|
||||||
This method changes the `CSS media type` through the `media` argument, and/or the `'prefers-colors-scheme'` media feature, using the `colorScheme` argument.
|
This method changes the `CSS media type` through the `media` argument, and/or the `'prefers-colors-scheme'` media feature, using the `colorScheme` argument.
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,20 @@ defaults to 1. See [UIEvent.detail].
|
||||||
|
|
||||||
When set, this method only performs the [actionability](./actionability.md) checks and skips the action. Defaults to `false`. Useful to wait until the element is ready for the action without performing it.
|
When set, this method only performs the [actionability](./actionability.md) checks and skips the action. Defaults to `false`. Useful to wait until the element is ready for the action without performing it.
|
||||||
|
|
||||||
|
## input-source-position
|
||||||
|
- `sourcePosition` <[Object]>
|
||||||
|
- `x` <[float]>
|
||||||
|
- `y` <[float]>
|
||||||
|
|
||||||
|
Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not specified, some visible point of the element is used.
|
||||||
|
|
||||||
|
## input-target-position
|
||||||
|
- `targetPosition` <[Object]>
|
||||||
|
- `x` <[float]>
|
||||||
|
- `y` <[float]>
|
||||||
|
|
||||||
|
Drops on the target element at this point relative to the top-left corner of the element's padding box. If not specified, some visible point of the element is used.
|
||||||
|
|
||||||
## query-selector
|
## query-selector
|
||||||
- `selector` <[string]>
|
- `selector` <[string]>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1462,12 +1462,16 @@ export type FrameDragAndDropParams = {
|
||||||
noWaitAfter?: boolean,
|
noWaitAfter?: boolean,
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
trial?: boolean,
|
trial?: boolean,
|
||||||
|
sourcePosition?: Point,
|
||||||
|
targetPosition?: Point,
|
||||||
};
|
};
|
||||||
export type FrameDragAndDropOptions = {
|
export type FrameDragAndDropOptions = {
|
||||||
force?: boolean,
|
force?: boolean,
|
||||||
noWaitAfter?: boolean,
|
noWaitAfter?: boolean,
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
trial?: boolean,
|
trial?: boolean,
|
||||||
|
sourcePosition?: Point,
|
||||||
|
targetPosition?: Point,
|
||||||
};
|
};
|
||||||
export type FrameDragAndDropResult = void;
|
export type FrameDragAndDropResult = void;
|
||||||
export type FrameDblclickParams = {
|
export type FrameDblclickParams = {
|
||||||
|
|
|
||||||
|
|
@ -1188,6 +1188,8 @@ Frame:
|
||||||
noWaitAfter: boolean?
|
noWaitAfter: boolean?
|
||||||
timeout: number?
|
timeout: number?
|
||||||
trial: boolean?
|
trial: boolean?
|
||||||
|
sourcePosition: Point?
|
||||||
|
targetPosition: Point?
|
||||||
|
|
||||||
dblclick:
|
dblclick:
|
||||||
parameters:
|
parameters:
|
||||||
|
|
|
||||||
|
|
@ -597,6 +597,8 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||||
noWaitAfter: tOptional(tBoolean),
|
noWaitAfter: tOptional(tBoolean),
|
||||||
timeout: tOptional(tNumber),
|
timeout: tOptional(tNumber),
|
||||||
trial: tOptional(tBoolean),
|
trial: tOptional(tBoolean),
|
||||||
|
sourcePosition: tOptional(tType('Point')),
|
||||||
|
targetPosition: tOptional(tType('Point')),
|
||||||
});
|
});
|
||||||
scheme.FrameDblclickParams = tObject({
|
scheme.FrameDblclickParams = tObject({
|
||||||
selector: tString,
|
selector: tString,
|
||||||
|
|
|
||||||
|
|
@ -983,7 +983,7 @@ export class Frame extends SdkObject {
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.DragActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
await controller.run(async progress => {
|
await controller.run(async progress => {
|
||||||
await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, !!options.strict, async handle => {
|
await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, !!options.strict, async handle => {
|
||||||
|
|
@ -992,6 +992,7 @@ export class Frame extends SdkObject {
|
||||||
await this._page.mouse.down();
|
await this._page.mouse.down();
|
||||||
}, {
|
}, {
|
||||||
...options,
|
...options,
|
||||||
|
position: options.sourcePosition,
|
||||||
timeout: progress.timeUntilDeadline(),
|
timeout: progress.timeUntilDeadline(),
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
@ -1001,6 +1002,7 @@ export class Frame extends SdkObject {
|
||||||
await this._page.mouse.up();
|
await this._page.mouse.up();
|
||||||
}, {
|
}, {
|
||||||
...options,
|
...options,
|
||||||
|
position: options.targetPosition,
|
||||||
timeout: progress.timeUntilDeadline(),
|
timeout: progress.timeUntilDeadline(),
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,12 @@ export type PointerActionOptions = {
|
||||||
position?: Point;
|
position?: Point;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DragActionOptions = {
|
||||||
|
sourcePosition?: Point;
|
||||||
|
targetPosition?: Point;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MouseClickOptions = PointerActionOptions & {
|
export type MouseClickOptions = PointerActionOptions & {
|
||||||
delay?: number;
|
delay?: number;
|
||||||
button?: MouseButton;
|
button?: MouseButton;
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,41 @@ it.describe('Drag and drop', () => {
|
||||||
expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target
|
expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow specifying the position', async ({page, server}) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<div style="width:100px;height:100px;background:red;" id="red">
|
||||||
|
</div>
|
||||||
|
<div style="width:100px;height:100px;background:blue;" id="blue">
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
const eventsHandle = await page.evaluateHandle(() => {
|
||||||
|
const events = [];
|
||||||
|
document.getElementById('red').addEventListener('mousedown', event => {
|
||||||
|
events.push({
|
||||||
|
type: 'mousedown',
|
||||||
|
x: event.offsetX,
|
||||||
|
y: event.offsetY,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.getElementById('blue').addEventListener('mouseup', event => {
|
||||||
|
events.push({
|
||||||
|
type: 'mouseup',
|
||||||
|
x: event.offsetX,
|
||||||
|
y: event.offsetY,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return events;
|
||||||
|
});
|
||||||
|
await page.dragAndDrop('#red', '#blue', {
|
||||||
|
sourcePosition: {x: 34, y: 7},
|
||||||
|
targetPosition: {x: 10, y: 20},
|
||||||
|
});
|
||||||
|
expect(await eventsHandle.jsonValue()).toEqual([
|
||||||
|
{type: 'mousedown', x: 34, y: 7},
|
||||||
|
{type: 'mouseup', x: 10, y: 20},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
async function trackEvents(target: ElementHandle) {
|
async function trackEvents(target: ElementHandle) {
|
||||||
const eventsHandle = await target.evaluateHandle(target => {
|
const eventsHandle = await target.evaluateHandle(target => {
|
||||||
const events: string[] = [];
|
const events: string[] = [];
|
||||||
|
|
|
||||||
40
types/types.d.ts
vendored
40
types/types.d.ts
vendored
|
|
@ -1441,12 +1441,32 @@ export interface Page {
|
||||||
*/
|
*/
|
||||||
noWaitAfter?: boolean;
|
noWaitAfter?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
|
||||||
|
* specified, some visible point of the element is used.
|
||||||
|
*/
|
||||||
|
sourcePosition?: {
|
||||||
|
x: number;
|
||||||
|
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||||
* element, the call throws an exception.
|
* element, the call throws an exception.
|
||||||
*/
|
*/
|
||||||
strict?: boolean;
|
strict?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drops on the target element at this point relative to the top-left corner of the element's padding box. If not
|
||||||
|
* specified, some visible point of the element is used.
|
||||||
|
*/
|
||||||
|
targetPosition?: {
|
||||||
|
x: number;
|
||||||
|
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
|
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
|
||||||
* using the
|
* using the
|
||||||
|
|
@ -3865,12 +3885,32 @@ export interface Frame {
|
||||||
*/
|
*/
|
||||||
noWaitAfter?: boolean;
|
noWaitAfter?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
|
||||||
|
* specified, some visible point of the element is used.
|
||||||
|
*/
|
||||||
|
sourcePosition?: {
|
||||||
|
x: number;
|
||||||
|
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||||
* element, the call throws an exception.
|
* element, the call throws an exception.
|
||||||
*/
|
*/
|
||||||
strict?: boolean;
|
strict?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drops on the target element at this point relative to the top-left corner of the element's padding box. If not
|
||||||
|
* specified, some visible point of the element is used.
|
||||||
|
*/
|
||||||
|
targetPosition?: {
|
||||||
|
x: number;
|
||||||
|
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
|
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
|
||||||
* using the
|
* using the
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue