I have an E2E tests suite with Playwright that runs on different browsers and viewports.
I specified the different browsers and viewports in my playwright.config.ts
:
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
},
},
{
name: 'webkit',
use: {
...devices['Desktop Safari'],
},
},
/* Test against mobile viewports. */
{
name: 'Mobile Chrome',
use: {
...devices['Pixel 5'],
},
},
{
name: 'Mobile Safari',
use: {
...devices['iPhone 12'],
},
},
]
There are certain tests that need to execute different assertions and clicks based on the viewport.
For example, when the viewport gets small enough, the header shrinks into a burger menu. On desktop, there is a "log out" button in the header, but on mobile, you have to open the burger menu first to see the "log out" button.
How can I write a test that runs only on mobile viewports (and vice versa, a test that runs only on desktop viewports)?
I was able to make it work with Playwright, but I didn't like my solution and suspect there is a better way to do this.
I grabbed the isMobile
property from the test
function, and then added a conditional click to open the burger menu on mobile like this:
test('given the user is logged in: lets the user log out', async ({
page,
baseURL,
isMobile,
browserName,
}) => {
const { id } = await loginAndSaveUserProfileToDatabase({ page });
await page.goto('./home');
if (isMobile) {
await page.getByRole('button', { name: /open main menu/i }).click();
}
// Logging the user out should redirect you to the landing page.
await page.getByRole('button', { name: /open user menu/i }).click();
await page.getByRole('menuitem', { name: /log out/i }).click();
expect(page.url()).toEqual(baseURL + '/');
// ...
}));
I don't like this approach, because it introduces a conditional into the test, which is an anti-pattern (and gets called out by the Playwright ESLint plugin). Also isMobile
doesn't work for Firefox.
Ideally, there'd be a feature in Playwright like TestCafe's meta
tags. In TestCafe you can add a meta
to the test and filter out tests through this tag.
test
.meta('mobile', true)
('My test that only runs on mobile', async t => { /* ... */});
But I couldn't find anything like that in the docs (other than grep
tagging, which I'm unsure if its well suited for this use-case), so I'm asking this question.