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

+21 -15
View File
@@ -1,11 +1,7 @@
import {
getEnabledElement,
StackViewport,
VolumeViewport,
utilities as csUtils,
Enums as CoreEnums,
Types as CoreTypes,
BaseVolumeViewport,
getRenderingEngines,
} from '@cornerstonejs/core';
import {
@@ -38,6 +34,12 @@ import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/u
import { getViewportEnabledElement } from './utils/getViewportEnabledElement';
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
import toggleVOISliceSync from './utils/toggleVOISliceSync';
import {
isStackViewportType,
isOrthographicViewportType,
isVolume3DViewportType,
isVolumeViewportType,
} from './utils/getLegacyViewportType';
import {
usePositionPresentationStore,
useSegmentationPresentationStore,
@@ -324,7 +326,7 @@ function commandsModule({
// Todo: check if PMAP modality should be handled such as SEG
displaySet.Modality !== 'SEG'
? SegmentationRepresentations.Contour
: viewport.type === CoreEnums.ViewportType.VOLUME_3D
: isVolume3DViewportType(viewport)
? SegmentationRepresentations.Surface
: SegmentationRepresentations.Labelmap;
@@ -910,7 +912,7 @@ function commandsModule({
const { lower, upper } = csUtils.windowLevel.toLowHighRange(windowWidthNum, windowCenterNum);
if (viewport instanceof BaseVolumeViewport) {
if (isVolumeViewportType(viewport)) {
const volumeId = actions.getVolumeIdForDisplaySet({
viewportId,
displaySetInstanceUID,
@@ -986,8 +988,12 @@ function commandsModule({
},
getVolumeIdForDisplaySet: ({ viewportId, displaySetInstanceUID }) => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (viewport instanceof BaseVolumeViewport) {
const volumeIds = viewport.getAllVolumeIds();
// `instanceof BaseVolumeViewport` is false for GenericViewport compat adapters,
// so use the capability guard instead (cornerstone 5.x generic-viewport guide).
// A stack-mode adapter passes the guard but getAllVolumeIds() returns [], so the
// result is the same null as before on stacks.
if (csUtils.viewportSupportsVolumeId(viewport)) {
const volumeIds = (viewport as CoreTypes.IVolumeViewport).getAllVolumeIds();
const volumeId = volumeIds.find(id => id.includes(displaySetInstanceUID));
return volumeId;
}
@@ -1256,7 +1262,7 @@ function commandsModule({
}
const { viewport } = enabledElement;
if (viewport instanceof StackViewport) {
if (isStackViewportType(viewport)) {
if (direction) {
const { parallelScale } = viewport.getCamera();
viewport.setCamera({ parallelScale: parallelScale * scaleFactor });
@@ -1286,9 +1292,9 @@ function commandsModule({
// -> Copied from cornerstone3D jumpToSlice\_getImageSliceData()
let numberOfSlices = 0;
if (viewport instanceof StackViewport) {
if (isStackViewportType(viewport)) {
numberOfSlices = viewport.getImageIds().length;
} else if (viewport instanceof VolumeViewport) {
} else if (isOrthographicViewportType(viewport)) {
numberOfSlices = csUtils.getImageSliceDataForVolumeViewport(viewport).numberOfSlices;
} else {
throw new Error('Unsupported viewport type');
@@ -1344,11 +1350,11 @@ function commandsModule({
// HP takes priority over the default opacity
colormap = { ...colormap, opacity: hpOpacity || opacity };
if (viewport instanceof StackViewport) {
if (isStackViewportType(viewport)) {
viewport.setProperties({ colormap });
}
if (viewport instanceof VolumeViewport) {
if (isOrthographicViewportType(viewport)) {
if (!displaySetInstanceUID) {
const { viewports } = viewportGridService.getState();
displaySetInstanceUID = viewports.get(viewportId)?.displaySetInstanceUIDs[0];
@@ -2145,7 +2151,7 @@ function commandsModule({
setViewportOrientation: ({ viewportId, orientation }) => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport || viewport.type !== CoreEnums.ViewportType.ORTHOGRAPHIC) {
if (!viewport || !isOrthographicViewportType(viewport)) {
console.warn('Orientation can only be set on volume viewports');
return;
}
@@ -2227,7 +2233,7 @@ function commandsModule({
const { viewport } = enabledElement;
if (viewport instanceof BaseVolumeViewport) {
if (isVolumeViewportType(viewport)) {
const camera = viewport.getCamera();
const rotAngle = (rotation * Math.PI) / 180;
const rotMat = mat4.identity(new Float32Array(16));