I’m testing a web page using playwright. The website shows many externally hosted images that sometimes take forever to load, resulting in the tests to time out. All images are hosted on img.domain-name.com
. In order to fix this issue, I’d like to abort long-running image requests.
The documentation shows a way to abort such requests via an interceptor like this:
await context.route(/^https://img.domain-name.com/, route => route.abort());
However, I’d like quick image requests to pass through and only abort those that are long-running.
I tried, setting a timeout for calling route.abort()
, but realized I can only call abort
OR continue
, not both, as I tried.
await context.route(/^https://img.domain-name.com/, (route) => {
const timer = setTimeout(() => {
route.abort()
.catch((error) => console.log(`[${url}] Aborting, caught error: ${error}`));
}, 3_000);
await route.continue()
.then(() => clearTimeout(timer))
.catch(() => clearTimeout(timer));
});
My second approach was to directly handle the requests and pass the responses. That seems to at least work, but results in many tests timing out and the images on the page not properly loading. In theory, the 3s timeout should result in almost all images loading correctly, with very few exceptions.
await context.route(/^https://img.domain-name.com/, (route) => {
const timerPromise: Promise<Error> = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Request timed out')), 3_000)
);
try {
const response: APIResponse | Error = await Promise.race([route.fetch(), timerPromise]);
await route.fulfill({
// @ts-ignore
response
});
} catch (error) {
console.log(`Error: ${error}`);
await route.abort();
}
});
Am I on the right track here or is there a more elegant solution?