Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0e68ca9

Browse files
authoredMar 27, 2024··
feat(roll): roll Playwright to 1.43.0-beta-1711484700000 (#2895)
1 parent 55d726a commit 0e68ca9

20 files changed

+427
-29
lines changed
 

‎README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
| | Linux | macOS | Windows |
55
| :--- | :---: | :---: | :---: |
6-
| Chromium <!-- GEN:chromium-version -->123.0.6312.4<!-- GEN:stop --> ||||
6+
| Chromium <!-- GEN:chromium-version -->124.0.6367.8<!-- GEN:stop --> ||||
77
| WebKit <!-- GEN:webkit-version -->17.4<!-- GEN:stop --> ||||
8-
| Firefox <!-- GEN:firefox-version -->123.0<!-- GEN:stop --> ||||
8+
| Firefox <!-- GEN:firefox-version -->124.0<!-- GEN:stop --> ||||
99

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

‎src/Common/Version.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<AssemblyVersion>1.42.0</AssemblyVersion>
44
<PackageVersion>$(AssemblyVersion)</PackageVersion>
5-
<DriverVersion>1.42.1</DriverVersion>
5+
<DriverVersion>1.43.0-beta-1711484700000</DriverVersion>
66
<ReleaseVersion>$(AssemblyVersion)</ReleaseVersion>
77
<FileVersion>$(AssemblyVersion)</FileVersion>
88
<NoDefaultExcludes>true</NoDefaultExcludes>

‎src/Playwright.Tests/BrowserContextClearCookiesTests.cs

+149
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* SOFTWARE.
2424
*/
2525

26+
using System.Text.RegularExpressions;
27+
2628
namespace Microsoft.Playwright.Tests;
2729

2830
public class BrowserContextClearCookiesTests : PageTestEx
@@ -82,4 +84,151 @@ await anotherContext.AddCookiesAsync(new[]
8284
Assert.IsEmpty(await Context.CookiesAsync());
8385
Assert.IsEmpty(await anotherContext.CookiesAsync());
8486
}
87+
88+
[PlaywrightTest("browsercontext-clearcookies.spec.ts", "should remove cookies by name")]
89+
public async Task ShouldRemoveCookiesByName()
90+
{
91+
await Context.AddCookiesAsync(
92+
[
93+
new Cookie
94+
{
95+
Name = "cookie1",
96+
Value = "1",
97+
Domain = new Uri(Server.Prefix).Host,
98+
Path = "/"
99+
},
100+
new Cookie
101+
{
102+
Name = "cookie2",
103+
Value = "2",
104+
Domain = new Uri(Server.Prefix).Host,
105+
Path = "/"
106+
}
107+
]);
108+
await Page.GotoAsync(Server.Prefix);
109+
Assert.AreEqual("cookie1=1; cookie2=2", await Page.EvaluateAsync<string>("document.cookie"));
110+
await Context.ClearCookiesAsync(new() { Name = "cookie1" });
111+
Assert.AreEqual("cookie2=2", await Page.EvaluateAsync<string>("document.cookie"));
112+
}
113+
114+
[PlaywrightTest("browsercontext-clearcookies.spec.ts", "should remove cookies by name regex")]
115+
public async Task ShouldRemoveCookiesByNameRegex()
116+
{
117+
await Context.AddCookiesAsync(
118+
[
119+
new Cookie
120+
{
121+
Name = "cookie1",
122+
Value = "1",
123+
Domain = new Uri(Server.Prefix).Host,
124+
Path = "/"
125+
},
126+
new Cookie
127+
{
128+
Name = "cookie2",
129+
Value = "2",
130+
Domain = new Uri(Server.Prefix).Host,
131+
Path = "/"
132+
}
133+
]);
134+
await Page.GotoAsync(Server.Prefix);
135+
Assert.AreEqual("cookie1=1; cookie2=2", await Page.EvaluateAsync<string>("document.cookie"));
136+
await Context.ClearCookiesAsync(new() { NameRegex = new Regex("coo.*1") });
137+
Assert.AreEqual("cookie2=2", await Page.EvaluateAsync<string>("document.cookie"));
138+
}
139+
140+
[PlaywrightTest("browsercontext-clearcookies.spec.ts", "should remove cookies by domain")]
141+
public async Task ShouldRemoveCookiesByDomain()
142+
{
143+
await Context.AddCookiesAsync(
144+
[
145+
new Cookie
146+
{
147+
Name = "cookie1",
148+
Value = "1",
149+
Domain = new Uri(Server.Prefix).Host,
150+
Path = "/"
151+
},
152+
new Cookie
153+
{
154+
Name = "cookie2",
155+
Value = "2",
156+
Domain = new Uri(Server.CrossProcessPrefix).Host,
157+
Path = "/"
158+
}
159+
]);
160+
await Page.GotoAsync(Server.Prefix);
161+
Assert.AreEqual("cookie1=1", await Page.EvaluateAsync<string>("document.cookie"));
162+
await Page.GotoAsync(Server.CrossProcessPrefix);
163+
Assert.AreEqual("cookie2=2", await Page.EvaluateAsync<string>("document.cookie"));
164+
await Context.ClearCookiesAsync(new() { Domain = new Uri(Server.CrossProcessPrefix).Host });
165+
Assert.IsEmpty(await Page.EvaluateAsync<string>("document.cookie"));
166+
await Page.GotoAsync(Server.Prefix);
167+
Assert.AreEqual("cookie1=1", await Page.EvaluateAsync<string>("document.cookie"));
168+
}
169+
170+
[PlaywrightTest("browsercontext-clearcookies.spec.ts", "should remove cookies by path")]
171+
public async Task ShouldRemoveCookiesByPath()
172+
{
173+
await Context.AddCookiesAsync(
174+
[
175+
new Cookie
176+
{
177+
Name = "cookie1",
178+
Value = "1",
179+
Domain = new Uri(Server.Prefix).Host,
180+
Path = "/api/v1"
181+
},
182+
new Cookie
183+
{
184+
Name = "cookie2",
185+
Value = "2",
186+
Domain = new Uri(Server.Prefix).Host,
187+
Path = "/api/v2"
188+
},
189+
new Cookie
190+
{
191+
Name = "cookie3",
192+
Value = "3",
193+
Domain = new Uri(Server.Prefix).Host,
194+
Path = "/"
195+
}
196+
]);
197+
await Page.GotoAsync(Server.Prefix + "/api/v1");
198+
Assert.AreEqual("cookie1=1; cookie3=3", await Page.EvaluateAsync<string>("document.cookie"));
199+
await Context.ClearCookiesAsync(new() { Path = "/api/v1" });
200+
Assert.AreEqual("cookie3=3", await Page.EvaluateAsync<string>("document.cookie"));
201+
await Page.GotoAsync(Server.Prefix + "/api/v2");
202+
Assert.AreEqual("cookie2=2; cookie3=3", await Page.EvaluateAsync<string>("document.cookie"));
203+
await Page.GotoAsync(Server.Prefix + "/");
204+
Assert.AreEqual("cookie3=3", await Page.EvaluateAsync<string>("document.cookie"));
205+
}
206+
207+
[PlaywrightTest("browsercontext-clearcookies.spec.ts", "should remove cookies by name and domain")]
208+
public async Task ShouldRemoveCookiesByNameAndDomain()
209+
{
210+
await Context.AddCookiesAsync(
211+
[
212+
new Cookie
213+
{
214+
Name = "cookie1",
215+
Value = "1",
216+
Domain = new Uri(Server.Prefix).Host,
217+
Path = "/"
218+
},
219+
new Cookie
220+
{
221+
Name = "cookie1",
222+
Value = "1",
223+
Domain = new Uri(Server.CrossProcessPrefix).Host,
224+
Path = "/"
225+
}
226+
]);
227+
await Page.GotoAsync(Server.Prefix);
228+
Assert.AreEqual("cookie1=1", await Page.EvaluateAsync<string>("document.cookie"));
229+
await Context.ClearCookiesAsync(new() { Name = "cookie1", Domain = new Uri(Server.Prefix).Host });
230+
Assert.IsEmpty(await Page.EvaluateAsync<string>("document.cookie"));
231+
await Page.GotoAsync(Server.CrossProcessPrefix);
232+
Assert.AreEqual("cookie1=1", await Page.EvaluateAsync<string>("document.cookie"));
233+
}
85234
}

