feat(test runner): remove createContext fixture (#8109)
We can now use `browser.newContext()` or `browser.newPage()` instead.
This commit is contained in:
parent
75981bc0aa
commit
2744cd6c9a
|
|
@ -137,66 +137,6 @@ Learn how to [configure context](./test-configuration.md) through other fixtures
|
||||||
|
|
||||||
The [`property: Fixtures.page`] belongs to this context.
|
The [`property: Fixtures.page`] belongs to this context.
|
||||||
|
|
||||||
## property: Fixtures.createContext
|
|
||||||
- type: <[function]\([BrowserContextOptions]|[void]\):[BrowserContext]>
|
|
||||||
|
|
||||||
A function that creates a new context, taking into account all options set
|
|
||||||
through [configuration file](./test-configuration.md) or [`method: Test.use`] calls. All contexts created by this function are similar to the default [`property: Fixtures.context`].
|
|
||||||
|
|
||||||
This function is useful for multi-context scenarios, for example testing
|
|
||||||
two users talking over the chat application.
|
|
||||||
|
|
||||||
A single `options` argument will be merged with all the default options from [configuration file](./test-configuration.md) or [`method: Test.use`] calls and passed to [`method: Browser.newContext`]. If you'd like to undo some of these options, override them with some value or `undefined`. For example:
|
|
||||||
|
|
||||||
```js js-flavor=ts
|
|
||||||
// example.spec.ts
|
|
||||||
|
|
||||||
import { test } from '@playwright/test';
|
|
||||||
|
|
||||||
// All contexts will use this storage state.
|
|
||||||
test.use({ storageState: 'state.json' });
|
|
||||||
|
|
||||||
test('my test', async ({ createContext }) => {
|
|
||||||
// An isolated context
|
|
||||||
const context1 = await createContext();
|
|
||||||
|
|
||||||
// Another isolated context with custom options
|
|
||||||
const context2 = await createContext({
|
|
||||||
// Undo 'state.json' from above
|
|
||||||
storageState: undefined,
|
|
||||||
// Set custom locale
|
|
||||||
locale: 'en-US',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
```js js-flavor=js
|
|
||||||
// example.spec.js
|
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
const { test } = require('@playwright/test');
|
|
||||||
|
|
||||||
// All contexts will use this storage state.
|
|
||||||
test.use({ storageState: 'state.json' });
|
|
||||||
|
|
||||||
test('my test', async ({ createContext }) => {
|
|
||||||
// An isolated context
|
|
||||||
const context1 = await createContext();
|
|
||||||
|
|
||||||
// Another isolated context with custom options
|
|
||||||
const context2 = await createContext({
|
|
||||||
// Undo 'state.json' from above
|
|
||||||
storageState: undefined,
|
|
||||||
// Set custom locale
|
|
||||||
locale: 'en-US',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## property: Fixtures.contextOptions
|
## property: Fixtures.contextOptions
|
||||||
- type: <[Object]>
|
- type: <[Object]>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -284,36 +284,31 @@ export const test = _baseTest.extend<TestFixtures, WorkerAndFileFixtures>({
|
||||||
}));
|
}));
|
||||||
}, { auto: true }],
|
}, { auto: true }],
|
||||||
|
|
||||||
createContext: async ({ browser, video, _artifactsDir }, use, testInfo) => {
|
context: async ({ browser, video, _artifactsDir }, use, testInfo) => {
|
||||||
|
if (testInfo.title === 'beforeAll' || testInfo.title === 'afterAll')
|
||||||
|
throw new Error(`"context" and "page" fixtures are not suppoted in ${testInfo.title}. Use browser.newContext() instead.`);
|
||||||
|
|
||||||
let videoMode = typeof video === 'string' ? video : video.mode;
|
let videoMode = typeof video === 'string' ? video : video.mode;
|
||||||
if (videoMode === 'retry-with-video')
|
if (videoMode === 'retry-with-video')
|
||||||
videoMode = 'on-first-retry';
|
videoMode = 'on-first-retry';
|
||||||
|
|
||||||
const captureVideo = (videoMode === 'on' || videoMode === 'retain-on-failure' || (videoMode === 'on-first-retry' && testInfo.retry === 1));
|
const captureVideo = (videoMode === 'on' || videoMode === 'retain-on-failure' || (videoMode === 'on-first-retry' && testInfo.retry === 1));
|
||||||
|
const videoOptions: BrowserContextOptions = captureVideo ? {
|
||||||
|
recordVideo: {
|
||||||
|
dir: _artifactsDir(),
|
||||||
|
size: typeof video === 'string' ? undefined : video.size,
|
||||||
|
}
|
||||||
|
} : {};
|
||||||
|
const context = await browser.newContext(videoOptions);
|
||||||
|
|
||||||
const allContexts: BrowserContext[] = [];
|
|
||||||
const allPages: Page[] = [];
|
const allPages: Page[] = [];
|
||||||
|
context.on('page', page => allPages.push(page));
|
||||||
|
|
||||||
await use(async (additionalOptions = {}) => {
|
await use(context);
|
||||||
let recordVideoDir: string | null = null;
|
|
||||||
const recordVideoSize = typeof video === 'string' ? undefined : video.size;
|
|
||||||
if (captureVideo)
|
|
||||||
recordVideoDir = _artifactsDir();
|
|
||||||
|
|
||||||
const combinedOptions: BrowserContextOptions = {
|
const prependToError = testInfo.status === 'timedOut' ?
|
||||||
recordVideo: recordVideoDir ? { dir: recordVideoDir, size: recordVideoSize } : undefined,
|
formatPendingCalls((context as any)._connection.pendingProtocolCalls()) : '';
|
||||||
...additionalOptions,
|
await context.close();
|
||||||
};
|
|
||||||
const context = await browser.newContext(combinedOptions);
|
|
||||||
context.on('page', page => allPages.push(page));
|
|
||||||
|
|
||||||
allContexts.push(context);
|
|
||||||
return context;
|
|
||||||
});
|
|
||||||
|
|
||||||
const prependToError = (testInfo.status === 'timedOut' && allContexts.length) ?
|
|
||||||
formatPendingCalls((allContexts[0] as any)._connection.pendingProtocolCalls()) : '';
|
|
||||||
await Promise.all(allContexts.map(context => context.close()));
|
|
||||||
if (prependToError) {
|
if (prependToError) {
|
||||||
if (!testInfo.error) {
|
if (!testInfo.error) {
|
||||||
testInfo.error = { value: prependToError };
|
testInfo.error = { value: prependToError };
|
||||||
|
|
@ -343,12 +338,6 @@ export const test = _baseTest.extend<TestFixtures, WorkerAndFileFixtures>({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
context: async ({ createContext }, use, testInfo) => {
|
|
||||||
if (testInfo.title === 'beforeAll' || testInfo.title === 'afterAll')
|
|
||||||
throw new Error(`"context" and "page" fixtures are not suppoted in ${testInfo.title}. Use browser.newContext() instead.`);
|
|
||||||
await use(await createContext());
|
|
||||||
},
|
|
||||||
|
|
||||||
page: async ({ context }, use) => {
|
page: async ({ context }, use) => {
|
||||||
await use(await context.newPage());
|
await use(await context.newPage());
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,12 @@ const testFiles = {
|
||||||
await page.setContent('I am the page');
|
await page.setContent('I am the page');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('two contexts', async ({ page, createContext }) => {
|
test('two contexts', async ({ page, browser }) => {
|
||||||
await page.setContent('I am the page');
|
await page.setContent('I am the page');
|
||||||
|
|
||||||
const context2 = await createContext();
|
const page2 = await browser.newPage();
|
||||||
const page2 = await context2.newPage();
|
|
||||||
await page2.setContent('I am the page');
|
await page2.setContent('I am the page');
|
||||||
|
await page2.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('failing', async ({ page }) => {
|
test('failing', async ({ page }) => {
|
||||||
|
|
@ -76,14 +76,13 @@ const testFiles = {
|
||||||
expect(1).toBe(2);
|
expect(1).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('two contexts failing', async ({ page, createContext }) => {
|
test('two contexts failing', async ({ page, browser }) => {
|
||||||
await page.setContent('I am the page');
|
await page.setContent('I am the page');
|
||||||
|
|
||||||
const context2 = await createContext();
|
const page2 = await browser.newPage();
|
||||||
const page2 = await context2.newPage();
|
|
||||||
await page2.setContent('I am the page');
|
await page2.setContent('I am the page');
|
||||||
|
|
||||||
expect(1).toBe(2);
|
expect(1).toBe(2);
|
||||||
|
await page2.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('own context passing', async ({ browser }) => {
|
test('own context passing', async ({ browser }) => {
|
||||||
|
|
|
||||||
64
types/test.d.ts
vendored
64
types/test.d.ts
vendored
|
|
@ -2720,70 +2720,6 @@ export interface PlaywrightWorkerArgs {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export interface PlaywrightTestArgs {
|
export interface PlaywrightTestArgs {
|
||||||
/**
|
|
||||||
* A function that creates a new context, taking into account all options set through
|
|
||||||
* [configuration file](https://playwright.dev/docs/test-configuration) or
|
|
||||||
* [test.use(fixtures)](https://playwright.dev/docs/api/class-test#test-use) calls. All contexts created by this function
|
|
||||||
* are similar to the default [fixtures.context](https://playwright.dev/docs/api/class-fixtures#fixtures-context).
|
|
||||||
*
|
|
||||||
* This function is useful for multi-context scenarios, for example testing two users talking over the chat application.
|
|
||||||
*
|
|
||||||
* A single `options` argument will be merged with all the default options from
|
|
||||||
* [configuration file](https://playwright.dev/docs/test-configuration) or
|
|
||||||
* [test.use(fixtures)](https://playwright.dev/docs/api/class-test#test-use) calls and passed to
|
|
||||||
* [browser.newContext([options])](https://playwright.dev/docs/api/class-browser#browser-new-context). If you'd like to
|
|
||||||
* undo some of these options, override them with some value or `undefined`. For example:
|
|
||||||
*
|
|
||||||
* ```js js-flavor=ts
|
|
||||||
* // example.spec.ts
|
|
||||||
*
|
|
||||||
* import { test } from '@playwright/test';
|
|
||||||
*
|
|
||||||
* // All contexts will use this storage state.
|
|
||||||
* test.use({ storageState: 'state.json' });
|
|
||||||
*
|
|
||||||
* test('my test', async ({ createContext }) => {
|
|
||||||
* // An isolated context
|
|
||||||
* const context1 = await createContext();
|
|
||||||
*
|
|
||||||
* // Another isolated context with custom options
|
|
||||||
* const context2 = await createContext({
|
|
||||||
* // Undo 'state.json' from above
|
|
||||||
* storageState: undefined,
|
|
||||||
* // Set custom locale
|
|
||||||
* locale: 'en-US',
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* // ...
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* ```js js-flavor=js
|
|
||||||
* // example.spec.js
|
|
||||||
* // @ts-check
|
|
||||||
*
|
|
||||||
* const { test } = require('@playwright/test');
|
|
||||||
*
|
|
||||||
* // All contexts will use this storage state.
|
|
||||||
* test.use({ storageState: 'state.json' });
|
|
||||||
*
|
|
||||||
* test('my test', async ({ createContext }) => {
|
|
||||||
* // An isolated context
|
|
||||||
* const context1 = await createContext();
|
|
||||||
*
|
|
||||||
* // Another isolated context with custom options
|
|
||||||
* const context2 = await createContext({
|
|
||||||
* // Undo 'state.json' from above
|
|
||||||
* storageState: undefined,
|
|
||||||
* // Set custom locale
|
|
||||||
* locale: 'en-US',
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* // ...
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
createContext: (options?: BrowserContextOptions) => Promise<BrowserContext>;
|
createContext: (options?: BrowserContextOptions) => Promise<BrowserContext>;
|
||||||
/**
|
/**
|
||||||
* Isolated [BrowserContext] instance, created for each test. Since contexts are isolated between each other, every test
|
* Isolated [BrowserContext] instance, created for each test. Since contexts are isolated between each other, every test
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue