feat: Support intervals arg for toPass (#30037)

Fixes #30040

# Context

In the `playwright.config` file, we can custom the default `timeout`
property for `expect.toPass` by the property:

```ts title='playwright.config.ts'
export default defineConfig({
  // ...
  expect: {
    toPass: {
      timeout: 60_000,
    },
  },
});
```

However, we can't customize the `intervals` option. So the default value
is always `[100, 250, 500, 1000]`.

# Goal

Add the possibility to customize the intervals option from the
`playwright.config` file.

```ts title='playwright.config.ts'
export default defineConfig({
  // ...
  expect: {
    toPass: {
      timeout: 60_000,
      intervals: [1000, 2000, 3000]
    },
  },
});
```
This commit is contained in:
Hansanto 2024-03-29 18:17:29 +01:00 committed by GitHub
parent 3001c9ac73
commit a950a7b86b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 52 additions and 1 deletions

View File

@ -54,6 +54,7 @@ export default defineConfig({
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
- `toPass` ?<[Object]> Configuration for the [expect(value).toPass()](../test-assertions.md#expecttopass) method.
- `timeout` ?<[int]> timeout for toPass method in milliseconds.
- `intervals` ?<[Array]<[int]>> probe intervals for toPass method in milliseconds.
Configuration for the `expect` assertion library. Learn more about [various timeouts](../test-timeouts.md).

View File

@ -104,6 +104,7 @@ export default defineConfig({
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
- `toPass` ?<[Object]> Configuration for the [expect(value).toPass()](../test-assertions.md) method.
- `timeout` ?<[int]> timeout for toPass method in milliseconds.
- `intervals` ?<[Array]<[int]>> probe intervals for toPass method in milliseconds.
Configuration for the `expect` assertion library.

View File

@ -369,6 +369,7 @@ export async function toPass(
) {
const testInfo = currentTestInfo();
const timeout = takeFirst(options.timeout, testInfo?._projectInternal.expect?.toPass?.timeout, 0);
const intervals = takeFirst(options.intervals, testInfo?._projectInternal.expect?.toPass?.intervals, [100, 250, 500, 1000]);
const { deadline, timeoutMessage } = testInfo ? testInfo._deadlineForMatcher(timeout) : TestInfoImpl._defaultDeadlineForMatcher(timeout);
const result = await pollAgainstDeadline<Error|undefined>(async () => {
@ -380,7 +381,7 @@ export async function toPass(
} catch (e) {
return { continuePolling: !this.isNot, result: e };
}
}, deadline, options.intervals || [100, 250, 500, 1000]);
}, deadline, intervals);
if (result.timedOut) {
const message = result.result ? [

View File

@ -702,6 +702,11 @@ interface TestConfig {
* timeout for toPass method in milliseconds.
*/
timeout?: number;
/**
* probe intervals for toPass method in milliseconds.
*/
intervals?: Array<number>;
};
};
@ -8597,6 +8602,11 @@ interface TestProject {
* timeout for toPass method in milliseconds.
*/
timeout?: number;
/**
* probe intervals for toPass method in milliseconds.
*/
intervals?: Array<number>;
};
};

View File

@ -260,3 +260,41 @@ test('should give priority to timeout parameter over timeout in config file', as
4 | await test.expect(() => {
`.trim());
});
test('should respect intervals in config file when intervals parameter is not passed', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.js': `module.exports = { expect: { toPass: { timeout: 2000, intervals: [100, 1000] } } }`,
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('should fail', async () => {
let attempt = 0;
await test.expect(() => {
expect(++attempt).toBe(-1);
}).toPass();
});
`
});
expect(result.exitCode).toBe(1);
expect(result.output).toContain('Error: expect(received).toBe(expected) // Object.is equality');
expect(result.output).toContain('Expected: -1');
expect(result.output).toContain('Received: 3');
});
test('should give priority to intervals parameter over intervals in config file', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.js': `module.exports = { expect: { toPass: { timeout: 2000, intervals: [100] } } }`,
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('should fail', async () => {
let attempt = 0;
await test.expect(() => {
expect(++attempt).toBe(-1);
}).toPass({ intervals: [100, 1000] });
});
`
});
expect(result.exitCode).toBe(1);
expect(result.output).toContain('Error: expect(received).toBe(expected) // Object.is equality');
expect(result.output).toContain('Expected: -1');
expect(result.output).toContain('Received: 3');
});