3

Goal: Use playwright for testing without having to log in multiple times as per documentation here.

Problem: Playwright tests not picking up session token from Next-Auth and hence am not able to reuse an authenticated status across mutiple tests.

My understanding is that Next-Auth checks for next-auth.session-token to validate the auth status. However following the above docs, I've noticed that the session token never get's stored in the storageState.json. If I manually add in the session token to the JSON then the tests work as expected.

Here is a very barebones repo I've setup with just a login button and one test.

Here's the typical [...nextAuth].js

import GithubProvider from "next-auth/providers/github";

export const authOptions = {
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
  debug: true,
};

export default NextAuth(authOptions);

Here's the global-setup.js for Playwright with email/password swapped out


module.exports = async () => {
  const browser = await chromium.launch({
    headless: false,
  });
  const page = await browser.newPage();

  await page.goto('http://localhost:3000/');
  await page.getByRole('button', { name: 'Sign in' }).click();
  await page.getByRole('button', { name: 'Sign in with GitHub' }).click();
  await page
    .getByLabel('Username or email address')
    .fill('email');
  await page.getByLabel('Password').fill('password');
  await page.getByRole('button', { name: 'Sign in' }).click();

  await page.context().storageState({ path: 'storageState.json' });
  await browser.close();
};

Here's the e2e test I'm running

const { test, expect } = require("@playwright/test");

test.use({
  storageState: "storageState.json",
});

test("sign in through github", async ({ page }) => {
  await page.goto("http://localhost:3000");
  await expect(page.getByText("Signed in as")).not.toBeEmpty();
});

I expect the auth state to be stored in storageState.json from the code in global-setup.js. It does indeed store information there but it's missing the next-auth.session-token for some reason and hence causes the tests I'm running to fail.

6
  • Were you ever able to solve this? One thought is that maybe the global setup didn’t wait long enough after clicking the sign in button before saving the storageState. Commented Feb 12, 2023 at 8:51
  • No never solved it. The global setup stores stuff, it just for some reason leaves out the "next-auth.session-token". I'll probably try my luck creating a ticket in playwright's github page. Interesting to see no one else is having a similar issue nor are there examples online. Commented Feb 13, 2023 at 0:26
  • That is odd… if you add a breakpoint/pause, run in debug mode, and inspect the browser are you able to find that cookie? Just to make sure the cookie is there and that Playwright is just not saving it. Could also potentially use Playwright’s cookies method to see if Playwright can find it that way to determine if Playwright even detects the cookie, if that makes sense. Commented Feb 13, 2023 at 0:45
  • Verified that the cookie is there, that's why I posted the question in the first place. I'll look into the cookies method you suggested, thanks. Commented Feb 25, 2023 at 3:56
  • You stated that your “understanding is that Next-Auth checks for” it, and that it wasn’t in the storageState.json, but never indicated that you had verified the cookie was actually there when it runs and could’ve just assumed it would’ve been there, or that it would’ve been there at the time storageState.json was saved, so I wanted to clarify/confirm. I am interested in the potential results of using the cookies method to try and check what Playwright sees, as it could point more specifically to the issue. Commented Feb 25, 2023 at 8:17

3 Answers 3

0

This is what worked for me:

In playwright.config.ts, in the projects section, I added a path to the storage state file (where user.js is located):

projects: [
   { name: 'auth-setup', testMatch: /auth\.setup\.ts/ },
   {
     name: 'Desktop Chrome',
     use: {
       ...devices['Desktop Chrome'],
       storageState: <storage_state_path>, // <---- Add this
     },
     dependencies: ['auth-setup'],
   },
]
Sign up to request clarification or add additional context in comments.

Comments

0

I had the same issue, the mentioned next-auth.session-token is stored but it does not happen instantly with other cookies at start.

In my situation waiting for url helped.

So:

  1. Login as user
  2. Check session cookies - next-auth.session-token will not be there yet
  3. Wait for some url with page.waitForUrl() so that the page would load
  4. Check session cookies - the next-auth.session-token should be there (it was in my case)

Comments

0

I seem to have gotten farther than most here on this exact issue.

Unfortunately haven’t cracked it yet.

https://github.com/nextauthjs/next-auth/discussions/12022

TLDR is it’s working for me only in ui mode and only on the 2nd and subsequent test runs.

Absolutely no idea why the cookie behaves like this.

1 Comment

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.