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]: Nuget package version compatibility #2181

Closed cosminstirbu closed 2 years ago

cosminstirbu commented 2 years ago

Hello,

We're using Azure DevOps to run our Playwright tests and at the moment we're installing Playwright on demand before we run the tests via pwsh bin/Debug/net6.0/playwright.ps1 install --with-deps chromium

This takes approximately 1m 30s to install it.

We'd like to "pre-install" Playwright by baking it into a Docker image that we would use via a self-hosted build agent.

We're not sure however if there is some sort of strong-coupling or backwards compatibility issues - e.g. if the current "client" Nuget version is 1.22.0 and we would bump the "server" to a newer version in our Docker image - would this lead to any issues?

The vice versa I would expect to lead to issues, especially if the "client" relies on some new functionality that is not available on an older "server" version.

Thank you, Cosmin

mxschmitt commented 2 years ago

There is strong coupling between the operating system dependencies a browser requires and browsers itself and Playwright versions. (For Chromium not that strong, but for WebKit and Firefox very strong).

if you're using launchServer/connect then the version always has to match, but I think you mean something else with your client/server example.

We recommend using the official Docker image, this is guaranteed to work with the right version over time: https://playwright.dev/dotnet/docs/docker

cosminstirbu commented 2 years ago

Our self-hosted agents are Docker images themselves, so we're not able to run the Playwright Docker image in another Docker image.

My client/server terminology is probably inaccurate. I made a parallel with Appium, where the server can be installed via npm and then you can use the any client library (e.g., C#, Java, etc) in our tests that interacts with the server.

So given that we already have a Docker image, what would be the best way to pre-install Playwright on that image so we can then run our tests using the Nuget package?

What considerations should we keep in mind when managing the versions of the pre-installed Playwright and the Nuget package?

mxschmitt commented 2 years ago

If you have your own Docker image, you can extend (FROM keyword in Docker) from our image, and then it already contains the OS dependencies, browsers and has the right operating system (ubuntu).

Preinstalling Playwright for .NET works probably like that: https://github.com/microsoft/playwright-dotnet/blob/c1386969fd21739aa8bb4324e7bcf507b382055d/utils/docker/Dockerfile.focal#L29-L41

if you have no project yet, so we're creating one, installing Playwright, building it and installing the browsers etc. with the pwsh file.

What considerations should we keep in mind when managing the versions of the pre-installed Playwright and the Nuget package?

That they need to match the version.

cosminstirbu commented 2 years ago

Thank you for sharing the install scripts, they are really helpful.

Since the versions need to match, I am wondering what would be the best approach to have multiple Playwright versions pre-installed so we can allow teams to control (maybe via an environment variable) which version they want to use.

Our self-hosted agents are used by multiple teams, and each team might rely on a different version of Playwright.

I am looking for something similar to the Microsoft-hosted agents - e.g., https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md#net-core-sdk we can see here we have multiple versions of .NET Core SDK and the user can control which one they want to use.

mxschmitt commented 2 years ago

ah gotcha, so if you do this multiple times and keep the project directories alive, then the browsers won't be garbage collected from the internal registry.

Browsers are usually quite lightweight, only ~100mb each, takes usually less than 5 seconds to download. So I think the major point are the operating system dependencies, which you can install with "--with-deps" or just "install-deps" see here: https://playwright.dev/dotnet/docs/cli These take usually 1-2 minutes to install.

cosminstirbu commented 2 years ago

So you're suggesting to install only the operating system dependencies as part of the Docker image and then install the browsers on demand before running the tests?

Is it safe to assume that the operating system dependencies are compatible with most Playwright versions?

mxschmitt commented 2 years ago

If you install the OS system dependencies for version 1.18 and version 1.22 you can ensure that the browsers are going to launch on both of the versions. I'd not go so far and make the assumption that 1.23 will also work, it probably will, but e.g. WebKit changes deps sometimes and then it will fail to launch the browser.

cosminstirbu commented 2 years ago

Ok, we'll give that a try. We'll pre-install the OS system dependencies on the Docker image and install the browser on demand.

Thank you.

mxschmitt commented 2 years ago

Closing by that!

cosminstirbu commented 2 years ago

Hi @mxschmitt - we did include the snippet above in our own image, however we're running into the following exception that seems to do something with the path:

Microsoft.Playwright.PlaywrightException : Executable doesn't exist at /root/.cache/ms-playwright/chromium-1005/chrome-linux/chrome

It looks like we should probably update the path used in the snippet, not sure what value we should update to though.

304NotModified commented 2 years ago

Microsoft.Playwright.PlaywrightException : Executable doesn't exist at /root/.cache/ms-playwright/chromium-1005/chrome-linux/chrome

related; https://github.com/microsoft/playwright-dotnet/issues/2239

mxschmitt commented 2 years ago

You need to execute the ps1 script again, otherwise the browsers are not installed. Also make sure that the Docker image tag matches with the Playwright version you are using, then the browsers


@304NotModified please don't send in every issue that you want to have automatically the browsers installed before launching them. If you want to do it, you can manually do that with the workaround described in it.

304NotModified commented 2 years ago

@mxschmitt just linked related stuff. But will do it the other way around otherwise.

Sorry about that. will remove the noisy posts

mxschmitt commented 2 years ago

Yes please, because like this you generate a huge amount of notifications, people will get emails etc. I'm totally fine with the other way!

cosminstirbu commented 2 years ago

@mxschmitt

I did run install-deps chromium command as well via the ps1 script from the tests .csproj.

You are right about the versions though - on the docker image we were using 1.24.1, while in the tests .csproj we had 1.22.0. After I've updated the .csproj to also use 1.24.1 it worked.

However, this takes me back to my initial question about the coupling between the docker image version and the .csproj version. You've suggested that it should be safe to have an older version installed on the docker image with the operating system dependencies and a newer version in the .csproj that installs the browser dependencies - is this still the case? (I know that in my specific error we had the opposite, we had a newer version in the docker image and an older version in the .csproj, so please disregard this scenario).

mxschmitt commented 2 years ago

install-deps only installs OS deps not the actual browsers. See here: https://playwright.dev/dotnet/docs/cli#install-browsers

What you want is install --with-deps or call both after each other.

cosminstirbu commented 2 years ago

I understand. I'm still not clear about how the versioning works though, and what would be the acceptable scenarios where the version installed (with system dependencies) on the docker image can be different from the Nuget version (which will install the browsers).

mxschmitt commented 2 years ago

TL;DR: if you use the official Docker image with the exact version as .NET dependency, then you don't need install/install-deps if you use an official supported OS aka Ubuntu or the official Docker image with a different version tag, then you need install/install-deps OR install --with-deps