feat: use setup() instead of test() for project setup (#19281)

This commit is contained in:
Yury Semikhatsky 2022-12-05 18:15:01 -08:00 committed by GitHub
parent 81c8620bfe
commit f9ef18912d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 214 additions and 115 deletions

View File

@ -32,6 +32,7 @@ export type TestGroup = {
projectId: string;
tests: TestCase[];
watchMode: boolean;
isProjectSetup: boolean;
};
type TestResultData = {
@ -567,6 +568,7 @@ class Worker extends EventEmitter {
return { testId: test.id, retry: test.results.length };
}),
watchMode: testGroup.watchMode,
projectSetup: testGroup.isProjectSetup,
};
this.send({ method: 'run', params: runPayload });
}

View File

@ -21,9 +21,9 @@ import * as playwrightLibrary from 'playwright-core';
import * as outOfProcess from 'playwright-core/lib/outofprocess';
import { createGuid, debugMode } from 'playwright-core/lib/utils';
import { removeFolders } from 'playwright-core/lib/utils/fileUtils';
import type { PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestInfo, TestType, TraceMode, VideoMode } from '../types/test';
import type { Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestInfo, TestType, TraceMode, VideoMode } from '../types/test';
import type { TestInfoImpl } from './testInfo';
import { rootTestType } from './testType';
import { rootTestType, _setProjectSetup } from './testType';
export { expect } from './expect';
export { addRunnerPlugin as _addRunnerPlugin } from './plugins';
export const _baseTest: TestType<{}, {}> = rootTestType.test;
@ -53,7 +53,7 @@ type WorkerFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions & {
_snapshotSuffix: string;
};
export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
defaultBrowserType: ['chromium', { scope: 'worker', option: true }],
browserName: [({ defaultBrowserType }, use) => use(defaultBrowserType), { scope: 'worker', option: true }],
playwright: [async ({ }, use) => {
@ -627,4 +627,8 @@ export function shouldCaptureTrace(traceMode: TraceMode, testInfo: TestInfo) {
const kTracingStarted = Symbol('kTracingStarted');
export const test = _baseTest.extend<TestFixtures, WorkerFixtures>(playwrightFixtures);
export const setup = _baseTest.extend<TestFixtures, WorkerFixtures>(playwrightFixtures);
_setProjectSetup(setup, true);
export default test;

View File

@ -96,6 +96,7 @@ export type RunPayload = {
file: string;
entries: TestEntry[];
watchMode: boolean;
projectSetup: boolean;
};
export type DonePayload = {

View File

@ -180,11 +180,12 @@ export class Loader {
}
}
async loadTestFile(file: string, environment: 'runner' | 'worker') {
async loadTestFile(file: string, environment: 'runner' | 'worker', projectSetup: boolean) {
if (cachedFileSuites.has(file))
return cachedFileSuites.get(file)!;
const suite = new Suite(path.relative(this._fullConfig.rootDir, file) || path.basename(file), 'file');
suite._requireFile = file;
suite._isProjectSetup = projectSetup;
suite.location = { file, line: 0, column: 0 };
setCurrentlyLoadingFileSuite(suite);

View File

@ -280,7 +280,7 @@ export class Runner {
const projects = this._collectProjects(options.projectFilter);
const { filesByProject, setupFiles } = await this._collectFiles(projects, options.testFileFilters);
let result = await this._createFilteredRootSuite(options, filesByProject, new Set(), !!setupFiles.size);
let result = await this._createFilteredRootSuite(options, filesByProject, new Set(), !!setupFiles.size, setupFiles);
if (setupFiles.size) {
const allTests = result.rootSuite.allTests();
const tests = allTests.filter(test => !setupFiles.has(test._requireFile));
@ -289,7 +289,7 @@ export class Runner {
// - if the filter also matches some of the setup tests, we'll run only
// that maching subset of setup tests.
if (tests.length > 0 && tests.length === allTests.length)
result = await this._createFilteredRootSuite(options, filesByProject, setupFiles, false);
result = await this._createFilteredRootSuite(options, filesByProject, setupFiles, false, setupFiles);
}
fatalErrors.push(...result.fatalErrors);
@ -307,7 +307,7 @@ export class Runner {
return { rootSuite, projectSetupGroups, testGroups };
}
private async _createFilteredRootSuite(options: RunOptions, filesByProject: Map<FullProjectInternal, string[]>, doNotFilterFiles: Set<string>, shouldCloneTests: boolean): Promise<{rootSuite: Suite, fatalErrors: TestError[]}> {
private async _createFilteredRootSuite(options: RunOptions, filesByProject: Map<FullProjectInternal, string[]>, doNotFilterFiles: Set<string>, shouldCloneTests: boolean, setupFiles: Set<string>): Promise<{rootSuite: Suite, fatalErrors: TestError[]}> {
const config = this._loader.fullConfig();
const fatalErrors: TestError[] = [];
const allTestFiles = new Set<string>();
@ -317,7 +317,7 @@ export class Runner {
// Add all tests.
const preprocessRoot = new Suite('', 'root');
for (const file of allTestFiles) {
const fileSuite = await this._loader.loadTestFile(file, 'runner');
const fileSuite = await this._loader.loadTestFile(file, 'runner', setupFiles.has(file));
if (fileSuite._loadError)
fatalErrors.push(fileSuite._loadError);
// We have to clone only if there maybe subsequent calls of this method.
@ -824,6 +824,7 @@ function createTestGroups(projectSuites: Suite[], workers: number): TestGroup[]
projectId: test._projectId,
tests: [],
watchMode: false,
isProjectSetup: test._isProjectSetup,
};
};

View File

@ -23,6 +23,7 @@ class Base {
title: string;
_only = false;
_requireFile: string = '';
_isProjectSetup: boolean = false;
constructor(title: string) {
this.title = title;
@ -120,6 +121,7 @@ export class Suite extends Base implements reporterTypes.Suite {
suite._only = this._only;
suite.location = this.location;
suite._requireFile = this._requireFile;
suite._isProjectSetup = this._isProjectSetup;
suite._use = this._use.slice();
suite._hooks = this._hooks.slice();
suite._timeout = this._timeout;
@ -191,6 +193,7 @@ export class TestCase extends Base implements reporterTypes.TestCase {
const test = new TestCase(this.title, this.fn, this._testType, this.location);
test._only = this._only;
test._requireFile = this._requireFile;
test._isProjectSetup = this._isProjectSetup;
test.expectedStatus = this.expectedStatus;
test.annotations = this.annotations.slice();
test._annotateWithInheritence = this._annotateWithInheritence;

View File

@ -26,6 +26,8 @@ const testTypeSymbol = Symbol('testType');
export class TestTypeImpl {
readonly fixtures: FixturesWithLocation[];
readonly test: TestType<any, any>;
// Wether the test is 'setup' which should only be called inside project setup files.
_projectSetup: boolean = false;
constructor(fixtures: FixturesWithLocation[]) {
this.fixtures = fixtures;
@ -77,14 +79,20 @@ export class TestTypeImpl {
` when one of the dependencies in your package.json depends on @playwright/test.`,
].join('\n'));
}
if (this._projectSetup !== suite._isProjectSetup) {
if (this._projectSetup)
throw errorWithLocation(location, `${title} is called in a file which is not a part of project setup.`);
throw errorWithLocation(location, `${title} is called in a project setup file (use 'setup' instead of 'test').`);
}
return suite;
}
private _createTest(type: 'default' | 'only' | 'skip' | 'fixme', location: Location, title: string, fn: Function) {
throwIfRunningInsideJest();
const suite = this._ensureCurrentSuite(location, 'test()');
const suite = this._ensureCurrentSuite(location, this._projectSetup ? 'setup()' : 'test()');
const test = new TestCase(title, fn, this, location);
test._requireFile = suite._requireFile;
test._isProjectSetup = suite._isProjectSetup;
suite._addTest(test);
if (type === 'only')
@ -101,7 +109,7 @@ export class TestTypeImpl {
private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only' | 'skip' | 'fixme', location: Location, title: string | Function, fn?: Function) {
throwIfRunningInsideJest();
const suite = this._ensureCurrentSuite(location, 'test.describe()');
const suite = this._ensureCurrentSuite(location, this._projectSetup ? 'setup.describe()' : 'test.describe()');
if (typeof title === 'function') {
fn = title;
@ -110,6 +118,7 @@ export class TestTypeImpl {
const child = new Suite(title, 'describe');
child._requireFile = suite._requireFile;
child._isProjectSetup = suite._isProjectSetup;
child.location = location;
suite._addSuite(child);
@ -135,13 +144,13 @@ export class TestTypeImpl {
}
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, fn: Function) {
const suite = this._ensureCurrentSuite(location, `test.${name}()`);
const suite = this._ensureCurrentSuite(location, `${this._projectSetup ? 'setup' : 'test'}.${name}()`);
suite._hooks.push({ type: name, fn, location });
}
private _configure(location: Location, options: { mode?: 'parallel' | 'serial', retries?: number, timeout?: number }) {
throwIfRunningInsideJest();
const suite = this._ensureCurrentSuite(location, `test.describe.configure()`);
const suite = this._ensureCurrentSuite(location, `${this._projectSetup ? 'setup' : 'test'}.describe.configure()`);
if (options.timeout !== undefined)
suite._timeout = options.timeout;
@ -202,14 +211,14 @@ export class TestTypeImpl {
}
private _use(location: Location, fixtures: Fixtures) {
const suite = this._ensureCurrentSuite(location, `test.use()`);
const suite = this._ensureCurrentSuite(location, `${this._projectSetup ? 'setup' : 'test'}.use()`);
suite._use.push({ fixtures, location });
}
private async _step<T>(location: Location, title: string, body: () => Promise<T>): Promise<T> {
const testInfo = currentTestInfo();
if (!testInfo)
throw errorWithLocation(location, `test.step() can only be called from a test`);
throw errorWithLocation(location, `${this._projectSetup ? 'setup' : 'test'}.step() can only be called from a test`);
const step = testInfo._addStep({
category: 'test.step',
title,
@ -254,4 +263,11 @@ function throwIfRunningInsideJest() {
}
}
export function _setProjectSetup(test: TestType<any, any>, projectSetup: boolean) {
const testTypeImpl = (test as any)[testTypeSymbol] as TestTypeImpl;
if (!testTypeImpl)
throw new Error(`Argument is not a TestType`);
testTypeImpl._projectSetup = projectSetup;
}
export const rootTestType = new TestTypeImpl([]);

View File

@ -169,7 +169,7 @@ export class WorkerRunner extends EventEmitter {
let fatalUnknownTestIds;
try {
await this._loadIfNeeded();
const fileSuite = await this._loader.loadTestFile(runPayload.file, 'worker');
const fileSuite = await this._loader.loadTestFile(runPayload.file, 'worker', runPayload.projectSetup);
const suite = this._loader.buildFileSuiteForProject(this._project, fileSuite, this._params.repeatEachIndex, test => {
if (runPayload.watchMode) {
const testResolvedPayload: WatchTestResolvedPayload = {

View File

@ -29,8 +29,8 @@ function createConfigWithProjects(names: string[], testInfo: TestInfo, projectTe
await new Promise(f => setTimeout(f, 100));
});`;
files[`${name}/${name}.setup.ts`] = `
const { test } = pwt;
test('${name} setup', async () => {
const { setup } = pwt;
setup('${name} setup', async () => {
await new Promise(f => setTimeout(f, 100));
});`;
}
@ -142,8 +142,8 @@ test('should stop project if setup fails', async ({ runGroups }, testInfo) => {
};
const configWithFiles = createConfigWithProjects(['a', 'b', 'c'], testInfo, projectTemplates);
configWithFiles[`a/a.setup.ts`] = `
const { test, expect } = pwt;
test('a setup', async () => {
const { setup, expect } = pwt;
setup('a setup', async () => {
expect(1).toBe(2);
});`;
@ -179,9 +179,9 @@ test('should run setup in each project shard', async ({ runGroups }, testInfo) =
test('test2', async () => { });
`,
'c.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
};
@ -233,14 +233,14 @@ test('should run setup only for projects that have tests in the shard', async ({
test('test2', async () => { });
`,
'p1.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'p2.setup.ts': `
const { test } = pwt;
test('setup3', async () => { });
test('setup4', async () => { });
const { setup } = pwt;
setup('setup3', async () => { });
setup('setup4', async () => { });
`,
};
@ -347,20 +347,20 @@ test('list-files should enumerate setup files in same group', async ({ runComman
]
};`,
'a1.setup.ts': `
const { test } = pwt;
test('test1', async () => { });
const { setup } = pwt;
setup('test1', async () => { });
`,
'a2.setup.ts': `
const { test } = pwt;
test('test1', async () => { });
const { setup } = pwt;
setup('test1', async () => { });
`,
'a.test.ts': `
const { test } = pwt;
test('test2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('test3', async () => { });
const { setup } = pwt;
setup('test3', async () => { });
`,
'b.test.ts': `
const { test } = pwt;
@ -394,20 +394,20 @@ test('test --list should enumerate setup tests as regular ones', async ({ runCom
]
};`,
'a1.setup.ts': `
const { test } = pwt;
test('test1', async () => { });
const { setup } = pwt;
setup('test1', async () => { });
`,
'a2.setup.ts': `
const { test } = pwt;
test('test1', async () => { });
const { setup } = pwt;
setup('test1', async () => { });
`,
'a.test.ts': `
const { test } = pwt;
test('test2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('test3', async () => { });
const { setup } = pwt;
setup('test3', async () => { });
`,
'b.test.ts': `
const { test } = pwt;
@ -445,17 +445,17 @@ test('should allow .only in setup files', async ({ runGroups }, testInfo) => {
test('test4', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test.only('setup1', async () => { });
test('setup2', async () => { });
test.only('setup3', async () => { });
const { setup } = pwt;
setup.only('setup1', async () => { });
setup('setup2', async () => { });
setup.only('setup3', async () => { });
`,
};
const { exitCode, passed, timeline, output } = await runGroups(files);
expect(output).toContain('Running 2 tests using 1 worker');
expect(output).toContain('[p1] a.setup.ts:5:12 setup1');
expect(output).toContain('[p1] a.setup.ts:7:12 setup3');
expect(output).toContain('[p1] a.setup.ts:5:13 setup1');
expect(output).toContain('[p1] a.setup.ts:7:13 setup3');
expect(fileNames(timeline)).toEqual(['a.setup.ts']);
expect(exitCode).toBe(0);
expect(passed).toBe(2);
@ -480,12 +480,12 @@ test('should allow describe.only in setup files', async ({ runGroups }, testInfo
test('test4', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test.describe.only('main', () => {
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup.describe.only('main', () => {
setup('setup1', async () => { });
setup('setup2', async () => { });
});
test('setup3', async () => { });
setup('setup3', async () => { });
`,
};
@ -517,12 +517,12 @@ test('should filter describe line in setup files', async ({ runGroups }, testInf
test('test4', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test.describe('main', () => {
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup.describe('main', () => {
setup('setup1', async () => { });
setup('setup2', async () => { });
});
test('setup3', async () => { });
setup('setup3', async () => { });
`,
};
@ -554,16 +554,16 @@ test('should allow .only in both setup and test files', async ({ runGroups }, te
test('test4', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test.only('setup1', async () => { });
test('setup2', async () => { });
test('setup3', async () => { });
const { setup } = pwt;
setup.only('setup1', async () => { });
setup('setup2', async () => { });
setup('setup3', async () => { });
`,
};
const { exitCode, output } = await runGroups(files);
expect(exitCode).toBe(0);
expect(output).toContain('[p1] a.setup.ts:5:12 setup1');
expect(output).toContain('[p1] a.setup.ts:5:13 setup1');
expect(output).toContain('[p1] a.test.ts:7:12 test2');
});
@ -586,13 +586,13 @@ test('should run full setup when there is test.only', async ({ runGroups }, test
test('test4', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup3', async () => { });
const { setup } = pwt;
setup('setup3', async () => { });
`,
};
@ -628,13 +628,13 @@ test('should allow filtering setup by file:line', async ({ runGroups }, testInfo
test('test3', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
`,
'b.test.ts': `
const { test } = pwt;
@ -680,13 +680,13 @@ test('should support filters matching both setup and test', async ({ runGroups }
test('test3', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
`,
'b.test.ts': `
const { test } = pwt;
@ -726,12 +726,12 @@ test('should run setup for a project if tests match only in another project', as
test('test1', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
`,
'b.test.ts': `
const { test } = pwt;
@ -765,13 +765,13 @@ test('should run all setup files if only tests match filter', async ({ runGroups
test('test3', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
`,
};
@ -802,13 +802,13 @@ test('should run all setup files if only tests match grep filter', async ({ runG
test('test3', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
`,
};
@ -840,14 +840,14 @@ test('should apply project.grep filter to both setup and tests', async ({ runGro
test('foo', async () => { });
`,
'a.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('setup2', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('setup2', async () => { });
`,
'b.setup.ts': `
const { test } = pwt;
test('setup1', async () => { });
test('foo', async () => { });
const { setup } = pwt;
setup('setup1', async () => { });
setup('foo', async () => { });
`,
};
@ -858,3 +858,74 @@ test('should apply project.grep filter to both setup and tests', async ({ runGro
expect(output).toContain('[p1] a.test.ts:6:7 test1');
expect(output).toContain('[p1] a.test.ts:7:7 test2');
});
test('should prohibit setup in test files', async ({ runGroups }, testInfo) => {
const files = {
'a.test.ts': `
const { setup, test } = pwt;
setup('test1', async () => { });
test('test2', async () => { });
`,
};
const { exitCode, output } = await runGroups(files);
expect(exitCode).toBe(1);
expect(output).toContain('setup() is called in a file which is not a part of project setup.');
});
test('should prohibit setup hooks in test files', async ({ runGroups }, testInfo) => {
const files = {
'a.test.ts': `
const { setup } = pwt;
setup.beforeAll(async () => { });
`,
};
const { exitCode, output } = await runGroups(files);
expect(exitCode).toBe(1);
expect(output).toContain('setup.beforeAll() is called in a file which is not a part of project setup');
});
test('should prohibit test in setup files', async ({ runGroups }, testInfo) => {
const files = {
'playwright.config.ts': `
module.exports = {
projects: [
{
name: 'p1',
setup: /.*.setup.ts/,
},
]
};`,
'a.setup.ts': `
const { test } = pwt;
test('test1', async () => { });
`,
};
const { exitCode, output } = await runGroups(files);
expect(exitCode).toBe(1);
expect(output).toContain('test() is called in a project setup file');
});
test('should prohibit test hooks in setup files', async ({ runGroups }, testInfo) => {
const files = {
'playwright.config.ts': `
module.exports = {
projects: [
{
name: 'p1',
setup: /.*.setup.ts/,
},
]
};`,
'a.setup.ts': `
const { test } = pwt;
test.beforeEach(async () => { });
`,
};
const { exitCode, output } = await runGroups(files);
expect(exitCode).toBe(1);
expect(output).toContain('test.beforeEach() is called in a project setup file');
});

View File

@ -56,9 +56,9 @@ test('should share storage state between project setup and tests', async ({ runI
};
`,
'storage.setup.ts': `
const { test, expect } = pwt;
test('should initialize storage', async ({ }) => {
const storage = test.info().storage();
const { setup, expect } = pwt;
setup('should initialize storage', async ({ }) => {
const storage = setup.info().storage();
expect(await storage.get('number')).toBe(undefined);
await storage.set('number', 2022)
expect(await storage.get('number')).toBe(2022);
@ -142,16 +142,16 @@ test('should isolate storage state between projects', async ({ runInlineTest })
};
`,
'storage.setup.ts': `
const { test, expect } = pwt;
test('should initialize storage', async ({ }) => {
const storage = test.info().storage();
const { setup, expect } = pwt;
setup('should initialize storage', async ({ }) => {
const storage = setup.info().storage();
expect(await storage.get('number')).toBe(undefined);
await storage.set('number', 2022)
expect(await storage.get('number')).toBe(2022);
expect(await storage.get('name')).toBe(undefined);
await storage.set('name', 'str-' + test.info().project.name)
expect(await storage.get('name')).toBe('str-' + test.info().project.name);
await storage.set('name', 'str-' + setup.info().project.name)
expect(await storage.get('name')).toBe('str-' + setup.info().project.name);
});
`,
'a.test.ts': `
@ -192,9 +192,9 @@ test('should load context storageState from storage', async ({ runInlineTest, se
};
`,
'storage.setup.ts': `
const { test, expect } = pwt;
test('should save storageState', async ({ page, context }) => {
const storage = test.info().storage();
const { setup, expect } = pwt;
setup('should save storageState', async ({ page, context }) => {
const storage = setup.info().storage();
expect(await storage.get('user')).toBe(undefined);
await page.goto('${server.PREFIX}/setcookie.html');
const state = await page.context().storageState();
@ -245,12 +245,12 @@ test('should load storageStateName specified in the project config from storage'
};
`,
'storage.setup.ts': `
const { test, expect } = pwt;
test.use({
const { setup, expect } = pwt;
setup.use({
storageStateName: ({}, use) => use(undefined),
})
test('should save storageState', async ({ page, context }) => {
const storage = test.info().storage();
setup('should save storageState', async ({ page, context }) => {
const storage = setup.info().storage();
expect(await storage.get('stateInStorage')).toBe(undefined);
await page.goto('${server.PREFIX}/setcookie.html');
const state = await page.context().storageState();
@ -290,12 +290,12 @@ test('should load storageStateName specified in the global config from storage',
};
`,
'storage.setup.ts': `
const { test, expect } = pwt;
test.use({
const { setup, expect } = pwt;
setup.use({
storageStateName: ({}, use) => use(undefined),
})
test('should save storageStateName', async ({ page, context }) => {
const storage = test.info().storage();
setup('should save storageStateName', async ({ page, context }) => {
const storage = setup.info().storage();
expect(await storage.get('stateInStorage')).toBe(undefined);
await page.goto('${server.PREFIX}/setcookie.html');
const state = await page.context().storageState();