diff --git a/docs/src/test-global-setup-teardown-js.md b/docs/src/test-global-setup-teardown-js.md new file mode 100644 index 0000000000..81cf0ee603 --- /dev/null +++ b/docs/src/test-global-setup-teardown-js.md @@ -0,0 +1,136 @@ +--- +id: test-global-setup-teardown +title: "Global setup and teardown" +--- + +To set something up once before running all tests, use `globalSetup` option in the [configuration file](#configuration-object). The global setup file must export a single function that takes a config object. This function will be run once before all the tests. + +Similarly, use `globalTeardown` to run something once after all the tests. Alternatively, let `globalSetup` return a function that will be used as a global teardown. You can pass data such as port number, authentication tokens, etc. from your global setup to your tests using environment variables. + +```js +// playwright.config.ts/js +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + use: { + globalSetup: require.resolve('./global-setup'), + globalTeardown: require.resolve('./global-teardown'), + }, +}); +``` + +## Example + +Here is a global setup example that authenticates once and reuses authentication state in tests. It uses the `baseURL` and `storageState` options from the configuration file. + +```js +// global-setup.ts/js +import { chromium, FullConfig } from '@playwright/test'; + +async function globalSetup(config: FullConfig) { + const { baseURL, storageState } = config.projects[0].use; + const browser = await chromium.launch(); + const page = await browser.newPage(); + await page.goto(baseURL!); + await page.getByLabel('User Name').fill('user'); + await page.getByLabel('Password').fill('password'); + await page.getByText('Sign in').click(); + await page.context().storageState({ path: storageState as string }); + await browser.close(); +} + +export default globalSetup; +``` + +Specify `globalSetup`, `baseURL` and `storageState` in the configuration file. + +```js +// playwright.config.ts/js +import { defineConfig } from '@playwright/test'; +export default defineConfig({ + globalSetup: require.resolve('./global-setup'), + use: { + baseURL: 'http://localhost:3000/', + storageState: 'state.json', + }, +}); +``` + +Tests start already authenticated because we specify `storageState` that was populated by global setup. + +```js +import { test } from '@playwright/test'; + +test('test', async ({ page }) => { + await page.goto('/'); + // You are signed in! +}); +``` + +You can make arbitrary data available in your tests from your global setup file by setting them as environment variables via `process.env`. + +```js +// global-setup.ts/js +import { FullConfig } from '@playwright/test'; + +async function globalSetup(config: FullConfig) { + process.env.FOO = 'some data'; + // Or a more complicated data structure as JSON: + process.env.BAR = JSON.stringify({ some: 'data' }); +} + +export default globalSetup; +``` + +Tests have access to the `process.env` properties set in the global setup. + +```js +const { test } = require('@playwright/test'); + +test('test', async ({ page }) => { + // environment variables which are set in globalSetup are only available inside test(). + const { FOO, BAR } = process.env; + + // FOO and BAR properties are populated. + expect(FOO).toEqual('some data'); + + const complexData = JSON.parse(BAR); + expect(BAR).toEqual({ some: 'data' }); +}); +``` + +### Capturing trace of failures during global setup + +In some instances, it may be useful to capture a trace of failures encountered during the global setup. In order to do this, you must [start tracing](./api/class-tracing.md#tracing-start) in your setup, and you must ensure that you [stop tracing](./api/class-tracing.md#tracing-stop) if an error occurs before that error is thrown. This can be achieved by wrapping your setup in a `try...catch` block. Here is an example that expands the global setup example to capture a trace. + +```js +// global-setup.ts/js +import { chromium, FullConfig } from '@playwright/test'; + +async function globalSetup(config: FullConfig) { + const { baseURL, storageState } = config.projects[0].use; + const browser = await chromium.launch(); + const context = await browser.newContext(); + const page = await context.newPage(); + try { + await context.tracing.start({ screenshots: true, snapshots: true }); + await page.goto(baseURL!); + await page.getByLabel('User Name').fill('user'); + await page.getByLabel('Password').fill('password'); + await page.getByText('Sign in').click(); + await context.storageState({ path: storageState as string }); + await context.tracing.stop({ + path: './test-results/setup-trace.zip', + }) + await browser.close(); + } catch (error) { + await context.tracing.stop({ + path: './test-results/failed-setup-trace.zip', + }); + await browser.close(); + throw error; + } +} + +export default globalSetup; +```