diff --git a/packages/playwright-core/src/server/dom.ts b/packages/playwright-core/src/server/dom.ts index 9d8b9fd7a1..ce7d0b2510 100644 --- a/packages/playwright-core/src/server/dom.ts +++ b/packages/playwright-core/src/server/dom.ts @@ -1015,14 +1015,14 @@ export function waitForSelectorTask(selector: SelectorInfo, state: 'attached' | if (lastElement !== element) { lastElement = element; if (!element) { - progress.log(` selector did not resolve to any element`); + progress.log(` locator did not resolve to any element`); } else { if (elements.length > 1) { if (strict) throw injected.strictModeViolationError(parsed, elements); - progress.log(` selector resolved to ${elements.length} elements. Proceeding with the first one.`); + progress.log(` locator resolved to ${elements.length} elements. Proceeding with the first one.`); } - progress.log(` selector resolved to ${visible ? 'visible' : 'hidden'} ${injected.previewNode(element)}`); + progress.log(` locator resolved to ${visible ? 'visible' : 'hidden'} ${injected.previewNode(element)}`); } } diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 94c8028161..0fe1c4fdab 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -804,7 +804,7 @@ export class Frame extends SdkObject { if (!['attached', 'detached', 'visible', 'hidden'].includes(state)) 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}`); + progress.log(`waiting for ${this._asLocator(selector)}${state === 'attached' ? '' : ' to be ' + state}`); return this.retryWithProgress(progress, selector, options, async (selectorInFrame, continuePolling) => { // Be careful, |this| can be different from |frame|. // We did not pass omitAttached, so it is non-null. @@ -1114,7 +1114,7 @@ export class Frame extends SdkObject { const { frame, info } = selectorInFrame!; // Be careful, |this| can be different from |frame|. const task = dom.waitForSelectorTask(info, 'attached'); - progress.log(`waiting for "${this._asLocator(selector)}"`); + progress.log(`waiting for ${this._asLocator(selector)}`); const handle = await frame._scheduleRerunnableHandleTask(progress, info.world, task); const element = handle.asElement() as dom.ElementHandle; try { @@ -1268,7 +1268,7 @@ export class Frame extends SdkObject { async isVisible(metadata: CallMetadata, selector: string, options: types.StrictOptions = {}): Promise { const controller = new ProgressController(metadata, this); return controller.run(async progress => { - progress.log(` checking visibility of "${selector}"`); + progress.log(` checking visibility of ${this._asLocator(selector)}`); const pair = await this.resolveFrameForSelectorNoWait(selector, options); if (!pair) return false; @@ -1515,7 +1515,7 @@ export class Frame extends SdkObject { const callbackText = body.toString(); return this.retryWithProgress(progress, selector, options, async selectorInFrame => { // Be careful, |this| can be different from |frame|. - progress.log(`waiting for "${this._asLocator(selector)}"`); + progress.log(`waiting for ${this._asLocator(selector)}`); const { frame, info } = selectorInFrame || { frame: this, info: { parsed: { parts: [{ name: 'internal:control', body: 'return-empty', source: 'internal:control=return-empty' }] }, world: 'utility', strict: !!options.strict } }; return await frame._scheduleRerunnableTaskInFrame(progress, info, callbackText, taskData, options); }); @@ -1542,12 +1542,12 @@ export class Frame extends SdkObject { if (querySelectorAll) { elements = injected.querySelectorAll(info.parsed, document); element = elements[0]; - progress.logRepeating(` selector resolved to ${elements.length} element${elements.length === 1 ? '' : 's'}`); + progress.logRepeating(` locator resolved to ${elements.length} element${elements.length === 1 ? '' : 's'}`); } else { element = injected.querySelector(info.parsed, document, info.strict); elements = element ? [element] : []; if (element) - progress.logRepeating(` selector resolved to ${injected.previewNode(element)}`); + progress.logRepeating(` locator resolved to ${injected.previewNode(element)}`); } if (!element && !omitAttached) @@ -1667,7 +1667,7 @@ export class Frame extends SdkObject { for (let i = 0; i < frameChunks.length - 1 && progress.isRunning(); ++i) { const info = this._page.parseSelector(frameChunks[i], options); const task = dom.waitForSelectorTask(info, 'attached', false, i === 0 ? scope : undefined); - progress.log(` waiting for frame "${stringifySelector(frameChunks[i])}"`); + progress.log(` waiting for frameLocator('${stringifySelector(frameChunks[i])}')`); const handle = i === 0 && scope ? await frame._runWaitForSelectorTaskOnce(progress, stringifySelector(info.parsed), info.world, task) : await frame._scheduleRerunnableHandleTask(progress, info.world, task); const element = handle.asElement() as dom.ElementHandle; @@ -1710,7 +1710,7 @@ export class Frame extends SdkObject { progress.cleanupWhenAborted(() => result.dispose()); return result; } catch (e) { - throw new Error(`Error: frame navigated while waiting for "${this._asLocator(selector)}"`); + throw new Error(`Error: frame navigated while waiting for ${this._asLocator(selector)}`); } } diff --git a/packages/playwright-core/src/server/injected/injectedScript.ts b/packages/playwright-core/src/server/injected/injectedScript.ts index ca1b5c7fad..2793eec3e1 100644 --- a/packages/playwright-core/src/server/injected/injectedScript.ts +++ b/packages/playwright-core/src/server/injected/injectedScript.ts @@ -1018,10 +1018,10 @@ export class InjectedScript { preview: this.previewNode(m), selector: this.generateSelector(m), })); - const lines = infos.map((info, i) => `\n ${i + 1}) ${info.preview} aka page.${asLocator(this._sdkLanguage, info.selector)}`); + const lines = infos.map((info, i) => `\n ${i + 1}) ${info.preview} aka ${asLocator(this._sdkLanguage, info.selector)}`); if (infos.length < matches.length) lines.push('\n ...'); - return this.createStacklessError(`strict mode violation: "${stringifySelector(selector)}" resolved to ${matches.length} elements:${lines.join('')}\n`); + return this.createStacklessError(`strict mode violation: ${asLocator(this._sdkLanguage, stringifySelector(selector))} resolved to ${matches.length} elements:${lines.join('')}\n`); } createStacklessError(message: string): Error { diff --git a/tests/library/inspector/pause.spec.ts b/tests/library/inspector/pause.spec.ts index 4e2c65ddb5..63694cb15f 100644 --- a/tests/library/inspector/pause.spec.ts +++ b/tests/library/inspector/pause.spec.ts @@ -296,8 +296,8 @@ it.describe('pause', () => { expect(await sanitizeLog(recorderPage)).toEqual([ 'page.pause- XXms', 'page.getByRole(\'button\').isChecked()- XXms', - 'waiting for \"getByRole(\'button\')"', - 'selector resolved to ', + 'waiting for getByRole(\'button\')', + 'locator resolved to ', 'error: Error: Not a checkbox or radio button', ]); const error = await scriptPromise; diff --git a/tests/page/expect-boolean.spec.ts b/tests/page/expect-boolean.spec.ts index 01968a5cde..92e1dfe776 100644 --- a/tests/page/expect-boolean.spec.ts +++ b/tests/page/expect-boolean.spec.ts @@ -59,7 +59,7 @@ test.describe('toBeChecked', () => { const locator = page.locator('input'); const error = await expect(locator).not.toBeChecked({ timeout: 1000 }).catch(e => e); expect(error.message).toContain(`expect.toBeChecked with timeout 1000ms`); - expect(error.message).toContain(`selector resolved to `); + expect(error.message).toContain(`locator resolved to `); }); test('fail with checked:false', async ({ page }) => { @@ -74,7 +74,7 @@ test.describe('toBeChecked', () => { const locator2 = page.locator('input2'); const error = await expect(locator2).not.toBeChecked({ timeout: 1000 }).catch(e => e); expect(error.message).toContain(`expect.toBeChecked with timeout 1000ms`); - expect(error.message).toContain('waiting for "locator(\'input2\')"'); + expect(error.message).toContain('waiting for locator(\'input2\')'); }); test('with role', async ({ page }) => { @@ -143,7 +143,7 @@ test.describe('toBeEnabled', () => { await page.setContent(''); const locator = page.locator('button'); const error = await expect(locator).toBeEnabled({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain(`selector resolved to `); + expect(error.message).toContain(`locator resolved to `); }); test('eventually', async ({ page }) => { @@ -272,14 +272,14 @@ test.describe('toBeVisible', () => { await page.setContent(''); const locator = page.locator('button'); const error = await expect(locator).toBeVisible({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain(`selector resolved to `); + expect(error.message).toContain(`locator resolved to `); }); test('fail with not', async ({ page }) => { await page.setContent(''); const locator = page.locator('input'); const error = await expect(locator).not.toBeVisible({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain(`selector resolved to `); + expect(error.message).toContain(`locator resolved to `); }); }); @@ -324,14 +324,14 @@ test.describe('toBeHidden', () => { await page.setContent(''); const locator = page.locator('input'); const error = await expect(locator).toBeHidden({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain(`selector resolved to `); + expect(error.message).toContain(`locator resolved to `); }); test('fail with not', async ({ page }) => { await page.setContent(''); const locator = page.locator('button'); const error = await expect(locator).not.toBeHidden({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain(`selector resolved to `); + expect(error.message).toContain(`locator resolved to `); }); test('fail with not when nothing matching', async ({ page }) => { diff --git a/tests/page/expect-to-have-text.spec.ts b/tests/page/expect-to-have-text.spec.ts index ffca1c3fcf..9b83b65235 100644 --- a/tests/page/expect-to-have-text.spec.ts +++ b/tests/page/expect-to-have-text.spec.ts @@ -152,7 +152,7 @@ test.describe('not.toHaveText', () => { const error = await expect(page.locator('span')).not.toHaveText('hello', { timeout: 1000 }).catch(e => e); expect(stripAnsi(error.message)).toContain('Expected string: not "hello"'); expect(stripAnsi(error.message)).toContain('Received string: ""'); - expect(stripAnsi(error.message)).toContain('waiting for "locator(\'span\')"'); + expect(stripAnsi(error.message)).toContain('waiting for locator(\'span\')'); }); }); @@ -217,15 +217,15 @@ test.describe('toHaveText with array', () => { const error = await expect(locator).toHaveText(['Text 1', /Text \d/, 'Extra'], { timeout: 1000 }).catch(e => e); expect(stripAnsi(error.message)).toContain('- "Extra"'); expect(error.message).toContain('expect.toHaveText with timeout 1000ms'); - expect(error.message).toContain('waiting for "locator(\'div\')"'); - expect(error.message).toContain('selector resolved to 2 elements'); + expect(error.message).toContain('waiting for locator(\'div\')'); + expect(error.message).toContain('locator resolved to 2 elements'); }); test('fail on repeating array matchers', async ({ page }) => { await page.setContent('
KekFoo
'); const locator = page.locator('div'); const error = await expect(locator).toContainText(['KekFoo', 'KekFoo', 'KekFoo'], { timeout: 1000 }).catch(e => e); - expect(error.message).toContain('selector resolved to 1 element'); + expect(error.message).toContain('locator resolved to 1 element'); }); }); diff --git a/tests/page/locator-convenience.spec.ts b/tests/page/locator-convenience.spec.ts index 31966b4b93..de4b9f90e6 100644 --- a/tests/page/locator-convenience.spec.ts +++ b/tests/page/locator-convenience.spec.ts @@ -85,7 +85,7 @@ it('innerText should produce log', async ({ page, server }) => { await page.setContent(`
Hello
`); const locator = page.locator('span'); const error = await locator.innerText({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain('waiting for "locator(\'span\')"'); + expect(error.message).toContain('waiting for locator(\'span\')'); }); it('textContent should work', async ({ page, server }) => { diff --git a/tests/page/locator-frame.spec.ts b/tests/page/locator-frame.spec.ts index f2f94d766e..06b19770c7 100644 --- a/tests/page/locator-frame.spec.ts +++ b/tests/page/locator-frame.spec.ts @@ -98,7 +98,7 @@ it('should work for $ and $$', async ({ page, server }) => { it('should wait for frame', async ({ page, server }) => { await page.goto(server.EMPTY_PAGE); const error = await page.frameLocator('iframe').locator('span').click({ timeout: 1000 }).catch(e => e); - expect(error.message).toContain('waiting for frame "iframe"'); + expect(error.message).toContain('waiting for frameLocator(\'iframe\')'); }); it('should wait for frame 2', async ({ page, server }) => { @@ -225,7 +225,7 @@ it('locator.frameLocator should throw on ambiguity', async ({ page, server }) => await page.goto(server.EMPTY_PAGE); const button = page.locator('body').frameLocator('iframe').locator('button'); const error = await button.waitFor().catch(e => e); - expect(error.message).toContain('Error: strict mode violation: "body >> iframe" resolved to 3 elements'); + expect(error.message).toContain(`Error: strict mode violation: locator('body').locator('iframe') resolved to 3 elements`); }); it('locator.frameLocator should not throw on first/last/nth', async ({ page, server }) => { diff --git a/tests/page/page-strict.spec.ts b/tests/page/page-strict.spec.ts index 19cca03f50..90ccc3c558 100644 --- a/tests/page/page-strict.spec.ts +++ b/tests/page/page-strict.spec.ts @@ -20,8 +20,8 @@ it('should fail page.textContent in strict mode', async ({ page }) => { await page.setContent(`span1
target
`); const error = await page.textContent('span', { strict: true }).catch(e => e); expect(error.message).toContain('strict mode violation'); - expect(error.message).toContain(`1) span1 aka page.getByText('span1')`); - expect(error.message).toContain(`2) target aka page.getByText('target')`); + expect(error.message).toContain(`1) span1 aka getByText('span1')`); + expect(error.message).toContain(`2) target aka getByText('target')`); }); it('should fail page.getAttribute in strict mode', async ({ page }) => { @@ -34,8 +34,8 @@ it('should fail page.fill in strict mode', async ({ page }) => { await page.setContent(`
`); const error = await page.fill('input', 'text', { strict: true }).catch(e => e); expect(error.message).toContain('strict mode violation'); - expect(error.message).toContain(`1) aka page.locator('input').first()`); - expect(error.message).toContain(`2) aka page.locator('div input')`); + expect(error.message).toContain(`1) aka locator('input').first()`); + expect(error.message).toContain(`2) aka locator('div input')`); }); it('should fail page.$ in strict mode', async ({ page }) => { @@ -54,8 +54,8 @@ it('should fail page.dispatchEvent in strict mode', async ({ page }) => { await page.setContent(`
`); const error = await page.dispatchEvent('span', 'click', {}, { strict: true }).catch(e => e); expect(error.message).toContain('strict mode violation'); - expect(error.message).toContain(`1) aka page.locator('span').first()`); - expect(error.message).toContain(`2) aka page.locator('div span')`); + expect(error.message).toContain(`1) aka locator('span').first()`); + expect(error.message).toContain(`2) aka locator('div span')`); }); it('should properly format :nth-child() in strict mode message', async ({ page }) => { diff --git a/tests/page/page-wait-for-selector-1.spec.ts b/tests/page/page-wait-for-selector-1.spec.ts index 3476da8e87..59f2d963c9 100644 --- a/tests/page/page-wait-for-selector-1.spec.ts +++ b/tests/page/page-wait-for-selector-1.spec.ts @@ -81,8 +81,7 @@ it('elementHandle.waitForSelector should throw on navigation', async ({ page, se await page.evaluate(() => 1); await page.goto(server.EMPTY_PAGE); const error = await promise; - expect(error.message).toContain('Error: frame navigated while waiting for'); - expect(error.message).toContain('"locator(\'span\')"'); + expect(error.message).toContain('Error: frame navigated while waiting for locator(\'span\')'); }); it('should work with removed MutationObserver', async ({ page, server }) => { @@ -134,10 +133,10 @@ it('should report logs while waiting for visible', async ({ page, server }) => { const error = await watchdog.catch(e => e); expect(error.message).toContain(`frame.waitForSelector: Timeout 5000ms exceeded.`); - expect(error.message).toContain(`waiting for "locator(\'div\')" to be visible`); - expect(error.message).toContain(`selector resolved to hidden
`); + expect(error.message).toContain(`waiting for locator(\'div\') to be visible`); + expect(error.message).toContain(`locator resolved to hidden
`); }); it('should report logs while waiting for hidden', async ({ page, server }) => { @@ -165,9 +164,9 @@ it('should report logs while waiting for hidden', async ({ page, server }) => { const error = await watchdog.catch(e => e); expect(error.message).toContain(`frame.waitForSelector: Timeout 5000ms exceeded.`); - expect(error.message).toContain(`waiting for "locator(\'div\')" to be hidden`); - expect(error.message).toContain(`selector resolved to visible
hello
`); - expect(error.message).toContain(`selector resolved to visible
hello
`); + expect(error.message).toContain(`waiting for locator(\'div\') to be hidden`); + expect(error.message).toContain(`locator resolved to visible
hello
`); + expect(error.message).toContain(`locator resolved to visible
hello
`); }); it('should report logs when the selector resolves to multiple elements', async ({ page, server }) => { @@ -183,7 +182,7 @@ it('should report logs when the selector resolves to multiple elements', async ( const error = await page.click('text=Reset', { timeout: 1000 }).catch(e => e); - expect(error.toString()).toContain('selector resolved to 2 elements. Proceeding with the first one.'); + expect(error.toString()).toContain('locator resolved to 2 elements. Proceeding with the first one.'); }); it('should resolve promise when node is added in shadow dom', async ({ page, server }) => { diff --git a/tests/page/page-wait-for-selector-2.spec.ts b/tests/page/page-wait-for-selector-2.spec.ts index 33f2f83691..5ad57107bb 100644 --- a/tests/page/page-wait-for-selector-2.spec.ts +++ b/tests/page/page-wait-for-selector-2.spec.ts @@ -131,7 +131,7 @@ it('should respect timeout', async ({ page, playwright }) => { await page.waitForSelector('div', { timeout: 3000, state: 'attached' }).catch(e => error = e); expect(error).toBeTruthy(); expect(error.message).toContain('page.waitForSelector: Timeout 3000ms exceeded'); - expect(error.message).toContain('waiting for "locator(\'div\')"'); + expect(error.message).toContain('waiting for locator(\'div\')'); expect(error).toBeInstanceOf(playwright.errors.TimeoutError); }); @@ -141,7 +141,7 @@ it('should have an error message specifically for awaiting an element to be hidd await page.waitForSelector('div', { state: 'hidden', timeout: 1000 }).catch(e => error = e); expect(error).toBeTruthy(); expect(error.message).toContain('page.waitForSelector: Timeout 1000ms exceeded'); - expect(error.message).toContain('waiting for "locator(\'div\')" to be hidden'); + expect(error.message).toContain('waiting for locator(\'div\') to be hidden'); }); it('should respond to node attribute mutation', async ({ page, server }) => { @@ -233,7 +233,7 @@ it('should respect timeout xpath', async ({ page, playwright }) => { await page.waitForSelector('//div', { state: 'attached', timeout: 3000 }).catch(e => error = e); expect(error).toBeTruthy(); expect(error.message).toContain('page.waitForSelector: Timeout 3000ms exceeded'); - expect(error.message).toContain('waiting for "locator(\'xpath=//div\')"'); + expect(error.message).toContain('waiting for locator(\'xpath=//div\')'); expect(error).toBeInstanceOf(playwright.errors.TimeoutError); }); @@ -326,6 +326,5 @@ it('should fail when navigating while on handle', async ({ page, mode, server }) const body = await page.waitForSelector('body'); const error = await body.waitForSelector('div', { __testHookBeforeAdoptNode } as any).catch(e => e); - expect(error.message).toContain('Error: frame navigated while waiting for'); - expect(error.message).toContain('"locator(\'div\')"'); + expect(error.message).toContain('Error: frame navigated while waiting for locator(\'div\')'); }); diff --git a/tests/playwright-test/expect.spec.ts b/tests/playwright-test/expect.spec.ts index 583a63a25f..db87fae5bf 100644 --- a/tests/playwright-test/expect.spec.ts +++ b/tests/playwright-test/expect.spec.ts @@ -507,7 +507,7 @@ test('should print pending operations for toHaveText', async ({ runInlineTest }) expect(output).toContain('Error: expect(received).toHaveText(expected)'); expect(output).toContain('Expected string: "Text"'); expect(output).toContain('Received string: ""'); - expect(output).toContain('waiting for "locator(\'no-such-thing\')"'); + expect(output).toContain('waiting for locator(\'no-such-thing\')'); }); test('should print expected/received on Ctrl+C', async ({ runInlineTest }) => { diff --git a/tests/playwright-test/playwright.spec.ts b/tests/playwright-test/playwright.spec.ts index 831eb58959..daa856f51a 100644 --- a/tests/playwright-test/playwright.spec.ts +++ b/tests/playwright-test/playwright.spec.ts @@ -366,7 +366,7 @@ test('should report error on timeout with shared page', async ({ runInlineTest } expect(result.exitCode).toBe(1); expect(result.passed).toBe(1); expect(result.failed).toBe(1); - expect(result.output).toContain('waiting for "getByText(\'Missing\')"'); + expect(result.output).toContain('waiting for getByText(\'Missing\')'); expect(stripAnsi(result.output)).toContain(`14 | await page.getByText('Missing').click();`); }); diff --git a/tests/playwright-test/reporter.spec.ts b/tests/playwright-test/reporter.spec.ts index 91f855fa99..b424923368 100644 --- a/tests/playwright-test/reporter.spec.ts +++ b/tests/playwright-test/reporter.spec.ts @@ -394,7 +394,7 @@ test('should report api step failure', async ({ runInlineTest }) => { `%% begin {\"title\":\"page.setContent\",\"category\":\"pw:api\"}`, `%% end {\"title\":\"page.setContent\",\"category\":\"pw:api\"}`, `%% begin {\"title\":\"page.click(input)\",\"category\":\"pw:api\"}`, - `%% end {\"title\":\"page.click(input)\",\"category\":\"pw:api\",\"error\":{\"message\":\"page.click: Timeout 1ms exceeded.\\n=========================== logs ===========================\\nwaiting for \\\"locator('input')\\\"\\n============================================================\",\"stack\":\"\"}}`, + `%% end {\"title\":\"page.click(input)\",\"category\":\"pw:api\",\"error\":{\"message\":\"page.click: Timeout 1ms exceeded.\\n=========================== logs ===========================\\nwaiting for locator('input')\\n============================================================\",\"stack\":\"\"}}`, `%% begin {\"title\":\"After Hooks\",\"category\":\"hook\"}`, `%% begin {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, `%% end {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`,