fix(click): work around input alignment on chromium (#1282)

This commit is contained in:
Pavel Feldman 2020-03-07 08:19:31 -08:00 committed by GitHub
parent 996f97a6c0
commit 78bd29d558
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 27 additions and 12 deletions

View File

@ -560,6 +560,10 @@ export class CRPage implements PageDelegate {
return getAccessibilityTree(this._client, needle); return getAccessibilityTree(this._client, needle);
} }
async inputActionEpilogue(): Promise<void> {
await this._client.send('Page.enable').catch(e => {});
}
async pdf(options?: types.PDFOptions): Promise<platform.BufferType> { async pdf(options?: types.PDFOptions): Promise<platform.BufferType> {
return this._pdf.generate(options); return this._pdf.generate(options);
} }

View File

@ -258,7 +258,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
await action(point); await action(point);
if (restoreModifiers) if (restoreModifiers)
await this._page.keyboard._ensureModifiers(restoreModifiers); await this._page.keyboard._ensureModifiers(restoreModifiers);
}, options); }, options, true);
} }
hover(options?: PointerActionOptions & types.PointerActionWaitOptions): Promise<void> { hover(options?: PointerActionOptions & types.PointerActionWaitOptions): Promise<void> {
@ -309,7 +309,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
await this._page.keyboard.sendCharacters(value); await this._page.keyboard.sendCharacters(value);
else else
await this._page.keyboard.press('Delete'); await this._page.keyboard.press('Delete');
}, options); }, options, true);
} }
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[]) { async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[]) {
@ -358,14 +358,14 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
await this._page._frameManager.waitForNavigationsCreatedBy(async () => { await this._page._frameManager.waitForNavigationsCreatedBy(async () => {
await this.focus(); await this.focus();
await this._page.keyboard.type(text, options); await this._page.keyboard.type(text, options);
}, options); }, options, true);
} }
async press(key: string, options?: { delay?: number, text?: string } & types.NavigatingActionWaitOptions) { async press(key: string, options?: { delay?: number, text?: string } & types.NavigatingActionWaitOptions) {
await this._page._frameManager.waitForNavigationsCreatedBy(async () => { await this._page._frameManager.waitForNavigationsCreatedBy(async () => {
await this.focus(); await this.focus();
await this._page.keyboard.press(key, options); await this._page.keyboard.press(key, options);
}, options); }, options, true);
} }
async check(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { async check(options?: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {

View File

@ -433,6 +433,9 @@ export class FFPage implements PageDelegate {
return getAccessibilityTree(this._session, needle); return getAccessibilityTree(this._session, needle);
} }
async inputActionEpilogue(): Promise<void> {
}
async getFrameElement(frame: frames.Frame): Promise<dom.ElementHandle> { async getFrameElement(frame: frames.Frame): Promise<dom.ElementHandle> {
const parent = frame.parentFrame(); const parent = frame.parentFrame();
if (!parent) if (!parent)

View File

@ -100,13 +100,15 @@ export class FrameManager {
} }
} }
async waitForNavigationsCreatedBy<T>(action: () => Promise<T>, options?: types.NavigatingActionWaitOptions): Promise<T> { async waitForNavigationsCreatedBy<T>(action: () => Promise<T>, options?: types.NavigatingActionWaitOptions, input?: boolean): Promise<T> {
if (options && options.waitUntil === 'nowait') if (options && options.waitUntil === 'nowait')
return action(); return action();
const barrier = new PendingNavigationBarrier(options); const barrier = new PendingNavigationBarrier(options);
this._pendingNavigationBarriers.add(barrier); this._pendingNavigationBarriers.add(barrier);
try { try {
const result = await action(); const result = await action();
if (input)
await this._page._delegate.inputActionEpilogue();
await barrier.waitFor(); await barrier.waitFor();
// Resolve in the next task, after all waitForNavigations. // Resolve in the next task, after all waitForNavigations.
await new Promise(platform.makeWaitForNextTask()); await new Promise(platform.makeWaitForNextTask());

View File

@ -70,6 +70,9 @@ export interface PageDelegate {
getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}>; getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}>;
pdf?: (options?: types.PDFOptions) => Promise<platform.BufferType>; pdf?: (options?: types.PDFOptions) => Promise<platform.BufferType>;
coverage?: () => any; coverage?: () => any;
// Work around Chrome's non-associated input and protocol.
inputActionEpilogue(): Promise<void>;
} }
type PageState = { type PageState = {

View File

@ -701,6 +701,9 @@ export class WKPage implements PageDelegate {
return getAccessibilityTree(this._session, needle); return getAccessibilityTree(this._session, needle);
} }
async inputActionEpilogue(): Promise<void> {
}
async getFrameElement(frame: frames.Frame): Promise<dom.ElementHandle> { async getFrameElement(frame: frames.Frame): Promise<dom.ElementHandle> {
const parent = frame.parentFrame(); const parent = frame.parentFrame();
if (!parent) if (!parent)

View File

@ -802,7 +802,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF
}); });
describe('Page.automaticWaiting', () => { 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 = []; const messages = [];
server.setRoute('/empty.html', async (req, res) => { server.setRoute('/empty.html', async (req, res) => {
messages.push('route'); messages.push('route');
@ -817,7 +817,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF
]); ]);
expect(messages.join('|')).toBe('route|waitForNavigation|click'); 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 = []; const messages = [];
server.setRoute('/empty.html', async (req, res) => { server.setRoute('/empty.html', async (req, res) => {
messages.push('route'); messages.push('route');
@ -832,7 +832,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF
]); ]);
expect(messages.join('|')).toBe('route|waitForNavigation|click'); 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 = []; const messages = [];
server.setRoute('/empty.html?foo=bar', async (req, res) => { server.setRoute('/empty.html?foo=bar', async (req, res) => {
messages.push('route'); messages.push('route');
@ -851,7 +851,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF
]); ]);
expect(messages.join('|')).toBe('route|waitForNavigation|click'); 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 = []; const messages = [];
server.setRoute('/empty.html', async (req, res) => { server.setRoute('/empty.html', async (req, res) => {
messages.push('route'); messages.push('route');
@ -882,9 +882,9 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF
]); ]);
expect(messages.join('|')).toBe('route|waitForNavigation|evaluate'); 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 = []; 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'); }); server.setRoute('/empty.html?override', async (req, res) => { messages.push('routeoverride'); res.end('done'); });
await Promise.all([ await Promise.all([
page.evaluate(` page.evaluate(`
@ -905,7 +905,7 @@ module.exports.describe = function({testRunner, expect, playwright, MAC, WIN, FF
]); ]);
expect(messages.join('|')).toBe('route|waitForNavigation|evaluate'); 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 = []; const messages = [];
server.setRoute('/empty.html', async (req, res) => { messages.push('route'); res.end('done'); }); server.setRoute('/empty.html', async (req, res) => { messages.push('route'); res.end('done'); });