‎src/Playwright.Tests/BrowserContextStorageStateTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ await page1.EvaluateAsync(@"() =>
4949
string storage = await Context.StorageStateAsync();
5050

5151
// TODO: think about IVT-in the StorageState and serializing
52-
string expected = @"{""cookies"":[],""origins"":[{""origin"":""https://www.example.com"",""localStorage"":[{""name"":""name1"",""value"":""value1""}]},{""origin"":""https://www.domain.com"",""localStorage"":[{""name"":""name2"",""value"":""value2""}]}]}";
52+
string expected = @"{""cookies"":[],""origins"":[{""origin"":""https://www.domain.com"",""localStorage"":[{""name"":""name2"",""value"":""value2""}]},{""origin"":""https://www.example.com"",""localStorage"":[{""name"":""name1"",""value"":""value1""}]}]}";
5353
Assert.AreEqual(expected, storage);
5454
}
5555

‎src/Playwright.Tests/ElementHandleMiscTests.cs

+9
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,13 @@ public async Task ShouldCheckTheBoxUsingSetChecked()
115115
Assert.IsFalse(await Page.EvaluateAsync<bool>("checkbox.checked"));
116116
}
117117

118+
[PlaywrightTest("elementhandle-misc.spec.ts", "should allow disposing twice")]
119+
public async Task ShouldAllowDisposingTwice()
120+
{
121+
await Page.SetContentAsync("<section>39</section>");
122+
var element = await Page.QuerySelectorAsync("section");
123+
Assert.NotNull(element);
124+
await element.DisposeAsync();
125+
await element.DisposeAsync();
126+
}
118127
}

