Skip to content

Commit 1af60d9

Browse files
authored
fix(recorder): coalesce highlight resolutions and update highlights atomically (#43897)
1 parent 6cc61f0 commit 1af60d9

3 files changed

Lines changed: 17 additions & 6 deletions

File tree

‎packages/playwright-core/src/server/highlightController.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export class HighlightController {
4040
private _entries = new Map<string, HighlightEntry>();
4141
private _resolutionTimer: NodeJS.Timeout | undefined;
4242
private _resolutionChain: Promise<void> = Promise.resolve();
43+
private _pendingResolution: Promise<void> | undefined;
4344

4445
constructor(page: Page) {
4546
this._page = page;
@@ -90,8 +91,15 @@ export class HighlightController {
9091
clearTimeout(this._resolutionTimer);
9192
this._resolutionTimer = undefined;
9293
}
93-
this._resolutionChain = this._resolutionChain.then(() => this._resolve()).catch(() => {});
94-
return this._resolutionChain;
94+
// Coalesce multiple queued highlights.
95+
if (!this._pendingResolution) {
96+
this._pendingResolution = this._resolutionChain.then(() => {
97+
this._pendingResolution = undefined;
98+
return this._resolve();
99+
}).catch(() => {});
100+
this._resolutionChain = this._pendingResolution;
101+
}
102+
return this._pendingResolution;
95103
}
96104

97105
private async _resolve() {

‎packages/playwright-core/src/server/recorder.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,11 +370,13 @@ export class Recorder extends EventEmitter<RecorderEventMap> implements Instrume
370370
if (previous && previous.selector === selector && previous.anyFrame === anyFrame)
371371
return;
372372
this._highlightedSelector = selector === undefined ? undefined : { selector, anyFrame };
373-
await Promise.all(this._context.pages().map(async page => {
373+
await Promise.all(this._context.pages().map(page => {
374+
const promises: Promise<void>[] = [];
374375
if (previous)
375-
await page.highlightController.removeHighlight(previous.selector).catch(() => {});
376+
promises.push(page.highlightController.removeHighlight(previous.selector).catch(() => {}));
376377
if (selector)
377-
await page.highlightController.addHighlight(selector, { anyFrame }).catch(() => {});
378+
promises.push(page.highlightController.addHighlight(selector, { anyFrame }).catch(() => {}));
379+
return Promise.all(promises);
378380
}));
379381
}
380382

‎tests/library/inspector/cli-codegen-aria.spec.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ test.describe(() => {
109109

110110
{
111111
// No accessible name => two boxes.
112+
await expect(recorder.page.locator('x-pw-highlight')).toHaveCount(2);
112113
const box11 = roundBox(await submitButton.boundingBox());
113114
const box12 = roundBox(await recorder.page.locator('x-pw-highlight').first().boundingBox());
114115
expect(box11).toEqual(box12);
@@ -121,7 +122,7 @@ test.describe(() => {
121122
{
122123
// Different button.
123124
await recorder.recorderPage.locator('.tab-aria .CodeMirror').pressSequentially('"Cancel"');
124-
await expect(recorder.page.locator('x-pw-highlight')).toBeVisible();
125+
await expect(recorder.page.locator('x-pw-highlight')).toHaveCount(1);
125126
const box1 = roundBox(await cancelButton.boundingBox());
126127
const box2 = roundBox(await recorder.page.locator('x-pw-highlight').boundingBox());
127128
expect(box1).toEqual(box2);

0 commit comments

Comments
 (0)