diff --git a/docs/src/api/params.md b/docs/src/api/params.md index 3e0c71cd89..d20ce3a651 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -1087,7 +1087,7 @@ When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, ## locator-get-by-test-id-test-id * since: v1.27 -- `testId` <[string]> +- `testId` <[string]|[RegExp]> Id to locate the element by. diff --git a/packages/playwright-core/src/client/frame.ts b/packages/playwright-core/src/client/frame.ts index 69ea7e477d..a539828d3e 100644 --- a/packages/playwright-core/src/client/frame.ts +++ b/packages/playwright-core/src/client/frame.ts @@ -309,7 +309,7 @@ export class Frame extends ChannelOwner implements api.Fr return new Locator(this, selector, options); } - getByTestId(testId: string): Locator { + getByTestId(testId: string | RegExp): Locator { return this.locator(getByTestIdSelector(testIdAttributeName(), testId)); } diff --git a/packages/playwright-core/src/client/locator.ts b/packages/playwright-core/src/client/locator.ts index e13a3f7d71..999b3961ad 100644 --- a/packages/playwright-core/src/client/locator.ts +++ b/packages/playwright-core/src/client/locator.ts @@ -133,7 +133,7 @@ export class Locator implements api.Locator { return new Locator(this._frame, this._selector + ' >> ' + selector, options); } - getByTestId(testId: string): Locator { + getByTestId(testId: string | RegExp): Locator { return this.locator(getByTestIdSelector(testIdAttributeName(), testId)); } @@ -339,7 +339,7 @@ export class FrameLocator implements api.FrameLocator { return new Locator(this._frame, this._frameSelector + ' >> internal:control=enter-frame >> ' + selector, options); } - getByTestId(testId: string): Locator { + getByTestId(testId: string | RegExp): Locator { return this.locator(getByTestIdSelector(testIdAttributeName(), testId)); } diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index d3eb929dcd..1dd4f79937 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -572,7 +572,7 @@ export class Page extends ChannelOwner implements api.Page return this.mainFrame().locator(selector, options); } - getByTestId(testId: string): Locator { + getByTestId(testId: string | RegExp): Locator { return this.mainFrame().getByTestId(testId); } diff --git a/packages/playwright-core/src/utils/isomorphic/locatorUtils.ts b/packages/playwright-core/src/utils/isomorphic/locatorUtils.ts index 3896713d0d..51b51cc410 100644 --- a/packages/playwright-core/src/utils/isomorphic/locatorUtils.ts +++ b/packages/playwright-core/src/utils/isomorphic/locatorUtils.ts @@ -34,7 +34,9 @@ function getByAttributeTextSelector(attrName: string, text: string | RegExp, opt return `internal:attr=[${attrName}=${escapeForAttributeSelector(text, options?.exact || false)}]`; } -export function getByTestIdSelector(testIdAttributeName: string, testId: string): string { +export function getByTestIdSelector(testIdAttributeName: string, testId: string | RegExp): string { + if (!isString(testId)) + return `internal:testid=[${testIdAttributeName}=${testId}]`; return `internal:testid=[${testIdAttributeName}=${escapeForAttributeSelector(testId, true)}]`; } diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index a88b5152d4..023ed057bc 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -2597,7 +2597,7 @@ export interface Page { * * @param testId Id to locate the element by. */ - getByTestId(testId: string): Locator; + getByTestId(testId: string|RegExp): Locator; /** * Allows locating elements that contain given text. Consider the following DOM structure: @@ -5849,7 +5849,7 @@ export interface Frame { * * @param testId Id to locate the element by. */ - getByTestId(testId: string): Locator; + getByTestId(testId: string|RegExp): Locator; /** * Allows locating elements that contain given text. Consider the following DOM structure: @@ -10546,7 +10546,7 @@ export interface Locator { * * @param testId Id to locate the element by. */ - getByTestId(testId: string): Locator; + getByTestId(testId: string|RegExp): Locator; /** * Allows locating elements that contain given text. Consider the following DOM structure: @@ -16114,7 +16114,7 @@ export interface FrameLocator { * * @param testId Id to locate the element by. */ - getByTestId(testId: string): Locator; + getByTestId(testId: string|RegExp): Locator; /** * Allows locating elements that contain given text. Consider the following DOM structure: diff --git a/tests/page/selectors-get-by.spec.ts b/tests/page/selectors-get-by.spec.ts index 7aae90c09c..0f310b2390 100644 --- a/tests/page/selectors-get-by.spec.ts +++ b/tests/page/selectors-get-by.spec.ts @@ -36,6 +36,13 @@ it('getByTestId should escape id', async ({ page }) => { await expect(page.getByTestId('He"llo')).toHaveText('Hello world'); }); +it('getByTestId should work for regex', async ({ page }) => { + await page.setContent('
Hello world
'); + await expect(page.getByTestId(/He[l]*o/)).toHaveText('Hello world'); + await expect(page.mainFrame().getByTestId('Hello')).toHaveText('Hello world'); + await expect(page.locator('div').getByTestId('Hello')).toHaveText('Hello world'); +}); + it('getByText should work', async ({ page }) => { await page.setContent(`
yo
ya
\nye
`); expect(await page.getByText('ye').evaluate(e => e.outerHTML)).toContain('>\nye ');