‎src/Playwright.Tests/Locator/LocatorFrameTests.cs

+25-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ await page.RouteAsync("**/empty.html", async route =>
3333
{
3434
await route.FulfillAsync(new()
3535
{
36-
Body = "<iframe src=\"/iframe.html\"></iframe>",
36+
Body = "<iframe src=\"/iframe.html\" name=\"frame1\"></iframe>",
3737
ContentType = "text/html"
3838
});
3939
});
@@ -309,4 +309,28 @@ public async Task LocatorFrameLocatorShouldNotThrowOnFirstLastNth()
309309
var button3 = Page.Locator("body").FrameLocator("iframe").Last.Locator("button");
310310
await Expect(button3).ToHaveTextAsync("Hello from iframe-3.html");
311311
}
312+
313+
[PlaywrightTest("locator-frame.spec.ts", "locator.contentFrame should work")]
314+
public async Task LocatorContentFrameShouldWork()
315+
{
316+
await RouteIFrame(Page);
317+
await Page.GotoAsync(Server.EmptyPage);
318+
var locator = Page.Locator("iframe");
319+
var frameLocator = locator.ContentFrame;
320+
var button = frameLocator.Locator("button");
321+
Assert.AreEqual(await button.InnerTextAsync(), "Hello iframe");
322+
await Expect(button).ToHaveTextAsync("Hello iframe");
323+
await button.ClickAsync();
324+
}
325+
326+
[PlaywrightTest("locator-frame.spec.ts", "frameLocator.Owner should work")]
327+
public async Task FrameLocatorOwnerShouldWork()
328+
{
329+
await RouteIFrame(Page);
330+
await Page.GotoAsync(Server.EmptyPage);
331+
var frameLocator = Page.FrameLocator("iframe");
332+
var locator = frameLocator.Owner;
333+
await Expect(locator).ToBeVisibleAsync();
334+
Assert.AreEqual(await locator.GetAttributeAsync("name"), "frame1");
335+
}
312336
}

