Skip to content

Commit

Permalink
Added cypress tests for slice/join (#7249)
Browse files Browse the repository at this point in the history
  • Loading branch information
klakhov authored Dec 19, 2023
1 parent 48ab12b commit d9e7b2c
Show file tree
Hide file tree
Showing 2 changed files with 295 additions and 0 deletions.
222 changes: 222 additions & 0 deletions tests/cypress/e2e/features/slice_join.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

/// <reference types="cypress" />

context('Slice and join tools', { scrollBehavior: false }, () => {
const taskName = 'Slice and join actions';
const serverFiles = ['images/image_1.jpg', 'images/image_2.jpg', 'images/image_3.jpg'];

const basicMask = [{
method: 'brush',
coordinates: [[300, 300], [700, 300], [700, 700], [300, 700]],
}];
const doubleMask = [{
method: 'brush',
coordinates: [[200, 200], [300, 200], [300, 300], [200, 300]],
},
{
method: 'brush',
coordinates: [[200, 350], [300, 350], [300, 450], [200, 450]],
},
];
const filledMask = [{
method: 'brush-size',
value: 150,
}, {
method: 'brush',
coordinates: [[300, 300], [400, 300], [400, 400], [300, 400]],
}];

const polygon = {
reDraw: false,
type: 'Shape',
labelName: 'polygon label',
pointsMap: [
{ x: 100, y: 100 },
{ x: 300, y: 140 },
{ x: 200, y: 440 },
{ x: 130, y: 300 },
],
complete: true,
numberOfPoints: null,
};

let taskID = null;
let jobID = null;

before(() => {
cy.visit('auth/login');
cy.login();
cy.headlessCreateTask({
labels: [
{ name: 'mask label', attributes: [], type: 'mask' },
{ name: 'polygon label', attributes: [], type: 'polygon' },
],
name: taskName,
project_id: null,
source_storage: { location: 'local' },
target_storage: { location: 'local' },
}, {
server_files: serverFiles,
image_quality: 70,
use_zip_chunks: true,
use_cache: true,
sorting_method: 'lexicographical',
}).then((response) => {
taskID = response.taskID;
[jobID] = response.jobID;
}).then(() => {
cy.visit(`/tasks/${taskID}/jobs/${jobID}`);
cy.get('.cvat-canvas-container').should('exist').and('be.visible');
});
});

after(() => {
cy.logout();
cy.getAuthKey().then((response) => {
const authKey = response.body.key;
cy.request({
method: 'DELETE',
url: `/api/tasks/${taskID}`,
headers: {
Authorization: `Token ${authKey}`,
},
});
});
});

beforeEach(() => {
cy.removeAnnotations();
cy.goCheckFrameNumber(0);
});

function checkSliceSuccess() {
cy.get('#cvat_canvas_shape_1').should('not.exist');
cy.get('#cvat_canvas_shape_2').should('exist').and('be.visible');
cy.get('#cvat_canvas_shape_3').should('exist').and('be.visible');
}

function checkJoinSuccess() {
cy.get('#cvat_canvas_shape_2').should('not.exist');
cy.get('#cvat_canvas_shape_3').should('not.exist');
cy.get('#cvat_canvas_shape_4').should('exist').and('be.visible');
}

describe('Testing slice/join tools', () => {
it('Draw basic mask. Slice into two shapes. Join back.', () => {
cy.startMaskDrawing();
cy.drawMask(basicMask);
cy.finishMaskDrawing();

cy.get('#cvat_canvas_shape_1').should('exist').and('be.visible');
cy.sliceShape('#cvat_canvas_shape_1', [[1, 1], [250, 500], [720, 500]]);
checkSliceSuccess();

cy.joinShapes(['#cvat_canvas_shape_2', '#cvat_canvas_shape_3'], [[1, 1], [1, 1]]);
checkJoinSuccess();
});

it('Draw one mask with two shapes. Slice into two shapes. Join back.', () => {
cy.startMaskDrawing();
cy.drawMask(doubleMask);
cy.finishMaskDrawing();

cy.get('#cvat_canvas_shape_1').should('exist').and('be.visible');
cy.sliceShape('#cvat_canvas_shape_1', [[1, 1], [150, 230], [300, 230]]);
checkSliceSuccess();

cy.joinShapes(['#cvat_canvas_shape_2', '#cvat_canvas_shape_3'], [[1, 1], [1, 1]]);
checkJoinSuccess();
});

it('Draw filled mask. Slice with polyline. Join back.', () => {
cy.startMaskDrawing();
cy.drawMask(filledMask);
cy.finishMaskDrawing();

cy.get('#cvat_canvas_shape_1').should('exist').and('be.visible');
cy.sliceShape(
'#cvat_canvas_shape_1',
[
[50, 55], [180, 230], [210, 260],
[240, 200], [270, 230], [300, 230],
[330, 260], [360, 200], [390, 230],
[500, 230],
],
{ shortcut: '{alt}j' },
);
checkSliceSuccess();

cy.joinShapes(
['#cvat_canvas_shape_2', '#cvat_canvas_shape_3'],
[[50, 5], [70, 70]],
{ shortcut: 'j' },
);
checkJoinSuccess();
});

it('Draw polygon. Slice into two shapes.', () => {
cy.createPolygon(polygon);
cy.sliceShape(
'#cvat_canvas_shape_1',
[
[1, 1], [110, 160], [270, 240],
],
);
checkSliceSuccess();
});

it('Draw polygon. Slice with polyline.', () => {
cy.createPolygon(polygon);
cy.sliceShape(
'#cvat_canvas_shape_1',
[
[1, 1], [110, 160], [140, 150],
[170, 130], [190, 190], [230, 250],
[400, 130],
],
);
checkSliceSuccess();
});

it('Draw polygon. Check removing of slicing polyline points.', () => {
cy.createPolygon(polygon);
cy.sliceShape(
'#cvat_canvas_shape_1',
[
[1, 1], [110, 160], [140, 150],
[170, 130], [190, 190], [230, 250],
],
);
for (let i = 0; i < 5; i++) {
cy.get('body').rightclick();
}

cy.get('.cvat-canvas-hints-container').within(() => {
cy.contains('Set initial point on the shape contour').should('exist');
});
cy.get('body').type('{alt}j');
});

it('Draw mask. Slice with slip mode.', () => {
cy.startMaskDrawing();
cy.drawMask(filledMask);
cy.finishMaskDrawing();

cy.get('#cvat_canvas_shape_1').should('exist').and('be.visible');
cy.sliceShape(
'#cvat_canvas_shape_1',
[
[50, 55], [180, 230], [200, 240],
[210, 250], [220, 260], [230, 270],
[240, 280], [250, 290], [260, 300],
[500, 230],
],
{ slipMode: true },
);
checkSliceSuccess();
});
});
});
73 changes: 73 additions & 0 deletions tests/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,79 @@ Cypress.Commands.add('finishMaskDrawing', () => {
cy.get('.cvat-brush-tools-finish').click();
});

Cypress.Commands.add('sliceShape', (
object,
coordinates,
options = {
shortcut: null,
slipMode: false,
},
) => {
const { shortcut, slipMode } = options;
if (shortcut) {
cy.get('body').type(shortcut);
} else {
cy.get('.cvat-slice-control').click();
cy.get('.cvat-slice-control').trigger('mouseleave');
}

cy.get('.cvat-canvas-hints-container').within(() => {
cy.contains('Click a mask or polygon shape you would like to slice').should('exist');
});

const [initialX, initialY] = coordinates.shift();
cy.get(object).click(initialX, initialY);
cy.get('.cvat-canvas-hints-container').within(() => {
cy.contains('Set initial point on the shape contour').should('exist');
});

cy.get('.cvat-canvas-container').then(($canvas) => {
if (slipMode) {
const [initX, initY] = coordinates.shift();
cy.wrap($canvas).click(initX, initY);
const [endX, endY] = coordinates.pop();

for (const [x, y] of coordinates) {
cy.wrap($canvas).trigger('mousemove', x, y, { button: 0, shiftKey: true, bubbles: true });
}
cy.wrap($canvas).click(endX, endY);
} else {
for (const [x, y] of coordinates) {
cy.wrap($canvas).click(x, y);
}
}
});
});

Cypress.Commands.add('joinShapes', (
objects,
coordinates,
options = {
shortcut: null,
},
) => {
const { shortcut } = options;

const interactWithTool = () => {
if (shortcut) {
cy.get('body').type(shortcut);
} else {
cy.get('.cvat-join-control').click();
cy.get('.cvat-join-control').trigger('mouseleave');
}
};
interactWithTool();

cy.get('.cvat-canvas-hints-container').within(() => {
cy.contains('Click masks you would like to join').should('exist');
});

for (const [index, object] of objects.entries()) {
cy.get(object).click(coordinates[index][0], coordinates[index][1]);
}
interactWithTool();
});

Cypress.Commands.overwrite('visit', (orig, url, options) => {
orig(url, options);
cy.closeModalUnsupportedPlatform();
Expand Down

0 comments on commit d9e7b2c

Please sign in to comment.