Skip to content

Commit a45498a

Browse files
TanayParikhMackinnonBuck
authored andcommitted
Upgrade Playwright
Cherry-pick of #38414
1 parent a9f3592 commit a45498a

19 files changed

+158
-179
lines changed

.config/dotnet-tools.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
"isRoot": true,
44
"tools": {
55
"dotnet-serve": {
6-
"version": "1.7.139",
6+
"version": "1.8.15",
77
"commands": [
88
"dotnet-serve"
99
]
1010
},
11-
"playwright-sharp-tool": {
12-
"version": "0.170.2",
11+
"Microsoft.Playwright.CLI": {
12+
"version": "1.2.2",
1313
"commands": [
14-
"playwright-sharp"
14+
"playwright"
1515
]
1616
}
1717
}

eng/Dependencies.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ and are generated based on the last package release.
188188
<LatestPackageReference Include="NuGet.Frameworks" />
189189
<LatestPackageReference Include="NuGet.Versioning" />
190190
<LatestPackageReference Include="Photino.NET" />
191-
<LatestPackageReference Include="PlaywrightSharp" />
191+
<LatestPackageReference Include="Microsoft.Playwright" />
192192
<LatestPackageReference Include="Polly" />
193193
<LatestPackageReference Include="Polly.Extensions.Http" />
194194
<LatestPackageReference Include="Selenium.Support" />

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@
249249
<NewtonsoftJsonVersion>13.0.1</NewtonsoftJsonVersion>
250250
<NSwagApiDescriptionClientVersion>13.0.4</NSwagApiDescriptionClientVersion>
251251
<PhotinoNETVersion>1.1.6</PhotinoNETVersion>
252-
<PlaywrightSharpVersion>0.192.0</PlaywrightSharpVersion>
252+
<MicrosoftPlaywrightVersion>1.17.3</MicrosoftPlaywrightVersion>
253253
<PollyExtensionsHttpVersion>3.0.0</PollyExtensionsHttpVersion>
254254
<PollyVersion>7.2.2</PollyVersion>
255255
<SeleniumSupportVersion>4.3.0</SeleniumSupportVersion>

eng/helix/content/RunTests/RunTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88

99
<ItemGroup>
1010
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20158.1" />
11-
<PackageReference Condition=" '$(InstallPlaywright)' == 'true' " Include="PlaywrightSharp" Version="0.192.0" />
11+
<PackageReference Condition=" '$(InstallPlaywright)' == 'true' " Include="Microsoft.Playwright" Version="1.17.3" />
1212
</ItemGroup>
1313
</Project>

eng/helix/content/RunTests/TestRunner.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
using System.Threading;
1010
using System.Threading.Tasks;
1111
#if INSTALLPLAYWRIGHT
12-
using PlaywrightSharp;
12+
using Microsoft.Playwright;
1313
#endif
1414

1515
namespace RunTests
@@ -55,9 +55,6 @@ public bool SetupEnvironment()
5555
var playwrightBrowsers = Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH");
5656
ProcessUtil.PrintMessage($"Setting PLAYWRIGHT_BROWSERS_PATH: {playwrightBrowsers}");
5757
EnvironmentVariables.Add("PLAYWRIGHT_BROWSERS_PATH", playwrightBrowsers);
58-
var playrightDriver = Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH");
59-
ProcessUtil.PrintMessage($"Setting PLAYWRIGHT_DRIVER_PATH: {playrightDriver}");
60-
EnvironmentVariables.Add("PLAYWRIGHT_DRIVER_PATH", playrightDriver);
6158
#else
6259
ProcessUtil.PrintMessage($"Skipping setting PLAYWRIGHT_BROWSERS_PATH");
6360
#endif
@@ -112,8 +109,10 @@ public async Task<bool> InstallPlaywrightAsync()
112109
{
113110
try
114111
{
115-
ProcessUtil.PrintMessage($"Installing Playwright to Browsers: {Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH")} Driver: {Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH")}");
116-
await Playwright.InstallAsync(Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH"), Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH"));
112+
Console.WriteLine($"Installing Playwright Browsers to {Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH")}");
113+
114+
var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
115+
117116
DisplayContents(Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH"));
118117
return true;
119118
}