‎src/Playwright.Tests/PageNetworkRequestTest.cs

+17
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ public async Task ShouldParseTheDataIfContentTypeIsApplicationXWwwFormUrlencoded
165165
Assert.AreEqual("123", element?.GetProperty("baz").ToString());
166166
}
167167

168+
[PlaywrightTest("page-network-request.spec.ts", "should parse the data if content-type is application/x-www-form-urlencoded; charset=UTF-8")]
169+
public async Task ShouldParseTheDataIfContentTypeIsApplicationXWwwFormUrlencodedCharsetUTF8()
170+
{
171+
await Page.GotoAsync(Server.EmptyPage);
172+
var requestPromise = Page.WaitForRequestAsync("**/post");
173+
await Page.EvaluateAsync(@"() => fetch('./post', {
174+
method: 'POST',
175+
headers: {
176+
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
177+
},
178+
body: 'foo=bar&baz=123'
179+
})");
180+
var request = await requestPromise;
181+
Assert.AreEqual("bar", request.PostDataJSON()?.GetProperty("foo").ToString());
182+
Assert.AreEqual("123", request.PostDataJSON()?.GetProperty("baz").ToString());
183+
}
184+
168185
[PlaywrightTest("page-network-request.spec.ts", "should be |undefined| when there is no post data")]
169186
public async Task ShouldBeUndefinedWhenThereIsNoPostData2()
170187
{

‎src/Playwright/API/Generated/IBrowserContext.cs

+23-7
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,12 @@ public partial interface IBrowserContext
9898
/// waiting for the dialog, and actions like click will never finish.
9999
/// </para>
100100
/// <para>**Usage**</para>
101-
/// <code>context.Dialog += (_, dialog) =&gt; dialog.AcceptAsync();</code>
101+
/// <code>
102+
/// Context.Dialog += async (_, dialog) =&gt;<br/>
103+
/// {<br/>
104+
/// await dialog.AcceptAsync();<br/>
105+
/// };
106+
/// </code>
102107
/// </summary>
103108
/// <remarks>
104109
/// <para>
@@ -222,7 +227,7 @@ public partial interface IBrowserContext
222227
/// </para>
223228
/// <para>**Usage**</para>
224229
/// <para>An example of overriding <c>Math.random</c> before the page loads:</para>
225-
/// <code>await context.AddInitScriptAsync(scriptPath: "preload.js");</code>
230+
/// <code>await Context.AddInitScriptAsync(scriptPath: "preload.js");</code>
226231
/// </summary>
227232
/// <remarks>
228233
/// <para>
@@ -242,8 +247,19 @@ public partial interface IBrowserContext
242247
/// </summary>
243248
IBrowser? Browser { get; }
244249

245-
/// <summary><para>Clears context cookies.</para></summary>
246-
Task ClearCookiesAsync();
250+
/// <summary>
251+
/// <para>Removes cookies from context. Accepts optional filter.</para>
252+
/// <para>**Usage**</para>
253+
/// <code>
254+
/// await context.ClearCookiesAsync();<br/>
255+
/// await context.ClearCookiesAsync(new() { Name = "session-id" });<br/>
256+
/// await context.ClearCookiesAsync(new() { Domain = "my-origin.com" });<br/>
257+
/// await context.ClearCookiesAsync(new() { Path = "/api/v1" });<br/>
258+
/// await context.ClearCookiesAsync(new() { Name = "session-id", Domain = "my-origin.com" });
259+
/// </code>
260+
/// </summary>
261+
/// <param name="options">Call options</param>
262+
Task ClearCookiesAsync(BrowserContextClearCookiesOptions? options = default);
247263

248264
/// <summary>
249265
/// <para>Clears all permission overrides for the browser context.</para>
@@ -479,7 +495,7 @@ public partial interface IBrowserContext
479495
/// await page.RouteAsync("/api/**", async r =&gt;<br/>
480496
/// {<br/>
481497
/// if (r.Request.PostData.Contains("my-string"))<br/>
482-
/// await r.FulfillAsync(body: "mocked-data");<br/>
498+
/// await r.FulfillAsync(new() { Body = "mocked-data" });<br/>
483499
/// else<br/>
484500
/// await r.ContinueAsync();<br/>
485501
/// });
@@ -540,7 +556,7 @@ public partial interface IBrowserContext
540556
/// await page.RouteAsync("/api/**", async r =&gt;<br/>
541557
/// {<br/>
542558
/// if (r.Request.PostData.Contains("my-string"))<br/>
543-
/// await r.FulfillAsync(body: "mocked-data");<br/>
559+
/// await r.FulfillAsync(new() { Body = "mocked-data" });<br/>
544560
/// else<br/>
545561
/// await r.ContinueAsync();<br/>
546562
/// });
@@ -601,7 +617,7 @@ public partial interface IBrowserContext
601617
/// await page.RouteAsync("/api/**", async r =&gt;<br/>
602618
/// {<br/>
603619
/// if (r.Request.PostData.Contains("my-string"))<br/>
604-
/// await r.FulfillAsync(body: "mocked-data");<br/>
620+
/// await r.FulfillAsync(new() { Body = "mocked-data" });<br/>
605621
/// else<br/>
606622
/// await r.ContinueAsync();<br/>
607623
/// });

‎src/Playwright/API/Generated/IFrameLocator.cs

+26-3
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,13 @@ namespace Microsoft.Playwright;
5454
/// <para>**Converting Locator to FrameLocator**</para>
5555
/// <para>
5656
/// If you have a <see cref="ILocator"/> object pointing to an <c>iframe</c> it can
57-
/// be converted to <see cref="IFrameLocator"/> using <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:scope"><c>:scope</c></a>
58-
/// CSS selector:
57+
/// be converted to <see cref="IFrameLocator"/> using <see cref="ILocator.ContentFrame"/>.
58+
/// </para>
59+
/// <para>**Converting FrameLocator to Locator**</para>
60+
/// <para>
61+
/// If you have a <see cref="IFrameLocator"/> object it can be converted to <see cref="ILocator"/>
62+
/// pointing to the same <c>iframe</c> using <see cref="IFrameLocator.Owner"/>.
5963
/// </para>
60-
/// <code>var frameLocator = locator.FrameLocator(":scope");</code>
6164
/// </summary>
6265
public partial interface IFrameLocator
6366
{
@@ -370,6 +373,26 @@ public partial interface IFrameLocator
370373
/// <param name="index">
371374
/// </param>
372375
IFrameLocator Nth(int index);
376+
377+
/// <summary>
378+
/// <para>
379+
/// Returns a <see cref="ILocator"/> object pointing to the same <c>iframe</c> as this
380+
/// frame locator.
381+
/// </para>
382+
/// <para>
383+
/// Useful when you have a <see cref="IFrameLocator"/> object obtained somewhere, and
384+
/// later on would like to interact with the <c>iframe</c> element.
385+
/// </para>
386+
/// <para>For a reverse operation, use <see cref="ILocator.ContentFrame"/>.</para>
387+
/// <para>**Usage**</para>
388+
/// <code>
389+
/// var frameLocator = Page.FrameLocator("iframe[name=\"embedded\"]");<br/>
390+
/// // ...<br/>
391+
/// var locator = frameLocator.Owner;<br/>
392+
/// await Expect(locator).ToBeVisibleAsync();
393+
/// </code>
394+
/// </summary>
395+
ILocator Owner { get; }
373396
}
374397

375398
#nullable disable

0 commit comments

Comments
 (0)
Please sign in to comment.