fix(expect): poll/toPass should not wait over specified timeout (#20266)

Drive-by: unflake some timeout-dependent tests.
This commit is contained in:
Dmitry Gozman 2023-01-20 15:47:24 -08:00 committed by GitHub
parent d8e8ddba20
commit eafa6fda13
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 10 deletions

View file

@ -126,7 +126,12 @@ export async function pollAgainstTimeout<T>(callback: () => Promise<{ continuePo
lastResult = received.result.result; lastResult = received.result.result;
if (!received.result.continuePolling) if (!received.result.continuePolling)
return { result: received.result.result, timedOut: false }; return { result: received.result.result, timedOut: false };
await new Promise(x => setTimeout(x, pollIntervals!.shift() ?? lastPollInterval)); let interval = pollIntervals!.shift() ?? lastPollInterval;
if (timeout !== 0) {
const elapsed = monotonicTime() - startTime;
interval = Math.min(interval, Math.max(timeout - elapsed, 1));
}
await new Promise(x => setTimeout(x, interval));
} }
return { timedOut: true, result: lastResult }; return { timedOut: true, result: lastResult };
} }

View file

@ -311,7 +311,7 @@ export async function toBeOK(
export async function toPass( export async function toPass(
this: ReturnType<Expect['getState']>, this: ReturnType<Expect['getState']>,
callback: () => void, callback: () => any,
options: { options: {
intervals?: number[]; intervals?: number[];
timeout?: number, timeout?: number,

View file

@ -56,10 +56,10 @@ it('should support global userAgent option', async ({ playwright, server }) => {
}); });
it('should support global timeout option', async ({ playwright, server }) => { it('should support global timeout option', async ({ playwright, server }) => {
const request = await playwright.request.newContext({ timeout: 1 }); const request = await playwright.request.newContext({ timeout: 100 });
server.setRoute('/empty.html', (req, res) => {}); server.setRoute('/empty.html', (req, res) => {});
const error = await request.get(server.EMPTY_PAGE).catch(e => e); const error = await request.get(server.EMPTY_PAGE).catch(e => e);
expect(error.message).toContain('Request timed out after 1ms'); expect(error.message).toContain('Request timed out after 100ms');
}); });
it('should propagate extra http headers with redirects', async ({ playwright, server }) => { it('should propagate extra http headers with redirects', async ({ playwright, server }) => {

View file

@ -208,9 +208,11 @@ test('should respect interval', async ({ runInlineTest }) => {
const { test } = pwt; const { test } = pwt;
test('should fail', async () => { test('should fail', async () => {
let probes = 0; let probes = 0;
await test.expect.poll(() => ++probes, { timeout: 1000, intervals: [600] }).toBe(3).catch(() => {}); const startTime = Date.now();
// Probe at 0s, at 0.6s. await test.expect.poll(() => ++probes, { timeout: 1000, intervals: [0, 10000] }).toBe(3).catch(() => {});
// Probe at 0 and epsilon.
expect(probes).toBe(2); expect(probes).toBe(2);
expect(Date.now() - startTime).toBeLessThan(5000);
}); });
` `
}); });

View file

@ -100,12 +100,14 @@ test('should respect interval', async ({ runInlineTest }) => {
const { test } = pwt; const { test } = pwt;
test('should fail', async () => { test('should fail', async () => {
let probes = 0; let probes = 0;
const startTime = Date.now();
await test.expect(() => { await test.expect(() => {
++probes ++probes;
expect(1).toBe(2); expect(1).toBe(2);
}).toPass({ timeout: 1000, intervals: [600] }).catch(() => {}); }).toPass({ timeout: 1000, intervals: [0, 10000] }).catch(() => {});
// Probe at 0s, at 0.6s. // Probe at 0 and epsilon.
expect(probes).toBe(2); expect(probes).toBe(2);
expect(Date.now() - startTime).toBeLessThan(5000);
}); });
` `
}); });
@ -157,7 +159,7 @@ test('should work with soft', async ({ runInlineTest }) => {
test('should respect soft', async () => { test('should respect soft', async () => {
await test.expect.soft(() => { await test.expect.soft(() => {
expect(1).toBe(3); expect(1).toBe(3);
}).toPass({ timeout: 1 }); }).toPass({ timeout: 1000 });
expect.soft(2).toBe(3); expect.soft(2).toBe(3);
}); });
` `