Skip to content

Commit

Permalink
chore(roll): roll Playwright to v1.50 (#3100)
Browse files Browse the repository at this point in the history
  • Loading branch information
mxschmitt authored Jan 30, 2025
1 parent 366b1e1 commit df83b16
Show file tree
Hide file tree
Showing 18 changed files with 301 additions and 60 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

| | Linux | macOS | Windows |
| :--- | :---: | :---: | :---: |
| Chromium <!-- GEN:chromium-version -->131.0.6778.33<!-- GEN:stop --> ||||
| Chromium <!-- GEN:chromium-version -->133.0.6943.16<!-- GEN:stop --> ||||
| WebKit <!-- GEN:webkit-version -->18.2<!-- GEN:stop --> ||||
| Firefox <!-- GEN:firefox-version -->132.0<!-- GEN:stop --> ||||
| Firefox <!-- GEN:firefox-version -->134.0<!-- GEN:stop --> ||||

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**.

Expand Down
2 changes: 1 addition & 1 deletion src/Common/Version.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyVersion>1.50.0</AssemblyVersion>
<PackageVersion>$(AssemblyVersion)-beta-2</PackageVersion>
<DriverVersion>1.49.0</DriverVersion>
<DriverVersion>1.50.0-beta-1737762224000</DriverVersion>
<ReleaseVersion>$(AssemblyVersion)</ReleaseVersion>
<FileVersion>$(AssemblyVersion)</FileVersion>
<NoDefaultExcludes>true</NoDefaultExcludes>
Expand Down
6 changes: 5 additions & 1 deletion src/Playwright.TestingHarnessTest/tests/mstest/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,11 @@ test('should be able to parse LaunchOptions.Proxy from runsettings', async ({ ru
}).listen(3128);

const waitForProxyRequest = new Promise<[string, string]>((resolve) => {
proxyServer.once('proxyReq', (proxyReq, req, res, options) => {
proxyServer.on('proxyReq', (proxyReq, req, res, options) => {
if (req.url.includes('google.com')) // Telemetry requests.
{
return;
}
const authHeader = proxyReq.getHeader('authorization') as string;
const auth = Buffer.from(authHeader.split(' ')[1], 'base64').toString();
resolve([req.url, auth]);
Expand Down
63 changes: 63 additions & 0 deletions src/Playwright.Tests/Assertions/LocatorAssertionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ public async Task ShouldSupportToBeChecked()
StringAssert.Contains("LocatorAssertions.ToBeCheckedAsync with timeout 300ms", exception.Message);
}

[PlaywrightTest("tests/page/expect-boolean.spec.ts", "with indeterminate:true")]
public async Task WithIndeterminateTrue()
{
await Page.SetContentAsync("<input type=checkbox></input>");
await Page.Locator("input").EvaluateAsync("e => e.indeterminate = true");
await Expect(Page.Locator("input")).ToBeCheckedAsync(new() { Indeterminate = true });
}

[PlaywrightTest("tests/page/expect-boolean.spec.ts", "with indeterminate:true and checked")]
public async Task WithIndeterminateTrueAndChecked()
{
await Page.SetContentAsync("<input type=checkbox></input>");
await Page.Locator("input").EvaluateAsync("e => e.indeterminate = true");
var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Expect(Page.Locator("input")).ToBeCheckedAsync(new() { Indeterminate = true, Checked = false }));
StringAssert.Contains("Can't assert indeterminate and checked at the same time", exception.Message);
}

[PlaywrightTest("tests/page/expect-boolean.spec.ts", "fail with indeterminate: true")]
public async Task FailWithIndeterminateTrue()
{
await Page.SetContentAsync("<input type=checkbox></input>");
var locator = Page.Locator("input");
var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Expect(locator).ToBeCheckedAsync(new() { Indeterminate = true, Timeout = 1000 }));
StringAssert.Contains("LocatorAssertions.ToBeCheckedAsync with timeout 1000ms", exception.Message);
}

[PlaywrightTest("playwright-test/playwright.expect.spec.ts", "should be able to set default timeout")]
public async Task ShouldBeAbleToSetDefaultTimeout()
{
Expand Down Expand Up @@ -720,6 +746,43 @@ public async Task ToHaveAccessibleDescription()
await Expect(Page.Locator("div")).ToHaveAccessibleDescriptionAsync(new Regex("hello"), new() { IgnoreCase = true });
}

[PlaywrightTest("page/expect-misc.spec.ts", "toHaveAccessibleErrorMessage")]
public async Task ToHaveAccessibleErrorMessage()
{
await Page.SetContentAsync(@"
<form>
<input role=""textbox"" aria-invalid=""true"" aria-errormessage=""error-message"" />
<div id=""error-message"">Hello</div>
<div id=""irrelevant-error"">This should not be considered.</div>
</form>");
var locator = Page.Locator("input[role=\"textbox\"]");
await Expect(locator).ToHaveAccessibleErrorMessageAsync("Hello");
await Expect(locator).Not.ToHaveAccessibleErrorMessageAsync("hello");
await Expect(locator).ToHaveAccessibleErrorMessageAsync("hello", new() { IgnoreCase = true });
await Expect(locator).ToHaveAccessibleErrorMessageAsync(new Regex(@"ell\w"));
await Expect(locator).Not.ToHaveAccessibleErrorMessageAsync(new Regex("hello"));
await Expect(locator).ToHaveAccessibleErrorMessageAsync(new Regex("hello"), new() { IgnoreCase = true });
await Expect(locator).Not.ToHaveAccessibleErrorMessageAsync("This should not be considered.");
}


[PlaywrightTest("page/expect-misc.spec.ts", "toHaveAccessibleErrorMessage should handle multiple aria-errormessage reference")]
public async Task ToHaveAccessibleErrorMessageShouldHandleMultipleAriaErrormessageReference()
{
await Page.SetContentAsync(@"
<form>
<input role=""textbox"" aria-invalid=""true"" aria-errormessage=""error1 error2"" />
<div id=""error1"">First error message.</div>
<div id=""error2"">Second error message.</div>
<div id=""irrelevant-error"">This should not be considered.</div>
</form>");
var locator = Page.Locator("input[role=\"textbox\"]");
await Expect(locator).ToHaveAccessibleErrorMessageAsync("First error message. Second error message.");
await Expect(locator).ToHaveAccessibleErrorMessageAsync(new Regex("first error message.", RegexOptions.IgnoreCase));
await Expect(locator).ToHaveAccessibleErrorMessageAsync(new Regex("second error message.", RegexOptions.IgnoreCase));
await Expect(locator).Not.ToHaveAccessibleErrorMessageAsync(new Regex("This should not be considered.", RegexOptions.IgnoreCase));
}

[PlaywrightTest("page/expect-misc.spec.ts", "toHaveRole")]
public async Task ToHaveRole()
{
Expand Down
14 changes: 8 additions & 6 deletions src/Playwright/API/Generated/IBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ public partial interface IBrowser
/// browser and disconnects from the browser server.
/// </para>
/// <para>
/// This is similar to force quitting the browser. Therefore, you should call <see cref="IBrowserContext.CloseAsync"/>
/// on any <see cref="IBrowserContext"/>'s you explicitly created earlier with <see
/// cref="IBrowser.NewContextAsync"/> **before** calling <see cref="IBrowser.CloseAsync"/>.
/// This is similar to force-quitting the browser. To close pages gracefully and ensure
/// you receive page close events, call <see cref="IBrowserContext.CloseAsync"/> on
/// any <see cref="IBrowserContext"/> instances you explicitly created earlier using
/// <see cref="IBrowser.NewContextAsync"/> **before** calling <see cref="IBrowser.CloseAsync"/>.
/// </para>
/// <para>
/// The <see cref="IBrowser"/> object itself is considered to be disposed and cannot
Expand All @@ -84,9 +85,10 @@ public partial interface IBrowser
/// </summary>
/// <remarks>
/// <para>
/// This is similar to force quitting the browser. Therefore, you should call <see cref="IBrowserContext.CloseAsync"/>
/// on any <see cref="IBrowserContext"/>'s you explicitly created earlier with <see
/// cref="IBrowser.NewContextAsync"/> **before** calling <see cref="IBrowser.CloseAsync"/>.
/// This is similar to force-quitting the browser. To close pages gracefully and ensure
/// you receive page close events, call <see cref="IBrowserContext.CloseAsync"/> on
/// any <see cref="IBrowserContext"/> instances you explicitly created earlier using
/// <see cref="IBrowser.NewContextAsync"/> **before** calling <see cref="IBrowser.CloseAsync"/>.
///
/// </para>
/// </remarks>
Expand Down
9 changes: 5 additions & 4 deletions src/Playwright/API/Generated/IBrowserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,12 @@ public partial interface IBrowserContext
/// </para>
/// </summary>
/// <param name="permissions">
/// A permission or an array of permissions to grant. Permissions can be one of the
/// following values:
/// A list of permissions to grant.
/// Supported permissions differ between browsers, and even between different versions
/// of the same browser. Any permission may stop working after an update.
/// Here are some permissions that may be supported by some browsers:
/// <list type="bullet">
/// <item><description><c>'accelerometer'</c></description></item>
/// <item><description><c>'accessibility-events'</c></description></item>
/// <item><description><c>'ambient-light-sensor'</c></description></item>
/// <item><description><c>'background-sync'</c></description></item>
/// <item><description><c>'camera'</c></description></item>
Expand Down Expand Up @@ -862,7 +863,7 @@ public partial interface IBrowserContext
/// <see cref="IBrowserContext.SetDefaultTimeout"/>.
/// </para>
/// </remarks>
/// <param name="timeout">Maximum time in milliseconds</param>
/// <param name="timeout">Maximum time in milliseconds. Pass <c>0</c> to disable timeout.</param>
void SetDefaultTimeout(float timeout);

/// <summary>
Expand Down
12 changes: 12 additions & 0 deletions src/Playwright/API/Generated/IClock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ public partial interface IClock
/// await page.Clock.PauseAtAsync(DateTime.Parse("2020-02-02"));<br/>
/// await page.Clock.PauseAtAsync("2020-02-02");
/// </code>
/// <para>
/// For best results, install the clock before navigating the page and set it to a time
/// slightly before the intended test time. This ensures that all timers run normally
/// during page loading, preventing the page from getting stuck. Once the page has fully
/// loaded, you can safely use <see cref="IClock.PauseAtAsync"/> to pause the clock.
/// </para>
/// </summary>
/// <param name="time">Time to pause at.</param>
Task PauseAtAsync(DateTime time);
Expand All @@ -168,6 +174,12 @@ public partial interface IClock
/// await page.Clock.PauseAtAsync(DateTime.Parse("2020-02-02"));<br/>
/// await page.Clock.PauseAtAsync("2020-02-02");
/// </code>
/// <para>
/// For best results, install the clock before navigating the page and set it to a time
/// slightly before the intended test time. This ensures that all timers run normally
/// during page loading, preventing the page from getting stuck. Once the page has fully
/// loaded, you can safely use <see cref="IClock.PauseAtAsync"/> to pause the clock.
/// </para>
/// </summary>
/// <param name="time">Time to pause at.</param>
Task PauseAtAsync(string time);
Expand Down
27 changes: 23 additions & 4 deletions src/Playwright/API/Generated/ILocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,12 @@ public partial interface ILocator
Task<bool> IsDisabledAsync(LocatorIsDisabledOptions? options = default);

/// <summary>
/// <para>Returns whether the element is <a href="https://playwright.dev/dotnet/docs/actionability#editable">editable</a>.</para>
/// <para>
/// Returns whether the element is <a href="https://playwright.dev/dotnet/docs/actionability#editable">editable</a>.
/// If the target element is not an <c>&lt;input&gt;</c>, <c>&lt;textarea&gt;</c>, <c>&lt;select&gt;</c>,
/// <c>[contenteditable]</c> and does not have a role allowing <c>[aria-readonly]</c>,
/// this method throws an error.
/// </para>
/// <para>
/// If you need to assert that an element is editable, prefer <see cref="ILocatorAssertions.ToBeEditableAsync"/>
/// to avoid flakiness. See <a href="https://playwright.dev/dotnet/docs/test-assertions">assertions
Expand Down Expand Up @@ -1157,24 +1162,38 @@ public partial interface ILocator
/// <para>Creates a locator matching all elements that match one or both of the two locators.</para>
/// <para>
/// Note that when both locators match something, the resulting locator will have multiple
/// matches and violate <a href="https://playwright.dev/dotnet/docs/locators#strictness">locator
/// strictness</a> guidelines.
/// matches, potentially causing a <a href="https://playwright.dev/dotnet/docs/locators#strictness">locator
/// strictness</a> violation.
/// </para>
/// <para>**Usage**</para>
/// <para>
/// Consider a scenario where you'd like to click on a "New email" button, but sometimes
/// a security settings dialog shows up instead. In this case, you can wait for either
/// a "New email" button, or a dialog and act accordingly.
/// </para>
/// <para>
/// If both "New email" button and security dialog appear on screen, the "or" locator
/// will match both of them, possibly throwing the <a href="https://playwright.dev/dotnet/docs/locators#strictness">"strict
/// mode violation" error</a>. In this case, you can use <see cref="ILocator.First"/>
/// to only match one of them.
/// </para>
/// <code>
/// var newEmail = page.GetByRole(AriaRole.Button, new() { Name = "New" });<br/>
/// var dialog = page.GetByText("Confirm security settings");<br/>
/// await Expect(newEmail.Or(dialog)).ToBeVisibleAsync();<br/>
/// await Expect(newEmail.Or(dialog).First).ToBeVisibleAsync();<br/>
/// if (await dialog.IsVisibleAsync())<br/>
/// await page.GetByRole(AriaRole.Button, new() { Name = "Dismiss" }).ClickAsync();<br/>
/// await newEmail.ClickAsync();
/// </code>
/// </summary>
/// <remarks>
/// <para>
/// If both "New email" button and security dialog appear on screen, the "or" locator
/// will match both of them, possibly throwing the <a href="https://playwright.dev/dotnet/docs/locators#strictness">"strict
/// mode violation" error</a>. In this case, you can use <see cref="ILocator.First"/>
/// to only match one of them.
/// </para>
/// </remarks>
/// <param name="locator">Alternative locator to match.</param>
ILocator Or(ILocator locator);

Expand Down
Loading

0 comments on commit df83b16

Please sign in to comment.