diff --git a/extensions/dicom-microscopy/src/DicomMicroscopyViewport.tsx b/extensions/dicom-microscopy/src/DicomMicroscopyViewport.tsx index 11da8bca2..2f3e36af6 100644 --- a/extensions/dicom-microscopy/src/DicomMicroscopyViewport.tsx +++ b/extensions/dicom-microscopy/src/DicomMicroscopyViewport.tsx @@ -254,6 +254,7 @@ const DicomMicroscopyViewport = React.memo(
{ container.current = ref; resizeRef.current = ref; diff --git a/tests/Angle.spec.ts b/tests/Angle.spec.ts index 4b188115c..dae950dc9 100644 --- a/tests/Angle.spec.ts +++ b/tests/Angle.spec.ts @@ -13,7 +13,8 @@ test('should display the angle tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.moreTools.angle.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 550, y: 200 }, { x: 450, y: 250 }, { x: 550, y: 300 }, diff --git a/tests/ArrowAnnotate.spec.ts b/tests/ArrowAnnotate.spec.ts index 7260ae5b1..fafb8babd 100644 --- a/tests/ArrowAnnotate.spec.ts +++ b/tests/ArrowAnnotate.spec.ts @@ -17,7 +17,8 @@ test('should display the arrow tool and allow free-form text to be entered', asy await mainToolbarPageObject.measurementTools.arrowAnnotate.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 164, y: 234 }, { x: 344, y: 232 }, ]); @@ -38,7 +39,7 @@ test('should display the arrow tool and allow free-form text to be entered', asy // Now edit the arrow text and the label should not change. - await viewportPageObject.active.doubleClickAt({ x: 164, y: 234 }); + await activeViewport.doubleClickAt({ x: 164, y: 234 }); await DOMOverlayPageObject.dialog.input.fillAndSave('Neil Peart was the drummer for Rush'); diff --git a/tests/Bidirectional.spec.ts b/tests/Bidirectional.spec.ts index 7a5322e80..e4d103566 100644 --- a/tests/Bidirectional.spec.ts +++ b/tests/Bidirectional.spec.ts @@ -13,7 +13,8 @@ test('should display the bidirectional tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.bidirectional.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 405, y: 277 }, { x: 515, y: 339 }, ]); diff --git a/tests/Circle.spec.ts b/tests/Circle.spec.ts index 8f59e0e45..3db30f90b 100644 --- a/tests/Circle.spec.ts +++ b/tests/Circle.spec.ts @@ -13,7 +13,8 @@ test('should display the circle tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.circleROI.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 480, y: 205 }, { x: 488, y: 247 }, ]); diff --git a/tests/CobbAngle.spec.ts b/tests/CobbAngle.spec.ts index d880d7b9f..cb760c969 100644 --- a/tests/CobbAngle.spec.ts +++ b/tests/CobbAngle.spec.ts @@ -13,7 +13,8 @@ test('should display the cobb angle tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.moreTools.cobbAngle.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 515, y: 212 }, { x: 616, y: 207 }, { x: 527, y: 293 }, diff --git a/tests/ContextMenu.spec.ts b/tests/ContextMenu.spec.ts index 9cd760a59..c93146a3a 100644 --- a/tests/ContextMenu.spec.ts +++ b/tests/ContextMenu.spec.ts @@ -13,7 +13,8 @@ test('should the context menu completely on screen and is not clipped for a poin viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.length.click(); - await viewportPageObject.active.normalizedClickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.normalizedClickAt([ { x: 0.45, y: 0.98 }, { x: 0.55, y: 0.98 }, ]); @@ -22,7 +23,7 @@ test('should the context menu completely on screen and is not clipped for a poin await checkForScreenshot(page, page, screenShotPaths.contextMenu.preContextMenuNearBottomEdge); - await viewportPageObject.active.normalizedClickAt([{ x: 0.55, y: 0.98 }], 'right'); + await activeViewport.normalizedClickAt([{ x: 0.55, y: 0.98 }], 'right'); await checkForScreenshot({ page, diff --git a/tests/ContourSegLocking.spec.ts b/tests/ContourSegLocking.spec.ts index f9b8d367b..786b54dbb 100644 --- a/tests/ContourSegLocking.spec.ts +++ b/tests/ContourSegLocking.spec.ts @@ -23,7 +23,7 @@ test('should not allow contours to be edited in basic viewer mode', async ({ // Wait for the segmentation to hydrate. await page.waitForTimeout(5000); - const svgPathLocatorPreEdit = viewportPageObject.getById('default').svg(); + const svgPathLocatorPreEdit = (await viewportPageObject.getById('default')).svg(); expect( await svgPathLocatorPreEdit.count(), @@ -39,7 +39,7 @@ test('should not allow contours to be edited in basic viewer mode', async ({ end: { x: 0.1, y: -0.2 }, }); - const svgPathLocatorPostEdit = viewportPageObject.getById('default').svg(); + const svgPathLocatorPostEdit = (await viewportPageObject.getById('default')).svg(); expect( await svgPathLocatorPostEdit.getAttribute('d'), @@ -77,7 +77,7 @@ test('should not allow contours to be edited when panelSegmentation.disableEditi // Wait for the segmentation to hydrate. await page.waitForTimeout(5000); - const svgPathLocatorPreEdit = viewportPageObject.getById('default').svg(); + const svgPathLocatorPreEdit = (await viewportPageObject.getById('default')).svg(); expect( await svgPathLocatorPreEdit.count(), @@ -93,7 +93,7 @@ test('should not allow contours to be edited when panelSegmentation.disableEditi end: { x: 0.1, y: -0.2 }, }); - const svgPathLocatorPostEdit = viewportPageObject.getById('default').svg(); + const svgPathLocatorPostEdit = (await viewportPageObject.getById('default')).svg(); expect( await svgPathLocatorPostEdit.getAttribute('d'), @@ -131,7 +131,7 @@ test('should allow contours to be edited when panelSegmentation.disableEditing i // Wait for the segmentation to hydrate. await page.waitForTimeout(5000); - const svgPathLocatorPreEdit = viewportPageObject.getById('default').svg('path'); + const svgPathLocatorPreEdit = (await viewportPageObject.getById('default')).svg('path'); expect( await svgPathLocatorPreEdit.count(), @@ -147,7 +147,7 @@ test('should allow contours to be edited when panelSegmentation.disableEditing i end: { x: 0.1, y: -0.2 }, }); - const svgPathLocatorPostEdit = viewportPageObject.getById('default').svg('path'); + const svgPathLocatorPostEdit = (await viewportPageObject.getById('default')).svg('path'); expect( await svgPathLocatorPostEdit.getAttribute('d'), diff --git a/tests/ContourSegmentToggleVisibility.spec.ts b/tests/ContourSegmentToggleVisibility.spec.ts index 2955c674b..a4c6a65d9 100644 --- a/tests/ContourSegmentToggleVisibility.spec.ts +++ b/tests/ContourSegmentToggleVisibility.spec.ts @@ -2,46 +2,48 @@ import { expect, test, visitStudy, getSvgPath, navigateWithViewportArrow } from const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501'; -test.beforeEach(async ({ - page, - leftPanelPageObject, - DOMOverlayPageObject, - rightPanelPageObject -}) => { - const mode = 'segmentation'; - await visitStudy(page, studyInstanceUID, mode, 2000); - await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); - await page.waitForTimeout(5000); - await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); - await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0).click(); - await page.waitForTimeout(1000); -}); +test.beforeEach( + async ({ page, leftPanelPageObject, DOMOverlayPageObject, rightPanelPageObject }) => { + const mode = 'segmentation'; + await visitStudy(page, studyInstanceUID, mode, 2000); + await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); + await page.waitForTimeout(5000); + await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); + await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0).click(); + await page.waitForTimeout(1000); + } +); test('should toggle all segments visibility - on/off', async ({ rightPanelPageObject, viewportPageObject, }) => { - const svgPathLocator = viewportPageObject.getById('default').svg('path'); + const svgPathLocator = (await viewportPageObject.getById('default')).svg('path'); await expect(svgPathLocator, 'Expected first segment SVG paths to be visible').toHaveCount(2); await rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click(); - await expect(svgPathLocator, 'Expected no SVG paths after toggling all visibility off').toHaveCount(0); + await expect( + svgPathLocator, + 'Expected no SVG paths after toggling all visibility off' + ).toHaveCount(0); await rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click(); - await expect(svgPathLocator, 'Expected SVG path count to match initial after toggling all back on').toHaveCount(2); + await expect( + svgPathLocator, + 'Expected SVG path count to match initial after toggling all back on' + ).toHaveCount(2); }); - test('when segment visibility is off it is not shown when clicked on', async ({ rightPanelPageObject, viewportPageObject, }) => { await rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click(); - const svgPathLocator = viewportPageObject.getById('default').svg('path'); + const svgPathLocator = (await viewportPageObject.getById('default')).svg('path'); await expect(svgPathLocator, 'All segments to be hidden').toHaveCount(0); await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(1).click(); @@ -51,14 +53,13 @@ test('when segment visibility is off it is not shown when clicked on', async ({ await expect(svgPathLocator, 'All segments to remain hidden').toHaveCount(0); }); - test('when segment visibility is off it is not shown when viewport contour navigation is used', async ({ rightPanelPageObject, viewportPageObject, }) => { await rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click(); - const svgPathLocator = viewportPageObject.getById('default').svg('path'); + const svgPathLocator = (await viewportPageObject.getById('default')).svg('path'); await expect(svgPathLocator, 'All segments to be hidden').toHaveCount(0); await navigateWithViewportArrow(viewportPageObject, 'next'); @@ -71,7 +72,7 @@ test('when segment visibility is off it is not shown when viewport contour navig test('should restore svg paths when segment visibility is toggled on/off', async ({ rightPanelPageObject, viewportPageObject, - page + page, }) => { await rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click(); @@ -81,11 +82,16 @@ test('should restore svg paths when segment visibility is toggled on/off', async expect(svgPathBefore, 'Expected a visible SVG path for segment 0').not.toBeNull(); await segment0.toggleVisibility(); - await expect(viewportPageObject.getById('default').svg('path'), 'No segment to be displayed').toHaveCount(0); + await expect( + (await viewportPageObject.getById('default')).svg('path'), + 'No segment to be displayed' + ).toHaveCount(0); await segment0.toggleVisibility(); const svgPathAfter = await getSvgPath(viewportPageObject); - expect(svgPathAfter, 'Expected SVG path to be restored after toggling visibility back on').toBe(svgPathBefore); + expect(svgPathAfter, 'Expected SVG path to be restored after toggling visibility back on').toBe( + svgPathBefore + ); }); test('should toggle an individual segment visibility - on/off', async ({ @@ -94,7 +100,7 @@ test('should toggle an individual segment visibility - on/off', async ({ }) => { // Establish known state by selecting segment 1 await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(1).click(); - const svgPathLocator = viewportPageObject.getById('default').svg('path'); + const svgPathLocator = (await viewportPageObject.getById('default')).svg('path'); await expect(svgPathLocator, 'Expected first segment SVG paths to be visible').toHaveCount(4); const segment0 = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0); diff --git a/tests/DataOverlayMenu.spec.ts b/tests/DataOverlayMenu.spec.ts index 71f115f20..138ba0965 100644 --- a/tests/DataOverlayMenu.spec.ts +++ b/tests/DataOverlayMenu.spec.ts @@ -10,7 +10,7 @@ test('should display added, selected and removed segmentation promptly', async ( await visitStudy(page, studyInstanceUID, mode, 2000); // Add a segmentation overlay and ensure the overlay menu reflects this change. - const dataOverlayPageObject = viewportPageObject.getById('default').overlayMenu.dataOverlay; + const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; await dataOverlayPageObject.toggle(); await dataOverlayPageObject.addSegmentation('2d-tta_nnU-Net_Segmentation'); diff --git a/tests/DicomTagBrowser.spec.ts b/tests/DicomTagBrowser.spec.ts index fd3d31cc0..7471c8b12 100644 --- a/tests/DicomTagBrowser.spec.ts +++ b/tests/DicomTagBrowser.spec.ts @@ -76,7 +76,7 @@ test('should open DICOM Tag Browser from empty viewport and show default series' await mainToolbarPageObject.layoutSelection.click(); await page.getByTestId('Layout-2-2').click(); - await viewportPageObject.getNth(6).pane.click(); + await viewportPageObject.getNthLocator(6).click(); await mainToolbarPageObject.moreTools.tagBrowser.click(); @@ -102,7 +102,7 @@ test('should open DICOM Tag Browser with active viewport series when viewport ha await mainToolbarPageObject.layoutSelection.click(); await page.getByTestId('Layout-2-2').click(); - await viewportPageObject.getNth(2).pane.click(); + await (await viewportPageObject.getNth(2)).pane.click(); await mainToolbarPageObject.moreTools.tagBrowser.click(); diff --git a/tests/Ellipse.spec.ts b/tests/Ellipse.spec.ts index 15580dd5c..03c7c80d8 100644 --- a/tests/Ellipse.spec.ts +++ b/tests/Ellipse.spec.ts @@ -13,7 +13,8 @@ test('should display the ellipse tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.ellipticalROI.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 446, y: 245 }, { x: 508, y: 281 }, ]); diff --git a/tests/FreehandROI.spec.ts b/tests/FreehandROI.spec.ts index eed68b3b6..735ee833b 100644 --- a/tests/FreehandROI.spec.ts +++ b/tests/FreehandROI.spec.ts @@ -13,7 +13,8 @@ test('should not fire MEASUREMENT_ADDED when clicking the annotation text', asyn viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.freehandROI.click(); - await viewportPageObject.active.normalizedDragAt({ + const activeViewport = await viewportPageObject.active; + await activeViewport.normalizedDragAt({ start: { x: 0.35, y: 0.35 }, end: { x: 0.6, y: 0.55 }, config: { steps: 20, delay: 30 }, @@ -23,11 +24,10 @@ test('should not fire MEASUREMENT_ADDED when clicking the annotation text', asyn const measurementAdded = await subscribeToMeasurementAdded(page); try { - const annotation = viewportPageObject.active.nthAnnotation(0); + const annotation = activeViewport.nthAnnotation(0); await annotation.text.click(); await expect(measurementAdded.waitFired(1000)).rejects.toThrow(); - } finally { await measurementAdded.unsubscribe(); } diff --git a/tests/JumpToMeasurementMPR.spec.ts b/tests/JumpToMeasurementMPR.spec.ts index 3f0dcc649..577401863 100644 --- a/tests/JumpToMeasurementMPR.spec.ts +++ b/tests/JumpToMeasurementMPR.spec.ts @@ -43,7 +43,8 @@ test('should hydrate in MPR correctly', async ({ await page.waitForTimeout(5000); await mainToolbarPageObject.measurementTools.bidirectional.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 405, y: 277 }, { x: 515, y: 339 }, ]); diff --git a/tests/LabelMapSegLocking.spec.ts b/tests/LabelMapSegLocking.spec.ts index e35c11d74..782ad7bcf 100644 --- a/tests/LabelMapSegLocking.spec.ts +++ b/tests/LabelMapSegLocking.spec.ts @@ -46,15 +46,16 @@ test('should prevent editing of label map segmentations when panelSegmentation.d await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.setRadius(1000); // Attempt to erase the segmentations by dragging the eraser tool across the image several times. - await viewportPageObject.getById('default').normalizedDragAt({ + const defaultViewport = await viewportPageObject.getById('default'); + await defaultViewport.normalizedDragAt({ start: { x: 0.01, y: 0.25 }, end: { x: 1.0, y: 0.25 }, }); - await viewportPageObject.getById('default').normalizedDragAt({ + await defaultViewport.normalizedDragAt({ start: { x: 0.01, y: 0.5 }, end: { x: 1.0, y: 0.5 }, }); - await viewportPageObject.getById('default').normalizedDragAt({ + await defaultViewport.normalizedDragAt({ start: { x: 0.01, y: 0.75 }, end: { x: 1.0, y: 0.75 }, }); @@ -101,15 +102,16 @@ test('should allow editing of label map segmentations when panelSegmentation.dis await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.setRadius(1000); // Attempt to erase the segmentations by dragging the eraser tool across the image several times. - await viewportPageObject.getById('default').normalizedDragAt({ + const defaultViewport = await viewportPageObject.getById('default'); + await defaultViewport.normalizedDragAt({ start: { x: 0.01, y: 0.25 }, end: { x: 1.0, y: 0.25 }, }); - await viewportPageObject.getById('default').normalizedDragAt({ + await defaultViewport.normalizedDragAt({ start: { x: 0.01, y: 0.5 }, end: { x: 1.0, y: 0.5 }, }); - await viewportPageObject.getById('default').normalizedDragAt({ + await defaultViewport.normalizedDragAt({ start: { x: 0.01, y: 0.75 }, end: { x: 1.0, y: 0.75 }, }); diff --git a/tests/Length.spec.ts b/tests/Length.spec.ts index 43f262cb9..48074e8cf 100644 --- a/tests/Length.spec.ts +++ b/tests/Length.spec.ts @@ -13,7 +13,8 @@ test('should display the length tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.length.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 364, y: 234 }, { x: 544, y: 232 }, ]); diff --git a/tests/Livewire.spec.ts b/tests/Livewire.spec.ts index 5eeb32a13..c6f3d211c 100644 --- a/tests/Livewire.spec.ts +++ b/tests/Livewire.spec.ts @@ -13,7 +13,8 @@ test('should display the livewire tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.livewireContour.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 380, y: 459 }, { x: 420, y: 396 }, { x: 523, y: 392 }, diff --git a/tests/MPRThenRTOverlayNoHydration.spec.ts b/tests/MPRThenRTOverlayNoHydration.spec.ts index 160762882..2bbde7bc6 100644 --- a/tests/MPRThenRTOverlayNoHydration.spec.ts +++ b/tests/MPRThenRTOverlayNoHydration.spec.ts @@ -23,13 +23,14 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me ); // Hover over the middle/sagittal viewport so that the data overlay menu is available. - await viewportPageObject.getById('mpr-sagittal').pane.hover(); - const dataOverlayPageObject = viewportPageObject.getById('mpr-sagittal').overlayMenu.dataOverlay; - await dataOverlayPageObject.toggle('mpr-sagittal'); - await dataOverlayPageObject.addSegmentation('ARIA RadOnc Structure Sets', 'mpr-sagittal'); + const sagittalViewport = await viewportPageObject.getById('mpr-sagittal'); + await sagittalViewport.pane.hover(); + const dataOverlayPageObject = sagittalViewport.overlayMenu.dataOverlay; + await dataOverlayPageObject.toggle(); + await dataOverlayPageObject.addSegmentation('ARIA RadOnc Structure Sets'); // Hide the overlay menu. - await dataOverlayPageObject.toggle('mpr-sagittal'); + await dataOverlayPageObject.toggle(); // Adding an overlay should not show the LOAD button. await assertNumberOfModalityLoadBadges({ page, expectedCount: 0 }); diff --git a/tests/MPRThenSEGOverlayNoHydration.spec.ts b/tests/MPRThenSEGOverlayNoHydration.spec.ts index b67e3d8d9..69186f882 100644 --- a/tests/MPRThenSEGOverlayNoHydration.spec.ts +++ b/tests/MPRThenSEGOverlayNoHydration.spec.ts @@ -26,13 +26,14 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu', ); // Hover over the middle/sagittal viewport so that the data overlay menu is available. - await viewportPageObject.getById('mpr-axial').pane.hover(); - const dataOverlayPageObject = viewportPageObject.getById('mpr-axial').overlayMenu.dataOverlay; - await dataOverlayPageObject.toggle('mpr-axial'); - await dataOverlayPageObject.addSegmentation('Segmentation', 'mpr-axial'); + const axialViewport = await viewportPageObject.getById('mpr-axial'); + await axialViewport.pane.hover(); + const dataOverlayPageObject = axialViewport.overlayMenu.dataOverlay; + await dataOverlayPageObject.toggle(); + await dataOverlayPageObject.addSegmentation('Segmentation'); // Hide the overlay menu. - await dataOverlayPageObject.toggle('mpr-axial'); + await dataOverlayPageObject.toggle(); // Adding an overlay should not show the LOAD button. await assertNumberOfModalityLoadBadges({ page, expectedCount: 0 }); diff --git a/tests/MeasurementPanel.spec.ts b/tests/MeasurementPanel.spec.ts index 86de99424..6bf831abe 100644 --- a/tests/MeasurementPanel.spec.ts +++ b/tests/MeasurementPanel.spec.ts @@ -95,7 +95,8 @@ test('checks if measurement item can be relabeled through the context menu on th // Right click and click rename await page.waitForTimeout(200); // small delay for context menu - await viewportPageObject.active.nthAnnotation(0).contextMenu.open(); + const activeViewport = await viewportPageObject.active; + await activeViewport.nthAnnotation(0).contextMenu.open(); await page.waitForTimeout(200); // small delay for context menu const addLabelButton = DOMOverlayPageObject.viewport.annotationContextMenu.addLabel; @@ -117,7 +118,8 @@ test('checks if image would jump when clicked on a measurement item', async ({ rightPanelPageObject, viewportPageObject, }) => { - const viewportInfoBottomRight = viewportPageObject.active.overlayText.bottomRight.instanceNumber; + const activeViewport = await viewportPageObject.active; + const viewportInfoBottomRight = activeViewport.overlayText.bottomRight.instanceNumber; // Image loads on slice 1, confirm on slice 1 then add measurement await expect(viewportInfoBottomRight).toContainText('1/', { timeout: 10000 }); @@ -198,7 +200,8 @@ test('checks if measurement item can be deleted through the context menu on the // Right click and click rename await page.waitForTimeout(200); // small delay for context menu - await viewportPageObject.active.nthAnnotation(0).contextMenu.open(); + const activeViewport = await viewportPageObject.active; + await activeViewport.nthAnnotation(0).contextMenu.open(); await page.waitForTimeout(200); // small delay for context menu const deleteButton = DOMOverlayPageObject.viewport.annotationContextMenu.delete; @@ -207,6 +210,6 @@ test('checks if measurement item can be deleted through the context menu on the // Open measurement panel and confirm measurement is gone await rightPanelPageObject.measurementsPanel.select(); - await expect(viewportPageObject.active.nthAnnotation(0).locator).toBeHidden(); + await expect(activeViewport.nthAnnotation(0).locator).toBeHidden(); expect(await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount()).toBe(0); }); diff --git a/tests/MicroscopyPanel.spec.ts b/tests/MicroscopyPanel.spec.ts index 7178c4dc8..803fee6b7 100644 --- a/tests/MicroscopyPanel.spec.ts +++ b/tests/MicroscopyPanel.spec.ts @@ -16,9 +16,10 @@ test('should rename a microscopy measurement label', async ({ await mainToolbarPageObject.measurementTools.line.click(); - await viewportPageObject.active.clickAt([{ x: 400, y: 200 }]); + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([{ x: 400, y: 200 }]); await page.waitForTimeout(200); - await viewportPageObject.active.clickAt([{ x: 550, y: 250 }]); + await activeViewport.clickAt([{ x: 550, y: 250 }]); const measurementRow = rightPanelPageObject.microscopyPanel.nthMeasurement(0); await expect(measurementRow.locator).toBeVisible(); diff --git a/tests/MultipleSegmentationDataOverlays.spec.ts b/tests/MultipleSegmentationDataOverlays.spec.ts index 0fda2a419..f56250707 100644 --- a/tests/MultipleSegmentationDataOverlays.spec.ts +++ b/tests/MultipleSegmentationDataOverlays.spec.ts @@ -17,7 +17,7 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({ await rightPanelPageObject.toggle(); // Add multiple segmentation overlays and ensure the overlay menu reflects this change. - const dataOverlayPageObject = viewportPageObject.getById('default').overlayMenu.dataOverlay; + const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; await dataOverlayPageObject.toggle(); await dataOverlayPageObject.addSegmentation('2d-tta_nnU-Net_Segmentation'); diff --git a/tests/Probe.spec.ts b/tests/Probe.spec.ts index f1c6ea81e..2ccfd2a76 100644 --- a/tests/Probe.spec.ts +++ b/tests/Probe.spec.ts @@ -13,7 +13,8 @@ test('should display the probe tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.moreTools.probe.click(); - await viewportPageObject.active.clickAt([{ x: 550, y: 200 }]); + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([{ x: 550, y: 200 }]); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await checkForScreenshot(page, page, screenShotPaths.probe.probeDisplayedCorrectly); }); diff --git a/tests/RTDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts b/tests/RTDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts index c8b5cb97f..d36484588 100644 --- a/tests/RTDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts +++ b/tests/RTDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts @@ -12,7 +12,7 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT page, viewportPageObject, }) => { - const dataOverlayPageObject = viewportPageObject.getById('default').overlayMenu.dataOverlay; + const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; await dataOverlayPageObject.toggle(); await dataOverlayPageObject.addSegmentation('Contours on PET'); diff --git a/tests/RTDataOverlayNoHydrationThenMPR.spec.ts b/tests/RTDataOverlayNoHydrationThenMPR.spec.ts index 8ad4e484a..ed5f40824 100644 --- a/tests/RTDataOverlayNoHydrationThenMPR.spec.ts +++ b/tests/RTDataOverlayNoHydrationThenMPR.spec.ts @@ -14,7 +14,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me viewportPageObject, }) => { await rightPanelPageObject.toggle(); - const dataOverlayPageObject = viewportPageObject.getById('default').overlayMenu.dataOverlay; + const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; await dataOverlayPageObject.toggle(); await dataOverlayPageObject.addSegmentation('ARIA RadOnc Structure Sets'); diff --git a/tests/RTHydrationDisableConfirmation.spec.ts b/tests/RTHydrationDisableConfirmation.spec.ts index d2c6c9564..1a1b4c817 100644 --- a/tests/RTHydrationDisableConfirmation.spec.ts +++ b/tests/RTHydrationDisableConfirmation.spec.ts @@ -25,6 +25,8 @@ test('should auto hydrate RT STRUCT on the second load and keep viewport stable rightPanelPageObject, viewportPageObject, }) => { + const activeViewport = await viewportPageObject.active; + // First load await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); await page.waitForTimeout(5000); @@ -37,7 +39,7 @@ test('should auto hydrate RT STRUCT on the second load and keep viewport stable await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.rtHydrationDisableConfirmation.firstLoadPostHydration ); @@ -48,7 +50,7 @@ test('should auto hydrate RT STRUCT on the second load and keep viewport stable await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.rtHydrationDisableConfirmation.viewportAfterFirstDelete ); @@ -65,7 +67,7 @@ test('should auto hydrate RT STRUCT on the second load and keep viewport stable await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.rtHydrationDisableConfirmation.secondLoadPostHydration ); @@ -75,7 +77,7 @@ test('should auto hydrate RT STRUCT on the second load and keep viewport stable await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.rtHydrationDisableConfirmation.viewportAfterSecondDelete ); }); diff --git a/tests/Rectangle.spec.ts b/tests/Rectangle.spec.ts index 34a5b501d..4d06f6cad 100644 --- a/tests/Rectangle.spec.ts +++ b/tests/Rectangle.spec.ts @@ -13,7 +13,8 @@ test('should display the rectangle tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.rectangleROI.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 476, y: 159 }, { x: 591, y: 217 }, ]); diff --git a/tests/SEGDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts b/tests/SEGDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts index 5e891fcf8..81852a5d5 100644 --- a/tests/SEGDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts +++ b/tests/SEGDataOverlayForUnreferencedDisplaySetNoHydration.spec.ts @@ -15,17 +15,16 @@ test('should overlay an unhydrated SEG over a display set that the SEG does NOT }) => { await leftPanelPageObject.loadSeriesByDescription('Apparent Diffusion Coefficient'); - await viewportPageObject.getById('default').overlayMenu.dataOverlay.toggle(); + const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; + await dataOverlayPageObject.toggle(); - await viewportPageObject - .getById('default') - .overlayMenu.dataOverlay.addSegmentation('T2 Weighted Axial Segmentations'); + await dataOverlayPageObject.addSegmentation('T2 Weighted Axial Segmentations'); // Adding an overlay should not show the LOAD button. assertNumberOfModalityLoadBadges({ page, expectedCount: 0 }); // Hide the overlay menu. - await viewportPageObject.getById('default').overlayMenu.dataOverlay.toggle(); + await dataOverlayPageObject.toggle(); await page.waitForTimeout(5000); await checkForScreenshot( diff --git a/tests/SEGDataOverlayNoHydrationThenMPR.spec.ts b/tests/SEGDataOverlayNoHydrationThenMPR.spec.ts index 93dcbf1fd..5f1de2183 100644 --- a/tests/SEGDataOverlayNoHydrationThenMPR.spec.ts +++ b/tests/SEGDataOverlayNoHydrationThenMPR.spec.ts @@ -14,16 +14,15 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu', viewportPageObject, }) => { await rightPanelPageObject.toggle(); - await viewportPageObject.getById('default').overlayMenu.dataOverlay.toggle(); - await viewportPageObject - .getById('default') - .overlayMenu.dataOverlay.addSegmentation('Segmentation'); + const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; + await dataOverlayPageObject.toggle(); + await dataOverlayPageObject.addSegmentation('Segmentation'); // Adding an overlay should not show the LOAD button. assertNumberOfModalityLoadBadges({ page, expectedCount: 0 }); // Hide the overlay menu. - await viewportPageObject.getById('default').overlayMenu.dataOverlay.toggle(); + await dataOverlayPageObject.toggle(); await page.waitForTimeout(5000); diff --git a/tests/SEGDrawingToolsResizing.spec.ts b/tests/SEGDrawingToolsResizing.spec.ts index 1fe57ce47..365c905c1 100644 --- a/tests/SEGDrawingToolsResizing.spec.ts +++ b/tests/SEGDrawingToolsResizing.spec.ts @@ -20,11 +20,12 @@ async function performDrawingToolInteraction( rightPanelPageObject: RightPanelPageObject, viewportPageObject: ViewportPageObject ) { + const activeViewport = await viewportPageObject.active; const brushRadiusInput = rightPanelPageObject.labelMapSegmentationPanel.tools[toolName].input; - const circle = viewportPageObject.active.svg('circle').first(); + const circle = activeViewport.svg('circle').first(); await expect(brushRadiusInput).toHaveValue('25'); - await viewportPageObject.active.clickAt([{ x: 275, y: 300 }]); + await activeViewport.clickAt([{ x: 275, y: 300 }]); let radius = parseFloat(await circle.getAttribute('r')); expect(radius).toBeGreaterThanOrEqual(65); expect(radius).toBeLessThanOrEqual(68); @@ -32,7 +33,7 @@ async function performDrawingToolInteraction( await page.waitForTimeout(500); await press({ page, key: '[', nTimes: 2 }); await expect(brushRadiusInput).toHaveValue('19'); - await viewportPageObject.active.clickAt([{ x: 500, y: 300 }]); + await activeViewport.clickAt([{ x: 500, y: 300 }]); radius = parseFloat(await circle.getAttribute('r')); expect(radius).toBeGreaterThanOrEqual(49); expect(radius).toBeLessThanOrEqual(52); @@ -41,7 +42,7 @@ async function performDrawingToolInteraction( await press({ page, key: ']', nTimes: 5 }); await expect(brushRadiusInput).toHaveValue('34'); - await viewportPageObject.active.clickAt([{ x: 275, y: 500 }]); + await activeViewport.clickAt([{ x: 275, y: 500 }]); radius = parseFloat(await circle.getAttribute('r')); expect(radius).toBeGreaterThanOrEqual(87); expect(radius).toBeLessThanOrEqual(90); @@ -49,7 +50,7 @@ async function performDrawingToolInteraction( await page.waitForTimeout(500); await brushRadiusInput.fill('42'); - await viewportPageObject.active.clickAt([{ x: 500, y: 500 }]); + await activeViewport.clickAt([{ x: 500, y: 500 }]); radius = parseFloat(await circle.getAttribute('r')); expect(radius).toBeGreaterThanOrEqual(108); expect(radius).toBeLessThanOrEqual(111); @@ -62,13 +63,15 @@ test('should resize segmentation brush tool', async ({ rightPanelPageObject, viewportPageObject, }) => { + const activeViewport = await viewportPageObject.active; + await page.getByTestId('Brush-btn').click(); await performDrawingToolInteraction(page, 'brush', rightPanelPageObject, viewportPageObject); await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.segDrawingToolsResizing.brushTool ); }); @@ -78,10 +81,12 @@ test('should resize segmentation eraser tool', async ({ rightPanelPageObject, viewportPageObject, }) => { + const activeViewport = await viewportPageObject.active; + await page.getByTestId('Brush-btn').click(); await page.getByTestId('brush-radius').locator('input').fill('99.5'); - await viewportPageObject.active.clickAt([{ x: 400, y: 400 }]); + await activeViewport.clickAt([{ x: 400, y: 400 }]); await page.waitForTimeout(500); @@ -94,7 +99,7 @@ test('should resize segmentation eraser tool', async ({ await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.segDrawingToolsResizing.eraserTool ); }); diff --git a/tests/SRHydrationArrowNavigation.spec.ts b/tests/SRHydrationArrowNavigation.spec.ts index 9be6fbe94..0ffa2d35e 100644 --- a/tests/SRHydrationArrowNavigation.spec.ts +++ b/tests/SRHydrationArrowNavigation.spec.ts @@ -26,8 +26,10 @@ test('should navigate SR measurements with next/prev arrows after hydration for const measurementCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount(); expect(measurementCount).toBeGreaterThan(1); + const activeViewport = await viewportPageObject.active; + // Navigate to first image - await viewportPageObject.active.pane.click(); + await activeViewport.pane.click(); await press({ page, key: 'Home' }); await page.waitForTimeout(2000); @@ -36,9 +38,9 @@ test('should navigate SR measurements with next/prev arrows after hydration for await expectRowSelected(rightPanelPageObject.measurementsPanel.panel.nthMeasurement(1)); - await expect(viewportPageObject.active.svg('circle')).toBeVisible(); + await expect(activeViewport.svg('circle')).toBeVisible(); - const secondAnnotation = viewportPageObject.active.nthAnnotation(0); + const secondAnnotation = activeViewport.nthAnnotation(0); await expect(secondAnnotation.locator).toBeVisible(); await expect(secondAnnotation.text.locator).toBeVisible(); @@ -47,9 +49,9 @@ test('should navigate SR measurements with next/prev arrows after hydration for await expectRowSelected(rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0)); - await expect(viewportPageObject.active.svg('circle')).toBeVisible(); + await expect(activeViewport.svg('circle')).toBeVisible(); - const firstAnnotation = viewportPageObject.active.nthAnnotation(0); + const firstAnnotation = activeViewport.nthAnnotation(0); await expect(firstAnnotation.locator).toBeVisible(); await expect(firstAnnotation.text.locator).toBeVisible(); }); @@ -72,23 +74,25 @@ test('should keep arrows visible and functional after clicking measurement in ri const measurementCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount(); expect(measurementCount).toBeGreaterThan(1); + const activeViewport = await viewportPageObject.active; + // click on first measurement await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click(); - await expect(viewportPageObject.active.nthAnnotation(0).locator).toBeVisible(); + await expect(activeViewport.nthAnnotation(0).locator).toBeVisible(); - await expect(viewportPageObject.active.navigationArrows.next.button).toBeVisible(); - await expect(viewportPageObject.active.navigationArrows.prev.button).toBeVisible(); + await expect(activeViewport.navigationArrows.next.button).toBeVisible(); + await expect(activeViewport.navigationArrows.prev.button).toBeVisible(); // navigate to second measurement await navigateWithViewportArrow(viewportPageObject, 'next'); await expectRowSelected(rightPanelPageObject.measurementsPanel.panel.nthMeasurement(1)); - await expect(viewportPageObject.active.nthAnnotation(0).locator).toBeVisible(); + await expect(activeViewport.nthAnnotation(0).locator).toBeVisible(); // navigate back to first measurement await navigateWithViewportArrow(viewportPageObject, 'prev'); await expectRowSelected(rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0)); - await expect(viewportPageObject.active.nthAnnotation(0).locator).toBeVisible(); + await expect(activeViewport.nthAnnotation(0).locator).toBeVisible(); }); diff --git a/tests/Scoord3dProbe.spec.ts b/tests/Scoord3dProbe.spec.ts index 69cab3b9a..ad2c999a6 100644 --- a/tests/Scoord3dProbe.spec.ts +++ b/tests/Scoord3dProbe.spec.ts @@ -40,10 +40,12 @@ test('should hydrate SCOORD3D probe measurements correctly', async ({ // Wait for the SR to load and stabilize before taking screenshot await page.waitForTimeout(1000); + const activeViewport = await viewportPageObject.active; + // Take screenshot before hydration - use viewport locator instead of full page await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoord3dProbe.scoord3dProbePreHydration ); @@ -85,7 +87,7 @@ test('should hydrate SCOORD3D probe measurements correctly', async ({ // Take screenshot after hydration showing the probe measurements - use viewport locator await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoord3dProbe.scoord3dProbePostHydration ); @@ -131,7 +133,7 @@ test('should hydrate SCOORD3D probe measurements correctly', async ({ // Take screenshot showing the jump to measurement functionality - use viewport locator await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoord3dProbe.scoord3dProbeJumpToMeasurement ); }); @@ -182,10 +184,12 @@ test('should display SCOORD3D probe measurements correctly', async ({ // Wait for rendering to complete before taking screenshot await page.waitForTimeout(2000); + const activeViewport = await viewportPageObject.active; + // Take screenshot showing the SCOORD3D probe measurements rendered correctly - use viewport locator await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoord3dProbe.scoord3dProbeDisplayedCorrectly ); diff --git a/tests/ScoordRectangle.spec.ts b/tests/ScoordRectangle.spec.ts index 836178252..b7f92ad7b 100644 --- a/tests/ScoordRectangle.spec.ts +++ b/tests/ScoordRectangle.spec.ts @@ -41,10 +41,12 @@ test('should hydrate SCOORD rectangle measurements correctly', async ({ // Wait for the SR to load and stabilize before taking screenshot await page.waitForTimeout(1000); + const activeViewport = await viewportPageObject.active; + // Take screenshot before hydration - use viewport locator instead of full page await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoordRectangle.scoordRectanglePreHydration ); @@ -86,7 +88,7 @@ test('should hydrate SCOORD rectangle measurements correctly', async ({ // Take screenshot after hydration showing the rectangle measurements - use viewport locator await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoordRectangle.scoordRectanglePostHydration ); @@ -129,7 +131,7 @@ test('should hydrate SCOORD rectangle measurements correctly', async ({ // Take screenshot showing the jump to measurement functionality - use viewport locator await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoordRectangle.scoordRectangleJumpToMeasurement ); }); @@ -180,10 +182,12 @@ test('should display SCOORD rectangle measurements correctly', async ({ // Wait for rendering to complete before taking screenshot await page.waitForTimeout(2000); + const activeViewport = await viewportPageObject.active; + // Take screenshot showing the SCOORD rectangle measurements rendered correctly - use viewport locator await checkForScreenshot( page, - viewportPageObject.active.pane, + activeViewport.pane, screenShotPaths.scoordRectangle.scoordRectangleDisplayedCorrectly ); diff --git a/tests/SegmentationPanel.spec.ts b/tests/SegmentationPanel.spec.ts index 046f46bb2..22f1aad49 100644 --- a/tests/SegmentationPanel.spec.ts +++ b/tests/SegmentationPanel.spec.ts @@ -44,7 +44,8 @@ test('checks saved segmentations loads and jumps to slices', async ({ rightPanelPageObject, viewportPageObject, }) => { - const viewportInfoBottomRight = viewportPageObject.active.overlayText.bottomRight.instanceNumber; + const activeViewport = await viewportPageObject.active; + const viewportInfoBottomRight = activeViewport.overlayText.bottomRight.instanceNumber; // Image loads on slice 1, confirm on slice 1 await expect(viewportInfoBottomRight).toContainText('1/', { timeout: 10000 }); diff --git a/tests/Spline.spec.ts b/tests/Spline.spec.ts index db57222d8..79a41ee60 100644 --- a/tests/Spline.spec.ts +++ b/tests/Spline.spec.ts @@ -13,7 +13,8 @@ test('should display the spline tool', async ({ viewportPageObject, }) => { await mainToolbarPageObject.measurementTools.splineROI.click(); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 380, y: 459 }, { x: 420, y: 396 }, { x: 523, y: 392 }, diff --git a/tests/TMTVAlignment.spec.ts b/tests/TMTVAlignment.spec.ts index 611cd8e9c..d4ded1269 100644 --- a/tests/TMTVAlignment.spec.ts +++ b/tests/TMTVAlignment.spec.ts @@ -5,51 +5,54 @@ test.skip('PT should show slice closest to CT', async ({ page, viewportPageObjec const mode = 'tmtv'; await visitStudy(page, studyInstanceUID, mode); - const getNthViewportPane = (index: number) => viewportPageObject.getNth(index).pane; + const viewport1 = await viewportPageObject.getNth(1); + const viewport2 = await viewportPageObject.getNth(2); + const viewport4 = await viewportPageObject.getNth(4); + const viewport5 = await viewportPageObject.getNth(5); // Sagittal - await expect(getNthViewportPane(1)).toContainText('257/512', { + await expect(viewport1.pane).toContainText('257/512', { useInnerText: true, }); // Should default i 257 - await expect.soft(getNthViewportPane(4)).toContainText('97/192'); + await expect.soft(viewport4.pane).toContainText('97/192'); await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 256 - await expect(getNthViewportPane(1)).toContainText('256/512'); - await expect.soft(getNthViewportPane(4)).toContainText('96/192'); + await expect(viewport1.pane).toContainText('256/512'); + await expect.soft(viewport4.pane).toContainText('96/192'); await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 255 - await expect(getNthViewportPane(1)).toContainText('255/512'); - await expect.soft(getNthViewportPane(4)).toContainText('95/192'); + await expect(viewport1.pane).toContainText('255/512'); + await expect.soft(viewport4.pane).toContainText('95/192'); await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 254 - await expect(getNthViewportPane(1)).toContainText('254/512'); - await expect.soft(getNthViewportPane(4)).toContainText('95/192'); + await expect(viewport1.pane).toContainText('254/512'); + await expect.soft(viewport4.pane).toContainText('95/192'); await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 253 - await expect(getNthViewportPane(1)).toContainText('253/512'); - await expect.soft(getNthViewportPane(4)).toContainText('94/192'); + await expect(viewport1.pane).toContainText('253/512'); + await expect.soft(viewport4.pane).toContainText('94/192'); await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 252 - await expect(getNthViewportPane(1)).toContainText('252/512'); - await expect.soft(getNthViewportPane(4)).toContainText('94/192'); + await expect(viewport1.pane).toContainText('252/512'); + await expect.soft(viewport4.pane).toContainText('94/192'); await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 251 - await expect(getNthViewportPane(1)).toContainText('251/512'); - await expect.soft(getNthViewportPane(4)).toContainText('93/192'); + await expect(viewport1.pane).toContainText('251/512'); + await expect.soft(viewport4.pane).toContainText('93/192'); // Coronal - await expect(getNthViewportPane(2)).toContainText('256/512'); // Should default i 256 - await expect.soft(getNthViewportPane(5)).toContainText('96/192'); + await expect(viewport2.pane).toContainText('256/512'); // Should default i 256 + await expect.soft(viewport5.pane).toContainText('96/192'); await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 255 - await expect(getNthViewportPane(2)).toContainText('255/512'); - await expect.soft(getNthViewportPane(5)).toContainText('96/192'); + await expect(viewport2.pane).toContainText('255/512'); + await expect.soft(viewport5.pane).toContainText('96/192'); await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 254 - await expect(getNthViewportPane(2)).toContainText('254/512'); - await expect.soft(getNthViewportPane(5)).toContainText('95/192'); + await expect(viewport2.pane).toContainText('254/512'); + await expect.soft(viewport5.pane).toContainText('95/192'); await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 253 - await expect(getNthViewportPane(2)).toContainText('253/512'); - await expect.soft(getNthViewportPane(5)).toContainText('95/192'); + await expect(viewport2.pane).toContainText('253/512'); + await expect.soft(viewport5.pane).toContainText('95/192'); await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 252 - await expect(getNthViewportPane(2)).toContainText('252/512'); - await expect.soft(getNthViewportPane(5)).toContainText('94/192'); + await expect(viewport2.pane).toContainText('252/512'); + await expect.soft(viewport5.pane).toContainText('94/192'); await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 251 - await expect(getNthViewportPane(2)).toContainText('251/512'); - await expect.soft(getNthViewportPane(5)).toContainText('94/192'); + await expect(viewport2.pane).toContainText('251/512'); + await expect.soft(viewport5.pane).toContainText('94/192'); await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 250 - await expect(getNthViewportPane(2)).toContainText('250/512'); - await expect.soft(getNthViewportPane(5)).toContainText('93/192'); + await expect(viewport2.pane).toContainText('250/512'); + await expect.soft(viewport5.pane).toContainText('93/192'); }); diff --git a/tests/TMTVCSVReport.spec.ts b/tests/TMTVCSVReport.spec.ts index 70b25de0e..58671dc9a 100644 --- a/tests/TMTVCSVReport.spec.ts +++ b/tests/TMTVCSVReport.spec.ts @@ -13,7 +13,8 @@ test('should create and download the TMTV CSV report correctly', async ({ await rightPanelPageObject.tmtvPanel.addSegmentationButton.click(); await rightPanelPageObject.tmtvPanel.tools.brush.click(); - await viewportPageObject.getById('ctAXIAL').normalizedClickAt([{ x: 0.5, y: 0.5 }]); + const viewport = await viewportPageObject.getById('ctAXIAL'); + await viewport.normalizedClickAt([{ x: 0.5, y: 0.5 }]); await page.waitForTimeout(5000); diff --git a/tests/TMTVModalityUnit.spec.ts b/tests/TMTVModalityUnit.spec.ts index 314da4b3a..b791a686e 100644 --- a/tests/TMTVModalityUnit.spec.ts +++ b/tests/TMTVModalityUnit.spec.ts @@ -14,7 +14,8 @@ test.skip('pets where SUV cannot be calculated should show same unit in TMTV as await leftPanelPageObject.toggle(); // Change to image where SUV cannot be calculated - await viewportPageObject.getNth(3).normalizedClickAt([{ x: 0.5, y: 0.5 }]); + const viewport = await viewportPageObject.getNth(3); + await viewport.normalizedClickAt([{ x: 0.5, y: 0.5 }]); await page.getByRole('button', { name: 'NAC' }).nth(1).dblclick(); // Wait for the new series to load @@ -24,7 +25,7 @@ test.skip('pets where SUV cannot be calculated should show same unit in TMTV as mainToolbarPageObject.measurementTools.ellipticalROI.click(); await clearAllAnnotations(page); - await viewportPageObject.active.clickAt([ + await (await viewportPageObject.active).clickAt([ { x: 100, y: 100 }, { x: 150, y: 150 }, ]); diff --git a/tests/TMTVRecalculate.spec.ts b/tests/TMTVRecalculate.spec.ts index ea363e9c4..8f16a6f2c 100644 --- a/tests/TMTVRecalculate.spec.ts +++ b/tests/TMTVRecalculate.spec.ts @@ -14,7 +14,8 @@ test.skip('should update SUV values correctly.', async ({ await mainToolbarPageObject.measurementTools.ellipticalROI.click(); await clearAllAnnotations(page); - await viewportPageObject.active.clickAt([ + const activeViewport = await viewportPageObject.active; + await activeViewport.clickAt([ { x: 100, y: 100 }, { x: 150, y: 150 }, ]); diff --git a/tests/TMTVSUV.spec.ts b/tests/TMTVSUV.spec.ts index c823e34a6..29aac2f74 100644 --- a/tests/TMTVSUV.spec.ts +++ b/tests/TMTVSUV.spec.ts @@ -9,7 +9,8 @@ test('should restrict the percentage of max SUV to be between 0 and 1', async ({ const mode = 'tmtv'; await visitStudy(page, studyInstanceUID, mode, 10000); - await viewportPageObject.getById('ptAXIAL').normalizedClickAt([{ x: 0.5, y: 0.5 }]); + const viewport = await viewportPageObject.getById('ptAXIAL'); + await viewport.normalizedClickAt([{ x: 0.5, y: 0.5 }]); await rightPanelPageObject.tmtvPanel.addSegmentationButton.click(); diff --git a/tests/WindowLevelOverlayText.spec.ts b/tests/WindowLevelOverlayText.spec.ts index 2a7145d6d..a2a848d75 100644 --- a/tests/WindowLevelOverlayText.spec.ts +++ b/tests/WindowLevelOverlayText.spec.ts @@ -9,20 +9,20 @@ test('should display the window level text as an overlay in various viewport lay const mode = 'viewer'; await visitStudy(page, studyInstanceUID, mode, 2000); - await expect(viewportPageObject.getNth(0).overlayText.bottomLeft.windowLevel).toBeVisible(); + await expect((await viewportPageObject.getNth(0)).overlayText.bottomLeft.windowLevel).toBeVisible(); await mainToolbarPageObject.layoutSelection.click(); await page.getByTestId('Layout-3-0').click(); for (let i = 0; i < 3; i++) { - await expect(viewportPageObject.getNth(i).overlayText.bottomLeft.windowLevel).toBeVisible(); + await expect((await viewportPageObject.getNth(i)).overlayText.bottomLeft.windowLevel).toBeVisible(); } await mainToolbarPageObject.layoutSelection.click(); await page.getByTestId('Layout-1-1').click(); for (let i = 0; i < 3; i++) { - await expect(viewportPageObject.getNth(i).overlayText.bottomLeft.windowLevel).toBeVisible(); + await expect((await viewportPageObject.getNth(i)).overlayText.bottomLeft.windowLevel).toBeVisible(); } }); @@ -35,6 +35,6 @@ test('should display the window level text as an overlay in the various TMTV vie await visitStudy(page, studyInstanceUID, mode, 2000); for (let i = 0; i < 9; i++) { - await expect(viewportPageObject.getNth(i).overlayText.bottomLeft.windowLevel).toBeVisible(); + await expect((await viewportPageObject.getNth(i)).overlayText.bottomLeft.windowLevel).toBeVisible(); } }); diff --git a/tests/pages/DataOverlayPageObject.ts b/tests/pages/DataOverlayPageObject.ts index 4b830d6d9..e26d4632b 100644 --- a/tests/pages/DataOverlayPageObject.ts +++ b/tests/pages/DataOverlayPageObject.ts @@ -2,17 +2,19 @@ import { Page } from '@playwright/test'; export class DataOverlayPageObject { readonly page: Page; + readonly viewportId: string; - constructor(page: Page) { + constructor(page: Page, viewportId: string) { this.page = page; + this.viewportId = viewportId; } - async toggle(viewportId: string = 'default') { - await this.page.getByTestId(`dataOverlayMenu-${viewportId}-btn`).click(); + async toggle() { + await this.page.getByTestId(`dataOverlayMenu-${this.viewportId}-btn`).click(); } - async addSegmentation(segmentation: string, viewportId: string = 'default') { - await this.page.getByTestId(`AddSegmentationDataOverlay-${viewportId}`).click(); + async addSegmentation(segmentation: string) { + await this.page.getByTestId(`AddSegmentationDataOverlay-${this.viewportId}`).click(); await this.page.getByText('SELECT A SEGMENTATION').click(); await this.page.getByTestId(segmentation).click(); } diff --git a/tests/pages/ViewportPageObject.ts b/tests/pages/ViewportPageObject.ts index 690b7eea6..e40015b85 100644 --- a/tests/pages/ViewportPageObject.ts +++ b/tests/pages/ViewportPageObject.ts @@ -21,7 +21,6 @@ export interface IOverlayText { get windowLevel(): Locator; get instanceNumber(): Locator; } - function overlayTextFactory(viewport: Locator, id: string): IOverlayText { const locator = viewport.getByTestId(id); return { @@ -96,11 +95,9 @@ export interface IViewportPageObject { export class ViewportPageObject { readonly page: Page; - private readonly dataOverlayPageObject: DataOverlayPageObject; constructor(page: Page) { this.page = page; - this.dataOverlayPageObject = new DataOverlayPageObject(page); } private getAnnotation(viewport: Locator, nth: number) { @@ -128,6 +125,14 @@ export class ViewportPageObject { }; } + private async getViewportId(viewport: Locator): Promise { + const id = await viewport.locator('[data-viewportid]').getAttribute('data-viewportid'); + if (id === null) { + throw new Error('Could not resolve data-viewportid from viewport locator'); + } + return id; + } + private getOrientationMarkers(viewport: Locator) { return { topMid: viewport.locator('.top-mid.orientation-marker'), @@ -146,9 +151,9 @@ export class ViewportPageObject { }; } - private getOverlayMenu(viewport: Locator) { + private async getOverlayMenu(viewport: Locator) { return { - dataOverlay: this.dataOverlayPageObject, + dataOverlay: new DataOverlayPageObject(this.page, await this.getViewportId(viewport)), get orientation() { const button = viewport.locator('[data-cy^="orientationMenu"]'); return { @@ -195,7 +200,7 @@ export class ViewportPageObject { }; } - private viewportPageObjectFactory(viewport: Locator): IViewportPageObject { + private async viewportPageObjectFactory(viewport: Locator): Promise { return { nthAnnotation: (nth: number) => this.getAnnotation(viewport, nth), doubleClickAt: async (point: { x: number; y: number }) => { @@ -233,7 +238,7 @@ export class ViewportPageObject { }, orientationMarkers: this.getOrientationMarkers(viewport), overlayText: this.getOverlayText(viewport), - overlayMenu: this.getOverlayMenu(viewport), + overlayMenu: await this.getOverlayMenu(viewport), pane: viewport, svg: (innerElement?: SvgInnerElement) => { return this.getSvg(viewport, innerElement); @@ -242,7 +247,7 @@ export class ViewportPageObject { }; } - get active(): IViewportPageObject { + get active(): Promise { const viewport = this.page.locator('[data-cy="viewport-pane"][data-is-active="true"]'); return this.viewportPageObjectFactory(viewport); } @@ -313,15 +318,19 @@ export class ViewportPageObject { async getAll(): Promise { const viewports = await this.page.getByTestId('viewport-pane').all(); - return viewports.map(viewport => this.viewportPageObjectFactory(viewport)); + return await Promise.all(viewports.map(viewport => this.viewportPageObjectFactory(viewport))); } - getNth(index: number): IViewportPageObject { - const viewport = this.page.getByTestId('viewport-pane').nth(index); + getNth(index: number): Promise { + const viewport = this.getNthLocator(index); return this.viewportPageObjectFactory(viewport); } - getById(viewportId: string): IViewportPageObject { + getNthLocator(index: number): Locator { + return this.page.getByTestId('viewport-pane').nth(index); + } + + getById(viewportId: string): Promise { const viewport = this.page.locator( `[data-cy="viewport-pane"]:has(div[data-viewportid="${viewportId}"])` ); diff --git a/tests/utils/addLengthMeasurement.ts b/tests/utils/addLengthMeasurement.ts index 9d5960a11..8ddbc9d8a 100644 --- a/tests/utils/addLengthMeasurement.ts +++ b/tests/utils/addLengthMeasurement.ts @@ -33,7 +33,7 @@ export async function addLengthMeasurement( const [x2, y2] = secondClick; const lengthButton = mainToolbarPageObject.measurementTools.selectedTool.button; - const viewport = viewportPageObject.active; + const viewport = await viewportPageObject.active; // Assert that the primary measurement button is 'Length' tool await expect(lengthButton).toHaveAttribute('data-tool', 'Length'); diff --git a/tests/utils/getSvgPath.ts b/tests/utils/getSvgPath.ts index 16461e823..1fb6359e3 100644 --- a/tests/utils/getSvgPath.ts +++ b/tests/utils/getSvgPath.ts @@ -1,11 +1,7 @@ import { ViewportPageObject } from '../pages/ViewportPageObject'; const getSvgPath = async (viewportPageObject: ViewportPageObject, viewportId = 'default') => { - return viewportPageObject - .getById(viewportId) - .svg('path') - .first() - .getAttribute('d'); + return (await viewportPageObject.getById(viewportId)).svg('path').first().getAttribute('d'); }; export { getSvgPath }; diff --git a/tests/utils/navigateWithViewportArrow.ts b/tests/utils/navigateWithViewportArrow.ts index bdd472ba5..1a84cfb35 100644 --- a/tests/utils/navigateWithViewportArrow.ts +++ b/tests/utils/navigateWithViewportArrow.ts @@ -5,9 +5,8 @@ const navigateWithViewportArrow = async ( direction: 'next' | 'prev', viewportId = 'default' ) => { - const viewport = viewportPageObject.getById(viewportId); + const viewport = await viewportPageObject.getById(viewportId); await viewport.navigationArrows[direction].click(); }; export { navigateWithViewportArrow }; -