diff --git a/README.md b/README.md index be0ef81ec6..2d540c0b63 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 109.0.5414.46 | ✅ | ✅ | ✅ | +| Chromium 110.0.5481.38 | ✅ | ✅ | ✅ | | WebKit 16.4 | ✅ | ✅ | ✅ | -| Firefox 107.0 | ✅ | ✅ | ✅ | +| Firefox 108.0.2 | ✅ | ✅ | ✅ | Playwright for .NET is the official language port of [Playwright](https://playwright.dev), the library to automate [Chromium](https://www.chromium.org/Home), [Firefox](https://www.mozilla.org/en-US/firefox/new/) and [WebKit](https://webkit.org/) with a single API. Playwright is built to enable cross-browser web automation that is **ever-green**, **capable**, **reliable** and **fast**. diff --git a/src/Common/Version.props b/src/Common/Version.props index 289dab4f25..7e17298783 100644 --- a/src/Common/Version.props +++ b/src/Common/Version.props @@ -2,7 +2,7 @@ 1.29.0 $(AssemblyVersion) - 1.29.1 + 1.30.0-beta-1674276599000 $(AssemblyVersion) $(AssemblyVersion) true diff --git a/src/Playwright.Tests/GlobalFetchTests.cs b/src/Playwright.Tests/GlobalFetchTests.cs index 1bad4a75c4..260e7cdf99 100644 --- a/src/Playwright.Tests/GlobalFetchTests.cs +++ b/src/Playwright.Tests/GlobalFetchTests.cs @@ -77,10 +77,10 @@ public async Task ShouldSupportGlobalUserAgentOption() [PlaywrightTest("global-fetch.spec.ts", "should support global timeout option")] public async Task ShouldSupportGlobalTimeoutOption() { - var request = await Playwright.APIRequest.NewContextAsync(new() { Timeout = 1 }); + var request = await Playwright.APIRequest.NewContextAsync(new() { Timeout = 100 }); Server.SetRoute("/empty.html", async request => await Task.Delay(5_000)); var exception = Assert.ThrowsAsync(() => request.GetAsync(Server.EmptyPage)); - StringAssert.Contains("Request timed out after 1ms", exception.Message); + StringAssert.Contains("Request timed out after 100ms", exception.Message); } [PlaywrightTest("global-fetch.spec.ts", "should propagate extra http headers with redirects")] diff --git a/src/Playwright.Tests/PageWaitForSelector1Tests.cs b/src/Playwright.Tests/PageWaitForSelector1Tests.cs index 75424b2118..43b61aea05 100644 --- a/src/Playwright.Tests/PageWaitForSelector1Tests.cs +++ b/src/Playwright.Tests/PageWaitForSelector1Tests.cs @@ -81,7 +81,7 @@ public async Task ElementHandleWaitForSelectorShouldThrowOnNavigation() await Page.GotoAsync(Server.EmptyPage); var exception = await PlaywrightAssert.ThrowsAsync(() => task); - StringAssert.Contains("Error: frame navigated while waiting for Locator(\"span\")", exception.Message); + StringAssert.Contains("waiting for Locator(\"span\") to be visible", exception.Message); } [PlaywrightTest("page-wait-for-selector-1.spec.ts", "should work with removed MutationObserver")] @@ -146,7 +146,6 @@ await frame.EvaluateAsync(@"() => { StringAssert.Contains("Timeout 5000ms", exception.Message); StringAssert.Contains("waiting for Locator(\"div\") to be visible", exception.Message); StringAssert.Contains("locator resolved to hidden
abcdefghijklmnopqrstuvwyxzabcdefghijklmnopqrstuvw…
", exception.Message); - StringAssert.Contains("locator did not resolve to any element", exception.Message); StringAssert.Contains("locator resolved to hidden
", exception.Message); } diff --git a/src/Playwright.Tests/PermissionsTests.cs b/src/Playwright.Tests/PermissionsTests.cs index cac1bcfb22..30abfc9efe 100644 --- a/src/Playwright.Tests/PermissionsTests.cs +++ b/src/Playwright.Tests/PermissionsTests.cs @@ -151,7 +151,11 @@ await Page.EvaluateAsync(@"() => { new[] { "prompt", "denied", "granted" }, await Page.EvaluateAsync("window.events")); await Context.ClearPermissionsAsync(); + + // Note: Chromium 110 stopped triggering "onchange" when clearing permissions. Assert.AreEqual( + (BrowserName == "chromium" && BrowserMajorVersion >= 110) ? + new[] { "prompt", "denied", "granted" } : new[] { "prompt", "denied", "granted", "prompt" }, await Page.EvaluateAsync("window.events")); } diff --git a/src/Playwright/API/Generated/IFrame.cs b/src/Playwright/API/Generated/IFrame.cs index 6432a1eabb..a8b8ec3a66 100644 --- a/src/Playwright/API/Generated/IFrame.cs +++ b/src/Playwright/API/Generated/IFrame.cs @@ -534,60 +534,76 @@ public partial interface IFrame Task GetAttributeAsync(string selector, string name, FrameGetAttributeOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(string text, FrameGetByAltTextOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(Regex text, FrameGetByAltTextOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(string text, FrameGetByLabelOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(Regex text, FrameGetByLabelOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options ILocator GetByPlaceholder(string text, FrameGetByPlaceholderOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options @@ -598,11 +614,32 @@ public partial interface IFrame /// Allows locating elements by their ARIA /// role, ARIA attributes /// and accessible name. - /// Note that role selector **does not replace** accessibility audits and conformance - /// tests, but rather gives early feedback about the ARIA guidelines. /// + /// **Usage** + /// Consider the following DOM structure. + /// You can locate each element by it's implicit role: + /// + /// await Expect(page
+ /// .GetByRole(AriaRole.Heading, new() { Name = "Sign up" }))
+ /// .ToBeVisibleAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Checkbox, new() { Name = "Subscribe" })
+ /// .CheckAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Button, new() {
+ /// NameRegex = new Regex("submit", RegexOptions.IgnoreCase)
+ /// })
+ /// .ClickAsync(); + ///
+ /// **Details** /// - /// Note that many html elements have an implicitly defined + /// Role selector **does not replace** accessibility audits and conformance tests, but + /// rather gives early feedback about the ARIA guidelines. + /// + /// + /// Many html elements have an implicitly defined /// role that is recognized by the role selector. You can find all the supported /// roles here. ARIA guidelines **do not recommend** duplicating implicit roles /// and attributes by setting role and/or aria-* attributes to default @@ -614,27 +651,43 @@ public partial interface IFrame ILocator GetByRole(AriaRole role, FrameGetByRoleOptions? options = default); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(string testId); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(Regex testId); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -652,12 +705,7 @@ public partial interface IFrame /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -668,13 +716,19 @@ public partial interface IFrame /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + /// /// Text to locate the element for. /// Call options ILocator GetByText(string text, FrameGetByTextOptions? options = default); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -692,12 +746,7 @@ public partial interface IFrame /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -708,26 +757,28 @@ public partial interface IFrame /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + /// /// Text to locate the element for. /// Call options ILocator GetByText(Regex text, FrameGetByTextOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options ILocator GetByTitle(string text, FrameGetByTitleOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options diff --git a/src/Playwright/API/Generated/IFrameLocator.cs b/src/Playwright/API/Generated/IFrameLocator.cs index 9464ed55cf..93a7a4aea5 100644 --- a/src/Playwright/API/Generated/IFrameLocator.cs +++ b/src/Playwright/API/Generated/IFrameLocator.cs @@ -74,60 +74,76 @@ public partial interface IFrameLocator IFrameLocator FrameLocator(string selector); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(string text, FrameLocatorGetByAltTextOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(Regex text, FrameLocatorGetByAltTextOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(string text, FrameLocatorGetByLabelOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(Regex text, FrameLocatorGetByLabelOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options ILocator GetByPlaceholder(string text, FrameLocatorGetByPlaceholderOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options @@ -138,11 +154,32 @@ public partial interface IFrameLocator /// Allows locating elements by their ARIA /// role, ARIA attributes /// and accessible name. - /// Note that role selector **does not replace** accessibility audits and conformance - /// tests, but rather gives early feedback about the ARIA guidelines. + /// + /// **Usage** + /// Consider the following DOM structure. + /// You can locate each element by it's implicit role: + /// + /// await Expect(page
+ /// .GetByRole(AriaRole.Heading, new() { Name = "Sign up" }))
+ /// .ToBeVisibleAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Checkbox, new() { Name = "Subscribe" })
+ /// .CheckAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Button, new() {
+ /// NameRegex = new Regex("submit", RegexOptions.IgnoreCase)
+ /// })
+ /// .ClickAsync(); + ///
+ /// **Details** + /// + /// Role selector **does not replace** accessibility audits and conformance tests, but + /// rather gives early feedback about the ARIA guidelines. /// /// - /// Note that many html elements have an implicitly defined + /// Many html elements have an implicitly defined /// role that is recognized by the role selector. You can find all the supported /// roles here. ARIA guidelines **do not recommend** duplicating implicit roles /// and attributes by setting role and/or aria-* attributes to default @@ -154,27 +191,43 @@ public partial interface IFrameLocator ILocator GetByRole(AriaRole role, FrameLocatorGetByRoleOptions? options = default); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(string testId); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(Regex testId); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -192,12 +245,7 @@ public partial interface IFrameLocator /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -208,13 +256,19 @@ public partial interface IFrameLocator /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + /// /// Text to locate the element for. /// Call options ILocator GetByText(string text, FrameLocatorGetByTextOptions? options = default); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -232,12 +286,7 @@ public partial interface IFrameLocator /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -248,26 +297,28 @@ public partial interface IFrameLocator /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + /// /// Text to locate the element for. /// Call options ILocator GetByText(Regex text, FrameLocatorGetByTextOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options ILocator GetByTitle(string text, FrameLocatorGetByTitleOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options diff --git a/src/Playwright/API/Generated/ILocator.cs b/src/Playwright/API/Generated/ILocator.cs index 3cc4f7bb69..a6bfb93fe9 100644 --- a/src/Playwright/API/Generated/ILocator.cs +++ b/src/Playwright/API/Generated/ILocator.cs @@ -54,10 +54,18 @@ public partial interface ILocator /// Task> AllAsync(); - /// Returns an array of node.innerText values for all matching nodes. + /// + /// Returns an array of node.innerText values for all matching nodes. + /// **Usage** + /// var texts = await page.GetByRole(AriaRole.Link).AllInnerTextsAsync(); + /// Task> AllInnerTextsAsync(); - /// Returns an array of node.textContent values for all matching nodes. + /// + /// Returns an array of node.textContent values for all matching nodes. + /// **Usage** + /// var texts = await page.GetByRole(AriaRole.Link).AllTextContentsAsync(); + /// Task> AllTextContentsAsync(); /// @@ -71,10 +79,11 @@ public partial interface ILocator /// /// - /// This method returns the bounding box of the element, or null if the element - /// is not visible. The bounding box is calculated relative to the main frame viewport - /// - which is usually the same as the browser window. + /// This method returns the bounding box of the element matching the locator, or null + /// if the element is not visible. The bounding box is calculated relative to the main + /// frame viewport - which is usually the same as the browser window. /// + /// **Details** /// /// Scrolling affects the returned bounding box, similarly to Element.getBoundingClientRect. /// That means x and/or y may be negative. @@ -89,7 +98,7 @@ public partial interface ILocator /// /// **Usage** /// - /// var box = await element.BoundingBoxAsync();
+ /// var box = await page.GetByRole(AriaRole.Button).BoundingBoxAsync();
/// await page.Mouse.ClickAsync(box.X + box.Width / 2, box.Y + box.Height / 2); ///
///
@@ -97,7 +106,9 @@ public partial interface ILocator Task BoundingBoxAsync(LocatorBoundingBoxOptions? options = default); /// - /// This method checks the element by performing the following steps: + /// Ensure that checkbox or radio element is checked. + /// **Details** + /// Performs the following steps: /// /// /// Ensure that element is a checkbox or a radio input. If not, this method throws. @@ -124,11 +135,15 @@ public partial interface ILocator /// this method throws a . Passing zero timeout disables /// this. /// + /// **Usage** + /// await page.GetByRole(AriaRole.Checkbox).CheckAsync(); /// /// Call options Task CheckAsync(LocatorCheckOptions? options = default); /// + /// Clear the input field. + /// **Details** /// /// This method waits for actionability /// checks, focuses the element, clears it and triggers an input event after @@ -140,6 +155,8 @@ public partial interface ILocator /// is inside the <label> element that has an associated control, /// the control will be cleared instead. /// + /// **Usage** + /// await page.GetByRole(AriaRole.Textbox).ClearAsync(); /// /// Call options Task ClearAsync(LocatorClearOptions? options = default); @@ -172,14 +189,31 @@ public partial interface ILocator /// this method throws a . Passing zero timeout disables /// this. /// + /// **Usage** + /// Click a button: + /// await page.GetByRole(AriaRole.Button).ClickAsync(); + /// Shift-right-click at a specific position on a canvas: + /// + /// await page.Locator("canvas").ClickAsync(new() {
+ /// Button = MouseButton.Right,
+ /// Modifiers = new[] { KeyboardModifier.Shift },
+ /// Position = new Position { X = 0, Y = 0 }
+ /// }); + ///
///
/// Call options Task ClickAsync(LocatorClickOptions? options = default); - /// Returns the number of elements matching given selector. + /// + /// Returns the number of elements matching the locator. + /// **Usage** + /// int count = await page.GetByRole(AriaRole.Listitem).CountAsync(); + /// Task CountAsync(); /// + /// Double-click an element. + /// **Details** /// This method double clicks the element by performing the following steps: /// /// @@ -217,13 +251,15 @@ public partial interface ILocator Task DblClickAsync(LocatorDblClickOptions? options = default); /// + /// Programmaticaly dispatch an event on the matching element. + /// **Usage** + /// await locator.DispatchEventAsync("click"); + /// **Details** /// - /// The snippet below dispatches the click event on the element. Regardless of + /// The snippet above dispatches the click event on the element. Regardless of /// the visibility state of the element, click is dispatched. This is equivalent /// to calling element.click(). /// - /// **Usage** - /// await element.DispatchEventAsync("click"); /// /// Under the hood, it creates an instance of an event based on the given , initializes it with properties and dispatches @@ -243,12 +279,12 @@ public partial interface ILocator /// Event /// /// - /// You can also specify JSHandle as the property value if you want live objects - /// to be passed into the event: + /// You can also specify as the property value if you want live + /// objects to be passed into the event: /// /// /// var dataTransfer = await page.EvaluateHandleAsync("() => new DataTransfer()");
- /// await element.DispatchEventAsync("dragstart", new Dictionary<string, object>
+ /// await locator.DispatchEventAsync("dragstart", new Dictionary<string, object>
/// {
/// { "dataTransfer", dataTransfer }
/// }); @@ -260,6 +296,8 @@ public partial interface ILocator Task DispatchEventAsync(string type, object? eventInit = default, LocatorDispatchEventOptions? options = default); /// + /// Drag the source element towards the target element and drop it. + /// **Details** /// /// This method drags the locator to another target locator or target position. It will /// first move to the source element, perform a mousedown, then move to the target @@ -285,24 +323,41 @@ public partial interface ILocator /// /// - /// Resolves given locator to the first matching DOM element. If no elements matching - /// the query are visible, waits for them up to a given timeout. If multiple elements - /// match the selector, throws. + /// Always prefer using s and web assertions over s + /// because latter are inherently racy. + /// + /// + /// Resolves given locator to the first matching DOM element. If there are no matching + /// elements, waits for one. If multiple elements match the locator, throws. /// /// /// Call options Task ElementHandleAsync(LocatorElementHandleOptions? options = default); - /// Resolves given locator to all matching DOM elements. + /// + /// + /// Always prefer using s and web assertions over s + /// because latter are inherently racy. + /// + /// + /// Resolves given locator to all matching DOM elements. If there are no matching elements, + /// returns an empty list. + /// + /// Task> ElementHandlesAsync(); /// - /// Returns the return value of . - /// This method passes this handle as the first argument to . + /// Execute JavaScript code in the page, taking the matching element as an argument. + /// **Details** /// - /// If returns a , then handle.evaluate - /// would wait for the promise to resolve and return its value. + /// Returns the return value of , called with the matching + /// element as a first argument, and as a second argument. /// + /// + /// If returns a , this method will + /// wait for the promise to resolve and return its value. + /// + /// If throws or rejects, this method throws. /// **Usage** /// /// var tweets = page.Locator(".tweet .retweets");
@@ -318,19 +373,22 @@ public partial interface ILocator Task EvaluateAsync(string expression, object? arg = default, LocatorEvaluateOptions? options = default); /// + /// Execute JavaScript code in the page, taking all matching elements as an argument. + /// **Details** /// - /// The method finds all elements matching the specified locator and passes an array - /// of matched elements as a first argument to . Returns - /// the result of invocation. + /// Returns the return value of , called with an array + /// of all matching elements as a first argument, and as a second + /// argument. /// /// - /// If returns a , then - /// would wait for the promise to resolve and return its value. + /// If returns a , this method will + /// wait for the promise to resolve and return its value. /// + /// If throws or rejects, this method throws. /// **Usage** /// - /// var elements = page.Locator("div");
- /// var divsCount = await elements.EvaluateAllAsync<bool>("(divs, min) => divs.length >= min", 10); + /// var locator = page.Locator("div");
+ /// var moreThanTen = await locator.EvaluateAllAsync<bool>("(divs, min) => divs.length > min", 10); ///
///
/// @@ -341,17 +399,25 @@ public partial interface ILocator Task EvaluateAllAsync(string expression, object? arg = default); /// - /// Returns the return value of as a . - /// This method passes this handle as the first argument to . + /// + /// Execute JavaScript code in the page, taking the matching element as an argument, + /// and return a with the result. + /// + /// **Details** + /// + /// Returns the return value of as a, + /// called with the matching element as a first argument, and + /// as a second argument. + /// /// /// The only difference between and /// is that returns . /// /// - /// If the function passed to the returns - /// a , then would wait - /// for the promise to resolve and return its value. + /// If returns a , this method will + /// wait for the promise to resolve and return its value. /// + /// If throws or rejects, this method throws. /// See for more details. /// /// @@ -363,6 +429,10 @@ public partial interface ILocator Task EvaluateHandleAsync(string expression, object? arg = default, LocatorEvaluateHandleOptions? options = default); /// + /// Set a value to the input field. + /// **Usage** + /// await page.GetByRole(AriaRole.Textbox).FillAsync("example value"); + /// **Details** /// /// This method waits for actionability /// checks, focuses the element, fills it and triggers an input event after filling. @@ -409,18 +479,18 @@ public partial interface ILocator /// /// /// Calls focus - /// on the element. + /// on the matching element. /// /// /// Call options Task FocusAsync(LocatorFocusOptions? options = default); /// - /// **Usage** /// /// When working with iframes, you can create a frame locator that will enter the iframe - /// and allow selecting elements in that iframe: + /// and allow locating elements in that iframe: /// + /// **Usage** /// /// var locator = page.FrameLocator("iframe").GetByText("Submit");
/// await locator.ClickAsync(); @@ -429,66 +499,82 @@ public partial interface ILocator /// A selector to use when resolving DOM element. IFrameLocator FrameLocator(string selector); - /// Returns element attribute value. + /// Returns the matching element's attribute value. /// Attribute name to get the value for. /// Call options Task GetAttributeAsync(string name, LocatorGetAttributeOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(string text, LocatorGetByAltTextOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(Regex text, LocatorGetByAltTextOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(string text, LocatorGetByLabelOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(Regex text, LocatorGetByLabelOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options ILocator GetByPlaceholder(string text, LocatorGetByPlaceholderOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options @@ -499,11 +585,32 @@ public partial interface ILocator /// Allows locating elements by their ARIA /// role, ARIA attributes /// and accessible name. - /// Note that role selector **does not replace** accessibility audits and conformance - /// tests, but rather gives early feedback about the ARIA guidelines. + /// + /// **Usage** + /// Consider the following DOM structure. + /// You can locate each element by it's implicit role: + /// + /// await Expect(page
+ /// .GetByRole(AriaRole.Heading, new() { Name = "Sign up" }))
+ /// .ToBeVisibleAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Checkbox, new() { Name = "Subscribe" })
+ /// .CheckAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Button, new() {
+ /// NameRegex = new Regex("submit", RegexOptions.IgnoreCase)
+ /// })
+ /// .ClickAsync(); + ///
+ /// **Details** + /// + /// Role selector **does not replace** accessibility audits and conformance tests, but + /// rather gives early feedback about the ARIA guidelines. /// /// - /// Note that many html elements have an implicitly defined + /// Many html elements have an implicitly defined /// role that is recognized by the role selector. You can find all the supported /// roles here. ARIA guidelines **do not recommend** duplicating implicit roles /// and attributes by setting role and/or aria-* attributes to default @@ -515,27 +622,43 @@ public partial interface ILocator ILocator GetByRole(AriaRole role, LocatorGetByRoleOptions? options = default); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(string testId); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(Regex testId); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -553,12 +676,7 @@ public partial interface ILocator /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -569,13 +687,19 @@ public partial interface ILocator /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + ///
/// Text to locate the element for. /// Call options ILocator GetByText(string text, LocatorGetByTextOptions? options = default); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -593,12 +717,7 @@ public partial interface ILocator /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -609,26 +728,28 @@ public partial interface ILocator /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + ///
/// Text to locate the element for. /// Call options ILocator GetByText(Regex text, LocatorGetByTextOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options ILocator GetByTitle(string text, LocatorGetByTitleOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options @@ -643,6 +764,10 @@ public partial interface ILocator Task HighlightAsync(); /// + /// Hover over the matching element. + /// **Usage** + /// await page.GetByRole(AriaRole.Link).HoverAsync(); + /// **Details** /// This method hovers over the element by performing the following steps: /// /// @@ -672,22 +797,25 @@ public partial interface ILocator /// Call options Task HoverAsync(LocatorHoverOptions? options = default); - /// Returns the element.innerHTML. + /// Returns the element.innerHTML. /// Call options Task InnerHTMLAsync(LocatorInnerHTMLOptions? options = default); - /// Returns the element.innerText. + /// Returns the element.innerText. /// Call options Task InnerTextAsync(LocatorInnerTextOptions? options = default); /// /// - /// Returns input.value for the selected <input> or <textarea> + /// Returns the value for the matching <input> or <textarea> /// or <select> element. /// + /// **Usage** + /// String value = await page.GetByRole(AriaRole.Textbox).InputValueAsync(); + /// **Details** /// - /// Throws for non-input elements. However, if the element is inside the <label> - /// element that has an associated control, + /// Throws elements that are not an input, textarea or a select. However, if the element + /// is inside the <label> element that has an associated control, /// returns the value of the control. /// /// @@ -699,31 +827,57 @@ public partial interface ILocator /// Returns whether the element is checked. Throws if the element is not a checkbox /// or radio input. /// + /// **Usage** + /// Boolean checked = await page.GetByRole(AriaRole.Checkbox).IsCheckedAsync(); /// /// Call options Task IsCheckedAsync(LocatorIsCheckedOptions? options = default); - /// Returns whether the element is disabled, the opposite of enabled. + /// + /// Returns whether the element is disabled, the opposite of enabled. + /// **Usage** + /// Boolean disabled = await page.GetByRole(AriaRole.Button).IsDisabledAsync(); + /// /// Call options Task IsDisabledAsync(LocatorIsDisabledOptions? options = default); - /// Returns whether the element is editable. + /// + /// Returns whether the element is editable. + /// **Usage** + /// Boolean editable = await page.GetByRole(AriaRole.Textbox).IsEditableAsync(); + /// /// Call options Task IsEditableAsync(LocatorIsEditableOptions? options = default); - /// Returns whether the element is enabled. + /// + /// Returns whether the element is enabled. + /// **Usage** + /// Boolean enabled = await page.GetByRole(AriaRole.Button).IsEnabledAsync(); + /// /// Call options Task IsEnabledAsync(LocatorIsEnabledOptions? options = default); - /// Returns whether the element is hidden, the opposite of visible. + /// + /// Returns whether the element is hidden, the opposite of visible. + /// **Usage** + /// Boolean hidden = await page.GetByRole(AriaRole.Button).IsHiddenAsync(); + /// /// Call options Task IsHiddenAsync(LocatorIsHiddenOptions? options = default); - /// Returns whether the element is visible. + /// + /// Returns whether the element is visible. + /// **Usage** + /// Boolean visible = await page.GetByRole(AriaRole.Button).IsVisibleAsync(); + /// /// Call options Task IsVisibleAsync(LocatorIsVisibleOptions? options = default); - /// Returns locator to the last matching element. + /// + /// Returns locator to the last matching element. + /// **Usage** + /// var banana = await page.GetByRole(AriaRole.Listitem).Last(1); + /// ILocator Last { get; } /// @@ -742,6 +896,8 @@ public partial interface ILocator /// Returns locator to the n-th matching element. It's zero based, nth(0) selects /// the first element. /// + /// **Usage** + /// var banana = await page.GetByRole(AriaRole.Listitem).Nth(2); /// /// /// @@ -751,6 +907,10 @@ public partial interface ILocator IPage Page { get; } /// + /// Focuses the mathing element and presses a combintation of the keys. + /// **Usage** + /// await page.GetByRole(AriaRole.Textbox).PressAsync("Backspace"); + /// **Details** /// Focuses the element, and then uses and . /// /// can specify the intended keyboardEvent.key @@ -791,6 +951,17 @@ public partial interface ILocator Task PressAsync(string key, LocatorPressOptions? options = default); /// + /// Take a screenshot of the element matching the locator. + /// **Usage** + /// await page.GetByRole(AriaRole.Link).ScreenshotAsync(); + /// Disable animations and save screenshot to a file: + /// + /// await page.GetByRole(AriaRole.Link).ScreenshotAsync(new() {
+ /// Animations = ScreenshotAnimations.Disabled,
+ /// Path = "link.png"
+ /// }); + ///
+ /// **Details** /// /// This method captures a screenshot of the page, clipped to the size and position /// of a particular element matching the locator. If the element is covered by other @@ -1062,6 +1233,10 @@ public partial interface ILocator Task SelectTextAsync(LocatorSelectTextOptions? options = default); /// + /// Set the state of a checkbox or a radio element. + /// **Usage** + /// await page.GetByRole(AriaRole.Checkbox).SetCheckedAsync(true); + /// **Details** /// This method checks or unchecks an element by performing the following steps: /// /// @@ -1093,6 +1268,27 @@ public partial interface ILocator Task SetCheckedAsync(bool checkedState, LocatorSetCheckedOptions? options = default); /// + /// Upload file or multiple files into <input type=file>. + /// **Usage** + /// + /// // Select one file
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync("myfile.pdf");
+ ///
+ /// // Select multiple files
+ /// await page.GetByLabel("Upload files").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" });
+ ///
+ /// // Remove all the selected files
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new[] {});
+ ///
+ /// // Upload buffer from memory
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new FilePayload
+ /// {
+ /// Name = "file.txt",
+ /// MimeType = "text/plain",
+ /// Buffer = System.Text.Encoding.UTF8.GetBytes("this is a test"),
+ /// }); + ///
+ /// **Details** /// /// Sets the value of the file input to these file paths or files. If some of the filePaths /// are relative paths, then they are resolved relative to the current working directory. @@ -1111,6 +1307,27 @@ public partial interface ILocator Task SetInputFilesAsync(string files, LocatorSetInputFilesOptions? options = default); /// + /// Upload file or multiple files into <input type=file>. + /// **Usage** + /// + /// // Select one file
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync("myfile.pdf");
+ ///
+ /// // Select multiple files
+ /// await page.GetByLabel("Upload files").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" });
+ ///
+ /// // Remove all the selected files
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new[] {});
+ ///
+ /// // Upload buffer from memory
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new FilePayload
+ /// {
+ /// Name = "file.txt",
+ /// MimeType = "text/plain",
+ /// Buffer = System.Text.Encoding.UTF8.GetBytes("this is a test"),
+ /// }); + ///
+ /// **Details** /// /// Sets the value of the file input to these file paths or files. If some of the filePaths /// are relative paths, then they are resolved relative to the current working directory. @@ -1129,6 +1346,27 @@ public partial interface ILocator Task SetInputFilesAsync(IEnumerable files, LocatorSetInputFilesOptions? options = default); /// + /// Upload file or multiple files into <input type=file>. + /// **Usage** + /// + /// // Select one file
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync("myfile.pdf");
+ ///
+ /// // Select multiple files
+ /// await page.GetByLabel("Upload files").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" });
+ ///
+ /// // Remove all the selected files
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new[] {});
+ ///
+ /// // Upload buffer from memory
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new FilePayload
+ /// {
+ /// Name = "file.txt",
+ /// MimeType = "text/plain",
+ /// Buffer = System.Text.Encoding.UTF8.GetBytes("this is a test"),
+ /// }); + ///
+ /// **Details** /// /// Sets the value of the file input to these file paths or files. If some of the filePaths /// are relative paths, then they are resolved relative to the current working directory. @@ -1147,6 +1385,27 @@ public partial interface ILocator Task SetInputFilesAsync(FilePayload files, LocatorSetInputFilesOptions? options = default); /// + /// Upload file or multiple files into <input type=file>. + /// **Usage** + /// + /// // Select one file
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync("myfile.pdf");
+ ///
+ /// // Select multiple files
+ /// await page.GetByLabel("Upload files").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" });
+ ///
+ /// // Remove all the selected files
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new[] {});
+ ///
+ /// // Upload buffer from memory
+ /// await page.GetByLabel("Upload file").SetInputFilesAsync(new FilePayload
+ /// {
+ /// Name = "file.txt",
+ /// MimeType = "text/plain",
+ /// Buffer = System.Text.Encoding.UTF8.GetBytes("this is a test"),
+ /// }); + ///
+ /// **Details** /// /// Sets the value of the file input to these file paths or files. If some of the filePaths /// are relative paths, then they are resolved relative to the current working directory. @@ -1165,6 +1424,8 @@ public partial interface ILocator Task SetInputFilesAsync(IEnumerable files, LocatorSetInputFilesOptions? options = default); /// + /// Perform a tap gesture on the element matching the locator. + /// **Details** /// This method taps the element by performing the following steps: /// /// @@ -1200,7 +1461,7 @@ public partial interface ILocator /// Call options Task TapAsync(LocatorTapOptions? options = default); - /// Returns the node.textContent. + /// Returns the node.textContent. /// Call options Task TextContentAsync(LocatorTextContentOptions? options = default); @@ -1227,7 +1488,11 @@ public partial interface ILocator Task TypeAsync(string text, LocatorTypeOptions? options = default); /// - /// This method checks the element by performing the following steps: + /// Ensure that checkbox or radio element is unchecked. + /// **Usage** + /// await page.GetByRole(AriaRole.Checkbox).UncheckAsync(); + /// **Details** + /// This method unchecks the element by performing the following steps: /// /// /// Ensure that element is a checkbox or a radio input. If not, this method throws. diff --git a/src/Playwright/API/Generated/IPage.cs b/src/Playwright/API/Generated/IPage.cs index 81dde00719..4603b528b1 100644 --- a/src/Playwright/API/Generated/IPage.cs +++ b/src/Playwright/API/Generated/IPage.cs @@ -974,60 +974,76 @@ public partial interface IPage Task GetAttributeAsync(string selector, string name, PageGetAttributeOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(string text, PageGetByAltTextOptions? options = default); /// - /// - /// Allows locating elements by their alt text. For example, this method will find the - /// image by alt text "Castle": - /// + /// Allows locating elements by their alt text. + /// **Usage** + /// For example, this method will find the image by alt text "Playwright logo": + /// await page.GetByAltText("Playwright logo").ClickAsync(); /// /// Text to locate the element for. /// Call options ILocator GetByAltText(Regex text, PageGetByAltTextOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(string text, PageGetByLabelOptions? options = default); /// + /// Allows locating input elements by the text of the associated label. + /// **Usage** /// - /// Allows locating input elements by the text of the associated label. For example, - /// this method will find the input by label text "Password" in the following DOM: + /// For example, this method will find the input by label text "Password" in the following + /// DOM: /// + /// await page.GetByLabel("Password").FillAsync("secret"); /// /// Text to locate the element for. /// Call options ILocator GetByLabel(Regex text, PageGetByLabelOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options ILocator GetByPlaceholder(string text, PageGetByPlaceholderOptions? options = default); /// - /// - /// Allows locating input elements by the placeholder text. For example, this method - /// will find the input by placeholder "Country": - /// + /// Allows locating input elements by the placeholder text. + /// **Usage** + /// For example, consider the following DOM structure. + /// You can fill the input after locating it by the placeholder text: + /// + /// await page
+ /// .GetByPlaceholder("name@example.com")
+ /// .FillAsync("playwright@microsoft.com"); + ///
///
/// Text to locate the element for. /// Call options @@ -1038,11 +1054,32 @@ public partial interface IPage /// Allows locating elements by their ARIA /// role, ARIA attributes /// and accessible name. - /// Note that role selector **does not replace** accessibility audits and conformance - /// tests, but rather gives early feedback about the ARIA guidelines. + /// + /// **Usage** + /// Consider the following DOM structure. + /// You can locate each element by it's implicit role: + /// + /// await Expect(page
+ /// .GetByRole(AriaRole.Heading, new() { Name = "Sign up" }))
+ /// .ToBeVisibleAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Checkbox, new() { Name = "Subscribe" })
+ /// .CheckAsync();
+ ///
+ /// await page
+ /// .GetByRole(AriaRole.Button, new() {
+ /// NameRegex = new Regex("submit", RegexOptions.IgnoreCase)
+ /// })
+ /// .ClickAsync(); + ///
+ /// **Details** + /// + /// Role selector **does not replace** accessibility audits and conformance tests, but + /// rather gives early feedback about the ARIA guidelines. /// /// - /// Note that many html elements have an implicitly defined + /// Many html elements have an implicitly defined /// role that is recognized by the role selector. You can find all the supported /// roles here. ARIA guidelines **do not recommend** duplicating implicit roles /// and attributes by setting role and/or aria-* attributes to default @@ -1054,27 +1091,43 @@ public partial interface IPage ILocator GetByRole(AriaRole role, PageGetByRoleOptions? options = default); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(string testId); /// + /// Locate element by the test id. + /// **Usage** + /// Consider the following DOM structure. + /// You can locate the element by it's test id: + /// await page.GetByTestId("directions").ClickAsync(); + /// **Details** /// - /// Locate element by the test id. By default, the data-testid attribute is used - /// as a test id. Use to configure a different - /// test id attribute if necessary. + /// By default, the data-testid attribute is used as a test id. Use + /// to configure a different test id attribute if necessary. /// /// /// Id to locate the element by. ILocator GetByTestId(Regex testId); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -1092,12 +1145,7 @@ public partial interface IPage /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -1108,13 +1156,19 @@ public partial interface IPage /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + ///
/// Text to locate the element for. /// Call options ILocator GetByText(string text, PageGetByTextOptions? options = default); /// - /// Allows locating elements that contain given text. Consider the following DOM structure: + /// Allows locating elements that contain given text. + /// + /// See also that allows to match by another criteria, + /// like an accessible role, and then filter by the text content. + /// + /// **Usage** + /// Consider the following DOM structure: /// You can locate by text substring, exact string, or a regular expression: /// /// // Matches <span>
@@ -1132,12 +1186,7 @@ public partial interface IPage /// // Matches second <div>
/// page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase)) ///
- /// - /// See also that allows to match by another criteria, - /// like an accessible role, and then filter by the text content. - /// - ///
- /// + /// **Details** /// /// Matching by text always normalizes whitespace, even with exact match. For example, /// it turns multiple spaces into one, turns line breaks into spaces and ignores leading @@ -1148,26 +1197,28 @@ public partial interface IPage /// value instead of the text content. For example, locating by text "Log /// in" matches <input type=button value="Log in">. /// - /// + ///
/// Text to locate the element for. /// Call options ILocator GetByText(Regex text, PageGetByTextOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options ILocator GetByTitle(string text, PageGetByTitleOptions? options = default); /// - /// - /// Allows locating elements by their title. For example, this method will find the - /// button by its title "Place the order": - /// + /// Allows locating elements by their title attribute. + /// **Usage** + /// Consider the following DOM structure. + /// You can check the issues count after locating it by the title text: + /// await Expect(page.GetByTitle("Issues count")).toHaveText("25 issues"); /// /// Text to locate the element for. /// Call options @@ -2661,6 +2712,10 @@ public partial interface IPage /// /// + /// **DEPRECATED** This method is inherently racy, please use + /// instead. + /// + /// /// Waits for the main frame navigation and returns the main resource response. In case /// of multiple redirects, the navigation will resolve with the response of the last /// redirect. In case of navigation to a different anchor or navigation due to History @@ -2690,10 +2745,15 @@ public partial interface IPage /// /// /// Call options + [System.Obsolete] Task WaitForNavigationAsync(PageWaitForNavigationOptions? options = default); /// /// + /// **DEPRECATED** This method is inherently racy, please use + /// instead. + /// + /// /// Waits for the main frame navigation and returns the main resource response. In case /// of multiple redirects, the navigation will resolve with the response of the last /// redirect. In case of navigation to a different anchor or navigation due to History @@ -2724,6 +2784,7 @@ public partial interface IPage /// /// Action that triggers the event. /// Call options + [System.Obsolete] Task RunAndWaitForNavigationAsync(Func action, PageRunAndWaitForNavigationOptions? options = default); /// diff --git a/src/Playwright/Core/Page.cs b/src/Playwright/Core/Page.cs index f72f8ae586..6be6f89d01 100644 --- a/src/Playwright/Core/Page.cs +++ b/src/Playwright/Core/Page.cs @@ -941,7 +941,7 @@ public Task IsVisibleAsync(string selector, PageIsVisibleOptions options = }); #pragma warning restore CS0612 // Type or member is obsolete - public Task PauseAsync() => Context.Channel.PauseAsync(); + public Task PauseAsync() => Task.WhenAny(Context.Channel.PauseAsync(), ClosedOrCrashedTcs.Task); public void SetDefaultNavigationTimeout(float timeout) { diff --git a/src/Playwright/Scripts/playwright.cmd b/src/Playwright/Scripts/playwright.cmd index d1142c2dfc..12f6f29acd 100755 --- a/src/Playwright/Scripts/playwright.cmd +++ b/src/Playwright/Scripts/playwright.cmd @@ -1,6 +1,6 @@ @echo off setlocal if not defined PLAYWRIGHT_NODEJS_PATH ( - set PLAYWRIGHT_NODEJS_PATH=%~dp0\node.exe + set PLAYWRIGHT_NODEJS_PATH="%~dp0\node.exe" ) -"""%PLAYWRIGHT_NODEJS_PATH%""" "%~dp0\..\..\package\lib\cli\cli.js" %* +""%PLAYWRIGHT_NODEJS_PATH%"" "%~dp0\..\..\package\lib\cli\cli.js" %*