chore: deprecate locator.frameLocator() (#32306)

This commit is contained in:
Pavel Feldman 2024-08-26 10:28:54 -07:00 committed by GitHub
parent 3d9342aa77
commit 4340d153df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 133 additions and 180 deletions

View File

@ -2195,6 +2195,7 @@ A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] ob
## method: Page.frameLocator
* since: v1.17
regular [`Locator`] instead.
- returns: <[FrameLocator]>
When working with iframes, you can create a frame locator that will enter the iframe and allow selecting elements

View File

@ -191,15 +191,9 @@ export class Recorder implements InstrumentationListener {
});
await this._context.exposeBinding('__pw_recorderSetSelector', false, async ({ frame }, selector: string) => {
const selectorPromises: Promise<string | undefined>[] = [];
let currentFrame: Frame | null = frame;
while (currentFrame) {
selectorPromises.push(findFrameSelector(currentFrame));
currentFrame = currentFrame.parentFrame();
}
const fullSelector = (await Promise.all(selectorPromises)).filter(Boolean);
fullSelector.push(selector);
await this._recorderApp?.setSelector(fullSelector.join(' >> internal:control=enter-frame >> '), true);
const selectorChain = await generateFrameSelector(frame);
selectorChain.push(selector);
await this._recorderApp?.setSelector(selectorChain.join(' >> internal:control=enter-frame >> '), true);
});
await this._context.exposeBinding('__pw_recorderSetMode', false, async ({ frame }, mode: Mode) => {
@ -539,45 +533,14 @@ class ContextRecorder extends EventEmitter {
private _describeMainFrame(page: Page): actions.FrameDescription {
return {
pageAlias: this._pageAliases.get(page)!,
isMainFrame: true,
framePath: [],
};
}
private async _describeFrame(frame: Frame): Promise<actions.FrameDescription> {
const page = frame._page;
const pageAlias = this._pageAliases.get(page)!;
const chain: Frame[] = [];
for (let ancestor: Frame | null = frame; ancestor; ancestor = ancestor.parentFrame())
chain.push(ancestor);
chain.reverse();
if (chain.length === 1)
return this._describeMainFrame(page);
const selectorPromises: Promise<string | undefined>[] = [];
for (let i = 0; i < chain.length - 1; i++)
selectorPromises.push(findFrameSelector(chain[i + 1]));
const result = await raceAgainstDeadline(() => Promise.all(selectorPromises), monotonicTime() + 2000);
if (!result.timedOut && result.result.every(selector => !!selector)) {
return {
pageAlias,
isMainFrame: false,
selectorsChain: result.result as string[],
};
}
// Best effort to find a selector for the frame.
const selectorsChain = [];
for (let i = 0; i < chain.length - 1; i++) {
if (chain[i].name())
selectorsChain.push(`iframe[name=${quoteCSSAttributeValue(chain[i].name())}]`);
else
selectorsChain.push(`iframe[src=${quoteCSSAttributeValue(chain[i].url())}]`);
}
return {
pageAlias,
isMainFrame: false,
selectorsChain,
pageAlias: this._pageAliases.get(frame._page)!,
framePath: await generateFrameSelector(frame),
};
}
@ -691,20 +654,41 @@ function isScreenshotCommand(metadata: CallMetadata) {
return metadata.method.toLowerCase().includes('screenshot');
}
async function findFrameSelector(frame: Frame): Promise<string | undefined> {
try {
async function generateFrameSelector(frame: Frame): Promise<string[]> {
const selectorPromises: Promise<string>[] = [];
while (frame) {
const parent = frame.parentFrame();
const frameElement = await frame.frameElement();
if (!frameElement || !parent)
return;
const utility = await parent._utilityContext();
const injected = await utility.injectedScript();
const selector = await injected.evaluate((injected, element) => {
return injected.generateSelectorSimple(element as Element, { testIdAttributeName: '', omitInternalEngines: true });
}, frameElement);
return selector;
} catch (e) {
if (!parent)
break;
selectorPromises.push(generateFrameSelectorInParent(parent, frame));
frame = parent;
}
const result = await Promise.all(selectorPromises);
return result.reverse();
}
async function generateFrameSelectorInParent(parent: Frame, frame: Frame): Promise<string> {
const result = await raceAgainstDeadline(async () => {
try {
const frameElement = await frame.frameElement();
if (!frameElement || !parent)
return;
const utility = await parent._utilityContext();
const injected = await utility.injectedScript();
const selector = await injected.evaluate((injected, element) => {
return injected.generateSelectorSimple(element as Element);
}, frameElement);
return selector;
} catch (e) {
return e.toString();
}
}, monotonicTime() + 2000);
if (!result.timedOut && result.result)
return result.result;
if (frame.name())
return `iframe[name=${quoteCSSAttributeValue(frame.name())}]`;
return `iframe[src=${quoteCSSAttributeValue(frame.url())}]`;
}
async function innerPerformAction(frame: Frame, action: string, params: any, cb: (callMetadata: CallMetadata) => Promise<any>): Promise<boolean> {

View File

@ -146,7 +146,7 @@ export class CodeGenerator extends EventEmitter {
this.addAction({
frame: {
pageAlias,
isMainFrame: true,
framePath: [],
},
committed: true,
action: {

View File

@ -72,14 +72,8 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
return formatter.format();
}
let subject: string;
if (actionInContext.frame.isMainFrame) {
subject = pageAlias;
} else {
const locators = actionInContext.frame.selectorsChain.map(selector => `.FrameLocator(${quote(selector)})`);
subject = `${pageAlias}${locators.join('')}`;
}
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector)}.ContentFrame()`);
const subject = `${pageAlias}${locators.join('')}`;
const signals = toSignalMap(action);
if (signals.dialog) {

View File

@ -63,16 +63,8 @@ export class JavaLanguageGenerator implements LanguageGenerator {
return formatter.format();
}
let subject: string;
let inFrameLocator = false;
if (actionInContext.frame.isMainFrame) {
subject = pageAlias;
} else {
const locators = actionInContext.frame.selectorsChain.map(selector => `.frameLocator(${quote(selector)})`);
subject = `${pageAlias}${locators.join('')}`;
inFrameLocator = true;
}
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector, false)}.contentFrame()`);
const subject = `${pageAlias}${locators.join('')}`;
const signals = toSignalMap(action);
if (signals.dialog) {
@ -82,7 +74,7 @@ export class JavaLanguageGenerator implements LanguageGenerator {
});`);
}
let code = this._generateActionCall(subject, action, inFrameLocator);
let code = this._generateActionCall(subject, action, !!actionInContext.frame.framePath.length);
if (signals.popup) {
code = `Page ${signals.popup.popupAlias} = ${pageAlias}.waitForPopup(() -> {

View File

@ -52,14 +52,8 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {
return formatter.format();
}
let subject: string;
if (actionInContext.frame.isMainFrame) {
subject = pageAlias;
} else {
const locators = actionInContext.frame.selectorsChain.map(selector => `.frameLocator(${quote(selector)})`);
subject = `${pageAlias}${locators.join('')}`;
}
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector)}.contentFrame()`);
const subject = `${pageAlias}${locators.join('')}`;
const signals = toSignalMap(action);
if (signals.dialog) {

View File

@ -59,14 +59,8 @@ export class PythonLanguageGenerator implements LanguageGenerator {
return formatter.format();
}
let subject: string;
if (actionInContext.frame.isMainFrame) {
subject = pageAlias;
} else {
const locators = actionInContext.frame.selectorsChain.map(selector => `.frame_locator(${quote(selector)})`);
subject = `${pageAlias}${locators.join('')}`;
}
const locators = actionInContext.frame.framePath.map(selector => `.${this._asLocator(selector)}.content_frame()`);
const subject = `${pageAlias}${locators.join('')}`;
const signals = toSignalMap(action);
if (signals.dialog)

View File

@ -150,13 +150,7 @@ export type DialogSignal = BaseSignal & {
export type Signal = NavigationSignal | PopupSignal | DownloadSignal | DialogSignal;
type FrameDescriptionMainFrame = {
isMainFrame: true;
export type FrameDescription = {
pageAlias: string;
framePath: string[];
};
type FrameDescriptionChildFrame = {
isMainFrame: false;
selectorsChain: string[];
};
export type FrameDescription = { pageAlias: string } & (FrameDescriptionMainFrame | FrameDescriptionChildFrame);

View File

@ -120,20 +120,20 @@ await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).Nth(1).ClickAsy
frameHello1.click('text=Hello1'),
]);
expect(sources.get('JavaScript')!.text).toContain(`
await page.frameLocator('#frame1').getByText('Hello1').click();`);
expect.soft(sources.get('JavaScript')!.text).toContain(`
await page.locator('#frame1').contentFrame().getByText('Hello1').click();`);
expect(sources.get('Java')!.text).toContain(`
page.frameLocator("#frame1").getByText("Hello1").click();`);
expect.soft(sources.get('Java')!.text).toContain(`
page.locator("#frame1").contentFrame().getByText("Hello1").click();`);
expect(sources.get('Python')!.text).toContain(`
page.frame_locator("#frame1").get_by_text("Hello1").click()`);
expect.soft(sources.get('Python')!.text).toContain(`
page.locator("#frame1").content_frame().get_by_text("Hello1").click()`);
expect(sources.get('Python Async')!.text).toContain(`
await page.frame_locator("#frame1").get_by_text("Hello1").click()`);
expect.soft(sources.get('Python Async')!.text).toContain(`
await page.locator("#frame1").content_frame().get_by_text("Hello1").click()`);
expect(sources.get('C#')!.text).toContain(`
await page.FrameLocator("#frame1").GetByText("Hello1").ClickAsync();`);
expect.soft(sources.get('C#')!.text).toContain(`
await page.Locator("#frame1").ContentFrame().GetByText("Hello1").ClickAsync();`);
[sources] = await Promise.all([
@ -142,19 +142,19 @@ await page.FrameLocator("#frame1").GetByText("Hello1").ClickAsync();`);
]);
expect.soft(sources.get('JavaScript')!.text).toContain(`
await page.frameLocator('#frame1').frameLocator('iframe').getByText('Hello2').click();`);
await page.locator('#frame1').contentFrame().locator('iframe').contentFrame().getByText('Hello2').click();`);
expect.soft(sources.get('Java')!.text).toContain(`
page.frameLocator("#frame1").frameLocator("iframe").getByText("Hello2").click();`);
page.locator("#frame1").contentFrame().locator("iframe").contentFrame().getByText("Hello2").click();`);
expect.soft(sources.get('Python')!.text).toContain(`
page.frame_locator("#frame1").frame_locator("iframe").get_by_text("Hello2").click()`);
page.locator("#frame1").content_frame().locator("iframe").content_frame().get_by_text("Hello2").click()`);
expect.soft(sources.get('Python Async')!.text).toContain(`
await page.frame_locator("#frame1").frame_locator("iframe").get_by_text("Hello2").click()`);
await page.locator("#frame1").content_frame().locator("iframe").content_frame().get_by_text("Hello2").click()`);
expect.soft(sources.get('C#')!.text).toContain(`
await page.FrameLocator("#frame1").FrameLocator("iframe").GetByText("Hello2").ClickAsync();`);
await page.Locator("#frame1").ContentFrame().Locator("iframe").ContentFrame().GetByText("Hello2").ClickAsync();`);
[sources] = await Promise.all([
@ -163,19 +163,19 @@ await page.FrameLocator("#frame1").FrameLocator("iframe").GetByText("Hello2").Cl
]);
expect.soft(sources.get('JavaScript')!.text).toContain(`
await page.frameLocator('#frame1').frameLocator('iframe').frameLocator('iframe[name="one"]').getByText('HelloNameOne').click();`);
await page.locator('#frame1').contentFrame().locator('iframe').contentFrame().locator('iframe[name="one"]').contentFrame().getByText('HelloNameOne').click();`);
expect.soft(sources.get('Java')!.text).toContain(`
page.frameLocator("#frame1").frameLocator("iframe").frameLocator("iframe[name=\\"one\\"]").getByText("HelloNameOne").click();`);
page.locator("#frame1").contentFrame().locator("iframe").contentFrame().locator("iframe[name=\\"one\\"]").contentFrame().getByText("HelloNameOne").click();`);
expect.soft(sources.get('Python')!.text).toContain(`
page.frame_locator("#frame1").frame_locator("iframe").frame_locator("iframe[name=\\"one\\"]").get_by_text("HelloNameOne").click()`);
page.locator("#frame1").content_frame().locator("iframe").content_frame().locator("iframe[name=\\"one\\"]").content_frame().get_by_text("HelloNameOne").click()`);
expect.soft(sources.get('Python Async')!.text).toContain(`
await page.frame_locator("#frame1").frame_locator("iframe").frame_locator("iframe[name=\\"one\\"]").get_by_text("HelloNameOne").click()`);
await page.locator("#frame1").content_frame().locator("iframe").content_frame().locator("iframe[name=\\"one\\"]").content_frame().get_by_text("HelloNameOne").click()`);
expect.soft(sources.get('C#')!.text).toContain(`
await page.FrameLocator("#frame1").FrameLocator("iframe").FrameLocator("iframe[name=\\"one\\"]").GetByText("HelloNameOne").ClickAsync();`);
await page.Locator("#frame1").ContentFrame().Locator("iframe").ContentFrame().Locator("iframe[name=\\"one\\"]").ContentFrame().GetByText("HelloNameOne").ClickAsync();`);
[sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'HelloNameAnonymous'),
@ -183,19 +183,19 @@ await page.FrameLocator("#frame1").FrameLocator("iframe").FrameLocator("iframe[n
]);
expect.soft(sources.get('JavaScript')!.text).toContain(`
await page.frameLocator('#frame1').frameLocator('iframe').frameLocator('iframe >> nth=2').getByText('HelloNameAnonymous').click();`);
await page.locator('#frame1').contentFrame().locator('iframe').contentFrame().locator('iframe').nth(2).contentFrame().getByText('HelloNameAnonymous').click();`);
expect.soft(sources.get('Java')!.text).toContain(`
page.frameLocator("#frame1").frameLocator("iframe").frameLocator("iframe >> nth=2").getByText("HelloNameAnonymous").click();`);
page.locator("#frame1").contentFrame().locator("iframe").contentFrame().locator("iframe").nth(2).contentFrame().getByText("HelloNameAnonymous").click();`);
expect.soft(sources.get('Python')!.text).toContain(`
page.frame_locator("#frame1").frame_locator("iframe").frame_locator("iframe >> nth=2").get_by_text("HelloNameAnonymous").click()`);
page.locator("#frame1").content_frame().locator("iframe").content_frame().locator("iframe").nth(2).content_frame().get_by_text("HelloNameAnonymous").click()`);
expect.soft(sources.get('Python Async')!.text).toContain(`
await page.frame_locator("#frame1").frame_locator("iframe").frame_locator("iframe >> nth=2").get_by_text("HelloNameAnonymous").click()`);
await page.locator("#frame1").content_frame().locator("iframe").content_frame().locator("iframe").nth(2).content_frame().get_by_text("HelloNameAnonymous").click()`);
expect.soft(sources.get('C#')!.text).toContain(`
await page.FrameLocator("#frame1").FrameLocator("iframe").FrameLocator("iframe >> nth=2").GetByText("HelloNameAnonymous").ClickAsync();`);
await page.Locator("#frame1").ContentFrame().Locator("iframe").ContentFrame().Locator("iframe").Nth(2).ContentFrame().GetByText("HelloNameAnonymous").ClickAsync();`);
});
test('should generate frame locators with special characters in name attribute', async ({ page, openRecorder, server }) => {
@ -208,22 +208,22 @@ await page.FrameLocator("#frame1").FrameLocator("iframe").FrameLocator("iframe >
});
const [sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'Click me'),
page.frameLocator('iframe[name="foo<bar\'\\"`>"]').getByRole('button', { name: 'Click me' }).click(),
page.locator('iframe[name="foo<bar\'\\"`>"]').contentFrame().getByRole('button', { name: 'Click me' }).click(),
]);
expect.soft(sources.get('JavaScript')!.text).toContain(`
await page.frameLocator('iframe[name="foo\\\\<bar\\\\\\'\\\\"\\\\\`\\\\>"]').getByRole('button', { name: 'Click me' }).click();`);
await page.locator('iframe[name="foo\\\\<bar\\\\\\'\\\\"\\\\\`\\\\>"]').contentFrame().getByRole('button', { name: 'Click me' }).click();`);
expect.soft(sources.get('Java')!.text).toContain(`
page.frameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName("Click me")).click()`);
page.locator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").contentFrame().getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName("Click me")).click()`);
expect.soft(sources.get('Python')!.text).toContain(`
page.frame_locator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").get_by_role("button", name="Click me").click()`);
page.locator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").content_frame().get_by_role("button", name="Click me").click()`);
expect.soft(sources.get('Python Async')!.text).toContain(`
await page.frame_locator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").get_by_role("button", name="Click me").click()`);
await page.locator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").content_frame().get_by_role("button", name="Click me").click()`);
expect.soft(sources.get('C#')!.text).toContain(`
await page.FrameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`);
await page.Locator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]").ContentFrame().GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`);
});
test('should generate frame locators with title attribute', async ({ page, openRecorder, server }) => {
@ -234,27 +234,27 @@ await page.FrameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]")
const [sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'Click me'),
page.frameLocator('[title="hello world"]').getByRole('button', { name: 'Click me' }).click(),
page.locator('[title="hello world"]').contentFrame().getByRole('button', { name: 'Click me' }).click(),
]);
expect(sources.get('JavaScript')!.text).toContain(
`await page.frameLocator('iframe[title="hello world"]').getByRole('button', { name: 'Click me' }).click();`
expect.soft(sources.get('JavaScript')!.text).toContain(
`await page.locator('iframe[title="hello world"]').contentFrame().getByRole('button', { name: 'Click me' }).click();`
);
expect(sources.get('Java')!.text).toContain(
`page.frameLocator(\"iframe[title=\\\"hello world\\\"]\").getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
expect.soft(sources.get('Java')!.text).toContain(
`page.locator(\"iframe[title=\\\"hello world\\\"]\").contentFrame().getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
);
expect(sources.get('Python')!.text).toContain(
`page.frame_locator(\"iframe[title=\\\"hello world\\\"]\").get_by_role(\"button\", name=\"Click me\").click()`
expect.soft(sources.get('Python')!.text).toContain(
`page.locator(\"iframe[title=\\\"hello world\\\"]\").content_frame().get_by_role(\"button\", name=\"Click me\").click()`
);
expect(sources.get('Python Async')!.text).toContain(
`await page.frame_locator("iframe[title=\\\"hello world\\\"]").get_by_role("button", name="Click me").click()`
expect.soft(sources.get('Python Async')!.text).toContain(
`await page.locator("iframe[title=\\\"hello world\\\"]").content_frame().get_by_role("button", name="Click me").click()`
);
expect(sources.get('C#')!.text).toContain(
`await page.FrameLocator("iframe[title=\\\"hello world\\\"]").GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
expect.soft(sources.get('C#')!.text).toContain(
`await page.Locator("iframe[title=\\\"hello world\\\"]").ContentFrame().GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
);
});
@ -266,27 +266,27 @@ await page.FrameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]")
const [sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'Click me'),
page.frameLocator('[name="hello world"]').getByRole('button', { name: 'Click me' }).click(),
page.locator('[name="hello world"]').contentFrame().getByRole('button', { name: 'Click me' }).click(),
]);
expect(sources.get('JavaScript')!.text).toContain(
`await page.frameLocator('iframe[name="hello world"]').getByRole('button', { name: 'Click me' }).click();`
expect.soft(sources.get('JavaScript')!.text).toContain(
`await page.locator('iframe[name="hello world"]').contentFrame().getByRole('button', { name: 'Click me' }).click();`
);
expect(sources.get('Java')!.text).toContain(
`page.frameLocator(\"iframe[name=\\\"hello world\\\"]\").getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
expect.soft(sources.get('Java')!.text).toContain(
`page.locator(\"iframe[name=\\\"hello world\\\"]\").contentFrame().getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
);
expect(sources.get('Python')!.text).toContain(
`page.frame_locator(\"iframe[name=\\\"hello world\\\"]\").get_by_role(\"button\", name=\"Click me\").click()`
expect.soft(sources.get('Python')!.text).toContain(
`page.locator(\"iframe[name=\\\"hello world\\\"]\").content_frame().get_by_role(\"button\", name=\"Click me\").click()`
);
expect(sources.get('Python Async')!.text).toContain(
`await page.frame_locator("iframe[name=\\\"hello world\\\"]").get_by_role("button", name="Click me").click()`
expect.soft(sources.get('Python Async')!.text).toContain(
`await page.locator("iframe[name=\\\"hello world\\\"]").content_frame().get_by_role("button", name="Click me").click()`
);
expect(sources.get('C#')!.text).toContain(
`await page.FrameLocator("iframe[name=\\\"hello world\\\"]").GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
expect.soft(sources.get('C#')!.text).toContain(
`await page.Locator("iframe[name=\\\"hello world\\\"]").ContentFrame().GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
);
});
@ -298,27 +298,27 @@ await page.FrameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]")
const [sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'Click me'),
page.frameLocator('[id="hello-world"]').getByRole('button', { name: 'Click me' }).click(),
page.locator('[id="hello-world"]').contentFrame().getByRole('button', { name: 'Click me' }).click(),
]);
expect(sources.get('JavaScript')!.text).toContain(
`await page.frameLocator('#hello-world').getByRole('button', { name: 'Click me' }).click();`
expect.soft(sources.get('JavaScript')!.text).toContain(
`await page.locator('#hello-world').contentFrame().getByRole('button', { name: 'Click me' }).click();`
);
expect(sources.get('Java')!.text).toContain(
`page.frameLocator(\"#hello-world\").getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
expect.soft(sources.get('Java')!.text).toContain(
`page.locator(\"#hello-world\").contentFrame().getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
);
expect(sources.get('Python')!.text).toContain(
`page.frame_locator(\"#hello-world\").get_by_role(\"button\", name=\"Click me\").click()`
expect.soft(sources.get('Python')!.text).toContain(
`page.locator(\"#hello-world\").content_frame().get_by_role(\"button\", name=\"Click me\").click()`
);
expect(sources.get('Python Async')!.text).toContain(
`await page.frame_locator("#hello-world").get_by_role("button", name="Click me").click()`
expect.soft(sources.get('Python Async')!.text).toContain(
`await page.locator("#hello-world").content_frame().get_by_role("button", name="Click me").click()`
);
expect(sources.get('C#')!.text).toContain(
`await page.FrameLocator("#hello-world").GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
expect.soft(sources.get('C#')!.text).toContain(
`await page.Locator("#hello-world").ContentFrame().GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
);
});
@ -330,27 +330,27 @@ await page.FrameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]")
const [sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'my-testid'),
page.frameLocator('iframe[data-testid="my-testid"]').getByRole('button', { name: 'Click me' }).click(),
page.locator('iframe[data-testid="my-testid"]').contentFrame().getByRole('button', { name: 'Click me' }).click(),
]);
expect(sources.get('JavaScript')!.text).toContain(
`await page.frameLocator('[data-testid="my-testid"]').getByRole('button', { name: 'Click me' }).click();`
expect.soft(sources.get('JavaScript')!.text).toContain(
`await page.locator('[data-testid="my-testid"]').contentFrame().getByRole('button', { name: 'Click me' }).click();`
);
expect(sources.get('Java')!.text).toContain(
`page.frameLocator(\"[data-testid=\\\"my-testid\\\"]\").getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
expect.soft(sources.get('Java')!.text).toContain(
`page.locator(\"[data-testid=\\\"my-testid\\\"]\").contentFrame().getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName(\"Click me\")).click();`
);
expect(sources.get('Python')!.text).toContain(
`page.frame_locator(\"[data-testid=\\\"my-testid\\\"]\").get_by_role(\"button\", name=\"Click me\").click()`
expect.soft(sources.get('Python')!.text).toContain(
`page.locator(\"[data-testid=\\\"my-testid\\\"]\").content_frame().get_by_role(\"button\", name=\"Click me\").click()`
);
expect(sources.get('Python Async')!.text).toContain(
`await page.frame_locator("[data-testid=\\\"my-testid\\\"]").get_by_role("button", name="Click me").click()`
expect.soft(sources.get('Python Async')!.text).toContain(
`await page.locator("[data-testid=\\\"my-testid\\\"]").content_frame().get_by_role("button", name="Click me").click()`
);
expect(sources.get('C#')!.text).toContain(
`await page.FrameLocator("[data-testid=\\\"my-testid\\\"]").GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
expect.soft(sources.get('C#')!.text).toContain(
`await page.Locator("[data-testid=\\\"my-testid\\\"]").ContentFrame().GetByRole(AriaRole.Button, new() { Name = "Click me" }).ClickAsync();`
);
});
@ -365,19 +365,19 @@ await page.FrameLocator("iframe[name=\\"foo\\\\<bar\\\\'\\\\\\"\\\\\`\\\\>\\"]")
]);
expect.soft(sources.get('JavaScript')!.text).toContain(`
await page.frameLocator('#frame1').getByRole('button', { name: 'Submit' }).click();`);
await page.locator('#frame1').contentFrame().getByRole('button', { name: 'Submit' }).click();`);
expect.soft(sources.get('Java')!.text).toContain(`
page.frameLocator("#frame1").getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName("Submit")).click();`);
page.locator("#frame1").contentFrame().getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName("Submit")).click();`);
expect.soft(sources.get('Python')!.text).toContain(`
page.frame_locator("#frame1").get_by_role("button", name="Submit").click()`);
page.locator("#frame1").content_frame().get_by_role("button", name="Submit").click()`);
expect.soft(sources.get('Python Async')!.text).toContain(`
await page.frame_locator("#frame1").get_by_role("button", name="Submit").click()`);
await page.locator("#frame1").content_frame().get_by_role("button", name="Submit").click()`);
expect.soft(sources.get('C#')!.text).toContain(`
await page.FrameLocator("#frame1").GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();`);
await page.Locator("#frame1").ContentFrame().GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();`);
});
test('should generate getByTestId', async ({ page, openRecorder }) => {