fix: display testId as regex in trace-viewer (#23361)
Fixes https://github.com/microsoft/playwright/issues/23298
This commit is contained in:
parent
fda57978e8
commit
9e75b95153
|
|
@ -286,7 +286,7 @@ export class JavaScriptLocatorFactory implements LocatorFactory {
|
||||||
case 'or':
|
case 'or':
|
||||||
return `or(${body})`;
|
return `or(${body})`;
|
||||||
case 'test-id':
|
case 'test-id':
|
||||||
return `getByTestId(${this.quote(body as string)})`;
|
return `getByTestId(${this.toTestIdValue(body)})`;
|
||||||
case 'text':
|
case 'text':
|
||||||
return this.toCallWithExact('getByText', body, !!options.exact);
|
return this.toCallWithExact('getByText', body, !!options.exact);
|
||||||
case 'alt':
|
case 'alt':
|
||||||
|
|
@ -318,6 +318,12 @@ export class JavaScriptLocatorFactory implements LocatorFactory {
|
||||||
return this.quote(body);
|
return this.quote(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toTestIdValue(value: string | RegExp): string {
|
||||||
|
if (isRegExp(value))
|
||||||
|
return String(value);
|
||||||
|
return this.quote(value);
|
||||||
|
}
|
||||||
|
|
||||||
private quote(text: string) {
|
private quote(text: string) {
|
||||||
return escapeWithQuotes(text, '\'');
|
return escapeWithQuotes(text, '\'');
|
||||||
}
|
}
|
||||||
|
|
@ -370,7 +376,7 @@ export class PythonLocatorFactory implements LocatorFactory {
|
||||||
case 'or':
|
case 'or':
|
||||||
return `or_(${body})`;
|
return `or_(${body})`;
|
||||||
case 'test-id':
|
case 'test-id':
|
||||||
return `get_by_test_id(${this.quote(body as string)})`;
|
return `get_by_test_id(${this.toTestIdValue(body)})`;
|
||||||
case 'text':
|
case 'text':
|
||||||
return this.toCallWithExact('get_by_text', body, !!options.exact);
|
return this.toCallWithExact('get_by_text', body, !!options.exact);
|
||||||
case 'alt':
|
case 'alt':
|
||||||
|
|
@ -409,6 +415,12 @@ export class PythonLocatorFactory implements LocatorFactory {
|
||||||
return `${this.quote(body)}`;
|
return `${this.quote(body)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toTestIdValue(value: string | RegExp) {
|
||||||
|
if (isRegExp(value))
|
||||||
|
return this.regexToString(value);
|
||||||
|
return this.quote(value);
|
||||||
|
}
|
||||||
|
|
||||||
private quote(text: string) {
|
private quote(text: string) {
|
||||||
return escapeWithQuotes(text, '\"');
|
return escapeWithQuotes(text, '\"');
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +475,7 @@ export class JavaLocatorFactory implements LocatorFactory {
|
||||||
case 'or':
|
case 'or':
|
||||||
return `or(${body})`;
|
return `or(${body})`;
|
||||||
case 'test-id':
|
case 'test-id':
|
||||||
return `getByTestId(${this.quote(body as string)})`;
|
return `getByTestId(${this.toTestIdValue(body)})`;
|
||||||
case 'text':
|
case 'text':
|
||||||
return this.toCallWithExact(clazz, 'getByText', body, !!options.exact);
|
return this.toCallWithExact(clazz, 'getByText', body, !!options.exact);
|
||||||
case 'alt':
|
case 'alt':
|
||||||
|
|
@ -502,6 +514,12 @@ export class JavaLocatorFactory implements LocatorFactory {
|
||||||
return this.quote(body);
|
return this.quote(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toTestIdValue(value: string | RegExp) {
|
||||||
|
if (isRegExp(value))
|
||||||
|
return this.regexToString(value);
|
||||||
|
return this.quote(value);
|
||||||
|
}
|
||||||
|
|
||||||
private quote(text: string) {
|
private quote(text: string) {
|
||||||
return escapeWithQuotes(text, '\"');
|
return escapeWithQuotes(text, '\"');
|
||||||
}
|
}
|
||||||
|
|
@ -550,7 +568,7 @@ export class CSharpLocatorFactory implements LocatorFactory {
|
||||||
case 'or':
|
case 'or':
|
||||||
return `Or(${body})`;
|
return `Or(${body})`;
|
||||||
case 'test-id':
|
case 'test-id':
|
||||||
return `GetByTestId(${this.quote(body as string)})`;
|
return `GetByTestId(${this.toTestIdValue(body)})`;
|
||||||
case 'text':
|
case 'text':
|
||||||
return this.toCallWithExact('GetByText', body, !!options.exact);
|
return this.toCallWithExact('GetByText', body, !!options.exact);
|
||||||
case 'alt':
|
case 'alt':
|
||||||
|
|
@ -589,6 +607,12 @@ export class CSharpLocatorFactory implements LocatorFactory {
|
||||||
return `HasText = ${this.quote(body)}`;
|
return `HasText = ${this.quote(body)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private toTestIdValue(value: string | RegExp) {
|
||||||
|
if (isRegExp(value))
|
||||||
|
return this.regexToString(value);
|
||||||
|
return this.quote(value);
|
||||||
|
}
|
||||||
|
|
||||||
private toHasNotText(body: string | RegExp) {
|
private toHasNotText(body: string | RegExp) {
|
||||||
if (isRegExp(body))
|
if (isRegExp(body))
|
||||||
return `HasNotTextRegex = ${this.regexToString(body)}`;
|
return `HasNotTextRegex = ${this.regexToString(body)}`;
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ function transform(template: string, params: TemplateParams, testIdAttributeName
|
||||||
.replace(/getbyrole\(([^)]+)\)/g, 'internal:role=$1')
|
.replace(/getbyrole\(([^)]+)\)/g, 'internal:role=$1')
|
||||||
.replace(/getbytext\(([^)]+)\)/g, 'internal:text=$1')
|
.replace(/getbytext\(([^)]+)\)/g, 'internal:text=$1')
|
||||||
.replace(/getbylabel\(([^)]+)\)/g, 'internal:label=$1')
|
.replace(/getbylabel\(([^)]+)\)/g, 'internal:label=$1')
|
||||||
.replace(/getbytestid\(([^)]+)\)/g, `internal:testid=[${testIdAttributeName}=$1s]`)
|
.replace(/getbytestid\(([^)]+)\)/g, `internal:testid=[${testIdAttributeName}=$1]`)
|
||||||
.replace(/getby(placeholder|alt|title)(?:text)?\(([^)]+)\)/g, 'internal:attr=[$1=$2]')
|
.replace(/getby(placeholder|alt|title)(?:text)?\(([^)]+)\)/g, 'internal:attr=[$1=$2]')
|
||||||
.replace(/first(\(\))?/g, 'nth=0')
|
.replace(/first(\(\))?/g, 'nth=0')
|
||||||
.replace(/last(\(\))?/g, 'nth=-1')
|
.replace(/last(\(\))?/g, 'nth=-1')
|
||||||
|
|
@ -200,7 +200,9 @@ function transform(template: string, params: TemplateParams, testIdAttributeName
|
||||||
const param = params[+ordinal - 1];
|
const param = params[+ordinal - 1];
|
||||||
if (t.startsWith('internal:has=') || t.startsWith('internal:has-not='))
|
if (t.startsWith('internal:has=') || t.startsWith('internal:has-not='))
|
||||||
return param.text;
|
return param.text;
|
||||||
if (t.startsWith('internal:attr') || t.startsWith('internal:testid') || t.startsWith('internal:role'))
|
if (t.startsWith('internal:testid'))
|
||||||
|
return escapeForAttributeSelector(param.text, true);
|
||||||
|
if (t.startsWith('internal:attr') || t.startsWith('internal:role'))
|
||||||
return escapeForAttributeSelector(param.text, suffix === 's');
|
return escapeForAttributeSelector(param.text, suffix === 's');
|
||||||
return escapeForTextSelector(param.text, suffix === 's');
|
return escapeForTextSelector(param.text, suffix === 's');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,13 @@ it('reverse engineer locators', async ({ page }) => {
|
||||||
csharp: 'GetByTestId("He\\"llo")'
|
csharp: 'GetByTestId("He\\"llo")'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expect.soft(generate(page.getByTestId(/He"llo/))).toEqual({
|
||||||
|
javascript: 'getByTestId(/He"llo/)',
|
||||||
|
python: 'get_by_test_id(re.compile(r"He\\"llo"))',
|
||||||
|
java: 'getByTestId(Pattern.compile("He\\"llo"))',
|
||||||
|
csharp: 'GetByTestId(new Regex("He\\"llo"))'
|
||||||
|
});
|
||||||
|
|
||||||
expect.soft(generate(page.getByText('Hello', { exact: true }))).toEqual({
|
expect.soft(generate(page.getByText('Hello', { exact: true }))).toEqual({
|
||||||
csharp: 'GetByText("Hello", new() { Exact = true })',
|
csharp: 'GetByText("Hello", new() { Exact = true })',
|
||||||
java: 'getByText("Hello", new Page.GetByTextOptions().setExact(true))',
|
java: 'getByText("Hello", new Page.GetByTextOptions().setExact(true))',
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ test.beforeAll(async function recordTrace({ browser, browserName, browserType, s
|
||||||
await page.goto('data:text/html,<html>Hello world</html>');
|
await page.goto('data:text/html,<html>Hello world</html>');
|
||||||
await page.setContent('<button>Click</button>');
|
await page.setContent('<button>Click</button>');
|
||||||
await expect(page.locator('button')).toHaveText('Click');
|
await expect(page.locator('button')).toHaveText('Click');
|
||||||
|
await expect(page.getByTestId('amazing-btn')).toBeHidden();
|
||||||
|
await expect(page.getByTestId(/amazing-btn-regex/)).toBeHidden();
|
||||||
await page.evaluate(({ a }) => {
|
await page.evaluate(({ a }) => {
|
||||||
console.log('Info');
|
console.log('Info');
|
||||||
console.warn('Warning');
|
console.warn('Warning');
|
||||||
|
|
@ -102,6 +104,8 @@ test('should open simple trace viewer', async ({ showTraceViewer }) => {
|
||||||
/page.gotodata:text\/html,<html>Hello world<\/html>/,
|
/page.gotodata:text\/html,<html>Hello world<\/html>/,
|
||||||
/page.setContent/,
|
/page.setContent/,
|
||||||
/expect.toHaveTextlocator\('button'\)/,
|
/expect.toHaveTextlocator\('button'\)/,
|
||||||
|
/expect.toBeHiddengetByTestId\('amazing-btn'\)/,
|
||||||
|
/expect.toBeHiddengetByTestId\(\/amazing-btn-regex\/\)/,
|
||||||
/page.evaluate/,
|
/page.evaluate/,
|
||||||
/page.evaluate/,
|
/page.evaluate/,
|
||||||
/locator.clickgetByText\('Click'\)/,
|
/locator.clickgetByText\('Click'\)/,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue