mirror of
https://github.com/microsoft/playwright.git
synced 2024-11-28 01:15:10 +03:00
fix: noWaitAfter option for hover (#17856)
Fixes https://github.com/microsoft/playwright/issues/17833
This commit is contained in:
parent
1b5c2f9aba
commit
639b28db3b
@ -555,6 +555,9 @@ When all steps combined have not finished during the specified [`option: timeout
|
||||
### option: ElementHandle.hover.trial = %%-input-trial-%%
|
||||
* since: v1.11
|
||||
|
||||
### option: ElementHandle.hover.noWaitAfter = %%-input-no-wait-after-%%
|
||||
* since: v1.28
|
||||
|
||||
## async method: ElementHandle.innerHTML
|
||||
* since: v1.8
|
||||
- returns: <[string]>
|
||||
|
@ -1059,6 +1059,8 @@ When all steps combined have not finished during the specified [`option: timeout
|
||||
* since: v1.8
|
||||
### option: Frame.hover.trial = %%-input-trial-%%
|
||||
* since: v1.11
|
||||
### option: Frame.hover.noWaitAfter = %%-input-no-wait-after-%%
|
||||
* since: v1.28
|
||||
|
||||
## async method: Frame.innerHTML
|
||||
* since: v1.8
|
||||
|
@ -734,6 +734,8 @@ When all steps combined have not finished during the specified [`option: timeout
|
||||
* since: v1.14
|
||||
### option: Locator.hover.trial = %%-input-trial-%%
|
||||
* since: v1.14
|
||||
### option: Locator.hover.noWaitAfter = %%-input-no-wait-after-%%
|
||||
* since: v1.28
|
||||
|
||||
## async method: Locator.innerHTML
|
||||
* since: v1.14
|
||||
|
@ -2369,6 +2369,8 @@ Shortcut for main frame's [`method: Frame.hover`].
|
||||
* since: v1.8
|
||||
### option: Page.hover.trial = %%-input-trial-%%
|
||||
* since: v1.11
|
||||
### option: Page.hover.noWaitAfter = %%-input-no-wait-after-%%
|
||||
* since: v1.28
|
||||
|
||||
## async method: Page.innerHTML
|
||||
* since: v1.8
|
||||
|
@ -1331,6 +1331,7 @@ scheme.FrameHoverParams = tObject({
|
||||
position: tOptional(tType('Point')),
|
||||
timeout: tOptional(tNumber),
|
||||
trial: tOptional(tBoolean),
|
||||
noWaitAfter: tOptional(tBoolean),
|
||||
});
|
||||
scheme.FrameHoverResult = tOptional(tObject({}));
|
||||
scheme.FrameInnerHTMLParams = tObject({
|
||||
@ -1717,6 +1718,7 @@ scheme.ElementHandleHoverParams = tObject({
|
||||
position: tOptional(tType('Point')),
|
||||
timeout: tOptional(tNumber),
|
||||
trial: tOptional(tBoolean),
|
||||
noWaitAfter: tOptional(tBoolean),
|
||||
});
|
||||
scheme.ElementHandleHoverResult = tOptional(tObject({}));
|
||||
scheme.ElementHandleInnerHTMLParams = tOptional(tObject({}));
|
||||
|
@ -499,7 +499,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}, this._page._timeoutSettings.timeout(options));
|
||||
}
|
||||
|
||||
_hover(progress: Progress, options: types.PointerActionOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
_hover(progress: Progress, options: types.PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions): Promise<'error:notconnected' | 'done'> {
|
||||
return this._retryPointerAction(progress, 'hover', false /* waitForEnabled */, point => this._page.mouse.move(point.x, point.y), options);
|
||||
}
|
||||
|
||||
|
@ -1287,7 +1287,7 @@ export class Frame extends SdkObject {
|
||||
return this._elementState(metadata, selector, 'checked', options);
|
||||
}
|
||||
|
||||
async hover(metadata: CallMetadata, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) {
|
||||
async hover(metadata: CallMetadata, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
return controller.run(async progress => {
|
||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._hover(progress, options)));
|
||||
|
28
packages/playwright-core/types/types.d.ts
vendored
28
packages/playwright-core/types/types.d.ts
vendored
@ -2753,6 +2753,13 @@ export interface Page {
|
||||
*/
|
||||
modifiers?: Array<"Alt"|"Control"|"Meta"|"Shift">;
|
||||
|
||||
/**
|
||||
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
|
||||
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
|
||||
* inaccessible pages. Defaults to `false`.
|
||||
*/
|
||||
noWaitAfter?: boolean;
|
||||
|
||||
/**
|
||||
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
|
||||
* element.
|
||||
@ -5785,6 +5792,13 @@ export interface Frame {
|
||||
*/
|
||||
modifiers?: Array<"Alt"|"Control"|"Meta"|"Shift">;
|
||||
|
||||
/**
|
||||
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
|
||||
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
|
||||
* inaccessible pages. Defaults to `false`.
|
||||
*/
|
||||
noWaitAfter?: boolean;
|
||||
|
||||
/**
|
||||
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
|
||||
* element.
|
||||
@ -8710,6 +8724,13 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
||||
*/
|
||||
modifiers?: Array<"Alt"|"Control"|"Meta"|"Shift">;
|
||||
|
||||
/**
|
||||
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
|
||||
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
|
||||
* inaccessible pages. Defaults to `false`.
|
||||
*/
|
||||
noWaitAfter?: boolean;
|
||||
|
||||
/**
|
||||
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
|
||||
* element.
|
||||
@ -10171,6 +10192,13 @@ export interface Locator {
|
||||
*/
|
||||
modifiers?: Array<"Alt"|"Control"|"Meta"|"Shift">;
|
||||
|
||||
/**
|
||||
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
|
||||
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
|
||||
* inaccessible pages. Defaults to `false`.
|
||||
*/
|
||||
noWaitAfter?: boolean;
|
||||
|
||||
/**
|
||||
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
|
||||
* element.
|
||||
|
@ -2441,6 +2441,7 @@ export type FrameHoverParams = {
|
||||
position?: Point,
|
||||
timeout?: number,
|
||||
trial?: boolean,
|
||||
noWaitAfter?: boolean,
|
||||
};
|
||||
export type FrameHoverOptions = {
|
||||
strict?: boolean,
|
||||
@ -2449,6 +2450,7 @@ export type FrameHoverOptions = {
|
||||
position?: Point,
|
||||
timeout?: number,
|
||||
trial?: boolean,
|
||||
noWaitAfter?: boolean,
|
||||
};
|
||||
export type FrameHoverResult = void;
|
||||
export type FrameInnerHTMLParams = {
|
||||
@ -3095,6 +3097,7 @@ export type ElementHandleHoverParams = {
|
||||
position?: Point,
|
||||
timeout?: number,
|
||||
trial?: boolean,
|
||||
noWaitAfter?: boolean,
|
||||
};
|
||||
export type ElementHandleHoverOptions = {
|
||||
force?: boolean,
|
||||
@ -3102,6 +3105,7 @@ export type ElementHandleHoverOptions = {
|
||||
position?: Point,
|
||||
timeout?: number,
|
||||
trial?: boolean,
|
||||
noWaitAfter?: boolean,
|
||||
};
|
||||
export type ElementHandleHoverResult = void;
|
||||
export type ElementHandleInnerHTMLParams = {};
|
||||
|
@ -1767,6 +1767,7 @@ Frame:
|
||||
position: Point?
|
||||
timeout: number?
|
||||
trial: boolean?
|
||||
noWaitAfter: boolean?
|
||||
tracing:
|
||||
snapshot: true
|
||||
pausesBeforeInput: true
|
||||
@ -2332,6 +2333,7 @@ ElementHandle:
|
||||
position: Point?
|
||||
timeout: number?
|
||||
trial: boolean?
|
||||
noWaitAfter: boolean?
|
||||
tracing:
|
||||
snapshot: true
|
||||
pausesBeforeInput: true
|
||||
|
@ -33,6 +33,16 @@ it('should hover when Node is removed', async ({ page, server }) => {
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||
});
|
||||
|
||||
it('hover should support noWaitAfter', async ({ page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`<button onmouseover='location.href="${server.PREFIX}/next"'>GO</button>`);
|
||||
await Promise.all([
|
||||
new Promise(fulfill => server.setRoute('/next', fulfill)),
|
||||
page.locator('button').hover({ noWaitAfter: true })
|
||||
]);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should fill input', async ({ page, server }) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
const handle = page.locator('input');
|
||||
|
@ -173,6 +173,16 @@ it('should trigger hover state', async ({ page, server }) => {
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-91');
|
||||
});
|
||||
|
||||
it('hover should support noWaitAfter', async ({ page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`<button onmouseover='location.href="${server.PREFIX}/next"'>GO</button>`);
|
||||
await Promise.all([
|
||||
new Promise(fulfill => server.setRoute('/next', fulfill)),
|
||||
page.hover('button', { noWaitAfter: true })
|
||||
]);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should trigger hover state on disabled button', async ({ page, server }) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.$eval('#button-6', (button: HTMLButtonElement) => button.disabled = true);
|
||||
|
Loading…
Reference in New Issue
Block a user