Sponsored Link
Looking for a unified way to  viewmonitor, and  debug Playwright Test Automation runs?
Try the Playwright Dashboard by today. Use the coupon code PWSOL10 for a 12 month 10% discount.

A better way to control before and after blocks with test titles

"Without continual growth and progress, such words as improvement, achievement, and success have no meaning." - Benjamin Franklin.

Have you ever looked at the code you wrote a few months ago and started thinking, "Wow, 'old me' thought it was pretty good, but this is actually just okay"? I love moments like this because they prove that I am learning and growing, finding new ways to resolve issues or even make minor improvements.

Last year I needed to run the afterEach block conditionally, and the solution was this: How to conditionally use afterEach in your Playwright Tests Now, I have found another solution for the same problem (I personally think it's a better style).

Last week I was writing a set of tests and realized that I needed to run the beforeEach block conditionally to create some test data. Using the same logic I used for afterEach before didn't seem fitting, and it would result in heavily relying on the order of the tests. Plus having the same code copied over a few tests would not be DRY (Don't Repeat Yourself).

Thanks to the testInfo class, you can get the test title in before and after blocks (be aware: beforeAll will have access only to the first test, while afterAll will have access only to the last test). I am not going to tell you how helpful testInfo  can be because there is already an article about it here: Is it possible to get the current Playwright test name while the test is running?

Having testInfo in our arsenal, we can control the beforeEach and afterEach blocks with test titles (or key words in them) and a simple if statement in the blocks themselves.

import { test } from "@playwright/test";

test.describe("Control before/after blocks with test titles", async () => {
  test.beforeEach(async ({}, testInfo) => {
    if (testInfo.title.includes("#runBeforeEach"))
      console.log("beforeEach() executed");
  });

  test.afterEach(async ({}, testInfo) => {
    if (testInfo.title.includes("#runAfterEach"))
      console.log("afterEach() executed");
  });

  test("First test", async () => {
    console.log("First test");
  });

  test("Second test #runBeforeEach", async () => {
    console.log("Second test");
  });

  test("Third test #runAfterEach", async () => {
    console.log("Third test");
  });
});
output

Obviously, #runBeforeEach and #runAfterEach can be replaced with anything you want. Just make sure that the code is still readable and makes sense 😉

Keep in mind you can use the if statement not for the whole before/after block but for a part of it.

  test.beforeEach(async ({}, testInfo) => {
    /*
      some code which needs to run before each test
    */

    if (testInfo.title.includes("#runBeforeEach"))
      console.log("beforeEach() executed");
  });

I hope you find this useful, and if you did, please ❤️ and subscribe below to receive more useful tips. If you want to reach out to me personally, feel free to connect or message on LinkedIn.