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;
|
return abortController;
|
||||||
};
|
};
|
||||||
|
|
||||||
await Promise.allSettled(
|
const results = await Promise.allSettled(
|
||||||
this.#locators.map(locator => {
|
this.#locators.map(locator => {
|
||||||
return action(
|
return action(
|
||||||
locator.on(LocatorEmittedEvents.Action, handleLocatorAction(locator)),
|
locator.on(LocatorEmittedEvents.Action, handleLocatorAction(locator)),
|
||||||
@ -732,6 +732,26 @@ class RaceLocatorImpl extends Locator {
|
|||||||
);
|
);
|
||||||
|
|
||||||
options.signal?.throwIfAborted();
|
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(
|
override async click(
|
||||||
|
@ -222,7 +222,9 @@ describe('Locator', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should time out', async () => {
|
it('should time out', async () => {
|
||||||
const clock = sinon.useFakeTimers();
|
const clock = sinon.useFakeTimers({
|
||||||
|
shouldClearNativeTimers: true,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
|
|
||||||
@ -243,7 +245,9 @@ describe('Locator', function () {
|
|||||||
|
|
||||||
it('should retry clicks on errors', async () => {
|
it('should retry clicks on errors', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
const clock = sinon.useFakeTimers();
|
const clock = sinon.useFakeTimers({
|
||||||
|
shouldClearNativeTimers: true,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
page.setDefaultTimeout(5000);
|
page.setDefaultTimeout(5000);
|
||||||
await page.setViewport({width: 500, height: 500});
|
await page.setViewport({width: 500, height: 500});
|
||||||
@ -262,7 +266,9 @@ describe('Locator', function () {
|
|||||||
|
|
||||||
it('can be aborted', async () => {
|
it('can be aborted', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
const clock = sinon.useFakeTimers();
|
const clock = sinon.useFakeTimers({
|
||||||
|
shouldClearNativeTimers: true,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
page.setDefaultTimeout(5000);
|
page.setDefaultTimeout(5000);
|
||||||
|
|
||||||
@ -476,7 +482,9 @@ describe('Locator', function () {
|
|||||||
|
|
||||||
it('can be aborted', async () => {
|
it('can be aborted', async () => {
|
||||||
const {page} = await getTestState();
|
const {page} = await getTestState();
|
||||||
const clock = sinon.useFakeTimers();
|
const clock = sinon.useFakeTimers({
|
||||||
|
shouldClearNativeTimers: true,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
await page.setViewport({width: 500, height: 500});
|
await page.setViewport({width: 500, height: 500});
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -498,5 +506,36 @@ describe('Locator', function () {
|
|||||||
clock.restore();
|
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