playwright: [BUG] Playwright cookie not written on file for auth on gitlab-ci
Hello, I am trying to implement playwright Auth on gitlab ci and i have nearly tried every way possible, this is not a server related problem since the cookie is being sent from the server, what i have tried:
- using the before script and going through regular UI auth, kicks back to the auth page (somehow the authentified state is not preserved) Link to video from playwright report using the before all method
- I went to global auth config setup, first started with the global setup which worked at first and then did not work on gitlab ci (not creating cookies file, therefore not storing anything), so i checked the docs and found this new way of doing auth link
- Auth setup file as a test, and then setting a setup project as dependency for other projects, so i implemented that, and now i am getting a 200 reponse from the server with the cookie, but it is not set on the cookies file i am setting( you will find the server reponse in the ci photos, and the cookie is not written in the file).

I am a bit confused to what i am doing wrong,i know that the problem lies within the function that writes the state to the file, so i thought about writing a function that writes the cookie from the response to a file replacing the storage state function, but i thought first maybe i am doing something wrong and someone can point me at the right direction, any help is appreciated, thanks.
System info
- Playwright Version: [1.32.2]
- Operating System: [All]
- Browser: [All, Chromium, Firefox, WebKit]
- Other info:
Source code
- I provided exact source code that allows reproducing the issue locally.
Config file
// playwright.config.ts
/* eslint-disable import/no-extraneous-dependencies */
import { defineConfig, devices } from '@playwright/test';
import { config } from 'dotenv';
import { resolve } from 'path';
// import { resolve } from 'path';
import vite from '../../vite.config';
config({ path: `${process.env.INIT_CWD}/../../.env.local` });
export default defineConfig({
// outputDir: '/builds/estale/playwright',
testDir: './views',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* Run tests in files in parallel */
fullyParallel: false,
/* 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', { open: 'never' }]],
/* Global setup and teardown scripts. See https://playwright.dev/docs/test-advanced#global-setup-and-teardown */
// globalSetup: require.resolve('./playwright.setup.ts'),
// globalTeardown: require.resolve('./playwright.teardown'),
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
headless: false,
actionTimeout: 0,
trace: 'on-first-retry',
video: 'on',
// baseURL: 'http://127.0.0.1:3000',
screenshot: 'on',
// baseURL: import.meta.env.BASE_URL,
// baseURL:`http://${vite['server'].host}:${vite['server'].port}`,
// storageState: resolve(__dirname, 'playwright.cookies.json'),
launchOptions: {
slowMo: 1000,
},
ignoreHTTPSErrors: true,
},
/* Configure projects for major browsers */
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
storageState: resolve('src/intranet/views', 'playwright.cookies.json'),
},
dependencies: ['setup'],
},
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
storageState: resolve('src/intranet/views', 'playwright.cookies.json'),
},
dependencies: ['setup'],
},
{
name: 'webkit',
use: {
...devices['Desktop Safari'],
storageState: resolve('src/intranet/views', 'playwright.cookies.json'),
},
dependencies: ['setup'],
},
],
webServer: [{
command: 'npm run dev',
url: `http://${vite['server'].host}:${vite['server'].port}`,
// url: 'http://127.0.0.1:3000',
timeout: 120 * 1000,
reuseExistingServer: !process.env.CI,
}],
});
Auth setup test file
/* eslint-disable import/no-extraneous-dependencies */
// auth.setup.ts
import { test as setup, expect } from '@playwright/test';
import { resolve } from 'path';
const authFile = resolve(__dirname, 'playwright.cookies.json');
// await requestContext.storageState({ path: config.projects[0].use.storageState as string });
// const authFile = 'playwright.cookies.json';
const login = 'XXX;
const motdepasse = 'YYY';
//old method of authentication using UI (does not set the cookie)
/* setup('authenticate', async ({ page }) => {
// Perform authentication steps. Replace these actions with your own.
await page.goto('http://127.0.0.1:3000/auth/signin');
const mail = page.getByPlaceholder('Saisissez votre adresse e-mail');
const mdp = page.getByPlaceholder('Saisissez votre mot de passe');
const loginBtn = page.getByText('Se connecter');
await mail.fill(login, { force: true });
await mdp.fill(motdepasse);
await loginBtn.click();
await page.waitForLoadState('domcontentloaded');
await page.context().storageState({ path: authFile }).then(() => {
console.log('state written to file!');
}).catch((err) => console.log(err));
// const l = await page.context().storageState();
// console.log('authentication done!', l);
});
*/
//api auth(does not set the cookie)
setup('authenticate', async ({ request }) => {
// Send authentication request. Replace with your own.
console.log('inside api auth!');
const response = await request.post('http://docker:8080/api/login', {
data: {
email: login,
password: motdepasse,
},
headers: {
'Content-Type': 'application/json',
},
});
expect(response.ok()).toBeTruthy();
expect(response.status()).toBe(200);
console.log('response from auth test: ', await response.json());
// await request.storageState({ path: authFile });
await request.storageState({ path: authFile }).then(() => {
console.log('state written to file!');
}).catch((err) => console.log(err));
console.log(response);
console.log('Authentication done!');
});
Test file (self-contained)
const authFile = resolve(__dirname, 'playwright.cookies.json');
// test.use({ storageState: authFile });
test('Visit Intranet', async ({ page }) => {
console.log(`cookies: ${await page.context().cookies()}`);
await page.goto('http://127.0.0.1:3000/intranet/');
await page.waitForLoadState('load');
});
Steps
- [Authentication]
- [Running the tests]
Expected
[The cookie should be written in the playwright.cookies.json file, and the tests authentified]
Actual
[The browser kicks back to the login page(using before script / global setup / auth.setup.ts), the cookie is also not set]
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 5
- Comments: 21 (5 by maintainers)
I’m facing the same issue.
I think it’s really odd that we can still be facing this kind of issue in our day and age
Try to run your frontend part on CI and then check proxy set up. If you have health checker. By curl for example
curl -v -X GET http://localhost:3000/api/health. Make sure that you set it up correctly.It should be something like this:
or
if you have api prefix
In your tests you should make api calls from
http://frontend_domain/apiYes, because of the different domains for frontend and api. Try using a proxy, I think it will work for you as well.
Happening to me too and can’t seem to find a fix.
Same problem
Same problem