Skip to content

Commit 2a21386

Browse files
committed
Add a Program.Main() override with a throwOnError parameter
Ensuring that playwright is properly installed can be done by running the following code: ```csharp var playwright = new Microsoft.Playwright.Program(); var exitCode = playwright.Run(["install", "--with-deps"]); ``` This is fine when the installation succeeds and the exit code is 0. But when running under xUnit.net (which [does **not** capture the console output](https://xunit.net/docs/capturing-output)) and the installation fails with exit code 1, then it becomes impossibly hard to diagnose the root cause of the failure. For example, a failure can be triggered by deleting the installed browers in the `ms-playwright` cache directory and setting the `https_proxy` environment variable to an invalid proxy: `http://127.0.0.1:33333`. Under these conditions, running with the new `throwOnError` parameter becomes diagnosable. ```csharp var playwright = new Microsoft.Playwright.Program(); var exitCode = playwright.Run(["install", "--with-deps", "firefox"], throwOnError: true); ``` This throws a `PlaywrightException` with the exact command executed and its output, making it clear what the problem is. > Failed to run ~/playwright-dotnet/src/playwright-xunit/bin/Debug/net8.0/.playwright/node/darwin-x64/node "~/playwright-dotnet/src/playwright-xunit/bin/Debug/net8.0/.playwright/package/cli.js" "install" "--with-deps" "firefox" > Downloading Firefox 132.0 (playwright build v1466) from https://playwright.azureedge.net/builds/firefox/1466/firefox-mac.zip > Error: connect ECONNREFUSED 127.0.0.1:33333 > at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1610:16) { > errno: -61, > code: 'ECONNREFUSED', > syscall: 'connect', > address: '127.0.0.1', > port: 33333 > } > Downloading Firefox 132.0 (playwright build v1466) from https://playwright-akamai.azureedge.net/builds/firefox/1466/firefox-mac.zip > Error: connect ECONNREFUSED 127.0.0.1:33333 > at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1610:16) { > errno: -61, > code: 'ECONNREFUSED', > syscall: 'connect', > address: '127.0.0.1', > port: 33333 > } > Downloading Firefox 132.0 (playwright build v1466) from https://playwright-verizon.azureedge.net/builds/firefox/1466/firefox-mac.zip > Error: connect ECONNREFUSED 127.0.0.1:33333 > at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1610:16) { > errno: -61, > code: 'ECONNREFUSED', > syscall: 'connect', > address: '127.0.0.1', > port: 33333 > } > Failed to install browsers > Error: Failed to download Firefox 132.0 (playwright build v1466), caused by > Error: Download failure, code=1
1 parent 1320cc6 commit 2a21386

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/Playwright/Program.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
using System;
2626
using System.Diagnostics;
27+
using System.IO;
2728
using Microsoft.Playwright.Helpers;
2829

2930
namespace Microsoft.Playwright;
@@ -37,14 +38,19 @@ public static int Main(string[] args)
3738
}
3839

3940
public int Run(string[] args)
41+
{
42+
return Run(args, throwOnError: false);
43+
}
44+
45+
public int Run(string[] args, bool throwOnError)
4046
{
4147
Func<string?, string> getArgs;
4248
string executablePath;
4349
try
4450
{
4551
(executablePath, getArgs) = Driver.GetExecutablePath();
4652
}
47-
catch
53+
catch when (!throwOnError)
4854
{
4955
return PrintError("Microsoft.Playwright assembly was found, but is missing required assets. Please ensure to build your project before running Playwright tool.");
5056
}
@@ -55,6 +61,8 @@ public int Run(string[] args)
5561
// This works after net8.0-preview-4
5662
// https://github.com/dotnet/runtime/pull/82662
5763
WindowStyle = ProcessWindowStyle.Hidden,
64+
RedirectStandardOutput = throwOnError,
65+
RedirectStandardError = throwOnError,
5866
};
5967
foreach (var pair in Driver.EnvironmentVariables)
6068
{
@@ -66,9 +74,26 @@ public int Run(string[] args)
6674
StartInfo = playwrightStartInfo,
6775
};
6876

77+
using var pwOutput = new StringWriter();
78+
if (throwOnError)
79+
{
80+
pwProcess.OutputDataReceived += (_, eventArgs) => pwOutput.WriteLine(eventArgs.Data);
81+
pwProcess.ErrorDataReceived += (_, eventArgs) => pwOutput.WriteLine(eventArgs.Data);
82+
}
6983
pwProcess.Start();
84+
if (throwOnError)
85+
{
86+
pwProcess.BeginOutputReadLine();
87+
pwProcess.BeginErrorReadLine();
88+
}
7089

7190
pwProcess.WaitForExit();
91+
92+
if (pwProcess.ExitCode != 0 && throwOnError)
93+
{
94+
throw new PlaywrightException($"Failed to run {playwrightStartInfo.FileName} {playwrightStartInfo.Arguments}{Environment.NewLine}{pwOutput.ToString().Trim()}");
95+
}
96+
7297
return pwProcess.ExitCode;
7398
}
7499

0 commit comments

Comments
 (0)