Run grouped tests sequentially using Playwright

Viewed 5544

I'm using Playwright with nodejs and I have grouped a couple of tests together like this

import { test, expect } from '@playwright/test';

test.describe('Add a simple invoice test', () => {
    test('01.Login & add an invoice', async ({ page }) => {
        await page.goto("https://someUrl.com");
        await page.fill('input[id="email"]', "someEmailAddress");
        await page.fill('input[ng-model="ctrl.user.password"]', "somePassword");
        await page.click('button[id="login-btn"]');
    });

    test('02.Add an invoice', async ({ page }) => {
        await page.click('[name="invoice"]');
        await page.click('button[id="addInvoiceButton"]');
        await page.click('a[ng-click="ctrl.goToAddInvoice()"]');
        await page.fill('#invoiceTitle', Math.random().toString(36).substring(7));
        await page.fill('#exampleInputAmount', "120");
        await page.click("#invoiceCategory")
        await page.fill("#invoiceCategory > input", "Car")
        await page.keyboard.press("Enter");
        await page.click('button[id="submitInvoiceButton"]');
    });
});

The problem is that these 2 tests run in parallel whereas 02 is dependant on 01 since there's a required login.

How do I make 2 grouped tests run in the same context?

3 Answers

You shouldn't make your tests depend on each other. For example, I would extract the common login to a function and call that function from both tests. You could even add some asserts to the first test to check that the login worked. But you wouldn't do that on the second one.

The solution is very simple. It is executing as an independent test since you are passing {page} in each test, so if you want to use the same context for both the test you need to modify the test like below.


test.describe('Add a simple invoice test', () => {
  let page: Page;
  test.beforeAll(async ({ browser }) => {
    page = await browser.newPage();
  });

    test('01.Login & add an invoice', async () => { // do not pass page
        await page.goto("https://someUrl.com");
        await page.fill('input[id="email"]', "someEmailAddress");
        await page.fill('input[ng-model="ctrl.user.password"]', "somePassword");
        await page.click('button[id="login-btn"]');
    });

    test('02.Add an invoice', async () => { //do not pass page 
        await page.click('[name="invoice"]');
        await page.click('button[id="addInvoiceButton"]');
        await page.click('a[ng-click="ctrl.goToAddInvoice()"]');
        await page.fill('#invoiceTitle', Math.random().toString(36).substring(7));
        await page.fill('#exampleInputAmount', "120");
        await page.click("#invoiceCategory")
        await page.fill("#invoiceCategory > input", "Car")
        await page.keyboard.press("Enter");
        await page.click('button[id="submitInvoiceButton"]');
    });
});

This should work as you expected You can also refer to the Dzone Article regarding the same.

Note: Playwright doesn't recommend this approach but this answer should fulfill your need.

If you have a bunch of tests that have common setup steps then Playwright Test Runner has some pre-canned features you can use to either run once before all the tests (test.beforeAll) or alternatively before each test (test.beforeEach).

Docs for that are here: https://playwright.dev/docs/test-intro#use-test-hooks

There are similar options for teardown, so they could be something simple like going to the login page and logging in (then logging out at the end?), or something more complex like setting up data and clearing it down after the test.

Related