feat(locator handler): perform checkpoit during `locator.waitFor` (#32683)

Fixes #32255.
This commit is contained in:
Dmitry Gozman 2024-09-18 09:34:06 -07:00 committed by GitHub
parent d4eecafa8a
commit f9d9ad25de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 3 deletions

View File

@ -782,13 +782,16 @@ export class Frame extends SdkObject {
throw new Error(`state: expected one of (attached|detached|visible|hidden)`);
return controller.run(async progress => {
progress.log(`waiting for ${this._asLocator(selector)}${state === 'attached' ? '' : ' to be ' + state}`);
return await this.waitForSelectorInternal(progress, selector, options, scope);
return await this.waitForSelectorInternal(progress, selector, true, options, scope);
}, this._page._timeoutSettings.timeout(options));
}
async waitForSelectorInternal(progress: Progress, selector: string, options: types.WaitForElementOptions, scope?: dom.ElementHandle): Promise<dom.ElementHandle<Element> | null> {
async waitForSelectorInternal(progress: Progress, selector: string, performLocatorHandlersCheckpoint: boolean, options: types.WaitForElementOptions, scope?: dom.ElementHandle): Promise<dom.ElementHandle<Element> | null> {
const { state = 'visible' } = options;
const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => {
if (performLocatorHandlersCheckpoint)
await this._page.performLocatorHandlersCheckpoint(progress);
const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope);
progress.throwIfAborted();
if (!resolved) {

View File

@ -473,7 +473,7 @@ export class Page extends SdkObject {
progress.throwIfAborted();
if (!handler.noWaitAfter) {
progress.log(` locator handler has finished, waiting for ${asLocator(this.attribution.playwright.options.sdkLanguage, handler.selector)} to be hidden`);
await this.mainFrame().waitForSelectorInternal(progress, handler.selector, { state: 'hidden' });
await this.mainFrame().waitForSelectorInternal(progress, handler.selector, false, { state: 'hidden' });
} else {
progress.log(` locator handler has finished`);
}

View File

@ -181,6 +181,24 @@ test('should work with toBeVisible', async ({ page, server }) => {
expect(called).toBe(1);
});
test('should work with locator.waitFor', async ({ page, server }) => {
await page.goto(server.PREFIX + '/input/handle-locator.html');
let called = 0;
await page.addLocatorHandler(page.getByText('This interstitial covers the button'), async () => {
++called;
await page.locator('#close').click();
});
await page.evaluate(() => {
(window as any).clicked = 0;
(window as any).setupAnnoyingInterstitial('remove', 1);
});
await page.locator('#target').waitFor();
await expect(page.locator('#interstitial')).not.toBeVisible();
expect(called).toBe(1);
});
test('should work with toHaveScreenshot', async ({ page, server, isAndroid }) => {
test.fixme(isAndroid, 'Screenshots are cut off on Android');
await page.setViewportSize({ width: 500, height: 500 });