chore: generate expect types (#13439)
This commit is contained in:
parent
1ee42a366d
commit
1e1df6395f
|
|
@ -8,9 +8,7 @@ expected values stored in files.
|
|||
expect(screenshot).toMatchSnapshot('landing-page.png');
|
||||
```
|
||||
|
||||
<!-- TOC -->
|
||||
|
||||
## method: ScreenshotAssertions.toMatchSnapshot
|
||||
## method: ScreenshotAssertions.toMatchSnapshot#1
|
||||
|
||||
Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory.
|
||||
|
||||
|
|
@ -18,11 +16,8 @@ Ensures that passed value, either a [string] or a [Buffer], matches the expected
|
|||
// Basic usage.
|
||||
expect(await page.screenshot()).toMatchSnapshot('landing-page.png');
|
||||
|
||||
// Basic usage and the file name is derived from the test name.
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
|
||||
// Pass options to customize the snapshot comparison and have a generated name.
|
||||
expect(await page.screenshot()).toMatchSnapshot({
|
||||
expect(await page.screenshot()).toMatchSnapshot('landing-page.png', {
|
||||
maxDiffPixels: 27, // allow no more than 27 different pixels.
|
||||
});
|
||||
|
||||
|
|
@ -36,13 +31,49 @@ expect(await page.screenshot()).toMatchSnapshot(['landing', 'step3.png']);
|
|||
|
||||
Learn more about [visual comparisons](./test-snapshots.md).
|
||||
|
||||
### param: ScreenshotAssertions.toMatchSnapshot.nameOrOptions
|
||||
- `nameOrOptions` <[string]|[Array]<[string]>|[Object]>
|
||||
### param: ScreenshotAssertions.toMatchSnapshot#1.name
|
||||
- `name` <[string]|[Array]<[string]>>
|
||||
|
||||
Optional snapshot name. If not passed, the test name and ordinals are used when called multiple times. Also passing the options here is supported.
|
||||
Snapshot name.
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#1.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#1.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#1.threshold = %%-assertions-threshold-%%
|
||||
|
||||
|
||||
|
||||
## method: ScreenshotAssertions.toMatchSnapshot#2
|
||||
|
||||
Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory.
|
||||
|
||||
```js
|
||||
// Basic usage and the file name is derived from the test name.
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
|
||||
// Pass options to customize the snapshot comparison and have a generated name.
|
||||
expect(await page.screenshot()).toMatchSnapshot({
|
||||
maxDiffPixels: 27, // allow no more than 27 different pixels.
|
||||
});
|
||||
|
||||
// Configure image matching threshold and snapshot name.
|
||||
expect(await page.screenshot()).toMatchSnapshot({
|
||||
name: 'landing-page.png',
|
||||
threshold: 0.3,
|
||||
});
|
||||
```
|
||||
|
||||
Learn more about [visual comparisons](./test-snapshots.md).
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#2.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#2.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#2.name
|
||||
- `name` <[string]|[Array]<[string]>>
|
||||
|
||||
Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot#2.threshold = %%-assertions-threshold-%%
|
||||
|
||||
### option: ScreenshotAssertions.toMatchSnapshot.threshold = %%-assertions-threshold-%%
|
||||
|
|
|
|||
697
packages/playwright-test/types/test.d.ts
vendored
697
packages/playwright-test/types/test.d.ts
vendored
|
|
@ -15,10 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials } from 'playwright-core';
|
||||
import type { Expect } from './testExpect';
|
||||
|
||||
export type { Expect } from './testExpect';
|
||||
import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse } from 'playwright-core';
|
||||
|
||||
export type ReporterDescription =
|
||||
['dot'] |
|
||||
|
|
@ -2802,7 +2799,7 @@ export interface PlaywrightTestOptions {
|
|||
* [fixtures.page](https://playwright.dev/docs/api/class-fixtures#fixtures-page).
|
||||
*/
|
||||
export interface PlaywrightWorkerArgs {
|
||||
playwright: typeof import('..');
|
||||
playwright: typeof import('playwright-core');
|
||||
/**
|
||||
* [Browser] instance is shared between all tests in the [same worker](https://playwright.dev/docs/test-parallel) - this makes testing efficient.
|
||||
* However, each test runs in an isolated [BrowserContext] and gets a fresh environment.
|
||||
|
|
@ -2891,6 +2888,121 @@ export interface PlaywrightTestArgs {
|
|||
export type PlaywrightTestProject<TestArgs = {}, WorkerArgs = {}> = Project<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>;
|
||||
export type PlaywrightTestConfig<TestArgs = {}, WorkerArgs = {}> = Config<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>;
|
||||
|
||||
import type * as expectType from 'expect';
|
||||
|
||||
type AsymmetricMatcher = Record<string, any>;
|
||||
|
||||
type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;
|
||||
type ExtraMatchers<T, Type, Matchers> = T extends Type ? Matchers : IfAny<T, Matchers, {}>;
|
||||
|
||||
type BaseMatchers<R, T> = Pick<expectType.Matchers<R>, SupportedExpectProperties> & PlaywrightTest.Matchers<R, T>;
|
||||
|
||||
type MakeMatchers<R, T> = BaseMatchers<R, T> & {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: MakeMatchers<R, T>;
|
||||
/**
|
||||
* Use resolves to unwrap the value of a fulfilled promise so any other
|
||||
* matcher can be chained. If the promise is rejected the assertion fails.
|
||||
*/
|
||||
resolves: MakeMatchers<Promise<R>, Awaited<T>>;
|
||||
/**
|
||||
* Unwraps the reason of a rejected promise so any other matcher can be chained.
|
||||
* If the promise is fulfilled the assertion fails.
|
||||
*/
|
||||
rejects: MakeMatchers<Promise<R>, Awaited<T>>;
|
||||
} & ScreenshotAssertions &
|
||||
ExtraMatchers<T, Page, PageAssertions> &
|
||||
ExtraMatchers<T, Locator, LocatorAssertions> &
|
||||
ExtraMatchers<T, APIResponse, APIResponseAssertions>;
|
||||
|
||||
export declare type Expect = {
|
||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T>;
|
||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T>;
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number }) => BaseMatchers<Promise<void>, T> & {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: BaseMatchers<Promise<void>, T>;
|
||||
};
|
||||
|
||||
extend(arg0: any): void;
|
||||
getState(): expectType.MatcherState;
|
||||
setState(state: Partial<expectType.MatcherState>): void;
|
||||
any(expectedObject: any): AsymmetricMatcher;
|
||||
anything(): AsymmetricMatcher;
|
||||
arrayContaining(sample: Array<unknown>): AsymmetricMatcher;
|
||||
objectContaining(sample: Record<string, unknown>): AsymmetricMatcher;
|
||||
stringContaining(expected: string): AsymmetricMatcher;
|
||||
stringMatching(expected: string | RegExp): AsymmetricMatcher;
|
||||
/**
|
||||
* Removed following methods because they rely on a test-runner integration from Jest which we don't support:
|
||||
* - assertions()
|
||||
* - extractExpectedAssertionsErrors()
|
||||
* – hasAssertions()
|
||||
*/
|
||||
};
|
||||
|
||||
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;
|
||||
|
||||
/**
|
||||
* Removed methods require the jest.fn() integration from Jest to spy on function calls which we don't support:
|
||||
* - lastCalledWith()
|
||||
* - lastReturnedWith()
|
||||
* - nthCalledWith()
|
||||
* - nthReturnedWith()
|
||||
* - toBeCalled()
|
||||
* - toBeCalledTimes()
|
||||
* - toBeCalledWith()
|
||||
* - toHaveBeenCalled()
|
||||
* - toHaveBeenCalledTimes()
|
||||
* - toHaveBeenCalledWith()
|
||||
* - toHaveBeenLastCalledWith()
|
||||
* - toHaveBeenNthCalledWith()
|
||||
* - toHaveLastReturnedWith()
|
||||
* - toHaveNthReturnedWith()
|
||||
* - toHaveReturned()
|
||||
* - toHaveReturnedTimes()
|
||||
* - toHaveReturnedWith()
|
||||
* - toReturn()
|
||||
* - toReturnTimes()
|
||||
* - toReturnWith()
|
||||
* - toThrowErrorMatchingSnapshot()
|
||||
* - toThrowErrorMatchingInlineSnapshot()
|
||||
*/
|
||||
type SupportedExpectProperties =
|
||||
'toBe' |
|
||||
'toBeCloseTo' |
|
||||
'toBeDefined' |
|
||||
'toBeFalsy' |
|
||||
'toBeGreaterThan' |
|
||||
'toBeGreaterThanOrEqual' |
|
||||
'toBeInstanceOf' |
|
||||
'toBeLessThan' |
|
||||
'toBeLessThanOrEqual' |
|
||||
'toBeNaN' |
|
||||
'toBeNull' |
|
||||
'toBeTruthy' |
|
||||
'toBeUndefined' |
|
||||
'toContain' |
|
||||
'toContainEqual' |
|
||||
'toEqual' |
|
||||
'toHaveLength' |
|
||||
'toHaveProperty' |
|
||||
'toMatch' |
|
||||
'toMatchObject' |
|
||||
'toStrictEqual' |
|
||||
'toThrow' |
|
||||
'toThrowError'
|
||||
|
||||
declare global {
|
||||
export namespace PlaywrightTest {
|
||||
export interface Matchers<R, T = unknown> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These tests are executed in Playwright environment that launches the browser
|
||||
* and provides a fresh page to each test.
|
||||
|
|
@ -2905,6 +3017,581 @@ export const expect: Expect;
|
|||
export {};
|
||||
|
||||
|
||||
/**
|
||||
* The [APIResponseAssertions] class provides assertion methods that can be used to make assertions about the [APIResponse]
|
||||
* in the tests. A new instance of [APIResponseAssertions] is created by calling
|
||||
* [expect(response)](https://playwright.dev/docs/api/class-playwrightassertions#playwright-assertions-expect-api-response):
|
||||
*
|
||||
* ```js
|
||||
* import { test, expect } from '@playwright/test';
|
||||
*
|
||||
* test('navigates to login', async ({ page }) => {
|
||||
* // ...
|
||||
* const response = await page.request.get('https://playwright.dev');
|
||||
* await expect(response).toBeOK();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
interface APIResponseAssertions {
|
||||
/**
|
||||
* Makes the assertion check for the opposite condition. For example, this code tests that the response status is not
|
||||
* successful:
|
||||
*
|
||||
* ```js
|
||||
* await expect(response).not.toBeOK();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
not: APIResponseAssertions;
|
||||
|
||||
/**
|
||||
* Ensures the response status code is within [200..299] range.
|
||||
*
|
||||
* ```js
|
||||
* await expect(response).toBeOK();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
toBeOK(): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The [LocatorAssertions] class provides assertion methods that can be used to make assertions about the [Locator] state
|
||||
* in the tests. A new instance of [LocatorAssertions] is created by calling
|
||||
* [expect(locator)](https://playwright.dev/docs/api/class-playwrightassertions#playwright-assertions-expect-locator):
|
||||
*
|
||||
* ```js
|
||||
* import { test, expect } from '@playwright/test';
|
||||
*
|
||||
* test('status becomes submitted', async ({ page }) => {
|
||||
* // ...
|
||||
* await page.click('#submit-button');
|
||||
* await expect(page.locator('.status')).toHaveText('Submitted');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
interface LocatorAssertions {
|
||||
/**
|
||||
* Makes the assertion check for the opposite condition. For example, this code tests that the Locator doesn't contain text
|
||||
* `"error"`:
|
||||
*
|
||||
* ```js
|
||||
* await expect(locator).not.toContainText('error');
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
not: LocatorAssertions;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to a checked input.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('.subscribe');
|
||||
* await expect(locator).toBeChecked();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeChecked(options?: {
|
||||
checked?: boolean;
|
||||
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to a disabled element.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('button.submit');
|
||||
* await expect(locator).toBeDisabled();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeDisabled(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an editable element.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('input');
|
||||
* await expect(locator).toBeEditable();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeEditable(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an empty editable element or to a DOM node that has no text.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('div.warning');
|
||||
* await expect(locator).toBeEmpty();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeEmpty(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an enabled element.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('button.submit');
|
||||
* await expect(locator).toBeEnabled();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeEnabled(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to a focused DOM node.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('input');
|
||||
* await expect(locator).toBeFocused();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeFocused(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to a hidden DOM node, which is the opposite of [visible](https://playwright.dev/docs/api/actionability#visible).
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('.my-element');
|
||||
* await expect(locator).toBeHidden();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeHidden(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to a [visible](https://playwright.dev/docs/api/actionability#visible) DOM node.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('.my-element');
|
||||
* await expect(locator).toBeVisible();
|
||||
* ```
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
toBeVisible(options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element that contains the given text. You can use regular expressions for the value
|
||||
* as well.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('.title');
|
||||
* await expect(locator).toContainText('substring');
|
||||
* await expect(locator).toContainText(/\d messages/);
|
||||
* ```
|
||||
*
|
||||
* Note that if array is passed as an expected value, entire lists of elements can be asserted:
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('list > .list-item');
|
||||
* await expect(locator).toContainText(['Text 1', 'Text 4', 'Text 5']);
|
||||
* ```
|
||||
*
|
||||
* @param expected Expected substring or RegExp or a list of those.
|
||||
* @param options
|
||||
*/
|
||||
toContainText(expected: string|RegExp|Array<string|RegExp>, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
|
||||
/**
|
||||
* Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text.
|
||||
*/
|
||||
useInnerText?: boolean;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element with given attribute.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('input');
|
||||
* await expect(locator).toHaveAttribute('type', 'text');
|
||||
* ```
|
||||
*
|
||||
* @param name Attribute name.
|
||||
* @param value Expected attribute value.
|
||||
* @param options
|
||||
*/
|
||||
toHaveAttribute(name: string, value: string|RegExp, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element with given CSS class.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('#component');
|
||||
* await expect(locator).toHaveClass(/selected/);
|
||||
* ```
|
||||
*
|
||||
* Note that if array is passed as an expected value, entire lists of elements can be asserted:
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('list > .component');
|
||||
* await expect(locator).toHaveClass(['component', 'component selected', 'component']);
|
||||
* ```
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
* @param options
|
||||
*/
|
||||
toHaveClass(expected: string|RegExp|Array<string|RegExp>, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] resolves to an exact number of DOM nodes.
|
||||
*
|
||||
* ```js
|
||||
* const list = page.locator('list > .component');
|
||||
* await expect(list).toHaveCount(3);
|
||||
* ```
|
||||
*
|
||||
* @param count Expected count.
|
||||
* @param options
|
||||
*/
|
||||
toHaveCount(count: number, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] resolves to an element with the given computed CSS style.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('button');
|
||||
* await expect(locator).toHaveCSS('display', 'flex');
|
||||
* ```
|
||||
*
|
||||
* @param name CSS property name.
|
||||
* @param value CSS property value.
|
||||
* @param options
|
||||
*/
|
||||
toHaveCSS(name: string, value: string|RegExp, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element with the given DOM Node ID.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('input');
|
||||
* await expect(locator).toHaveId('lastname');
|
||||
* ```
|
||||
*
|
||||
* @param id Element id.
|
||||
* @param options
|
||||
*/
|
||||
toHaveId(id: string|RegExp, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element with given JavaScript property. Note that this property can be of a primitive
|
||||
* type as well as a plain serializable JavaScript object.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('.component');
|
||||
* await expect(locator).toHaveJSProperty('loaded', true);
|
||||
* ```
|
||||
*
|
||||
* @param name Property name.
|
||||
* @param value Property value.
|
||||
* @param options
|
||||
*/
|
||||
toHaveJSProperty(name: string, value: any, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element with the given text. You can use regular expressions for the value as well.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('.title');
|
||||
* await expect(locator).toHaveText(/Welcome, Test User/);
|
||||
* await expect(locator).toHaveText(/Welcome, .*\/);
|
||||
* ```
|
||||
*
|
||||
* Note that if array is passed as an expected value, entire lists of elements can be asserted:
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('list > .component');
|
||||
* await expect(locator).toHaveText(['Text 1', 'Text 2', 'Text 3']);
|
||||
* ```
|
||||
*
|
||||
* @param expected Expected substring or RegExp or a list of those.
|
||||
* @param options
|
||||
*/
|
||||
toHaveText(expected: string|RegExp|Array<string|RegExp>, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
|
||||
/**
|
||||
* Whether to use `element.innerText` instead of `element.textContent` when retrieving DOM node text.
|
||||
*/
|
||||
useInnerText?: boolean;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the [Locator] points to an element with the given input value. You can use regular expressions for the value as
|
||||
* well.
|
||||
*
|
||||
* ```js
|
||||
* const locator = page.locator('input[type=number]');
|
||||
* await expect(locator).toHaveValue(/[0-9]/);
|
||||
* ```
|
||||
*
|
||||
* @param value Expected value.
|
||||
* @param options
|
||||
*/
|
||||
toHaveValue(value: string|RegExp, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The [PageAssertions] class provides assertion methods that can be used to make assertions about the [Page] state in the
|
||||
* tests. A new instance of [PageAssertions] is created by calling
|
||||
* [expect(page)](https://playwright.dev/docs/api/class-playwrightassertions#playwright-assertions-expect-page):
|
||||
*
|
||||
* ```js
|
||||
* import { test, expect } from '@playwright/test';
|
||||
*
|
||||
* test('navigates to login', async ({ page }) => {
|
||||
* // ...
|
||||
* await page.click('#login');
|
||||
* await expect(page).toHaveURL(/.*\/login/);
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
interface PageAssertions {
|
||||
/**
|
||||
* Makes the assertion check for the opposite condition. For example, this code tests that the page URL doesn't contain
|
||||
* `"error"`:
|
||||
*
|
||||
* ```js
|
||||
* await expect(page).not.toHaveURL('error');
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
not: PageAssertions;
|
||||
|
||||
/**
|
||||
* Ensures the page has the given title.
|
||||
*
|
||||
* ```js
|
||||
* await expect(page).toHaveTitle(/.*checkout/);
|
||||
* ```
|
||||
*
|
||||
* @param titleOrRegExp Expected title or RegExp.
|
||||
* @param options
|
||||
*/
|
||||
toHaveTitle(titleOrRegExp: string|RegExp, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Ensures the page is navigated to the given URL.
|
||||
*
|
||||
* ```js
|
||||
* await expect(page).toHaveURL(/.*checkout/);
|
||||
* ```
|
||||
*
|
||||
* @param urlOrRegExp Expected substring or RegExp.
|
||||
* @param options
|
||||
*/
|
||||
toHaveURL(urlOrRegExp: string|RegExp, options?: {
|
||||
/**
|
||||
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Playwright provides methods for comparing page and element screenshots with expected values stored in files.
|
||||
*
|
||||
* ```js
|
||||
* expect(screenshot).toMatchSnapshot('landing-page.png');
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
interface ScreenshotAssertions {
|
||||
/**
|
||||
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots
|
||||
* directory.
|
||||
*
|
||||
* ```js
|
||||
* // Basic usage.
|
||||
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png');
|
||||
*
|
||||
* // Pass options to customize the snapshot comparison and have a generated name.
|
||||
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png', {
|
||||
* maxDiffPixels: 27, // allow no more than 27 different pixels.
|
||||
* });
|
||||
*
|
||||
* // Configure image matching threshold.
|
||||
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png', { threshold: 0.3 });
|
||||
*
|
||||
* // Bring some structure to your snapshot files by passing file path segments.
|
||||
* expect(await page.screenshot()).toMatchSnapshot(['landing', 'step2.png']);
|
||||
* expect(await page.screenshot()).toMatchSnapshot(['landing', 'step3.png']);
|
||||
* ```
|
||||
*
|
||||
* Learn more about [visual comparisons](https://playwright.dev/docs/api/test-snapshots).
|
||||
* @param name Snapshot name.
|
||||
* @param options
|
||||
*/
|
||||
toMatchSnapshot(name: string|Array<string>, options?: {
|
||||
/**
|
||||
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is
|
||||
* configurable with `TestConfig.expect`. Unset by default.
|
||||
*/
|
||||
maxDiffPixelRatio?: number;
|
||||
|
||||
/**
|
||||
* An acceptable amount of pixels that could be different, default is configurable with `TestConfig.expect`. Default is
|
||||
* configurable with `TestConfig.expect`. Unset by default.
|
||||
*/
|
||||
maxDiffPixels?: number;
|
||||
|
||||
/**
|
||||
* An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the same
|
||||
* pixel in compared images, between zero (strict) and one (lax), default is configurable with `TestConfig.expect`.
|
||||
* Defaults to `0.2`.
|
||||
*/
|
||||
threshold?: number;
|
||||
}): void;
|
||||
|
||||
/**
|
||||
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots
|
||||
* directory.
|
||||
*
|
||||
* ```js
|
||||
* // Basic usage and the file name is derived from the test name.
|
||||
* expect(await page.screenshot()).toMatchSnapshot();
|
||||
*
|
||||
* // Pass options to customize the snapshot comparison and have a generated name.
|
||||
* expect(await page.screenshot()).toMatchSnapshot({
|
||||
* maxDiffPixels: 27, // allow no more than 27 different pixels.
|
||||
* });
|
||||
*
|
||||
* // Configure image matching threshold and snapshot name.
|
||||
* expect(await page.screenshot()).toMatchSnapshot({
|
||||
* name: 'landing-page.png',
|
||||
* threshold: 0.3,
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Learn more about [visual comparisons](https://playwright.dev/docs/api/test-snapshots).
|
||||
* @param options
|
||||
*/
|
||||
toMatchSnapshot(options?: {
|
||||
/**
|
||||
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is
|
||||
* configurable with `TestConfig.expect`. Unset by default.
|
||||
*/
|
||||
maxDiffPixelRatio?: number;
|
||||
|
||||
/**
|
||||
* An acceptable amount of pixels that could be different, default is configurable with `TestConfig.expect`. Default is
|
||||
* configurable with `TestConfig.expect`. Unset by default.
|
||||
*/
|
||||
maxDiffPixels?: number;
|
||||
|
||||
/**
|
||||
* Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
||||
*/
|
||||
name?: string|Array<string>;
|
||||
|
||||
/**
|
||||
* An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the same
|
||||
* pixel in compared images, between zero (strict) and one (lax), default is configurable with `TestConfig.expect`.
|
||||
* Defaults to `0.2`.
|
||||
*/
|
||||
threshold?: number;
|
||||
}): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about an error thrown during test execution.
|
||||
*/
|
||||
|
|
|
|||
246
packages/playwright-test/types/testExpect.d.ts
vendored
246
packages/playwright-test/types/testExpect.d.ts
vendored
|
|
@ -1,246 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type * as expect from 'expect';
|
||||
import type { Page, Locator, APIResponse, PageScreenshotOptions, LocatorScreenshotOptions } from 'playwright-core';
|
||||
|
||||
export declare type AsymmetricMatcher = Record<string, any>;
|
||||
|
||||
type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;
|
||||
type ExtraMatchers<T, Type, Matchers> = T extends Type ? Matchers : IfAny<T, Matchers, {}>;
|
||||
|
||||
type MakeMatchers<R, T> = PlaywrightTest.Matchers<R, T> &
|
||||
ExtraMatchers<T, Page, PageMatchers> &
|
||||
ExtraMatchers<T, Locator, LocatorMatchers> &
|
||||
ExtraMatchers<T, APIResponse, APIResponseMatchers>;
|
||||
|
||||
export declare type Expect = {
|
||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T>;
|
||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T>;
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number }) => Omit<PlaywrightTest.Matchers<Promise<void>, T>, 'rejects' | 'resolves'>;
|
||||
|
||||
extend(arg0: any): void;
|
||||
getState(): expect.MatcherState;
|
||||
setState(state: Partial<expect.MatcherState>): void;
|
||||
any(expectedObject: any): AsymmetricMatcher;
|
||||
anything(): AsymmetricMatcher;
|
||||
arrayContaining(sample: Array<unknown>): AsymmetricMatcher;
|
||||
objectContaining(sample: Record<string, unknown>): AsymmetricMatcher;
|
||||
stringContaining(expected: string): AsymmetricMatcher;
|
||||
stringMatching(expected: string | RegExp): AsymmetricMatcher;
|
||||
/**
|
||||
* Removed following methods because they rely on a test-runner integration from Jest which we don't support:
|
||||
* - assertions()
|
||||
* - extractExpectedAssertionsErrors()
|
||||
* – hasAssertions()
|
||||
*/
|
||||
};
|
||||
|
||||
type ImageComparatorOptions = {
|
||||
threshold?: number,
|
||||
maxDiffPixels?: number,
|
||||
maxDiffPixelRatio?: number,
|
||||
};
|
||||
|
||||
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;
|
||||
|
||||
/**
|
||||
* Removed methods require the jest.fn() integration from Jest to spy on function calls which we don't support:
|
||||
* - lastCalledWith()
|
||||
* - lastReturnedWith()
|
||||
* - nthCalledWith()
|
||||
* - nthReturnedWith()
|
||||
* - toBeCalled()
|
||||
* - toBeCalledTimes()
|
||||
* - toBeCalledWith()
|
||||
* - toHaveBeenCalled()
|
||||
* - toHaveBeenCalledTimes()
|
||||
* - toHaveBeenCalledWith()
|
||||
* - toHaveBeenLastCalledWith()
|
||||
* - toHaveBeenNthCalledWith()
|
||||
* - toHaveLastReturnedWith()
|
||||
* - toHaveNthReturnedWith()
|
||||
* - toHaveReturned()
|
||||
* - toHaveReturnedTimes()
|
||||
* - toHaveReturnedWith()
|
||||
* - toReturn()
|
||||
* - toReturnTimes()
|
||||
* - toReturnWith()
|
||||
* - toThrowErrorMatchingSnapshot()
|
||||
* - toThrowErrorMatchingInlineSnapshot()
|
||||
*/
|
||||
type SupportedExpectProperties =
|
||||
'toBe' |
|
||||
'toBeCloseTo' |
|
||||
'toBeDefined' |
|
||||
'toBeFalsy' |
|
||||
'toBeGreaterThan' |
|
||||
'toBeGreaterThanOrEqual' |
|
||||
'toBeInstanceOf' |
|
||||
'toBeLessThan' |
|
||||
'toBeLessThanOrEqual' |
|
||||
'toBeNaN' |
|
||||
'toBeNull' |
|
||||
'toBeTruthy' |
|
||||
'toBeUndefined' |
|
||||
'toContain' |
|
||||
'toContainEqual' |
|
||||
'toEqual' |
|
||||
'toHaveLength' |
|
||||
'toHaveProperty' |
|
||||
'toMatch' |
|
||||
'toMatchObject' |
|
||||
'toStrictEqual' |
|
||||
'toThrow' |
|
||||
'toThrowError'
|
||||
|
||||
declare global {
|
||||
export namespace PlaywrightTest {
|
||||
export interface Matchers<R, T = unknown> extends Pick<expect.Matchers<R>, SupportedExpectProperties> {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: MakeMatchers<R, T>;
|
||||
/**
|
||||
* Use resolves to unwrap the value of a fulfilled promise so any other
|
||||
* matcher can be chained. If the promise is rejected the assertion fails.
|
||||
*/
|
||||
resolves: MakeMatchers<Promise<R>, Awaited<T>>;
|
||||
/**
|
||||
* Unwraps the reason of a rejected promise so any other matcher can be chained.
|
||||
* If the promise is fulfilled the assertion fails.
|
||||
*/
|
||||
rejects: MakeMatchers<Promise<R>, Awaited<T>>;
|
||||
/**
|
||||
* Match snapshot
|
||||
*/
|
||||
toMatchSnapshot(options?: ImageComparatorOptions & {
|
||||
name?: string | string[],
|
||||
}): R;
|
||||
/**
|
||||
* Match snapshot
|
||||
*/
|
||||
toMatchSnapshot(name: string | string[], options?: ImageComparatorOptions): R;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface LocatorMatchers {
|
||||
/**
|
||||
* Asserts input is checked (or unchecked if { checked: false } is passed).
|
||||
*/
|
||||
toBeChecked(options?: { checked?: boolean, timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts input is disabled.
|
||||
*/
|
||||
toBeDisabled(options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts input is editable.
|
||||
*/
|
||||
toBeEditable(options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts given DOM node or input has no text content or no input value.
|
||||
*/
|
||||
toBeEmpty(options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts input is enabled.
|
||||
*/
|
||||
toBeEnabled(options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts given DOM is a focused (active) in document.
|
||||
*/
|
||||
toBeFocused(options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts given DOM node is hidden or detached from DOM.
|
||||
*/
|
||||
toBeHidden(options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts element's text content matches given pattern or contains given substring.
|
||||
*/
|
||||
toContainText(expected: string | RegExp | (string | RegExp)[], options?: { timeout?: number, useInnerText?: boolean }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts element's attributes `name` matches expected value.
|
||||
*/
|
||||
toHaveAttribute(name: string, expected: string | RegExp, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts that DOM node has a given CSS class.
|
||||
*/
|
||||
toHaveClass(className: string | RegExp | (string | RegExp)[], options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts number of DOM nodes matching given locator.
|
||||
*/
|
||||
toHaveCount(expected: number, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts element's computed CSS property `name` matches expected value.
|
||||
*/
|
||||
toHaveCSS(name: string, expected: string | RegExp, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts element's `id` attribute matches expected value.
|
||||
*/
|
||||
toHaveId(expected: string | RegExp, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts JavaScript object that corresponds to the Node has a property with given value.
|
||||
*/
|
||||
toHaveJSProperty(name: string, value: any, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts element's text content.
|
||||
*/
|
||||
toHaveText(expected: string | RegExp | (string | RegExp)[], options?: { timeout?: number, useInnerText?: boolean }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts input element's value.
|
||||
*/
|
||||
toHaveValue(expected: string | RegExp, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts given DOM node visible on the screen.
|
||||
*/
|
||||
toBeVisible(options?: { timeout?: number }): Promise<void>;
|
||||
}
|
||||
interface PageMatchers {
|
||||
/**
|
||||
* Asserts page's title.
|
||||
*/
|
||||
toHaveTitle(expected: string | RegExp, options?: { timeout?: number }): Promise<void>;
|
||||
|
||||
/**
|
||||
* Asserts page's URL.
|
||||
*/
|
||||
toHaveURL(expected: string | RegExp, options?: { timeout?: number }): Promise<void>;
|
||||
}
|
||||
|
||||
interface APIResponseMatchers {
|
||||
/**
|
||||
* Asserts given APIResponse's status is between 200 and 299.
|
||||
*/
|
||||
toBeOK(): Promise<void>;
|
||||
}
|
||||
|
||||
export { };
|
||||
|
|
@ -45,7 +45,7 @@ test('should compile', async ({ runTSC }) => {
|
|||
const result = await runTSC({
|
||||
'a.spec.ts': `
|
||||
const { test } = pwt;
|
||||
test('should poll sync predicate', () => {
|
||||
test('should poll sync predicate', async ({ page }) => {
|
||||
let i = 0;
|
||||
test.expect.poll(() => ++i).toBe(3);
|
||||
test.expect.poll(() => ++i, 'message').toBe(3);
|
||||
|
|
@ -57,6 +57,11 @@ test('should compile', async ({ runTSC }) => {
|
|||
return ++i;
|
||||
}).toBe(3);
|
||||
test.expect.poll(() => Promise.resolve(++i)).toBe(3);
|
||||
|
||||
// @ts-expect-error
|
||||
await test.expect.poll(() => page.locator('foo')).toBeEnabled();
|
||||
// @ts-expect-error
|
||||
await test.expect.poll(() => page.locator('foo')).not.toBeEnabled();
|
||||
});
|
||||
`
|
||||
});
|
||||
|
|
|
|||
|
|
@ -212,9 +212,12 @@ test('should propose only the relevant matchers when custom expect matcher class
|
|||
const { test } = pwt;
|
||||
test('custom matchers', async ({ page }) => {
|
||||
await test.expect(page).toHaveURL('https://example.com');
|
||||
await test.expect(page).not.toHaveURL('https://example.com');
|
||||
await test.expect(page).toBe(true);
|
||||
// @ts-expect-error
|
||||
await test.expect(page).toBeEnabled();
|
||||
// @ts-expect-error
|
||||
await test.expect(page).not.toBeEnabled();
|
||||
|
||||
await test.expect(page.locator('foo')).toBeEnabled();
|
||||
await test.expect(page.locator('foo')).toBe(true);
|
||||
|
|
|
|||
|
|
@ -34,9 +34,10 @@ class TypesGenerator {
|
|||
/**
|
||||
* @param {{
|
||||
* documentation: Documentation,
|
||||
* classNames: Set<string>,
|
||||
* overridesToDocsClassMapping: Map<string, string>,
|
||||
* ignoreMissing: Set<string>,
|
||||
* classNamesToGenerate: Set<string>,
|
||||
* overridesToDocsClassMapping?: Map<string, string>,
|
||||
* ignoreMissing?: Set<string>,
|
||||
* doNotExportClassNames?: Set<string>,
|
||||
* }} options
|
||||
*/
|
||||
constructor(options) {
|
||||
|
|
@ -45,9 +46,10 @@ class TypesGenerator {
|
|||
/** @type {Set<string>} */
|
||||
this.handledMethods = new Set();
|
||||
this.documentation = options.documentation;
|
||||
this.classNames = options.classNames;
|
||||
this.overridesToDocsClassMapping = options.overridesToDocsClassMapping;
|
||||
this.ignoreMissing = options.ignoreMissing;
|
||||
this.classNamesToGenerate = options.classNamesToGenerate;
|
||||
this.overridesToDocsClassMapping = options.overridesToDocsClassMapping || new Map();
|
||||
this.ignoreMissing = options.ignoreMissing || new Set();
|
||||
this.doNotExportClassNames = options.doNotExportClassNames || new Set();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -61,7 +63,7 @@ class TypesGenerator {
|
|||
const createMarkdownLink = (member, text) => {
|
||||
const className = toKebabCase(member.clazz.name);
|
||||
const memberName = toKebabCase(member.name);
|
||||
let hash = null
|
||||
let hash = null;
|
||||
if (member.kind === 'property' || member.kind === 'method')
|
||||
hash = `${className}-${memberName}`.toLowerCase();
|
||||
else if (member.kind === 'event')
|
||||
|
|
@ -76,12 +78,13 @@ class TypesGenerator {
|
|||
return `\`${option}\``;
|
||||
if (clazz)
|
||||
return `[${clazz.name}]`;
|
||||
const className = member.clazz.varName === 'playwrightAssertions' ? '' : member.clazz.varName + '.';
|
||||
if (member.kind === 'method')
|
||||
return createMarkdownLink(member, `${member.clazz.varName}.${member.alias}(${this.renderJSSignature(member.argsArray)})`);
|
||||
return createMarkdownLink(member, `${className}${member.alias}(${this.renderJSSignature(member.argsArray)})`);
|
||||
if (member.kind === 'event')
|
||||
return createMarkdownLink(member, `${member.clazz.varName}.on('${member.alias.toLowerCase()}')`);
|
||||
return createMarkdownLink(member, `${className}on('${member.alias.toLowerCase()}')`);
|
||||
if (member.kind === 'property')
|
||||
return createMarkdownLink(member, `${member.clazz.varName}.${member.alias}`);
|
||||
return createMarkdownLink(member, `${className}${member.alias}`);
|
||||
throw new Error('Unknown member kind ' + member.kind);
|
||||
});
|
||||
this.documentation.generateSourceCodeComments();
|
||||
|
|
@ -113,13 +116,13 @@ class TypesGenerator {
|
|||
return this.memberJSDOC(method, ' ').trimLeft();
|
||||
}, (className) => {
|
||||
const docClass = this.docClassForName(className);
|
||||
if (!docClass || !this.classNames.has(docClass.name))
|
||||
if (!docClass || !this.classNamesToGenerate.has(docClass.name))
|
||||
return '';
|
||||
return this.classBody(docClass);
|
||||
});
|
||||
|
||||
const classes = this.documentation.classesArray
|
||||
.filter(cls => this.classNames.has(cls.name))
|
||||
.filter(cls => this.classNamesToGenerate.has(cls.name))
|
||||
.filter(cls => !handledClasses.has(cls.name));
|
||||
{
|
||||
const playwright = this.documentation.classesArray.find(c => c.name === 'Playwright');
|
||||
|
|
@ -152,7 +155,7 @@ class TypesGenerator {
|
|||
* @param {string} name
|
||||
*/
|
||||
docClassForName(name) {
|
||||
const mappedName = (this.overridesToDocsClassMapping ? this.overridesToDocsClassMapping.get(name) : undefined) || name;
|
||||
const mappedName = this.overridesToDocsClassMapping.get(name) || name;
|
||||
const docClass = this.documentation.classes.get(mappedName);
|
||||
if (!docClass && !this.canIgnoreMissingName(name))
|
||||
throw new Error(`Unknown override class ${name}`);
|
||||
|
|
@ -189,7 +192,8 @@ class TypesGenerator {
|
|||
if (classDesc.comment) {
|
||||
parts.push(this.writeComment(classDesc.comment))
|
||||
}
|
||||
parts.push(`export interface ${classDesc.name} ${classDesc.extends ? `extends ${classDesc.extends} ` : ''}{`);
|
||||
const shouldExport = !this.doNotExportClassNames.has(classDesc.name);
|
||||
parts.push(`${shouldExport ? 'export ' : ''}interface ${classDesc.name} ${classDesc.extends ? `extends ${classDesc.extends} ` : ''}{`);
|
||||
parts.push(this.classBody(classDesc));
|
||||
parts.push('}\n');
|
||||
return parts.join('\n');
|
||||
|
|
@ -497,14 +501,12 @@ class TypesGenerator {
|
|||
fs.mkdirSync(testTypesDir)
|
||||
writeFile(path.join(coreTypesDir, 'protocol.d.ts'), fs.readFileSync(path.join(PROJECT_DIR, 'packages', 'playwright-core', 'src', 'server', 'chromium', 'protocol.d.ts'), 'utf8'));
|
||||
|
||||
const assertionClasses = new Set(['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'ScreenshotAssertions']);
|
||||
const assertionClasses = new Set(['LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'ScreenshotAssertions']);
|
||||
const apiDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api'));
|
||||
apiDocumentation.index();
|
||||
const apiTypesGenerator = new TypesGenerator({
|
||||
documentation: apiDocumentation,
|
||||
classNames: new Set(apiDocumentation.classesArray.map(cls => cls.name).filter(name => !assertionClasses.has(name))),
|
||||
overridesToDocsClassMapping: new Map(),
|
||||
ignoreMissing: new Set(),
|
||||
classNamesToGenerate: new Set(apiDocumentation.classesArray.map(cls => cls.name).filter(name => !assertionClasses.has(name) && name !== 'PlaywrightAssertions')),
|
||||
});
|
||||
let apiTypes = await apiTypesGenerator.generateTypes(path.join(__dirname, 'overrides.d.ts'));
|
||||
const namedDevices = Object.keys(devices).map(name => ` ${JSON.stringify(name)}: DeviceDescriptor;`).join('\n');
|
||||
|
|
@ -530,7 +532,7 @@ class TypesGenerator {
|
|||
const testDocumentation = apiDocumentation.mergeWith(testOnlyDocumentation);
|
||||
const testTypesGenerator = new TypesGenerator({
|
||||
documentation: testDocumentation,
|
||||
classNames: new Set(['TestError', 'TestInfo', 'WorkerInfo']),
|
||||
classNamesToGenerate: new Set(['TestError', 'TestInfo', 'WorkerInfo', ...assertionClasses]),
|
||||
overridesToDocsClassMapping: new Map([
|
||||
['TestType', 'Test'],
|
||||
['Config', 'TestConfig'],
|
||||
|
|
@ -548,7 +550,9 @@ class TypesGenerator {
|
|||
'TestFunction',
|
||||
'PlaywrightWorkerOptions.defaultBrowserType',
|
||||
'PlaywrightWorkerArgs.playwright',
|
||||
'Matchers',
|
||||
]),
|
||||
doNotExportClassNames: new Set(assertionClasses),
|
||||
});
|
||||
let testTypes = await testTypesGenerator.generateTypes(path.join(__dirname, 'overrides-test.d.ts'));
|
||||
testTypes = testTypes.replace(/( +)\n/g, '\n'); // remove trailing whitespace
|
||||
|
|
@ -558,8 +562,7 @@ class TypesGenerator {
|
|||
const testReporterDocumentation = testDocumentation.mergeWith(testReporterOnlyDocumentation);
|
||||
const testReporterTypesGenerator = new TypesGenerator({
|
||||
documentation: testReporterDocumentation,
|
||||
classNames: new Set(testReporterOnlyDocumentation.classesArray.map(cls => cls.name)),
|
||||
overridesToDocsClassMapping: new Map(),
|
||||
classNamesToGenerate: new Set(testReporterOnlyDocumentation.classesArray.map(cls => cls.name)),
|
||||
ignoreMissing: new Set(['FullResult']),
|
||||
});
|
||||
let testReporterTypes = await testReporterTypesGenerator.generateTypes(path.join(__dirname, 'overrides-testReporter.d.ts'));
|
||||
|
|
|
|||
122
utils/generate_types/overrides-test.d.ts
vendored
122
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -14,10 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials } from 'playwright-core';
|
||||
import type { Expect } from './testExpect';
|
||||
|
||||
export type { Expect } from './testExpect';
|
||||
import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse } from 'playwright-core';
|
||||
|
||||
export type ReporterDescription =
|
||||
['dot'] |
|
||||
|
|
@ -332,7 +329,7 @@ export interface PlaywrightTestOptions {
|
|||
|
||||
|
||||
export interface PlaywrightWorkerArgs {
|
||||
playwright: typeof import('..');
|
||||
playwright: typeof import('playwright-core');
|
||||
browser: Browser;
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +342,121 @@ export interface PlaywrightTestArgs {
|
|||
export type PlaywrightTestProject<TestArgs = {}, WorkerArgs = {}> = Project<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>;
|
||||
export type PlaywrightTestConfig<TestArgs = {}, WorkerArgs = {}> = Config<PlaywrightTestOptions & TestArgs, PlaywrightWorkerOptions & WorkerArgs>;
|
||||
|
||||
import type * as expectType from 'expect';
|
||||
|
||||
type AsymmetricMatcher = Record<string, any>;
|
||||
|
||||
type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;
|
||||
type ExtraMatchers<T, Type, Matchers> = T extends Type ? Matchers : IfAny<T, Matchers, {}>;
|
||||
|
||||
type BaseMatchers<R, T> = Pick<expectType.Matchers<R>, SupportedExpectProperties> & PlaywrightTest.Matchers<R, T>;
|
||||
|
||||
type MakeMatchers<R, T> = BaseMatchers<R, T> & {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: MakeMatchers<R, T>;
|
||||
/**
|
||||
* Use resolves to unwrap the value of a fulfilled promise so any other
|
||||
* matcher can be chained. If the promise is rejected the assertion fails.
|
||||
*/
|
||||
resolves: MakeMatchers<Promise<R>, Awaited<T>>;
|
||||
/**
|
||||
* Unwraps the reason of a rejected promise so any other matcher can be chained.
|
||||
* If the promise is fulfilled the assertion fails.
|
||||
*/
|
||||
rejects: MakeMatchers<Promise<R>, Awaited<T>>;
|
||||
} & ScreenshotAssertions &
|
||||
ExtraMatchers<T, Page, PageAssertions> &
|
||||
ExtraMatchers<T, Locator, LocatorAssertions> &
|
||||
ExtraMatchers<T, APIResponse, APIResponseAssertions>;
|
||||
|
||||
export declare type Expect = {
|
||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T>;
|
||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T>;
|
||||
poll: <T = unknown>(actual: () => T | Promise<T>, messageOrOptions?: string | { message?: string, timeout?: number }) => BaseMatchers<Promise<void>, T> & {
|
||||
/**
|
||||
* If you know how to test something, `.not` lets you test its opposite.
|
||||
*/
|
||||
not: BaseMatchers<Promise<void>, T>;
|
||||
};
|
||||
|
||||
extend(arg0: any): void;
|
||||
getState(): expectType.MatcherState;
|
||||
setState(state: Partial<expectType.MatcherState>): void;
|
||||
any(expectedObject: any): AsymmetricMatcher;
|
||||
anything(): AsymmetricMatcher;
|
||||
arrayContaining(sample: Array<unknown>): AsymmetricMatcher;
|
||||
objectContaining(sample: Record<string, unknown>): AsymmetricMatcher;
|
||||
stringContaining(expected: string): AsymmetricMatcher;
|
||||
stringMatching(expected: string | RegExp): AsymmetricMatcher;
|
||||
/**
|
||||
* Removed following methods because they rely on a test-runner integration from Jest which we don't support:
|
||||
* - assertions()
|
||||
* - extractExpectedAssertionsErrors()
|
||||
* – hasAssertions()
|
||||
*/
|
||||
};
|
||||
|
||||
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;
|
||||
|
||||
/**
|
||||
* Removed methods require the jest.fn() integration from Jest to spy on function calls which we don't support:
|
||||
* - lastCalledWith()
|
||||
* - lastReturnedWith()
|
||||
* - nthCalledWith()
|
||||
* - nthReturnedWith()
|
||||
* - toBeCalled()
|
||||
* - toBeCalledTimes()
|
||||
* - toBeCalledWith()
|
||||
* - toHaveBeenCalled()
|
||||
* - toHaveBeenCalledTimes()
|
||||
* - toHaveBeenCalledWith()
|
||||
* - toHaveBeenLastCalledWith()
|
||||
* - toHaveBeenNthCalledWith()
|
||||
* - toHaveLastReturnedWith()
|
||||
* - toHaveNthReturnedWith()
|
||||
* - toHaveReturned()
|
||||
* - toHaveReturnedTimes()
|
||||
* - toHaveReturnedWith()
|
||||
* - toReturn()
|
||||
* - toReturnTimes()
|
||||
* - toReturnWith()
|
||||
* - toThrowErrorMatchingSnapshot()
|
||||
* - toThrowErrorMatchingInlineSnapshot()
|
||||
*/
|
||||
type SupportedExpectProperties =
|
||||
'toBe' |
|
||||
'toBeCloseTo' |
|
||||
'toBeDefined' |
|
||||
'toBeFalsy' |
|
||||
'toBeGreaterThan' |
|
||||
'toBeGreaterThanOrEqual' |
|
||||
'toBeInstanceOf' |
|
||||
'toBeLessThan' |
|
||||
'toBeLessThanOrEqual' |
|
||||
'toBeNaN' |
|
||||
'toBeNull' |
|
||||
'toBeTruthy' |
|
||||
'toBeUndefined' |
|
||||
'toContain' |
|
||||
'toContainEqual' |
|
||||
'toEqual' |
|
||||
'toHaveLength' |
|
||||
'toHaveProperty' |
|
||||
'toMatch' |
|
||||
'toMatchObject' |
|
||||
'toStrictEqual' |
|
||||
'toThrow' |
|
||||
'toThrowError'
|
||||
|
||||
declare global {
|
||||
export namespace PlaywrightTest {
|
||||
export interface Matchers<R, T = unknown> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These tests are executed in Playwright environment that launches the browser
|
||||
* and provides a fresh page to each test.
|
||||
|
|
|
|||
Loading…
Reference in a new issue