From 26c00a97a56f5c11970b6f5dd08bfd2d147c55a2 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 3 Apr 2023 15:05:40 -0700 Subject: [PATCH] fix(expect): do not produce logs twice (#22171) --- packages/playwright-core/src/server/frames.ts | 5 ++-- tests/page/expect-misc.spec.ts | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index c1a23f100f..85239919fe 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -1381,9 +1381,10 @@ export class Frame extends SdkObject { private async _expectInternal(metadata: CallMetadata, selector: string, options: FrameExpectParams, oneShot: boolean, timeout: number, lastIntermediateResult: { received?: any, isSet: boolean }): Promise<{ matches: boolean, received?: any, log?: string[], timedOut?: boolean }> { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - if (oneShot) + if (oneShot) { progress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ''}`); - progress.log(`waiting for ${this._asLocator(selector)}`); + progress.log(`waiting for ${this._asLocator(selector)}`); + } return await this.retryWithProgressAndTimeouts(progress, [100, 250, 500, 1000], async continuePolling => { const selectorInFrame = await this.selectors.resolveFrameForSelector(selector, { strict: true }); progress.throwIfAborted(); diff --git a/tests/page/expect-misc.spec.ts b/tests/page/expect-misc.spec.ts index 9bb771858d..afdb8e8803 100644 --- a/tests/page/expect-misc.spec.ts +++ b/tests/page/expect-misc.spec.ts @@ -341,3 +341,32 @@ test.describe('toBeInViewport', () => { await expect(page.locator('h1')).toBeInViewport(); }); }); + +test('toHaveCount should not produce logs twice', async ({ page }) => { + await page.setContent(''); + const error = await expect(page.locator('option')).toHaveCount(2, { timeout: 2000 }).catch(e => e); + const waitingForMessage = `waiting for locator('option')`; + expect(error.message).toContain(waitingForMessage); + expect(error.message).toContain(`locator resolved to 1 element`); + expect(error.message).toContain(`unexpected value "1"`); + expect(error.message.replace(waitingForMessage, '')).not.toContain(waitingForMessage); +}); + +test('toHaveText should not produce logs twice', async ({ page }) => { + await page.setContent('
hello
'); + const error = await expect(page.locator('div')).toHaveText('world', { timeout: 2000 }).catch(e => e); + const waitingForMessage = `waiting for locator('div')`; + expect(error.message).toContain(waitingForMessage); + expect(error.message).toContain(`locator resolved to
hello
`); + expect(error.message).toContain(`unexpected value "hello"`); + expect(error.message.replace(waitingForMessage, '')).not.toContain(waitingForMessage); +}); + +test('toHaveText that does not match should not produce logs twice', async ({ page }) => { + await page.setContent('
hello
'); + const error = await expect(page.locator('span')).toHaveText('world', { timeout: 2000 }).catch(e => e); + const waitingForMessage = `waiting for locator('span')`; + expect(error.message).toContain(waitingForMessage); + expect(error.message).not.toContain('locator resolved to'); + expect(error.message.replace(waitingForMessage, '')).not.toContain(waitingForMessage); +});