fix(page): page.click should work with disabled javascript (#2907)

Unfortunately, disabling javascript in page prevents any microtasks
to be executed even from puppeteer-originating javascript. As a
result, the IntersectionObserver hack we use to conditionally
scroll into view doesn't work.

To workaround this, we start always scrolling before clicking if
page's javascript is disabled.

Fixes #2898
This commit is contained in:
Andrey Lushnikov 2018-07-18 18:51:18 -07:00 committed by GitHub
parent e4e72c9e81
commit 56368aa07a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 2 deletions

View File

@ -55,11 +55,16 @@ class ElementHandle extends JSHandle {
}
async _scrollIntoViewIfNeeded() {
const error = await this.executionContext().evaluate(async element => {
const error = await this.executionContext().evaluate(async(element, pageJavascriptEnabled) => {
if (!element.isConnected)
return 'Node is detached from document';
if (element.nodeType !== Node.ELEMENT_NODE)
return 'Node is not of type HTMLElement';
// force-scroll if page's javascript is disabled.
if (!pageJavascriptEnabled) {
element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
return false;
}
const visibleRatio = await new Promise(resolve => {
const observer = new IntersectionObserver(entries => {
resolve(entries[0].intersectionRatio);
@ -70,7 +75,7 @@ class ElementHandle extends JSHandle {
if (visibleRatio !== 1.0)
element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
return false;
}, this);
}, this, this._page._javascriptEnabled);
if (error)
throw new Error(error);
}

View File

@ -88,6 +88,7 @@ class Page extends EventEmitter {
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
this._coverage = new Coverage(client);
this._defaultNavigationTimeout = 30000;
this._javascriptEnabled = true;
this._screenshotTaskQueue = screenshotTaskQueue;
@ -714,6 +715,9 @@ class Page extends EventEmitter {
* @param {boolean} enabled
*/
async setJavaScriptEnabled(enabled) {
if (this._javascriptEnabled === enabled)
return;
this._javascriptEnabled = enabled;
await this._client.send('Emulation.setScriptExecutionDisabled', { value: !enabled });
}

View File

@ -28,6 +28,15 @@ module.exports.addTests = function({testRunner, expect, DeviceDescriptors}) {
await page.click('button');
expect(await page.evaluate(() => result)).toBe('Clicked');
});
it('should click with disabled javascript', async({page, server}) => {
await page.setJavaScriptEnabled(false);
await page.goto(server.PREFIX + '/wrappedlink.html');
await Promise.all([
page.click('a'),
page.waitForNavigation()
]);
expect(page.url()).toBe(server.PREFIX + '/wrappedlink.html#clicked');
});
it('should click offscreen buttons', async({page, server}) => {
await page.goto(server.PREFIX + '/offscreenbuttons.html');