2021-10-05 20:22:16 +02:00
|
|
|
---
|
|
|
|
id: test-parameterize
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
title: "Parametrize tests"
|
2021-10-05 20:22:16 +02:00
|
|
|
---
|
|
|
|
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
You can either parametrize tests on a test level or on a project level.
|
2021-10-05 20:22:16 +02:00
|
|
|
|
|
|
|
<!-- TOC -->
|
|
|
|
|
|
|
|
## Parametrized Tests
|
|
|
|
|
|
|
|
```js js-flavor=js
|
|
|
|
// example.spec.js
|
|
|
|
const people = ['Alice', 'Bob'];
|
2021-11-12 14:50:45 +01:00
|
|
|
for (const name of people) {
|
2021-10-05 20:22:16 +02:00
|
|
|
test(`testing with ${name}`, async () => {
|
|
|
|
// ...
|
|
|
|
});
|
|
|
|
// You can also do it with test.describe() or with multiple tests as long the test name is unique.
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```js js-flavor=ts
|
|
|
|
// example.spec.ts
|
|
|
|
const people = ['Alice', 'Bob'];
|
2021-11-12 14:50:45 +01:00
|
|
|
for (const name of people) {
|
2021-10-05 20:22:16 +02:00
|
|
|
test(`testing with ${name}`, async () => {
|
|
|
|
// ...
|
|
|
|
});
|
|
|
|
// You can also do it with test.describe() or with multiple tests as long the test name is unique.
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Parametrized Projects
|
|
|
|
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
Playwright Test supports running multiple test projects at the same time. In the following example, we'll run two projects with different options.
|
|
|
|
|
|
|
|
We declare the option `person` and set the value in the config. The first project runs with the value `Alice` and the second with the value `Bob`.
|
2021-10-05 20:22:16 +02:00
|
|
|
|
|
|
|
```js js-flavor=js
|
|
|
|
// my-test.js
|
|
|
|
const base = require('@playwright/test');
|
|
|
|
|
|
|
|
exports.test = base.test.extend({
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
// Define an option and provide a default value.
|
|
|
|
// We can later override it in the config.
|
|
|
|
person: ['John', { option: true }],
|
2021-10-05 20:22:16 +02:00
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
```js js-flavor=ts
|
|
|
|
// my-test.ts
|
|
|
|
import { test as base } from '@playwright/test';
|
|
|
|
|
|
|
|
export type TestOptions = {
|
|
|
|
person: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const test = base.extend<TestOptions>({
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
// Define an option and provide a default value.
|
|
|
|
// We can later override it in the config.
|
|
|
|
person: ['John', { option: true }],
|
2021-10-05 20:22:16 +02:00
|
|
|
});
|
|
|
|
```
|
|
|
|
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
We can use this option in the test, similarly to [fixtures](./test-fixtures.md).
|
|
|
|
|
2021-10-05 20:22:16 +02:00
|
|
|
```js js-flavor=js
|
|
|
|
// example.spec.js
|
|
|
|
const { test } = require('./my-test');
|
|
|
|
|
|
|
|
test('test 1', async ({ page, person }) => {
|
|
|
|
await page.goto(`/index.html`);
|
|
|
|
await expect(page.locator('#node')).toContainText(person);
|
|
|
|
// ...
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
```js js-flavor=ts
|
|
|
|
// example.spec.ts
|
|
|
|
import { test } from './my-test';
|
|
|
|
|
|
|
|
test('test 1', async ({ page, person }) => {
|
|
|
|
await page.goto(`/index.html`);
|
|
|
|
await expect(page.locator('#node')).toContainText(person);
|
|
|
|
// ...
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
Now, we can run tests in multiple configurations by using projects.
|
|
|
|
|
2021-10-05 20:22:16 +02:00
|
|
|
```js js-flavor=js
|
|
|
|
// playwright.config.js
|
|
|
|
// @ts-check
|
|
|
|
|
2021-11-12 17:00:41 +02:00
|
|
|
/** @type {import('@playwright/test').PlaywrightTestConfig<{ person: string }>} */
|
2021-10-05 20:22:16 +02:00
|
|
|
const config = {
|
|
|
|
projects: [
|
|
|
|
{
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
name: 'alice',
|
2021-10-05 20:22:16 +02:00
|
|
|
use: { person: 'Alice' },
|
|
|
|
},
|
|
|
|
{
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
name: 'bob',
|
2021-10-05 20:22:16 +02:00
|
|
|
use: { person: 'Bob' },
|
|
|
|
},
|
|
|
|
]
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = config;
|
|
|
|
```
|
|
|
|
|
|
|
|
```js js-flavor=ts
|
|
|
|
// playwright.config.ts
|
|
|
|
import { PlaywrightTestConfig } from '@playwright/test';
|
|
|
|
import { TestOptions } from './my-test';
|
|
|
|
|
|
|
|
const config: PlaywrightTestConfig<TestOptions> = {
|
|
|
|
projects: [
|
|
|
|
{
|
|
|
|
name: 'alice',
|
|
|
|
use: { person: 'Alice' },
|
|
|
|
},
|
|
|
|
{
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
name: 'bob',
|
2021-10-05 20:22:16 +02:00
|
|
|
use: { person: 'Bob' },
|
|
|
|
},
|
|
|
|
]
|
|
|
|
};
|
|
|
|
export default config;
|
|
|
|
```
|
feat(test runner): replace declare/define with "options" (#10293)
1. Fixtures defined in test.extend() can now have `{ option: true }` configuration that makes them overridable in the config. Options support all other properties of fixtures - value/function, scope, auto.
```
const test = base.extend<MyOptions>({
foo: ['default', { option: true }],
});
```
2. test.declare() and project.define are removed.
3. project.use applies overrides to default option values and nothing else. Any test.extend() and test.use() calls take priority over config options.
Required user changes: if someone used to define fixture options with test.extend(), overriding them in config will stop working. The solution is to add `{ option: true }`.
```
// Old code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: 123,
myFixture: ({ myOption }, use) => use(2 * myOption),
});
// New code
export const test = base.extend<{ myOption: number, myFixture: number }>({
myOption: [123, { option: true }],
myFixture: ({ myOption }, use) => use(2 * myOption),
});
```
2021-11-18 15:45:52 -08:00
|
|
|
|
|
|
|
We can also use the option in a fixture. Learn more about [fixtures](./test-fixtures.md).
|
|
|
|
|
|
|
|
```js js-flavor=js
|
|
|
|
// my-test.js
|
|
|
|
const base = require('@playwright/test');
|
|
|
|
|
|
|
|
exports.test = base.test.extend({
|
|
|
|
// Define an option and provide a default value.
|
|
|
|
// We can later override it in the config.
|
|
|
|
person: ['John', { option: true }],
|
|
|
|
|
|
|
|
// Override default "page" fixture.
|
|
|
|
page: async ({ page, person }, use) => {
|
|
|
|
await page.goto('/chat');
|
|
|
|
// We use "person" parameter as a "name" for the chat room.
|
|
|
|
await page.locator('#name').fill(person);
|
|
|
|
await page.click('text=Enter chat room');
|
|
|
|
// Each test will get a "page" that already has the person name.
|
|
|
|
await use(page);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
```js js-flavor=ts
|
|
|
|
// my-test.ts
|
|
|
|
import { test as base } from '@playwright/test';
|
|
|
|
|
|
|
|
export type TestOptions = {
|
|
|
|
person: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const test = base.test.extend<TestOptions>({
|
|
|
|
// Define an option and provide a default value.
|
|
|
|
// We can later override it in the config.
|
|
|
|
person: ['John', { option: true }],
|
|
|
|
|
|
|
|
// Override default "page" fixture.
|
|
|
|
page: async ({ page, person }, use) => {
|
|
|
|
await page.goto('/chat');
|
|
|
|
// We use "person" parameter as a "name" for the chat room.
|
|
|
|
await page.locator('#name').fill(person);
|
|
|
|
await page.click('text=Enter chat room');
|
|
|
|
// Each test will get a "page" that already has the person name.
|
|
|
|
await use(page);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
```
|