javascripttypescriptautomated-testsplaywrightplaywright-test

Playwright before each for all spec files


I am very new to Playwright. Due to my test suites, I need to login into my application before running each test. Inside a single spec file that is easy, I can simply call test.beforeEach. My issue is: I need to before the login before each test of each spec file.

test.describe('Test', () => {
    //I need to make the code inside this beforeEach a exported 
    //function to call inside the before each of every spec file I have
    test.beforeEach(async ({ page }) => {
        await page.goto('/login');
        await page.click('text=Log in with Google account');
        await page.fill('id=identifierId', LoginAutomationCredentials.USER);
        await page.click('button[jsname="LgbsSe"]');
        await page.fill('input[type="password"]', LoginAutomationCredentials.PASSWORD);
        await page.click('button[jsname="LgbsSe"]');
        const otp = authenticator.generateToken(LoginAutomationCredentials.TOKEN);
        await page.fill('id=totpPin', otp);
        await page.click('button[jsname="LgbsSe"]');
    });

    it('Some description', async ({ page }) => {
        await page.goto('/foo');
        const dateFilter = await page.inputValue('input[placeholder="2011/03/02"]');
        expect(dateFilter).toBe('2021/12/07');
    });
});

I tried simply taking that code and and making it a function inside a separate .ts file and then importing it, but I figured the context is needed in order to do this. This is probably something every tester that uses playwright knows and uses regularly, however, I did not find anything on the subject.

How can I avoid copying the entire code of beforeEach and pasting it to all my spec files? How can I make it a function and call it whenever I want?


Solution

  • Use fixtures.

    fixture.js:

    const base = require('@playwright/test')
    const newTest = base.test.extend({
        login: async({page}, use) => {
            await login();
            await use(page); //runs test here
            //logic after test
        }
    })
    exports.newTest = newTest
    exports.expect = newTest.expect
    

    Then in your tests:

    const {newTest} = require('fixture.js')
    newTest('mytest', async ({login}) => {
        //test logic
        login.goto(''); // using login here since I pass it as page in the fixture.
    })