microsoft / playwright-dotnet

.NET version of the Playwright testing and automation library.
https://playwright.dev/dotnet/
MIT License
2.47k stars 235 forks source link

[Question]: Not supported under Windows .NET Core Azure App Service? #2608

Closed karimayachi closed 1 year ago

karimayachi commented 1 year ago

Can PlayWright work under a Windows .NET Core Azure App Service?

I have a hard time getting PlayWright to work under a Windows Azure App Service with a .NET Core WebAPI, to the point where I wonder if it is possible at all.

I see a couple of other issues here where people got the " Executable doesn't exist at ..." error (https://github.com/microsoft/playwright-dotnet/issues/2238, https://github.com/microsoft/playwright-dotnet/issues/2427).

This error is probably because the Powershell install script installs the browsers in %LOCALAPPDATA%, which maps to D:\local\localAppData\ on the ASE. This is non-persistent storage and not accessible to the App Service instance.

But moving past this problem and installing in a place that the instance can actually reach, we still can't launch a Chromium instance.

PlayWright fails with:

spawn UNKNOWN\n=========================== logs ===========================\n D:\home\chromium-1064\chrome-win\chrome.exe --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --no-sandbox --user-data-dir=D:\local\Temp\playwright_chromiumdev_profile-RPgsMj --remote-debugging-pipe --no-startup-window\n============================================================

Trying to launch the Chromium executable directly from code, without PlayWright gives a more insightfull error:

An error occurred trying to start process 'D:\home\chromium-1064\chrome-win\chrome.exe' with working directory 'D:\home\site\wwwroot'. The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.

(Please ignore that the working directory is not the same as the launch directory. Changing this makes no difference)

Googling "side-by-side-configuration" hints towards problems with C++ distributables.

I also came across this text:

There are multiple libraries used to convert HTML to PDF. Many Windows/.NET specific versions leverage IE APIs and therefore leverage User32/GDI32 extensively. These APIs are largely blocked in the sandbox (regardless of plan) and therefore these frameworks do not work in the sandbox.

There are some frameworks that do not leverage User32/GDI32 extensively (wkhtmltopdf, for example) and we are working on enabling these in Basic+ the same way we enabled SQL Reporting.

Source: https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#pdf-generation-from-html

So, our question is: is it fundamentally impossible to run PlayWright on a Windows .NET Core App Service, or are we just doing something wrong?

I know people have been running it on Linux / NodeJS App Services, but I feel like this Microsoft supported, .NET native tool should just run on a Windows ASE on Microsoft Azure.

mxschmitt commented 1 year ago

So the error which you are receiving is that the browsers are not there, and most likely as you said the volumes are not persistent. To workaround that there are multiple ways:

a) You can call Microsoft.Playwright.Program.Main(new[] { "install", "chromium" }); during your runtime when you start your service, so a new Chromium will get installed there. b) You can change the path where the browser are installed, so during the time you build your service, the browsers are stored somewhere differently, where the directory is persistent. See here.

These are general ways of fixing that there are no browsers. The other issue you wrote about is that there are libraries missing, which indeed could be the case, since usually such services like Azure App Service, have a very minimal Windows under the hood, and browsers need unfortunately a lot of dependencies to run.

Our general recommendation is to use our official Docker container under the hood, which is guaranteed to work, since we run all our tests there as well: https://playwright.dev/dotnet/docs/docker

karimayachi commented 1 year ago

Hi Max,

Thanks for answering our question! The first problem (the browsers not being present due to none persistent storage) we had indeed already fixed by changing the path in which the browsers were installed.

I mainly included that part to be complete and prevent people from answering "you should install the browsers" 😄

Our real problem indeed is that the browsers won't start. As I understand you, this could indeed be the case and there is no known solution. We will probably proceed by using containers in stead of App Services as you've recommended.

I will close this question. Regards

AlexCorsega commented 5 months ago

Did you make playwright work on azure app service?

GabrielEquusoftware commented 3 months ago

I was able to run it by calling Environment.GetEnvironmentVariable("HOME_EXPANDED") as said in this thread https://stackoverflow.com/a/71056667/6843449