refactor(tests): update viewport page object usage to async and update all effected tests (#5927)

This commit is contained in:
Ghadeer Albattarni 2026-03-27 16:37:42 -04:00 committed by GitHub
parent 485f0d75d9
commit 2a728b244c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 240 additions and 181 deletions

View File

@ -254,6 +254,7 @@ const DicomMicroscopyViewport = React.memo(
</div>
<div
style={style}
data-viewportid={viewportId}
ref={(ref: any) => {
container.current = ref;
resizeRef.current = ref;

View File

@ -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 },

View File

@ -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');

View File

@ -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 },
]);

View File

@ -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 },
]);

View File

@ -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 },

View File

@ -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,

View File

@ -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'),

View File

@ -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);

View File

@ -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');

View File

@ -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();

View File

@ -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 },
]);

View File

@ -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();
}

View File

@ -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 },
]);

View File

@ -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 },
});

View File

@ -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 },
]);

View File

@ -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 },

View File

@ -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 });

View File

@ -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 });

View File

@ -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);
});

View File

@ -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();

View File

@ -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');

View File

@ -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);
});

View File

@ -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');

View File

@ -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');

View File

@ -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
);
});

View File

@ -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 },
]);

View File

@ -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(

View File

@ -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);

View File

@ -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
);
});

View File

@ -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();
});

View File

@ -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
);

View File

@ -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
);

View File

@ -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 });

View File

@ -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 },

View File

@ -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');
});

View File

@ -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);

View File

@ -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 },
]);

View File

@ -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 },
]);

View File

@ -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();

View File

@ -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();
}
});

View File

@ -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();
}

View File

@ -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<string> {
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<IViewportPageObject> {
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<IViewportPageObject> {
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<IViewportPageObject[]> {
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<IViewportPageObject> {
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<IViewportPageObject> {
const viewport = this.page.locator(
`[data-cy="viewport-pane"]:has(div[data-viewportid="${viewportId}"])`
);

View File

@ -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');

View File

@ -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 };

View File

@ -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 };