diff --git a/docs/src/intro-csharp.md b/docs/src/intro-csharp.md index fff4913a28..edf3c4aaff 100644 --- a/docs/src/intro-csharp.md +++ b/docs/src/intro-csharp.md @@ -73,7 +73,7 @@ dotnet build pwsh bin/Debug/netX/playwright.ps1 install ``` -If `pwsh` is not available, you have to [install PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell). +If `pwsh` is not available, you have to [install PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell). ## Add Example Tests @@ -110,7 +110,7 @@ public class Tests : PageTest await Expect(Page).ToHaveTitleAsync(new Regex("Playwright")); // create a locator - var getStarted = Page.GetByRole(AriaRole.Link, new() { NameString = "Get started" }); + var getStarted = Page.GetByRole(AriaRole.Link, new() { Name = "Get started" }); // Expect an attribute "to be strictly equal" to the value. await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro"); @@ -145,7 +145,7 @@ public class UnitTest1 : PageTest await Expect(Page).ToHaveTitleAsync(new Regex("Playwright")); // create a locator - var getStarted = Page.GetByRole(AriaRole.Link, new() { NameString = "Get started" }); + var getStarted = Page.GetByRole(AriaRole.Link, new() { Name = "Get started" }); // Expect an attribute "to be strictly equal" to the value. await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro"); diff --git a/docs/src/locators.md b/docs/src/locators.md index 5de045109b..12e56e6cb5 100644 --- a/docs/src/locators.md +++ b/docs/src/locators.md @@ -64,14 +64,14 @@ await page.GetByLabel("User Name").FillAsync("John"); await page.GetByLabel("Password").FillAsync("secret-password"); -await page.GetByRole(AriaRole.Button, new() { NameString = "Sign in" }).ClickAsync(); +await page.GetByRole(AriaRole.Button, new() { Name = "Sign in" }).ClickAsync(); await Expect(page.GetByText("Welcome, John!")).ToBeVisibleAsync(); ``` ## Locating elements -Playwright comes with multiple built-in locators. To make tests resilient, we recommend prioritizing user-facing attributes and explicit contracts such as [`method: Page.getByRole`]. +Playwright comes with multiple built-in locators. To make tests resilient, we recommend prioritizing user-facing attributes and explicit contracts such as [`method: Page.getByRole`]. For example, consider the following DOM structure. @@ -99,7 +99,7 @@ page.get_by_role("button", name="Sign in").click() ``` ```csharp -await page.GetByRole(AriaRole.Button, new() { NameString = "Sign in" }).ClickAsync(); +await page.GetByRole(AriaRole.Button, new() { Name = "Sign in" }).ClickAsync(); ``` :::tip @@ -141,7 +141,7 @@ locator.click() ``` ```csharp -var locator = page.GetByRole(AriaRole.Button, new() { NameString = "Sign in" }) +var locator = page.GetByRole(AriaRole.Button, new() { Name = "Sign in" }) await locator.HoverAsync(); await locator.ClickAsync(); @@ -180,7 +180,7 @@ locator.click() ```csharp var locator = page .FrameLocator("#my-frame") - .GetByRole(AriaRole.Button), new() { NameString = "Sign in" }); + .GetByRole(AriaRole.Button), new() { Name = "Sign in" }); await locator.ClickAsync(); ``` @@ -244,11 +244,11 @@ page.getByRole(AriaRole.BUTTON, ```csharp await Expect(page - .GetByRole(AriaRole.Heading, new() { NameString = "Sign up" })) + .GetByRole(AriaRole.Heading, new() { Name = "Sign up" })) .ToBeVisibleAsync(); await page - .GetByRole(AriaRole.Checkbox, new() { NameString = "Subscribe" }) + .GetByRole(AriaRole.Checkbox, new() { Name = "Subscribe" }) .CheckAsync(); await page @@ -594,7 +594,7 @@ playwright.selectors.set_test_id_attribute("data-pw") playwright.Selectors.SetTestIdAttribute("data-pw"); ``` -In your html you can now use `data-pw` as your test id instead of the default `data-testid`. +In your html you can now use `data-pw` as your test id instead of the default `data-testid`. ```html card @@ -773,7 +773,7 @@ page.locator("x-details", has_text="Details" ).click() ``` ```csharp await page - .Locator("x-details", new() { HasTextString = "Details" }) + .Locator("x-details", new() { HasText = "Details" }) .ClickAsync(); ``` @@ -851,8 +851,8 @@ page.get_by_role("listitem").filter(has_text="Product 2").get_by_role( ```csharp await page .GetByRole(AriaRole.Listitem) - .Filter(new() { HasTextString = "Product 2" }) - .GetByRole(AriaRole.Button, new () { NameString = "Add to cart" }) + .Filter(new() { HasText = "Product 2" }) + .GetByRole(AriaRole.Button, new () { Name = "Add to cart" }) .ClickAsync(); ``` @@ -891,7 +891,7 @@ page.get_by_role("listitem").filter(has_text=re.compile("Product 2")).get_by_rol await page .GetByRole(AriaRole.Listitem) .Filter(new() { HasTextRegex = new Regex("Product 2") }) - .GetByRole(AriaRole.Button, new () { NameString = "Add to cart" }) + .GetByRole(AriaRole.Button, new () { Name = "Add to cart" }) .ClickAsync(); ``` @@ -945,10 +945,10 @@ await page .GetByRole(AriaRole.Listitem) .Filter(new() { Has = page.GetByRole(AriaRole.Heading, new () { - NameString = "Product 2" + Name = "Product 2" }) }) - .GetByRole(AriaRole.Button, new () { NameString = "Add to cart" }) + .GetByRole(AriaRole.Button, new () { Name = "Add to cart" }) .ClickAsync(); ``` @@ -1035,10 +1035,10 @@ product ```csharp var product = page .GetByRole(AriaRole.Listitem) - .Filter(new() { HasTextString = "Product 2" }); + .Filter(new() { HasText = "Product 2" }); await product - .GetByRole(AriaRole.Button), new() { NameString = "Add to cart" }) + .GetByRole(AriaRole.Button), new() { Name = "Add to cart" }) .ClickAsync(); ``` @@ -1208,7 +1208,7 @@ page.getByRole(AriaRole.LISTITEM) ```csharp await page .GetByRole(AriaRole.Listitem) - .Filter(new() { HasTextString = "orange" }) + .Filter(new() { HasText = "orange" }) .ClickAsync(); ``` @@ -1345,9 +1345,9 @@ rowLocator var rowLocator = page.GetByRole(AriaRole.Listitem); await rowLocator - .Filter(new() { HasTextString = "Mary" }) + .Filter(new() { HasText = "Mary" }) .Filter(new() { - Has = page.GetByRole(AriaRole.Button), new() { NameString = "Say goodbye" }) + Has = page.GetByRole(AriaRole.Button), new() { Name = "Say goodbye" }) }) .ScreenshotAsync(new() { Path = "screenshot.png" }); ``` diff --git a/docs/src/writing-tests-csharp.md b/docs/src/writing-tests-csharp.md index dc9f58a9a7..5ab80032de 100644 --- a/docs/src/writing-tests-csharp.md +++ b/docs/src/writing-tests-csharp.md @@ -36,7 +36,7 @@ public class Tests : PageTest await Expect(Page).ToHaveTitleAsync(new Regex("Playwright")); // create a locator - var getStarted = Page.GetByRole(AriaRole.Link, new() { NameString = "Get started" }); + var getStarted = Page.GetByRole(AriaRole.Link, new() { Name = "Get started" }); // Expect an attribute "to be strictly equal" to the value. await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro"); @@ -71,7 +71,7 @@ public class UnitTest1 : PageTest await Expect(Page).ToHaveTitleAsync(new Regex("Playwright")); // create a locator - var getStarted = Page.GetByRole(AriaRole.Link, new() { NameString = "Get started" }); + var getStarted = Page.GetByRole(AriaRole.Link, new() { Name = "Get started" }); // Expect an attribute "to be strictly equal" to the value. await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro"); @@ -102,7 +102,7 @@ await Expect(Page).ToHaveTitleAsync(new Regex("Playwright")); [Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as `.ClickAsync` `.FillAsync` etc. ```csharp -var getStarted = Page.GetByRole(AriaRole.Link, new() { NameString = "Get started" }); +var getStarted = Page.GetByRole(AriaRole.Link, new() { Name = "Get started" }); await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/installation"); await getStarted.ClickAsync(); diff --git a/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts b/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts index b76fa5c853..fc63f905f2 100644 --- a/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts +++ b/packages/playwright-core/src/server/isomorphic/locatorGenerators.ts @@ -387,7 +387,7 @@ export class CSharpLocatorFactory implements LocatorFactory { if (isRegExp(options.name)) { attrs.push(`NameRegex = ${this.regexToString(options.name)}`); } else if (typeof options.name === 'string') { - attrs.push(`NameString = ${this.quote(options.name)}`); + attrs.push(`Name = ${this.quote(options.name)}`); if (options.exact) attrs.push(`Exact = true`); } @@ -432,7 +432,7 @@ export class CSharpLocatorFactory implements LocatorFactory { private toHasText(body: string | RegExp) { if (isRegExp(body)) return `HasTextRegex = ${this.regexToString(body)}`; - return `HasTextString = ${this.quote(body)}`; + return `HasText = ${this.quote(body)}`; } private quote(text: string) { diff --git a/tests/library/inspector/cli-codegen-1.spec.ts b/tests/library/inspector/cli-codegen-1.spec.ts index f8c6a42960..71a0a52cdc 100644 --- a/tests/library/inspector/cli-codegen-1.spec.ts +++ b/tests/library/inspector/cli-codegen-1.spec.ts @@ -47,7 +47,7 @@ test.describe('cli codegen', () => { page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Submit")).click()`); expect.soft(sources.get('C#').text).toContain(` - await page.GetByRole(AriaRole.Button, new() { NameString = "Submit" }).ClickAsync();`); + await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();`); expect(message.text()).toBe('click'); }); @@ -189,7 +189,7 @@ test.describe('cli codegen', () => { page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Submit")).click()`); expect.soft(sources.get('C#').text).toContain(` - await page.GetByRole(AriaRole.Button, new() { NameString = "Submit" }).ClickAsync();`); + await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();`); expect(message.text()).toBe('click'); }); @@ -630,7 +630,7 @@ test.describe('cli codegen', () => { expect.soft(sources.get('C#').text).toContain(` var page1 = await page.RunAndWaitForPopupAsync(async () => { - await page.GetByRole(AriaRole.Link, new() { NameString = "link" }).ClickAsync(); + await page.GetByRole(AriaRole.Link, new() { Name = "link" }).ClickAsync(); });`); expect(popup.url()).toBe('about:blank'); diff --git a/tests/library/inspector/cli-codegen-2.spec.ts b/tests/library/inspector/cli-codegen-2.spec.ts index 5ec4445633..7bc69317da 100644 --- a/tests/library/inspector/cli-codegen-2.spec.ts +++ b/tests/library/inspector/cli-codegen-2.spec.ts @@ -258,7 +258,7 @@ test.describe('cli codegen', () => { expect.soft(sources.get('C#').text).toContain(` var download1 = await page.RunAndWaitForDownloadAsync(async () => { - await page.GetByRole(AriaRole.Link, new() { NameString = "Download" }).ClickAsync(); + await page.GetByRole(AriaRole.Link, new() { Name = "Download" }).ClickAsync(); });`); }); @@ -306,7 +306,7 @@ test.describe('cli codegen', () => { page.Dialog -= page_Dialog1_EventHandler; } page.Dialog += page_Dialog1_EventHandler; - await page.GetByRole(AriaRole.Button, new() { NameString = "click me" }).ClickAsync();`); + await page.GetByRole(AriaRole.Button, new() { Name = "click me" }).ClickAsync();`); }); diff --git a/tests/library/inspector/cli-codegen-3.spec.ts b/tests/library/inspector/cli-codegen-3.spec.ts index 21c635ff15..f1b0a7e25d 100644 --- a/tests/library/inspector/cli-codegen-3.spec.ts +++ b/tests/library/inspector/cli-codegen-3.spec.ts @@ -49,7 +49,7 @@ test.describe('cli codegen', () => { page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Submit")).first().click();`); expect.soft(sources.get('C#').text).toContain(` - await page.GetByRole(AriaRole.Button, new() { NameString = "Submit" }).First.ClickAsync();`); + await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).First.ClickAsync();`); expect(message.text()).toBe('click1'); }); @@ -84,7 +84,7 @@ test.describe('cli codegen', () => { page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Submit")).nth(1).click();`); expect.soft(sources.get('C#').text).toContain(` - await page.GetByRole(AriaRole.Button, new() { NameString = "Submit" }).Nth(1).ClickAsync();`); + await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).Nth(1).ClickAsync();`); expect(message.text()).toBe('click2'); }); @@ -226,7 +226,7 @@ test.describe('cli codegen', () => { await page.frame_locator("#frame1").get_by_role("button", name="Submit").click()`); expect.soft(sources.get('C#').text).toContain(` - await page.FrameLocator("#frame1").GetByRole(AriaRole.Button, new() { NameString = "Submit" }).ClickAsync();`); + await page.FrameLocator("#frame1").GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();`); }); test('should generate getByTestId', async ({ page, openRecorder }) => { diff --git a/tests/library/locator-generator.spec.ts b/tests/library/locator-generator.spec.ts index c684371461..014fe79cab 100644 --- a/tests/library/locator-generator.spec.ts +++ b/tests/library/locator-generator.spec.ts @@ -186,7 +186,7 @@ it('reverse engineer getByRole', async ({ page }) => { javascript: `getByRole('button', { name: 'Hello' })`, python: `get_by_role("button", name="Hello")`, java: `getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Hello"))`, - csharp: `GetByRole(AriaRole.Button, new() { NameString = "Hello" })`, + csharp: `GetByRole(AriaRole.Button, new() { Name = "Hello" })`, }); expect.soft(generate(page.getByRole('button', { name: /Hello/ }))).toEqual({ javascript: `getByRole('button', { name: /Hello/ })`, @@ -198,7 +198,7 @@ it('reverse engineer getByRole', async ({ page }) => { javascript: `getByRole('button', { name: 'He"llo', exact: true })`, python: `get_by_role("button", name="He\\"llo", exact=True)`, java: `getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("He\\"llo").setExact(true))`, - csharp: `GetByRole(AriaRole.Button, new() { NameString = "He\\"llo", Exact = true })`, + csharp: `GetByRole(AriaRole.Button, new() { Name = "He\\"llo", Exact = true })`, }); expect.soft(generate(page.getByRole('button', { checked: true, pressed: false, level: 3 }))).toEqual({ javascript: `getByRole('button', { checked: true, level: 3, pressed: false })`, @@ -270,7 +270,7 @@ it('reverse engineer locators with regex', async ({ page }) => { it('reverse engineer hasText', async ({ page }) => { expect.soft(generate(page.getByText('Hello').filter({ hasText: 'wo"rld\n' }))).toEqual({ - csharp: `GetByText("Hello").Filter(new() { HasTextString = "wo\\"rld\\n" })`, + csharp: `GetByText("Hello").Filter(new() { HasText = "wo\\"rld\\n" })`, java: `getByText("Hello").filter(new Locator.LocatorOptions().setHasText("wo\\"rld\\n"))`, javascript: `getByText('Hello').filter({ hasText: 'wo"rld\\n' })`, python: `get_by_text("Hello").filter(has_text="wo\\"rld\\n")`, @@ -305,7 +305,7 @@ it('reverse engineer has', async ({ page }) => { .filter({ hasText: 'foo' }) .filter({ has: page.locator('a') }); expect.soft(generate(locator)).toEqual({ - csharp: `Locator("section").Filter(new() { Has = Locator("div").Filter(new() { Has = Locator("span") }) }).Filter(new() { HasTextString = "foo" }).Filter(new() { Has = Locator("a") })`, + csharp: `Locator("section").Filter(new() { Has = Locator("div").Filter(new() { Has = Locator("span") }) }).Filter(new() { HasText = "foo" }).Filter(new() { Has = Locator("a") })`, java: `locator("section").filter(new Locator.LocatorOptions().setHas(locator("div").filter(new Locator.LocatorOptions().setHas(locator("span"))))).filter(new Locator.LocatorOptions().setHasText("foo")).filter(new Locator.LocatorOptions().setHas(locator("a")))`, javascript: `locator('section').filter({ has: locator('div').filter({ has: locator('span') }) }).filter({ hasText: 'foo' }).filter({ has: locator('a') })`, python: `locator("section").filter(has=locator("div").filter(has=locator("span"))).filter(has_text="foo").filter(has=locator("a"))`, @@ -342,7 +342,7 @@ it.describe(() => {
Goodbye world
`); expect.soft(await generateForNode(page, '[mark="1"]')).toEqual({ - csharp: 'Locator("div").Filter(new() { HasTextString = "Goodbye world" }).Locator("span")', + csharp: 'Locator("div").Filter(new() { HasText = "Goodbye world" }).Locator("span")', java: 'locator("div").filter(new Locator.LocatorOptions().setHasText("Goodbye world")).locator("span")', javascript: `locator('div').filter({ hasText: 'Goodbye world' }).locator('span')`, python: 'locator("div").filter(has_text="Goodbye world").locator("span")', @@ -354,7 +354,7 @@ it('parse locators strictly', () => { const selector = 'div >> internal:has-text=\"Goodbye world\"i >> span'; // Exact - expect.soft(parseLocator('csharp', `Locator("div").Filter(new() { HasTextString = "Goodbye world" }).Locator("span")`)).toBe(selector); + expect.soft(parseLocator('csharp', `Locator("div").Filter(new() { HasText = "Goodbye world" }).Locator("span")`)).toBe(selector); expect.soft(parseLocator('java', `locator("div").filter(new Locator.LocatorOptions().setHasText("Goodbye world")).locator("span")`)).toBe(selector); expect.soft(parseLocator('javascript', `locator('div').filter({ hasText: 'Goodbye world' }).locator('span')`)).toBe(selector); expect.soft(parseLocator('python', `locator("div").filter(has_text="Goodbye world").locator("span")`)).toBe(selector); @@ -364,13 +364,13 @@ it('parse locators strictly', () => { expect.soft(parseLocator('python', `locator('div').filter(has_text='Goodbye world').locator('span')`)).toBe(selector); // Whitespace - expect.soft(parseLocator('csharp', `Locator("div") . Filter (new ( ) { HasTextString = "Goodbye world" }).Locator( "span" )`)).toBe(selector); + expect.soft(parseLocator('csharp', `Locator("div") . Filter (new ( ) { HasText = "Goodbye world" }).Locator( "span" )`)).toBe(selector); expect.soft(parseLocator('java', ` locator("div" ). filter( new Locator. LocatorOptions ( ) .setHasText( "Goodbye world" ) ).locator( "span")`)).toBe(selector); expect.soft(parseLocator('javascript', `locator\n('div')\n\n.filter({ hasText : 'Goodbye world'\n }\n).locator('span')\n`)).toBe(selector); expect.soft(parseLocator('python', `\tlocator(\t"div").filter(\thas_text="Goodbye world"\t).locator\t("span")`)).toBe(selector); // Extra symbols - expect.soft(parseLocator('csharp', `Locator("div").Filter(new() { HasTextString = "Goodbye world" }).Locator("span"))`)).not.toBe(selector); + expect.soft(parseLocator('csharp', `Locator("div").Filter(new() { HasText = "Goodbye world" }).Locator("span"))`)).not.toBe(selector); expect.soft(parseLocator('java', `locator("div").filter(new Locator.LocatorOptions().setHasText("Goodbye world"))..locator("span")`)).not.toBe(selector); expect.soft(parseLocator('javascript', `locator('div').filter({ hasText: 'Goodbye world' }}).locator('span')`)).not.toBe(selector); expect.soft(parseLocator('python', `locator("div").filter(has_text=="Goodbye world").locator("span")`)).not.toBe(selector);