fix: ohif tests to run with cornerstone 3d 5.0 (#6043)

* chore(tests): Update multiple screenshot test images for various specs

* feat(screenshot-reviewer): Add screenshot review tool and update package.json scripts

* fix(DICOMSRDisplayTool): Improve actor presence check in viewport

* chore(tests): Update multiple screenshot assets for various specs

* chore(tests): Integrate waitForPaintToSettle and waitForViewportsRendered in multiple specs for improved rendering stability

* chore(tests): Update screenshot assets for SEGHydration and SEGNoHydration specs

* test: update progressive loading screenshots

* jest 30 test fixes for compatibility with pnpm cs3d

* Use correct setDisplaySets instead of setDataId

* fix: Naming change for LegacyVolumeViewport3D

* Update to allow tolerance for contour tests

* update

* fix

* refactor: Replace instanceof checks with utility functions for viewport type validation

* fix: Update createSegmentationForViewport to handle undefined displaySetInstanceUID gracefully

* bun lock

* fix: Install cs3d with pnpm instead of bun

* Update node version for playwright

* Update to v5.0.0 of cs3d

* fix: Build dependency

* audit

* Change to a web await retry assert

* Fix timing related test failures

* fix: Freehand close

---------

Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
This commit is contained in:
AlirezaandBill Wallace authored and GitHub committed 2026-06-09 20:25:14 -04:00
1 parent a27f779f0b
commit 6dd150d401
172 files changed
+3081 -1866

No files matched your search

+2
View File
@@ -32,6 +32,7 @@ import {
waitForAnyViewportNeedsRender,
waitForViewportsRendered,
waitForViewportRenderCycle,
waitForPaintToSettle,
} from './waitForViewportsRendered';
export {
@@ -62,6 +63,7 @@ export {
waitForAnyViewportNeedsRender,
waitForViewportsRendered,
waitForViewportRenderCycle,
waitForPaintToSettle,
test,
expect,
};
+58 -4
View File
@@ -11,6 +11,12 @@ type WaitForViewportsRenderedOptions = {
* viewports to report loaded.
*/
waitVolumeLoad?: boolean;
/**
* If true (default), inserts a post-rendered "settle" step that waits two
* animation frames and a short idle window so the GPU has presented the
* final paint before screenshots are taken.
*/
settle?: boolean;
};
type WaitForRenderCycleToCompleteOptions = {
@@ -28,6 +34,10 @@ type WaitForRenderCycleToCompleteOptions = {
* viewports to report loaded during the rendered phase.
*/
waitVolumeLoad?: boolean;
/**
* If true (default), inserts a post-rendered "settle" step before resolving.
*/
settle?: boolean;
};
/**
@@ -39,9 +49,14 @@ const waitForViewportRenderCycle = async (
page: Page,
options: WaitForRenderCycleToCompleteOptions = {}
) => {
const { needsRenderTimeout = 5000, renderedTimeout = 15000, waitVolumeLoad = true } = options;
const {
needsRenderTimeout = 5000,
renderedTimeout = 15000,
waitVolumeLoad = true,
settle = true,
} = options;
await waitForAnyViewportNeedsRender(page, { timeout: needsRenderTimeout });
await waitForViewportsRendered(page, { timeout: renderedTimeout, waitVolumeLoad });
await waitForViewportsRendered(page, { timeout: renderedTimeout, waitVolumeLoad, settle });
};
/**
@@ -93,7 +108,7 @@ const waitForViewportsRendered = async (
page: Page,
options: WaitForViewportsRenderedOptions = {}
) => {
const { timeout = 15000, waitVolumeLoad = true } = options;
const { timeout = 15000, waitVolumeLoad = true, settle = true } = options;
await page.waitForFunction(
({ waitVolumeLoad }) => {
@@ -158,6 +173,45 @@ const waitForViewportsRendered = async (
{ waitVolumeLoad },
{ timeout }
);
if (settle) {
await waitForPaintToSettle(page);
}
};
export { waitForViewportsRendered, waitForAnyViewportNeedsRender, waitForViewportRenderCycle };
/**
* After the render-cycle predicate has resolved, give the browser two animation
* frames (RAF fires *before* the paint commits, so we wait for two consecutive
* frames plus a microtask) followed by a short idle window. This drains the
* tail of any progressive texture uploads that landed in the same tick the
* `loadStatus.loaded` flag was flipped, so screenshots capture the final paint
* rather than a mid-stream frame. Mirrors the `scheduleAfterPaint` deferral in
* BaseStreamingImageVolume on the cs3d side.
*/
const waitForPaintToSettle = async (page: Page) => {
await page.evaluate(
() =>
new Promise<void>(resolve => {
const raf = (cb: FrameRequestCallback) =>
typeof requestAnimationFrame === 'function'
? requestAnimationFrame(cb)
: (setTimeout(cb, 16) as unknown as number);
raf(() =>
raf(() => {
Promise.resolve().then(resolve);
})
);
})
);
// Final guard against stragglers (e.g. label-outline edge detection that
// queues an extra render via requestAnimationFrame from inside an event
// handler).
await page.waitForTimeout(150);
};
export {
waitForViewportsRendered,
waitForAnyViewportNeedsRender,
waitForViewportRenderCycle,
waitForPaintToSettle,
};