diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 7010490e921e..00a32e6c111f 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,15 +3,15 @@
"isRoot": true,
"tools": {
"dotnet-serve": {
- "version": "1.7.139",
+ "version": "1.8.15",
"commands": [
"dotnet-serve"
]
},
- "playwright-sharp-tool": {
- "version": "0.170.2",
+ "Microsoft.Playwright.CLI": {
+ "version": "1.2.2",
"commands": [
- "playwright-sharp"
+ "playwright"
]
}
}
diff --git a/eng/Dependencies.props b/eng/Dependencies.props
index 602c32ec12a4..13c753d0df48 100644
--- a/eng/Dependencies.props
+++ b/eng/Dependencies.props
@@ -188,7 +188,7 @@ and are generated based on the last package release.
-
+
diff --git a/eng/Versions.props b/eng/Versions.props
index 9369f8bc00d3..2efe8ee37ade 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -249,7 +249,7 @@
13.0.1
13.0.4
1.1.6
- 0.192.0
+ 1.17.3
3.0.0
7.2.2
4.3.0
diff --git a/eng/helix/content/RunTests/RunTests.csproj b/eng/helix/content/RunTests/RunTests.csproj
index db5888e80343..d18c6f515176 100644
--- a/eng/helix/content/RunTests/RunTests.csproj
+++ b/eng/helix/content/RunTests/RunTests.csproj
@@ -8,6 +8,6 @@
-
+
diff --git a/eng/helix/content/RunTests/TestRunner.cs b/eng/helix/content/RunTests/TestRunner.cs
index d951ea512f93..55cba0a4fa6d 100644
--- a/eng/helix/content/RunTests/TestRunner.cs
+++ b/eng/helix/content/RunTests/TestRunner.cs
@@ -9,7 +9,7 @@
using System.Threading;
using System.Threading.Tasks;
#if INSTALLPLAYWRIGHT
-using PlaywrightSharp;
+using Microsoft.Playwright;
#endif
namespace RunTests
@@ -55,9 +55,6 @@ public bool SetupEnvironment()
var playwrightBrowsers = Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH");
ProcessUtil.PrintMessage($"Setting PLAYWRIGHT_BROWSERS_PATH: {playwrightBrowsers}");
EnvironmentVariables.Add("PLAYWRIGHT_BROWSERS_PATH", playwrightBrowsers);
- var playrightDriver = Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH");
- ProcessUtil.PrintMessage($"Setting PLAYWRIGHT_DRIVER_PATH: {playrightDriver}");
- EnvironmentVariables.Add("PLAYWRIGHT_DRIVER_PATH", playrightDriver);
#else
ProcessUtil.PrintMessage($"Skipping setting PLAYWRIGHT_BROWSERS_PATH");
#endif
@@ -112,8 +109,10 @@ public async Task InstallPlaywrightAsync()
{
try
{
- ProcessUtil.PrintMessage($"Installing Playwright to Browsers: {Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH")} Driver: {Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH")}");
- await Playwright.InstallAsync(Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH"), Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH"));
+ Console.WriteLine($"Installing Playwright Browsers to {Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH")}");
+
+ var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
+
DisplayContents(Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH"));
return true;
}
diff --git a/eng/helix/content/runtests.cmd b/eng/helix/content/runtests.cmd
index a3c6de9c0a45..22d533626ef7 100644
--- a/eng/helix/content/runtests.cmd
+++ b/eng/helix/content/runtests.cmd
@@ -16,7 +16,6 @@ set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
set DOTNET_MULTILEVEL_LOOKUP=0
set InstallPlaywright=%$installPlaywright%
set PLAYWRIGHT_BROWSERS_PATH=%CD%\ms-playwright
-set PLAYWRIGHT_DRIVER_PATH=%CD%\.playwright\win-x64\native\playwright.cmd
REM Avoid https://github.com/dotnet/aspnetcore/issues/41937 in current session.
set ASPNETCORE_ENVIRONMENT=
diff --git a/eng/helix/content/runtests.sh b/eng/helix/content/runtests.sh
index 286b9abfe998..e268e78f2361 100644
--- a/eng/helix/content/runtests.sh
+++ b/eng/helix/content/runtests.sh
@@ -21,7 +21,6 @@ export PATH="$PATH:$DIR:$DIR/node/bin"
# Set playwright stuff
export PLAYWRIGHT_BROWSERS_PATH="$DIR/ms-playwright"
if [[ "$helixQueue" == *"OSX"* ]]; then
- export PLAYWRIGHT_DRIVER_PATH="$DIR/.playwright/osx/native/playwright.sh"
PLAYWRIGHT_NODE_PATH=$DIR/.playwright/osx/native/node
else
export PLAYWRIGHT_DRIVER_PATH="$DIR/.playwright/unix/native/playwright.sh"
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs
index bf5d3fc8d32a..a4224de6d16b 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs
@@ -8,7 +8,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.BrowserTesting;
using Microsoft.AspNetCore.Testing;
-using PlaywrightSharp;
+using Microsoft.Playwright;
using ProjectTemplates.Tests.Infrastructure;
using Templates.Test.Helpers;
using Xunit;
@@ -137,20 +137,31 @@ public async Task BlazorServerTemplateWorks_IndividualAuth(BrowserKind browserKi
private async Task TestBasicNavigation(Project project, IPage page)
{
- var socket = BrowserContextInfo.Pages[page].WebSockets.SingleOrDefault() ??
- (await page.WaitForEventAsync(PageEvent.WebSocket)).WebSocket;
+ var socket = await page.WaitForWebSocketAsync();
+
+ var framesReceived = 0;
+ var framesSent = 0;
+
+ void FrameReceived(object sender, IWebSocketFrame frame) { framesReceived++; }
+ void FrameSent(object sender, IWebSocketFrame frame) { framesSent++; }
+
+ socket.FrameReceived += FrameReceived;
+ socket.FrameSent += FrameSent;
// Receive render batch
- await socket.WaitForEventAsync(WebSocketEvent.FrameReceived);
- await socket.WaitForEventAsync(WebSocketEvent.FrameSent);
+ await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesReceived == 1 });
+ await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesSent == 1 });
// JS interop call to intercept navigation
- await socket.WaitForEventAsync(WebSocketEvent.FrameReceived);
- await socket.WaitForEventAsync(WebSocketEvent.FrameSent);
+ await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesReceived == 2 });
+ await page.WaitForWebSocketAsync(new() { Predicate = (s) => framesSent == 2 });
+
+ socket.FrameReceived -= FrameReceived;
+ socket.FrameSent -= FrameSent;
await page.WaitForSelectorAsync("nav");
// element gets project ID injected into it during template execution
- Assert.Equal("Index", (await page.GetTitleAsync()).Trim());
+ Assert.Equal("Index", (await page.TitleAsync()).Trim());
// Initially displays the home page
await page.WaitForSelectorAsync("h1 >> text=Hello, world!");
@@ -169,7 +180,7 @@ private async Task TestBasicNavigation(Project project, IPage page)
// Asynchronously loads and displays the table of weather forecasts
await page.WaitForSelectorAsync("table>tbody>tr");
- Assert.Equal(5, (await page.QuerySelectorAllAsync("p+table>tbody>tr")).Count());
+ Assert.Equal(5, await page.Locator("p+table>tbody>tr").CountAsync());
}
[Theory]
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj
index a488e4073861..1ba24e3b8b2e 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj
@@ -47,8 +47,8 @@
-
-
+
+
false
true
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs
index 80827924f662..a7cad5a32327 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs
@@ -16,7 +16,7 @@
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.CommandLineUtils;
using Newtonsoft.Json.Linq;
-using PlaywrightSharp;
+using Microsoft.Playwright;
using Templates.Test.Helpers;
using Xunit;
using Xunit.Abstractions;
@@ -64,7 +64,7 @@ public async Task BlazorWasmStandaloneTemplate_Works(BrowserKind browserKind)
private async Task NavigateToPage(IBrowserContext browser, string listeningUri)
{
var page = await browser.NewPageAsync();
- await page.GoToAsync(listeningUri, LifecycleEvent.Networkidle);
+ await page.GotoAsync(listeningUri, new() { WaitUntil = WaitUntilState.NetworkIdle });
return page;
}
@@ -141,9 +141,9 @@ public async Task BlazorWasmStandalonePwaTemplate_Works(BrowserKind browserKind)
// The PWA template supports offline use. By now, the browser should have cached everything it needs,
// so we can continue working even without the server.
- await page.GoToAsync("about:blank");
+ await page.GotoAsync("about:blank");
await browser.SetOfflineAsync(true);
- await page.GoToAsync(listeningUri);
+ await page.GotoAsync(listeningUri);
await TestBasicNavigation(project.ProjectName, page, skipFetchData: true);
await page.CloseAsync();
}
@@ -189,9 +189,9 @@ public async Task BlazorWasmHostedPwaTemplate_Works(BrowserKind browserKind)
// The PWA template supports offline use. By now, the browser should have cached everything it needs,
// so we can continue working even without the server.
// Since this is the hosted project, backend APIs won't work offline, so we need to skip "fetchdata"
- await page.GoToAsync("about:blank");
+ await page.GotoAsync("about:blank");
await browser.SetOfflineAsync(true);
- await page.GoToAsync(listeningUri);
+ await page.GotoAsync(listeningUri);
await TestBasicNavigation(project.ProjectName, page, skipFetchData: true);
await page.CloseAsync();
}
@@ -424,11 +424,11 @@ private async Task TestBasicNavigation(string appName, IPage page, bool usesAuth
// Initially displays the home page
await page.WaitForSelectorAsync("h1 >> text=Hello, world!");
- Assert.Equal("Index", (await page.GetTitleAsync()).Trim());
+ Assert.Equal("Index", (await page.TitleAsync()).Trim());
// Can navigate to the counter page
await Task.WhenAll(
- page.WaitForNavigationAsync("**/counter"),
+ page.WaitForNavigationAsync(new() { UrlString = "**/counter" }),
page.WaitForSelectorAsync("h1 >> text=Counter"),
page.WaitForSelectorAsync("p >> text=Current count: 0"),
page.ClickAsync("a[href=counter]"));
@@ -441,12 +441,12 @@ private async Task TestBasicNavigation(string appName, IPage page, bool usesAuth
if (usesAuth)
{
await Task.WhenAll(
- page.WaitForNavigationAsync("**/Identity/Account/Login**", LifecycleEvent.Networkidle),
+ page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/Login**", WaitUntil = LifecycleEvent.Networkidle }),
page.ClickAsync("text=Log in"));
await Task.WhenAll(
page.WaitForSelectorAsync("[name=\"Input.Email\"]"),
- page.WaitForNavigationAsync("**/Identity/Account/Register**", LifecycleEvent.Networkidle),
+ page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/Register**", WaitUntil = LifecycleEvent.Networkidle }),
page.ClickAsync("text=Register as a new user"));
var userName = $"{Guid.NewGuid()}@example.com";
@@ -458,12 +458,12 @@ private async Task TestBasicNavigation(string appName, IPage page, bool usesAuth
// We will be redirected to the RegisterConfirmation
await Task.WhenAll(
- page.WaitForNavigationAsync("**/Identity/Account/RegisterConfirmation**", LifecycleEvent.Networkidle),
+ page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/RegisterConfirmation**", WaitUntil = LifecycleEvent.Networkidle }),
page.ClickAsync("#registerSubmit"));
// We will be redirected to the ConfirmEmail
await Task.WhenAll(
- page.WaitForNavigationAsync("**/Identity/Account/ConfirmEmail**", LifecycleEvent.Networkidle),
+ page.WaitForNavigationAsync(new() { UrlString = "**/Identity/Account/ConfirmEmail**", WaitUntil = LifecycleEvent.Networkidle }),
page.ClickAsync("text=Click here to confirm your account"));
// Now we can login
@@ -474,21 +474,21 @@ private async Task TestBasicNavigation(string appName, IPage page, bool usesAuth
await page.ClickAsync("#login-submit");
// Need to navigate to fetch page
- await page.GoToAsync(new Uri(page.Url).GetLeftPart(UriPartial.Authority));
- Assert.Equal(appName.Trim(), (await page.GetTitleAsync()).Trim());
+ await page.GotoAsync(new Uri(page.Url).GetLeftPart(UriPartial.Authority));
+ Assert.Equal(appName.Trim(), (await page.TitleAsync()).Trim());
}
if (!skipFetchData)
{
// Can navigate to the 'fetch data' page
await Task.WhenAll(
- page.WaitForNavigationAsync("**/fetchdata"),
+ page.WaitForNavigationAsync(new() { UrlString = "**/fetchdata" }),
page.WaitForSelectorAsync("h1 >> text=Weather forecast"),
page.ClickAsync("text=Fetch data"));
// Asynchronously loads and displays the table of weather forecasts
await page.WaitForSelectorAsync("table>tbody>tr");
- Assert.Equal(5, (await page.QuerySelectorAllAsync("p+table>tbody>tr")).Count());
+ Assert.Equal(5, await page.Locator("p+table>tbody>tr").CountAsync());
}
}
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/playwrightSettings.json b/src/ProjectTemplates/BlazorTemplates.Tests/playwrightSettings.json
index 48f1423de9fb..f97e60263b22 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/playwrightSettings.json
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/playwrightSettings.json
@@ -4,27 +4,18 @@
"BaseArtifactsFolder": ".",
"GlobalBrowserOptions": {
"ChromiumSandbox": true,
- "DumpIO": true,
- "IgnoreHTTPSErrors": true,
"Headless": true,
"Timeout": 30000
},
"GlobalContextOptions": {
- "RecordVideo": {
- "Dir": "videos"
- },
- "RecordHar": {
- "Path": "har"
- },
+ "RecordVideoDir": "videos",
+ "RecordHarPath": "har",
"IgnoreHTTPSErrors": true
},
"BrowserOptions": {
"Chromium": {
"BrowserKind": "Chromium",
- "IsEnabled": true,
- "Args": {
- "--ignore-certificate-errors": true
- }
+ "IsEnabled": true
},
"Firefox": {
"BrowserKind": "Firefox",
diff --git a/src/ProjectTemplates/Shared/AspNetProcess.cs b/src/ProjectTemplates/Shared/AspNetProcess.cs
index a620f008fe6d..c8dec11d304f 100644
--- a/src/ProjectTemplates/Shared/AspNetProcess.cs
+++ b/src/ProjectTemplates/Shared/AspNetProcess.cs
@@ -17,7 +17,7 @@
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
-using PlaywrightSharp;
+using Microsoft.Playwright;
using Xunit;
using Xunit.Abstractions;
@@ -109,7 +109,7 @@ public class AspNetProcess : IDisposable
public async Task VisitInBrowserAsync(IPage page)
{
_output.WriteLine($"Opening browser at {ListeningUri}...");
- await page.GoToAsync(ListeningUri.AbsoluteUri);
+ await page.GotoAsync(ListeningUri.AbsoluteUri);
}
diff --git a/src/Shared/BrowserTesting/src/BrowserManager.cs b/src/Shared/BrowserTesting/src/BrowserManager.cs
index 9a290689c424..5b3bf0503b3d 100644
--- a/src/Shared/BrowserTesting/src/BrowserManager.cs
+++ b/src/Shared/BrowserTesting/src/BrowserManager.cs
@@ -9,7 +9,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
-using PlaywrightSharp;
+using Microsoft.Playwright;
namespace Microsoft.AspNetCore.BrowserTesting
{
@@ -47,20 +47,12 @@ private async Task InitializeAsync()
async Task InitializeCore()
{
- var driverPath = Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_PATH");
- if (!string.IsNullOrEmpty(driverPath))
- {
- Playwright = await PlaywrightSharp.Playwright.CreateAsync(_loggerFactory, driverExecutablePath: driverPath, debug: "pw:api");
- }
- else
- {
- Playwright = await PlaywrightSharp.Playwright.CreateAsync(_loggerFactory, debug: "pw:api");
- }
+ Playwright = await Microsoft.Playwright.Playwright.CreateAsync();
foreach (var (browserName, options) in _browserManagerConfiguration.BrowserOptions)
{
if (!_launchBrowsers.ContainsKey(browserName))
{
- var effectiveLaunchOptions = _browserManagerConfiguration.GetLaunchOptions(options.BrowserLaunchOptions);
+ var effectiveLaunchOptions = _browserManagerConfiguration.GetBrowserTypeLaunchOptions(options.BrowserLaunchOptions);
var browser = options.BrowserKind switch
{
@@ -108,10 +100,10 @@ public Task GetBrowserInstance(string browserInstance, string c
contextInfo);
}
- public Task GetBrowserInstance(BrowserKind browserInstance, string contextName, BrowserContextOptions options, ContextInformation contextInfo) =>
+ public Task GetBrowserInstance(BrowserKind browserInstance, string contextName, BrowserNewContextOptions options, ContextInformation contextInfo) =>
GetBrowserInstance(browserInstance.ToString(), contextName, options, contextInfo);
- public Task GetBrowserInstance(string browserInstance, string contextName, BrowserContextOptions options, ContextInformation contextInfo)
+ public Task GetBrowserInstance(string browserInstance, string contextName, BrowserNewContextOptions options, ContextInformation contextInfo)
{
if (_launchBrowsers.TryGetValue(browserInstance, out var browser))
{
@@ -126,9 +118,10 @@ public Task GetBrowserInstance(string browserInstance, string c
private async Task AttachContextInfo(Task browserContextTask, ContextInformation contextInfo)
{
var context = await browserContextTask;
- context.DefaultTimeout = HasFailedTests ?
+ var defaultTimeout = HasFailedTests ?
_browserManagerConfiguration.TimeoutAfterFirstFailureInMilliseconds:
_browserManagerConfiguration.TimeoutInMilliseconds;
+ context.SetDefaultTimeout(defaultTimeout);
contextInfo.Attach(context);
return context;
diff --git a/src/Shared/BrowserTesting/src/BrowserManagerConfiguration.cs b/src/Shared/BrowserTesting/src/BrowserManagerConfiguration.cs
index 331de7624157..e4ba0385e3aa 100644
--- a/src/Shared/BrowserTesting/src/BrowserManagerConfiguration.cs
+++ b/src/Shared/BrowserTesting/src/BrowserManagerConfiguration.cs
@@ -6,7 +6,7 @@
using System.IO;
using System.Linq;
using Microsoft.Extensions.Configuration;
-using PlaywrightSharp;
+using Microsoft.Playwright;
namespace Microsoft.AspNetCore.BrowserTesting
{
@@ -25,9 +25,9 @@ public BrowserManagerConfiguration(IConfiguration configuration)
public bool IsDisabled { get; private set; }
- public LaunchOptions GlobalBrowserOptions { get; private set; }
+ public BrowserTypeLaunchOptions GlobalBrowserOptions { get; private set; }
- public BrowserContextOptions GlobalContextOptions { get; private set; }
+ public BrowserNewContextOptions GlobalContextOptions { get; private set; }
public IDictionary BrowserOptions { get; } =
new Dictionary(StringComparer.OrdinalIgnoreCase);
@@ -35,22 +35,22 @@ public BrowserManagerConfiguration(IConfiguration configuration)
public ISet DisabledBrowsers { get; } =
new HashSet(StringComparer.OrdinalIgnoreCase);
- public IDictionary ContextOptions { get; private set; } =
- new Dictionary(StringComparer.OrdinalIgnoreCase);
+ public IDictionary ContextOptions { get; private set; } =
+ new Dictionary(StringComparer.OrdinalIgnoreCase);
- public LaunchOptions GetLaunchOptions(LaunchOptions browserLaunchOptions)
+ public BrowserTypeLaunchOptions GetBrowserTypeLaunchOptions(BrowserTypeLaunchOptions browserBrowserTypeLaunchOptions)
{
- if (browserLaunchOptions == null)
+ if (browserBrowserTypeLaunchOptions == null)
{
return GlobalBrowserOptions;
}
else
{
- return Combine(GlobalBrowserOptions, browserLaunchOptions);
+ return Combine(GlobalBrowserOptions, browserBrowserTypeLaunchOptions);
}
}
- public BrowserContextOptions GetContextOptions(string browser)
+ public BrowserNewContextOptions GetContextOptions(string browser)
{
if (!BrowserOptions.TryGetValue(browser, out var browserOptions))
{
@@ -66,10 +66,10 @@ public BrowserContextOptions GetContextOptions(string browser)
}
}
- public BrowserContextOptions GetContextOptions(string browser, string contextName) =>
+ public BrowserNewContextOptions GetContextOptions(string browser, string contextName) =>
Combine(GetContextOptions(browser.ToString()), ContextOptions.TryGetValue(contextName, out var context) ? context : throw new InvalidOperationException("Invalid context name"));
- public BrowserContextOptions GetContextOptions(string browser, string contextName, BrowserContextOptions options) =>
+ public BrowserNewContextOptions GetContextOptions(string browser, string contextName, BrowserNewContextOptions options) =>
Combine(GetContextOptions(browser, contextName), options);
private void Load(IConfiguration configuration)
@@ -126,37 +126,37 @@ private void Load(IConfiguration configuration)
}
}
- private BrowserContextOptions LoadContextOptions(IConfiguration configuration) => EnsureFoldersExist(new BrowserContextOptions
+ private BrowserNewContextOptions LoadContextOptions(IConfiguration configuration) => EnsureFoldersExist(new BrowserNewContextOptions
{
- Proxy = BindValue(configuration, nameof(BrowserContextOptions.Proxy)),
- RecordVideo = BindValue(configuration, nameof(BrowserContextOptions.RecordVideo)),
- RecordHar = BindValue(configuration, nameof(BrowserContextOptions.RecordHar)),
+ Proxy = BindValue(configuration, nameof(BrowserNewContextOptions.Proxy)),
+ RecordVideo = BindValue(configuration, nameof(BrowserNewContextOptions.RecordVideo)),
+ RecordHar = BindValue(configuration, nameof(BrowserNewContextOptions.RecordHar)),
ExtraHTTPHeaders = BindMultiValueMap(
- configuration.GetSection(nameof(BrowserContextOptions.ExtraHTTPHeaders)),
+ configuration.GetSection(nameof(BrowserNewContextOptions.ExtraHTTPHeaders)),
argsMap => argsMap.ToDictionary(kvp => kvp.Key, kvp => string.Join(", ", kvp.Value))),
- Locale = configuration.GetValue(nameof(BrowserContextOptions.Locale)),
- ColorScheme = configuration.GetValue(nameof(BrowserContextOptions.ColorScheme)),
- AcceptDownloads = configuration.GetValue(nameof(BrowserContextOptions.AcceptDownloads)),
- HasTouch = configuration.GetValue(nameof(BrowserContextOptions.HasTouch)),
- HttpCredentials = configuration.GetValue(nameof(BrowserContextOptions.HttpCredentials)),
- DeviceScaleFactor = configuration.GetValue(nameof(BrowserContextOptions.DeviceScaleFactor)),
- Offline = configuration.GetValue(nameof(BrowserContextOptions.Offline)),
- IsMobile = configuration.GetValue(nameof(BrowserContextOptions.IsMobile)),
+ Locale = configuration.GetValue(nameof(BrowserNewContextOptions.Locale)),
+ ColorScheme = configuration.GetValue(nameof(BrowserNewContextOptions.ColorScheme)),
+ AcceptDownloads = configuration.GetValue(nameof(BrowserNewContextOptions.AcceptDownloads)),
+ HasTouch = configuration.GetValue(nameof(BrowserNewContextOptions.HasTouch)),
+ HttpCredentials = configuration.GetValue(nameof(BrowserNewContextOptions.HttpCredentials)),
+ DeviceScaleFactor = configuration.GetValue(nameof(BrowserNewContextOptions.DeviceScaleFactor)),
+ Offline = configuration.GetValue(nameof(BrowserNewContextOptions.Offline)),
+ IsMobile = configuration.GetValue(nameof(BrowserNewContextOptions.IsMobile)),
// TODO: Map this properly
- Permissions = configuration.GetValue(nameof(BrowserContextOptions.Permissions)),
+ Permissions = configuration.GetValue(nameof(BrowserNewContextOptions.Permissions)),
- Geolocation = BindValue(configuration, nameof(BrowserContextOptions.Geolocation)),
- TimezoneId = configuration.GetValue(nameof(BrowserContextOptions.TimezoneId)),
- IgnoreHTTPSErrors = configuration.GetValue(nameof(BrowserContextOptions.IgnoreHTTPSErrors)),
- JavaScriptEnabled = configuration.GetValue(nameof(BrowserContextOptions.JavaScriptEnabled)),
- BypassCSP = configuration.GetValue(nameof(BrowserContextOptions.BypassCSP)),
- UserAgent = configuration.GetValue(nameof(BrowserContextOptions.UserAgent)),
- Viewport = BindValue(configuration, nameof(BrowserContextOptions.Viewport)),
- StorageStatePath = configuration.GetValue(nameof(BrowserContextOptions.StorageStatePath)),
+ Geolocation = BindValue(configuration, nameof(BrowserNewContextOptions.Geolocation)),
+ TimezoneId = configuration.GetValue(nameof(BrowserNewContextOptions.TimezoneId)),
+ IgnoreHTTPSErrors = configuration.GetValue(nameof(BrowserNewContextOptions.IgnoreHTTPSErrors)),
+ JavaScriptEnabled = configuration.GetValue(nameof(BrowserNewContextOptions.JavaScriptEnabled)),
+ BypassCSP = configuration.GetValue(nameof(BrowserNewContextOptions.BypassCSP)),
+ UserAgent = configuration.GetValue(nameof(BrowserNewContextOptions.UserAgent)),
+ Viewport = BindValue(configuration, nameof(BrowserNewContextOptions.Viewport)),
+ StorageStatePath = configuration.GetValue(nameof(BrowserNewContextOptions.StorageStatePath)),
// TODO: Map this properly
- StorageState = BindValue(configuration, nameof(BrowserContextOptions.StorageState))
+ StorageState = BindValue(configuration, nameof(BrowserNewContextOptions.StorageState))
});
private static T BindValue(IConfiguration configuration, string key) where T : new()
@@ -167,16 +167,16 @@ private static T BindValue(IConfiguration configuration, string key) where T
return section.Exists() ? instance : default;
}
- private BrowserContextOptions EnsureFoldersExist(BrowserContextOptions browserContextOptions)
+ private BrowserNewContextOptions EnsureFoldersExist(BrowserNewContextOptions browserContextOptions)
{
- if (browserContextOptions?.RecordVideo?.Dir != null)
+ if (browserContextOptions?.RecordVideoDir != null)
{
- browserContextOptions.RecordVideo.Dir = EnsureFolderExists(browserContextOptions.RecordVideo.Dir);
+ browserContextOptions.RecordVideoDir = EnsureFolderExists(browserContextOptions.RecordVideoDir);
}
- if (browserContextOptions?.RecordHar?.Path != null)
+ if (browserContextOptions?.RecordHarPath != null)
{
- browserContextOptions.RecordHar.Path = EnsureFolderExists(browserContextOptions.RecordHar.Path);
+ browserContextOptions.RecordHarPath = EnsureFolderExists(browserContextOptions.RecordHarPath);
}
return browserContextOptions;
@@ -197,28 +197,27 @@ string EnsureFolderExists(string folderPath)
}
}
- private LaunchOptions LoadBrowserLaunchOptions(IConfiguration configuration) => new LaunchOptions
+ private BrowserTypeLaunchOptions LoadBrowserLaunchOptions(IConfiguration configuration) => new BrowserTypeLaunchOptions
{
- IgnoreDefaultArgs = BindArgumentMap(configuration.GetSection(nameof(LaunchOptions.IgnoreAllDefaultArgs))),
- ChromiumSandbox = configuration.GetValue(nameof(LaunchOptions.ChromiumSandbox)),
- HandleSIGHUP = configuration.GetValue(nameof(LaunchOptions.HandleSIGHUP)),
- HandleSIGTERM = configuration.GetValue(nameof(LaunchOptions.HandleSIGTERM)),
- HandleSIGINT = configuration.GetValue(nameof(LaunchOptions.HandleSIGINT)),
- IgnoreAllDefaultArgs = configuration.GetValue(nameof(LaunchOptions.IgnoreAllDefaultArgs)),
- SlowMo = configuration.GetValue(nameof(LaunchOptions.SlowMo)),
- Env = configuration.GetValue>(nameof(LaunchOptions.Env)),
- DumpIO = configuration.GetValue(nameof(LaunchOptions.DumpIO)),
- IgnoreHTTPSErrors = configuration.GetValue(nameof(LaunchOptions.IgnoreHTTPSErrors)),
- DownloadsPath = configuration.GetValue(nameof(LaunchOptions.DownloadsPath)),
- ExecutablePath = configuration.GetValue(nameof(LaunchOptions.ExecutablePath)),
- Devtools = configuration.GetValue(nameof(LaunchOptions.Devtools)),
- UserDataDir = configuration.GetValue(nameof(LaunchOptions.UserDataDir)),
+ IgnoreDefaultArgs = BindArgumentMap(configuration.GetSection(nameof(BrowserTypeLaunchOptions.IgnoreAllDefaultArgs))),
+ ChromiumSandbox = configuration.GetValue(nameof(BrowserTypeLaunchOptions.ChromiumSandbox)),
+ HandleSIGHUP = configuration.GetValue(nameof(BrowserTypeLaunchOptions.HandleSIGHUP)),
+ HandleSIGTERM = configuration.GetValue(nameof(BrowserTypeLaunchOptions.HandleSIGTERM)),
+ HandleSIGINT = configuration.GetValue(nameof(BrowserTypeLaunchOptions.HandleSIGINT)),
+ IgnoreAllDefaultArgs = configuration.GetValue(nameof(BrowserTypeLaunchOptions.IgnoreAllDefaultArgs)),
+ SlowMo = configuration.GetValue(nameof(BrowserTypeLaunchOptions.SlowMo)),
+ Env = configuration.GetValue>(nameof(BrowserTypeLaunchOptions.Env)),
+ DumpIO = configuration.GetValue(nameof(BrowserTypeLaunchOptions.DumpIO)),
+ IgnoreHTTPSErrors = configuration.GetValue(nameof(BrowserTypeLaunchOptions.IgnoreHTTPSErrors)),
+ DownloadsPath = configuration.GetValue(nameof(BrowserTypeLaunchOptions.DownloadsPath)),
+ ExecutablePath = configuration.GetValue(nameof(BrowserTypeLaunchOptions.ExecutablePath)),
+ Devtools = configuration.GetValue(nameof(BrowserTypeLaunchOptions.Devtools)),
Args = BindMultiValueMap(
- configuration.GetSection(nameof(LaunchOptions.Args)),
+ configuration.GetSection(nameof(BrowserTypeLaunchOptions.Args)),
argsMap => argsMap.SelectMany(argNameValue => argNameValue.Value.Prepend(argNameValue.Key)).ToArray()),
- Headless = configuration.GetValue(nameof(LaunchOptions.Headless)),
- Timeout = configuration.GetValue(nameof(LaunchOptions.Timeout)),
- Proxy = configuration.GetValue(nameof(LaunchOptions.Proxy))
+ Headless = configuration.GetValue(nameof(BrowserTypeLaunchOptions.Headless)),
+ Timeout = configuration.GetValue(nameof(BrowserTypeLaunchOptions.Timeout)),
+ Proxy = configuration.GetValue(nameof(BrowserTypeLaunchOptions.Proxy))
};
private T BindMultiValueMap(IConfigurationSection processArgsMap, Func>, T> mapper)
@@ -307,20 +306,14 @@ static HashSet InitializeMapValue(Dictionary> ar
true => configuration.Get>().Where(kvp => kvp.Value == true).Select(kvp => kvp.Key).ToArray()
};
- private static BrowserContextOptions Combine(BrowserContextOptions defaultOptions, BrowserContextOptions overrideOptions) =>
+ private static BrowserNewContextOptions Combine(BrowserNewContextOptions defaultOptions, BrowserNewContextOptions overrideOptions) =>
new()
{
Proxy = overrideOptions?.Proxy != default ? overrideOptions.Proxy : defaultOptions.Proxy,
- RecordVideo = overrideOptions?.RecordVideo != default ?
- new() { Dir = overrideOptions.RecordVideo.Dir, Size = overrideOptions.RecordVideo.Size?.Clone() } :
- defaultOptions != default ?
- new() { Dir = defaultOptions.RecordVideo.Dir, Size = defaultOptions.RecordVideo.Size?.Clone() } :
- default,
- RecordHar = overrideOptions?.RecordHar != default ?
- new() { Path = overrideOptions.RecordHar.Path, OmitContent = overrideOptions.RecordHar.OmitContent } :
- defaultOptions?.RecordHar != default ?
- new() { Path = defaultOptions.RecordHar.Path, OmitContent = defaultOptions.RecordHar.OmitContent } :
- default,
+ RecordVideoDir = overrideOptions?.RecordVideoDir != default ? overrideOptions.RecordVideoDir : defaultOptions.RecordVideoDir,
+ RecordVideoSize = overrideOptions?.RecordVideoSize != default ? overrideOptions.RecordVideoSize : defaultOptions.RecordVideoSize,
+ RecordHarPath = overrideOptions?.RecordHarPath != default ? overrideOptions.RecordHarPath : defaultOptions.RecordHarPath,
+ RecordHarOmitContent = overrideOptions?.RecordHarOmitContent != default ? overrideOptions.RecordHarOmitContent : defaultOptions.RecordHarOmitContent,
ExtraHTTPHeaders = overrideOptions?.ExtraHTTPHeaders != default ? overrideOptions.ExtraHTTPHeaders : defaultOptions.ExtraHTTPHeaders,
Locale = overrideOptions?.Locale != default ? overrideOptions.Locale : defaultOptions.Locale,
ColorScheme = overrideOptions?.ColorScheme != default ? overrideOptions.ColorScheme : defaultOptions.ColorScheme,
@@ -337,12 +330,12 @@ static HashSet InitializeMapValue(Dictionary> ar
JavaScriptEnabled = overrideOptions?.JavaScriptEnabled != default ? overrideOptions.JavaScriptEnabled : defaultOptions.JavaScriptEnabled,
BypassCSP = overrideOptions?.BypassCSP != default ? overrideOptions.BypassCSP : defaultOptions.BypassCSP,
UserAgent = overrideOptions?.UserAgent != default ? overrideOptions.UserAgent : defaultOptions.UserAgent,
- Viewport = overrideOptions?.Viewport != default ? overrideOptions.Viewport : defaultOptions.Viewport,
+ ViewportSize = overrideOptions?.ViewportSize != default ? overrideOptions.ViewportSize : defaultOptions.ViewportSize,
StorageStatePath = overrideOptions?.StorageStatePath != default ? overrideOptions.StorageStatePath : defaultOptions.StorageStatePath,
StorageState = overrideOptions?.StorageState != default ? overrideOptions.StorageState : defaultOptions.StorageState
};
- private LaunchOptions Combine(LaunchOptions defaultOptions, LaunchOptions overrideOptions) =>
+ private BrowserTypeLaunchOptions Combine(BrowserTypeLaunchOptions defaultOptions, BrowserTypeLaunchOptions overrideOptions) =>
new()
{
IgnoreDefaultArgs = overrideOptions.IgnoreDefaultArgs != default ? overrideOptions.IgnoreDefaultArgs : defaultOptions.IgnoreDefaultArgs,
@@ -353,12 +346,9 @@ static HashSet InitializeMapValue(Dictionary> ar
IgnoreAllDefaultArgs = overrideOptions.IgnoreAllDefaultArgs != default ? overrideOptions.IgnoreAllDefaultArgs : defaultOptions.IgnoreAllDefaultArgs,
SlowMo = overrideOptions.SlowMo != default ? overrideOptions.SlowMo : defaultOptions.SlowMo,
Env = overrideOptions.Env != default ? overrideOptions.Env : defaultOptions.Env,
- DumpIO = overrideOptions.DumpIO != default ? overrideOptions.DumpIO : defaultOptions.DumpIO,
- IgnoreHTTPSErrors = overrideOptions.IgnoreHTTPSErrors != default ? overrideOptions.IgnoreHTTPSErrors : defaultOptions.IgnoreHTTPSErrors,
DownloadsPath = overrideOptions.DownloadsPath != default ? overrideOptions.DownloadsPath : defaultOptions.DownloadsPath,
ExecutablePath = overrideOptions.ExecutablePath != default ? overrideOptions.ExecutablePath : defaultOptions.ExecutablePath,
Devtools = overrideOptions.Devtools != default ? overrideOptions.Devtools : defaultOptions.Devtools,
- UserDataDir = overrideOptions.UserDataDir != default ? overrideOptions.UserDataDir : defaultOptions.UserDataDir,
Args = overrideOptions.Args != default ? overrideOptions.Args : defaultOptions.Args,
Headless = overrideOptions.Headless != default ? overrideOptions.Headless : defaultOptions.Headless,
Timeout = overrideOptions.Timeout != default ? overrideOptions.Timeout : defaultOptions.Timeout,
@@ -366,5 +356,5 @@ static HashSet InitializeMapValue(Dictionary> ar
};
}
- public record BrowserOptions(BrowserKind BrowserKind, LaunchOptions BrowserLaunchOptions, BrowserContextOptions DefaultContextOptions);
+ public record BrowserOptions(BrowserKind BrowserKind, BrowserTypeLaunchOptions BrowserBrowserTypeLaunchOptions, BrowserNewContextOptions DefaultContextOptions);
}
diff --git a/src/Shared/BrowserTesting/src/BrowserTestBase.cs b/src/Shared/BrowserTesting/src/BrowserTestBase.cs
index 1b3a29d1694f..3e443b00077f 100644
--- a/src/Shared/BrowserTesting/src/BrowserTestBase.cs
+++ b/src/Shared/BrowserTesting/src/BrowserTestBase.cs
@@ -9,7 +9,7 @@
using Microsoft.AspNetCore.BrowserTesting;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Configuration;
-using PlaywrightSharp;
+using Microsoft.Playwright;
using Xunit;
using Xunit.Abstractions;
diff --git a/src/Shared/BrowserTesting/src/ContextInformation.cs b/src/Shared/BrowserTesting/src/ContextInformation.cs
index d8264d3248f9..6476a8aa9800 100644
--- a/src/Shared/BrowserTesting/src/ContextInformation.cs
+++ b/src/Shared/BrowserTesting/src/ContextInformation.cs
@@ -5,7 +5,7 @@
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Logging;
-using PlaywrightSharp;
+using Microsoft.Playwright;
namespace Microsoft.AspNetCore.BrowserTesting
{
@@ -26,7 +26,7 @@ internal void Attach(IBrowserContext context)
context.Page += AttachToPage;
}
- private void AttachToPage(object sender, PageEventArgs args)
+ private void AttachToPage(object sender, IPage page)
{
var logger = _factory.CreateLogger();
if (_harPath != null)
@@ -34,15 +34,14 @@ private void AttachToPage(object sender, PageEventArgs args)
logger.LogInformation($"Network trace will be saved at '{_harPath}'");
}
- var pageInfo = new PageInformation(args.Page, logger);
- Pages.Add(args.Page, pageInfo);
- args.Page.Close += CleanupPage;
- args.Page.Crash += CleanupPage;
+ var pageInfo = new PageInformation(page, logger);
+ Pages.Add(page, pageInfo);
+ page.Close += CleanupPage;
+ page.Crash += CleanupPage;
}
- private void CleanupPage(object sender, EventArgs e)
+ private void CleanupPage(object sender, IPage page)
{
- var page = (IPage)sender;
if (Pages.TryGetValue(page, out var info))
{
info.Dispose();
@@ -50,23 +49,23 @@ private void CleanupPage(object sender, EventArgs e)
}
}
- internal BrowserContextOptions ConfigureUniqueHarPath(BrowserContextOptions browserContextOptions)
+ internal BrowserNewContextOptions ConfigureUniqueHarPath(BrowserNewContextOptions browserContextOptions)
{
var uploadDir = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT");
- if (browserContextOptions?.RecordHar?.Path != null)
+ if (browserContextOptions?.RecordHarPath != null)
{
var identifier = Guid.NewGuid().ToString("N");
- browserContextOptions.RecordHar.Path = Path.Combine(
- string.IsNullOrEmpty(uploadDir) ? browserContextOptions.RecordHar.Path : uploadDir,
+ browserContextOptions.RecordHarPath = Path.Combine(
+ string.IsNullOrEmpty(uploadDir) ? browserContextOptions.RecordHarPath : uploadDir,
$"{identifier}.har");
- _harPath = browserContextOptions.RecordHar.Path;
+ _harPath = browserContextOptions.RecordHarPath;
}
- if (browserContextOptions?.RecordVideo?.Dir != null)
+ if (browserContextOptions?.RecordVideoDir != null)
{
if (!string.IsNullOrEmpty(uploadDir))
{
- browserContextOptions.RecordVideo.Dir = uploadDir;
+ browserContextOptions.RecordVideoDir = uploadDir;
}
}
diff --git a/src/Shared/BrowserTesting/src/Microsoft.AspNetCore.BrowserTesting.csproj b/src/Shared/BrowserTesting/src/Microsoft.AspNetCore.BrowserTesting.csproj
index c027e9ee1e27..595483b51d9b 100644
--- a/src/Shared/BrowserTesting/src/Microsoft.AspNetCore.BrowserTesting.csproj
+++ b/src/Shared/BrowserTesting/src/Microsoft.AspNetCore.BrowserTesting.csproj
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/src/Shared/BrowserTesting/src/PageInformation.cs b/src/Shared/BrowserTesting/src/PageInformation.cs
index f02724a9c101..6ac75663cd6c 100644
--- a/src/Shared/BrowserTesting/src/PageInformation.cs
+++ b/src/Shared/BrowserTesting/src/PageInformation.cs
@@ -5,13 +5,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
-using PlaywrightSharp;
+using Microsoft.Playwright;
namespace Microsoft.AspNetCore.BrowserTesting
{
public class PageInformation : IDisposable
{
- private readonly Page _page;
+ private readonly IPage _page;
private readonly ILogger _logger;
public List FailedRequests { get; } = new();
@@ -22,7 +22,7 @@ public class PageInformation : IDisposable
public List WebSockets { get; set; } = new();
- public PageInformation(Page page, ILogger logger)
+ public PageInformation(IPage page, ILogger logger)
{
page.Console += RecordConsoleMessage;
page.PageError += RecordPageError;
@@ -34,16 +34,16 @@ public PageInformation(Page page, ILogger logger)
_ = LogPageVideoPath();
}
- private void CaptureWebSocket(object sender, WebSocketEventArgs e)
+ private void CaptureWebSocket(object sender, IWebSocket webSocket)
{
- WebSockets.Add(e.WebSocket);
+ WebSockets.Add(webSocket);
}
private async Task LogPageVideoPath()
{
try
{
- var path = _page.Video != null ? await _page.Video.GetPathAsync() : null;
+ var path = _page.Video != null ? await _page.Video.PathAsync() : null;
if (path != null)
{
_logger.LogInformation($"Page video recorded at: {path}");
@@ -63,41 +63,40 @@ public void Dispose()
_page.RequestFailed -= RecordFailedRequest;
}
- private void RecordFailedRequest(object sender, RequestFailedEventArgs e)
+ private void RecordFailedRequest(object sender, IRequest e)
{
try
{
- _logger.LogError(e.FailureText);
+ _logger.LogError(e.Failure);
}
catch
{
}
- FailedRequests.Add(e.FailureText);
+ FailedRequests.Add(e.Failure);
}
- private void RecordPageError(object sender, PageErrorEventArgs e)
+ private void RecordPageError(object sender, string message)
{
// There needs to be a bit of experimentation with this, but message should be a good start.
try
{
- _logger.LogError(e.Message);
+ _logger.LogError(message);
}
catch
{
}
- PageErrors.Add(e.Message);
+ PageErrors.Add(message);
}
- private void RecordConsoleMessage(object sender, ConsoleEventArgs e)
+ private void RecordConsoleMessage(object sender, IConsoleMessage message)
{
try
{
- var message = e.Message;
var messageText = message.Text.Replace(Environment.NewLine, $"{Environment.NewLine} ");
var location = message.Location;
- var logMessage = $"[{_page.Url}]{Environment.NewLine} {messageText}{Environment.NewLine} ({location.URL}:{location.LineNumber}:{location.ColumnNumber})";
+ var logMessage = $"[{_page.Url}]{Environment.NewLine} {messageText}{Environment.NewLine} ({location.URL}:{location.LineNumber}:{location.ColumnNumber})";
_logger.Log(MapLogLevel(message.Type), logMessage);
diff --git a/src/Shared/Process/ProcessEx.cs b/src/Shared/Process/ProcessEx.cs
index f0bef370692b..b04957ba0ef3 100644
--- a/src/Shared/Process/ProcessEx.cs
+++ b/src/Shared/Process/ProcessEx.cs
@@ -48,7 +48,6 @@ public ProcessEx(ITestOutputHelper output, Process proc, TimeSpan timeout)
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
-
// We greedily create a timeout exception message even though a timeout is unlikely to happen for two reasons:
// 1. To make it less likely for Process getters to throw exceptions like "System.InvalidOperationException: Process has exited, ..."
// 2. To ensure if/when exceptions are thrown from Process getters, these exceptions can easily be observed.