fix(segmentation): Removed LOAD/hydrate button for segmentation overlays (#5214)

This commit is contained in:
Joe Boccanfuso 2025-07-15 09:02:36 -04:00 committed by GitHub
parent 302705ea4d
commit e0289dc49f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 95 additions and 7 deletions

View File

@ -41,7 +41,6 @@ function OHIFCornerstoneRTViewport(props: withAppTypes) {
const [{ viewports, activeViewportId }, viewportGridService] = useViewportGrid();
// States
const selectedSegmentObjectIndex: number = 0;
const { setPositionPresentation } = usePositionPresentationStore();
const [rtIsLoading, setRtIsLoading] = useState(!rtDisplaySet.isLoaded);
const [processingProgress, setProcessingProgress] = useState({

View File

@ -17,13 +17,13 @@ function ModalityLoadBadge({ viewportId }: { viewportId: string }) {
const { isTracked, isLocked } = useMeasurementTracking({ viewportId });
const { backgroundDisplaySet, overlayDisplaySets } = useViewportDisplaySets(viewportId);
const { backgroundDisplaySet } = useViewportDisplaySets(viewportId);
const [specialDisplaySet, setSpecialDisplaySet] = useState(null);
const allDisplaySets = useMemo(() => {
return [backgroundDisplaySet, ...overlayDisplaySets].filter(Boolean);
}, [backgroundDisplaySet, overlayDisplaySets]);
return [backgroundDisplaySet].filter(Boolean);
}, [backgroundDisplaySet]);
useEffect(() => {
const displaySet = allDisplaySets.find(ds => ds.isOverlayDisplaySet || ds?.Modality === 'SR');
@ -120,7 +120,10 @@ function ModalityLoadBadge({ viewportId }: { viewportId: string }) {
const StatusArea = () => {
if (!statusInfo.isHydrated) {
return (
<div className="flex h-6 cursor-default text-sm leading-6 text-white">
<div
data-cy={`ModalityLoadBadge-${viewportId}`}
className="flex h-6 cursor-default text-sm leading-6 text-white"
>
<div className="bg-customgray-100 flex min-w-[45px] items-center rounded-l-xl rounded-r p-1">
<StatusIcon />
<span className="ml-1">{statusInfo.type}</span>

View File

@ -58,8 +58,8 @@
"test:e2e:ci": "TEST_ENV=true npx playwright test",
"test:e2e:ui": "TEST_ENV=true npx playwright test --ui",
"test:e2e:reporter": "TEST_ENV=true npx playwright test --reporter=html",
"test:e2e:update": "TEST_ENV=true npx playwright test --reporter=html --update-snapshots",
"test:e2e:update:debug": "TEST_ENV=true npx playwright test -g @debug --reporter=html --update-snapshots ",
"test:e2e:update": "TEST_ENV=true npx playwright test --reporter=html --update-snapshots -g shouldUpdateThis",
"test:e2e:update:debug": "TEST_ENV=true npx playwright test -g @debug --reporter=html --update-snapshots -g shouldUpdateThis",
"test:e2e:headed": "TEST_ENV=true npx playwright test --headed",
"test:e2e:debug": "TEST_ENV=true npx playwright test --debug",
"test:e2e:dist": "lerna run test:e2e:dist --stream",

View File

@ -13,6 +13,8 @@ test('should display added, selected and removed segmentation promptly', async (
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('2d-tta_nnU-Net_Segmentation').click();
await page.waitForTimeout(5000);
await checkForScreenshot({
page,
screenshotPath:
@ -25,6 +27,8 @@ test('should display added, selected and removed segmentation promptly', async (
// navigate to the 51st image and ensure the correct overlay is displayed
await press({ page, key: 'ArrowDown', nTimes: 50 });
await page.waitForTimeout(5000);
await checkForScreenshot({
page,
screenshotPath: screenShotPaths.dataOverlayMenu.overlay2d_tta_nnU_Net_Segmentation,
@ -37,6 +41,8 @@ test('should display added, selected and removed segmentation promptly', async (
await page.getByTestId('overlay-ds-select-value-2D-TTA_NNU-NET_SEGMENTATION').click();
await page.getByTestId('Segmentation-SEG').click();
await page.waitForTimeout(5000);
await checkForScreenshot({
page,
screenshotPath: screenShotPaths.dataOverlayMenu.overlayMenuWithSegmentationSelected,
@ -48,6 +54,8 @@ test('should display added, selected and removed segmentation promptly', async (
// navigate to the 51st image and ensure the correct overlay is displayed
await press({ page, key: 'ArrowDown', nTimes: 50 });
await page.waitForTimeout(5000);
await checkForScreenshot({
page,
screenshotPath: screenShotPaths.dataOverlayMenu.overlaySegmentation,
@ -60,6 +68,8 @@ test('should display added, selected and removed segmentation promptly', async (
await page.getByTestId('overlay-ds-more-button-SEGMENTATION').click();
await page.getByTestId('overlay-ds-remove-button-SEGMENTATION').click();
await page.waitForTimeout(5000);
await checkForScreenshot({
page,
screenshotPath: screenShotPaths.dataOverlayMenu.overlayMenuWithSegmentationOverlaysRemoved,
@ -71,6 +81,8 @@ test('should display added, selected and removed segmentation promptly', async (
// navigate to the 51st image and ensure no overlay is displayed
await press({ page, key: 'ArrowDown', nTimes: 50 });
await page.waitForTimeout(5000);
await checkForScreenshot({
page,
screenshotPath: screenShotPaths.dataOverlayMenu.noOverlay,

View File

@ -1,5 +1,6 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.5962.99.1.2968617883.1314880426.1493322302363.3.0';
@ -32,6 +33,9 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
// Hide the overlay menu.
await page.getByTestId('dataOverlayMenu-mpr-sagittal-btn').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
// Wait 5 seconds for RT to load. This is necessary in particular when screen shots are added or replaced.
await page.waitForTimeout(5000);

View File

@ -1,5 +1,6 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046';
@ -15,6 +16,8 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await page.getByTestId('Layout').click();
await page.getByTestId('MPR').click();
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,
@ -31,6 +34,11 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
// Hide the overlay menu.
await page.getByTestId('dataOverlayMenu-mpr-sagittal-btn').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,

View File

@ -1,6 +1,7 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { press } from './utils/keyboardUtils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.32722.99.99.239341353911714368772597187099978969331';
@ -18,14 +19,23 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('2d-tta_nnU-Net_Segmentation').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
await page.getByTestId('AddSegmentationDataOverlay-default').click();
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('Segmentation').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
await page.getByTestId('AddSegmentationDataOverlay-default').click();
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('3d_lowres-tta_nnU-Net_Segmentation').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
await checkForScreenshot({
page,
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu,
@ -59,6 +69,9 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('Series 3 - RTSTRUCT').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
await page.waitForTimeout(5000);
await checkForScreenshot({

View File

@ -1,6 +1,7 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { press } from './utils/keyboardUtils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501';
@ -16,9 +17,14 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('Contours on PET').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
// Hide the overlay menu.
await page.getByTestId('dataOverlayMenu-default-btn').click();
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,
@ -28,6 +34,8 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT
// Navigate to the middle image of the default viewport.
await press({ page, key: 'ArrowDown', nTimes: 23 });
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,

View File

@ -1,5 +1,6 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.5962.99.1.2968617883.1314880426.1493322302363.3.0';
@ -16,6 +17,9 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('ARIA RadOnc Structure Sets').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
// Hide the overlay menu.
await page.getByTestId('dataOverlayMenu-default-btn').click();
@ -37,4 +41,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
page,
screenShotPaths.rtDataOverlayNoHydrationThenMPR.rtDataOverlayNoHydrationPostMPR
);
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
});

View File

@ -1,6 +1,7 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { press } from './utils/keyboardUtils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
@ -16,9 +17,14 @@ test('should overlay an unhydrated SEG over a display set that the SEG does NOT
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('Segmentation').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
// Hide the overlay menu.
await page.getByTestId('dataOverlayMenu-default-btn').click();
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,
@ -28,6 +34,8 @@ test('should overlay an unhydrated SEG over a display set that the SEG does NOT
// Navigate to the middle image of the default viewport.
await press({ page, key: 'ArrowDown', nTimes: 9 });
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,

View File

@ -1,5 +1,6 @@
import { test } from 'playwright-test-coverage';
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
import { assertNumberOfModalityLoadBadges } from './utils/assertions';
test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046';
@ -16,9 +17,14 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await page.getByText('SELECT A SEGMENTATION').click();
await page.getByTestId('Segmentation').click();
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
// Hide the overlay menu.
await page.getByTestId('dataOverlayMenu-default-btn').click();
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,
@ -28,9 +34,14 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await page.getByTestId('Layout').click();
await page.getByTestId('MPR').click();
await page.waitForTimeout(5000);
await checkForScreenshot(
page,
page,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPostMPR
);
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 277 KiB

15
tests/utils/assertions.ts Normal file
View File

@ -0,0 +1,15 @@
import { Page } from '@playwright/test';
import { expect } from 'playwright-test-coverage';
/**
* Asserts the number of Modality Load Badges present on the page.
*/
export async function assertNumberOfModalityLoadBadges({
page,
expectedCount,
}: {
page: Page;
expectedCount: number;
}) {
await expect(page.locator('css=div[data-cy^="ModalityLoadBadge-"]')).toHaveCount(expectedCount);
}