eng/helix/content/runtests.cmd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
1616
set DOTNET_MULTILEVEL_LOOKUP=0
1717
set InstallPlaywright=%$installPlaywright%
1818
set PLAYWRIGHT_BROWSERS_PATH=%CD%\ms-playwright
19-
set PLAYWRIGHT_DRIVER_PATH=%CD%\.playwright\win-x64\native\playwright.cmd
2019

2120
REM Avoid https://github.com/dotnet/aspnetcore/issues/41937 in current session.
2221
set ASPNETCORE_ENVIRONMENT=

eng/helix/content/runtests.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export PATH="$PATH:$DIR:$DIR/node/bin"
2121
# Set playwright stuff
2222
export PLAYWRIGHT_BROWSERS_PATH="$DIR/ms-playwright"
2323
if [[ "$helixQueue" == *"OSX"* ]]; then
24-
export PLAYWRIGHT_DRIVER_PATH="$DIR/.playwright/osx/native/playwright.sh"
2524
PLAYWRIGHT_NODE_PATH=$DIR/.playwright/osx/native/node
2625
else
2726
export PLAYWRIGHT_DRIVER_PATH="$DIR/.playwright/unix/native/playwright.sh"

src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using System.Threading.Tasks;
99
using Microsoft.AspNetCore.BrowserTesting;
1010
using Microsoft.AspNetCore.Testing;
11-
using PlaywrightSharp;
11+
using Microsoft.Playwright;
1212
using ProjectTemplates.Tests.Infrastructure;
1313
using Templates.Test.Helpers;
1414
using Xunit;
@@ -137,20 +137,31 @@ public async Task BlazorServerTemplateWorks_IndividualAuth(BrowserKind browserKi
137137

138138
private async Task TestBasicNavigation(Project project, IPage page)
139139
{
140-
var socket = BrowserContextInfo.Pages[page].WebSockets.SingleOrDefault() ??
141-
(await page.WaitForEventAsync(PageEvent.WebSocket)).WebSocket;
140+
var socket = await page.WaitForWebSocketAsync();
141+
142+
var framesReceived = 0;
143+
var framesSent = 0;
144+
145+
void FrameReceived(object sender, IWebSocketFrame frame) { framesReceived++; }
146+
void FrameSent(object sender, IWebSocketFrame frame) { framesSent++; }
147+
148+
socket.FrameReceived += FrameReceived;
149+
socket.FrameSent += FrameSent;
142150

143151
// Receive render batch
144-
await socket.WaitForEventAsync(WebSocketEvent.FrameReceived);
145-
await socket.WaitForEventAsync(WebSocketEvent.FrameSent);
152+
await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesReceived == 1 });
153+
await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesSent == 1 });
146154

147155
// JS interop call to intercept navigation
148-
await socket.WaitForEventAsync(WebSocketEvent.FrameReceived);
149-
await socket.WaitForEventAsync(WebSocketEvent.FrameSent);
156+
await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesReceived == 2 });
157+
await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesSent == 2 });
158+
159+
socket.FrameReceived -= FrameReceived;
160+
socket.FrameSent -= FrameSent;
150161

151162
await page.WaitForSelectorAsync("nav");
152163
// <title> element gets project ID injected into it during template execution
153-
Assert.Equal("Index", (await page.GetTitleAsync()).Trim());
164+
Assert.Equal("Index", (await page.TitleAsync()).Trim());
154165

155166
// Initially displays the home page
156167
await page.WaitForSelectorAsync("h1 >> text=Hello, world!");
@@ -169,7 +180,7 @@ private async Task TestBasicNavigation(Project project, IPage page)
169180

170181
// Asynchronously loads and displays the table of weather forecasts
171182
await page.WaitForSelectorAsync("table>tbody>tr");
172-
Assert.Equal(5, (await page.QuerySelectorAllAsync("p+table>tbody>tr")).Count());
183+
Assert.Equal(5, await page.Locator("p+table>tbody>tr").CountAsync());
173184
}
174185

175186
[Theory]

