Global setup code is code that runs before your other tests. This can be, for example, a login action, navigation to a URL, or clicking away that annoying cookie bar. Usually these are actions that you want executed once before the rest of your tests run. You can do this by defining a global setup file as explained in my other article: Authenticate Once with Playwright. As of version 1.31, there is a new way of writing Playwright setup code — by using project dependencies. I will use the login method as an example.
If you want to dive straight into the solution, you can check out the repository HERE.
Let’s create a file called login.setup.ts and define a test to log in a user:
At the top of the file, you can use an import alias to distinguish that this test is a setup test. On line 7 instead of using the “test” keyword, you can use the “setup” alias. This will not change the behavior of the test.
The username and password are read from a .env file that you need to create when you clone the repository and would like to run this on your machine.
Logging in consists of navigating to the login page, filling in the credentials, and clicking on the “Log in” button. The “waitForURL” method checks that the page has navigated to the URL after clicking the button. After this it will proceed to line 15. On this line, the state is saved to a file.
In the playwright.config.ts file you can add a project dependency as follows:
At the top of the file, the dotenv library is initialized. Recall that the username and password are read from the environment variables.
On line 7, the path to the storage state is specified. This is used in our setup test to write the storage data.
The first project in the projects array is the setup project. This will run the test inside the “login.setup.ts” file. In the second project named “Chrome”, the “dependencies” property is added. You can also depend on multiple projects. You can read more on this here.
In this case, there is one dependency on the setup project. This will ensure that all tests in the setup projects will run, and need to pass, before the tests in the “Chrome” project.
While writing Playwright setup code can be also be done with a global setup file, let’s have a look at a comparison to this new project dependencies approach. On the website of Playwright, some of the listed benefits over the traditional global setup file are:
All these benefits are an effect of being able to write setup code as test code.
Global setup file:
As a dependency:
The dependency test is shown in the run results, giving the full picture of the test run. This could be important when you have a bottleneck somewhere in your setup code.
Global setup file:
As a dependency:
As you can see there is a lot more detail, which can be very useful for debugging.
If you debug using the VSCode Playwright plugin it is easiest when you are using the default Playwright config file “playwright.config.ts”.
Global setup file:
The experience is as you would expect from a debugger. You cannot directly debug the setup code, instead you need to debug one of your tests that follows the global setup code. One thing that is missing though is the ability to visually highlight elements in your browser:
As a dependency:
When using the VSCode debugger, you can place a breakpoint directly in the setup code and run that setup code, because it is seen as a test in the Playwright test explorer. However, if you run a test in a project that depends on the setup test, the setup code will not be triggered.
You are able to visually highlight DOM elements:
Using project dependencies for writing Playwright setup code is fairly easy and consists of the following steps:
There are some benefits to using project dependencies, such as displaying the setup tests in a reporter and a slightly better debugging experience. The added flexibility allows for more complex scenarios when projects need to depend on multiple selected setup tests. There is also the consistency factor in that your setup code looks like the rest of your test code.
All in all, I prefer using project dependencies over a global config file.
Which method do you prefer? Drop me a message on LinkedIn or Twitter @rscorradin.