-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Open
Labels
Description
Summary
So I followed this example (more or less) https://web.dev/lighthouse-user-flows/#looking-for-feedback
What I am trying to do is navigate to a page, scroll to the bottom, and scroll back to the top.
However, if I put the scroll to the bottom in a timespan at the end it resets to the top of the page.
How do I avoid this?
const url = new URL(targetUrl);
const browser = await launch({headless: false});
const page = await browser.newPage();
const flow = await new UserFlow(page);
const scrollAction = new ScrollAction(page);
await flow.navigate(url.href, { stepName: "Cold Initial Navigation" });
await flow.startTimespan({ stepName: 'Scroll To Bottom Of Page' } );
await scrollAction.swipeToPageBottom();
await flow.endTimespan();
await flow.startTimespan({ stepName: 'Scroll To Top Of Page' });
await scrollAction!.swipeToPageTop();
await flow.endTimespan();
const report = await flow.createFlowResult();
await browser.close();and the scroll action
import { CDPSession, Page, Protocol } from "puppeteer";
export class ScrollAction {
private session?: CDPSession;
constructor(private page: Page) {}
async swipeToPageBottom(): Promise<void> {
await this.page.waitForSelector("body");
await this._synthesizeTouchScroll('down');
}
async swipeToPageTop(): Promise<void> {
await this.page.waitForSelector("body");
await this._synthesizeTouchScroll('up');
}
private async _synthesizeTouchScroll(direction: 'down' | 'up'): Promise<void> {
const scrollParams = await this._getScrollParams(direction);
if (!this.session) {
this.session = await this.page.target().createCDPSession();
}
// https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture
await this.session.send('Input.synthesizeScrollGesture', scrollParams);
}
private async _getScrollParams(direction: 'down' | 'up'): Promise<Protocol.Input.SynthesizeScrollGestureRequest> {
const innerHeight = await this._getInnerContentHeight();
const x = 200;
const y = direction === 'up' ? 200 : 600;
const scrollDistance = 1500;
const speed = 800;
const repeatDelayMs = 250;
const yDistance = direction === 'up' ? scrollDistance : scrollDistance * (-1);
const repeatCount = Math.ceil(innerHeight/scrollDistance) -1;
const gestureSourceType = 'touch';
return {x, y, yDistance, speed, repeatCount, repeatDelayMs, gestureSourceType};
}
private async _getInnerContentHeight(): Promise<number> {
const innerContentHandle = await this.page.$("body");
const innerContentBox = await innerContentHandle!.boundingBox();
return innerContentBox!.height;
}
}Now what is interesting is that if I remove the timestamp it works fine.
If I don't, its scrolls to the bottom and then appears at the top and tries to scroll from there.
What am I doing wrong or is it a config that I am missing?
Thanks so much in advance :)