Skip to content

Automatically install required browser files for Playwright #3190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

0xced
Copy link
Contributor

@0xced 0xced commented Jun 18, 2025

This will prevent this exception when Playwright.MSTest, Playwright.NUnit or Playwright.Xunit is used:

Microsoft.Playwright.PlaywrightException
Executable doesn't exist at ~/Library/Caches/ms-playwright/chromium-1148/chrome-mac/Chromium.app/Contents/MacOS/Chromium
╔════════════════════════════════════════════════════════════╗
║ Looks like Playwright was just installed or updated.       ║
║ Please run the following command to download new browsers: ║
║                                                            ║
║     pwsh bin/Debug/netX/playwright.ps1 install             ║
║                                                            ║
║ <3 Playwright Team                                         ║
╚════════════════════════════════════════════════════════════╝
   at Microsoft.Playwright.Transport.Connection.InnerSendMessageToServerAsync[T](ChannelOwner object, String method, Dictionary`2 dictionary, Boolean keepNulls) in /_/src/Playwright/Transport/Connection.cs:line 206
   at Microsoft.Playwright.Transport.Connection.WrapApiCallAsync[T](Func`1 action, Boolean isInternal) in /_/src/Playwright/Transport/Connection.cs:line 535
   at Microsoft.Playwright.Core.BrowserType.LaunchAsync(BrowserTypeLaunchOptions options) in /_/src/Playwright/Core/BrowserType.cs:line 56
   at Microsoft.Playwright.Xunit.BrowserService.CreateBrowser(IBrowserType browserType) in /_/src/Playwright.Xunit/BrowserService.cs:line 56
   at Microsoft.Playwright.Xunit.BrowserService.<>c__DisplayClass5_0.<<Register>b__0>d.MoveNext() in /_/src/Playwright.Xunit/BrowserService.cs:line 46
--- End of stack trace from previous location ---
   at Microsoft.Playwright.Xunit.WorkerAwareTest.RegisterService[T](String name, Func`1 factory) in /_/src/Playwright.Xunit/WorkerAwareTest.cs:line 54
   at Microsoft.Playwright.Xunit.BrowserTest.InitializeAsync() in /_/src/Playwright.Xunit/BrowserTest.cs:line 45
   at Microsoft.Playwright.Xunit.ContextTest.InitializeAsync() in /_/src/Playwright.Xunit/ContextTest.cs:line 35
   at Microsoft.Playwright.Xunit.PageTest.InitializeAsync() in /_/src/Playwright.Xunit/PageTest.cs:line 35

This helps with #2286.

Aslo note that this pull request is stacked on top of #3140.

0xced added 2 commits June 18, 2025 14:29
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
This will prevent this exception:

> Microsoft.Playwright.PlaywrightException
> Executable doesn't exist at ~/Library/Caches/ms-playwright/chromium-1148/chrome-mac/Chromium.app/Contents/MacOS/Chromium
> ╔════════════════════════════════════════════════════════════╗
> ║ Looks like Playwright was just installed or updated.       ║
> ║ Please run the following command to download new browsers: ║
> ║                                                            ║
> ║     pwsh bin/Debug/netX/playwright.ps1 install             ║
> ║                                                            ║
> ║ <3 Playwright Team                                         ║
> ╚════════════════════════════════════════════════════════════╝
>    at Microsoft.Playwright.Transport.Connection.InnerSendMessageToServerAsync[T](ChannelOwner object, String method, Dictionary`2 dictionary, Boolean keepNulls) in /_/src/Playwright/Transport/Connection.cs:line 206
>    at Microsoft.Playwright.Transport.Connection.WrapApiCallAsync[T](Func`1 action, Boolean isInternal) in /_/src/Playwright/Transport/Connection.cs:line 535
>    at Microsoft.Playwright.Core.BrowserType.LaunchAsync(BrowserTypeLaunchOptions options) in /_/src/Playwright/Core/BrowserType.cs:line 56
>    at Microsoft.Playwright.Xunit.BrowserService.CreateBrowser(IBrowserType browserType) in /_/src/Playwright.Xunit/BrowserService.cs:line 56
>    at Microsoft.Playwright.Xunit.BrowserService.<>c__DisplayClass5_0.<<Register>b__0>d.MoveNext() in /_/src/Playwright.Xunit/BrowserService.cs:line 46
> --- End of stack trace from previous location ---
>    at Microsoft.Playwright.Xunit.WorkerAwareTest.RegisterService[T](String name, Func`1 factory) in /_/src/Playwright.Xunit/WorkerAwareTest.cs:line 54
>    at Microsoft.Playwright.Xunit.BrowserTest.InitializeAsync() in /_/src/Playwright.Xunit/BrowserTest.cs:line 45
>    at Microsoft.Playwright.Xunit.ContextTest.InitializeAsync() in /_/src/Playwright.Xunit/ContextTest.cs:line 35
>    at Microsoft.Playwright.Xunit.PageTest.InitializeAsync() in /_/src/Playwright.Xunit/PageTest.cs:line 35

This helps with microsoft#2286.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant