fix(segmentation overlays): Allow for the addition of multiple segmentation overlays. (#5189)
No files matched your search
@@ -35,9 +35,9 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
|
||||
// Wait 5 seconds for RT to load. This is necessary in particular when screen shots are added or replaced.
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(
|
||||
await checkForScreenshot({
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.mprThenRTOverlayNoHydration.mprPostRTOverlayNoHydration
|
||||
);
|
||||
screenshotPath: screenShotPaths.mprThenRTOverlayNoHydration.mprPostRTOverlayNoHydration,
|
||||
normalizedClip: { x: 0, y: 0, width: 1.0, height: 0.75 }, // clip to avoid any popups concerning surface creation and clipping
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
import { test } from 'playwright-test-coverage';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
import { press } from './utils/keyboardUtils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.32722.99.99.239341353911714368772597187099978969331';
|
||||
const mode = 'viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display multiple segmentation overlays (both SEG and RT)', async ({ page }) => {
|
||||
await page.getByTestId('side-panel-header-right').click();
|
||||
|
||||
// Add multiple segmentation overlays and ensure the overlay menu reflects this change.
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click();
|
||||
|
||||
await page.getByTestId('AddSegmentationDataOverlay-default').click();
|
||||
await page.getByText('SELECT A SEGMENTATION').click();
|
||||
await page.getByTestId('2d-tta_nnU-Net_Segmentation').click();
|
||||
|
||||
await page.getByTestId('AddSegmentationDataOverlay-default').click();
|
||||
await page.getByText('SELECT A SEGMENTATION').click();
|
||||
await page.getByTestId('Segmentation').click();
|
||||
|
||||
await page.getByTestId('AddSegmentationDataOverlay-default').click();
|
||||
await page.getByText('SELECT A SEGMENTATION').click();
|
||||
await page.getByTestId('3d_lowres-tta_nnU-Net_Segmentation').click();
|
||||
|
||||
await checkForScreenshot({
|
||||
page,
|
||||
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu,
|
||||
});
|
||||
|
||||
// Hide the overlay menu and then show it again. The overlays from before should still be displayed.
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click(); // hide
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click(); // show
|
||||
|
||||
await checkForScreenshot({
|
||||
page,
|
||||
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu,
|
||||
});
|
||||
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click(); // hide
|
||||
|
||||
// Navigate to image 56.
|
||||
await press({ page, key: 'ArrowDown', nTimes: 55 });
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot({
|
||||
page,
|
||||
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaysDisplayed,
|
||||
});
|
||||
|
||||
// Now add the RT overlay
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click();
|
||||
|
||||
await page.getByTestId('AddSegmentationDataOverlay-default').click();
|
||||
await page.getByText('SELECT A SEGMENTATION').click();
|
||||
await page.getByTestId('Series 3 - RTSTRUCT').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot({
|
||||
page,
|
||||
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaySEGsAndRTDisplayed,
|
||||
});
|
||||
|
||||
// Hide the overlay menu and then show it again. The overlays from before should still be displayed.
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click(); // hide
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click(); // show
|
||||
|
||||
await checkForScreenshot({
|
||||
page,
|
||||
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaySEGsAndRTDisplayed,
|
||||
});
|
||||
});
|
||||
@@ -19,6 +19,8 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
|
||||
// Hide the overlay menu.
|
||||
await page.getByTestId('dataOverlayMenu-default-btn').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
@@ -28,6 +30,8 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.getByTestId('MPR').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
|
||||
@@ -13,14 +13,20 @@ test('should hydrate an RTSTRUCT from MPR', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.getByTestId('MPR').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprBeforeRT);
|
||||
|
||||
await page.getByTestId('study-browser-thumbnail-no-image').dblclick();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprAfterRT);
|
||||
|
||||
await page.getByTestId('yes-hydrate-btn').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprAfterRTHydrated);
|
||||
|
||||
await page.getByTestId('Layout').click();
|
||||
|
||||
@@ -13,11 +13,15 @@ test('should hydrate an RTSTRUCT and then launch MPR', async ({ page }) => {
|
||||
|
||||
await page.getByTestId('yes-hydrate-btn').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydrationThenMPR.rtPostHydration);
|
||||
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.getByTestId('Axial Primary').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
|
||||
@@ -11,10 +11,14 @@ test('should launch MPR with unhydrated RTSTRUCT', async ({ page }) => {
|
||||
await page.getByTestId('side-panel-header-right').click();
|
||||
await page.getByTestId('study-browser-thumbnail-no-image').dblclick();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtNoHydrationThenMPR.rtNoHydrationPreMPR);
|
||||
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.getByTestId('MPR').click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtNoHydrationThenMPR.rtNoHydrationPostMPR);
|
||||
});
|
||||
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 182 KiB |
@@ -9,6 +9,12 @@ type CheckForScreenshotProps = {
|
||||
delay?: number;
|
||||
maxDiffPixelRatio?: number;
|
||||
threshold?: number;
|
||||
normalizedClip?: {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
};
|
||||
|
||||
const _checkForScreenshot = async (props: CheckForScreenshotProps) => {
|
||||
@@ -20,15 +26,34 @@ const _checkForScreenshot = async (props: CheckForScreenshotProps) => {
|
||||
delay = 500,
|
||||
maxDiffPixelRatio = 0.02,
|
||||
threshold = 0.05,
|
||||
normalizedClip,
|
||||
} = props;
|
||||
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
for (let i = 0; i < attempts; i++) {
|
||||
try {
|
||||
let clip;
|
||||
if (normalizedClip) {
|
||||
let boundingBox;
|
||||
if (locator === page) {
|
||||
boundingBox = { x: 0, y: 0, ...(await page.viewportSize()) };
|
||||
} else {
|
||||
boundingBox = await (locator as Locator).boundingBox();
|
||||
}
|
||||
|
||||
clip = {
|
||||
x: normalizedClip.x * boundingBox.width,
|
||||
y: normalizedClip.y * boundingBox.height,
|
||||
width: normalizedClip.width * boundingBox.width,
|
||||
height: normalizedClip.height * boundingBox.height,
|
||||
};
|
||||
}
|
||||
|
||||
await expect(locator).toHaveScreenshot(screenshotPath, {
|
||||
maxDiffPixelRatio,
|
||||
threshold,
|
||||
clip,
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -173,6 +173,11 @@ const screenShotPaths = {
|
||||
overlaySegmentation: 'overlaySegmentation.png',
|
||||
noOverlay: 'noOverlay.png',
|
||||
},
|
||||
multipleSegmentationDataOverlays: {
|
||||
threeSegOverlaysInOverlayMenu: 'threeSegOverlaysInOverlayMenu.png',
|
||||
overlaysDisplayed: 'overlaysDisplayed.png',
|
||||
overlaySEGsAndRTDisplayed: 'overlaySEGsAndRTDisplayed.png',
|
||||
},
|
||||
};
|
||||
|
||||
export { screenShotPaths };
|
||||