test( zoomIn-tool): verify horizontal flip is preserved in magnified view (#5983)
This commit is contained in:
1 parent
03860030bd
commit
62620afb9b
20 files changed
+384
-220
No files matched your search
@@ -0,0 +1,34 @@
|
||||
import { checkForScreenshot, screenShotPaths, test, visitStudy } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046';
|
||||
const mode = 'viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should render the magnified region with the same horizontal flip as the source viewport', async ({
|
||||
page,
|
||||
mainToolbarPageObject,
|
||||
viewportPageObject,
|
||||
}) => {
|
||||
await mainToolbarPageObject.moreTools.flipHorizontal.click();
|
||||
|
||||
const activeViewport = await viewportPageObject.active;
|
||||
|
||||
await activeViewport.sliceNavigation.toSlice(61);
|
||||
|
||||
await mainToolbarPageObject.moreTools.magnify.click();
|
||||
|
||||
await activeViewport.magnifyGlass.drag({
|
||||
start: { x: 0.78, y: 0.91 },
|
||||
mouseUp: false,
|
||||
});
|
||||
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
activeViewport.magnifyGlass.locator,
|
||||
screenShotPaths.zoomIn.magnifyViewportDisplayedCorrectly
|
||||
);
|
||||
|
||||
await activeViewport.magnifyGlass.stopDrag();
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
import { simulateNormalizedDragOnElement } from '../utils';
|
||||
|
||||
type MagnifyDragParams = {
|
||||
start: { x: number; y: number };
|
||||
end?: { x: number; y: number };
|
||||
mouseUp?: boolean;
|
||||
button?: 'left' | 'right' | 'middle';
|
||||
delay?: number;
|
||||
steps?: number;
|
||||
};
|
||||
|
||||
export class MagnifyGlassPageObject {
|
||||
readonly page: Page;
|
||||
readonly viewport: Locator;
|
||||
|
||||
constructor(page: Page, viewport: Locator) {
|
||||
this.page = page;
|
||||
this.viewport = viewport;
|
||||
}
|
||||
|
||||
get locator(): Locator {
|
||||
return this.viewport.locator('.magnifyTool');
|
||||
}
|
||||
|
||||
async drag({
|
||||
start,
|
||||
end,
|
||||
button,
|
||||
delay,
|
||||
steps,
|
||||
mouseUp = true,
|
||||
}: MagnifyDragParams): Promise<void> {
|
||||
await simulateNormalizedDragOnElement({
|
||||
locator: this.viewport,
|
||||
start,
|
||||
end: end ?? start,
|
||||
button,
|
||||
delay,
|
||||
steps,
|
||||
mouseUp,
|
||||
});
|
||||
}
|
||||
|
||||
async stopDrag(): Promise<void> {
|
||||
await this.page.mouse.up();
|
||||
}
|
||||
}
|
||||
@@ -326,6 +326,16 @@ export class MainToolbarPageObject {
|
||||
},
|
||||
};
|
||||
},
|
||||
get magnify() {
|
||||
const button = page.getByTestId('Magnify');
|
||||
return {
|
||||
button,
|
||||
async click() {
|
||||
await moreTools.click();
|
||||
await button.click();
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '../utils';
|
||||
import { DataOverlayPageObject } from './DataOverlayPageObject';
|
||||
import { DOMOverlayPageObject } from './DOMOverlayPageObject';
|
||||
import { MagnifyGlassPageObject } from './MagnifyGlassPageObject';
|
||||
|
||||
type SvgInnerElement = 'circle' | 'path' | 'd';
|
||||
|
||||
@@ -91,6 +92,13 @@ export interface IViewportPageObject {
|
||||
click: () => Promise<void>;
|
||||
};
|
||||
};
|
||||
sliceNavigation: {
|
||||
toSlice: (sliceIndex: number) => Promise<void>;
|
||||
toFirstSlice: () => Promise<void>;
|
||||
toLastSlice: () => Promise<void>;
|
||||
scrollBy: (delta: number) => Promise<void>;
|
||||
};
|
||||
magnifyGlass: MagnifyGlassPageObject;
|
||||
}
|
||||
|
||||
export class ViewportPageObject {
|
||||
@@ -200,6 +208,59 @@ export class ViewportPageObject {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: awaiting the returned methods (toSlice, toFirstSlice, toLastSlice, scrollBy)
|
||||
* does not guarantee the viewport has finished rendering. Follow up with
|
||||
* `waitForViewportsRendered` if you need pixel-stable state.
|
||||
*/
|
||||
private getSliceNavigation(viewport: Locator) {
|
||||
const page = this.page;
|
||||
|
||||
const jumpToImage = async (imageIndex: number) => {
|
||||
const viewportId = await this.getViewportId(viewport);
|
||||
await page.evaluate(
|
||||
({ commandsManager, viewportId, imageIndex }) => {
|
||||
return commandsManager.runCommand('jumpToImage', {
|
||||
imageIndex,
|
||||
viewport: { id: viewportId },
|
||||
});
|
||||
},
|
||||
{
|
||||
viewportId,
|
||||
imageIndex,
|
||||
commandsManager: await page.evaluateHandle('window.commandsManager'),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const scrollBy = async (delta: number) => {
|
||||
const viewportId = await this.getViewportId(viewport);
|
||||
await page.evaluate(
|
||||
({ services, viewportId, delta }) => {
|
||||
const cornerstoneViewport = (
|
||||
services as any
|
||||
).cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
||||
if (!cornerstoneViewport) {
|
||||
return;
|
||||
}
|
||||
return cornerstoneViewport.scroll(delta);
|
||||
},
|
||||
{
|
||||
viewportId,
|
||||
delta,
|
||||
services: await page.evaluateHandle('window.services'),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
toSlice: jumpToImage,
|
||||
toFirstSlice: () => jumpToImage(0),
|
||||
toLastSlice: () => jumpToImage(-1),
|
||||
scrollBy,
|
||||
};
|
||||
}
|
||||
|
||||
private async viewportPageObjectFactory(viewport: Locator): Promise<IViewportPageObject> {
|
||||
return {
|
||||
nthAnnotation: (nth: number) => this.getAnnotation(viewport, nth),
|
||||
@@ -244,6 +305,8 @@ export class ViewportPageObject {
|
||||
return this.getSvg(viewport, innerElement);
|
||||
},
|
||||
navigationArrows: this.getNavigationArrows(viewport),
|
||||
sliceNavigation: this.getSliceNavigation(viewport),
|
||||
magnifyGlass: new MagnifyGlassPageObject(this.page, viewport),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { RightPanelPageObject } from './RightPanelPageObject';
|
||||
import { ViewportPageObject } from './ViewportPageObject';
|
||||
import { NotFoundStudyPageObject } from './NotFoundStudyPageObject';
|
||||
import { DicomTagBrowserPageObject } from './DicomTagBrowserPageObject';
|
||||
import { MagnifyGlassPageObject } from './MagnifyGlassPageObject';
|
||||
|
||||
export {
|
||||
DOMOverlayPageObject,
|
||||
@@ -14,4 +15,5 @@ export {
|
||||
ViewportPageObject,
|
||||
NotFoundStudyPageObject,
|
||||
DicomTagBrowserPageObject,
|
||||
MagnifyGlassPageObject,
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -97,6 +97,9 @@ const screenShotPaths = {
|
||||
reset: {
|
||||
resetDisplayedCorrectly: 'resetDisplayedCorrectly.png',
|
||||
},
|
||||
zoomIn: {
|
||||
magnifyViewportDisplayedCorrectly: 'magnifyViewportDisplayedCorrectly.png',
|
||||
},
|
||||
rtDataOverlayForUnreferencedDisplaySetNoHydration: {
|
||||
overlayFirstImage: 'overlayFirstImage.png',
|
||||
overlayMiddleImage: 'overlayMiddleImage.png',
|
||||
|
||||
@@ -17,6 +17,7 @@ export async function simulateNormalizedDragOnElement({
|
||||
button = 'left',
|
||||
delay = 50,
|
||||
steps = 10,
|
||||
mouseUp = true,
|
||||
}: {
|
||||
locator: Locator;
|
||||
start: { x: number; y: number };
|
||||
@@ -24,6 +25,7 @@ export async function simulateNormalizedDragOnElement({
|
||||
button?: 'left' | 'right' | 'middle';
|
||||
delay?: number;
|
||||
steps?: number;
|
||||
mouseUp?: boolean;
|
||||
}) {
|
||||
const bBox = await locator.boundingBox();
|
||||
if (!bBox) {
|
||||
@@ -42,7 +44,7 @@ export async function simulateNormalizedDragOnElement({
|
||||
// Get the page from the locator context
|
||||
const page = locator.page();
|
||||
|
||||
page.mouse.move(startPosition.x, startPosition.y);
|
||||
await page.mouse.move(startPosition.x, startPosition.y);
|
||||
|
||||
// Start drag
|
||||
await page.mouse.down({ button });
|
||||
@@ -63,5 +65,7 @@ export async function simulateNormalizedDragOnElement({
|
||||
}
|
||||
|
||||
// End drag
|
||||
await page.mouse.up({ button });
|
||||
if (mouseUp) {
|
||||
await page.mouse.up({ button });
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user