Search code examples
javascriptbasic-authenticationplaywright

Basic auth not being stored in storageState


I'm setting up a playwright project and trying to store Basic auth for reusability in my tests using dependencies. The setup always passes, yet the example spec fails with the error page.goto: net::ERR_INVALID_AUTH_CREDENTIALS at https://the-internet.herokuapp.com/basic_auth
My config file:

// @ts-check
const {defineConfig, devices} = require('@playwright/test');

/**
 * Read environment variables from file.
 * https://github.com/motdotla/dotenv
 */
// require('dotenv').config();

/**
 * @see https://playwright.dev/docs/test-configuration
 */
module.exports = defineConfig({
  testDir: './tests',
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: 'html',
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Base URL to use in actions like `await page.goto('/')`. */
    baseURL: 'https://the-internet.herokuapp.com/basic_auth',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
  },

  /* Configure projects for major browsers */
  projects: [
    {
      name: 'setup',
      testDir: './',
      testMatch: 'globalSetup.js'
    },
    {
      name: 'testrun',
      dependencies: ['setup'],
      use: { storageState: './LoginAuth.json' }
    },
],
}
globalSetup: 
test('setup', async ({ page }) => {
    const authHeaders = 'Basic ' + Buffer.from('admin:admin').toString('base64');
    await page.setExtraHTTPHeaders({ Authorization : authHeaders })
    await page.goto('');
    await expect(page.getByText('Congratulations!')).toBeVisible();
    await page.context().storageState({ path: './LoginAuth.json' })
})
my spec: 
test('new fckn test', async ({page}) => {
  await page.goto('');

  await expect(page.getByText('Congratulations!')).toBeVisible();
})

I tried the old way as well already (function globalSetup()) and a few different variations, yet nothing works. What am I doing wrong?


Solution

  • I believe that basic auth credentials are not stored in the local storage or cookies.

    You can set httpCredentials in the config and remove the setup project. Example:

    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      use: {
        httpCredentials: {
          username: 'user',
          password: 'pass',
        },
      },
    });
    

    Docs: https://playwright.dev/docs/api/class-testoptions#test-options-http-credentials

    The approach you have taken is valid for cases where session cookies are involved. Basic auth uses the same credential in every request, so it is just cached by the browser in memory.