From 333c89a023fe5b2874b42ebb2c2992d51efdfc19 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 30 Oct 2025 15:59:59 -0700 Subject: [PATCH] chore: support arrayOf --- docs/src/api/class-genericassertions.md | 23 +++++++++++++++++++++++ docs/src/test-assertions-js.md | 1 + packages/playwright/types/test.d.ts | 22 ++++++++++++++++++++++ tests/playwright-test/expect.spec.ts | 18 ++++++++++++++++++ utils/generate_types/index.js | 1 + utils/generate_types/overrides-test.d.ts | 1 + 6 files changed, 66 insertions(+) diff --git a/docs/src/api/class-genericassertions.md b/docs/src/api/class-genericassertions.md index 180a15dc4b378..603995eddd4e0 100644 --- a/docs/src/api/class-genericassertions.md +++ b/docs/src/api/class-genericassertions.md @@ -354,6 +354,7 @@ expect(value).toEqual({ prop: 1 }); * [`method: GenericAssertions.any`] * [`method: GenericAssertions.anything`] * [`method: GenericAssertions.arrayContaining`] +* [`method: GenericAssertions.arrayOf`] * [`method: GenericAssertions.closeTo`] * [`method: GenericAssertions.objectContaining`] * [`method: GenericAssertions.stringContaining`] @@ -625,6 +626,28 @@ expect([1, 2, 3]).not.toEqual(expect.arrayContaining([1, 4])); Expected array that is a subset of the received value. +## method: GenericAssertions.arrayOf +* since: v1.57 + +`expect.arrayOf()` matches array of objects created from the [`param: constructor`] or a corresponding primitive type. Use it inside [`method: GenericAssertions.toEqual`] to perform pattern matching. + +**Usage** + +```js +// Match instance of a class. +class Example {} +expect([new Example(), new Example()]).toEqual(expect.arrayOf(Example)); + +// Match any string. +expect(['a', 'b', 'c']).toEqual(expect.arrayOf(String)); +``` + +### param: GenericAssertions.arrayOf.constructor +* since: v1.57 +- `constructor` <[Function]> + +Constructor of the expected object like `ExampleClass`, or a primitive boxed type like `Number`. + ## method: GenericAssertions.closeTo * since: v1.9 diff --git a/docs/src/test-assertions-js.md b/docs/src/test-assertions-js.md index 3efc0db5e5894..59f30b3bba808 100644 --- a/docs/src/test-assertions-js.md +++ b/docs/src/test-assertions-js.md @@ -94,6 +94,7 @@ Prefer [auto-retrying](#auto-retrying-assertions) assertions whenever possible. | [`method: GenericAssertions.any`] | Matches any instance of a class/primitive | | [`method: GenericAssertions.anything`] | Matches anything | | [`method: GenericAssertions.arrayContaining`] | Array contains specific elements | +| [`method: GenericAssertions.arrayOf`] | Array contains elements of specific type | | [`method: GenericAssertions.closeTo`] | Number is approximately equal | | [`method: GenericAssertions.objectContaining`] | Object contains specific properties | | [`method: GenericAssertions.stringContaining`] | String contains a substring | diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 0dcb5d4c600df..b5babaa8d908e 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -7728,6 +7728,27 @@ interface AsymmetricMatchers { * @param expected Expected array that is a subset of the received value. */ arrayContaining(sample: Array): AsymmetricMatcher; + /** + * `expect.arrayOf()` matches array of objects created from the + * [`constructor`](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-array-of-option-constructor) + * or a corresponding primitive type. Use it inside + * [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal) + * to perform pattern matching. + * + * **Usage** + * + * ```js + * // Match instance of a class. + * class Example {} + * expect([new Example(), new Example()]).toEqual(expect.arrayOf(Example)); + * + * // Match any string. + * expect(['a', 'b', 'c']).toEqual(expect.arrayOf(String)); + * ``` + * + * @param constructor Constructor of the expected object like `ExampleClass`, or a primitive boxed type like `Number`. + */ + arrayOf(sample: unknown): AsymmetricMatcher; /** * Compares floating point numbers for approximate equality. Use this method inside * [expect(value).toEqual(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-equal) @@ -8111,6 +8132,7 @@ interface GenericAssertions { * - [expect(value).any(constructor)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-any) * - [expect(value).anything()](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-anything) * - [expect(value).arrayContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-array-containing) + * - [expect(value).arrayOf(constructor)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-array-of) * - [expect(value).closeTo(expected[, numDigits])](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-close-to) * - [expect(value).objectContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-object-containing) * - [expect(value).stringContaining(expected)](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-string-containing) diff --git a/tests/playwright-test/expect.spec.ts b/tests/playwright-test/expect.spec.ts index 43c42447b6f00..67ec3bac0eef7 100644 --- a/tests/playwright-test/expect.spec.ts +++ b/tests/playwright-test/expect.spec.ts @@ -1301,3 +1301,21 @@ test('multiple custom asymmetric matchers in async expect should present the cor expect(result.output).toContain('- \"aProperty\": isUndefined<>'); expect(result.output).toContain('+ \"aProperty\": \"foo\"'); }); + +test('should support arrayOf', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'expect-test.spec.ts': ` + import { test, expect } from '@playwright/test'; + test('pass', () => { + expect([1,2,3]).toEqual(expect.arrayOf(expect.any(Number))); + }); + test('fail', () => { + expect([1,2,'3']).toEqual(expect.arrayOf(expect.any(Number))); + }); + ` + }); + expect(result.exitCode).toBe(1); + expect(result.passed).toBe(1); + expect(result.failed).toBe(1); + expect(result.output).toContain('ArrayOf Any'); +}); diff --git a/utils/generate_types/index.js b/utils/generate_types/index.js index 809da4c96b01d..a34e6f7941634 100644 --- a/utils/generate_types/index.js +++ b/utils/generate_types/index.js @@ -551,6 +551,7 @@ class TypesGenerator { 'GenericAssertions.any', 'GenericAssertions.anything', 'GenericAssertions.arrayContaining', + 'GenericAssertions.arrayOf', 'GenericAssertions.closeTo', 'GenericAssertions.objectContaining', 'GenericAssertions.stringContaining', diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 665c7ecd32d12..7b46b3402b491 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -321,6 +321,7 @@ interface AsymmetricMatchers { any(sample: unknown): AsymmetricMatcher; anything(): AsymmetricMatcher; arrayContaining(sample: Array): AsymmetricMatcher; + arrayOf(sample: unknown): AsymmetricMatcher; closeTo(sample: number, precision?: number): AsymmetricMatcher; objectContaining(sample: Record): AsymmetricMatcher; stringContaining(sample: string): AsymmetricMatcher;