fix(console-api): locator filter with hasText (#29563)

Relates https://github.com/microsoft/playwright/issues/29546
This commit is contained in:
Max Schmitt 2024-02-20 17:35:11 +01:00 committed by GitHub
parent 023ef97c49
commit 84fefdaac6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 8 deletions

View File

@ -22,23 +22,22 @@ import type { Language } from '../../utils/isomorphic/locatorGenerators';
import type { InjectedScript } from './injectedScript';
const selectorSymbol = Symbol('selector');
const injectedScriptSymbol = Symbol('injectedScript');
class Locator {
[selectorSymbol]: string;
element: Element | undefined;
elements: Element[] | undefined;
constructor(injectedScript: InjectedScript, selector: string, options?: { hasText?: string | RegExp, hasNotText?: string | RegExp, has?: Locator, hasNot?: Locator }) {
(this as any)[selectorSymbol] = selector;
(this as any)[injectedScriptSymbol] = injectedScript;
if (options?.hasText)
selector += ` >> internal:has-text=${escapeForTextSelector(options.hasText, false)}`;
if (options?.hasNotText)
selector += ` >> internal:has-not-text=${escapeForTextSelector(options.hasNotText, false)}`;
if (options?.has)
selector += ` >> internal:has=` + JSON.stringify((options.has as any)[selectorSymbol]);
selector += ` >> internal:has=` + JSON.stringify(options.has[selectorSymbol]);
if (options?.hasNot)
selector += ` >> internal:has-not=` + JSON.stringify((options.hasNot as any)[selectorSymbol]);
selector += ` >> internal:has-not=` + JSON.stringify(options.hasNot[selectorSymbol]);
this[selectorSymbol] = selector;
if (selector) {
const parsed = injectedScript.parseSelector(selector);
this.element = injectedScript.querySelector(parsed, injectedScript.document, false);
@ -60,8 +59,8 @@ class Locator {
self.first = (): Locator => self.locator('nth=0');
self.last = (): Locator => self.locator('nth=-1');
self.nth = (index: number): Locator => self.locator(`nth=${index}`);
self.and = (locator: Locator): Locator => new Locator(injectedScript, selectorBase + ` >> internal:and=` + JSON.stringify((locator as any)[selectorSymbol]));
self.or = (locator: Locator): Locator => new Locator(injectedScript, selectorBase + ` >> internal:or=` + JSON.stringify((locator as any)[selectorSymbol]));
self.and = (locator: Locator): Locator => new Locator(injectedScript, selectorBase + ` >> internal:and=` + JSON.stringify(locator[selectorSymbol]));
self.or = (locator: Locator): Locator => new Locator(injectedScript, selectorBase + ` >> internal:or=` + JSON.stringify(locator[selectorSymbol]));
}
}

View File

@ -64,9 +64,14 @@ it('should support playwright.locator.values', async ({ page }) => {
});
it('should support playwright.locator({ has })', async ({ page }) => {
await page.setContent('<div>Hi</div><div><span>Hello</span></div>');
await page.setContent(`
<div>Hi</div>
<div><span>Hello</span></div>
<div><span>dont match</span></div>
`);
expect(await page.evaluate(`playwright.locator('div', { has: playwright.locator('span') }).element.innerHTML`)).toContain('Hello');
expect(await page.evaluate(`playwright.locator('div', { has: playwright.locator('text=Hello') }).element.innerHTML`)).toContain('span');
expect(await page.evaluate(`playwright.locator('div', { has: playwright.locator('span', { hasText: 'Hello' }) }).elements.length`)).toBe(1);
});
it('should support playwright.locator({ hasNot })', async ({ page }) => {