Search code examples
javascriptreactjse2e-testingplaywright

Playwright - baseURL is getting ignored when using custom test fixture


I am creating a fixture to automatically log in. If in tests I import import { test } from "@playwright/test"; then I can normally use await page.goto("/"); instead of "http://localhost:3000/" because in the file playwright.config.ts there is this configuration:

  use: {
    // Base URL to use in actions like `await page.goto('/')`.
    baseURL: "http://localhost:3000/",

    // Collect trace when retrying the failed test.
    trace: "on-first-retry",
  },

However if in specific tests I want to be already configured, I import test from import test from "../fixtures";

This is the fixtures.ts file:

import axios from "axios";
import { test as baseTest } from "@playwright/test";

const test = baseTest.extend({
  contextOptions: async ({ contextOptions, context }, use) => {
    // login function
    const login = async () => {
      try {
        const response = await axios.post(
          "https://content-moderation-service-staging.limango.dev/login",
          {
            email: "usernamethatworks",
            password: "passwordthatworks",
          },
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        );

        const jwtToken = response.data.token;
        return jwtToken;
      } catch (error) {
        console.error(error);
      }
    };

    const jwtToken = await login();


    await context.addCookies([
      {
        name: "access-token",
        value: jwtToken,
        domain: "localhost:3000",
        path: "/",
        expires: new Date(Date.now() + 24 * 60 * 60 * 1000).getTime() / 1000,
        httpOnly: false, // set httpOnly to false
        secure: true,
        sameSite: "Strict",
      },
    ]);

    // eslint-disable-next-line no-param-reassign
    contextOptions.extraHTTPHeaders = {
      Cookie: `access-token=${jwtToken}`,
    };

    await use(contextOptions);
  },
});

export default test;

Such tests work only if I put await page.goto("http://localhost:3000/"); if I put await page.goto("/"); I get:

page.goto: Protocol error (Page.navigate): Cannot navigate to invalid URL
=========================== logs ===========================
navigating to "/", waiting until "load"
============================================================

How can I fix it so that the fixture will use the playwright.config.ts configuration?


Solution

  • Your new contextOption overrides the default one, so you need to add the baseURL to the new one:

    import {test as baseTest} from "@playwright/test";
    
    const test = baseTest.extend({
        contextOptions: async ({ contextOptions, context, baseURL }, use) => {
            //your code
            await use({ baseURL: baseURL })
        }
    });
    
    export default test;
    

    Now running the test, baseURL is passed correctly:

    import test from './fixture'
    import {chromium} from '@playwright/test'
    
    test('Test with custom fixture', async({ contextOptions }, run) => {
        const browser = await chromium.launch()
        const context = await browser.newContext(contextOptions)
        const page = await context.newPage()
        await page.goto('/')
    })