From e6e6be94f926209fe8150cf756e0738227330454 Mon Sep 17 00:00:00 2001 From: Dmitry Kruchinin <33020454+dvkruchinin@users.noreply.github.com> Date: Thu, 24 Dec 2020 09:57:36 +0300 Subject: [PATCH] Cypress test. Label constructor. Color label. (#2568) * Cypress test. Label constructor. Color label. One test adaptation. * Fix test case22. Disable checking tag name. * Some fix. * Add css classes. Update cypress command. * Version updated * Some rework case22 Co-authored-by: Kruchinin --- .../objects-side-bar/object-item-basics.tsx | 1 + .../top-bar/annotation-menu.tsx | 1 + .../case_14_appearance_features.js | 83 ++++++----- .../case_22_tag_annotation_mode.js | 28 ++-- .../case_31_label_constructor_color_label.js | 129 ++++++++++++++++++ tests/cypress/support/commands.js | 25 +++- 6 files changed, 215 insertions(+), 52 deletions(-) create mode 100644 tests/cypress/integration/actions_tasks_objects/case_31_label_constructor_color_label.js diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx index 3517010f..8aa249ee 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx @@ -110,6 +110,7 @@ function ItemTopComponent(props: Props): JSX.Element { labels={labels} value={labelID} onChange={changeLabel} + className='cvat-objects-sidebar-state-item-label-selector' /> diff --git a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx index 5f0970ac..3ac000f4 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx @@ -117,6 +117,7 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { content: 'You are going to remove all the annotations from the client. ' + 'It will stay on the server till you save the job. Continue?', + className: 'cvat-modal-confirm-remove-annotation', onOk: () => { onClickMenu(copyParams); }, diff --git a/tests/cypress/integration/actions_tasks_objects/case_14_appearance_features.js b/tests/cypress/integration/actions_tasks_objects/case_14_appearance_features.js index 92909f13..7d912bdb 100644 --- a/tests/cypress/integration/actions_tasks_objects/case_14_appearance_features.js +++ b/tests/cypress/integration/actions_tasks_objects/case_14_appearance_features.js @@ -69,7 +69,7 @@ context('Appearance features', () => { describe(`Testing case "${caseId}"`, () => { it('Create a rectangle, a polygon, a polyline, a cuboid and points.', () => { cy.createRectangle(createRectangleShape2Points); - cy.get('#cvat_canvas_shape_1').then($rectangleShape => { + cy.get('#cvat_canvas_shape_1').then(($rectangleShape) => { fill = $rectangleShape.css('fill'); fillOpacity = $rectangleShape.css('fill-opacity'); }); @@ -79,41 +79,55 @@ context('Appearance features', () => { cy.createPoint(createPointsShape); }); it('Set opacity level for shapes to 100. All shapes are filled.', () => { - cy.get('.cvat-appearance-opacity-slider').click('right').within(() => { - cy.get('[role="slider"]').should('have.attr', 'aria-valuemax').then(($ariaValuemax) => { - ariaValuenow = $ariaValuemax; - cy.get('[role="slider"]').should('have.attr', 'aria-valuenow', ariaValuenow); - }); - }); - cy.get('.cvat_canvas_shape').each(object => { - cy.get(object).should('have.prop', 'tagName').then($tagName => { - if ($tagName !== 'polyline') { - expect(Number(object.css('fill-opacity'))).to.be.gt(Number(fillOpacity)); // expected 1 to be above 0.03 - } else { - expect(Number(object.css('fill-opacity'))).to.be.lt(Number(fillOpacity)); // expected 0 to be below 0.03 - } + cy.get('.cvat-appearance-opacity-slider') + .click('right') + .within(() => { + cy.get('[role="slider"]') + .should('have.attr', 'aria-valuemax') + .then(($ariaValuemax) => { + ariaValuenow = $ariaValuemax; + cy.get('[role="slider"]').should('have.attr', 'aria-valuenow', ariaValuenow); + }); }); + cy.get('.cvat_canvas_shape').each((object) => { + cy.get(object) + .should('have.prop', 'tagName') + .then(($tagName) => { + if ($tagName !== 'polyline') { + expect(Number(object.css('fill-opacity'))).to.be.gt(Number(fillOpacity)); // expected 1 to be above 0.03 + } else { + expect(Number(object.css('fill-opacity'))).to.be.lt(Number(fillOpacity)); // expected 0 to be below 0.03 + } + }); }); }); it('Set selected opacity to 0.', () => { - cy.get('.cvat-appearance-selected-opacity-slider').click('left').within(() => { - cy.get('[role="slider"]').should('have.attr', 'aria-valuemin').then(($ariaValuemin) => { - ariaValuenow = $ariaValuemin; - cy.get('[role="slider"]').should('have.attr', 'aria-valuenow', ariaValuenow); + cy.get('.cvat-appearance-selected-opacity-slider') + .click('left') + .within(() => { + cy.get('[role="slider"]') + .should('have.attr', 'aria-valuemin') + .then(($ariaValuemin) => { + ariaValuenow = $ariaValuemin; + cy.get('[role="slider"]').should('have.attr', 'aria-valuenow', ariaValuenow); + }); }); - }); }); it('Activate the box, the polygon and the cuboid. Boxes are transparent during activated.', () => { for (const i of ['#cvat_canvas_shape_1', '#cvat_canvas_shape_2', '#cvat_canvas_shape_4']) { - cy.get(i).trigger('mousemove').should('have.class', 'cvat_canvas_shape_activated').and('have.css', 'fill-opacity', ariaValuenow); + cy.get(i) + .trigger('mousemove') + .should('have.class', 'cvat_canvas_shape_activated') + .and('have.css', 'fill-opacity', ariaValuenow); } }); it('Activate checkbox "show projections".', () => { cy.get('.cvat-appearance-cuboid-projections-checkbox').click(); }); it('Activated the cuboid. Projection lines are visible.', () => { - cy.get('#cvat_canvas_shape_4').trigger('mousemove', {force: true}) - .should('have.attr', 'projections', 'true'); + cy.get('#cvat_canvas_shape_4') + .trigger('mousemove', { force: true }) + .should('have.attr', 'projections', 'true'); cy.get('.cvat_canvas_cuboid_projections').should('be.visible'); // Deactivate all objects cy.get('.cvat-canvas-container').click(500, 500); @@ -121,29 +135,28 @@ context('Appearance features', () => { it('Activate checkbox "outlined borders" with a red color. The borders are red on the objects.', () => { cy.get('.cvat-appearance-outlinded-borders-checkbox').click(); cy.get('.cvat-appearance-outlined-borders-button').click(); - cy.get('.cvat-label-color-picker').within(() => { - cy.contains('hex').prev().clear().type(strokeColor); - cy.contains('Ok').click(); - }); - cy.get('.cvat_canvas_shape').each(object => { + cy.changeColorViaBadge(strokeColor); + cy.get('.cvat_canvas_shape').each((object) => { cy.get(object).should('have.attr', 'stroke', `#${strokeColor}`); }); }); it('Set "Color by" to instance. The shapes changed a color.', () => { cy.changeAppearance('Instance'); - cy.get('.cvat_canvas_shape').each(object => { + cy.get('.cvat_canvas_shape').each((object) => { cy.get(object).should('have.css', 'fill').and('not.equal', fill); }); }); it('Set "Color by" to group. The shapes are white.', () => { cy.changeAppearance('Group'); - cy.get('.cvat_canvas_shape').each(object => { - cy.get(object).should('have.prop', 'tagName').then($tagName => { - if ($tagName !== 'polyline') { - expect(Number(object.css('fill-opacity'))).to.be.gt(Number(fillOpacity)); // expected 1 to be above 0.03 - expect(object.css('fill')).to.be.equal('rgb(224, 224, 224)'); // expected rgb(224, 224, 224) to equal rgb(224, 224, 224) - } - }); + cy.get('.cvat_canvas_shape').each((object) => { + cy.get(object) + .should('have.prop', 'tagName') + .then(($tagName) => { + if ($tagName !== 'polyline') { + expect(Number(object.css('fill-opacity'))).to.be.gt(Number(fillOpacity)); // expected 1 to be above 0.03 + expect(object.css('fill')).to.be.equal('rgb(224, 224, 224)'); // expected rgb(224, 224, 224) to equal rgb(224, 224, 224) + } + }); }); // Disable "Outlined borders" and check css "stroke" for polyline. cy.get('.cvat-appearance-outlinded-borders-checkbox').click(); diff --git a/tests/cypress/integration/actions_tasks_objects/case_22_tag_annotation_mode.js b/tests/cypress/integration/actions_tasks_objects/case_22_tag_annotation_mode.js index 3fbbf66d..718fb25e 100644 --- a/tests/cypress/integration/actions_tasks_objects/case_22_tag_annotation_mode.js +++ b/tests/cypress/integration/actions_tasks_objects/case_22_tag_annotation_mode.js @@ -14,32 +14,32 @@ context('Tag annotation mode.', () => { cy.get('span.cvat-tag-annotation-sidebar-frame-tag-label').should('not.exist'); } else { cy.get('span.cvat-tag-annotation-sidebar-frame-tag-label').should('have.length', countTags); - }; - }; + } + } - function checkPresenceFrameTags(labelName) { + function checkPresenceFrameTags() { cy.get('.cvat-tag-annotation-sidebar-frame-tags').within(() => { - cy.get('span.cvat-tag-annotation-sidebar-frame-tag-label').contains(labelName).should('exist'); + cy.get('span.cvat-tag-annotation-sidebar-frame-tag-label').should('exist'); }); - }; + } function addTag() { cy.get('.cvat-tag-annotation-sidebar-buttons').contains('Add tag').click(); - }; + } function skipFrame() { cy.get('.cvat-tag-annotation-sidebar-buttons').contains('Skip frame').click(); - }; + } function changeCheckboxAutomaticallyGoToNextFrame(value) { cy.get('.cvat-tag-annotation-sidebar-checkbox-skip-frame').within(() => { - if (value == "check") { + if (value == 'check') { cy.get('[type="checkbox"]').check(); - } else if (value == "uncheck") { + } else if (value == 'uncheck') { cy.get('[type="checkbox"]').uncheck(); - }; + } }); - }; + } before(() => { cy.openTaskJob(taskName); @@ -62,19 +62,19 @@ context('Tag annotation mode.', () => { it('Add tag', () => { addTag(); checkCountFrameTags(1); - checkPresenceFrameTags(labelName); + checkPresenceFrameTags(); }); it('Set "Automatically go to the next frame" to true and add tag', () => { cy.goToNextFrame(1); checkCountFrameTags(0); - changeCheckboxAutomaticallyGoToNextFrame("check"); + changeCheckboxAutomaticallyGoToNextFrame('check'); addTag(); cy.checkFrameNum(2); checkCountFrameTags(0); cy.goToPreviousFrame(1); checkCountFrameTags(1); - checkPresenceFrameTags(labelName); + checkPresenceFrameTags(); }); }); }); diff --git a/tests/cypress/integration/actions_tasks_objects/case_31_label_constructor_color_label.js b/tests/cypress/integration/actions_tasks_objects/case_31_label_constructor_color_label.js new file mode 100644 index 00000000..7c0ba330 --- /dev/null +++ b/tests/cypress/integration/actions_tasks_objects/case_31_label_constructor_color_label.js @@ -0,0 +1,129 @@ +// Copyright (C) 2020 Intel Corporation +// +// SPDX-License-Identifier: MIT + +/// + +import { taskName } from '../../support/const'; + +context('Label constructor. Color label.', () => { + const caseId = '31'; + const labelColor = { + redHex: 'ff0000', + greenHex: '00ff00', + blueHex: '0000ff', + yellowHex: 'fcbe03', + redRgb: '255, 0, 0', + greenRgb: '0, 255, 0', + blueRgb: '0, 0, 255', + yellowRgb: '252, 190, 3', + }; + const colorRed = 'Color red'; + const colorGreen = 'Color green'; + const colorBlue = 'Color blue'; + const labelAdditionalAttrs = false; + + const createRectangleShape2Points = { + points: 'By 2 Points', + type: 'Shape', + labelName: colorRed, + firstX: 100, + firstY: 350, + secondX: 200, + secondY: 450, + }; + const createRectangleShape2PointsSecond = { + points: createRectangleShape2Points.points, + type: createRectangleShape2Points.type, + labelName: colorGreen, + firstX: createRectangleShape2Points.firstX + 150, + firstY: createRectangleShape2Points.firstY, + secondX: createRectangleShape2Points.secondX + 150, + secondY: createRectangleShape2Points.secondY, + }; + + const createRectangleShape2PointsThird = { + points: createRectangleShape2Points.points, + type: createRectangleShape2Points.type, + labelName: colorBlue, + firstX: createRectangleShape2PointsSecond.firstX + 150, + firstY: createRectangleShape2PointsSecond.firstY, + secondX: createRectangleShape2PointsSecond.secondX + 150, + secondY: createRectangleShape2PointsSecond.secondY, + }; + + before(() => { + cy.openTask(taskName); + }); + + after('Remove annotation and save job.', () => { + cy.removeAnnotations(); + cy.saveJob(); + }); + + describe(`Testing case "${caseId}"`, () => { + it('To add multiple labels with a color change.', () => { + cy.addNewLabel(colorRed, labelAdditionalAttrs, labelColor.redHex); + cy.addNewLabel(colorGreen, labelAdditionalAttrs, labelColor.greenHex); + cy.addNewLabel(colorBlue, labelAdditionalAttrs, labelColor.blueHex); + }); + + it('Check color for created labels.', () => { + cy.get('.cvat-constructor-viewer-item').then((label) => { + for (let i = 0; i < label.length; i++) { + if (label[i].textContent === colorRed) { + cy.get(label[i]).should('have.attr', 'style').and('contain', labelColor.redRgb); + } else if (label[i].textContent === colorGreen) { + cy.get(label[i]).should('have.attr', 'style').and('contain', labelColor.greenRgb); + } else if (label[i].textContent === colorBlue) { + cy.get(label[i]).should('have.attr', 'style').and('contain', labelColor.blueRgb); + } + } + }); + }); + + it('Open the job. Create an objects.', () => { + cy.openJob(); + cy.createRectangle(createRectangleShape2Points); + cy.createRectangle(createRectangleShape2PointsSecond); + cy.createRectangle(createRectangleShape2PointsThird); + }); + + it('Created objects and objects on the side panel should have the same solor as label.', () => { + cy.get('#cvat_canvas_shape_1').should('have.attr', 'stroke', `#${labelColor.redHex}`); + cy.get('#cvat_canvas_shape_2').should('have.attr', 'stroke', `#${labelColor.greenHex}`); + cy.get('#cvat_canvas_shape_3').should('have.attr', 'stroke', `#${labelColor.blueHex}`); + cy.get('#cvat-objects-sidebar-state-item-1') + .should('have.attr', 'style') + .and('contain', `background-color: rgba(${labelColor.redRgb}`); + cy.get('#cvat-objects-sidebar-state-item-2') + .should('have.attr', 'style') + .and('contain', `background-color: rgba(${labelColor.greenRgb}`); + cy.get('#cvat-objects-sidebar-state-item-3') + .should('have.attr', 'style') + .and('contain', `background-color: rgba(${labelColor.blueRgb}`); + }); + + it('Save job and change color for a label.', () => { + cy.saveJob(); + cy.goToTaskList(); + cy.openTask(taskName); + cy.contains('.cvat-constructor-viewer-item', colorRed).within(() => { + cy.get('[data-icon="edit"]').click(); + }); + cy.get('.cvat-change-task-label-color-button').click(); + cy.changeColorViaBadge(labelColor.yellowHex); + cy.contains('button', 'Done').click(); + }); + + it('Open the job. Existing objects with this label have changed their color.', () => { + cy.openJob(); + cy.getObjectIdNumberByLabelName(colorRed).then((objectId) => { + cy.get(`#cvat_canvas_shape_${objectId}`).should('have.attr', 'stroke', `#${labelColor.yellowHex}`); + cy.get(`#cvat-objects-sidebar-state-item-${objectId}`) + .should('have.attr', 'style') + .and('contain', `background-color: rgba(${labelColor.yellowRgb}`); + }); + }); + }); +}); diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js index 88169576..57b7fff2 100644 --- a/tests/cypress/support/commands.js +++ b/tests/cypress/support/commands.js @@ -419,8 +419,8 @@ Cypress.Commands.add('removeAnnotations', () => { cy.get('.cvat-annotation-menu').within(() => { cy.contains('Remove annotations').click(); }); - cy.get('.ant-modal-content').within(() => { - cy.get('.ant-btn-dangerous').click(); + cy.get('.cvat-modal-confirm-remove-annotation').within(() => { + cy.contains('button','Delete').click(); }); }); @@ -438,7 +438,7 @@ Cypress.Commands.add('changeColorViaBadge', (labelColor) => { }); }); -Cypress.Commands.add('addNewLabel', (newLabelName, additionalAttrs) => { +Cypress.Commands.add('addNewLabel', (newLabelName, additionalAttrs, labelColor) => { let listCvatConstructorViewerItemText = []; cy.get('.cvat-constructor-viewer').should('exist'); cy.document().then((doc) => { @@ -449,6 +449,10 @@ Cypress.Commands.add('addNewLabel', (newLabelName, additionalAttrs) => { if (listCvatConstructorViewerItemText.indexOf(newLabelName) === -1) { cy.contains('button', 'Add label').click(); cy.get('[placeholder="Label name"]').type(newLabelName); + if (labelColor) { + cy.get('.cvat-change-task-label-color-badge').click(); + cy.changeColorViaBadge(labelColor); + } if (additionalAttrs) { for (let i = 0; i < additionalAttrs.length; i++) { cy.updateAttributes(additionalAttrs[i]); @@ -547,3 +551,18 @@ Cypress.Commands.add('goToPreviousFrame', (expectedFrameNum) => { cy.get('.cvat-player-previous-button').click(); cy.checkFrameNum(expectedFrameNum); }); + +Cypress.Commands.add('getObjectIdNumberByLabelName', (labelName) => { + cy.document().then((doc) => { + const stateItemLabelSelectorList = Array.from(doc.querySelectorAll('.cvat-objects-sidebar-state-item-label-selector')); + for (let i = 0; i < stateItemLabelSelectorList.length; i++) { + if (stateItemLabelSelectorList[i].textContent === labelName) { + cy.get(stateItemLabelSelectorList[i]) + .parents('.cvat-objects-sidebar-state-item') + .should('have.attr', 'id').then((id) => { + return Number(id.match(/\d+$/)); + }); + } + } + }); +});