init
26
tests/3DFourUp.spec.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test.describe('3D four up Test', async () => {
|
||||
test('should render 3D four up correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^3D four up$/ })
|
||||
.first()
|
||||
.click();
|
||||
await reduce3DViewportSize(page);
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.threeDFourUp.threeDFourUpDisplayedCorrectly,
|
||||
200
|
||||
);
|
||||
});
|
||||
});
|
||||
26
tests/3DMain.spec.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test.describe('3D main Test', async () => {
|
||||
test('should render 3D main correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^3D main$/ })
|
||||
.first()
|
||||
.click();
|
||||
await reduce3DViewportSize(page);
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.threeDMain.threeDMainDisplayedCorrectly,
|
||||
200
|
||||
);
|
||||
});
|
||||
});
|
||||
26
tests/3DOnly.spec.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test.describe('3D only Test', async () => {
|
||||
test('should render 3D only correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^3D only$/ })
|
||||
.first()
|
||||
.click();
|
||||
await reduce3DViewportSize(page);
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.threeDOnly.threeDOnlyDisplayedCorrectly,
|
||||
200
|
||||
);
|
||||
});
|
||||
});
|
||||
27
tests/3DPrimary.spec.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, reduce3DViewportSize } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test.describe('3D primary Test', async () => {
|
||||
test('should render 3D primary correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^3D primary$/ })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await reduce3DViewportSize(page);
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.threeDPrimary.threeDPrimaryDisplayedCorrectly,
|
||||
200
|
||||
);
|
||||
});
|
||||
});
|
||||
33
tests/Angle.spec.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the angle tool', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('Angle').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 550,
|
||||
y: 200,
|
||||
},
|
||||
{
|
||||
x: 450,
|
||||
y: 250,
|
||||
},
|
||||
{
|
||||
x: 550,
|
||||
y: 300,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.angle.angleDisplayedCorrectly);
|
||||
});
|
||||
25
tests/AxialPrimary.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test.describe('Axial Primary Test', async () => {
|
||||
test('should render Axial Primary correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^Axial Primary$/ })
|
||||
.first()
|
||||
.click();
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.axialPrimary.axialPrimaryDisplayedCorrectly,
|
||||
200
|
||||
);
|
||||
});
|
||||
});
|
||||
34
tests/Bidirectional.spec.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the bidirectional tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('Bidirectional').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 405,
|
||||
y: 277,
|
||||
},
|
||||
{
|
||||
x: 515,
|
||||
y: 339,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.bidirectional.bidirectionalDisplayedCorrectly
|
||||
);
|
||||
});
|
||||
29
tests/Circle.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the circle tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('CircleROI').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 480,
|
||||
y: 205,
|
||||
},
|
||||
{
|
||||
x: 488,
|
||||
y: 247,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.circle.circleDisplayedCorrectly);
|
||||
});
|
||||
37
tests/CobbAngle.spec.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the cobb angle tool', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('CobbAngle').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 515,
|
||||
y: 212,
|
||||
},
|
||||
{
|
||||
x: 616,
|
||||
y: 207,
|
||||
},
|
||||
{
|
||||
x: 527,
|
||||
y: 293,
|
||||
},
|
||||
{
|
||||
x: 625,
|
||||
y: 291,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.cobbangle.cobbangleDisplayedCorrectly);
|
||||
});
|
||||
104
tests/Crosshairs.spec.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Page, test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, initilizeMousePositionTracker, getMousePosition } from './utils/index.js';
|
||||
|
||||
|
||||
const rotateCrosshairs = async (page: Page, id: string, lineNumber: number) => {
|
||||
const locator = await page.locator(id).locator('line').nth(lineNumber);
|
||||
await locator.click({ force: true });
|
||||
await locator.hover({ force: true });
|
||||
const circleLocator = await page.locator(id).locator('circle').nth(1);
|
||||
await circleLocator.hover({ force: true });
|
||||
await page.mouse.down();
|
||||
const position = await getMousePosition(page);
|
||||
await page.mouse.move(position.x, position.y + 100);
|
||||
await page.mouse.up();
|
||||
}
|
||||
|
||||
const increaseSlabThickness = async (page: Page, id: string, lineNumber: number, axis: string) => {
|
||||
const locator = await page.locator(id).locator('line').nth(lineNumber)
|
||||
await locator.click({ force: true });
|
||||
await locator.hover({ force: true });
|
||||
const circleLocator = await page.locator(id).locator('rect').first();
|
||||
await circleLocator.hover({ force: true });
|
||||
await page.mouse.down();
|
||||
const position = await getMousePosition(page);
|
||||
switch (axis) {
|
||||
case 'x':
|
||||
await page.mouse.move(position.x + 100, position.y);
|
||||
break;
|
||||
case 'y':
|
||||
await page.mouse.move(position.x, position.y + 100);
|
||||
break;
|
||||
}
|
||||
await page.mouse.up();
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
await initilizeMousePositionTracker(page);
|
||||
});
|
||||
|
||||
test.describe('Crosshairs Test', async () => {
|
||||
test('should render the crosshairs correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
|
||||
await page.getByTestId('Crosshairs').click();
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsRendered);
|
||||
});
|
||||
|
||||
test('should allow the user to rotate the crosshairs', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
|
||||
await page.getByTestId('Crosshairs').click();
|
||||
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-axial', 3);
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-sagittal', 0);
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-coronal', 0);
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsRotated);
|
||||
});
|
||||
|
||||
test('should allow the user to adjust the slab thickness', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
|
||||
await page.getByTestId('Crosshairs').click();
|
||||
|
||||
await increaseSlabThickness(page, '#svg-layer-mpr-axial', 0, 'x');
|
||||
await increaseSlabThickness(page, '#svg-layer-mpr-sagittal', 2, 'x');
|
||||
await increaseSlabThickness(page, '#svg-layer-mpr-coronal', 0, 'y');
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsSlabThickness);
|
||||
});
|
||||
|
||||
test('should reset the crosshairs to the initial position when reset is clicked', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
|
||||
await page.getByTestId('Crosshairs').click();
|
||||
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-axial', 3);
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-sagittal', 0);
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-coronal', 0);
|
||||
|
||||
await page.getByTestId('MoreTools-split-button-primary').click();
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsResetToolbar);
|
||||
});
|
||||
|
||||
test('should reset the crosshairs when a new displayset is loaded', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
|
||||
await page.getByTestId('Crosshairs').click();
|
||||
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-axial', 0);
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-sagittal', 0);
|
||||
await rotateCrosshairs(page, '#svg-layer-mpr-coronal', 3);
|
||||
|
||||
await page.getByTestId('study-browser-thumbnail').nth(1).dblclick();
|
||||
|
||||
await checkForScreenshot(page, page, screenShotPaths.crosshairs.crosshairsNewDisplayset);
|
||||
});
|
||||
|
||||
});
|
||||
18
tests/DicomTagBrowser.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the dicom tag browser', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('TagBrowser').click();
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.dicomTagBrowser.dicomTagBrowserDisplayedCorrectly
|
||||
);
|
||||
});
|
||||
29
tests/Ellipse.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the ellipse tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('EllipticalROI').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 446,
|
||||
y: 245,
|
||||
},
|
||||
{
|
||||
x: 508,
|
||||
y: 281,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.ellipse.ellipseDisplayedCorrectly);
|
||||
});
|
||||
18
tests/FlipHorizontal.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '2.16.840.1.114362.1.11972228.22789312658.616067305.306.2';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should flip the image horizontally', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('flipHorizontal').click();
|
||||
await checkForScreenshot(
|
||||
page,
|
||||
page,
|
||||
screenShotPaths.flipHorizontal.flipHorizontalDisplayedCorrectly
|
||||
);
|
||||
});
|
||||
14
tests/Invert.spec.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should invert the image', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('invert').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.invert.invertDisplayedCorrectly);
|
||||
});
|
||||
28
tests/Length.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the length tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-primary').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 364,
|
||||
y: 234,
|
||||
},
|
||||
{
|
||||
x: 544,
|
||||
y: 232,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.length.lengthDisplayedCorrectly);
|
||||
});
|
||||
45
tests/Livewire.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the livewire tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('LivewireContour').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 380,
|
||||
y: 459,
|
||||
},
|
||||
{
|
||||
x: 420,
|
||||
y: 396,
|
||||
},
|
||||
{
|
||||
x: 523,
|
||||
y: 392,
|
||||
},
|
||||
{
|
||||
x: 581,
|
||||
y: 447,
|
||||
},
|
||||
{
|
||||
x: 482,
|
||||
y: 493,
|
||||
},
|
||||
{
|
||||
x: 383,
|
||||
y: 461,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.livewire.livewireDisplayedCorrectly);
|
||||
});
|
||||
16
tests/MPR.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils/index.js';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test.describe('MPR Test', async () => {
|
||||
test('should render MPR correctly.', async ({ page }) => {
|
||||
await page.getByTestId('Layout').click();
|
||||
await page.locator('div').filter({ hasText: /^MPR$/ }).first().click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.mpr.mprDisplayedCorrectly);
|
||||
});
|
||||
});
|
||||
25
tests/Probe.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the probe tool', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('Probe').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 550,
|
||||
y: 200,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.probe.probeDisplayedCorrectly);
|
||||
});
|
||||
18
tests/RTHydration.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should hydrate RT reports correctly', async ({ page }) => {
|
||||
await page.getByTestId('side-panel-header-right').click();
|
||||
await page.getByTestId('study-browser-thumbnail-no-image').dblclick();
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPreHydration);
|
||||
await page.getByTestId('yes-hydrate-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPostHydration);
|
||||
await page.getByText('Small Sphere').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtJumpToStructure);
|
||||
});
|
||||
29
tests/Rectangle.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the rectangle tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('RectangleROI').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 476,
|
||||
y: 159,
|
||||
},
|
||||
{
|
||||
x: 591,
|
||||
y: 217,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.rectangle.rectangleDisplayedCorrectly);
|
||||
});
|
||||
18
tests/Reset.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '2.16.840.1.114362.1.11972228.22789312658.616067305.306.2';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should reset the image to its original state', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('rotate-right').click();
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('invert').click();
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('Reset').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.reset.resetDisplayedCorrectly);
|
||||
});
|
||||
14
tests/RotateRight.spec.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should rotate the image to the right', async ({ page }) => {
|
||||
await page.getByTestId('MoreTools-split-button-secondary').click();
|
||||
await page.getByTestId('rotate-right').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.rotateRight.rotateRightDisplayedCorrectly);
|
||||
});
|
||||
18
tests/SEGHydration.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.256467663913010332776401703474716742458';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should hydrate SEG reports correctly', async ({ page }) => {
|
||||
await page.getByTestId('side-panel-header-right').click();
|
||||
await page.getByTestId('study-browser-thumbnail-no-image').dblclick();
|
||||
await checkForScreenshot(page, page, screenShotPaths.segHydration.segPreHydration);
|
||||
await page.getByTestId('yes-hydrate-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.segHydration.segPostHydration);
|
||||
await page.getByText('Esophagus').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.segHydration.segJumpToSegment);
|
||||
});
|
||||
19
tests/SRHydration.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7695.4007.324475281161490036195179843543';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should hydrate SR reports correctly', async ({ page }) => {
|
||||
await page.getByTestId('side-panel-header-right').click();
|
||||
await page.getByTestId('trackedMeasurements-btn').click();
|
||||
await page.getByTestId('study-browser-thumbnail-no-image').dblclick();
|
||||
await checkForScreenshot(page, page, screenShotPaths.srHydration.srPreHydration);
|
||||
await page.getByTestId('yes-hydrate-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.srHydration.srPostHydration);
|
||||
await page.getByTestId('data-row').first().click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.srHydration.srJumpToMeasurement);
|
||||
});
|
||||
45
tests/Spline.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths, simulateClicksOnElement } from './utils';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
|
||||
const mode = 'Basic Viewer';
|
||||
await visitStudy(page, studyInstanceUID, mode, 2000);
|
||||
});
|
||||
|
||||
test('should display the spline tool', async ({ page }) => {
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('SplineROI').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas');
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 380,
|
||||
y: 459,
|
||||
},
|
||||
{
|
||||
x: 420,
|
||||
y: 396,
|
||||
},
|
||||
{
|
||||
x: 523,
|
||||
y: 392,
|
||||
},
|
||||
{
|
||||
x: 581,
|
||||
y: 447,
|
||||
},
|
||||
{
|
||||
x: 482,
|
||||
y: 493,
|
||||
},
|
||||
{
|
||||
x: 383,
|
||||
y: 461,
|
||||
},
|
||||
],
|
||||
});
|
||||
await page.getByTestId('prompt-begin-tracking-yes-btn').click();
|
||||
await checkForScreenshot(page, page, screenShotPaths.spline.splineDisplayedCorrectly);
|
||||
});
|
||||
54
tests/TMTVAlignment.spec.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { visitStudy, scrollVolumeViewport } from './utils';
|
||||
|
||||
test.skip('PT should show slice closest to CT', async ({ page }) => {
|
||||
const studyInstanceUID = '1.2.840.113619.2.290.3.3767434740.226.1600859119.501';
|
||||
const mode = 'Total Metabolic Tumor Volume';
|
||||
await visitStudy(page, studyInstanceUID, mode);
|
||||
|
||||
const vp = page.getByTestId('viewport-pane');
|
||||
|
||||
// Sagittal
|
||||
await expect(vp.nth(1)).toContainText('257/512', { useInnerText: true }); // Should default i 257
|
||||
await expect.soft(vp.nth(4)).toContainText('97/192');
|
||||
await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 256
|
||||
await expect(vp.nth(1)).toContainText('256/512');
|
||||
await expect.soft(vp.nth(4)).toContainText('96/192');
|
||||
await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 255
|
||||
await expect(vp.nth(1)).toContainText('255/512');
|
||||
await expect.soft(vp.nth(4)).toContainText('95/192');
|
||||
await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 254
|
||||
await expect(vp.nth(1)).toContainText('254/512');
|
||||
await expect.soft(vp.nth(4)).toContainText('95/192');
|
||||
await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 253
|
||||
await expect(vp.nth(1)).toContainText('253/512');
|
||||
await expect.soft(vp.nth(4)).toContainText('94/192');
|
||||
await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 252
|
||||
await expect(vp.nth(1)).toContainText('252/512');
|
||||
await expect.soft(vp.nth(4)).toContainText('94/192');
|
||||
await scrollVolumeViewport(page, 'ctSAGITTAL', -1); // CT i 251
|
||||
await expect(vp.nth(1)).toContainText('251/512');
|
||||
await expect.soft(vp.nth(4)).toContainText('93/192');
|
||||
|
||||
// Coronal
|
||||
await expect(vp.nth(2)).toContainText('256/512'); // Should default i 256
|
||||
await expect.soft(vp.nth(5)).toContainText('96/192');
|
||||
await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 255
|
||||
await expect(vp.nth(2)).toContainText('255/512');
|
||||
await expect.soft(vp.nth(5)).toContainText('96/192');
|
||||
await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 254
|
||||
await expect(vp.nth(2)).toContainText('254/512');
|
||||
await expect.soft(vp.nth(5)).toContainText('95/192');
|
||||
await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 253
|
||||
await expect(vp.nth(2)).toContainText('253/512');
|
||||
await expect.soft(vp.nth(5)).toContainText('95/192');
|
||||
await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 252
|
||||
await expect(vp.nth(2)).toContainText('252/512');
|
||||
await expect.soft(vp.nth(5)).toContainText('94/192');
|
||||
await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 251
|
||||
await expect(vp.nth(2)).toContainText('251/512');
|
||||
await expect.soft(vp.nth(5)).toContainText('94/192');
|
||||
await scrollVolumeViewport(page, 'ctCORONAL', -1); // CT i 250
|
||||
await expect(vp.nth(2)).toContainText('250/512');
|
||||
await expect.soft(vp.nth(5)).toContainText('93/192');
|
||||
});
|
||||
49
tests/TMTVModalityUnit.spec.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import {
|
||||
visitStudy,
|
||||
simulateClicksOnElement,
|
||||
getTMTVModalityUnit,
|
||||
clearAllAnnotations,
|
||||
} from './utils/index';
|
||||
|
||||
test.skip('pets where SUV cannot be calculated should show same unit in TMTV as in Basic Viewer.', async ({
|
||||
page,
|
||||
}) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339';
|
||||
const mode = 'Total Metabolic Tumor Volume';
|
||||
await visitStudy(page, studyInstanceUID, mode, 10000);
|
||||
|
||||
// Change to image where SUV cannot be calculated
|
||||
await page.getByTestId('side-panel-header-left').click();
|
||||
await page
|
||||
.getByRole('button', { name: 'S: 2 311 PET NAC' })
|
||||
.dragTo(page.getByTestId('viewport-grid').locator('canvas').nth(3));
|
||||
|
||||
// Wait for the new series to load
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Add ROI annotation
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('EllipticalROI').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas').first();
|
||||
await clearAllAnnotations(page);
|
||||
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
{
|
||||
x: 150,
|
||||
y: 150,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const modalityUnit = await getTMTVModalityUnit(page);
|
||||
|
||||
// in basic viewer, when you convert to volume, the unit is raw not PROPCNT (tmtv starts as a volume)
|
||||
expect(modalityUnit).toEqual('raw');
|
||||
});
|
||||
76
tests/TMTVRecalculate.spec.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { visitStudy, simulateClicksOnElement, getSUV, clearAllAnnotations } from './utils/index';
|
||||
|
||||
test.skip('should update SUV values correctly.', async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339';
|
||||
const mode = 'Total Metabolic Tumor Volume';
|
||||
await visitStudy(page, studyInstanceUID, mode, 10000);
|
||||
|
||||
// Create ROI
|
||||
await page.getByTestId('petSUV-btn').click();
|
||||
await page.getByTestId('MeasurementTools-split-button-secondary').click();
|
||||
await page.getByTestId('EllipticalROI').click();
|
||||
const locator = page.getByTestId('viewport-pane').locator('canvas').first();
|
||||
await clearAllAnnotations(page);
|
||||
|
||||
await simulateClicksOnElement({
|
||||
locator,
|
||||
points: [
|
||||
{
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
{
|
||||
x: 150,
|
||||
y: 150,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Get current SUV text
|
||||
let oldSUV = await getSUV(page);
|
||||
|
||||
// Change PT Weight
|
||||
await page.getByTestId('input-weight-input').fill('31');
|
||||
await page.getByText('Reload Data').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
// Get new SUV text
|
||||
let newSUV = await getSUV(page);
|
||||
|
||||
// Compare then store new SUV
|
||||
expect.soft(newSUV).not.toEqual(oldSUV);
|
||||
oldSUV = newSUV;
|
||||
|
||||
// Change total dose
|
||||
await page
|
||||
.getByText('Patient SexWeight kgTotal')
|
||||
.locator('div')
|
||||
.filter({ hasText: /^Total Dose bq$/ })
|
||||
.getByTestId('input-undefined')
|
||||
.fill('1888020304');
|
||||
await page.getByText('Reload Data').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Get new SUV
|
||||
newSUV = await getSUV(page);
|
||||
|
||||
// Compare then store new
|
||||
expect.soft(newSUV).not.toEqual(oldSUV);
|
||||
oldSUV = newSUV;
|
||||
|
||||
// Change injection time
|
||||
await page
|
||||
.getByText('Patient SexWeight kgTotal')
|
||||
.locator('div')
|
||||
.filter({ hasText: /^Injection Time s$/ })
|
||||
.getByTestId('input-undefined')
|
||||
.fill('060000');
|
||||
await page.getByText('Reload Data').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Get new SUV
|
||||
newSUV = await getSUV(page);
|
||||
|
||||
// Compare SUV
|
||||
expect.soft(newSUV).not.toEqual(oldSUV);
|
||||
});
|
||||
9
tests/TMTVRendering.spec.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { visitStudy, checkForScreenshot, screenShotPaths } from './utils/index.js';
|
||||
|
||||
test.skip('should render TMTV correctly.', async ({ page }) => {
|
||||
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339';
|
||||
const mode = 'Total Metabolic Tumor Volume';
|
||||
await visitStudy(page, studyInstanceUID, mode, 10000);
|
||||
await checkForScreenshot(page, page, screenShotPaths.tmtvRendering.tmtvDisplayedCorrectly, 100);
|
||||
});
|
||||
|
After Width: | Height: | Size: 338 KiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 312 KiB |
|
After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 350 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 263 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 246 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 250 KiB |
|
After Width: | Height: | Size: 252 KiB |
|
After Width: | Height: | Size: 258 KiB |
BIN
tests/screenshots/chromium/MPR.spec.ts/mprDisplayedCorrectly.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 240 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 243 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 256 KiB |
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||