src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
<Reference Include="Microsoft.Extensions.Configuration.Json" />
4848
<Reference Include="AngleSharp" />
4949
<Reference Include="System.Net.Http" />
50-
<Reference Include="PlaywrightSharp" Condition="'$(TargetOsName)' != 'linux-musl'" />
51-
<Reference Include="PlaywrightSharp" ExcludeAssets="build" Condition="'$(TargetOsName)' == 'linux-musl'" />
50+
<Reference Include="Microsoft.Playwright" Condition="'$(TargetOsName)' != 'linux-musl'" />
51+
<Reference Include="Microsoft.Playwright" ExcludeAssets="build" Condition="'$(TargetOsName)' == 'linux-musl'" />
5252
<ProjectReference Include="$(RepoRoot)src\Framework\App.Runtime\src\Microsoft.AspNetCore.App.Runtime.csproj">
5353
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
5454
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>

src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
using Microsoft.AspNetCore.Testing;
1717
using Microsoft.Extensions.CommandLineUtils;
1818
using Newtonsoft.Json.Linq;
19-
using PlaywrightSharp;
19+
using Microsoft.Playwright;
2020
using Templates.Test.Helpers;
2121
using Xunit;
2222
using Xunit.Abstractions;
@@ -64,7 +64,7 @@ public async Task BlazorWasmStandaloneTemplate_Works(BrowserKind browserKind)
6464
private async Task<IPage> NavigateToPage(IBrowserContext browser, string listeningUri)
6565
{
6666
var page = await browser.NewPageAsync();
67-
await page.GoToAsync(listeningUri, LifecycleEvent.Networkidle);
67+
await page.GotoAsync(listeningUri, new() { WaitUntil = WaitUntilState.NetworkIdle });
6868
return page;
6969
}
7070

@@ -141,9 +141,9 @@ public async Task BlazorWasmStandalonePwaTemplate_Works(BrowserKind browserKind)
141141

