docs(test-runner): initial API docs for test runner (#7732)
This commit is contained in:
parent
9e3ac1f3a2
commit
8f1074c76e
|
|
@ -87,9 +87,9 @@ Maximum time in milliseconds to wait for the application to start. Defaults to `
|
|||
### option: Electron.launch.locale = %%-context-option-locale-%%
|
||||
### option: Electron.launch.offline = %%-context-option-offline-%%
|
||||
### option: Electron.launch.recordhar = %%-context-option-recordhar-%%
|
||||
### option: Electron.launch.recordhar.path = %%-context-option-recordhar-path-%%
|
||||
### option: Electron.launch.recordhar.recordHarOmitContent = %%-context-option-recordhar-omit-content-%%
|
||||
### option: Electron.launch.recordharpath = %%-context-option-recordhar-path-%%
|
||||
### option: Electron.launch.recordHarOmitContent = %%-context-option-recordhar-omit-content-%%
|
||||
### option: Electron.launch.recordvideo = %%-context-option-recordvideo-%%
|
||||
### option: Electron.launch.recordvideo.dir = %%-context-option-recordvideo-dir-%%
|
||||
### option: Electron.launch.recordvideo.size = %%-context-option-recordvideo-size-%%
|
||||
### option: Electron.launch.recordvideodir = %%-context-option-recordvideo-dir-%%
|
||||
### option: Electron.launch.recordvideosize = %%-context-option-recordvideo-size-%%
|
||||
### option: Electron.launch.timezoneId = %%-context-option-timezoneid-%%
|
||||
|
|
|
|||
746
docs/src/test-api/class-test.md
Normal file
746
docs/src/test-api/class-test.md
Normal file
|
|
@ -0,0 +1,746 @@
|
|||
# class: Test
|
||||
* langs: js
|
||||
|
||||
Playwright Test provides a `test` function to declare tests and [`expect` function](https://jestjs.io/docs/expect) to write assertions.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('basic test', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
const name = await page.innerText('.navbar__title');
|
||||
expect(name).toBe('Playwright');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('basic test', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
const name = await page.innerText('.navbar__title');
|
||||
expect(name).toBe('Playwright');
|
||||
});
|
||||
```
|
||||
|
||||
## method: Test.(call)
|
||||
|
||||
Declares a test.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('basic test', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
const name = await page.innerText('.navbar__title');
|
||||
expect(name).toBe('Playwright');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('basic test', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
const name = await page.innerText('.navbar__title');
|
||||
expect(name).toBe('Playwright');
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.(call).title
|
||||
- `title` <[string]>
|
||||
|
||||
Test title.
|
||||
|
||||
### param: Test.(call).testFunction
|
||||
- `testFunction` <[function]\([Object], [TestInfo]\)>
|
||||
|
||||
Test function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||
|
||||
|
||||
|
||||
## method: Test.afterAll
|
||||
|
||||
Declares an `afterAll` hook that is executed once after all tests. When called in the scope of a test file, runs after all tests in the file. When called inside a [`method: Test.describe`] group, runs after all tests in the group.
|
||||
|
||||
### param: Test.afterAll.hookFunction
|
||||
- `hookFunction` <[function]\([Object], [WorkerInfo]\)>
|
||||
|
||||
Hook function that takes one or two arguments: an object with fixtures and optional [WorkerInfo].
|
||||
|
||||
|
||||
|
||||
## method: Test.afterEach
|
||||
|
||||
Declares an `afterEach` hook that is executed after each test. When called in the scope of a test file, runs before each test in the file. When called inside a [`method: Test.describe`] group, runs before each test in the group.
|
||||
|
||||
### param: Test.afterEach.hookFunction
|
||||
- `hookFunction` <[function]\([Object], [TestInfo]\)>
|
||||
|
||||
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||
|
||||
|
||||
## method: Test.beforeAll
|
||||
|
||||
Declares a `beforeAll` hook that is executed once before all tests. When called in the scope of a test file, runs before all tests in the file. When called inside a [`method: Test.describe`] group, runs before all tests in the group.
|
||||
|
||||
```js js-flavor=js
|
||||
// example.spec.js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeAll(async () => {
|
||||
console.log('Before tests');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
console.log('After tests');
|
||||
});
|
||||
|
||||
test('my test', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// example.spec.ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeAll(async () => {
|
||||
console.log('Before tests');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
console.log('After tests');
|
||||
});
|
||||
|
||||
test('my test', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
You can use [`method: Test.afterAll`] to teardown any resources set up in `beforeAll`.
|
||||
|
||||
### param: Test.beforeAll.hookFunction
|
||||
- `hookFunction` <[function]\([Object], [WorkerInfo]\)>
|
||||
|
||||
Hook function that takes one or two arguments: an object with fixtures and optional [WorkerInfo].
|
||||
|
||||
|
||||
|
||||
## method: Test.beforeEach
|
||||
|
||||
Declares a `beforeEach` hook that is executed before each test. When called in the scope of a test file, runs before each test in the file. When called inside a [`method: Test.describe`] group, runs before each test in the group.
|
||||
|
||||
```js js-flavor=js
|
||||
// example.spec.js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Go to the starting url before each test.
|
||||
await page.goto('https://my.start.url/');
|
||||
});
|
||||
|
||||
test('my test', async ({ page }) => {
|
||||
expect(page.url()).toBe('https://my.start.url/');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// example.spec.ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Go to the starting url before each test.
|
||||
await page.goto('https://my.start.url/');
|
||||
});
|
||||
|
||||
test('my test', async ({ page }) => {
|
||||
expect(page.url()).toBe('https://my.start.url/');
|
||||
});
|
||||
```
|
||||
|
||||
You can use [`method: Test.afterEach`] to teardown any resources set up in `beforeEach`.
|
||||
|
||||
### param: Test.beforeEach.hookFunction
|
||||
- `hookFunction` <[function]\([Object], [TestInfo]\)>
|
||||
|
||||
Hook function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||
|
||||
|
||||
|
||||
## method: Test.describe
|
||||
|
||||
Declares a group of tests.
|
||||
|
||||
```js js-flavor=js
|
||||
test.describe('two tests', () => {
|
||||
test('one', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
|
||||
test('two', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
test.describe('two tests', () => {
|
||||
test('one', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
|
||||
test('two', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.describe.title
|
||||
- `title` <[string]>
|
||||
|
||||
Group title.
|
||||
|
||||
### param: Test.describe.callback
|
||||
- `callback` <[function]>
|
||||
|
||||
A callback that is run immediately when calling [`method: Test.describe`]. Any tests added in this callback will belong to the group.
|
||||
|
||||
|
||||
## method: Test.describe.only
|
||||
|
||||
Declares a focused group of tests. If there are some focused tests or suites, all of them will be run but nothing else.
|
||||
|
||||
```js js-flavor=js
|
||||
test.describe.only('focused group', () => {
|
||||
test('in the focused group', async ({ page }) => {
|
||||
// This test will run
|
||||
});
|
||||
});
|
||||
test('not in the focused group', async ({ page }) => {
|
||||
// This test will not run
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
test.describe.only('focused group', () => {
|
||||
test('in the focused group', async ({ page }) => {
|
||||
// This test will run
|
||||
});
|
||||
});
|
||||
test('not in the focused group', async ({ page }) => {
|
||||
// This test will not run
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.describe.only.title
|
||||
- `title` <[string]>
|
||||
|
||||
Group title.
|
||||
|
||||
### param: Test.describe.only.callback
|
||||
- `callback` <[function]>
|
||||
|
||||
A callback that is run immediately when calling [`method: Test.describe.only`]. Any tests added in this callback will belong to the group.
|
||||
|
||||
|
||||
|
||||
|
||||
## property: Test.expect
|
||||
- type: <[Object]>
|
||||
|
||||
`expect` function can be used to create test assertions. Read [expect library documentation](https://jestjs.io/docs/expect) for more details.
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.fail
|
||||
|
||||
Marks a test or a group of tests as "should fail". Playwright Test runs these tests and ensures that they are actually failing. This is useful for documentation purposes to acknowledge that some functionality is broken until it is fixed.
|
||||
|
||||
Unconditional fail:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('not yet ready', async ({ page }) => {
|
||||
test.fail();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('not yet ready', async ({ page }) => {
|
||||
test.fail();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditional fail a test with an optional description:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('fail in WebKit', async ({ page, browserName }) => {
|
||||
test.fail(browserName === 'webkit', 'This feature is not implemented for Mac yet');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('fail in WebKit', async ({ page, browserName }) => {
|
||||
test.fail(browserName === 'webkit', 'This feature is not implemented for Mac yet');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditional fail for all tests in a file or [`method: Test.describe`] group:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.fail(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('fail in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('fail in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.fail(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('fail in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('fail in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.fail.condition
|
||||
- `condition` <[void]|[boolean]|[function]\([Object]\):[boolean]>
|
||||
|
||||
Optional condition - either a boolean value, or a function that takes a fixtures Object and returns a boolean. Test or tests are marked as "should fail" when the condition is `true`.
|
||||
|
||||
### param: Test.fail.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.fixme
|
||||
|
||||
Marks a test or a group of tests as "fixme". These tests will not be run, but the intention is to fix them.
|
||||
|
||||
Unconditional fixme:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('not yet ready', async ({ page }) => {
|
||||
test.fixme();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('not yet ready', async ({ page }) => {
|
||||
test.fixme();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditional fixme a test with an optional description:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('fixme in WebKit', async ({ page, browserName }) => {
|
||||
test.fixme(browserName === 'webkit', 'This feature is not implemented for Mac yet');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('fixme in WebKit', async ({ page, browserName }) => {
|
||||
test.fixme(browserName === 'webkit', 'This feature is not implemented for Mac yet');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditional fixme for all tests in a file or [`method: Test.describe`] group:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.fixme(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('fixme in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('fixme in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.fixme(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('fixme in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('fixme in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
`fixme` from a hook:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.fixme(process.env.APP_VERSION === 'v2', 'No settings in v2 yet');
|
||||
await page.goto('/settings');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.fixme(process.env.APP_VERSION === 'v2', 'No settings in v2 yet');
|
||||
await page.goto('/settings');
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.fixme.condition
|
||||
- `condition` <[void]|[boolean]|[function]\([Object]\):[boolean]>
|
||||
|
||||
Optional condition - either a boolean value, or a function that takes a fixtures Object and returns a boolean. Test or tests are marked as "fixme" when the condition is `true`.
|
||||
|
||||
### param: Test.fixme.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
|
||||
|
||||
## method: Test.only
|
||||
|
||||
Declares a focused test. If there are some focused tests or suites, all of them will be run but nothing else.
|
||||
|
||||
```js js-flavor=js
|
||||
test.only('focus this test', async ({ page }) => {
|
||||
// Run only focused tests in the entire project.
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
test.only('focus this test', async ({ page }) => {
|
||||
// Run only focused tests in the entire project.
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.only.title
|
||||
- `title` <[string]>
|
||||
|
||||
Test title.
|
||||
|
||||
### param: Test.only.testFunction
|
||||
- `testFunction` <[function]\([Object], [TestInfo]\)>
|
||||
|
||||
Test function that takes one or two arguments: an object with fixtures and optional [TestInfo].
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.setTimeout
|
||||
|
||||
Changes the timeout for the test.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('very slow test', async ({ page }) => {
|
||||
test.setTimeout(120000);
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('very slow test', async ({ page }) => {
|
||||
test.setTimeout(120000);
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Changing timeout from a slow hook:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
// Extend timeout for all tests running this hook by 30 seconds.
|
||||
test.setTimeout(testInfo.timeout + 30000);
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
// Extend timeout for all tests running this hook by 30 seconds.
|
||||
test.setTimeout(testInfo.timeout + 30000);
|
||||
});
|
||||
```
|
||||
|
||||
Timeout for the currently running test is available through [`property: TestInfo.timeout`].
|
||||
|
||||
### param: Test.setTimeout.timeout
|
||||
- `timeout` <[int]>
|
||||
|
||||
Timeout in milliseconds.
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.skip
|
||||
|
||||
Skips a test or a group of tests.
|
||||
|
||||
Unconditionally skip a test:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('broken test', async ({ page }) => {
|
||||
test.skip();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('broken test', async ({ page }) => {
|
||||
test.skip();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditionally skip a test with an optional description:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('skip in WebKit', async ({ page, browserName }) => {
|
||||
test.skip(browserName === 'webkit', 'This feature is not implemented for Mac');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('skip in WebKit', async ({ page, browserName }) => {
|
||||
test.skip(browserName === 'webkit', 'This feature is not implemented for Mac');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditionally skip all tests in a file or [`method: Test.describe`] group:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.skip(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('skip in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('skip in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.skip(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('skip in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('skip in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Skip from a hook:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.skip(process.env.APP_VERSION === 'v1', 'There are no settings in v1');
|
||||
await page.goto('/settings');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.skip(process.env.APP_VERSION === 'v1', 'There are no settings in v1');
|
||||
await page.goto('/settings');
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.skip.condition
|
||||
- `condition` <[void]|[boolean]|[function]\([Object]\):[boolean]>
|
||||
|
||||
Optional condition - either a boolean value, or a function that takes a fixtures Object and returns a boolean. Test or tests are skipped when the condition is `true`.
|
||||
|
||||
### param: Test.skip.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.slow
|
||||
|
||||
Marks a test or a group of tests as "slow". Slow tests will be given triple the default timeout.
|
||||
|
||||
Unconditional slow:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('slow test', async ({ page }) => {
|
||||
test.slow();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('slow test', async ({ page }) => {
|
||||
test.slow();
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditional slow a test with an optional description:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('slow in WebKit', async ({ page, browserName }) => {
|
||||
test.slow(browserName === 'webkit', 'This feature is slow on Mac');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('slow in WebKit', async ({ page, browserName }) => {
|
||||
test.slow(browserName === 'webkit', 'This feature is slow on Mac');
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Conditional slow for all tests in a file or [`method: Test.describe`] group:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.slow(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('slow in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('slow in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.slow(({ browserName }) => browserName === 'webkit');
|
||||
|
||||
test('slow in WebKit 1', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
test('fail in WebKit 2', async ({ page }) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.slow.condition
|
||||
- `condition` <[void]|[boolean]|[function]\([Object]\):[boolean]>
|
||||
|
||||
Optional condition - either a boolean value, or a function that takes a fixtures Object and returns a boolean. Test or tests are marked as "slow" when the condition is `true`.
|
||||
|
||||
### param: Test.slow.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
|
||||
|
||||
|
||||
## method: Test.use
|
||||
|
||||
Specifies parameters or fixtures to use in a single test file or a [`method: Test.describe`] group. Most useful to configure a fixture, for example set `locale` to configure `context` fixture.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.use({ locale: 'en-US' });
|
||||
|
||||
test('test with locale', async ({ page }) => {
|
||||
// Default context and page have locale as specified
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.use({ locale: 'en-US' });
|
||||
|
||||
test('test with locale', async ({ page }) => {
|
||||
// Default context and page have locale as specified
|
||||
});
|
||||
```
|
||||
|
||||
### param: Test.use.fixtures
|
||||
- `fixtures` <[Object]>
|
||||
|
||||
An object with fixture values.
|
||||
|
||||
|
||||
277
docs/src/test-api/class-testconfig.md
Normal file
277
docs/src/test-api/class-testconfig.md
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
# class: TestConfig
|
||||
* langs: js
|
||||
|
||||
Playwright Test provides many options to configure how your tests are collected and executed, for example `timeout` or `testDir`. These options are described in the [TestConfig] object in the [configuration file](./test-configuration.md).
|
||||
|
||||
Playwright Test supports running multiple test projects at the same time. Project-specific options should be put to [`property: TestConfig.projects`], but top-level [TestConfig] can also define base options shared between all projects.
|
||||
|
||||
```js js-flavor=js
|
||||
// playwright.config.js
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
timeout: 30000,
|
||||
globalTimeout: 600000,
|
||||
reporter: 'list',
|
||||
testDir: './tests',
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// playwright.config.ts
|
||||
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
timeout: 30000,
|
||||
globalTimeout: 600000,
|
||||
reporter: 'list',
|
||||
testDir: './tests',
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
## property: TestConfig.expect
|
||||
- type: <[Object]>
|
||||
- `toMatchSnapshot` <[Object]>
|
||||
- `threshold` <[float]> Image matching threshold between zero (strict) and one (lax).
|
||||
|
||||
Configuration for the `expect` assertion library.
|
||||
|
||||
## property: TestConfig.forbidOnly
|
||||
- type: <[boolean]>
|
||||
|
||||
Whether to exit with an error if any tests or groups are marked as [`method: Test.only`] or [`method: Test.describe.only`]. Useful on CI.
|
||||
|
||||
## property: TestConfig.globalSetup
|
||||
- type: <[string]>
|
||||
|
||||
Path to the global setup file. This file will be required and run before all the tests. It must export a single function.
|
||||
|
||||
Learn more about [global setup and teardown](./test-advanced.md#global-setup-and-teardown).
|
||||
|
||||
```js js-flavor=js
|
||||
// playwright.config.js
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
globalSetup: './global-setup',
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// playwright.config.ts
|
||||
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
globalSetup: './global-setup',
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
## property: TestConfig.globalTeardown
|
||||
- type: <[string]>
|
||||
|
||||
Path to the global teardown file. This file will be required and run after all the tests. It must export a single function. See also [`property: TestConfig.globalSetup`].
|
||||
|
||||
Learn more about [global setup and teardown](./test-advanced.md#global-setup-and-teardown).
|
||||
|
||||
|
||||
## property: TestConfig.globalTimeout
|
||||
- type: <[int]>
|
||||
|
||||
Maximum time in milliseconds the whole test suite can run. Zero timeout (default) disables this behavior. Useful on CI to prevent broken setup from running too long and wasting resources.
|
||||
|
||||
|
||||
## property: TestConfig.grep
|
||||
- type: <[RegExp]|[Array]<[RegExp]>>
|
||||
|
||||
Filter to only run tests with a title matching one of the patterns. For example, passing `grep: /cart/` should only run tests with "cart" in the title. Also available in the [command line](./test-cli.md) with the `-g` option.
|
||||
|
||||
`grep` option is also useful for [tagging tests](./test-annotations.md#tag-tests).
|
||||
|
||||
|
||||
## property: TestConfig.grepInvert
|
||||
- type: <[RegExp]|[Array]<[RegExp]>>
|
||||
|
||||
Filter to only run tests with a title **not** matching one of the patterns. This is the opposite of [`property: TestConfig.grep`]. Also available in the [command line](./test-cli.md) with the `--grep-invert` option.
|
||||
|
||||
`grepInvert` option is also useful for [tagging tests](./test-annotations.md#tag-tests).
|
||||
|
||||
|
||||
## property: TestConfig.maxFailures
|
||||
- type: <[int]>
|
||||
|
||||
The maximum number of test failures for the whole test suite run. After reaching this number, testing will stop and exit with an error. Setting to zero (default) disables this behavior.
|
||||
|
||||
Also available in the [command line](./test-cli.md) with the `--max-failures` and `-x` options.
|
||||
|
||||
## property: TestConfig.metadata
|
||||
- type: <[Object]>
|
||||
|
||||
Any JSON-serializable metadata that will be put directly to the test report.
|
||||
|
||||
## property: TestConfig.outputDir
|
||||
- type: <[string]>
|
||||
|
||||
The output directory for files created during test execution. Defaults to `test-results`.
|
||||
|
||||
This directory is cleaned at the start. When running a test, a unique subdirectory inside the [`property: TestConfig.outputDir`] is created, guaranteeing that test running in parallel do not conflict. This directory can be accessed by [`property: TestInfo.outputDir`] and [`method: TestInfo.outputPath`].
|
||||
|
||||
|
||||
Here is an example that uses [`method: TestInfo.outputPath`] to create a temporary file.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const fs = require('fs');
|
||||
|
||||
test('example test', async ({}, testInfo) => {
|
||||
const file = testInfo.outputPath('temporary-file.txt');
|
||||
await fs.promises.writeFile(file, 'Put some data to the file', 'utf8');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
import fs from 'fs';
|
||||
|
||||
test('example test', async ({}, testInfo) => {
|
||||
const file = testInfo.outputPath('temporary-file.txt');
|
||||
await fs.promises.writeFile(file, 'Put some data to the file', 'utf8');
|
||||
});
|
||||
```
|
||||
|
||||
## property: TestConfig.preserveOutput
|
||||
- type: <[PreserveOutput]<"always"|"never"|"failures-only">>
|
||||
|
||||
Whether to preserve test output in the [`property: TestConfig.outputDir`]. Defaults to `'always'`.
|
||||
1. `'always'` - preserve output for all tests;
|
||||
1. `'never'` - do not preserve output for any tests;
|
||||
1. `'failures-only'` - only preserve output for failed tests.
|
||||
|
||||
|
||||
## property: TestConfig.projects
|
||||
- type: <[Array]<[TestProject]>>
|
||||
|
||||
Playwright Test supports running multiple test projects at the same time. See [TestProject] for more information.
|
||||
|
||||
|
||||
## property: TestConfig.quiet
|
||||
- type: <[boolean]>
|
||||
|
||||
Whether to suppress stdio and stderr output from the tests.
|
||||
|
||||
## property: TestConfig.repeatEach
|
||||
- type: <[int]>
|
||||
|
||||
The number of times to repeat each test, useful for debugging flaky tests.
|
||||
|
||||
## property: TestConfig.reporter
|
||||
- type: <[string]|[Array]<[Object]>|[BuiltInReporter]<"list"|"dot"|"line"|"json"|"junit"|"null">>
|
||||
- `0` <[string]> Reporter name or module or file path
|
||||
- `1` <[Object]> An object with reporter options if any
|
||||
|
||||
The list of reporters to use. Each reporter can be:
|
||||
1. A builtin reporter name like `'list'` or `'json'`.
|
||||
2. A module name like `'my-awesome-reporter'`.
|
||||
3. A relative path to the reporter like `'./reporters/my-awesome-reporter.js'`.
|
||||
|
||||
You can pass options to the reporter in a tuple like `['json', { outputFile: './report.json' }]`.
|
||||
|
||||
Learn more in the [reporters guide](./test-reporters.md).
|
||||
|
||||
```js js-flavor=js
|
||||
// playwright.config.js
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
reporter: 'line',
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// playwright.config.ts
|
||||
import { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
reporter: 'line',
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
## property: TestConfig.reportSlowTests
|
||||
- type: <[Object]>
|
||||
- `max` <[int]> The maximum number of slow tests to report. Defaults to `5`.
|
||||
- `threshold` <[float]> Test duration in milliseconds that is considered slow. Defaults to 15 seconds.
|
||||
|
||||
Whether to report slow tests. Pass `null` to disable this feature.
|
||||
|
||||
Tests that took more than `threshold` milliseconds are considered slow, and the slowest ones are reported, no more than `max` number of them. Passing zero as `max` reports all slow tests that exceed the threshold.
|
||||
|
||||
## property: TestConfig.retries
|
||||
- type: <[int]>
|
||||
|
||||
The maximum number of retry attempts given to failed tests. Learn more about [test retries](./test-retries.md).
|
||||
|
||||
## property: TestConfig.shard
|
||||
- type: <[Object]>
|
||||
- `total` <[int]> The total number of shards.
|
||||
- `current` <[int]> The index of the shard to execute, one-based.
|
||||
|
||||
Shard tests and execute only the selected shard. Specify in the one-based form like `{ total: 5, current: 2 }`.
|
||||
|
||||
Learn more about [parallelism and sharding](./test-parallel.md) with Playwright Test.
|
||||
|
||||
## property: TestConfig.testDir
|
||||
- type: <[string]>
|
||||
|
||||
Directory that will be recursively scanned for test files. Defaults to the directory of the configuration file.
|
||||
|
||||
## property: TestConfig.testIgnore
|
||||
- type: <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>>
|
||||
|
||||
Files matching one of these patterns are not executed as test files. Matching is performed against the absolute file path. Strings are treated as glob patterns.
|
||||
|
||||
For example, `'**/test-assets/**'` will ignore any files in the `test-assets` directory.
|
||||
|
||||
## property: TestConfig.testMatch
|
||||
- type: <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>>
|
||||
|
||||
Only the files matching one of these patterns are executed as test files. Matching is performed against the absolute file path. Strings are treated as glob patterns.
|
||||
|
||||
By default, Playwright Test looks for files matching `.*(test|spec)\.(js|ts|mjs)`.
|
||||
|
||||
## property: TestConfig.timeout
|
||||
- type: <[int]>
|
||||
|
||||
Timeout for each test in milliseconds. Defaults to 30 seconds.
|
||||
|
||||
This is a base timeout for all tests. In addition, each test can configure its own timeout with [`method: Test.setTimeout`].
|
||||
|
||||
## property: TestConfig.updateSnapshots
|
||||
- type: <[UpdateSnapshots]<"all"|"none"|"missing">>
|
||||
|
||||
Whether to update expected snapshots with the actual results produced by the test run. Defaults to `'missing'`.
|
||||
1. `'all'` - All tests that are executed will update snapshots.
|
||||
1. `'none'` - No snapshots are updated.
|
||||
1. `'missing'` - Missing snapshots are created, for example when authoring a new test and running it for the first time. This is the default.
|
||||
|
||||
Learn more about [snapshots](./test-snapshots.md).
|
||||
|
||||
|
||||
## property: TestConfig.workers
|
||||
- type: <[int]>
|
||||
|
||||
The maximum number of concurrent worker processes to use for parallelizing tests.
|
||||
|
||||
Playwright Test uses worker processes to run tests. There is always at least one worker process, but more can be used to speed up test execution.
|
||||
|
||||
Defaults to one half of the number of CPU cores. Learn more about [parallelism and sharding](./test-parallel.md) with Playwright Test.
|
||||
354
docs/src/test-api/class-testinfo.md
Normal file
354
docs/src/test-api/class-testinfo.md
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
# class: TestInfo
|
||||
* langs: js
|
||||
|
||||
`TestInfo` contains information about currently running test. It is available to any test function, [`method: Test.beforeEach`] and [`method: Test.afterEach`] hooks and test-scoped fixtures. `TestInfo` provides utilities to control test execution: attach files, update test timeout, determine which test is currently running and whether it was retried, etc.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('basic test', async ({ page }, testInfo) => {
|
||||
expect(testInfo.title).toBe('basic test');
|
||||
await page.screenshot(testInfo.outputPath('screenshot.png'));
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('basic test', async ({ page }, testInfo) => {
|
||||
expect(testInfo.title).toBe('basic test');
|
||||
await page.screenshot(testInfo.outputPath('screenshot.png'));
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## property: TestInfo.annotations
|
||||
- type: <[Array]<[Object]>>
|
||||
- `type` <[string]> Annotation type, for example `'skip'` or `'fail'`.
|
||||
- `description` <[void]|[string]> Optional description.
|
||||
|
||||
The list of annotations applicable to the current test. Includes annotations from the test, annotations from all [`method: Test.describe`] groups the test belongs to and file-level annotations for the test file.
|
||||
|
||||
Learn more about [test annotations](./test-annotations.md).
|
||||
|
||||
## property: TestInfo.attachments
|
||||
- type: <[Array]<[Object]>>
|
||||
- `name` <[string]> Attachment name.
|
||||
- `contentType` <[string]> Content type of this attachment to properly present in the report, for example `'application/json'` or `'image/png'`.
|
||||
- `path` <[void]|[string]> Optional path on the filesystem to the attached file.
|
||||
- `body` <[void]|[Buffer]> Optional attachment body used instead of a file.
|
||||
|
||||
The list of files or buffers attached to the current test. Some reporters show test attachments. For example, you can attach a screenshot to the test.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test('basic test', async ({ page }, testInfo) => {
|
||||
await page.goto('https://playwright.dev');
|
||||
|
||||
// Capture a screenshot and attach it.
|
||||
const path = testInfo.outputPath('screenshot.png');
|
||||
await page.screenshot({ path });
|
||||
testInfo.attachments.push({ name: 'screenshot', path, contentType: 'image/png' });
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('basic test', async ({ page }, testInfo) => {
|
||||
await page.goto('https://playwright.dev');
|
||||
|
||||
// Capture a screenshot and attach it.
|
||||
const path = testInfo.outputPath('screenshot.png');
|
||||
await page.screenshot({ path });
|
||||
testInfo.attachments.push({ name: 'screenshot', path, contentType: 'image/png' });
|
||||
});
|
||||
```
|
||||
|
||||
## property: TestInfo.column
|
||||
- type: <[int]>
|
||||
|
||||
Column number where the currently running test is declared.
|
||||
|
||||
|
||||
## property: TestInfo.config
|
||||
- type: <[TestConfig]>
|
||||
|
||||
Processed configuration from the [configuration file](./test-configuration.md).
|
||||
|
||||
|
||||
## property: TestInfo.duration
|
||||
- type: <[int]>
|
||||
|
||||
The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not.
|
||||
|
||||
|
||||
## property: TestInfo.error
|
||||
- type: <[Object]>
|
||||
- `message` <[void]|[string]> Error message. Set when `Error` (or its subclass) has been thrown.
|
||||
- `stack` <[void]|[string]> Error stack. Set when `Error` (or its subclass) has been thrown.
|
||||
- `value` <[void]|[string]> The thrown value. Set when anything except the `Error` (or its subclass) has been thrown.
|
||||
|
||||
An error thrown during test execution, if any.
|
||||
|
||||
|
||||
## property: TestInfo.expectedStatus
|
||||
- type: <[TestStatus]<"passed"|"failed"|"timedOut"|"skipped">>
|
||||
|
||||
Expected status for the currently running test. This is usually `'passed'`, except for a few cases:
|
||||
1. `'skipped'` for skipped tests, e.g. with [`method: Test.skip`];
|
||||
1. `'failed'` for tests marked as failed with [`method: Test.fail`].
|
||||
|
||||
Expected status is usually compared with the actual [`property: TestInfo.status`]:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.afterEach(async ({}, testInfo) => {
|
||||
if (testInfo.status !== testInfo.expectedStatus)
|
||||
console.log(`${testInfo.title} did not run as expected!`);
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.afterEach(async ({}, testInfo) => {
|
||||
if (testInfo.status !== testInfo.expectedStatus)
|
||||
console.log(`${testInfo.title} did not run as expected!`);
|
||||
});
|
||||
```
|
||||
|
||||
## method: TestInfo.fail
|
||||
|
||||
Marks the currently running test as "should fail". Playwright Test ensures that this test is actually failing. This is similar to [`method: Test.fail`].
|
||||
|
||||
### param: TestInfo.fail.condition
|
||||
- `condition` <[void]|[boolean]>
|
||||
|
||||
Optional condition - the test is marked as "should fail" when the condition is `true`.
|
||||
|
||||
### param: TestInfo.fail.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
## property: TestInfo.file
|
||||
- type: <[string]>
|
||||
|
||||
Absolute path to a file where the currently running test is declared.
|
||||
|
||||
## method: TestInfo.fixme
|
||||
|
||||
Marks the currently running test as "fixme". The test will be skipped, but the intention is to fix it. This is similar to [`method: Test.fixme`].
|
||||
|
||||
### param: TestInfo.fixme.condition
|
||||
- `condition` <[void]|[boolean]>
|
||||
|
||||
Optional condition - the test is marked as "fixme" when the condition is `true`.
|
||||
|
||||
### param: TestInfo.fixme.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
## property: TestInfo.fn
|
||||
- type: <[function]\([Object], [TestInfo]\)>
|
||||
|
||||
Test function as passed to `test(title, testFunction)`.
|
||||
|
||||
## property: TestInfo.line
|
||||
- type: <[int]>
|
||||
|
||||
Line number where the currently running test is declared.
|
||||
|
||||
## property: TestInfo.outputDir
|
||||
- type: <[string]>
|
||||
|
||||
Absolute path to the output directory for this specific test run. Each test run gets its own directory so they cannot conflict.
|
||||
|
||||
## method: TestInfo.outputPath
|
||||
- returns: <[string]>
|
||||
|
||||
Returns a path inside the [`property: TestInfo.outputDir`] where the test can safely put a temporary file. Guarantees that tests running in parallel will not interfere with each other.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const fs = require('fs');
|
||||
|
||||
test('example test', async ({}, testInfo) => {
|
||||
const file = testInfo.outputPath('dir', 'temporary-file.txt');
|
||||
await fs.promises.writeFile(file, 'Put some data to the dir/temporary-file.txt', 'utf8');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
import fs from 'fs';
|
||||
|
||||
test('example test', async ({}, testInfo) => {
|
||||
const file = testInfo.outputPath('dir', 'temporary-file.txt');
|
||||
await fs.promises.writeFile(file, 'Put some data to the dir/temporary-file.txt', 'utf8');
|
||||
});
|
||||
```
|
||||
|
||||
### param: TestInfo.outputPath.pathSegments
|
||||
- `pathSegments` <[string...]>
|
||||
|
||||
Path segments to append at the end of the resulting path.
|
||||
|
||||
|
||||
## property: TestInfo.project
|
||||
- type: <[TestProject]>
|
||||
|
||||
Processed project configuration from the [configuration file](./test-configuration.md).
|
||||
|
||||
|
||||
## property: TestInfo.repeatEachIndex
|
||||
- type: <[int]>
|
||||
|
||||
Specifies a unique repeat index when running in "repeat each" mode. This mode is enabled by passing `--repeat-each` to the [command line](./test-cli.md).
|
||||
|
||||
## property: TestInfo.retry
|
||||
- type: <[int]>
|
||||
|
||||
Specifies the retry number when the test is retried after a failure. The first test run has [`property: TestInfo.retry`] equal to zero, the first retry has it equal to one, and so on. Learn more about [retries](./test-retries.md).
|
||||
|
||||
## method: TestInfo.setTimeout
|
||||
|
||||
Changes the timeout for the currently running test. Zero means no timeout.
|
||||
|
||||
Timeout is usually specified in the [configuration file](./test-configuration.md), but it could be useful to change the timeout in certain scenarios:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
// Extend timeout for all tests running this hook by 30 seconds.
|
||||
testInfo.setTimeout(testInfo.timeout + 30000);
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
// Extend timeout for all tests running this hook by 30 seconds.
|
||||
testInfo.setTimeout(testInfo.timeout + 30000);
|
||||
});
|
||||
```
|
||||
|
||||
### param: TestInfo.setTimeout.timeout
|
||||
- `timeout` <[int]>
|
||||
|
||||
Timeout in milliseconds.
|
||||
|
||||
## method: TestInfo.skip
|
||||
|
||||
Skips the currently running test. This is similar to [`method: Test.skip`].
|
||||
|
||||
### param: TestInfo.skip.condition
|
||||
- `condition` <[void]|[boolean]>
|
||||
|
||||
Optional condition - the test is skipped when the condition is `true`.
|
||||
|
||||
### param: TestInfo.skip.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
## method: TestInfo.slow
|
||||
|
||||
Marks the currently running test as "slow", giving it triple the default timeout. This is similar to [`method: Test.slow`].
|
||||
|
||||
### param: TestInfo.slow.condition
|
||||
- `condition` <[void]|[boolean]>
|
||||
|
||||
Optional condition - the test is marked as "slow" when the condition is `true`.
|
||||
|
||||
### param: TestInfo.slow.description
|
||||
- `description` <[void]|[string]>
|
||||
|
||||
Optional description that will be reflected in a test report.
|
||||
|
||||
## method: TestInfo.snapshotPath
|
||||
- returns: <[string]>
|
||||
|
||||
Returns a path to a snapshot file with the given `snapshotName`. Learn more about [snapshots](./test-snapshots.md).
|
||||
|
||||
### param: TestInfo.snapshotPath.snapshotName
|
||||
- `snapshotName` <[string]> The name of the snapshot. Note that snapshots with the same name in the same test file are expected to be the same.
|
||||
|
||||
## property: TestInfo.snapshotSuffix
|
||||
- type: <[string]>
|
||||
|
||||
Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on the platform, you can set `testInfo.snapshotSuffix` equal to `process.platform`. In this case `expect(value).toMatchSnapshot(snapshotName)` will use different snapshots depending on the platform. Learn more about [snapshots](./test-snapshots.md).
|
||||
|
||||
## property: TestInfo.status
|
||||
- type: <[void]|[TestStatus]<"passed"|"failed"|"timedOut"|"skipped">>
|
||||
|
||||
Actual status for the currently running test. Available after the test has finished in [`method: Test.afterEach`] hook and fixtures.
|
||||
|
||||
Status is usually compared with the [`property: TestInfo.expectedStatus`]:
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.afterEach(async ({}, testInfo) => {
|
||||
if (testInfo.status !== testInfo.expectedStatus)
|
||||
console.log(`${testInfo.title} did not run as expected!`);
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.afterEach(async ({}, testInfo) => {
|
||||
if (testInfo.status !== testInfo.expectedStatus)
|
||||
console.log(`${testInfo.title} did not run as expected!`);
|
||||
});
|
||||
```
|
||||
|
||||
## property: TestInfo.stderr
|
||||
- type: <[Array]<[string]|[Buffer]>>
|
||||
|
||||
Output written to `process.stderr` or `console.error` during the test execution.
|
||||
|
||||
## property: TestInfo.stdout
|
||||
- type: <[Array]<[string]|[Buffer]>>
|
||||
|
||||
Output written to `process.stdout` or `console.log` during the test execution.
|
||||
|
||||
## property: TestInfo.timeout
|
||||
- type: <[int]>
|
||||
|
||||
Timeout in milliseconds for the currently running test. Zero means no timeout. Timeout is usually specified in the [configuration file](./test-configuration.md)
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
// Extend timeout for all tests running this hook by 30 seconds.
|
||||
testInfo.setTimeout(testInfo.timeout + 30000);
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }, testInfo) => {
|
||||
// Extend timeout for all tests running this hook by 30 seconds.
|
||||
testInfo.setTimeout(testInfo.timeout + 30000);
|
||||
});
|
||||
```
|
||||
|
||||
## property: TestInfo.title
|
||||
- type: <[string]>
|
||||
|
||||
The title of the currently running test as passed to `test(title, testFunction)`.
|
||||
|
||||
## property: TestInfo.workerIndex
|
||||
- type: <[int]>
|
||||
|
||||
The unique index of the worker process that is running the test. Also available as `process.env.TEST_WORKER_INDEX`. Learn more about [parallelism and sharding](./test-parallel.md) with Playwright Test.
|
||||
275
docs/src/test-api/class-testproject.md
Normal file
275
docs/src/test-api/class-testproject.md
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
# class: TestProject
|
||||
* langs: js
|
||||
|
||||
Playwright Test supports running multiple test projects at the same time. This is useful for running tests in multiple configurations. For example, consider running tests against multiple browsers.
|
||||
|
||||
`TestProject` encapsulates configuration specific to a single project. Projects are configured in [`property: TestConfig.projects`] specified in the [configuration file](./test-configuration.md). Note that all properties of [TestProject] are available in the top-level [TestConfig], in which case they are shared between all projects.
|
||||
|
||||
Here is an example configuration that runs every test in Chromium, Firefox and WebKit, both Desktop and Mobile versions.
|
||||
|
||||
```js js-flavor=js
|
||||
// playwright.config.js
|
||||
// @ts-check
|
||||
const { devices } = require('@playwright/test');
|
||||
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
// Options shared for all projects.
|
||||
timeout: 30000,
|
||||
use: {
|
||||
ignoreHTTPSErrors: true,
|
||||
},
|
||||
|
||||
// Options specific to each project.
|
||||
projects: [
|
||||
{
|
||||
name: 'Desktop Chromium',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Desktop Safari',
|
||||
use: {
|
||||
browserName: 'webkit',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Desktop Firefox',
|
||||
use: {
|
||||
browserName: 'firefox',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Mobile Chrome',
|
||||
use: devices['Pixel 5'],
|
||||
},
|
||||
{
|
||||
name: 'Mobile Safari',
|
||||
use: devices['iPhone 12'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// playwright.config.ts
|
||||
import { PlaywrightTestConfig, devices } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
// Options shared for all projects.
|
||||
timeout: 30000,
|
||||
use: {
|
||||
ignoreHTTPSErrors: true,
|
||||
},
|
||||
|
||||
// Options specific to each project.
|
||||
projects: [
|
||||
{
|
||||
name: 'Desktop Chromium',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Desktop Safari',
|
||||
use: {
|
||||
browserName: 'webkit',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Desktop Firefox',
|
||||
use: {
|
||||
browserName: 'firefox',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Mobile Chrome',
|
||||
use: devices['Pixel 5'],
|
||||
},
|
||||
{
|
||||
name: 'Mobile Safari',
|
||||
use: devices['iPhone 12'],
|
||||
},
|
||||
],
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
## property: TestProject.expect
|
||||
- type: <[Object]>
|
||||
- `toMatchSnapshot` <[Object]>
|
||||
- `threshold` <[float]> Image matching threshold between zero (strict) and one (lax).
|
||||
|
||||
Configuration for the `expect` assertion library.
|
||||
|
||||
## property: TestProject.metadata
|
||||
- type: <[Object]>
|
||||
|
||||
Any JSON-serializable metadata that will be put directly to the test report.
|
||||
|
||||
## property: TestProject.name
|
||||
- type: <[string]>
|
||||
|
||||
Project name is visible in the report and during test execution.
|
||||
|
||||
## property: TestProject.outputDir
|
||||
- type: <[string]>
|
||||
|
||||
The output directory for files created during test execution. Defaults to `test-results`.
|
||||
|
||||
This directory is cleaned at the start. When running a test, a unique subdirectory inside the [`property: TestProject.outputDir`] is created, guaranteeing that test running in parallel do not conflict. This directory can be accessed by [`property: TestInfo.outputDir`] and [`method: TestInfo.outputPath`].
|
||||
|
||||
Here is an example that uses [`method: TestInfo.outputPath`] to create a temporary file.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const fs = require('fs');
|
||||
|
||||
test('example test', async ({}, testInfo) => {
|
||||
const file = testInfo.outputPath('temporary-file.txt');
|
||||
await fs.promises.writeFile(file, 'Put some data to the file', 'utf8');
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
import fs from 'fs';
|
||||
|
||||
test('example test', async ({}, testInfo) => {
|
||||
const file = testInfo.outputPath('temporary-file.txt');
|
||||
await fs.promises.writeFile(file, 'Put some data to the file', 'utf8');
|
||||
});
|
||||
```
|
||||
|
||||
## property: TestProject.repeatEach
|
||||
- type: <[int]>
|
||||
|
||||
The number of times to repeat each test, useful for debugging flaky tests.
|
||||
|
||||
## property: TestProject.retries
|
||||
- type: <[int]>
|
||||
|
||||
The maximum number of retry attempts given to failed tests. Learn more about [test retries](./test-retries.md).
|
||||
|
||||
## property: TestProject.testDir
|
||||
- type: <[string]>
|
||||
|
||||
Directory that will be recursively scanned for test files. Defaults to the directory of the configuration file.
|
||||
|
||||
Each project can use a different directory. Here is an example that runs smoke tests in three browsers and all other tests in stable Chrome browser.
|
||||
|
||||
```js js-flavor=js
|
||||
// playwright.config.js
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
projects: [
|
||||
{
|
||||
name: 'Smoke Chromium',
|
||||
testDir: './smoke-tests',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Smoke WebKit',
|
||||
testDir: './smoke-tests',
|
||||
use: {
|
||||
browserName: 'webkit',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Smoke Firefox',
|
||||
testDir: './smoke-tests',
|
||||
use: {
|
||||
browserName: 'firefox',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Chrome Stable',
|
||||
testDir: './',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
channel: 'chrome',
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
// playwright.config.ts
|
||||
import { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
projects: [
|
||||
{
|
||||
name: 'Smoke Chromium',
|
||||
testDir: './smoke-tests',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Smoke WebKit',
|
||||
testDir: './smoke-tests',
|
||||
use: {
|
||||
browserName: 'webkit',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Smoke Firefox',
|
||||
testDir: './smoke-tests',
|
||||
use: {
|
||||
browserName: 'firefox',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Chrome Stable',
|
||||
testDir: './',
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
channel: 'chrome',
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
export default config;
|
||||
```
|
||||
|
||||
|
||||
## property: TestProject.testIgnore
|
||||
- type: <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>>
|
||||
|
||||
Files matching one of these patterns are not executed as test files. Matching is performed against the absolute file path. Strings are treated as glob patterns.
|
||||
|
||||
For example, `'**/test-assets/**'` will ignore any files in the `test-assets` directory.
|
||||
|
||||
|
||||
## property: TestProject.testMatch
|
||||
- type: <[string]|[RegExp]|[Array]<[string]>|[Array]<[RegExp]>>
|
||||
|
||||
Only the files matching one of these patterns are executed as test files. Matching is performed against the absolute file path. Strings are treated as glob patterns.
|
||||
|
||||
By default, Playwright Test looks for files matching `.*(test|spec)\.(js|ts|mjs)`.
|
||||
|
||||
|
||||
## property: TestProject.timeout
|
||||
- type: <[int]>
|
||||
|
||||
Timeout for each test in milliseconds. Defaults to 30 seconds.
|
||||
|
||||
This is a base timeout for all tests. In addition, each test can configure its own timeout with [`method: Test.setTimeout`].
|
||||
|
||||
37
docs/src/test-api/class-workerinfo.md
Normal file
37
docs/src/test-api/class-workerinfo.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# class: WorkerInfo
|
||||
* langs: js
|
||||
|
||||
`WorkerInfo` contains information about the worker that is running tests. It is available to [`method: Test.beforeAll`] and [`method: Test.afterAll`] hooks and worker-scoped fixtures.
|
||||
|
||||
```js js-flavor=js
|
||||
const { test, expect } = require('@playwright/test');
|
||||
|
||||
test.beforeAll(async ({ browserName }, workerInfo) => {
|
||||
console.log(`Running ${browserName} in worker #${workerInfo.workerIndex}`);
|
||||
});
|
||||
```
|
||||
|
||||
```js js-flavor=ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeAll(async ({ browserName }, workerInfo) => {
|
||||
console.log(`Running ${browserName} in worker #${workerInfo.workerIndex}`);
|
||||
});
|
||||
```
|
||||
|
||||
## property: WorkerInfo.config
|
||||
- type: <[TestConfig]>
|
||||
|
||||
Processed configuration from the [configuration file](./test-configuration.md).
|
||||
|
||||
|
||||
## property: WorkerInfo.project
|
||||
- type: <[TestProject]>
|
||||
|
||||
Processed project configuration from the [configuration file](./test-configuration.md).
|
||||
|
||||
|
||||
## property: WorkerInfo.workerIndex
|
||||
- type: <[int]>
|
||||
|
||||
The unique index of the worker process that is running the test. Also available as `process.env.TEST_WORKER_INDEX`. Learn more about [parallelism and sharding](./test-parallel.md) with Playwright Test.
|
||||
|
|
@ -24,6 +24,8 @@ All the options are available in the [configuration file](./test-advanced.md). H
|
|||
|
||||
- `-g <grep>` or `--grep <grep>`: Only run tests matching this regular expression. For example, this will run `'should add to cart'` when passed `-g="add to cart"`.
|
||||
|
||||
- `--grep-invert <grep>`: Only run tests **not** matching this regular expression. The opposite of `--grep`.
|
||||
|
||||
- `--global-timeout <number>`: Total timeout for the whole test run in milliseconds. By default, there is no global timeout.
|
||||
|
||||
- `--list`: List all the tests, but do not run them.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ class ApiParser {
|
|||
let bodyParts = [];
|
||||
let paramsPath;
|
||||
for (const name of fs.readdirSync(apiDir)) {
|
||||
if (!name.endsWith('.md'))
|
||||
continue;
|
||||
if (name === 'params.md')
|
||||
paramsPath = path.join(apiDir, name);
|
||||
else
|
||||
|
|
@ -118,16 +120,25 @@ class ApiParser {
|
|||
* @param {MarkdownNode} spec
|
||||
*/
|
||||
parseArgument(spec) {
|
||||
const match = spec.text.match(/(param|option): ([^.]+)\.([^.]+)\.(.*)/);
|
||||
if(!match)
|
||||
const match = spec.text.match(/(param|option): (.*)/);
|
||||
if (!match)
|
||||
throw `Something went wrong with matching ${spec.text}`;
|
||||
const clazz = this.classes.get(match[2]);
|
||||
|
||||
// For "test.describe.only.title":
|
||||
// - className is "test"
|
||||
// - methodName is "describe.only"
|
||||
// - argument name is "title"
|
||||
const parts = match[2].split('.');
|
||||
const className = parts[0];
|
||||
const name = parts[parts.length - 1];
|
||||
const methodName = parts.slice(1, parts.length - 1).join('.');
|
||||
|
||||
const clazz = this.classes.get(className);
|
||||
if (!clazz)
|
||||
throw new Error('Invalid class ' + match[2]);
|
||||
const method = clazz.membersArray.find(m => m.kind === 'method' && m.alias === match[3]);
|
||||
throw new Error('Invalid class ' + className);
|
||||
const method = clazz.membersArray.find(m => m.kind === 'method' && m.alias === methodName);
|
||||
if (!method)
|
||||
throw new Error('Invalid method ' + match[2] + '.' + match[3]);
|
||||
const name = match[4];
|
||||
throw new Error(`Invalid method ${className}.${methodName} when parsing: ${match[0]}`);
|
||||
if (!name)
|
||||
throw new Error('Invalid member name ' + spec.text);
|
||||
if (match[1] === 'param') {
|
||||
|
|
@ -201,7 +212,7 @@ function parseVariable(line) {
|
|||
const name = match[1];
|
||||
const remainder = match[2];
|
||||
if (!remainder.startsWith('<'))
|
||||
throw new Error('Bad argument: ' + remainder);
|
||||
throw new Error(`Bad argument: "${name}" in "${line}"`);
|
||||
let depth = 0;
|
||||
for (let i = 0; i < remainder.length; ++i) {
|
||||
const c = remainder.charAt(i);
|
||||
|
|
|
|||
|
|
@ -37,10 +37,15 @@ run().catch(e => {
|
|||
});;
|
||||
|
||||
async function run() {
|
||||
const documentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api'));
|
||||
const apiDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api'));
|
||||
apiDocumentation.filterForLanguage('js');
|
||||
const testDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-api'));
|
||||
testDocumentation.filterForLanguage('js');
|
||||
const documentation = apiDocumentation.mergeWith(testDocumentation);
|
||||
documentation.mergeWith(testDocumentation);
|
||||
|
||||
// This validates member links.
|
||||
documentation.setLinkRenderer(() => undefined);
|
||||
documentation.filterForLanguage('js');
|
||||
|
||||
// Patch README.md
|
||||
const versions = await getBrowserVersions();
|
||||
|
|
@ -69,31 +74,32 @@ async function run() {
|
|||
{
|
||||
const devicesDescriptorsSourceFile = path.join(PROJECT_DIR, 'src', 'server', 'deviceDescriptorsSource.json')
|
||||
const devicesDescriptors = require(devicesDescriptorsSourceFile)
|
||||
for (const deviceName of Object.keys(devicesDescriptors))
|
||||
switch (devicesDescriptors[deviceName].defaultBrowserType) {
|
||||
case 'chromium':
|
||||
devicesDescriptors[deviceName].userAgent = devicesDescriptors[deviceName].userAgent.replace(
|
||||
/(.*Chrome\/)(.*?)( .*)/,
|
||||
`$1${versions.chromium}$3`
|
||||
).replace(
|
||||
/(.*Edg\/)(.*?)$/,
|
||||
`$1${versions.chromium}`
|
||||
)
|
||||
break;
|
||||
case 'firefox':
|
||||
devicesDescriptors[deviceName].userAgent = devicesDescriptors[deviceName].userAgent.replace(
|
||||
/^(.*Firefox\/)(.*?)( .*?)?$/,
|
||||
`$1${versions.firefox}$3`
|
||||
).replace(/(.*rv:)(.*)\)(.*?)/, `$1${versions.firefox}$3`)
|
||||
break;
|
||||
case 'webkit':
|
||||
devicesDescriptors[deviceName].userAgent = devicesDescriptors[deviceName].userAgent.replace(
|
||||
/(.*Version\/)(.*?)( .*)/,
|
||||
`$1${versions.webkit}$3`
|
||||
)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
for (const deviceName of Object.keys(devicesDescriptors)) {
|
||||
switch (devicesDescriptors[deviceName].defaultBrowserType) {
|
||||
case 'chromium':
|
||||
devicesDescriptors[deviceName].userAgent = devicesDescriptors[deviceName].userAgent.replace(
|
||||
/(.*Chrome\/)(.*?)( .*)/,
|
||||
`$1${versions.chromium}$3`
|
||||
).replace(
|
||||
/(.*Edg\/)(.*?)$/,
|
||||
`$1${versions.chromium}`
|
||||
)
|
||||
break;
|
||||
case 'firefox':
|
||||
devicesDescriptors[deviceName].userAgent = devicesDescriptors[deviceName].userAgent.replace(
|
||||
/^(.*Firefox\/)(.*?)( .*?)?$/,
|
||||
`$1${versions.firefox}$3`
|
||||
).replace(/(.*rv:)(.*)\)(.*?)/, `$1${versions.firefox}$3`)
|
||||
break;
|
||||
case 'webkit':
|
||||
devicesDescriptors[deviceName].userAgent = devicesDescriptors[deviceName].userAgent.replace(
|
||||
/(.*Version\/)(.*?)( .*)/,
|
||||
`$1${versions.webkit}$3`
|
||||
)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
writeAssumeNoop(devicesDescriptorsSourceFile, JSON.stringify(devicesDescriptors, null, 2), dirtyFiles);
|
||||
}
|
||||
|
|
@ -112,7 +118,7 @@ async function run() {
|
|||
{
|
||||
const srcClient = path.join(PROJECT_DIR, 'src', 'client');
|
||||
const sources = fs.readdirSync(srcClient).map(n => path.join(srcClient, n));
|
||||
const errors = missingDocs(documentation, sources, path.join(srcClient, 'api.ts'));
|
||||
const errors = missingDocs(apiDocumentation, sources, path.join(srcClient, 'api.ts'));
|
||||
if (errors.length) {
|
||||
console.log('============================');
|
||||
console.log('ERROR: missing documentation:');
|
||||
|
|
|
|||
|
|
@ -61,6 +61,14 @@ class Documentation {
|
|||
this.index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Documentation} documentation
|
||||
* @return {!Documentation}
|
||||
*/
|
||||
mergeWith(documentation) {
|
||||
return new Documentation([...this.classesArray, ...documentation.classesArray]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} errors
|
||||
*/
|
||||
|
|
@ -304,7 +312,7 @@ Documentation.Member = class {
|
|||
};
|
||||
this.async = false;
|
||||
this.alias = name;
|
||||
/**
|
||||
/**
|
||||
* Param is true and option false
|
||||
* @type {Boolean}
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue