mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(test): make use in config accept option values only (#8828)
Also include default options in FullConfig/FullProject. Also make examples compile and add a test.
This commit is contained in:
parent
ed34a67d4a
commit
d9d2d809a2
@ -193,11 +193,11 @@ async function globalSetup(config: FullConfig) {
|
|||||||
const { baseURL, storageState } = config.projects[0].use;
|
const { baseURL, storageState } = config.projects[0].use;
|
||||||
const browser = await chromium.launch();
|
const browser = await chromium.launch();
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.goto(baseURL);
|
await page.goto(baseURL!);
|
||||||
await page.fill('input[name="user"]', 'user');
|
await page.fill('input[name="user"]', 'user');
|
||||||
await page.fill('input[name="password"]', 'password');
|
await page.fill('input[name="password"]', 'password');
|
||||||
await page.click('text=Sign in');
|
await page.click('text=Sign in');
|
||||||
await page.context().storageState({ path: storageState });
|
await page.context().storageState({ path: storageState as string });
|
||||||
await browser.close();
|
await browser.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -301,11 +301,11 @@ async function globalSetup(config: FullConfig) {
|
|||||||
const { baseURL, storageState } = config.projects[0].use;
|
const { baseURL, storageState } = config.projects[0].use;
|
||||||
const browser = await chromium.launch();
|
const browser = await chromium.launch();
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.goto(baseURL);
|
await page.goto(baseURL!);
|
||||||
await page.fill('input[name="user"]', 'user');
|
await page.fill('input[name="user"]', 'user');
|
||||||
await page.fill('input[name="password"]', 'password');
|
await page.fill('input[name="password"]', 'password');
|
||||||
await page.click('text=Sign in');
|
await page.click('text=Sign in');
|
||||||
await page.context().storageState({ path: storageState });
|
await page.context().storageState({ path: storageState as string });
|
||||||
await browser.close();
|
await browser.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Locator, Page } from '../../..';
|
import { Locator, Page } from '../../..';
|
||||||
import { PlaywrightTestOptions} from '../../../types/test';
|
|
||||||
import { constructURLBasedOnBaseURL } from '../../utils/utils';
|
import { constructURLBasedOnBaseURL } from '../../utils/utils';
|
||||||
import { currentTestInfo } from '../globals';
|
import { currentTestInfo } from '../globals';
|
||||||
import type { Expect } from '../types';
|
import type { Expect } from '../types';
|
||||||
@ -240,7 +239,7 @@ export function toHaveURL(
|
|||||||
const testInfo = currentTestInfo();
|
const testInfo = currentTestInfo();
|
||||||
if (!testInfo)
|
if (!testInfo)
|
||||||
throw new Error(`toHaveURL must be called during the test`);
|
throw new Error(`toHaveURL must be called during the test`);
|
||||||
const baseURL = (testInfo.project.use as PlaywrightTestOptions)?.baseURL;
|
const baseURL = testInfo.project.use.baseURL;
|
||||||
|
|
||||||
return toMatchText.call(this, 'toHaveURL', page, 'Page', async () => {
|
return toMatchText.call(this, 'toHaveURL', page, 'Page', async () => {
|
||||||
return page.url();
|
return page.url();
|
||||||
|
|||||||
2
tests/playwright-test/entry/index.d.ts
vendored
2
tests/playwright-test/entry/index.d.ts
vendored
@ -15,3 +15,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export * from '../../../types/test';
|
export * from '../../../types/test';
|
||||||
|
export * from '../../../types/types';
|
||||||
|
export { default } from '../../../types/test';
|
||||||
|
|||||||
@ -238,45 +238,54 @@ test('globalSetup should allow requiring a package from node_modules', async ({
|
|||||||
expect(results[0].status).toBe('passed');
|
expect(results[0].status).toBe('passed');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('globalSetup should work for auth', async ({ runInlineTest }) => {
|
const authFiles = {
|
||||||
const result = await runInlineTest({
|
'playwright.config.ts': `
|
||||||
'playwright.config.ts': `
|
const config: pwt.PlaywrightTestConfig = {
|
||||||
module.exports = {
|
globalSetup: require.resolve('./auth'),
|
||||||
globalSetup: require.resolve('./auth.js'),
|
use: {
|
||||||
use: {
|
baseURL: 'https://www.example.com',
|
||||||
baseURL: 'https://www.example.com',
|
storageState: 'state.json',
|
||||||
storageState: 'state.json',
|
},
|
||||||
},
|
};
|
||||||
};
|
export default config;
|
||||||
`,
|
`,
|
||||||
'auth.js': `
|
'auth.ts': `
|
||||||
module.exports = async config => {
|
async function globalSetup(config: pwt.FullConfig) {
|
||||||
const { baseURL, storageState } = config.projects[0].use;
|
const { baseURL, storageState } = config.projects[0].use;
|
||||||
const browser = await pwt.chromium.launch();
|
const browser = await pwt.chromium.launch();
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.route('**/*', route => {
|
await page.route('**/*', route => {
|
||||||
route.fulfill({ body: '<html></html>' }).catch(() => {});
|
route.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||||
});
|
|
||||||
await page.goto(baseURL);
|
|
||||||
await page.evaluate(() => {
|
|
||||||
localStorage['name'] = 'value';
|
|
||||||
});
|
|
||||||
await page.context().storageState({ path: storageState });
|
|
||||||
await browser.close();
|
|
||||||
};
|
|
||||||
`,
|
|
||||||
'a.test.js': `
|
|
||||||
const { test } = pwt;
|
|
||||||
test('should have storage state', async ({ page }) => {
|
|
||||||
await page.route('**/*', route => {
|
|
||||||
route.fulfill({ body: '<html></html>' }).catch(() => {});
|
|
||||||
});
|
|
||||||
await page.goto('/');
|
|
||||||
const value = await page.evaluate(() => localStorage['name']);
|
|
||||||
expect(value).toBe('value');
|
|
||||||
});
|
});
|
||||||
`,
|
await page.goto(baseURL!);
|
||||||
});
|
await page.evaluate(() => {
|
||||||
|
localStorage['name'] = 'value';
|
||||||
|
});
|
||||||
|
await page.context().storageState({ path: storageState as string });
|
||||||
|
await browser.close();
|
||||||
|
};
|
||||||
|
export default globalSetup;
|
||||||
|
`,
|
||||||
|
'a.test.ts': `
|
||||||
|
const { test } = pwt;
|
||||||
|
test('should have storage state', async ({ page }) => {
|
||||||
|
await page.route('**/*', route => {
|
||||||
|
route.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||||
|
});
|
||||||
|
await page.goto('/');
|
||||||
|
const value = await page.evaluate(() => localStorage['name']);
|
||||||
|
expect(value).toBe('value');
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
test('globalSetup should work for auth', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest(authFiles);
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
expect(result.passed).toBe(1);
|
expect(result.passed).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('globalSetup auth should compile', async ({runTSC}) => {
|
||||||
|
const result = await runTSC(authFiles);
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
});
|
||||||
|
|||||||
11
types/test.d.ts
vendored
11
types/test.d.ts
vendored
@ -35,6 +35,7 @@ export type PreserveOutput = 'always' | 'never' | 'failures-only';
|
|||||||
export type UpdateSnapshots = 'all' | 'none' | 'missing';
|
export type UpdateSnapshots = 'all' | 'none' | 'missing';
|
||||||
|
|
||||||
type FixtureDefine<TestArgs extends KeyValue = {}, WorkerArgs extends KeyValue = {}> = { test: TestType<TestArgs, WorkerArgs>, fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs> };
|
type FixtureDefine<TestArgs extends KeyValue = {}, WorkerArgs extends KeyValue = {}> = { test: TestType<TestArgs, WorkerArgs>, fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs> };
|
||||||
|
type UseOptions<TestArgs, WorkerArgs> = { [K in keyof WorkerArgs]?: WorkerArgs[K] } & { [K in keyof TestArgs]?: TestArgs[K] };
|
||||||
|
|
||||||
type ExpectSettings = {
|
type ExpectSettings = {
|
||||||
// Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
// Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||||
@ -305,10 +306,10 @@ export interface Project<TestArgs = {}, WorkerArgs = {}> extends TestProject {
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
use?: Fixtures<{}, {}, TestArgs, WorkerArgs>;
|
use?: UseOptions<TestArgs, WorkerArgs>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FullProject<TestArgs = {}, WorkerArgs = {}> = Required<Project<TestArgs, WorkerArgs>>;
|
export type FullProject<TestArgs = {}, WorkerArgs = {}> = Required<Project<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>>;
|
||||||
|
|
||||||
export type WebServerConfig = {
|
export type WebServerConfig = {
|
||||||
/**
|
/**
|
||||||
@ -611,7 +612,7 @@ export interface Config<TestArgs = {}, WorkerArgs = {}> extends TestConfig {
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
use?: Fixtures<{}, {}, TestArgs, WorkerArgs>;
|
use?: UseOptions<TestArgs, WorkerArgs>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -636,7 +637,7 @@ export interface Config<TestArgs = {}, WorkerArgs = {}> extends TestConfig {
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export interface FullConfig {
|
export interface FullConfig<TestArgs = {}, WorkerArgs = {}> {
|
||||||
/**
|
/**
|
||||||
* Whether to exit with an error if any tests or groups are marked as
|
* Whether to exit with an error if any tests or groups are marked as
|
||||||
* [test.only(title, testFunction)](https://playwright.dev/docs/api/class-test#test-only) or
|
* [test.only(title, testFunction)](https://playwright.dev/docs/api/class-test#test-only) or
|
||||||
@ -706,7 +707,7 @@ export interface FullConfig {
|
|||||||
/**
|
/**
|
||||||
* Playwright Test supports running multiple test projects at the same time. See [TestProject] for more information.
|
* Playwright Test supports running multiple test projects at the same time. See [TestProject] for more information.
|
||||||
*/
|
*/
|
||||||
projects: FullProject[];
|
projects: FullProject<TestArgs, WorkerArgs>[];
|
||||||
/**
|
/**
|
||||||
* The list of reporters to use. Each reporter can be:
|
* The list of reporters to use. Each reporter can be:
|
||||||
* - A builtin reporter name like `'list'` or `'json'`.
|
* - A builtin reporter name like `'list'` or `'json'`.
|
||||||
|
|||||||
11
utils/generate_types/overrides-test.d.ts
vendored
11
utils/generate_types/overrides-test.d.ts
vendored
@ -34,6 +34,7 @@ export type PreserveOutput = 'always' | 'never' | 'failures-only';
|
|||||||
export type UpdateSnapshots = 'all' | 'none' | 'missing';
|
export type UpdateSnapshots = 'all' | 'none' | 'missing';
|
||||||
|
|
||||||
type FixtureDefine<TestArgs extends KeyValue = {}, WorkerArgs extends KeyValue = {}> = { test: TestType<TestArgs, WorkerArgs>, fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs> };
|
type FixtureDefine<TestArgs extends KeyValue = {}, WorkerArgs extends KeyValue = {}> = { test: TestType<TestArgs, WorkerArgs>, fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs> };
|
||||||
|
type UseOptions<TestArgs, WorkerArgs> = { [K in keyof WorkerArgs]?: WorkerArgs[K] } & { [K in keyof TestArgs]?: TestArgs[K] };
|
||||||
|
|
||||||
type ExpectSettings = {
|
type ExpectSettings = {
|
||||||
// Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
// Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||||
@ -59,10 +60,10 @@ interface TestProject {
|
|||||||
|
|
||||||
export interface Project<TestArgs = {}, WorkerArgs = {}> extends TestProject {
|
export interface Project<TestArgs = {}, WorkerArgs = {}> extends TestProject {
|
||||||
define?: FixtureDefine | FixtureDefine[];
|
define?: FixtureDefine | FixtureDefine[];
|
||||||
use?: Fixtures<{}, {}, TestArgs, WorkerArgs>;
|
use?: UseOptions<TestArgs, WorkerArgs>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FullProject<TestArgs = {}, WorkerArgs = {}> = Required<Project<TestArgs, WorkerArgs>>;
|
export type FullProject<TestArgs = {}, WorkerArgs = {}> = Required<Project<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>>;
|
||||||
|
|
||||||
export type WebServerConfig = {
|
export type WebServerConfig = {
|
||||||
/**
|
/**
|
||||||
@ -129,10 +130,10 @@ interface TestConfig {
|
|||||||
export interface Config<TestArgs = {}, WorkerArgs = {}> extends TestConfig {
|
export interface Config<TestArgs = {}, WorkerArgs = {}> extends TestConfig {
|
||||||
projects?: Project<TestArgs, WorkerArgs>[];
|
projects?: Project<TestArgs, WorkerArgs>[];
|
||||||
define?: FixtureDefine | FixtureDefine[];
|
define?: FixtureDefine | FixtureDefine[];
|
||||||
use?: Fixtures<{}, {}, TestArgs, WorkerArgs>;
|
use?: UseOptions<TestArgs, WorkerArgs>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FullConfig {
|
export interface FullConfig<TestArgs = {}, WorkerArgs = {}> {
|
||||||
forbidOnly: boolean;
|
forbidOnly: boolean;
|
||||||
globalSetup: string | null;
|
globalSetup: string | null;
|
||||||
globalTeardown: string | null;
|
globalTeardown: string | null;
|
||||||
@ -141,7 +142,7 @@ export interface FullConfig {
|
|||||||
grepInvert: RegExp | RegExp[] | null;
|
grepInvert: RegExp | RegExp[] | null;
|
||||||
maxFailures: number;
|
maxFailures: number;
|
||||||
preserveOutput: PreserveOutput;
|
preserveOutput: PreserveOutput;
|
||||||
projects: FullProject[];
|
projects: FullProject<TestArgs, WorkerArgs>[];
|
||||||
reporter: ReporterDescription[];
|
reporter: ReporterDescription[];
|
||||||
reportSlowTests: ReportSlowTests;
|
reportSlowTests: ReportSlowTests;
|
||||||
rootDir: string;
|
rootDir: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user