mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
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:
parent
e4e72c9e81
commit
56368aa07a
@ -55,11 +55,16 @@ class ElementHandle extends JSHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _scrollIntoViewIfNeeded() {
|
async _scrollIntoViewIfNeeded() {
|
||||||
const error = await this.executionContext().evaluate(async element => {
|
const error = await this.executionContext().evaluate(async(element, pageJavascriptEnabled) => {
|
||||||
if (!element.isConnected)
|
if (!element.isConnected)
|
||||||
return 'Node is detached from document';
|
return 'Node is detached from document';
|
||||||
if (element.nodeType !== Node.ELEMENT_NODE)
|
if (element.nodeType !== Node.ELEMENT_NODE)
|
||||||
return 'Node is not of type HTMLElement';
|
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 visibleRatio = await new Promise(resolve => {
|
||||||
const observer = new IntersectionObserver(entries => {
|
const observer = new IntersectionObserver(entries => {
|
||||||
resolve(entries[0].intersectionRatio);
|
resolve(entries[0].intersectionRatio);
|
||||||
@ -70,7 +75,7 @@ class ElementHandle extends JSHandle {
|
|||||||
if (visibleRatio !== 1.0)
|
if (visibleRatio !== 1.0)
|
||||||
element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
|
element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
|
||||||
return false;
|
return false;
|
||||||
}, this);
|
}, this, this._page._javascriptEnabled);
|
||||||
if (error)
|
if (error)
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,7 @@ class Page extends EventEmitter {
|
|||||||
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||||
this._coverage = new Coverage(client);
|
this._coverage = new Coverage(client);
|
||||||
this._defaultNavigationTimeout = 30000;
|
this._defaultNavigationTimeout = 30000;
|
||||||
|
this._javascriptEnabled = true;
|
||||||
|
|
||||||
this._screenshotTaskQueue = screenshotTaskQueue;
|
this._screenshotTaskQueue = screenshotTaskQueue;
|
||||||
|
|
||||||
@ -714,6 +715,9 @@ class Page extends EventEmitter {
|
|||||||
* @param {boolean} enabled
|
* @param {boolean} enabled
|
||||||
*/
|
*/
|
||||||
async setJavaScriptEnabled(enabled) {
|
async setJavaScriptEnabled(enabled) {
|
||||||
|
if (this._javascriptEnabled === enabled)
|
||||||
|
return;
|
||||||
|
this._javascriptEnabled = enabled;
|
||||||
await this._client.send('Emulation.setScriptExecutionDisabled', { value: !enabled });
|
await this._client.send('Emulation.setScriptExecutionDisabled', { value: !enabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,15 @@ module.exports.addTests = function({testRunner, expect, DeviceDescriptors}) {
|
|||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
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}) => {
|
it('should click offscreen buttons', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/offscreenbuttons.html');
|
await page.goto(server.PREFIX + '/offscreenbuttons.html');
|
||||||
|
Loading…
Reference in New Issue
Block a user