2021-10-05 20:22:16 +02:00
---
id: test-parameterize
2023-01-23 09:28:22 -08:00
title: "Parameterize tests"
2021-10-05 20:22:16 +02:00
---
2023-01-23 09:28:22 -08:00
You can either parameterize tests on a test level or on a project level.
2021-10-05 20:22:16 +02:00
2021-11-23 05:38:48 +10:00
## Parameterized Tests
2021-10-05 20:22:16 +02:00
2022-06-10 16:34:31 -08:00
```js tab=js-js
2021-10-05 20:22:16 +02:00
// 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.
}
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2021-10-05 20:22:16 +02:00
// 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.
}
```
2021-11-23 05:38:48 +10:00
## Parameterized Projects
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
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
2022-06-10 16:34:31 -08:00
```js tab=js-js
2021-10-05 20:22:16 +02:00
// 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
});
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2021-10-05 20:22:16 +02:00
// 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 ).
2022-06-10 16:34:31 -08:00
```js tab=js-js
2021-10-05 20:22:16 +02:00
// 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);
// ...
});
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2021-10-05 20:22:16 +02:00
// 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.
2022-06-10 16:34:31 -08:00
```js tab=js-js
2021-10-05 20:22:16 +02:00
// playwright.config.js
// @ts -check
2023-01-12 13:12:02 -08:00
module.exports = defineConfig({
2021-10-05 20:22:16 +02:00
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' },
},
]
2023-01-12 13:12:02 -08:00
});
2021-10-05 20:22:16 +02:00
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2021-10-05 20:22:16 +02:00
// playwright.config.ts
2023-01-12 13:12:02 -08:00
import type { defineConfig } from '@playwright/test ';
2021-10-05 20:22:16 +02:00
import { TestOptions } from './my-test';
2023-01-12 13:12:02 -08:00
export default defineConfig({
2021-10-05 20:22:16 +02:00
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' },
},
]
2023-01-12 13:12:02 -08:00
});
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 also use the option in a fixture. Learn more about [fixtures ](./test-fixtures.md ).
2022-06-10 16:34:31 -08:00
```js tab=js-js
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
// 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.
2022-10-04 09:29:26 -08:00
await page.getByLabel('User Name').fill(person);
2022-10-03 17:02:46 -07:00
await page.getByText('Enter chat room').click();
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
// Each test will get a "page" that already has the person name.
await use(page);
},
});
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
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
// my-test.ts
import { test as base } from '@playwright/test ';
export type TestOptions = {
person: string;
};
2022-11-16 21:44:45 +00:00
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 }],
// Override default "page" fixture.
page: async ({ page, person }, use) => {
await page.goto('/chat');
// We use "person" parameter as a "name" for the chat room.
2022-10-04 09:29:26 -08:00
await page.getByLabel('User Name').fill(person);
2022-10-03 17:02:46 -07:00
await page.getByText('Enter chat room').click();
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
// Each test will get a "page" that already has the person name.
await use(page);
},
});
```
2022-02-01 14:34:47 -08:00
:::note
2023-01-23 09:28:22 -08:00
Parameterized projects behavior has changed in version 1.18. [Learn more ](./release-notes#breaking-change-custom-config-options ).
2022-02-01 14:34:47 -08:00
:::
2022-02-22 15:24:35 -08:00
## Passing Environment Variables
You can use environment variables to configure tests from the command line.
For example, consider the following test file that needs a username and a password. It is usually a good idea not to store your secrets in the source code, so we'll need a way to pass secrets from outside.
2022-06-10 16:34:31 -08:00
```js tab=js-js
2022-02-22 15:24:35 -08:00
// example.spec.js
test(`example test` , async ({ page }) => {
// ...
2022-10-04 09:29:26 -08:00
await page.getByLabel('User Name').fill(process.env.USERNAME);
await page.getByLabel('Password').fill(process.env.PASSWORD);
2022-02-22 15:24:35 -08:00
});
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2022-02-22 15:24:35 -08:00
// example.spec.ts
test(`example test` , async ({ page }) => {
// ...
2022-10-04 09:29:26 -08:00
await page.getByLabel('User Name').fill(process.env.USERNAME);
await page.getByLabel('Password').fill(process.env.PASSWORD);
2022-02-22 15:24:35 -08:00
});
```
2023-01-30 09:53:28 +01:00
You can run this test with your secret username and password set in the command line.
2022-02-22 15:24:35 -08:00
2022-06-10 16:34:31 -08:00
```bash tab=bash-bash
2022-02-22 15:24:35 -08:00
USERNAME=me PASSWORD=secret npx playwright test
```
2022-06-10 16:34:31 -08:00
```batch tab=bash-batch
2022-02-22 15:24:35 -08:00
set USERNAME=me
set PASSWORD=secret
npx playwright test
```
2022-06-10 16:34:31 -08:00
```powershell tab=bash-powershell
2022-02-22 15:24:35 -08:00
$env:USERNAME=me
$env:PASSWORD=secret
npx playwright test
```
2022-08-09 21:47:17 +08:00
Similarly, configuration file can also read environment variables passed through the command line.
2022-02-22 15:24:35 -08:00
2022-06-10 16:34:31 -08:00
```js tab=js-js
2022-02-22 15:24:35 -08:00
// playwright.config.js
// @ts -check
2023-01-12 13:12:02 -08:00
const { defineConfig } = require('@playwright/test ');
module.exports = defineConfig({
2022-02-22 15:24:35 -08:00
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
2023-01-12 13:12:02 -08:00
});
2022-02-22 15:24:35 -08:00
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2022-02-22 15:24:35 -08:00
// playwright.config.ts
2023-01-12 13:12:02 -08:00
import { defineConfig } from '@playwright/test ';
2022-02-22 15:24:35 -08:00
2023-01-12 13:12:02 -08:00
export default defineConfig({
2022-02-22 15:24:35 -08:00
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
2023-01-12 13:12:02 -08:00
});
2022-02-22 15:24:35 -08:00
```
Now, you can run tests against a staging or a production environment:
2022-06-10 16:34:31 -08:00
```bash tab=bash-bash
2022-02-22 15:24:35 -08:00
STAGING=1 npx playwright test
```
2022-06-10 16:34:31 -08:00
```batch tab=bash-batch
2022-02-22 15:24:35 -08:00
set STAGING=1
npx playwright test
```
2022-06-10 16:34:31 -08:00
```powershell tab=bash-powershell
2022-02-22 15:24:35 -08:00
$env:STAGING=1
npx playwright test
```
### .env files
To make environment variables easier to manage, consider something like `.env` files. Here is an example that uses [`dotenv` ](https://www.npmjs.com/package/dotenv ) package to read environment variables directly in the configuration file.
2022-06-10 16:34:31 -08:00
```js tab=js-js
2022-02-22 15:24:35 -08:00
// playwright.config.js
// @ts -check
// Read from default ".env" file.
require('dotenv').config();
// Alternatively, read from "../my.env" file.
require('dotenv').config({ path: path.resolve(__dirname, '..', 'my.env') });
2023-01-12 13:12:02 -08:00
const { defineConfig } = require('@playwright/test ');
module.exports = defineConfig({
2022-02-22 15:24:35 -08:00
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
2023-01-12 13:12:02 -08:00
});
2022-02-22 15:24:35 -08:00
```
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2022-02-22 15:24:35 -08:00
// playwright.config.ts
2023-01-12 13:12:02 -08:00
import { defineConfig } from '@playwright/test ';
2022-02-22 15:24:35 -08:00
import dotenv from 'dotenv';
import path from 'path';
// Read from default ".env" file.
dotenv.config();
// Alternatively, read from "../my.env" file.
dotenv.config({ path: path.resolve(__dirname, '..', 'my.env') });
2023-01-12 13:12:02 -08:00
export default defineConfig({
2022-02-22 15:24:35 -08:00
use: {
baseURL: process.env.STAGING === '1' ? 'http://staging.example.test/' : 'http://example.test/',
}
2023-01-12 13:12:02 -08:00
});
2022-02-22 15:24:35 -08:00
```
Now, you can just edit `.env` file to set any variables you'd like.
```bash
# .env file
STAGING=0
USERNAME=me
PASSWORD=secret
```
Run tests as usual, your environment variables should be picked up.
```bash
npx playwright test
```
2022-03-03 18:36:12 +01:00
2022-03-04 00:07:59 +01:00
## Create tests via a CSV file
2022-03-03 18:36:12 +01:00
The Playwright test-runner runs in Node.js, this means you can directly read files from the file system and parse them with your preferred CSV library.
See for example this CSV file, in our example `input.csv` :
```txt
"test_case","some_value","some_other_value"
"value 1","value 11","foobar1"
"value 2","value 22","foobar21"
"value 3","value 33","foobar321"
"value 4","value 44","foobar4321"
```
Based on this we'll generate some tests by using the [csv-parse ](https://www.npmjs.com/package/csv-parse ) library from NPM:
2022-06-10 16:34:31 -08:00
```js tab=js-ts
2022-03-03 18:36:12 +01:00
// foo.spec.ts
import fs from 'fs';
import path from 'path';
import { test } from '@playwright/test ';
import { parse } from 'csv-parse/sync';
const records = parse(fs.readFileSync(path.join(__dirname, 'input.csv')), {
columns: true,
skip_empty_lines: true
});
for (const record of records) {
test(`fooo: ${record.test_case}` , async ({ page }) => {
console.log(record.test_case, record.some_value, record.some_other_value);
});
}
```
2022-06-10 16:34:31 -08:00
```js tab=js-js
2022-03-03 18:36:12 +01:00
// foo.spec.js
const fs = require('fs');
const path = require('path');
const { test } = require('@playwright/test ');
const { parse } = require('csv-parse/sync');
const records = parse(fs.readFileSync(path.join(__dirname, 'input.csv')), {
columns: true,
skip_empty_lines: true
});
for (const record of records) {
test(`fooo: ${record.test_case}` , async ({ page }) => {
console.log(record.test_case, record.some_value, record.some_other_value);
});
}
```