This reverts commit 6fef227f43
.
Not shipping in 1.28.
This commit is contained in:
Родитель
ac25fdd74b
Коммит
194abc35cd
|
@ -1083,51 +1083,6 @@ Test function that takes one or two arguments: an object with fixtures and optio
|
|||
|
||||
|
||||
|
||||
## method: Test.reset
|
||||
* since: v1.28
|
||||
|
||||
Resets options that were set up in the configuration file or with [`method: Test.use`] to their default or config-specified value.
|
||||
|
||||
```js tab=js-js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.reset({
|
||||
// Reset storage state to the default empty value.
|
||||
storageStage: 'default',
|
||||
|
||||
// Reset locale to the value specified in the config file.
|
||||
locale: 'config',
|
||||
});
|
||||
|
||||
test('example', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js tab=js-ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.reset({
|
||||
// Reset storage state to the default empty value.
|
||||
storageStage: 'default',
|
||||
|
||||
// Reset locale to the value specified in the config file.
|
||||
locale: 'config',
|
||||
});
|
||||
|
||||
test('example', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.reset.fixtures
|
||||
* since: v1.28
|
||||
- `options` <[Object]>
|
||||
|
||||
An object with options set to either `'config'` or `'default'`.
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.setTimeout
|
||||
* since: v1.10
|
||||
|
|
|
@ -48,13 +48,8 @@ type FixtureRegistration = {
|
|||
id: string;
|
||||
// A fixture override can use the previous version of the fixture.
|
||||
super?: FixtureRegistration;
|
||||
// Whether this fixture is an option value set from the config.
|
||||
fromConfig?: boolean;
|
||||
};
|
||||
|
||||
export const kResetToConfig = Symbol('reset-to-config');
|
||||
export const kResetToDefault = Symbol('reset-to-default');
|
||||
|
||||
class Fixture {
|
||||
runner: FixtureRunner;
|
||||
registration: FixtureRegistration;
|
||||
|
@ -193,7 +188,7 @@ export class FixturePool {
|
|||
constructor(fixturesList: FixturesWithLocation[], parentPool?: FixturePool, disallowWorkerFixtures?: boolean) {
|
||||
this.registrations = new Map(parentPool ? parentPool.registrations : []);
|
||||
|
||||
for (const { fixtures, location, fromConfig } of fixturesList) {
|
||||
for (const { fixtures, location } of fixturesList) {
|
||||
for (const entry of Object.entries(fixtures)) {
|
||||
const name = entry[0];
|
||||
let value = entry[1];
|
||||
|
@ -227,30 +222,17 @@ export class FixturePool {
|
|||
if (options.scope === 'worker' && disallowWorkerFixtures)
|
||||
throw errorWithLocations(`Cannot use({ ${name} }) in a describe group, because it forces a new worker.\nMake it top-level in the test file or put in the configuration file.`, { location, name });
|
||||
|
||||
if (fn === undefined && options.option) {
|
||||
// Overriding option with "undefined" value means setting it to the config value.
|
||||
fn = kResetToConfig;
|
||||
}
|
||||
if (fn === kResetToConfig || fn === kResetToDefault) {
|
||||
// Find the target fixture to copy the reset value from.
|
||||
// It is either the original definition, or "fromConfig" one.
|
||||
//
|
||||
// Note that "reset to config" behaves like "reset to default"
|
||||
// if no value is set in the config.
|
||||
let targetFixture = previous;
|
||||
while (targetFixture && targetFixture.super) {
|
||||
if (fn === kResetToConfig && targetFixture.fromConfig)
|
||||
break;
|
||||
targetFixture = targetFixture.super;
|
||||
}
|
||||
if (targetFixture)
|
||||
fn = targetFixture.fn;
|
||||
else
|
||||
fn = undefined;
|
||||
// Overriding option with "undefined" value means setting it to the default value
|
||||
// from the original declaration of the option.
|
||||
if (fn === undefined && options.option && previous) {
|
||||
let original = previous;
|
||||
while (original.super)
|
||||
original = original.super;
|
||||
fn = original.fn;
|
||||
}
|
||||
|
||||
const deps = fixtureParameterNames(fn, location);
|
||||
const registration: FixtureRegistration = { id: '', name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, deps, super: previous, fromConfig };
|
||||
const registration: FixtureRegistration = { id: '', name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, deps, super: previous };
|
||||
registrationId(registration);
|
||||
this.registrations.set(name, registration);
|
||||
}
|
||||
|
|
|
@ -434,17 +434,18 @@ class ProjectSuiteBuilder {
|
|||
return testType.fixtures;
|
||||
const result: FixturesWithLocation[] = [];
|
||||
for (const f of testType.fixtures) {
|
||||
result.push(f);
|
||||
const optionsFromConfig: Fixtures = {};
|
||||
const originalFixtures: Fixtures = {};
|
||||
for (const [key, value] of Object.entries(f.fixtures)) {
|
||||
if (isFixtureOption(value) && configKeys.has(key))
|
||||
(optionsFromConfig as any)[key] = [(configUse as any)[key], value[1]];
|
||||
else
|
||||
(originalFixtures as any)[key] = value;
|
||||
}
|
||||
if (Object.entries(optionsFromConfig).length) {
|
||||
// Add config options immediately after original option definition,
|
||||
// so that any test.use() override it.
|
||||
result.push({ fixtures: optionsFromConfig, location: { file: `project#${this._project._id}`, line: 1, column: 1 }, fromConfig: true });
|
||||
}
|
||||
if (Object.entries(optionsFromConfig).length)
|
||||
result.push({ fixtures: optionsFromConfig, location: { file: `project#${this._project._id}`, line: 1, column: 1 } });
|
||||
if (Object.entries(originalFixtures).length)
|
||||
result.push({ fixtures: originalFixtures, location: f.location });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
import { expect } from './expect';
|
||||
import { kResetToConfig, kResetToDefault } from './fixtures';
|
||||
import { currentlyLoadingFileSuite, currentTestInfo, setCurrentlyLoadingFileSuite } from './globals';
|
||||
import { TestCase, Suite } from './test';
|
||||
import { wrapFunctionWithLocation } from './transform';
|
||||
|
@ -55,7 +54,6 @@ export class TestTypeImpl {
|
|||
test.setTimeout = wrapFunctionWithLocation(this._setTimeout.bind(this));
|
||||
test.step = wrapFunctionWithLocation(this._step.bind(this));
|
||||
test.use = wrapFunctionWithLocation(this._use.bind(this));
|
||||
test.reset = wrapFunctionWithLocation(this._reset.bind(this));
|
||||
test.extend = wrapFunctionWithLocation(this._extend.bind(this));
|
||||
test._extendTest = wrapFunctionWithLocation(this._extendTest.bind(this));
|
||||
test.info = () => {
|
||||
|
@ -208,20 +206,6 @@ export class TestTypeImpl {
|
|||
suite._use.push({ fixtures, location });
|
||||
}
|
||||
|
||||
private _reset(location: Location, resets: Fixtures) {
|
||||
const suite = this._ensureCurrentSuite(location, `test.reset()`);
|
||||
const fixtures: any = {};
|
||||
for (const [key, value] of Object.entries(resets)) {
|
||||
if (value === 'config')
|
||||
fixtures[key] = kResetToConfig;
|
||||
else if (value === 'default')
|
||||
fixtures[key] = kResetToDefault;
|
||||
else
|
||||
throw errorWithLocation(location, `test.reset() supports "config" or "default", got unexpected value "${value}"`);
|
||||
}
|
||||
suite._use.push({ fixtures, location });
|
||||
}
|
||||
|
||||
private async _step<T>(location: Location, title: string, body: () => Promise<T>): Promise<T> {
|
||||
const testInfo = currentTestInfo();
|
||||
if (!testInfo)
|
||||
|
|
|
@ -24,7 +24,6 @@ export type { Location } from '../types/testReporter';
|
|||
export type FixturesWithLocation = {
|
||||
fixtures: Fixtures;
|
||||
location: Location;
|
||||
fromConfig?: boolean;
|
||||
};
|
||||
export type Annotation = { type: string, description?: string };
|
||||
|
||||
|
|
|
@ -2612,29 +2612,6 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||
* @param options An object with local options.
|
||||
*/
|
||||
use(fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs>): void;
|
||||
/**
|
||||
* Resets options that were set up in the configuration file or with
|
||||
* [test.use(options)](https://playwright.dev/docs/api/class-test#test-use) to their default or config-specified value.
|
||||
*
|
||||
* ```js
|
||||
* import { test, expect } from '@playwright/test';
|
||||
*
|
||||
* test.reset({
|
||||
* // Reset storage state to the default empty value.
|
||||
* storageStage: 'default',
|
||||
*
|
||||
* // Reset locale to the value specified in the config file.
|
||||
* locale: 'config',
|
||||
* });
|
||||
*
|
||||
* test('example', async ({ page }) => {
|
||||
* // ...
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param options An object with options set to either `'config'` or `'default'`.
|
||||
*/
|
||||
reset(options: ResetOptions<TestArgs & WorkerArgs>): void;
|
||||
/**
|
||||
* Declares a test step.
|
||||
*
|
||||
|
@ -2759,7 +2736,6 @@ export type Fixtures<T extends KeyValue = {}, W extends KeyValue = {}, PT extend
|
|||
} & {
|
||||
[K in keyof T]?: TestFixtureValue<T[K], T & W & PT & PW> | [TestFixtureValue<T[K], T & W & PT & PW>, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined }];
|
||||
};
|
||||
type ResetOptions<T extends KeyValue> = { [K in keyof T]?: 'config' | 'default' };
|
||||
|
||||
type BrowserName = 'chromium' | 'firefox' | 'webkit';
|
||||
type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
|
||||
|
|
|
@ -246,8 +246,8 @@ test('should load storageStateName specified in the project config from storage'
|
|||
`,
|
||||
'storage.setup.ts': `
|
||||
const { test, expect } = pwt;
|
||||
test.reset({
|
||||
storageStateName: 'default'
|
||||
test.use({
|
||||
storageStateName: ({}, use) => use(undefined),
|
||||
})
|
||||
test('should save storageState', async ({ page, context }) => {
|
||||
const storage = test.info().storage();
|
||||
|
@ -291,8 +291,8 @@ test('should load storageStateName specified in the global config from storage',
|
|||
`,
|
||||
'storage.setup.ts': `
|
||||
const { test, expect } = pwt;
|
||||
test.reset({
|
||||
storageStateName: 'default'
|
||||
test.use({
|
||||
storageStateName: ({}, use) => use(undefined),
|
||||
})
|
||||
test('should save storageStateName', async ({ page, context }) => {
|
||||
const storage = test.info().storage();
|
||||
|
|
|
@ -225,3 +225,54 @@ test('test._extendTest should print nice message when used as extend', async ({
|
|||
expect(result.passed).toBe(0);
|
||||
expect(result.output).toContain('Did you mean to call test.extend() with fixtures instead?');
|
||||
});
|
||||
|
||||
test('test.use() with undefined should not be ignored', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
use: { option1: 'config' },
|
||||
};
|
||||
`,
|
||||
'a.test.js': `
|
||||
const test = pwt.test.extend({
|
||||
option1: [ 'default', { option: true } ],
|
||||
option2: [ 'default', { option: true } ],
|
||||
});
|
||||
test('test1', async ({ option1, option2 }) => {
|
||||
console.log('test1: option1=' + option1);
|
||||
console.log('test1: option2=' + option2);
|
||||
});
|
||||
|
||||
test.describe('', () => {
|
||||
test.use({ option1: 'foo', option2: 'foo' });
|
||||
test('test2', async ({ option1, option2 }) => {
|
||||
console.log('test2: option1=' + option1);
|
||||
console.log('test2: option2=' + option2);
|
||||
});
|
||||
|
||||
test.describe('', () => {
|
||||
test.use({ option1: undefined, option2: undefined });
|
||||
test('test3', async ({ option1, option2 }) => {
|
||||
console.log('test3: option1=' + option1);
|
||||
console.log('test3: option2=' + option2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.extend({ option1: undefined, option2: undefined })('test4', async ({ option1, option2 }) => {
|
||||
console.log('test4: option1=' + option1);
|
||||
console.log('test4: option2=' + option2);
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(4);
|
||||
expect(result.output).toContain('test1: option1=config');
|
||||
expect(result.output).toContain('test1: option2=default');
|
||||
expect(result.output).toContain('test2: option1=foo');
|
||||
expect(result.output).toContain('test2: option2=foo');
|
||||
expect(result.output).toContain('test3: option1=config');
|
||||
expect(result.output).toContain('test3: option2=default');
|
||||
expect(result.output).toContain('test4: option1=config');
|
||||
expect(result.output).toContain('test4: option2=default');
|
||||
});
|
||||
|
|
|
@ -179,109 +179,3 @@ test('test.use() should throw if called from beforeAll ', async ({ runInlineTest
|
|||
expect(result.output).toContain('Playwright Test did not expect test.use() to be called here');
|
||||
});
|
||||
|
||||
test('test.use() with undefined should not be ignored', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
use: { option1: 'config' },
|
||||
};
|
||||
`,
|
||||
'a.test.js': `
|
||||
const test = pwt.test.extend({
|
||||
option1: [ 'default', { option: true } ],
|
||||
option2: [ 'default', { option: true } ],
|
||||
});
|
||||
test('test1', async ({ option1, option2 }) => {
|
||||
console.log('test1: option1=' + option1);
|
||||
console.log('test1: option2=' + option2);
|
||||
});
|
||||
|
||||
test.describe('', () => {
|
||||
test.use({ option1: 'foo', option2: 'foo' });
|
||||
test('test2', async ({ option1, option2 }) => {
|
||||
console.log('test2: option1=' + option1);
|
||||
console.log('test2: option2=' + option2);
|
||||
});
|
||||
|
||||
test.describe('', () => {
|
||||
test.use({ option1: undefined, option2: undefined });
|
||||
test('test3', async ({ option1, option2 }) => {
|
||||
console.log('test3: option1=' + option1);
|
||||
console.log('test3: option2=' + option2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.extend({ option1: undefined, option2: undefined })('test4', async ({ option1, option2 }) => {
|
||||
console.log('test4: option1=' + option1);
|
||||
console.log('test4: option2=' + option2);
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(4);
|
||||
expect(result.output).toContain('test1: option1=config');
|
||||
expect(result.output).toContain('test1: option2=default');
|
||||
expect(result.output).toContain('test2: option1=foo');
|
||||
expect(result.output).toContain('test2: option2=foo');
|
||||
expect(result.output).toContain('test3: option1=config');
|
||||
expect(result.output).toContain('test3: option2=default');
|
||||
expect(result.output).toContain('test4: option1=config');
|
||||
expect(result.output).toContain('test4: option2=default');
|
||||
});
|
||||
|
||||
test('test.reset() should reset to default or config', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
use: { option1: 'config-value' },
|
||||
};
|
||||
`,
|
||||
'a.test.js': `
|
||||
const test = pwt.test.extend({
|
||||
option1: [ 'default-value', { option: true } ],
|
||||
option2: [ 'default-value', { option: true } ],
|
||||
});
|
||||
|
||||
test.use({ option1: 'use-value', option2: 'use-value' });
|
||||
test('test1', async ({ option1, option2 }) => {
|
||||
console.log('test1: option1=' + option1);
|
||||
console.log('test1: option2=' + option2);
|
||||
});
|
||||
|
||||
test.describe(() => {
|
||||
test.reset({ option1: 'default', option2: 'default' });
|
||||
test('test2', async ({ option1, option2 }) => {
|
||||
console.log('test2: option1=' + option1);
|
||||
console.log('test2: option2=' + option2);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(() => {
|
||||
test.reset({ option1: 'config', option2: 'config' });
|
||||
test('test3', async ({ option1, option2 }) => {
|
||||
console.log('test3: option1=' + option1);
|
||||
console.log('test3: option2=' + option2);
|
||||
});
|
||||
});
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(3);
|
||||
expect(result.output).toContain('test1: option1=use-value');
|
||||
expect(result.output).toContain('test1: option2=use-value');
|
||||
expect(result.output).toContain('test2: option1=default-value');
|
||||
expect(result.output).toContain('test2: option2=default-value');
|
||||
expect(result.output).toContain('test3: option1=config-value');
|
||||
expect(result.output).toContain('test3: option2=default-value');
|
||||
});
|
||||
|
||||
test('test.reset() throws for unsupported value', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
pwt.test.reset({ option: 'foo' });
|
||||
`,
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.output).toContain('test.reset() supports "config" or "default", got unexpected value "foo"');
|
||||
});
|
||||
|
|
|
@ -136,13 +136,6 @@ test('should check types of fixtures', async ({ runTSC }) => {
|
|||
// @ts-expect-error
|
||||
test.use({ baz: 'baz' });
|
||||
|
||||
test.reset({ foo: 'default' });
|
||||
test.reset({ foo: 'config' });
|
||||
// @ts-expect-error
|
||||
test.reset({ unknown: 'config' });
|
||||
// @ts-expect-error
|
||||
test.reset({ foo: 'unknown' });
|
||||
|
||||
test('my test', async ({ foo, bar }) => {
|
||||
bar += parseInt(foo);
|
||||
});
|
||||
|
|
|
@ -151,7 +151,6 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
|||
beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||
afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
|
||||
use(fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs>): void;
|
||||
reset(options: ResetOptions<TestArgs & WorkerArgs>): void;
|
||||
step<T>(title: string, body: () => Promise<T>): Promise<T>;
|
||||
expect: Expect;
|
||||
extend<T extends KeyValue, W extends KeyValue = {}>(fixtures: Fixtures<T, W, TestArgs, WorkerArgs>): TestType<TestArgs & T, WorkerArgs & W>;
|
||||
|
@ -172,7 +171,6 @@ export type Fixtures<T extends KeyValue = {}, W extends KeyValue = {}, PT extend
|
|||
} & {
|
||||
[K in keyof T]?: TestFixtureValue<T[K], T & W & PT & PW> | [TestFixtureValue<T[K], T & W & PT & PW>, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined }];
|
||||
};
|
||||
type ResetOptions<T extends KeyValue> = { [K in keyof T]?: 'config' | 'default' };
|
||||
|
||||
type BrowserName = 'chromium' | 'firefox' | 'webkit';
|
||||
type BrowserChannel = Exclude<LaunchOptions['channel'], undefined>;
|
||||
|
|
Загрузка…
Ссылка в новой задаче