diff --git a/docs/src/api/class-locator.md b/docs/src/api/class-locator.md index 03c72a2fd9..b8d9c8a807 100644 --- a/docs/src/api/class-locator.md +++ b/docs/src/api/class-locator.md @@ -1591,31 +1591,51 @@ Creates a locator that matches either of the two locators. **Usage** -If your page shows a username input that is labelled either `Username` or `Login`, depending on some external factors you do not control, you can match both. +Consider a scenario where you'd like to click on a "New email" button, but sometimes a security settings dialog shows up instead. In this case, you can wait for either a "New email" button, or a dialog and act accordingly. ```js -const input = page.getByLabel('Username').or(page.getByLabel('Login')); -await input.fill('John'); +const newEmail = page.getByRole('button', { name: 'New' }); +const dialog = page.getByText('Confirm security settings'); +await expect(newEmail.or(dialog)).toBeVisible(); +if (await dialog.isVisible()) + await page.getByRole('button', { name: 'Dismiss' }).click(); +await newEmail.click(); ``` ```java -Locator input = page.getByLabel("Username").or(page.getByLabel("Login")); -input.fill("John"); +Locator newEmail = page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("New")); +Locator dialog = page.getByText("Confirm security settings"); +assertThat(newEmail.or(dialog)).isVisible(); +if (dialog.isVisible()) + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Dismiss")).click(); +newEmail.click(); ``` ```python async -input = page.get_by_label("Username").or_(page.get_by_label("Login")) -await input.fill("John") +new_email = page.get_by_role("button", name="New") +dialog = page.get_by_text("Confirm security settings") +await expect(new_email.or_(dialog)).to_be_visible() +if (await dialog.is_visible()) + await page.get_by_role("button", name="Dismiss").click() +await new_email.click() ``` ```python sync -input = page.get_by_label("Username").or_(page.get_by_label("Login")) -input.fill("John") +new_email = page.get_by_role("button", name="New") +dialog = page.get_by_text("Confirm security settings") +expect(new_email.or_(dialog)).to_be_visible() +if (dialog.is_visible()) + page.get_by_role("button", name="Dismiss").click() +new_email.click() ``` ```csharp -var input = page.GetByLabel("Username").Or(page.GetByLabel("Login")); -await input.FillAsync("John"); +var newEmail = page.GetByRole(AriaRole.Button, new() { Name = "New" }); +var dialog = page.GetByText("Confirm security settings"); +await Expect(newEmail.Or(dialog)).ToBeVisibleAsync(); +if (await dialog.IsVisibleAsync()) + await page.GetByRole(AriaRole.Button, new() { Name = "Dismiss" }).ClickAsync(); +await newEmail.ClickAsync(); ``` ### param: Locator.or.locator diff --git a/docs/src/other-locators.md b/docs/src/other-locators.md index 40b2230110..48de45199b 100644 --- a/docs/src/other-locators.md +++ b/docs/src/other-locators.md @@ -494,31 +494,51 @@ var parent = page.GetByText("Hello").Locator("xpath=.."); If you'd like to target one of the two or more elements, and you don't know which one it will be, use [`method: Locator.or`] to create a locator that matches any of the alternatives. -For example, to fill the username input that is labelled either `Username` or `Login`, depending on some external factors: +For example, consider a scenario where you'd like to click on a "New email" button, but sometimes a security settings dialog shows up instead. In this case, you can wait for either a "New email" button, or a dialog and act accordingly. ```js -const input = page.getByLabel('Username').or(page.getByLabel('Login')); -await input.fill('John'); +const newEmail = page.getByRole('button', { name: 'New' }); +const dialog = page.getByText('Confirm security settings'); +await expect(newEmail.or(dialog)).toBeVisible(); +if (await dialog.isVisible()) + await page.getByRole('button', { name: 'Dismiss' }).click(); +await newEmail.click(); ``` ```java -Locator input = page.getByLabel("Username").or(page.getByLabel("Login")); -input.fill("John"); +Locator newEmail = page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("New")); +Locator dialog = page.getByText("Confirm security settings"); +assertThat(newEmail.or(dialog)).isVisible(); +if (dialog.isVisible()) + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Dismiss")).click(); +newEmail.click(); ``` ```python async -input = page.get_by_label("Username").or_(page.get_by_label("Login")) -await input.fill("John") +new_email = page.get_by_role("button", name="New") +dialog = page.get_by_text("Confirm security settings") +await expect(new_email.or_(dialog)).to_be_visible() +if (await dialog.is_visible()) + await page.get_by_role("button", name="Dismiss").click() +await new_email.click() ``` ```python sync -input = page.get_by_label("Username").or_(page.get_by_label("Login")) -input.fill("John") +new_email = page.get_by_role("button", name="New") +dialog = page.get_by_text("Confirm security settings") +expect(new_email.or_(dialog)).to_be_visible() +if (dialog.is_visible()) + page.get_by_role("button", name="Dismiss").click() +new_email.click() ``` ```csharp -var input = page.GetByLabel("Username").Or(page.GetByLabel("Login")); -await input.FillAsync("John"); +var newEmail = page.GetByRole(AriaRole.Button, new() { Name = "New" }); +var dialog = page.GetByText("Confirm security settings"); +await Expect(newEmail.Or(dialog)).ToBeVisibleAsync(); +if (await dialog.IsVisibleAsync()) + await page.GetByRole(AriaRole.Button, new() { Name = "Dismiss" }).ClickAsync(); +await newEmail.ClickAsync(); ``` diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 4e8b7aaaca..addf0b66cd 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -11548,12 +11548,16 @@ export interface Locator { * * **Usage** * - * If your page shows a username input that is labelled either `Username` or `Login`, depending on some external - * factors you do not control, you can match both. + * Consider a scenario where you'd like to click on a "New email" button, but sometimes a security settings dialog + * shows up instead. In this case, you can wait for either a "New email" button, or a dialog and act accordingly. * * ```js - * const input = page.getByLabel('Username').or(page.getByLabel('Login')); - * await input.fill('John'); + * const newEmail = page.getByRole('button', { name: 'New' }); + * const dialog = page.getByText('Confirm security settings'); + * await expect(newEmail.or(dialog)).toBeVisible(); + * if (await dialog.isVisible()) + * await page.getByRole('button', { name: 'Dismiss' }).click(); + * await newEmail.click(); * ``` * * @param locator Alternative locator to match.