diff --git a/src/chromium/crPage.ts b/src/chromium/crPage.ts index a6c03aa996ae2..bf7b1ba9a3d99 100644 --- a/src/chromium/crPage.ts +++ b/src/chromium/crPage.ts @@ -560,6 +560,10 @@ export class CRPage implements PageDelegate { return getAccessibilityTree(this._client, needle); } + async inputActionEpilogue(): Promise { + await this._client.send('Page.enable').catch(e => {}); + } + async pdf(options?: types.PDFOptions): Promise { return this._pdf.generate(options); } diff --git a/src/dom.ts b/src/dom.ts index 5479fc23cd2a5..58d52b4e3298b 100644 --- a/src/dom.ts +++ b/src/dom.ts @@ -258,7 +258,7 @@ export class ElementHandle extends js.JSHandle { await action(point); if (restoreModifiers) await this._page.keyboard._ensureModifiers(restoreModifiers); - }, options); + }, options, true); } hover(options?: PointerActionOptions & types.PointerActionWaitOptions): Promise { @@ -309,7 +309,7 @@ export class ElementHandle extends js.JSHandle { await this._page.keyboard.sendCharacters(value); else await this._page.keyboard.press('Delete'); - }, options); + }, options, true); } async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[]) { @@ -358,14 +358,14 @@ export class ElementHandle extends js.JSHandle { await this._page._frameManager.waitForNavigationsCreatedBy(async () => { await this.focus(); await this._page.keyboard.type(text, options); - }, options); + }, options, true); } async press(key: string, options?: { delay?: number, text?: string } & types.NavigatingActionWaitOptions) { await this._page._frameManager.waitForNavigationsCreatedBy(async () => { await this.focus(); await this._page.keyboard.press(key, options); - }, options); + }, options, true); } async check(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { diff --git a/src/firefox/ffPage.ts b/src/firefox/ffPage.ts index 574242c10f5c3..96e093a519b63 100644 --- a/src/firefox/ffPage.ts +++ b/src/firefox/ffPage.ts @@ -433,6 +433,9 @@ export class FFPage implements PageDelegate { return getAccessibilityTree(this._session, needle); } + async inputActionEpilogue(): Promise { + } + async getFrameElement(frame: frames.Frame): Promise { const parent = frame.parentFrame(); if (!parent) diff --git a/src/frames.ts b/src/frames.ts index 5b3276d1bba35..0a59b32518edd 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -100,13 +100,15 @@ export class FrameManager { } } - async waitForNavigationsCreatedBy(action: () => Promise, options?: types.NavigatingActionWaitOptions): Promise { + async waitForNavigationsCreatedBy(action: () => Promise, options?: types.NavigatingActionWaitOptions, input?: boolean): Promise { if (options && options.waitUntil === 'nowait') return action(); const barrier = new PendingNavigationBarrier(options); this._pendingNavigationBarriers.add(barrier); try { const result = await action(); + if (input) + await this._page._delegate.inputActionEpilogue(); await barrier.waitFor(); // Resolve in the next task, after all waitForNavigations. await new Promise(platform.makeWaitForNextTask()); diff --git a/src/page.ts b/src/page.ts index a21b664f1e35e..3ff5375e49131 100644 --- a/src/page.ts +++ b/src/page.ts @@ -70,6 +70,9 @@ export interface PageDelegate { getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}>; pdf?: (options?: types.PDFOptions) => Promise; coverage?: () => any; + + // Work around Chrome's non-associated input and protocol. + inputActionEpilogue(): Promise; } type PageState = { diff --git a/src/webkit/wkPage.ts b/src/webkit/wkPage.ts index e05fe82805777..88146d29c2ff0 100644 --- a/src/webkit/wkPage.ts +++ b/src/webkit/wkPage.ts @@ -701,6 +701,9 @@ export class WKPage implements PageDelegate { return getAccessibilityTree(this._session, needle); } + async inputActionEpilogue(): Promise { + } + async getFrameElement(frame: frames.Frame): Promise { const parent = frame.parentFrame(); if (!parent) diff --git a/test/navigation.spec.js b/test/navigation.spec.js index 4bcdf80a21a96..b6d00e0bbb362 100644 --- a/test/navigation.spec.js +++ b/test/navigation.spec.js @@ -802,7 +802,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF }); describe('Page.automaticWaiting', () => { - it.fail(CHROMIUM)('clicking anchor should await navigation', async({page, server}) => { + it('clicking anchor should await navigation', async({page, server}) => { const messages = []; server.setRoute('/empty.html', async (req, res) => { messages.push('route'); @@ -817,7 +817,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF ]); expect(messages.join('|')).toBe('route|waitForNavigation|click'); }); - it.fail(CHROMIUM)('clicking anchor should await cross-process navigation', async({page, server}) => { + it('clicking anchor should await cross-process navigation', async({page, server}) => { const messages = []; server.setRoute('/empty.html', async (req, res) => { messages.push('route'); @@ -832,7 +832,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF ]); expect(messages.join('|')).toBe('route|waitForNavigation|click'); }); - it.fail(CHROMIUM)('should await form-get on click', async({page, server}) => { + it('should await form-get on click', async({page, server}) => { const messages = []; server.setRoute('/empty.html?foo=bar', async (req, res) => { messages.push('route'); @@ -851,7 +851,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF ]); expect(messages.join('|')).toBe('route|waitForNavigation|click'); }); - it.fail(CHROMIUM)('should await form-post on click', async({page, server}) => { + it('should await form-post on click', async({page, server}) => { const messages = []; server.setRoute('/empty.html', async (req, res) => { messages.push('route'); @@ -882,9 +882,9 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF ]); expect(messages.join('|')).toBe('route|waitForNavigation|evaluate'); }); - it.fail(CHROMIUM)('assigning location twice should await navigation', async({page, server}) => { + it.skip(CHROMIUM)('assigning location twice should await navigation', async({page, server}) => { const messages = []; - server.setRoute('/empty.html?cancel', async (req, res) => { messages.push('routecancel'); res.end('done'); }); + server.setRoute('/empty.html?cancel', async (req, res) => { res.end('done'); }); server.setRoute('/empty.html?override', async (req, res) => { messages.push('routeoverride'); res.end('done'); }); await Promise.all([ page.evaluate(` @@ -905,7 +905,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF ]); expect(messages.join('|')).toBe('route|waitForNavigation|evaluate'); }); - it.fail(CHROMIUM)('should await navigating specified target', async({page, server}) => { + it('should await navigating specified target', async({page, server}) => { const messages = []; server.setRoute('/empty.html', async (req, res) => { messages.push('route'); res.end('done'); });