diff --git a/packages/playwright-core/src/server/injected/selectorGenerator.ts b/packages/playwright-core/src/server/injected/selectorGenerator.ts index 06ba6c13c0..93e2526213 100644 --- a/packages/playwright-core/src/server/injected/selectorGenerator.ts +++ b/packages/playwright-core/src/server/injected/selectorGenerator.ts @@ -224,7 +224,7 @@ function cssFallback(injectedScript: InjectedScript, targetElement: Element, str const path = tokens.slice(); if (prefix) path.unshift(prefix); - const selector = path.join(' '); + const selector = path.join(' > '); const parsedSelector = injectedScript.parseSelector(selector); const node = injectedScript.querySelector(parsedSelector, targetElement.ownerDocument, false); return node === targetElement ? selector : undefined; diff --git a/tests/library/selector-generator.spec.ts b/tests/library/selector-generator.spec.ts index 95b7cae875..cef94b4d24 100644 --- a/tests/library/selector-generator.spec.ts +++ b/tests/library/selector-generator.spec.ts @@ -191,7 +191,28 @@ it.describe('selector generator', () => { `); - expect(await generate(page, 'c[mark="1"]')).toBe('b:nth-child(2) c'); + expect(await generate(page, 'c[mark="1"]')).toBe('b:nth-child(2) > c'); + }); + + it('should properly join child selectors under nested ordinals', async ({ page }) => { + await page.setContent(` + + + +
+ + +
+
+ +
+ +
+
+
+ + `); + expect(await generate(page, 'c[mark="1"]')).toBe('b:nth-child(2) > div > c'); }); it('should not use input[value]', async ({ page }) => { diff --git a/tests/page/page-strict.spec.ts b/tests/page/page-strict.spec.ts index fc64cc1914..9a90cdc8fd 100644 --- a/tests/page/page-strict.spec.ts +++ b/tests/page/page-strict.spec.ts @@ -57,3 +57,30 @@ it('should fail page.dispatchEvent in strict mode', async ({ page }) => { expect(error.message).toContain('1) aka playwright.$("span >> nth=0")'); expect(error.message).toContain('2) aka playwright.$("div span")'); }); + +it('should properly format :nth-child() in strict mode message', async ({ page }) => { + await page.setContent(` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `); + const error = await page.locator('.foo').hover().catch(e => e); + console.log(error.message); + expect(error.message).toContain('strict mode violation'); + // Second div has body > div:nth-child(2) > div:nth-child(2) selector which would be ambiguous + // if '>' were ' '. + expect(error.message).toContain('body > div:nth-child(2) > div:nth-child(2)'); +});