Skip to content

Commit

Permalink
test: stackSegmentation (CircularEraser, RectangleScissor and PaintFi…
Browse files Browse the repository at this point in the history
…ll screenshots) (#1385)

* test: stackSegmentation (CircularEraser, RectangleScissor and PaintFill)

* test: stackSegmentation (CircularEraser, RectangleScissor and PaintFill screenshots)
  • Loading branch information
lscoder committed Jul 10, 2024
1 parent 82b018e commit 7bab55d
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 28 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
200 changes: 173 additions & 27 deletions tests/stackSegmentation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import {
screenShotPaths,
simulateDrawPath,
} from './utils/index';
import pause from './utils/pause';
import locatorToPageCoord from './utils/locatorToPageCoord';
import simulateDrawRect from './utils/simulateDrawRect';

const SEG1_OUTERCIRCLE_POINT = [210, 235];

const segmentPoints1 = [
[100, 197],
Expand Down Expand Up @@ -42,7 +47,7 @@ test.describe('Stack Segmentation', async () => {
);
});

test.describe('when using circular brush tool', async () => {
test.describe('when circular brush tool is selected', async () => {
test.beforeEach(async ({ page }) => {
await page.getByRole('combobox').first().selectOption('CircularBrush');
});
Expand All @@ -63,39 +68,180 @@ test.describe('Stack Segmentation', async () => {
});
});

test.describe('when using paint fill tool', async () => {
test.describe('when circular eraser tool is selected', async () => {
test.beforeEach(async ({ page }) => {
const canvas = await page.locator('canvas');
await page.getByRole('combobox').first().selectOption('CircularEraser');
});

await page.getByRole('combobox').first().selectOption('CircularBrush');
test.describe('and it is on a segmentation 1 that has segments', async () => {
test('should erase the pixels from both circular segments', async ({
page,
}) => {
const canvas = await page.locator('canvas');

// Draw segment 1
await simulateDrawPath(page, canvas, segmentPoints1, {
interpolateSteps: true,
closePath: true,
await eraseVerticalLine(page, canvas);
await checkForScreenshot(
page,
canvas,
screenShotPaths.stackSegmentation.circularEraserSegmentation1
);
});
});

test.describe('and it is on a segmentation 2 that has no segments', async () => {
test('should not erase the pixels from segmentation 1', async ({
page,
}) => {
await page
.getByRole('button', { name: 'Create New Segmentation on' })
.click();

const canvas = await page.locator('canvas');

await eraseVerticalLine(page, canvas);
await checkForScreenshot(
page,
canvas,
screenShotPaths.stackSegmentation.circularEraserSegmentation2
);
});
});
});

test.describe('when rectangle scissor tool is selected', async () => {
test.beforeEach(async ({ page }) => {
await page.getByRole('combobox').first().selectOption('RectangleScissor');
});

test.describe('and it is on a segmentation 1 that has segments', async () => {
test('should fill the pixels within the rectangular region selected on segmentation 1', async ({
page,
}) => {
const canvas = await page.locator('canvas');

await drawRectangleScissor(page, canvas);
await checkForScreenshot(
page,
canvas,
screenShotPaths.stackSegmentation.rectangleScissorSegmentation1
);
});
});

test.describe('and it is on a segmentation 2 that has no segments', async () => {
test('should fill the pixels within the rectangular region selected on segmentation 2', async ({
page,
}) => {
const canvas = await page.locator('canvas');

await page
.getByRole('button', { name: 'Create New Segmentation on' })
.click();

await drawRectangleScissor(page, canvas);
await checkForScreenshot(
page,
canvas,
screenShotPaths.stackSegmentation.rectangleScissorSegmentation1
);
});
});
});

test.describe('when paint fill tool is selected', async () => {
test.beforeEach(async ({ page }) => {
await page.getByRole('combobox').first().selectOption('PaintFill');
});

// TODO: investigate why CLICK is not working
//
// test('should be able to fill a segment', async ({ page }) => {
// const canvas = await page.locator('canvas');
//
// // Click close to the center of segment 1
// await canvas.click({
// position: {
// x: 115,
// y: 215,
// },
// });
//
// await checkForScreenshot(
// page,
// canvas,
// screenShotPaths.stackSegmentation.paintFill
// );
// });
test.describe('and clicking on the outer circle', async () => {
test('should fill the outer circle', async ({ page }) => {
const canvas = await page.locator('canvas');

await runPaintFill(page, canvas, SEG1_OUTERCIRCLE_POINT);
await checkForScreenshot(
page,
canvas,
screenShotPaths.stackSegmentation.paintFillSeg1OuterCircle
);
});
});

test.describe('and creating a new segmentation', async () => {
test.describe('and clicking on the outer circle', async () => {
test('should paint the entire image over the previous segmetantion', async ({
page,
}) => {
const canvas = await page.locator('canvas');

await page
.getByRole('button', { name: 'Create New Segmentation on' })
.click();

await runPaintFill(page, canvas, SEG1_OUTERCIRCLE_POINT);
await checkForScreenshot(
page,
canvas,
screenShotPaths.stackSegmentation.paintFillSegmentation2
);
});
});
});
});
});

async function runPaintFill(page, canvas, clickPoint: number[]) {
const pageCoord = await locatorToPageCoord(page, canvas, clickPoint);
const toolsDropdown = await page.getByRole('combobox').first();
const selectedToolOption = await toolsDropdown.inputValue();

await toolsDropdown.selectOption('PaintFill');

await page.mouse.move(pageCoord[0], pageCoord[1]);
await page.mouse.down();
await pause(500); // Should wait for >300ms
await page.mouse.up();

// Restore it to its previous selected value
await toolsDropdown.selectOption(selectedToolOption);
}

async function eraseVerticalLine(page, canvas) {
const toolsDropdown = await page.getByRole('combobox').first();
const selectedToolOption = await toolsDropdown.inputValue();

await toolsDropdown.selectOption('CircularEraser');

const width = Number(await canvas.getAttribute('width'));
const height = Number(await canvas.getAttribute('height'));

// Draws a centered vertical line that crosses the two circular segments
const startPoint = [Math.round(width / 2), 3 * Math.round(height / 8)];
const endPoint = [Math.round(width / 2), 5 * Math.round(height / 8)];

await simulateDrawPath(page, canvas, [startPoint, endPoint], {
interpolateSteps: true,
});

// Restore it to its previous selected value
await toolsDropdown.selectOption(selectedToolOption);
}

async function drawRectangleScissor(page, canvas) {
const toolsDropdown = await page.getByRole('combobox').first();
const selectedToolOption = await toolsDropdown.inputValue();

await toolsDropdown.selectOption('RectangleScissor');

const width = Number(await canvas.getAttribute('width'));
const height = Number(await canvas.getAttribute('height'));
const rectTopLeftPoint = [Math.round(width / 3), Math.round(height / 3)];
const rectBottomRightPoint = [
2 * Math.round(width / 3),
Math.round(height / 2),
];

await simulateDrawRect(page, canvas, rectTopLeftPoint, rectBottomRightPoint);

// Restore it to its previous selected value
await toolsDropdown.selectOption(selectedToolOption);
}
9 changes: 9 additions & 0 deletions tests/utils/locatorToPageCoord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default async function locatorToPageCoord(
page,
locator,
point: number[]
) {
const bbox = await locator.boundingBox();

return [bbox.x + point[0], bbox.y + point[1]];
}
3 changes: 3 additions & 0 deletions tests/utils/pause.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function pause(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
7 changes: 6 additions & 1 deletion tests/utils/screenShotPaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ const screenShotPaths = {
stackSegmentation: {
defaultSegmentation: 'defaultSegmentation.png',
circularBrushSegment1: 'circularBrushSegment1.png',
paintFill: 'paintFill.png',
circularEraserSegmentation1: 'circularEraserSegmentation1.png',
circularEraserSegmentation2: 'circularEraserSegmentation2.png',
rectangleScissorSegmentation1: 'rectangleScissorSegmentation1.png',
rectangleScissorSegmentation2: 'rectangleScissorSegmentation2.png',
paintFillSeg1OuterCircle: 'paintFillSeg1OuterCircle.png',
paintFillSegmentation2: 'paintFillSegmentation2.png',
},
};

Expand Down
23 changes: 23 additions & 0 deletions tests/utils/simulateDrawRect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import locatorToPageCoord from './locatorToPageCoord';
import pause from './pause';

export default async function simulateDrawRect(
page,
locator,
rectTopLeft,
rectBottomRight
) {
const pageTopLeftPoint = await locatorToPageCoord(page, locator, rectTopLeft);
const pageBottomRightPoint = await locatorToPageCoord(
page,
locator,
rectBottomRight
);

await page.mouse.move(pageTopLeftPoint[0], pageTopLeftPoint[1]);
await page.mouse.down();
await pause(500);
await page.mouse.move(pageBottomRightPoint[0], pageBottomRightPoint[1]);
await pause(500);
await page.mouse.up();
}

0 comments on commit 7bab55d

Please sign in to comment.