# class: LocatorAssertions * since: v1.17 The [LocatorAssertions] class provides assertion methods that can be used to make assertions about the [Locator] state in the tests. ```js import { test, expect } from '@playwright/test'; test('status becomes submitted', async ({ page }) => { // ... await page.getByRole('button').click(); await expect(page.locator('.status')).toHaveText('Submitted'); }); ``` ```java ... import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; public class TestLocator { ... @Test void statusBecomesSubmitted() { ... page.getByRole(AriaRole.BUTTON).click(); assertThat(page.locator(".status")).hasText("Submitted"); } } ``` ```python async from playwright.async_api import Page, expect async def test_status_becomes_submitted(page: Page) -> None: # .. await page.get_by_role("button").click() await expect(page.locator(".status")).to_have_text("Submitted") ``` ```python sync from playwright.sync_api import Page, expect def test_status_becomes_submitted(page: Page) -> None: # .. page.get_by_role("button").click() expect(page.locator(".status")).to_have_text("Submitted") ``` ```csharp using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.Playwright.NUnit; using NUnit.Framework; namespace PlaywrightTests; [TestFixture] public class ExampleTests : PageTest { [Test] public async Task StatusBecomesSubmitted() { // .. await Page.GetByRole(AriaRole.Button).ClickAsync(); await Expect(Page.Locator(".status")).ToHaveTextAsync("Submitted"); } } ``` ## property: LocatorAssertions.not * since: v1.20 * langs: java, js, csharp - returns: <[LocatorAssertions]> Makes the assertion check for the opposite condition. For example, this code tests that the Locator doesn't contain text `"error"`: ```js await expect(locator).not.toContainText('error'); ``` ```java assertThat(locator).not().containsText("error"); ``` ```csharp await Expect(locator).Not.ToContainTextAsync("error"); ``` ## async method: LocatorAssertions.NotToBeAttached * since: v1.33 * langs: python The opposite of [`method: LocatorAssertions.toBeAttached`]. ### option: LocatorAssertions.NotToBeAttached.attached * since: v1.33 - `attached` <[boolean]> ### option: LocatorAssertions.NotToBeAttached.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.33 ## async method: LocatorAssertions.NotToBeChecked * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeChecked`]. ### option: LocatorAssertions.NotToBeChecked.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeDisabled * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeDisabled`]. ### option: LocatorAssertions.NotToBeDisabled.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeEditable * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeEditable`]. ### option: LocatorAssertions.NotToBeEditable.editable * since: v1.26 - `editable` <[boolean]> ### option: LocatorAssertions.NotToBeEditable.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeEmpty * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeEmpty`]. ### option: LocatorAssertions.NotToBeEmpty.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeEnabled * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeEnabled`]. ### option: LocatorAssertions.NotToBeEnabled.enabled * since: v1.26 - `enabled` <[boolean]> ### option: LocatorAssertions.NotToBeEnabled.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeFocused * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeFocused`]. ### option: LocatorAssertions.NotToBeFocused.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeHidden * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeHidden`]. ### option: LocatorAssertions.NotToBeHidden.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToBeInViewport * since: v1.31 * langs: python The opposite of [`method: LocatorAssertions.toBeInViewport`]. ### option: LocatorAssertions.NotToBeInViewport.ratio * since: v1.31 * langs: python - `ratio` <[float]> ### option: LocatorAssertions.NotToBeInViewport.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.31 * langs: python ## async method: LocatorAssertions.NotToBeVisible * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toBeVisible`]. ### option: LocatorAssertions.NotToBeVisible.visible * since: v1.26 - `visible` <[boolean]> ### option: LocatorAssertions.NotToBeVisible.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToContainText * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toContainText`]. ### param: LocatorAssertions.NotToContainText.expected * since: v1.18 - `expected` <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>|[Array]<[string]|[RegExp]>> Expected substring or RegExp or a list of those. ### option: LocatorAssertions.NotToContainText.ignoreCase * since: v1.23 - `ignoreCase` <[boolean]> Whether to perform case-insensitive match. [`option: ignoreCase`] option takes precedence over the corresponding regular expression flag if specified. ### option: LocatorAssertions.NotToContainText.useInnerText * since: v1.18 - `useInnerText` <[boolean]> Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text. ### option: LocatorAssertions.NotToContainText.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveAttribute * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveAttribute`]. ### param: LocatorAssertions.NotToHaveAttribute.name * since: v1.18 - `name` <[string]> Attribute name. ### param: LocatorAssertions.NotToHaveAttribute.value * since: v1.18 - `value` <[string]|[RegExp]> Expected attribute value. ### option: LocatorAssertions.NotToHaveAttribute.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveClass * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveClass`]. ### param: LocatorAssertions.NotToHaveClass.expected * since: v1.18 - `expected` <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>|[Array]<[string]|[RegExp]>> Expected class or RegExp or a list of those. ### option: LocatorAssertions.NotToHaveClass.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveCount * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveCount`]. ### param: LocatorAssertions.NotToHaveCount.count * since: v1.18 - `count` <[int]> Expected count. ### option: LocatorAssertions.NotToHaveCount.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveCSS * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveCSS`]. ### param: LocatorAssertions.NotToHaveCSS.name * since: v1.18 - `name` <[string]> CSS property name. ### param: LocatorAssertions.NotToHaveCSS.value * since: v1.18 - `value` <[string]|[RegExp]> CSS property value. ### option: LocatorAssertions.NotToHaveCSS.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveId * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveId`]. ### param: LocatorAssertions.NotToHaveId.id * since: v1.18 - `id` <[string]|[RegExp]> Element id. ### option: LocatorAssertions.NotToHaveId.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveJSProperty * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveJSProperty`]. ### param: LocatorAssertions.NotToHaveJSProperty.name * since: v1.18 - `name` <[string]> Property name. ### param: LocatorAssertions.NotToHaveJSProperty.value * since: v1.18 - `value` <[any]> Property value. ### option: LocatorAssertions.NotToHaveJSProperty.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveText * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveText`]. ### param: LocatorAssertions.NotToHaveText.expected * since: v1.18 - `expected` <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>|[Array]<[string]|[RegExp]>> Expected string or RegExp or a list of those. ### option: LocatorAssertions.NotToHaveText.ignoreCase * since: v1.23 - `ignoreCase` <[boolean]> Whether to perform case-insensitive match. [`option: ignoreCase`] option takes precedence over the corresponding regular expression flag if specified. ### option: LocatorAssertions.NotToHaveText.useInnerText * since: v1.18 - `useInnerText` <[boolean]> Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text. ### option: LocatorAssertions.NotToHaveText.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveValue * since: v1.20 * langs: python The opposite of [`method: LocatorAssertions.toHaveValue`]. ### param: LocatorAssertions.NotToHaveValue.value * since: v1.18 - `value` <[string]|[RegExp]> Expected value. ### option: LocatorAssertions.NotToHaveValue.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.NotToHaveValues * since: v1.23 * langs: python The opposite of [`method: LocatorAssertions.toHaveValues`]. ### param: LocatorAssertions.NotToHaveValues.values * since: v1.23 - `values` <[Array]<[string]>|[Array]<[RegExp]>|[Array]<[string]|[RegExp]>> Expected options currently selected. ### option: LocatorAssertions.NotToHaveValues.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.23 ## async method: LocatorAssertions.toBeAttached * since: v1.33 * langs: - alias-java: isAttached Ensures that [Locator] points to an [attached](../actionability.md#attached) DOM node. **Usage** ```js await expect(page.getByText('Hidden text')).toBeAttached(); ``` ```java assertThat(page.getByText("Hidden text")).isAttached(); ``` ```python async await expect(page.get_by_text("Hidden text")).to_be_attached() ``` ```python sync expect(page.get_by_text("Hidden text")).to_be_attached() ``` ```csharp await Expect(Page.GetByText("Hidden text")).ToBeAttachedAsync(); ``` ### option: LocatorAssertions.toBeAttached.attached * since: v1.33 - `attached` <[boolean]> ### option: LocatorAssertions.toBeAttached.timeout = %%-js-assertions-timeout-%% * since: v1.33 ### option: LocatorAssertions.toBeAttached.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.33 ## async method: LocatorAssertions.toBeChecked * since: v1.20 * langs: - alias-java: isChecked Ensures the [Locator] points to a checked input. **Usage** ```js const locator = page.getByLabel('Subscribe to newsletter'); await expect(locator).toBeChecked(); ``` ```java assertThat(page.getByLabel("Subscribe to newsletter")).isChecked(); ``` ```python async from playwright.async_api import expect locator = page.get_by_label("Subscribe to newsletter") await expect(locator).to_be_checked() ``` ```python sync from playwright.sync_api import expect locator = page.get_by_label("Subscribe to newsletter") expect(locator).to_be_checked() ``` ```csharp var locator = Page.GetByLabel("Subscribe to newsletter"); await Expect(locator).ToBeCheckedAsync(); ``` ### option: LocatorAssertions.toBeChecked.checked * since: v1.18 - `checked` <[boolean]> ### option: LocatorAssertions.toBeChecked.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeChecked.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeDisabled * since: v1.20 * langs: - alias-java: isDisabled Ensures the [Locator] points to a disabled element. Element is disabled if it has "disabled" attribute or is disabled via ['aria-disabled'](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-disabled). Note that only native control elements such as HTML `button`, `input`, `select`, `textarea`, `option`, `optgroup` can be disabled by setting "disabled" attribute. "disabled" attribute on other elements is ignored by the browser. **Usage** ```js const locator = page.locator('button.submit'); await expect(locator).toBeDisabled(); ``` ```java assertThat(page.locator("button.submit")).isDisabled(); ``` ```python async from playwright.async_api import expect locator = page.locator("button.submit") await expect(locator).to_be_disabled() ``` ```python sync from playwright.sync_api import expect locator = page.locator("button.submit") expect(locator).to_be_disabled() ``` ```csharp var locator = Page.Locator("button.submit"); await Expect(locator).ToBeDisabledAsync(); ``` ### option: LocatorAssertions.toBeDisabled.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeDisabled.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeEditable * since: v1.20 * langs: - alias-java: isEditable Ensures the [Locator] points to an editable element. **Usage** ```js const locator = page.getByRole('textbox'); await expect(locator).toBeEditable(); ``` ```java assertThat(page.getByRole(AriaRole.TEXTBOX)).isEditable(); ``` ```python async from playwright.async_api import expect locator = page.get_by_role("textbox") await expect(locator).to_be_editable() ``` ```python sync from playwright.sync_api import expect locator = page.get_by_role("textbox") expect(locator).to_be_editable() ``` ```csharp var locator = Page.GetByRole(AriaRole.Textbox); await Expect(locator).ToBeEditableAsync(); ``` ### option: LocatorAssertions.toBeEditable.editable * since: v1.26 - `editable` <[boolean]> ### option: LocatorAssertions.toBeEditable.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeEditable.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeEmpty * since: v1.20 * langs: - alias-java: isEmpty Ensures the [Locator] points to an empty editable element or to a DOM node that has no text. **Usage** ```js const locator = page.locator('div.warning'); await expect(locator).toBeEmpty(); ``` ```java assertThat(page.locator("div.warning")).isEmpty(); ``` ```python async from playwright.async_api import expect locator = page.locator("div.warning") await expect(locator).to_be_empty() ``` ```python sync from playwright.sync_api import expect locator = page.locator("div.warning") expect(locator).to_be_empty() ``` ```csharp var locator = Page.Locator("div.warning"); await Expect(locator).ToBeEmptyAsync(); ``` ### option: LocatorAssertions.toBeEmpty.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeEmpty.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeEnabled * since: v1.20 * langs: - alias-java: isEnabled Ensures the [Locator] points to an enabled element. **Usage** ```js const locator = page.locator('button.submit'); await expect(locator).toBeEnabled(); ``` ```java assertThat(page.locator("button.submit")).isEnabled(); ``` ```python async from playwright.async_api import expect locator = page.locator("button.submit") await expect(locator).to_be_enabled() ``` ```python sync from playwright.sync_api import expect locator = page.locator("button.submit") expect(locator).to_be_enabled() ``` ```csharp var locator = Page.Locator("button.submit"); await Expect(locator).toBeEnabledAsync(); ``` ### option: LocatorAssertions.toBeEnabled.enabled * since: v1.26 - `enabled` <[boolean]> ### option: LocatorAssertions.toBeEnabled.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeEnabled.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeFocused * since: v1.20 * langs: - alias-java: isFocused Ensures the [Locator] points to a focused DOM node. **Usage** ```js const locator = page.getByRole('textbox'); await expect(locator).toBeFocused(); ``` ```java assertThat(page.getByRole(AriaRole.TEXTBOX)).isFocused(); ``` ```python async from playwright.async_api import expect locator = page.get_by_role("textbox") await expect(locator).to_be_focused() ``` ```python sync from playwright.sync_api import expect locator = page.get_by_role("textbox") expect(locator).to_be_focused() ``` ```csharp var locator = Page.GetByRole(AriaRole.Textbox); await Expect(locator).ToBeFocusedAsync(); ``` ### option: LocatorAssertions.toBeFocused.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeFocused.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeHidden * since: v1.20 * langs: - alias-java: isHidden Ensures that [Locator] either does not resolve to any DOM node, or resolves to a [non-visible](../actionability.md#visible) one. **Usage** ```js const locator = page.locator('.my-element'); await expect(locator).toBeHidden(); ``` ```java assertThat(page.locator(".my-element")).isHidden(); ``` ```python async from playwright.async_api import expect locator = page.locator('.my-element') await expect(locator).to_be_hidden() ``` ```python sync from playwright.sync_api import expect locator = page.locator('.my-element') expect(locator).to_be_hidden() ``` ```csharp var locator = Page.Locator(".my-element"); await Expect(locator).ToBeHiddenAsync(); ``` ### option: LocatorAssertions.toBeHidden.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeHidden.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toBeInViewport * since: v1.31 * langs: - alias-java: isInViewport Ensures the [Locator] points to an element that intersects viewport, according to the [intersection observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API). **Usage** ```js const locator = page.getByRole('button'); // Make sure at least some part of element intersects viewport. await expect(locator).toBeInViewport(); // Make sure element is fully outside of viewport. await expect(locator).not.toBeInViewport(); // Make sure that at least half of the element intersects viewport. await expect(locator).toBeInViewport({ ratio: 0.5 }); ``` ```java Locator locator = page.getByRole(AriaRole.BUTTON); // Make sure at least some part of element intersects viewport. assertThat(locator).isInViewport(); // Make sure element is fully outside of viewport. assertThat(locator).not().isInViewport(); // Make sure that at least half of the element intersects viewport. assertThat(locator).isInViewport(new LocatorAssertions.IsInViewportOptions().setRatio(0.5)); ``` ```csharp var locator = Page.GetByRole(AriaRole.Button); // Make sure at least some part of element intersects viewport. await Expect(locator).ToBeInViewportAsync(); // Make sure element is fully outside of viewport. await Expect(locator).Not.ToBeInViewportAsync(); // Make sure that at least half of the element intersects viewport. await Expect(locator).ToBeInViewportAsync(new() { Ratio = 0.5 }); ``` ```python async from playwright.async_api import expect locator = page.get_by_role("button") # Make sure at least some part of element intersects viewport. await expect(locator).to_be_in_viewport() # Make sure element is fully outside of viewport. await expect(locator).not_to_be_in_viewport() # Make sure that at least half of the element intersects viewport. await expect(locator).to_be_in_viewport(ratio=0.5) ``` ```python sync from playwright.sync_api import expect locator = page.get_by_role("button") # Make sure at least some part of element intersects viewport. expect(locator).to_be_in_viewport() # Make sure element is fully outside of viewport. expect(locator).not_to_be_in_viewport() # Make sure that at least half of the element intersects viewport. expect(locator).to_be_in_viewport(ratio=0.5) ``` ### option: LocatorAssertions.toBeInViewport.ratio * since: v1.31 - `ratio` <[float]> The minimal ratio of the element to intersect viewport. If equals to `0`, then element should intersect viewport at any positive ratio. Defaults to `0`. ### option: LocatorAssertions.toBeInViewport.timeout = %%-js-assertions-timeout-%% * since: v1.31 ### option: LocatorAssertions.toBeInViewport.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.31 ## async method: LocatorAssertions.toBeVisible * since: v1.20 * langs: - alias-java: isVisible Ensures that [Locator] points to an [attached](../actionability.md#attached) and [visible](../actionability.md#visible) DOM node. To check that at least one element from the list is visible, use [`method: Locator.first`]. **Usage** ```js // A specific element is visible. await expect(page.getByText('Welcome')).toBeVisible(); // At least one item in the list is visible. await expect(page.getByTestId('todo-item').first()).toBeVisible(); // At least one of the two elements is visible, possibly both. await expect( page.getByRole('button', { name: 'Sign in' }) .or(page.getByRole('button', { name: 'Sign up' })) .first() ).toBeVisible(); ``` ```java // A specific element is visible. assertThat(page.getByText("Welcome")).isVisible(); // At least one item in the list is visible. asserThat(page.getByTestId("todo-item").first()).isVisible(); // At least one of the two elements is visible, possibly both. asserThat( page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Sign in")) .or(page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Sign up"))) .first() ).isVisible(); ``` ```python async # A specific element is visible. await expect(page.get_by_text("Welcome")).to_be_visible() # At least one item in the list is visible. await expect(page.get_by_test_id("todo-item").first).to_be_visible() # At least one of the two elements is visible, possibly both. await expect( page.get_by_role("button", name="Sign in") .or_(page.get_by_role("button", name="Sign up")) .first ).to_be_visible() ``` ```python sync # A specific element is visible. expect(page.get_by_text("Welcome")).to_be_visible() # At least one item in the list is visible. expect(page.get_by_test_id("todo-item").first).to_be_visible() # At least one of the two elements is visible, possibly both. expect( page.get_by_role("button", name="Sign in") .or_(page.get_by_role("button", name="Sign up")) .first ).to_be_visible() ``` ```csharp // A specific element is visible. await Expect(Page.GetByText("Welcome")).ToBeVisibleAsync(); // At least one item in the list is visible. await Expect(Page.GetByTestId("todo-item").First).ToBeVisibleAsync(); // At least one of the two elements is visible, possibly both. await Expect( Page.GetByRole(AriaRole.Button, new() { Name = "Sign in" }) .Or(Page.GetByRole(AriaRole.Button, new() { Name = "Sign up" })) .First ).ToBeVisibleAsync(); ``` ### option: LocatorAssertions.toBeVisible.visible * since: v1.26 - `visible` <[boolean]> ### option: LocatorAssertions.toBeVisible.timeout = %%-js-assertions-timeout-%% * since: v1.18 ### option: LocatorAssertions.toBeVisible.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.18 ## async method: LocatorAssertions.toContainText * since: v1.20 * langs: - alias-java: containsText Ensures the [Locator] points to an element that contains the given text. You can use regular expressions for the value as well. **Usage** ```js const locator = page.locator('.title'); await expect(locator).toContainText('substring'); await expect(locator).toContainText(/\d messages/); ``` ```java assertThat(page.locator(".title")).containsText("substring"); ``` ```python async import re from playwright.async_api import expect locator = page.locator('.title') await expect(locator).to_contain_text("substring") await expect(locator).to_contain_text(re.compile(r"\d messages")) ``` ```python sync import re from playwright.sync_api import expect locator = page.locator('.title') expect(locator).to_contain_text("substring") expect(locator).to_contain_text(re.compile(r"\d messages")) ``` ```csharp var locator = Page.Locator(".title"); await Expect(locator).ToContainTextAsync("substring"); await Expect(locator).ToContainTextAsync(new Regex("\\d messages")); ``` If you pass an array as an expected value, the expectations are: 1. Locator resolves to a list of elements. 1. Elements from a **subset** of this list contain text from the expected array, respectively. 1. The matching subset of elements has the same order as the expected array. 1. Each text value from the expected array is matched by some element from the list. For example, consider the following list: ```html