142142
// The PWA template supports offline use. By now, the browser should have cached everything it needs,
143143
// so we can continue working even without the server.
144-
await page.GoToAsync("about:blank");
144+
await page.GotoAsync("about:blank");
145145
await browser.SetOfflineAsync(true);
146-
await page.GoToAsync(listeningUri);
146+
await page.GotoAsync(listeningUri);
147147
await TestBasicNavigation(project.ProjectName, page, skipFetchData: true);
148148
await page.CloseAsync();
149149
}
@@ -189,9 +189,9 @@ public async Task BlazorWasmHostedPwaTemplate_Works(BrowserKind browserKind)
189189
// The PWA template supports offline use. By now, the browser should have cached everything it needs,
190190
// so we can continue working even without the server.
191191
// Since this is the hosted project, backend APIs won't work offline, so we need to skip "fetchdata"
192-
await page.GoToAsync("about:blank");
192+
await page.GotoAsync("about:blank");
193193
await browser.SetOfflineAsync(true);
194-
await page.GoToAsync(listeningUri);
194+
await page.GotoAsync(listeningUri);
195195
await TestBasicNavigation(project.ProjectName, page, skipFetchData: true);
196196
await page.CloseAsync();
197197
}
@@ -424,11 +424,11 @@ private async Task TestBasicNavigation(string appName, IPage page, bool usesAuth
424424
// Initially displays the home page
425425
await page.WaitForSelectorAsync("h1 >> text=Hello, world!");
426426

427-
Assert.Equal("Index", (await page.GetTitleAsync()).Trim());
427+
Assert.Equal("Index", (await page.TitleAsync()).Trim());
428428

429429
// Can navigate to the counter page
430430
await Task.WhenAll(
431-
page.WaitForNavigationAsync("**/counter"),
431+
page.WaitForNavigationAsync(new() { UrlString = "**/counter" }),
432432
page.WaitForSelectorAsync("h1 >> text=Counter"),
433433
page.WaitForSelectorAsync("p >> text=Current count: 0"),
434434
page.ClickAsync("a[href=counter]"));
@@ -441,12 +441,12 @@ await Task.WhenAll(
441441
if (usesAuth)
442442
{
443443
await Task.WhenAll(
444-
page.WaitForNavigationAsync("**/Identity/Account/Login**", LifecycleEvent.Networkidle),
444+
page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/Login**", WaitUntil = LifecycleEvent.Networkidle }),
445445
page.ClickAsync("text=Log in"));
446446

447447
await Task.WhenAll(
448448
page.WaitForSelectorAsync("[name=\"Input.Email\"]"),
449-
page.WaitForNavigationAsync("**/Identity/Account/Register**", LifecycleEvent.Networkidle),
449+
page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/Register**", WaitUntil = LifecycleEvent.Networkidle }),
450450
page.ClickAsync("text=Register as a new user"));
451451

452452
var userName = $"{Guid.NewGuid()}@example.com";
@@ -458,12 +458,12 @@ await Task.WhenAll(
458458

459459
// We will be redirected to the RegisterConfirmation
460460
await Task.WhenAll(
461-
page.WaitForNavigationAsync("**/Identity/Account/RegisterConfirmation**", LifecycleEvent.Networkidle),
461+
page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/RegisterConfirmation**", WaitUntil = LifecycleEvent.Networkidle }),
462462
page.ClickAsync("#registerSubmit"));
463463

464464
// We will be redirected to the ConfirmEmail
465465
await Task.WhenAll(
466-
page.WaitForNavigationAsync("**/Identity/Account/ConfirmEmail**", LifecycleEvent.Networkidle),
466+
page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/ConfirmEmail**", WaitUntil = LifecycleEvent.Networkidle }),
467467
page.ClickAsync("text=Click here to confirm your account"));
468468

469469
// Now we can login
@@ -474,21 +474,21 @@ await Task.WhenAll(
474474
await page.ClickAsync("#login-submit");
475475

476476
// Need to navigate to fetch page
477-
await page.GoToAsync(new Uri(page.Url).GetLeftPart(UriPartial.Authority));
478-
Assert.Equal(appName.Trim(), (await page.GetTitleAsync()).Trim());
477+
await page.GotoAsync(new Uri(page.Url).GetLeftPart(UriPartial.Authority));
478+
Assert.Equal(appName.Trim(), (await page.TitleAsync()).Trim());
479479
}
480480

481481
if (!skipFetchData)
482482
{
483483
// Can navigate to the 'fetch data' page
484484
await Task.WhenAll(
485-
page.WaitForNavigationAsync("**/fetchdata"),
485+
page.WaitForNavigationAsync(new() { UrlString = "**/fetchdata" }),
486486
page.WaitForSelectorAsync("h1 >> text=Weather forecast"),
487487
page.ClickAsync("text=Fetch data"));
488488

489489
// Asynchronously loads and displays the table of weather forecasts
490490
await page.WaitForSelectorAsync("table>tbody>tr");
491-
Assert.Equal(5, (await page.QuerySelectorAllAsync("p+table>tbody>tr")).Count());
491+
Assert.Equal(5, await page.Locator("p+table>tbody>tr").CountAsync());
492492
}
493493
}
494494

src/ProjectTemplates/BlazorTemplates.Tests/playwrightSettings.json

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,18 @@
44
"BaseArtifactsFolder": ".",
55
"GlobalBrowserOptions": {
66
"ChromiumSandbox": true,
7-
"DumpIO": true,
8-
"IgnoreHTTPSErrors": true,
97
"Headless": true,
108
"Timeout": 30000
119
},
1210
"GlobalContextOptions": {
13-
"RecordVideo": {
14-
"Dir": "videos"
15-
},
16-
"RecordHar": {
17-
"Path": "har"
18-
},
11+
"RecordVideoDir": "videos",
12+
"RecordHarPath": "har",
1913
"IgnoreHTTPSErrors": true
2014
},
2115
"BrowserOptions": {
2216
"Chromium": {
2317
"BrowserKind": "Chromium",
24-
"IsEnabled": true,
25-
"Args": {
26-
"--ignore-certificate-errors": true
27-
}
18+
"IsEnabled": true
2819
},
2920
"Firefox": {
3021
"BrowserKind": "Firefox",

src/ProjectTemplates/Shared/AspNetProcess.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
using Microsoft.Extensions.CommandLineUtils;
1818
using Microsoft.Extensions.Logging;
1919
using Microsoft.Extensions.Logging.Abstractions;
20-
using PlaywrightSharp;
20+
using Microsoft.Playwright;
2121
using Xunit;
2222
using Xunit.Abstractions;
2323

@@ -109,7 +109,7 @@ public AspNetProcess(
109109
public async Task VisitInBrowserAsync(IPage page)
110110
{
111111
_output.WriteLine($"Opening browser at {ListeningUri}...");
112-
await page.GoToAsync(ListeningUri.AbsoluteUri);
112+
await page.GotoAsync(ListeningUri.AbsoluteUri);
113113
}
114114

115115

src/Shared/BrowserTesting/src/BrowserManager.cs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
using System.Threading.Tasks;
1010
using Microsoft.Extensions.Configuration;
1111
using Microsoft.Extensions.Logging;
12-
using PlaywrightSharp;
12+
using Microsoft.Playwright;
1313

1414
namespace Microsoft.AspNetCore.BrowserTesting
1515
{
@@ -47,20 +47,12 @@ private async Task InitializeAsync()
4747

4848
async Task InitializeCore()
4949
{
50-
var driverPath = Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH");
51-
if (!string.IsNullOrEmpty(driverPath))
52-
{
53-
Playwright = await PlaywrightSharp.Playwright.CreateAsync(_loggerFactory, driverExecutablePath: driverPath, debug: "pw:api");
54-
}
55-
else
56-
{
57-
Playwright = await PlaywrightSharp.Playwright.CreateAsync(_loggerFactory, debug: "pw:api");
58-
}
50+
Playwright = await Microsoft.Playwright.Playwright.CreateAsync();
5951
foreach (var (browserName, options) in _browserManagerConfiguration.BrowserOptions)
6052
{
6153
if (!_launchBrowsers.ContainsKey(browserName))
6254
{
63-
var effectiveLaunchOptions = _browserManagerConfiguration.GetLaunchOptions(options.BrowserLaunchOptions);
55+
var effectiveLaunchOptions = _browserManagerConfiguration.GetBrowserTypeLaunchOptions(options.BrowserLaunchOptions);
6456

6557
var browser = options.BrowserKind switch
6658
{
@@ -108,10 +100,10 @@ public Task<IBrowserContext> GetBrowserInstance(string browserInstance, string c
108100
contextInfo);
109101
}
110102

111-
public Task<IBrowserContext> GetBrowserInstance(BrowserKind browserInstance, string contextName, BrowserContextOptions options, ContextInformation contextInfo) =>
103+
public Task<IBrowserContext> GetBrowserInstance(BrowserKind browserInstance, string contextName, BrowserNewContextOptions options, ContextInformation contextInfo) =>
112104
GetBrowserInstance(browserInstance.ToString(), contextName, options, contextInfo);
113105

114-
public Task<IBrowserContext> GetBrowserInstance(string browserInstance, string contextName, BrowserContextOptions options, ContextInformation contextInfo)
106+
public Task<IBrowserContext> GetBrowserInstance(string browserInstance, string contextName, BrowserNewContextOptions options, ContextInformation contextInfo)
115107
{
116108
if (_launchBrowsers.TryGetValue(browserInstance, out var browser))
117109
{
@@ -126,9 +118,10 @@ public Task<IBrowserContext> GetBrowserInstance(string browserInstance, string c
126118
private async Task<IBrowserContext> AttachContextInfo(Task<IBrowserContext> browserContextTask, ContextInformation contextInfo)
127119
{
128120
var context = await browserContextTask;
129-
context.DefaultTimeout = HasFailedTests ?
121+
var defaultTimeout = HasFailedTests ?
130122
_browserManagerConfiguration.TimeoutAfterFirstFailureInMilliseconds:
131123
_browserManagerConfiguration.TimeoutInMilliseconds;
124+
context.SetDefaultTimeout(defaultTimeout);
132125

133126
contextInfo.Attach(context);
134127
return context;

0 commit comments

Comments
 (0)