mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix(locators): reject the race if there are only failures (#10567)
This commit is contained in:
parent
7af3e8d1fc
commit
e3dd5968ca
@ -722,7 +722,7 @@ class RaceLocatorImpl extends Locator {
|
||||
return abortController;
|
||||
};
|
||||
|
||||
await Promise.allSettled(
|
||||
const results = await Promise.allSettled(
|
||||
this.#locators.map(locator => {
|
||||
return action(
|
||||
locator.on(LocatorEmittedEvents.Action, handleLocatorAction(locator)),
|
||||
@ -732,6 +732,26 @@ class RaceLocatorImpl extends Locator {
|
||||
);
|
||||
|
||||
options.signal?.throwIfAborted();
|
||||
|
||||
const rejected = results.filter(
|
||||
(result): result is PromiseRejectedResult => {
|
||||
return result.status === 'rejected';
|
||||
}
|
||||
);
|
||||
|
||||
// If some locators are fulfilled, do not throw.
|
||||
if (rejected.length !== results.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const result of rejected) {
|
||||
const reason = result.reason;
|
||||
// AbortError is be an expected result of a race.
|
||||
if (isErrorLike(reason) && reason.name === 'AbortError') {
|
||||
continue;
|
||||
}
|
||||
throw reason;
|
||||
}
|
||||
}
|
||||
|
||||
override async click(
|
||||
|
@ -222,7 +222,9 @@ describe('Locator', function () {
|
||||
});
|
||||
|
||||
it('should time out', async () => {
|
||||
const clock = sinon.useFakeTimers();
|
||||
const clock = sinon.useFakeTimers({
|
||||
shouldClearNativeTimers: true,
|
||||
});
|
||||
try {
|
||||
const {page} = await getTestState();
|
||||
|
||||
@ -243,7 +245,9 @@ describe('Locator', function () {
|
||||
|
||||
it('should retry clicks on errors', async () => {
|
||||
const {page} = await getTestState();
|
||||
const clock = sinon.useFakeTimers();
|
||||
const clock = sinon.useFakeTimers({
|
||||
shouldClearNativeTimers: true,
|
||||
});
|
||||
try {
|
||||
page.setDefaultTimeout(5000);
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -262,7 +266,9 @@ describe('Locator', function () {
|
||||
|
||||
it('can be aborted', async () => {
|
||||
const {page} = await getTestState();
|
||||
const clock = sinon.useFakeTimers();
|
||||
const clock = sinon.useFakeTimers({
|
||||
shouldClearNativeTimers: true,
|
||||
});
|
||||
try {
|
||||
page.setDefaultTimeout(5000);
|
||||
|
||||
@ -476,7 +482,9 @@ describe('Locator', function () {
|
||||
|
||||
it('can be aborted', async () => {
|
||||
const {page} = await getTestState();
|
||||
const clock = sinon.useFakeTimers();
|
||||
const clock = sinon.useFakeTimers({
|
||||
shouldClearNativeTimers: true,
|
||||
});
|
||||
try {
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.setContent(`
|
||||
@ -498,5 +506,36 @@ describe('Locator', function () {
|
||||
clock.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it('should time out when all locators do not match', async () => {
|
||||
const clock = sinon.useFakeTimers({
|
||||
shouldClearNativeTimers: true,
|
||||
});
|
||||
try {
|
||||
const {page} = await getTestState();
|
||||
page.setDefaultTimeout(5000);
|
||||
await page.setContent(`<button>test</button>`);
|
||||
const result = Locator.race([
|
||||
page.locator('not-found'),
|
||||
page.locator('not-found'),
|
||||
]).click();
|
||||
clock.tick(5100);
|
||||
await expect(result).rejects.toEqual(
|
||||
new TimeoutError('waitForFunction timed out. The timeout is 5000ms.')
|
||||
);
|
||||
} finally {
|
||||
clock.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it('should not time out when one of the locators matches', async () => {
|
||||
const {page} = await getTestState();
|
||||
await page.setContent(`<button>test</button>`);
|
||||
const result = Locator.race([
|
||||
page.locator('not-found'),
|
||||
page.locator('button'),
|
||||
]).click();
|
||||
await expect(result).resolves.toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user