Skip to content

Commit e0b7e70

Browse files
committed
fix(playwright): resolve image compare migration test failures
1 parent 0a22b91 commit e0b7e70

2 files changed

Lines changed: 50 additions & 19 deletions

File tree

playwright/support/helpers.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,25 +104,52 @@ async function closeEnvDropdown(page) {
104104
async function openEnv(page, name) {
105105
await page.locator('.navbar-form .rc-tree-select').first().click();
106106

107+
// Cypress uses .contains(expectedText).should('exist') — DOM presence only, NOT visibility.
108+
// The env group node is in the DOM but hidden inside a collapsed tree node.
109+
// We must wait for attachment, then expand, then click the full name.
107110
const idx = name.indexOf('_');
108111
const expectedText = idx > 0 ? name.substring(0, idx) : name;
109112

110113
const tree = page.locator('.rc-tree-select-tree');
111114
await tree
112115
.locator(`text=${expectedText}`)
113116
.first()
114-
.waitFor({ state: 'visible', timeout: 10000 });
117+
.waitFor({ state: 'attached', timeout: 10000 });
115118

116119
await expandAllEnvGroups(page);
117120

118121
await tree.locator(`text=${name}`).first().click({ force: true });
119122
await closeEnvDropdown(page);
120123
}
121124

125+
/**
126+
* Collects exactly `count` download events triggered by `triggerFn`.
127+
* Works correctly even when downloads are staggered (e.g. ImageComparePane
128+
* staggers each link.click() by 300 ms via setTimeout).
129+
* Using Promise.all([waitForEvent, waitForEvent, click]) fails for staggered
130+
* downloads because both promises resolve on the same first event.
131+
*/
132+
async function collectDownloads(page, count, triggerFn) {
133+
const downloads = [];
134+
const done = new Promise((resolve) => {
135+
page.on('download', function handler(dl) {
136+
downloads.push(dl);
137+
if (downloads.length === count) {
138+
page.off('download', handler);
139+
resolve();
140+
}
141+
});
142+
});
143+
await triggerFn();
144+
await done;
145+
return downloads;
146+
}
147+
122148
module.exports = {
123149
runDemo,
124150
closeEnvs,
125151
expandAllEnvGroups,
126152
closeEnvDropdown,
127153
openEnv,
154+
collectDownloads,
128155
};

playwright/tests/image.spec.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99

1010
const { test, expect } = require('@playwright/test');
11-
const { runDemo, openEnv, closeEnvs } = require('../support/helpers');
11+
const { runDemo, openEnv, closeEnvs, collectDownloads } = require('../support/helpers');
1212

1313
const WIN_SEL = '.layout .react-grid-item';
1414
const CONTAINER_SEL = `${WIN_SEL} .content > div`;
@@ -388,18 +388,21 @@ test.describe('Image Pane', () => {
388388

389389
await expect(comparePane.locator('img.content-image')).toHaveCount(2);
390390

391-
// Both downloads fire simultaneously when save is clicked in compare mode
392-
const [dl1, dl2] = await Promise.all([
393-
page.waitForEvent('download'),
394-
page.waitForEvent('download'),
395-
comparePane.locator("button[title='save']").click(),
396-
]);
391+
// ImageComparePane.handleDownload staggers each link.click() by 300ms
392+
// (index * 300 ms setTimeout). Promise.all([waitForEvent, waitForEvent])
393+
// catches both promises on the same first event. Use collectDownloads instead.
394+
const downloads = await collectDownloads(
395+
page,
396+
2,
397+
() => comparePane.locator("button[title='save']").click()
398+
);
397399

398-
const filenames = [dl1.suggestedFilename(), dl2.suggestedFilename()].sort();
400+
const filenames = downloads.map((d) => d.suggestedFilename()).sort();
399401
expect(filenames).toContain('Random!_1.jpg');
400402
expect(filenames).toContain('Random!_2.jpg');
401-
expect(await dl1.path()).toBeTruthy();
402-
expect(await dl2.path()).toBeTruthy();
403+
for (const dl of downloads) {
404+
expect(await dl.path()).toBeTruthy();
405+
}
403406
});
404407

405408
test('image_compare_basic: captions are visible and do not overlap images', async ({
@@ -477,16 +480,17 @@ test.describe('Image Pane', () => {
477480

478481
await expect(comparePane.locator('img.content-image')).toHaveCount(2);
479482

480-
const [dl1, dl2] = await Promise.all([
481-
page.waitForEvent('download'),
482-
page.waitForEvent('download'),
483-
comparePane.locator("button[title='save']").click(),
484-
]);
483+
const downloads = await collectDownloads(
484+
page,
485+
2,
486+
() => comparePane.locator("button[title='save']").click()
487+
);
485488

486-
const filenames = [dl1.suggestedFilename(), dl2.suggestedFilename()].sort();
489+
const filenames = downloads.map((d) => d.suggestedFilename()).sort();
487490
expect(filenames).toContain('CompareTest_1.jpg');
488491
expect(filenames).toContain('CompareTest_2.jpg');
489-
expect(await dl1.path()).toBeTruthy();
490-
expect(await dl2.path()).toBeTruthy();
492+
for (const dl of downloads) {
493+
expect(await dl.path()).toBeTruthy();
494+
}
491495
});
492496
});

0 commit comments

Comments
 (0)