Last week, I worked on setting up shared authentication for end-to-end Playwright tests in starchart. This was necessary to avoid having to login before every test. The Playwright docs suggest a few different ways of doing this, such as a shared account for all tests, or setting up multiple roles.
I went with a similar setup to the setup you would have for multiple roles with a shared account across all tests that require login. Currently, all the pages do not differentiate between roles, i.e., they do not show different things based on the role. However, a design for an admin dashboard was being worked on, and will be implemented in the upcoming weeks. So, I decided to use a setup that would be easy to expand for different roles such as an admin
user.
I started by adding a setup file under my e2e tests folder which would go through the login process, and save the authenticated state in a file:
import { test as setup } from '@playwright/test';
const userFile = 'test/e2e/.auth/user.json';
setup('authenticate as user', async ({ page }) => {
...
// Login steps
await page.context().storageState({ path: userFile });
});
Then I modified playwright config and added a new project that will be a dependency of all other projects. A project has a name and defines configuration for running the tests on a specific device in this case:
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/,
},
{
name: ...,
use: {
...devices['Desktop Chrome'],
},
dependencies: ['setup'],
},
... other projects
By setting setup as a dependency, it will be run before the tests in the project are run. testMatch
defines a regex for the setup file(s), and it matches paths relative to the test directory defined in the config.
Since the setup process is run before the tests are run, we actually don't need to commit our file with the saved session to git. Thus, I added it to the .gitignore
file.
I also added tests for the New DNS Record form
. This form is used by a user to create a new DNS Record
. Since this required a user to be logged in, we can use the saved session state generated in the setup
project:
test.describe('authenticated as user', () => {
loggedInAsUser();
Here, loggedInAsUser()
is a util function that was added based on PR reviews:
export function loggedInAsUser() {
return test.use({ storageState: 'test/e2e/.auth/user.json' });
}
test.use
can be specified in a describe
block or in a test file. It is not necessary to use this in a beforeEach
or beforeAll
, and doing so would result in an error.
I ran the tests locally, and they all passed. However, I encountered a strange error in CI (which uses GitHub Actions) for the Mobile Safari
project:
Test timeout of 30000ms exceeded.
page.goto: Navigation failed because page was closed!
Playwright generates a report containing a video and a trace on the first retry, depending on the configuration. I looked at the video and saw that most of it was a blank black screen. After trying a bunch of things such as upgrading playwright, and commenting out all other projects, I found this open issue on the playwright project. There was a super helpful comment left on the issue with a temporary workaround. Basically, setting isMobile
to false for the iPhone
configuration used by the Mobile Safari
project results in the CI passing on GitHub actions.
Top comments (0)