New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(page): fix page.#scrollIntoViewIfNeeded method #8631
Conversation
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
it looks like Firefox implementation does not support |
@OrKoN Not sure it's the best approach as it'll introduce differences between chrome/firefox. See this test case: https://github.com/puppeteer/puppeteer/blob/main/test/src/elementhandle.spec.ts#L206 I think we should log a feature request in Firefox bug tracker for |
I don't think Firefox is going to look into extending the CDP support anytime soon unfortunately. cc @whimboo Henrik, is it something that could be a priority for you? |
I doubt that we could take that unless someone is interested to actually help with the implementation. Also |
@OrKoN I'll investigate it a bit further and I think I'll come up with a solution which would work in both envs. |
I ended up with this implementation which keeps backward compatibility as much as possible and it falls back to async #scrollIntoViewIfNeeded(): Promise<void> {
const error = await this.evaluate(
async (element): Promise<string | undefined> => {
if (!element.isConnected) {
return 'Node is detached from document';
}
if (element.nodeType !== Node.ELEMENT_NODE) {
return 'Node is not of type HTMLElement';
}
return;
}
);
if (error) {
throw new Error(error);
}
try {
await this._client.send('DOM.scrollIntoViewIfNeeded', {
objectId: this._remoteObject.objectId,
});
} catch (_err) {
// Fallback to Element.scrollIntoView if DOM.scrollIntoViewIfNeeded is not supported
await this.evaluate(
async (element, pageJavascriptEnabled): Promise<void> => {
// force-scroll if page's javascript is disabled.
if (!pageJavascriptEnabled) {
element.scrollIntoView({
block: 'center',
inline: 'center',
// @ts-expect-error Chrome still supports behavior: instant but
// it's not in the spec so TS shouts We don't want to make this
// breaking change in Puppeteer yet so we'll ignore the line.
behavior: 'instant',
});
}
const visibleRatio = await new Promise(resolve => {
const observer = new IntersectionObserver(entries => {
resolve(entries[0]!.intersectionRatio);
observer.disconnect();
});
observer.observe(element);
});
if (visibleRatio !== 1.0) {
element.scrollIntoView({
block: 'center',
inline: 'center',
// @ts-expect-error Chrome still supports behavior: instant but
// it's not in the spec so TS shouts We don't want to make this
// breaking change in Puppeteer yet so we'll ignore the line.
behavior: 'instant',
});
}
},
this.#page.isJavaScriptEnabled()
);
}
} |
@abozhilov I think 15.3.1 only contains type and documentation changes. The amount of flaky failures (which is unfortunately not zero) should be the same (but we removed automatic retries and we aim at fixing those). Could you update your PR with the latest code version? |
I've just updated my PR. |
Do you think we still need to mark this PR as a breaking change? It looks backward compatible. |
Also, it looks like a few elementhandle.spec.ts tests broke due to the changes to the test file |
@OrKoN It's backward compatible, but to be 100% sure I'll have a look at the test cases which you've mentioned. |
@OrKoN I've just reverted |
Hi @OrKoN, I would like to know by when we can expect this pull request to be merged. |
This patch fixes page.#scrollIntoViewIfNeeded, so that it works with devtools protocol. Now it blocks the main thread and waits until the scrolling action finishes in Chrome. Fallbacks to the old implementation if `DOM.scrollIntoViewIfNeeded` is not supported for Firefox. Issues: puppeteer#8627, puppeteer#1805
This patch fixes page.#scrollIntoViewIfNeededso that it works with devtools protocol.
Now it blocks the main thread and waits until the scrolling action finishes.
Issues: #8627, #1805
BREAKING CHANGE: page.#scrollIntoViewIfNeeded throws erros which come from the internal implementation.
Protocol error (DOM.scrollIntoViewIfNeeded): Node is detached from document
Protocol error (DOM.scrollIntoViewIfNeeded): Node does not have a layout object
Also now it does work with TextNode properly and does not throw an error.