feat(expect): add GenericAssertions documentation (#20564)

References #20432.
This commit is contained in:
Dmitry Gozman 2023-02-01 16:55:52 -08:00 committed by GitHub
parent 6f699cd346
commit f46883e58e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 1067 additions and 264 deletions

View file

@ -0,0 +1,534 @@
# class: GenericAssertions
* since: v1.9
* langs: js
The [GenericAssertions] class provides assertion methods that can be used to make assertions about any values in the tests. A new instance of [GenericAssertions] is created by calling [`method: PlaywrightAssertions.expectGeneric`]:
```js
import { test, expect } from '@playwright/test';
test('assert a value', async ({ page }) => {
const value = 1;
await expect(value).toBe(2);
});
```
## property: GenericAssertions.not
* since: v1.9
- returns: <[GenericAssertions]>
Makes the assertion check for the opposite condition. For example, the following code passes:
```js
const value = 1;
await expect(value).not.toBe(2);
```
## method: GenericAssertions.toBe
* since: v1.9
Compares value with [`param: expected`] by calling `Object.is`. This method compares objects by reference instead of their contents, similarly to the strict equality operator `===`.
**Usage**
```js
const value = { prop: 1 };
expect(value).toBe(value);
expect(value).not.toBe({});
expect(value.prop).toBe(1);
```
### param: GenericAssertions.toBe.expected
* since: v1.9
- `expected` <[any]>
Expected value.
## method: GenericAssertions.toBeCloseTo
* since: v1.9
Compares floating point numbers for approximate equality. Use this method instead of [`method: GenericAssertions.toBe`] when comparing floating point numbers.
**Usage**
```js
expect(0.1 + 0.2).not.toBe(0.3);
expect(0.1 + 0.2).toBeCloseTo(0.3, 5);
```
### param: GenericAssertions.toBeCloseTo.expected
* since: v1.9
- `expected` <[float]>
Expected value.
### param: GenericAssertions.toBeCloseTo.numDigits
* since: v1.9
- `numDigits` ?<[int]>
The number of decimal digits after the decimal point that must be equal.
## method: GenericAssertions.toBeDefined
* since: v1.9
Ensures that value is not `undefined`.
**Usage**
```js
const value = null;
expect(value).toBeDefined();
```
## method: GenericAssertions.toBeFalsy
* since: v1.9
Ensures that value is false in a boolean context, one of `false`, `0`, `''`, `null`, `undefined` or `NaN`. Use this method when you don't care about the specific value.
**Usage**
```js
const value = null;
expect(value).toBeFalsy();
```
## method: GenericAssertions.toBeGreaterThan
* since: v1.9
Ensures that `value > expected` for number or big integer values.
**Usage**
```js
const value = 42;
expect(value).toBeGreaterThan(1);
```
### param: GenericAssertions.toBeGreaterThan.expected
* since: v1.9
- `expected` <[float]|[bigint]>
The value to compare to.
## method: GenericAssertions.toBeGreaterThanOrEqual
* since: v1.9
Ensures that `value >= expected` for number or big integer values.
**Usage**
```js
const value = 42;
expect(value).toBeGreaterThanOrEqual(42);
```
### param: GenericAssertions.toBeGreaterThanOrEqual.expected
* since: v1.9
- `expected` <[float]|[bigint]>
The value to compare to.
## method: GenericAssertions.toBeInstanceOf
* since: v1.9
Ensures that value is an instance of a class. Uses `instanceof` operator.
**Usage**
```js
expect(page).toBeInstanceOf(Page);
class Example {}
expect(new Example()).toBeInstanceOf(Example);
```
### param: GenericAssertions.toBeInstanceOf.expected
* since: v1.9
- `expected` <[Function]>
The class or constructor function.
## method: GenericAssertions.toBeLessThan
* since: v1.9
Ensures that `value < expected` for number or big integer values.
**Usage**
```js
const value = 42;
expect(value).toBeLessThan(100);
```
### param: GenericAssertions.toBeLessThan.expected
* since: v1.9
- `expected` <[float]|[bigint]>
The value to compare to.
## method: GenericAssertions.toBeLessThanOrEqual
* since: v1.9
Ensures that `value <= expected` for number or big integer values.
**Usage**
```js
const value = 42;
expect(value).toBeLessThanOrEqual(42);
```
### param: GenericAssertions.toBeLessThanOrEqual.expected
* since: v1.9
- `expected` <[float]|[bigint]>
The value to compare to.
## method: GenericAssertions.toBeNaN
* since: v1.9
Ensures that value is `NaN`.
**Usage**
```js
const value = NaN;
expect(value).toBeNaN();
```
## method: GenericAssertions.toBeNull
* since: v1.9
Ensures that value is `null`.
**Usage**
```js
const value = null;
expect(value).toBeNull();
```
## method: GenericAssertions.toBeTruthy
* since: v1.9
Ensures that value is true in a boolean context, **anything but** `false`, `0`, `''`, `null`, `undefined` or `NaN`. Use this method when you don't care about the specific value.
**Usage**
```js
const value = { example: 'value' };
expect(value).toBeTruthy();
```
## method: GenericAssertions.toBeUndefined
* since: v1.9
Ensures that value is `undefined`.
**Usage**
```js
const value = undefined;
expect(value).toBeUndefined();
```
## method: GenericAssertions.toContain#1
* since: v1.9
Ensures that string value contains an expected substring. Comparison is case-sensitive.
**Usage**
```js
const value = 'Hello, World';
expect(value).toContain('World');
expect(value).toContain(',');
```
### param: GenericAssertions.toContain#1.expected
* since: v1.9
- `expected` <[string]>
Expected substring.
## method: GenericAssertions.toContain#2
* since: v1.9
Ensures that value is an `Array` or `Set` and contains an expected item.
**Usage**
```js
const value = [1, 2, 3];
expect(value).toContain(2);
expect(new Set(value)).toContain(2);
```
### param: GenericAssertions.toContain#2.expected
* since: v1.9
- `expected` <[any]>
Expected value in the collection.
## method: GenericAssertions.toContainEqual
* since: v1.9
Ensures that value is an `Array` or `Set` and contains an item equal to the expected.
For objects, this method recursively checks equality of all fields, rather than comparing objects by reference as performed by [`method: GenericAssertions.toContain#2`].
For primitive values, this method is equivalent to [`method: GenericAssertions.toContain#2`].
**Usage**
```js
const value = [
{ example: 1 },
{ another: 2 },
{ more: 3 },
];
expect(value).toContainEqual({ another: 2 });
expect(new Set(value)).toContainEqual({ another: 2 });
```
### param: GenericAssertions.toContainEqual.expected
* since: v1.9
- `expected` <[any]>
Expected value in the collection.
## method: GenericAssertions.toEqual
* since: v1.9
Compares contents of the value with contents of [`param: expected`], performing "deep equality" check.
For objects, this method recursively checks equality of all fields, rather than comparing objects by reference as performed by [`method: GenericAssertions.toBe`].
For primitive values, this method is equivalent to [`method: GenericAssertions.toBe`].
**Usage**
```js
const value = { prop: 1 };
expect(value).toEqual({ prop: 1 });
```
### param: GenericAssertions.toEqual.expected
* since: v1.9
- `expected` <[any]>
Expected value.
## method: GenericAssertions.toHaveLength
* since: v1.9
Ensures that value has a `.length` property equal to [`param: expected`]. Useful for arrays and strings.
**Usage**
```js
expect('Hello, World').toHaveLength(12);
expect([1, 2, 3]).toHaveLength(3);
```
### param: GenericAssertions.toHaveLength.expected
* since: v1.9
- `expected` <[int]>
Expected length.
## method: GenericAssertions.toHaveProperty
* since: v1.9
Ensures that property at provided `keyPath` exists on the object and optionally checks that property is equal to the [`param: expected`]. Equality is checked recursively, similarly to [`method: GenericAssertions.toEqual`].
**Usage**
```js
const value = {
a: {
b: [42],
},
c: true,
};
expect(value).toHaveProperty('a.b');
expect(value).toHaveProperty('a.b', [42]);
expect(value).toHaveProperty('a.b[0]', 42);
expect(value).toHaveProperty('c');
expect(value).toHaveProperty('c', true);
```
### param: GenericAssertions.toHaveProperty.keyPath
* since: v1.9
- `keyPath` <[string]>
Path to the property. Use dot notation `a.b` to check nested properties and indexed `a[2]` notation to check nested array items.
### param: GenericAssertions.toHaveProperty.expected
* since: v1.9
- `expected` ?<[any]>
Optional expected value to compare the property to.
## method: GenericAssertions.toMatch
* since: v1.9
Ensures that string value matches a regular expression.
**Usage**
```js
const value = 'Is 42 enough?';
expect(value).toMatches(/Is \d+ enough/);
```
### param: GenericAssertions.toMatch.expected
* since: v1.9
- `expected` <[RegExp]>
Regular expression to match against.
## method: GenericAssertions.toMatchObject
* since: v1.9
Compares contents of the value with contents of [`param: expected`], performing "deep equality" check. Allows extra properties to be present in the value, unlike [`method: GenericAssertions.toEqual`], so you can check just a subset of object properties.
When comparing arrays, the number of items must match, and each item is checked recursively.
**Usage**
```js
const value = {
a: 1,
b: 2,
c: true,
};
expect(value).toMatchObject({ a: 1, c: true });
expect(value).toMatchObject({ b: 2, c: true });
expect([{ a: 1, b: 2 }]).toMatchObject([{ a: 1 }]);
```
### param: GenericAssertions.toMatchObject.expected
* since: v1.9
- `expected` <[Object]|[Array]>
The expected object value to match against.
## method: GenericAssertions.toStrictEqual
* since: v1.9
Compares contents of the value with contents of [`param: expected`] **and** their types.
Differences from [`method: GenericAssertions.toEqual`]:
* Keys with undefined properties are checked. For example, `{ a: undefined, b: 2 }` does not match `{ b: 2 }`.
* Array sparseness is checked. For example, `[, 1]` does not match `[undefined, 1]`.
* Object types are checked to be equal. For example, a class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`.
**Usage**
```js
const value = { prop: 1 };
expect(value).toStrictEqual({ prop: 1 });
```
### param: GenericAssertions.toStrictEqual.expected
* since: v1.9
- `expected` <[any]>
Expected value.
## method: GenericAssertions.toThrow
* since: v1.9
Calls the function and ensures it throws an error.
Optionally compares the error with [`param: expected`]. Allowed expected values:
* Regular expression - error message should **match** the pattern.
* String - error message should **include** the substring.
* Error object - error message should be **equal to** the message property of the object.
* Error class - error object should be an **instance of** the class.
**Usage**
```js
expect(() => {
throw new Error('Something bad');
}).toThrow();
expect(() => {
throw new Error('Something bad');
}).toThrow(/something/);
expect(() => {
throw new Error('Something bad');
}).toThrow(Error);
```
### param: GenericAssertions.toThrow.expected
* since: v1.9
- `expected` ?<[any]>
Expected error message or error object.
## method: GenericAssertions.toThrowError
* since: v1.9
An alias for [`method: GenericAssertions.toThrow`].
**Usage**
```js
expect(() => {
throw new Error('Something bad');
}).toThrowError();
```
### param: GenericAssertions.toThrowError.expected
* since: v1.9
- `expected` ?<[any]>
Expected error message or error object.

View file

@ -96,6 +96,20 @@ PlaywrightAssertions.assertThat(response).isOK();
[APIResponse] object to use for assertions.
## method: PlaywrightAssertions.expectGeneric
* since: v1.9
* langs:
- alias-js: expect
- returns: <[GenericAssertions]>
Creates a [GenericAssertions] object for the given value.
### param: PlaywrightAssertions.expectGeneric.value
* since: v1.9
- `value` <[any]>
Value that will be asserted.
## method: PlaywrightAssertions.expectLocator
* since: v1.18
* langs:

View file

@ -108,261 +108,4 @@ export declare type MatcherState = {
// };
// ---------------------------------------
// -------------- Playwright -------------
// - Some of the removed matchers below require jest.fn
// - Some are overridden.
// - Some are missing (inline snapshot).
// ---------------------------------------
export interface Matchers<R> {
// /**
// * Ensures the last call to a mock function was provided specific args.
// */
// lastCalledWith(...args: Array<unknown>): R;
// /**
// * Ensure that the last call to a mock function has returned a specified value.
// */
// lastReturnedWith(value: unknown): R;
// /**
// * If you know how to test something, `.not` lets you test its opposite.
// */
// not: Matchers<R>;
// /**
// * Ensure that a mock function is called with specific arguments on an Nth call.
// */
// nthCalledWith(nthCall: number, ...args: Array<unknown>): R;
// /**
// * Ensure that the nth call to a mock function has returned a specified value.
// */
// nthReturnedWith(n: number, value: unknown): R;
// /**
// * 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: Matchers<Promise<R>>;
// /**
// * Unwraps the reason of a rejected promise so any other matcher can be chained.
// * If the promise is fulfilled the assertion fails.
// */
// rejects: Matchers<Promise<R>>;
/**
* Checks that a value is what you expect. It uses `===` to check strict equality.
* Don't use `toBe` with floating-point numbers.
*/
toBe(expected: unknown): R;
// /**
// * Ensures that a mock function is called.
// */
// toBeCalled(): R;
// /**
// * Ensures that a mock function is called an exact number of times.
// */
// toBeCalledTimes(expected: number): R;
// /**
// * Ensure that a mock function is called with specific arguments.
// */
// toBeCalledWith(...args: Array<unknown>): R;
/**
* Using exact equality with floating point numbers is a bad idea.
* Rounding means that intuitive things fail.
* The default for numDigits is 2.
*/
toBeCloseTo(expected: number, numDigits?: number): R;
/**
* Ensure that a variable is not undefined.
*/
toBeDefined(): R;
/**
* When you don't care what a value is, you just want to
* ensure a value is false in a boolean context.
*/
toBeFalsy(): R;
/**
* For comparing floating point numbers.
*/
toBeGreaterThan(expected: number | bigint): R;
/**
* For comparing floating point numbers.
*/
toBeGreaterThanOrEqual(expected: number | bigint): R;
/**
* Ensure that an object is an instance of a class.
* This matcher uses `instanceof` underneath.
*/
toBeInstanceOf(expected: Function): R;
/**
* For comparing floating point numbers.
*/
toBeLessThan(expected: number | bigint): R;
/**
* For comparing floating point numbers.
*/
toBeLessThanOrEqual(expected: number | bigint): R;
/**
* This is the same as `.toBe(null)` but the error messages are a bit nicer.
* So use `.toBeNull()` when you want to check that something is null.
*/
toBeNull(): R;
/**
* Use when you don't care what a value is, you just want to ensure a value
* is true in a boolean context. In JavaScript, there are six falsy values:
* `false`, `0`, `''`, `null`, `undefined`, and `NaN`. Everything else is truthy.
*/
toBeTruthy(): R;
/**
* Used to check that a variable is undefined.
*/
toBeUndefined(): R;
/**
* Used to check that a variable is NaN.
*/
toBeNaN(): R;
/**
* Used when you want to check that an item is in a list.
* For testing the items in the list, this uses `===`, a strict equality check.
*/
toContain(expected: unknown): R;
/**
* Used when you want to check that an item is in a list.
* For testing the items in the list, this matcher recursively checks the
* equality of all fields, rather than checking for object identity.
*/
toContainEqual(expected: unknown): R;
/**
* Used when you want to check that two objects have the same value.
* This matcher recursively checks the equality of all fields, rather than checking for object identity.
*/
toEqual(expected: unknown): R;
// /**
// * Ensures that a mock function is called.
// */
// toHaveBeenCalled(): R;
// /**
// * Ensures that a mock function is called an exact number of times.
// */
// toHaveBeenCalledTimes(expected: number): R;
// /**
// * Ensure that a mock function is called with specific arguments.
// */
// toHaveBeenCalledWith(...args: Array<unknown>): R;
// /**
// * Ensure that a mock function is called with specific arguments on an Nth call.
// */
// toHaveBeenNthCalledWith(nthCall: number, ...args: Array<unknown>): R;
// /**
// * If you have a mock function, you can use `.toHaveBeenLastCalledWith`
// * to test what arguments it was last called with.
// */
// toHaveBeenLastCalledWith(...args: Array<unknown>): R;
// /**
// * Use to test the specific value that a mock function last returned.
// * If the last call to the mock function threw an error, then this matcher will fail
// * no matter what value you provided as the expected return value.
// */
// toHaveLastReturnedWith(expected: unknown): R;
/**
* Used to check that an object has a `.length` property
* and it is set to a certain numeric value.
*/
toHaveLength(expected: number): R;
// /**
// * Use to test the specific value that a mock function returned for the nth call.
// * If the nth call to the mock function threw an error, then this matcher will fail
// * no matter what value you provided as the expected return value.
// */
// toHaveNthReturnedWith(nthCall: number, expected: unknown): R;
/**
* Use to check if property at provided reference keyPath exists for an object.
* For checking deeply nested properties in an object you may use dot notation or an array containing
* the keyPath for deep references.
*
* Optionally, you can provide a value to check if it's equal to the value present at keyPath
* on the target object. This matcher uses 'deep equality' (like `toEqual()`) and recursively checks
* the equality of all fields.
*
* @example
*
* expect(houseForSale).toHaveProperty('kitchen.area', 20);
*/
toHaveProperty(keyPath: string | Array<string>, value?: unknown): R;
// /**
// * Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time
// */
// toHaveReturned(): R;
// /**
// * Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times.
// * Any calls to the mock function that throw an error are not counted toward the number of times the function returned.
// */
// toHaveReturnedTimes(expected: number): R;
// /**
// * Use to ensure that a mock function returned a specific value.
// */
// toHaveReturnedWith(expected: unknown): R;
/**
* Check that a string matches a regular expression.
*/
toMatch(expected: string | RegExp): R;
/**
* Used to check that a JavaScript object matches a subset of the properties of an object
*/
toMatchObject(expected: Record<string, unknown> | Array<unknown>): R;
// /**
// * Ensure that a mock function has returned (as opposed to thrown) at least once.
// */
// toReturn(): R;
// /**
// * Ensure that a mock function has returned (as opposed to thrown) a specified number of times.
// */
// toReturnTimes(count: number): R;
// /**
// * Ensure that a mock function has returned a specified value at least once.
// */
// toReturnWith(value: unknown): R;
/**
* Use to test that objects have the same types as well as structure.
*/
toStrictEqual(expected: unknown): R;
/**
* Used to test that a function throws when it is called.
*/
toThrow(error?: unknown): R;
/**
* If you want to test that a specific error is thrown inside a function.
*/
toThrowError(error?: unknown): R;
// /**
// * This ensures that a value matches the most recent snapshot with property matchers.
// * Check out [the Snapshot Testing guide](https://jestjs.io/docs/snapshot-testing) for more information.
// */
// toMatchSnapshot<T extends {
// [P in keyof R]: unknown;
// }>(propertyMatchers: Partial<T>, snapshotName?: string): R;
// /**
// * This ensures that a value matches the most recent snapshot.
// * Check out [the Snapshot Testing guide](https://jestjs.io/docs/snapshot-testing) for more information.
// */
// toMatchSnapshot(snapshotName?: string): R;
// /**
// * This ensures that a value matches the most recent snapshot with property matchers.
// * Instead of writing the snapshot value to a .snap file, it will be written into the source code automatically.
// * Check out [the Snapshot Testing guide](https://jestjs.io/docs/snapshot-testing) for more information.
// */
// toMatchInlineSnapshot<T extends {
// [P in keyof R]: unknown;
// }>(propertyMatchers: Partial<T>, snapshot?: string): R;
// /**
// * This ensures that a value matches the most recent snapshot with property matchers.
// * Instead of writing the snapshot value to a .snap file, it will be written into the source code automatically.
// * Check out [the Snapshot Testing guide](https://jestjs.io/docs/snapshot-testing) for more information.
// */
// toMatchInlineSnapshot(snapshot?: string): R;
// /**
// * Used to test that a function throws a error matching the most recent snapshot when it is called.
// */
// toThrowErrorMatchingSnapshot(): R;
// /**
// * Used to test that a function throws a error matching the most recent snapshot when it is called.
// * Instead of writing the snapshot value to a .snap file, it will be written into the source code automatically.
// */
// toThrowErrorMatchingInlineSnapshot(snapshot?: string): R;
}
export {};

View file

@ -3780,7 +3780,421 @@ type Inverse<Matchers> = {
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> = expectType.Matchers<R> & PlaywrightTest.Matchers<R, T>;
/**
* The [GenericAssertions] class provides assertion methods that can be used to make assertions about any values in
* the tests. A new instance of [GenericAssertions] is created by calling
* [expect(value)](https://playwright.dev/docs/api/class-playwrightassertions#playwright-assertions-expect-generic):
*
* ```js
* import { test, expect } from '@playwright/test';
*
* test('assert a value', async ({ page }) => {
* const value = 1;
* await expect(value).toBe(2);
* });
* ```
*
*/
interface GenericAssertions<R> {
/**
* Makes the assertion check for the opposite condition. For example, the following code passes:
*
* ```js
* const value = 1;
* await expect(value).not.toBe(2);
* ```
*
*/
not: GenericAssertions<R>;
/**
* Compares value with `expected` by calling `Object.is`. This method compares objects by reference instead of their
* contents, similarly to the strict equality operator `===`.
*
* **Usage**
*
* ```js
* const value = { prop: 1 };
* expect(value).toBe(value);
* expect(value).not.toBe({});
* expect(value.prop).toBe(1);
* ```
*
* @param expected Expected value.
*/
toBe(expected: unknown): R;
/**
* Compares floating point numbers for approximate equality. Use this method instead of
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be)
* when comparing floating point numbers.
*
* **Usage**
*
* ```js
* expect(0.1 + 0.2).not.toBe(0.3);
* expect(0.1 + 0.2).toBeCloseTo(0.3, 5);
* ```
*
* @param expected Expected value.
* @param numDigits The number of decimal digits after the decimal point that must be equal.
*/
toBeCloseTo(expected: number, numDigits?: number): R;
/**
* Ensures that value is not `undefined`.
*
* **Usage**
*
* ```js
* const value = null;
* expect(value).toBeDefined();
* ```
*
*/
toBeDefined(): R;
/**
* Ensures that value is false in a boolean context, one of `false`, `0`, `''`, `null`, `undefined` or `NaN`. Use this
* method when you don't care about the specific value.
*
* **Usage**
*
* ```js
* const value = null;
* expect(value).toBeFalsy();
* ```
*
*/
toBeFalsy(): R;
/**
* Ensures that `value > expected` for number or big integer values.
*
* **Usage**
*
* ```js
* const value = 42;
* expect(value).toBeGreaterThan(1);
* ```
*
* @param expected The value to compare to.
*/
toBeGreaterThan(expected: number | bigint): R;
/**
* Ensures that `value >= expected` for number or big integer values.
*
* **Usage**
*
* ```js
* const value = 42;
* expect(value).toBeGreaterThanOrEqual(42);
* ```
*
* @param expected The value to compare to.
*/
toBeGreaterThanOrEqual(expected: number | bigint): R;
/**
* Ensures that value is an instance of a class. Uses `instanceof` operator.
*
* **Usage**
*
* ```js
* expect(page).toBeInstanceOf(Page);
*
* class Example {}
* expect(new Example()).toBeInstanceOf(Example);
* ```
*
* @param expected The class or constructor function.
*/
toBeInstanceOf(expected: Function): R;
/**
* Ensures that `value < expected` for number or big integer values.
*
* **Usage**
*
* ```js
* const value = 42;
* expect(value).toBeLessThan(100);
* ```
*
* @param expected The value to compare to.
*/
toBeLessThan(expected: number | bigint): R;
/**
* Ensures that `value <= expected` for number or big integer values.
*
* **Usage**
*
* ```js
* const value = 42;
* expect(value).toBeLessThanOrEqual(42);
* ```
*
* @param expected The value to compare to.
*/
toBeLessThanOrEqual(expected: number | bigint): R;
/**
* Ensures that value is `NaN`.
*
* **Usage**
*
* ```js
* const value = NaN;
* expect(value).toBeNaN();
* ```
*
*/
toBeNaN(): R;
/**
* Ensures that value is `null`.
*
* **Usage**
*
* ```js
* const value = null;
* expect(value).toBeNull();
* ```
*
*/
toBeNull(): R;
/**
* Ensures that value is true in a boolean context, **anything but** `false`, `0`, `''`, `null`, `undefined` or `NaN`.
* Use this method when you don't care about the specific value.
*
* **Usage**
*
* ```js
* const value = { example: 'value' };
* expect(value).toBeTruthy();
* ```
*
*/
toBeTruthy(): R;
/**
* Ensures that value is `undefined`.
*
* **Usage**
*
* ```js
* const value = undefined;
* expect(value).toBeUndefined();
* ```
*
*/
toBeUndefined(): R;
/**
* Ensures that string value contains an expected substring. Comparison is case-sensitive.
*
* **Usage**
*
* ```js
* const value = 'Hello, World';
* expect(value).toContain('World');
* expect(value).toContain(',');
* ```
*
* @param expected Expected substring.
*/
toContain(expected: string): R;
/**
* Ensures that value is an `Array` or `Set` and contains an expected item.
*
* **Usage**
*
* ```js
* const value = [1, 2, 3];
* expect(value).toContain(2);
* expect(new Set(value)).toContain(2);
* ```
*
* @param expected Expected value in the collection.
*/
toContain(expected: unknown): R;
/**
* Ensures that value is an `Array` or `Set` and contains an item equal to the expected.
*
* For objects, this method recursively checks equality of all fields, rather than comparing objects by reference as
* performed by
* [genericAssertions.toContain(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-contain-2).
*
* For primitive values, this method is equivalent to
* [genericAssertions.toContain(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-contain-2).
*
* **Usage**
*
* ```js
* const value = [
* { example: 1 },
* { another: 2 },
* { more: 3 },
* ];
* expect(value).toContainEqual({ another: 2 });
* expect(new Set(value)).toContainEqual({ another: 2 });
* ```
*
* @param expected Expected value in the collection.
*/
toContainEqual(expected: unknown): R;
/**
* Compares contents of the value with contents of `expected`, performing "deep equality" check.
*
* For objects, this method recursively checks equality of all fields, rather than comparing objects by reference as
* performed by
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be).
*
* For primitive values, this method is equivalent to
* [genericAssertions.toBe(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be).
*
* **Usage**
*
* ```js
* const value = { prop: 1 };
* expect(value).toEqual({ prop: 1 });
* ```
*
* @param expected Expected value.
*/
toEqual(expected: unknown): R;
/**
* Ensures that value has a `.length` property equal to `expected`. Useful for arrays and strings.
*
* **Usage**
*
* ```js
* expect('Hello, World').toHaveLength(12);
* expect([1, 2, 3]).toHaveLength(3);
* ```
*
* @param expected Expected length.
*/
toHaveLength(expected: number): R;
/**
* Ensures that property at provided `keyPath` exists on the object and optionally checks that property is equal to
* the `expected`. Equality is checked recursively, similarly to
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal).
*
* **Usage**
*
* ```js
* const value = {
* a: {
* b: [42],
* },
* c: true,
* };
* expect(value).toHaveProperty('a.b');
* expect(value).toHaveProperty('a.b', [42]);
* expect(value).toHaveProperty('a.b[0]', 42);
* expect(value).toHaveProperty('c');
* expect(value).toHaveProperty('c', true);
* ```
*
* @param keyPath Path to the property. Use dot notation `a.b` to check nested properties and indexed `a[2]` notation to check nested
* array items.
* @param expected Optional expected value to compare the property to.
*/
toHaveProperty(keyPath: string | Array<string>, value?: unknown): R;
/**
* Ensures that string value matches a regular expression.
*
* **Usage**
*
* ```js
* const value = 'Is 42 enough?';
* expect(value).toMatches(/Is \d+ enough/);
* ```
*
* @param expected Regular expression to match against.
*/
toMatch(expected: RegExp): R;
/**
* Compares contents of the value with contents of `expected`, performing "deep equality" check. Allows extra
* properties to be present in the value, unlike
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal),
* so you can check just a subset of object properties.
*
* When comparing arrays, the number of items must match, and each item is checked recursively.
*
* **Usage**
*
* ```js
* const value = {
* a: 1,
* b: 2,
* c: true,
* };
* expect(value).toMatchObject({ a: 1, c: true });
* expect(value).toMatchObject({ b: 2, c: true });
*
* expect([{ a: 1, b: 2 }]).toMatchObject([{ a: 1 }]);
* ```
*
* @param expected The expected object value to match against.
*/
toMatchObject(expected: Record<string, unknown> | Array<unknown>): R;
/**
* Compares contents of the value with contents of `expected` **and** their types.
*
* Differences from
* [genericAssertions.toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal):
* - Keys with undefined properties are checked. For example, `{ a: undefined, b: 2 }` does not match `{ b: 2 }`.
* - Array sparseness is checked. For example, `[, 1]` does not match `[undefined, 1]`.
* - Object types are checked to be equal. For example, a class instance with fields `a` and `b` will not equal a
* literal object with fields `a` and `b`.
*
* **Usage**
*
* ```js
* const value = { prop: 1 };
* expect(value).toStrictEqual({ prop: 1 });
* ```
*
* @param expected Expected value.
*/
toStrictEqual(expected: unknown): R;
/**
* Calls the function and ensures it throws an error.
*
* Optionally compares the error with `expected`. Allowed expected values:
* - Regular expression - error message should **match** the pattern.
* - String - error message should **include** the substring.
* - Error object - error message should be **equal to** the message property of the object.
* - Error class - error object should be an **instance of** the class.
*
* **Usage**
*
* ```js
* expect(() => {
* throw new Error('Something bad');
* }).toThrow();
*
* expect(() => {
* throw new Error('Something bad');
* }).toThrow(/something/);
*
* expect(() => {
* throw new Error('Something bad');
* }).toThrow(Error);
* ```
*
* @param expected Expected error message or error object.
*/
toThrow(error?: unknown): R;
/**
* An alias for
* [genericAssertions.toThrow([expected])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-throw).
*
* **Usage**
*
* ```js
* expect(() => {
* throw new Error('Something bad');
* }).toThrowError();
* ```
*
* @param expected Expected error message or error object.
*/
toThrowError(error?: unknown): R;
}
type BaseMatchers<R, T> = GenericAssertions<R> & PlaywrightTest.Matchers<R, T>;
type MakeMatchers<R, T> = BaseMatchers<R, T> & {
/**

View file

@ -133,16 +133,86 @@ test('should work with default expect prototype functions', async ({ runTSC, run
}
});
test('should work with default expect matchers', async ({ runTSC }) => {
test('should work with generic matchers', async ({ runTSC }) => {
const result = await runTSC({
'a.spec.ts': `
const { test } = pwt;
test.expect(42).toBe(42);
expect(42).toBe(42);
expect(0.1 + 0.2).toBeCloseTo(0.3, 5);
expect(null).toBeDefined();
expect(null).toBeFalsy();
expect(42).toBeGreaterThan(1);
expect(42).toBeGreaterThanOrEqual(42);
expect({}).toBeInstanceOf(Object);
expect(42).toBeLessThan(100);
expect(42).toBeLessThanOrEqual(42);
expect(null).toBeNull();
expect(42).toBeTruthy();
expect(undefined).toBeUndefined();
expect(NaN).toBeNaN();
expect('abc').toContain('a');
expect(['abc']).toContain('abc');
expect(['abc']).toContainEqual('abc');
expect({}).toEqual({});
expect([1, 2]).toHaveLength(2);
expect('abc').toMatch(/a.?c/);
expect({ a: 1, b: 2 }).toMatchObject({ a: 1 });
expect({}).toStrictEqual({});
expect(() => { throw new Error('Something bad'); }).toThrow('something');
expect(() => { throw new Error('Something bad'); }).toThrowError('something');
`
});
expect(result.exitCode).toBe(0);
});
test('should compile generic matchers', async ({ runTSC }) => {
const result = await runTSC({
'a.spec.ts': `
expect(42).toBe(42);
expect(42).toBeCloseTo(42);
expect(42).toBeCloseTo(42, 5);
expect(42).toBeDefined();
expect(42).toBeFalsy();
expect(42).toBeGreaterThan(1);
expect(42n).toBeGreaterThan(1n);
expect(42).toBeGreaterThanOrEqual(1);
expect(42n).toBeGreaterThanOrEqual(1n);
expect({}).toBeInstanceOf(Object);
expect(42).toBeLessThan(1);
expect(42n).toBeLessThan(1n);
expect(42).toBeLessThanOrEqual(1);
expect(42n).toBeLessThanOrEqual(1n);
expect(42).toBeNull();
expect(42).toBeTruthy();
expect(42).toBeUndefined();
expect(42).toBeNaN();
expect('abc').toContain('b');
expect([1, 2]).toContain(1);
expect(new Set([1, 2])).toContain(1);
expect([{}, { a: 1 }]).toContainEqual({});
expect({}).toEqual({});
expect([1, 2]).toHaveLength(2);
expect('abc').toMatch(/a.?c/);
expect({ a: 1, b: 2 }).toMatchObject({ a: 1 });
expect([]).toMatchObject([]);
expect({}).toStrictEqual({});
expect(() => { throw new Error('Something bad'); }).toThrow('something');
expect(() => { throw new Error('Something bad'); }).toThrow();
expect(() => { throw new Error('Something bad'); }).toThrowError('something');
expect(() => { throw new Error('Something bad'); }).toThrowError();
// @ts-expect-error
expect(42).toBe(123, 456);
// @ts-expect-error
expect(42).toBeCloseTo(42, '5');
// @ts-expect-error
expect(42).toBeFalsy(123);
// @ts-expect-error
expect({}).toBeInstanceOf({});
`,
});
expect(result.exitCode).toBe(0);
});
test('should work with expect message', async ({ runTSC }) => {
const result = await runTSC({
'a.spec.ts': `

View file

@ -22,7 +22,7 @@ const path = require('path');
/** @typedef {import('../../markdown').MarkdownNode} MarkdownNode */
const IGNORE_CLASSES = ['PlaywrightAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'SnapshotAssertions'];
const IGNORE_CLASSES = ['PlaywrightAssertions', 'GenericAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'SnapshotAssertions'];
module.exports = function lint(documentation, jsSources, apiFileName) {
const errors = [];

View file

@ -521,7 +521,7 @@ class TypesGenerator {
const coreDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api'));
const testDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-api'), path.join(PROJECT_DIR, 'docs', 'src', 'api', 'params.md'));
const reporterDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-reporter-api'));
const assertionClasses = new Set(['LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'SnapshotAssertions', 'PlaywrightAssertions']);
const assertionClasses = new Set(['GenericAssertions', 'LocatorAssertions', 'PageAssertions', 'APIResponseAssertions', 'SnapshotAssertions', 'PlaywrightAssertions']);
/**
* @param {boolean} includeExperimental

View file

@ -286,7 +286,35 @@ type Inverse<Matchers> = {
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> = expectType.Matchers<R> & PlaywrightTest.Matchers<R, T>;
interface GenericAssertions<R> {
not: GenericAssertions<R>;
toBe(expected: unknown): R;
toBeCloseTo(expected: number, numDigits?: number): R;
toBeDefined(): R;
toBeFalsy(): R;
toBeGreaterThan(expected: number | bigint): R;
toBeGreaterThanOrEqual(expected: number | bigint): R;
toBeInstanceOf(expected: Function): R;
toBeLessThan(expected: number | bigint): R;
toBeLessThanOrEqual(expected: number | bigint): R;
toBeNaN(): R;
toBeNull(): R;
toBeTruthy(): R;
toBeUndefined(): R;
toContain(expected: string): R;
toContain(expected: unknown): R;
toContainEqual(expected: unknown): R;
toEqual(expected: unknown): R;
toHaveLength(expected: number): R;
toHaveProperty(keyPath: string | Array<string>, value?: unknown): R;
toMatch(expected: RegExp): R;
toMatchObject(expected: Record<string, unknown> | Array<unknown>): R;
toStrictEqual(expected: unknown): R;
toThrow(error?: unknown): R;
toThrowError(error?: unknown): R;
}
type BaseMatchers<R, T> = GenericAssertions<R> & PlaywrightTest.Matchers<R, T>;
type MakeMatchers<R, T> = BaseMatchers<R, T> & {
/**