Skip to content

Commit e0a4c4a

Browse files
committed
test(e2e): atomic DOM queries in waitForViews and session-state polling
Same fix as waitForViewCounts: replace iteration over WDIO element handles with a single browser.execute. Eliminates the remaining 40 stale-element warnings per CI run originating from waitForViews (canvas.getAttribute on remounting views) and the four $$().length loops in session-state-lifecycle.e2e.ts.
1 parent 4b3085a commit e0a4c4a

2 files changed

Lines changed: 22 additions & 58 deletions

File tree

tests/pageobjects/volview.page.ts

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,44 +53,15 @@ class VolViewPage extends Page {
5353
async waitForViews(timeout = DOWNLOAD_TIMEOUT) {
5454
await browser.waitUntil(
5555
async () => {
56-
try {
57-
// Query views once per iteration to avoid multiple queries that could become stale
58-
const currentViews = await this.views;
59-
const viewCount = await currentViews.length;
60-
61-
if (viewCount === 0) {
62-
return false;
63-
}
64-
65-
// Check each view's dimensions in a single pass
66-
const viewPromises = currentViews.map(async (view) => {
67-
try {
68-
// Get attributes directly from the element reference
69-
const width = await view.getAttribute('width');
70-
const height = await view.getAttribute('height');
71-
72-
if (width && height) {
73-
const w = parseInt(width, 10);
74-
const h = parseInt(height, 10);
75-
// Canvas should have real dimensions, not be a 1x1 placeholder
76-
// Accept any size > 10 as a real view
77-
return w > 10 && h > 10;
78-
}
79-
return false;
80-
} catch {
81-
// Element may have been removed/recreated - that's ok, we'll retry
82-
return false;
83-
}
56+
return browser.execute(() => {
57+
const canvases = document.querySelectorAll(
58+
'div[data-testid~="vtk-view"] canvas'
59+
);
60+
return Array.from(canvases).some((c) => {
61+
const canvas = c as HTMLCanvasElement;
62+
return canvas.width > 10 && canvas.height > 10;
8463
});
85-
86-
const results = await Promise.all(await viewPromises);
87-
88-
// At least one view must have real dimensions
89-
return results.some((result) => result);
90-
} catch {
91-
// DOM may be updating, retry on next iteration
92-
return false;
93-
}
64+
});
9465
},
9566
{
9667
timeout,

tests/specs/session-state-lifecycle.e2e.ts

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ import { TEMP_DIR } from '../../wdio.shared.conf';
88

99
const SESSION_SAVE_TIMEOUT = 40000;
1010

11+
const waitForElementCount = async (selector: string, minCount = 1) => {
12+
await browser.waitUntil(async () => {
13+
const count = await browser.execute(
14+
(sel) => document.querySelectorAll(sel).length,
15+
selector
16+
);
17+
return count >= minCount;
18+
});
19+
};
20+
1121
const saveSession = async () => {
1222
const sessionFileName = await volViewPage.saveSession();
1323
const downloadedPath = path.join(TEMP_DIR, sessionFileName);
@@ -59,28 +69,14 @@ describe('Session state lifecycle', () => {
5969
await measurementsTab.waitForClickable();
6070
await measurementsTab.click();
6171

62-
await browser.waitUntil(async () => {
63-
const rectangleEntries = await $$(
64-
'.v-list-item i.mdi-vector-square.tool-icon'
65-
);
66-
return (await rectangleEntries.length) >= 1;
67-
});
68-
69-
await browser.waitUntil(async () => {
70-
const polygonEntries = await $$(
71-
'.v-list-item i.mdi-pentagon-outline.tool-icon'
72-
);
73-
return (await polygonEntries.length) >= 1;
74-
});
72+
await waitForElementCount('.v-list-item i.mdi-vector-square.tool-icon');
73+
await waitForElementCount('.v-list-item i.mdi-pentagon-outline.tool-icon');
7574

7675
const segmentGroupsTab = await $('button.v-tab*=Segment Groups');
7776
await segmentGroupsTab.waitForClickable();
7877
await segmentGroupsTab.click();
7978

80-
await browser.waitUntil(async () => {
81-
const segmentGroups = await $$('.segment-group-list .v-list-item');
82-
return (await segmentGroups.length) >= 1;
83-
});
79+
await waitForElementCount('.segment-group-list .v-list-item');
8480
});
8581

8682
it('edited label strokeWidth persists through save/load cycle', async () => {
@@ -96,10 +92,7 @@ describe('Session state lifecycle', () => {
9692
);
9793
await annotationsTab.click();
9894

99-
await browser.waitUntil(async () => {
100-
const buttons = await volViewPage.editLabelButtons;
101-
return (await buttons.length) >= 1;
102-
});
95+
await waitForElementCount('button[data-testid="edit-label-button"]');
10396

10497
const buttons = await volViewPage.editLabelButtons;
10598
await buttons[0].click();

0 commit comments

Comments
 (0)