init
This commit is contained in:
35
tests/utils/checkForScreenshot.ts
Normal file
35
tests/utils/checkForScreenshot.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { Locator, Page } from 'playwright';
|
||||
|
||||
/**
|
||||
* @param page - The page to interact with
|
||||
* @param locator - The element to check for screenshot
|
||||
* @param screenshotPath - The path to save the screenshot
|
||||
* @param attempts - The number of attempts to check for screenshot
|
||||
* @param delay - The delay between attempts
|
||||
* @returns True if the screenshot matches, otherwise throws an error
|
||||
*/
|
||||
const checkForScreenshot = async (
|
||||
page: Page,
|
||||
locator: Locator | Page,
|
||||
screenshotPath: string,
|
||||
attempts = 10,
|
||||
delay = 100
|
||||
) => {
|
||||
await page.waitForLoadState('networkidle');
|
||||
for (let i = 1; i < attempts; i++) {
|
||||
try {
|
||||
await expect(locator).toHaveScreenshot(screenshotPath, {
|
||||
maxDiffPixelRatio: 0.1,
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (i === attempts) {
|
||||
throw new Error('Screenshot does not match.');
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { checkForScreenshot };
|
||||
10
tests/utils/clearAllAnnotations.ts
Normal file
10
tests/utils/clearAllAnnotations.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
const clearAllAnnotations = async page => {
|
||||
await page.evaluate(
|
||||
({ cornerstoneTools }: AppTypes.Test) => {
|
||||
cornerstoneTools.annotation.state.removeAllAnnotations();
|
||||
},
|
||||
await page.evaluateHandle('window')
|
||||
);
|
||||
};
|
||||
|
||||
export { clearAllAnnotations };
|
||||
15
tests/utils/getSUV.ts
Normal file
15
tests/utils/getSUV.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
const getSUV = async page => {
|
||||
const SUV = await page.evaluate(
|
||||
({ services }: AppTypes.Test) => {
|
||||
const { measurementService } = services;
|
||||
const measurements = measurementService.getMeasurements();
|
||||
const displayText = measurements[0].displayText;
|
||||
return displayText[2];
|
||||
},
|
||||
await page.evaluateHandle('window')
|
||||
);
|
||||
|
||||
return SUV;
|
||||
};
|
||||
|
||||
export { getSUV };
|
||||
27
tests/utils/getTMTVModalityUnit.ts
Normal file
27
tests/utils/getTMTVModalityUnit.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
const getTMTVModalityUnit = async (page, attempts = 20) => {
|
||||
for (let i = 0; i < attempts; i++) {
|
||||
try {
|
||||
const modalityUnit = await page.evaluate(
|
||||
({ cornerstoneTools }: AppTypes.Test) => {
|
||||
const annotations = cornerstoneTools.annotation.state.getAllAnnotations();
|
||||
const stats = annotations[0].data.cachedStats;
|
||||
const targetIds = Object.keys(stats);
|
||||
const targetStats = stats[targetIds[1]];
|
||||
return targetStats.modalityUnit;
|
||||
},
|
||||
await page.evaluateHandle('window')
|
||||
);
|
||||
|
||||
if (modalityUnit) {
|
||||
return modalityUnit;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to get modalityUnit', error);
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
throw new Error('Failed to get modalityUnit after multiple attempts');
|
||||
};
|
||||
|
||||
export { getTMTVModalityUnit };
|
||||
24
tests/utils/index.ts
Normal file
24
tests/utils/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { visitStudy } from './visitStudy';
|
||||
import { checkForScreenshot } from './checkForScreenshot';
|
||||
import { screenShotPaths } from './screenShotPaths';
|
||||
import { simulateClicksOnElement } from './simulateClicksOnElement';
|
||||
import { reduce3DViewportSize } from './reduce3DviewportSize';
|
||||
import { getMousePosition, initilizeMousePositionTracker } from './mouseUtils';
|
||||
import { getSUV } from './getSUV';
|
||||
import { getTMTVModalityUnit } from './getTMTVModalityUnit';
|
||||
import { clearAllAnnotations } from './clearAllAnnotations';
|
||||
import { scrollVolumeViewport } from './scrollVolumeViewport';
|
||||
|
||||
export {
|
||||
visitStudy,
|
||||
checkForScreenshot,
|
||||
screenShotPaths,
|
||||
simulateClicksOnElement,
|
||||
reduce3DViewportSize,
|
||||
getMousePosition,
|
||||
initilizeMousePositionTracker,
|
||||
getSUV,
|
||||
getTMTVModalityUnit,
|
||||
clearAllAnnotations,
|
||||
scrollVolumeViewport,
|
||||
};
|
||||
25
tests/utils/mouseUtils.ts
Normal file
25
tests/utils/mouseUtils.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Page } from "@playwright/test";
|
||||
|
||||
interface WindowWithMousePosition extends Window {
|
||||
mouseX: number;
|
||||
mouseY: number;
|
||||
}
|
||||
|
||||
export const initilizeMousePositionTracker = async (page: Page) => {
|
||||
const window = await page.evaluateHandle("window") as any;
|
||||
await page.evaluate((window: WindowWithMousePosition) => {
|
||||
window.mouseX = 0;
|
||||
window.mouseY = 0;
|
||||
window.addEventListener("mousemove", (event) => {
|
||||
window.mouseX = event.clientX;
|
||||
window.mouseY = event.clientY;
|
||||
});
|
||||
}, window);
|
||||
}
|
||||
|
||||
export const getMousePosition = async (page: Page) => {
|
||||
const window = await page.evaluateHandle("window") as any;
|
||||
return await page.evaluate((window: WindowWithMousePosition) => {
|
||||
return { x: window.mouseX, y: window.mouseY };
|
||||
}, window);
|
||||
}
|
||||
13
tests/utils/reduce3DviewportSize.ts
Normal file
13
tests/utils/reduce3DviewportSize.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export const reduce3DViewportSize = async (page: any) => {
|
||||
await page.evaluate(
|
||||
({ cornerstone }: AppTypes.Test) => {
|
||||
const enabledElement = cornerstone
|
||||
.getEnabledElements()
|
||||
.filter(element => element.viewport.type === 'volume3d')[0];
|
||||
const { viewport } = enabledElement;
|
||||
viewport.setZoom(0.5);
|
||||
viewport.render();
|
||||
},
|
||||
await page.evaluateHandle('window')
|
||||
);
|
||||
};
|
||||
95
tests/utils/screenShotPaths.ts
Normal file
95
tests/utils/screenShotPaths.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Paths to the screenshots of the tests.
|
||||
*/
|
||||
const screenShotPaths = {
|
||||
angle: {
|
||||
angleDisplayedCorrectly: 'angleDisplayedCorrectly.png',
|
||||
},
|
||||
bidirectional: {
|
||||
bidirectionalDisplayedCorrectly: 'bidirectionalDisplayedCorrectly.png',
|
||||
},
|
||||
circle: {
|
||||
circleDisplayedCorrectly: 'circleDisplayedCorrectly.png',
|
||||
},
|
||||
cobbangle: {
|
||||
cobbangleDisplayedCorrectly: 'cobbangleDisplayedCorrectly.png',
|
||||
},
|
||||
ellipse: {
|
||||
ellipseDisplayedCorrectly: 'ellipseDisplayedCorrectly.png',
|
||||
},
|
||||
length: {
|
||||
lengthDisplayedCorrectly: 'lengthDisplayedCorrectly.png',
|
||||
},
|
||||
livewire: {
|
||||
livewireDisplayedCorrectly: 'livewireDisplayedCorrectly.png',
|
||||
},
|
||||
mpr: {
|
||||
mprDisplayedCorrectly: 'mprDisplayedCorrectly.png',
|
||||
},
|
||||
threeDFourUp: {
|
||||
threeDFourUpDisplayedCorrectly: 'threeDFourUpDisplayedCorrectly.png',
|
||||
},
|
||||
threeDMain: {
|
||||
threeDMainDisplayedCorrectly: 'threeDMainDisplayedCorrectly.png',
|
||||
},
|
||||
threeDPrimary: {
|
||||
threeDPrimaryDisplayedCorrectly: 'threeDPrimaryDisplayedCorrectly.png',
|
||||
},
|
||||
threeDOnly: {
|
||||
threeDOnlyDisplayedCorrectly: 'threeDOnlyDisplayedCorrectly.png',
|
||||
},
|
||||
axialPrimary: {
|
||||
axialPrimaryDisplayedCorrectly: 'axialPrimaryDisplayedCorrectly.png',
|
||||
},
|
||||
probe: {
|
||||
probeDisplayedCorrectly: 'probeDisplayedCorrectly.png',
|
||||
},
|
||||
rectangle: {
|
||||
rectangleDisplayedCorrectly: 'rectangleDisplayedCorrectly.png',
|
||||
},
|
||||
spline: {
|
||||
splineDisplayedCorrectly: 'splineDisplayedCorrectly.png',
|
||||
},
|
||||
dicomTagBrowser: {
|
||||
dicomTagBrowserDisplayedCorrectly: 'dicomTagBrowserDisplayedCorrectly.png',
|
||||
},
|
||||
rotateRight: {
|
||||
rotateRightDisplayedCorrectly: 'rotateRightDisplayedCorrectly.png',
|
||||
},
|
||||
invert: {
|
||||
invertDisplayedCorrectly: 'invertDisplayedCorrectly.png',
|
||||
},
|
||||
flipHorizontal: {
|
||||
flipHorizontalDisplayedCorrectly: 'flipHorizontalDisplayedCorrectly.png',
|
||||
},
|
||||
reset: {
|
||||
resetDisplayedCorrectly: 'resetDisplayedCorrectly.png',
|
||||
},
|
||||
srHydration: {
|
||||
srPostHydration: 'srPostHydration.png',
|
||||
srPreHydration: 'srPreHydration.png',
|
||||
srJumpToMeasurement: 'srJumpToMeasurement.png',
|
||||
},
|
||||
segHydration: {
|
||||
segPostHydration: 'segPostHydration.png',
|
||||
segPreHydration: 'segPreHydration.png',
|
||||
segJumpToSegment: 'segJumpToSegment.png',
|
||||
},
|
||||
rtHydration: {
|
||||
rtPostHydration: 'rtPostHydration.png',
|
||||
rtPreHydration: 'rtPreHydration.png',
|
||||
rtJumpToStructure: 'rtJumpToStructure.png',
|
||||
},
|
||||
crosshairs: {
|
||||
crosshairsRendered: 'crosshairsRendered.png',
|
||||
crosshairsRotated: 'crosshairsRotated.png',
|
||||
crosshairsSlabThickness: 'crosshairsSlabThickness.png',
|
||||
crosshairsResetToolbar: 'crosshairsResetToolbar.png',
|
||||
crosshairsNewDisplayset: 'crosshairsNewDisplayset.png',
|
||||
},
|
||||
tmtvRendering: {
|
||||
tmtvDisplayedCorrectly: 'tmtvDisplayedCorrectly.png',
|
||||
},
|
||||
};
|
||||
|
||||
export { screenShotPaths };
|
||||
17
tests/utils/scrollVolumeViewport.ts
Normal file
17
tests/utils/scrollVolumeViewport.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
type scrollVolumeViewportType = {
|
||||
viewportId: string;
|
||||
delta: number;
|
||||
};
|
||||
|
||||
const scrollVolumeViewport = async (page, viewportId, delta) => {
|
||||
await page.evaluate(
|
||||
({ services, viewportId, delta }: withTestTypes<scrollVolumeViewportType>) => {
|
||||
const { cornerstoneViewportService } = services;
|
||||
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId) as any;
|
||||
viewport.scroll(delta);
|
||||
},
|
||||
{ viewportId, delta, services: await page.evaluateHandle('window.services') }
|
||||
);
|
||||
};
|
||||
|
||||
export { scrollVolumeViewport };
|
||||
19
tests/utils/simulateClicksOnElement.ts
Normal file
19
tests/utils/simulateClicksOnElement.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Locator } from 'playwright';
|
||||
|
||||
/**
|
||||
*
|
||||
* @parm locator - The locator to click on
|
||||
* @param points - The points to click on
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export async function simulateClicksOnElement({
|
||||
locator,
|
||||
points,
|
||||
}: {
|
||||
locator: Locator;
|
||||
points: { x: number; y: number }[];
|
||||
}) {
|
||||
for (const { x, y } of points) {
|
||||
await locator.click({ delay: 100, position: { x, y } });
|
||||
}
|
||||
}
|
||||
24
tests/utils/visitStudy.ts
Normal file
24
tests/utils/visitStudy.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Page } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Visit the study
|
||||
* @param page - The page to interact with
|
||||
* @param title - The study instance UID of the study to visit
|
||||
* @param mode - The mode to visit the study in
|
||||
* @param delay - The delay to wait after visiting the study
|
||||
* @param datasources - the data source to load the study from
|
||||
*/
|
||||
export async function visitStudy(
|
||||
page: Page,
|
||||
studyInstanceUID: string,
|
||||
mode: string,
|
||||
delay: number = 0,
|
||||
datasources = 'ohif'
|
||||
) {
|
||||
await page.goto(`/?resultsPerPage=100&datasources=${datasources}`);
|
||||
await page.getByTestId(studyInstanceUID).click();
|
||||
await page.getByRole('button', { name: mode }).click();
|
||||
await page.waitForLoadState('domcontentloaded');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(delay);
|
||||
}
|
||||
Reference in New Issue
Block a user