Playwright - 未从 Chromium 中不同域的 storageState 文件设置 Cookie

Sri*_*hti 6 testing cookies chromium e2e-testing playwright

概念

我正在使用通过Playwright 中的文件重用身份验证状态的概念storageState
以下是我分布在不同文件中的代码片段:

代码

剧作家.config.json

import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';

const config: PlaywrightTestConfig = {
    testDir: './e2e',
    reporter: 'html',
    globalSetup: require.resolve('./e2e/global-setup.ts'),
    use: {
        storageState: './e2e/authStorageState.json',
    },

    projects: [
        {
            name: 'firefox',
            use: {
                ...devices['Desktop Firefox'],
            },
        },

        {
            name: 'webkit',
            use: {
                ...devices['Desktop Safari'],
            },
        },

        {
            name: 'chromium',
            use: {
                ...devices['Desktop Chrome'],
            },
        },
    ],
};

export default config;
Run Code Online (Sandbox Code Playgroud)

全局设置.ts

require('dotenv').config();

import { firefox, FullConfig } from '@playwright/test';
import E2EConstants from './e2e.constants';

const authenticateUser = async () => {
    const browser = await firefox.launch();
    const page = await browser.newPage();

    await page.goto(`${process.env.BASE_URL}/${E2EConstants.LoginPage.URL}`);
    await page
        .getByLabel(E2EConstants.LoginPage.LABEL.EMAIL)
        .fill(process.env.TEST_ADMIN_USERNAME as string);
    await page
        .getByLabel(E2EConstants.LoginPage.LABEL.PASSWORD)
        .fill(process.env.TEST_ADMIN_PASSWORD as string);
    await page.getByText(E2EConstants.LoginPage.BUTTON).click();

    await page.waitForLoadState('networkidle');

    await page.context().storageState({ path: './e2e/authStorageState.json' });

    await browser.close();
};

async function globalSetup(_: FullConfig) {
    await authenticateUser();
}

export default globalSetup;
Run Code Online (Sandbox Code Playgroud)

这会设置文件中的所有 cookie authStorageState.json。但是,有些 cookie 的域为 as .b.com,有些 cookie 的域为a.b.com

示例.spec.ts

require('dotenv').config();
import { test, expect } from '@playwright/test';

test('homepage has same link', async ({ page }) => {
    await page.goto(process.env.TEST_URL as string);

    await expect(page).toHaveURL(process.env.TEST_URL as string);
});
Run Code Online (Sandbox Code Playgroud)

TEST_URL带有域的 URL a.b.com,该域位于身份验证之后,并且仅当用户登录时才可访问。

问题

当我运行测试时,我发现 Chromium 测试失败,但 Firefox 和 Webkit 测试通过。与其他浏览器不同,该测试无法让用户在 Chromium 上登录。a.b.com这是因为Chromium 上没有设置与身份验证相关的 cookie(属于域),但在其他浏览器上设置了它们。但是,与身份验证无关的 cookie(属于.b.com域)在所有浏览器上均已正确设置。

我尝试过的

  1. 我尝试在删除与身份验证相关的 cookie 的和键后手动设置保存在文件url中的 cookie ,然后当我运行测试时,Chromium 测试也通过了。authStorageState.jsonhttps://a.b.comdomainpath
  2. secure所有未设置的 cookie 的键值为false。我尝试手动更改"secure": true所有未设置的cookie。请注意,该sameSite属性设置为"None"。这一更改使得 Chromium 测试用例通过。
  3. sameSite所有未设置的 cookie 的键在"None"具有"secure": false属性的同时也具有值。我尝试手动删除"sameSite": "None"所有未设置的 cookie 的属性。请注意,我没有更改该secure属性。这一更改使得 Chromium 测试用例通过。

[请注意,上述所有要点都是作为解决方法独立实施的,而不是一起完成的。]

要求

但是,由于该authStorageState.json文件是在首次登录时默认创建的,因此我想保留浏览器上显示的相同 cookie,而不是手动操作它们。如何让我的 Chromium 测试用例通过?

疑虑

  1. url为 Chromium 提供而不是domain+有什么区别path
  2. 为什么带有子域的 cookiea.b.com需要secure设置属性true并且基于 Chromium 的测试用例在此更改后通过?
  3. 删除"sameSite": "None"所有具有子域的 cookiea.b.com是否正确?为什么基于 Chromium 的测试用例在此更改后能够通过?