chore(tests): contour segment interactions e2e tests - rename and togglevisibility (#5891)
This commit is contained in:
parent
87eeefdf1b
commit
fe762b68e8
@ -206,6 +206,7 @@ const ActionsSecondary = React.forwardRef<HTMLDivElement, InputDialogActionButto
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
data-cy="input-dialog-cancel-button"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<FooterAction.Secondary
|
<FooterAction.Secondary
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export const AddSegmentRow: React.FC<{ children?: React.ReactNode }> = ({ childr
|
|||||||
onToggleSegmentationRepresentationVisibility,
|
onToggleSegmentationRepresentationVisibility,
|
||||||
data,
|
data,
|
||||||
showAddSegment,
|
showAddSegment,
|
||||||
|
segmentationRepresentationTypes
|
||||||
} = useSegmentationTableContext('AddSegmentRow');
|
} = useSegmentationTableContext('AddSegmentRow');
|
||||||
|
|
||||||
// Try to get from expanded context first, then fall back to active segmentation
|
// Try to get from expanded context first, then fall back to active segmentation
|
||||||
@ -47,6 +48,10 @@ export const AddSegmentRow: React.FC<{ children?: React.ReactNode }> = ({ childr
|
|||||||
|
|
||||||
const allowAddSegment = showAddSegment && !disableEditing;
|
const allowAddSegment = showAddSegment && !disableEditing;
|
||||||
|
|
||||||
|
const dataCyTypeSuffix = segmentationRepresentationTypes
|
||||||
|
? `-${segmentationRepresentationTypes[0]}`
|
||||||
|
: '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="my-px flex h-7 w-full items-center justify-between rounded pl-0.5 pr-7">
|
<div className="my-px flex h-7 w-full items-center justify-between rounded pl-0.5 pr-7">
|
||||||
<div className="mt-1 flex-1">
|
<div className="mt-1 flex-1">
|
||||||
@ -65,6 +70,7 @@ export const AddSegmentRow: React.FC<{ children?: React.ReactNode }> = ({ childr
|
|||||||
<Button
|
<Button
|
||||||
size="icon"
|
size="icon"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
data-cy={`all-segments-visibility-toggle${dataCyTypeSuffix}`}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
onToggleSegmentationRepresentationVisibility(segmentationId, representation?.type)
|
onToggleSegmentationRepresentationVisibility(segmentationId, representation?.type)
|
||||||
}
|
}
|
||||||
|
|||||||
57
tests/ContourSegmentRename.spec.ts
Normal file
57
tests/ContourSegmentRename.spec.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { expect, test, visitStudy } from './utils';
|
||||||
|
|
||||||
|
const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501';
|
||||||
|
const defautSegment0Name = 'Threshold';
|
||||||
|
const defautSegment1Name = 'Big Sphere';
|
||||||
|
|
||||||
|
test.beforeEach(async ({
|
||||||
|
page,
|
||||||
|
leftPanelPageObject,
|
||||||
|
DOMOverlayPageObject
|
||||||
|
}) => {
|
||||||
|
const mode = 'segmentation';
|
||||||
|
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||||
|
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
|
||||||
|
await page.waitForTimeout(5000);
|
||||||
|
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should rename contour segments', async ({
|
||||||
|
rightPanelPageObject,
|
||||||
|
}) => {
|
||||||
|
const segment0 = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0);
|
||||||
|
const segment1 = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(1);
|
||||||
|
|
||||||
|
await expect(segment0.title).toHaveText(defautSegment0Name);
|
||||||
|
await expect(segment1.title).toHaveText(defautSegment1Name);
|
||||||
|
|
||||||
|
await segment0.actions.rename('Renamed Segment');
|
||||||
|
await segment1.actions.rename('Seg-2 (updated) / v2.0 #$^&&@*!!');
|
||||||
|
|
||||||
|
await expect(segment0.title).toHaveText('Renamed Segment');
|
||||||
|
|
||||||
|
await expect(segment1.title).toHaveText('Seg-2 (updated) / v2.0 #$^&&@*!!');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not rename segment when dialog is cancelled without filling', async ({
|
||||||
|
rightPanelPageObject,
|
||||||
|
}) => {
|
||||||
|
const segment = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0);
|
||||||
|
await expect(segment.title).toHaveText(defautSegment0Name);
|
||||||
|
|
||||||
|
await segment.actions.cancelRename();
|
||||||
|
|
||||||
|
await expect(segment.title).toHaveText(defautSegment0Name);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not rename segment when dialog is cancelled after filling', async ({
|
||||||
|
rightPanelPageObject,
|
||||||
|
}) => {
|
||||||
|
const segment = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0);
|
||||||
|
|
||||||
|
await expect(segment.title).toHaveText(defautSegment0Name);
|
||||||
|
|
||||||
|
await segment.actions.cancelRename('Do Not Persist');
|
||||||
|
|
||||||
|
await expect(segment.title).toHaveText(defautSegment0Name);
|
||||||
|
});
|
||||||
113
tests/ContourSegmentToggleVisibility.spec.ts
Normal file
113
tests/ContourSegmentToggleVisibility.spec.ts
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { expect, test, visitStudy, getSvgPath, navigateWithViewportArrow } from './utils';
|
||||||
|
|
||||||
|
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('should toggle all segments visibility - on/off', async ({
|
||||||
|
rightPanelPageObject,
|
||||||
|
viewportPageObject,
|
||||||
|
}) => {
|
||||||
|
const svgPathLocator = 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 rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click();
|
||||||
|
|
||||||
|
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');
|
||||||
|
await expect(svgPathLocator, 'All segments to be hidden').toHaveCount(0);
|
||||||
|
|
||||||
|
await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(1).click();
|
||||||
|
await expect(svgPathLocator, 'All segments to remain hidden').toHaveCount(0);
|
||||||
|
|
||||||
|
await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(2).click();
|
||||||
|
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');
|
||||||
|
await expect(svgPathLocator, 'All segments to be hidden').toHaveCount(0);
|
||||||
|
|
||||||
|
await navigateWithViewportArrow(viewportPageObject, 'next');
|
||||||
|
await expect(svgPathLocator, 'All segments to remain hidden ').toHaveCount(0);
|
||||||
|
|
||||||
|
await navigateWithViewportArrow(viewportPageObject, 'next');
|
||||||
|
await expect(svgPathLocator, 'All segments to remain hidden ').toHaveCount(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should restore svg paths when segment visibility is toggled on/off', async ({
|
||||||
|
rightPanelPageObject,
|
||||||
|
viewportPageObject,
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
|
await rightPanelPageObject.contourSegmentationPanel.segmentsVisibilityToggle.click();
|
||||||
|
|
||||||
|
const segment0 = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(0);
|
||||||
|
await segment0.toggleVisibility();
|
||||||
|
const svgPathBefore = await getSvgPath(viewportPageObject);
|
||||||
|
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 segment0.toggleVisibility();
|
||||||
|
const svgPathAfter = await getSvgPath(viewportPageObject);
|
||||||
|
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 ({
|
||||||
|
rightPanelPageObject,
|
||||||
|
viewportPageObject,
|
||||||
|
}) => {
|
||||||
|
// Establish known state by selecting segment 1
|
||||||
|
await rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(1).click();
|
||||||
|
const svgPathLocator = 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);
|
||||||
|
await segment0.toggleVisibility();
|
||||||
|
await expect(svgPathLocator, 'Expected count to be 3 segments remaining').toHaveCount(3);
|
||||||
|
|
||||||
|
const segment1 = rightPanelPageObject.contourSegmentationPanel.panel.nthSegment(1);
|
||||||
|
await segment1.toggleVisibility();
|
||||||
|
await expect(svgPathLocator, 'Expected count to be 2 segments remaining').toHaveCount(2);
|
||||||
|
|
||||||
|
await segment0.toggleVisibility();
|
||||||
|
await expect(svgPathLocator, 'Expected count to be back to 3 segments remaining').toHaveCount(3);
|
||||||
|
|
||||||
|
await segment1.toggleVisibility();
|
||||||
|
await expect(svgPathLocator, 'Expected count to be restored to initial').toHaveCount(4);
|
||||||
|
});
|
||||||
@ -33,6 +33,7 @@ export class DOMOverlayPageObject {
|
|||||||
get input() {
|
get input() {
|
||||||
const locator = page.getByTestId('dialog-input');
|
const locator = page.getByTestId('dialog-input');
|
||||||
const saveButton = page.getByTestId('input-dialog-save-button');
|
const saveButton = page.getByTestId('input-dialog-save-button');
|
||||||
|
const cancelButton = page.getByTestId('input-dialog-cancel-button');
|
||||||
return {
|
return {
|
||||||
locator,
|
locator,
|
||||||
fill: async (text: string) => {
|
fill: async (text: string) => {
|
||||||
@ -45,6 +46,13 @@ export class DOMOverlayPageObject {
|
|||||||
save: async () => {
|
save: async () => {
|
||||||
await saveButton.click();
|
await saveButton.click();
|
||||||
},
|
},
|
||||||
|
fillAndCancel: async (text: string) => {
|
||||||
|
await locator.fill(text);
|
||||||
|
await cancelButton.click();
|
||||||
|
},
|
||||||
|
cancel: async () => {
|
||||||
|
await cancelButton.click();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,19 @@ export class RightPanelPageObject {
|
|||||||
await this.page.getByTestId('Rename').click();
|
await this.page.getByTestId('Rename').click();
|
||||||
await this.DOMOverlayPageObject.dialog.input.fillAndSave(text);
|
await this.DOMOverlayPageObject.dialog.input.fillAndSave(text);
|
||||||
},
|
},
|
||||||
|
cancelRename: async (newName?: string) => {
|
||||||
|
await actionsButton.click();
|
||||||
|
await this.page.getByTestId('Rename').click();
|
||||||
|
if (newName) {
|
||||||
|
await this.DOMOverlayPageObject.dialog.input.fillAndCancel(newName);
|
||||||
|
} else {
|
||||||
|
await this.DOMOverlayPageObject.dialog.input.cancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
duplicate: async () => {
|
||||||
|
await actionsButton.click();
|
||||||
|
await this.page.getByTestId('Duplicate').click();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +87,7 @@ export class RightPanelPageObject {
|
|||||||
return row.getByTestId('data-row-title');
|
return row.getByTestId('data-row-title');
|
||||||
},
|
},
|
||||||
click: async () => {
|
click: async () => {
|
||||||
await row.click();
|
await row.getByTestId('data-row-title').click();
|
||||||
},
|
},
|
||||||
locator: row,
|
locator: row,
|
||||||
toggleVisibility: async () => {
|
toggleVisibility: async () => {
|
||||||
@ -161,6 +174,19 @@ export class RightPanelPageObject {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getSegmentsVisibilityToggle(type?: string) {
|
||||||
|
const testId = type
|
||||||
|
? `all-segments-visibility-toggle-${type}`
|
||||||
|
: 'all-segments-visibility-toggle';
|
||||||
|
const button = this.page.getByTestId(testId);
|
||||||
|
return {
|
||||||
|
button,
|
||||||
|
click: async () => {
|
||||||
|
await button.click();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private getSegmentationPanel(typeSuffix?: string) {
|
private getSegmentationPanel(typeSuffix?: string) {
|
||||||
const page = this.page;
|
const page = this.page;
|
||||||
const getSegmentByIdx = (index: number) => this.getPanelRowByIdx(index);
|
const getSegmentByIdx = (index: number) => this.getPanelRowByIdx(index);
|
||||||
@ -189,10 +215,12 @@ export class RightPanelPageObject {
|
|||||||
const panel = this.getSegmentationPanel('Contour');
|
const panel = this.getSegmentationPanel('Contour');
|
||||||
const menuButton = page.getByTestId('panelSegmentationWithToolsContour-btn');
|
const menuButton = page.getByTestId('panelSegmentationWithToolsContour-btn');
|
||||||
const segmentationSelect = this.getSegmentationSelect('Contour');
|
const segmentationSelect = this.getSegmentationSelect('Contour');
|
||||||
|
const segmentsVisibilityToggle = this.getSegmentsVisibilityToggle('Contour');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addSegmentationButton,
|
addSegmentationButton,
|
||||||
menuButton,
|
menuButton,
|
||||||
|
segmentsVisibilityToggle,
|
||||||
panel,
|
panel,
|
||||||
segmentationSelect,
|
segmentationSelect,
|
||||||
select: async () => {
|
select: async () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user