Search code examples
typescriptplaywright

.beforeEach() POM on Playwright


At the moment, I have a file mytest.test.ts and the following code:

import { test, Page, expect } from '@playwright/test';
import * as homepage from '../pages/homepage';
import * as importQuiz from '../pages/importQuiz';
import * as sso from '../pages/sso';

let page: Page;

test.beforeEach(async ({ browser }) => {
  const email = process.env.EMAIL;
  const password = process.env.PASSWORD;
  const url = process.env.URL;
  page = await browser.newPage();
  await page.goto(url);
  await page.fill(sso.inputEmailField, email);
  await page.click(sso.submitButton);
  await page.fill(sso.inputPasswdField, password);
  await page.click(sso.submitButton);
  await page.click(sso.submitButton)
});

test.afterAll(async () => {
  await page.close();
});

test('test 1', async () => {
  await page.click(homepage.importQuizButton);
  await page.click(importQuiz.backButton);
  await expect(page.locator(homepage.homePage)).toBeVisible();
});

I would like to transfer test.beforeEach() to another file (so I can use it multiple times). I created a new file login.ts and pasted the following code:

import { test, Page } from '@playwright/test';
import * as sso from '../pages/sso';


export function login() {
    let page: Page;
    test.beforeEach(async ({ browser }) => {
        const email = process.env.EMAIL;
        const password = process.env.PASSWORD;
        const url = process.env.URL;
        page = await browser.newPage();
        await page.goto(url);
        await page.fill(sso.inputEmailField, email);
        await page.click(sso.submitButton);
        await page.fill(sso.inputPasswdField, password);
        await page.click(sso.submitButton);
        await page.click(sso.submitButton)
    })}

Then I modified my previous file (mytest.test.ts):

import { test, Page, expect } from '@playwright/test';
import * as homepage from '../pages/homepage';
import * as importQuiz from '../pages/importQuiz';
import * as sso from '../pages/sso';
import * as login from '../objects/login'

let page: Page;
login.login()


test.afterAll(async () => {
  await page.close();
});

test('test 1', async () => {
  await page.click(homepage.importQuizButton);
  await page.click(importQuiz.backButton);
  await expect(page.locator(homepage.homePage)).toBeVisible();
});

This is the error that I am getting:

Playwright Test did not expect test.beforeEach() to be called here.
Most common reasons include:
- You are calling test.beforeEach() in a configuration file.
- You are calling test.beforeEach() in a file that is imported by the configuration file.
- You have two different versions of @playwright/test. This usually happens
  when one of the dependencies in your package.json depends on @playwright/test.

Should I somehow add it to playwright.config.ts file? Where is the best place to locate it and how the code should look like? Thank you!


Solution

  • Not sure if it is possible to get rid of the entire before each, but you could move all of the logic to a utils.ts file.

    So in your utils.ts:

    export async function login( page: Page ) {
      const email = process.env.EMAIL;
      const password = process.env.PASSWORD;
      const url = process.env.URL;
      await page.goto(url);
      await page.fill(sso.inputEmailField, email);
      await page.click(sso.submitButton);
      await page.fill(sso.inputPasswdField, password);
      await page.click(sso.submitButton);
      await page.click(sso.submitButton)
    }
    

    And in your tests you just have a beforeEach calling that function:

    test.beforeEach(async ({ page }) => {
      await login(page);
    });