Cypress test. Dump/Upload annotation. (#2771)

* Add css classes.

* Add some functions for test

* Cypress test. Dump/Upload annotation.

* Increase Cypress version to 6.4.0

* Added css classes for projects

* Replace dowloadFolder parameter

* Commands adaptation to 6.4.0

* Tests adaptation

* Additional changes related to migration to 6.4.0

* some fix

* Update cvat-ui/src/components/project-page/details.tsx

Co-authored-by: Boris Sekachev <boris.sekachev@intel.com>

* Update cvat-ui/src/components/project-page/details.tsx

Co-authored-by: Boris Sekachev <boris.sekachev@intel.com>

* Apply comment

Co-authored-by: Boris Sekachev <boris.sekachev@intel.com>
main
Dmitry Kruchinin 5 years ago committed by GitHub
parent 68b3e71ffa
commit 0d99bec0cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -47,7 +47,7 @@ export default function LoadSubmenu(props: Props): JSX.Element {
return false;
}}
>
<Button block type='link' disabled={disabled}>
<Button block type='link' disabled={disabled} className='cvat-menu-load-submenu-item-button'>
<UploadOutlined />
<Text>{loader.name}</Text>
{pending && <LoadingOutlined style={{ marginLeft: 10 }} />}

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -99,6 +99,7 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
Modal.confirm({
title: 'Current annotation will be lost',
content: 'You are going to upload new annotations to this job. Continue?',
className: 'cvat-modal-content-load-job-annotation',
onOk: () => {
onClickMenu(copyParams, file);
},

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -29,7 +29,7 @@ export default function DetailsComponent(props: DetailsComponentProps): JSX.Elem
const [projectName, setProjectName] = useState(project.name);
return (
<div className='cvat-project-details'>
<div cvat-project-id={project.id} className='cvat-project-details'>
<Row>
<Col>
<Title
@ -41,13 +41,13 @@ export default function DetailsComponent(props: DetailsComponentProps): JSX.Elem
dispatch(updateProjectAsync(project));
},
}}
className='cvat-text-color'
className='cvat-text-color cvat-project-name'
>
{projectName}
</Title>
</Col>
</Row>
<Row justify='space-between'>
<Row justify='space-between' className='cvat-project-description'>
<Col>
<Text type='secondary'>
{`Project #${project.id} created`}

@ -4,6 +4,7 @@
"viewportWidth": 1300,
"viewportHeight": 960,
"defaultCommandTimeout": 25000,
"downloadsFolder": "cypress/fixtures",
"env": {
"user": "admin",
"email": "admin@localhost.company",

@ -52,6 +52,15 @@ context('Base actions on the project', () => {
const password = `${randomString(true)}`;
let projectID = '';
function getProjectID(projectName) {
cy.contains('.cvat-project-name', projectName)
.parents('.cvat-project-details')
.should('have.attr', 'cvat-project-id')
.then(($projectID) => {
projectID = $projectID;
});
}
before(() => {
cy.openProject(projectName);
});
@ -101,9 +110,7 @@ context('Base actions on the project', () => {
it('The task is successfully opened. No label editor on task page.', () => {
cy.goToProjectsList();
cy.openProject(projectName);
cy.getProjectID(projectName).then(($projectID) => {
projectID = $projectID;
});
getProjectID(projectName);
cy.get('.cvat-tasks-list-item').then((countTasks) => {
// The number of created tasks is greater than zero
expect(countTasks.length).to.be.gt(0);

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -96,7 +96,7 @@ context('Actions on polygon', () => {
});
it('Second shape is invisible', () => {
cy.get('#cvat_canvas_shape_2').should('not.be.visible');
cy.get('#cvat_canvas_shape_2').should('not.exist');
});
it('Increase z-layer with a special switcher', () => {

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -34,14 +34,12 @@ context('Create and delete a annotation task', () => {
it('Create a task', () => {
cy.createAnnotationTask(taskName, labelName, attrName, textDefaultValue, archiveName);
});
it('Delete the created task', () => {
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
taskID = $taskID;
});
cy.deleteTask(taskName);
});
it('Deleted task not exist', () => {
cy.contains('strong', `#${taskID}: `)
cy.contains('strong', taskName)
.parents('.cvat-tasks-list-item')
.should('have.attr', 'style', 'pointer-events: none; opacity: 0.5;');
});

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -10,9 +10,9 @@ context('Search task feature.', () => {
const caseId = '35';
function searchTask(option, result) {
cy.server().route('GET', '/api/v1/tasks**').as('searchTask');
cy.intercept('GET', '/api/v1/tasks**').as('searchTask');
cy.get('.cvat-task-page-search-task').find('[placeholder="Search"]').clear().type(`${option}{Enter}`);
cy.wait('@searchTask').its('status').should('equal', 200);
cy.wait('@searchTask').its('response.statusCode').should('equal', 200);
cy.contains('.cvat-item-task-name', taskName).should(result);
}

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -38,9 +38,7 @@ context('Check if parameters "startFrame", "stopFrame", "frameStep" works as exp
after(() => {
cy.goToTaskList();
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
});
describe(`Testing "${labelName}"`, () => {

@ -30,9 +30,7 @@ context('Try to create a task without necessary arguments.', () => {
after(() => {
cy.goToTaskList();
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
});
describe(`Testing "${labelName}"`, () => {

@ -32,15 +32,15 @@ context('Changing a default value for an attribute.', () => {
describe(`Testing case "${caseId}"`, () => {
it('Add a label, add text (leave its value empty by default) & checkbox attributes.', () => {
cy.server().route('PATCH', '/api/v1/tasks/**').as('patchTask');
cy.server().route('GET', '/api/v1/tasks**').as('getTask');
cy.intercept('PATCH', '/api/v1/tasks/**').as('patchTask');
cy.intercept('GET', '/api/v1/tasks**').as('getTask');
cy.addNewLabel(additionalLabel, additionalAttrsLabel);
cy.wait('@patchTask').its('status').should('equal', 200);
cy.wait('@getTask').its('status').should('equal', 200);
cy.wait('@patchTask').its('response.statusCode').should('equal', 200);
cy.wait('@getTask').its('response.statusCode').should('equal', 200);
});
it('Open label editor. Change default values for text & checkbox attributes, press Done.', () => {
cy.server().route('PATCH', '/api/v1/tasks/**').as('patchTask');
cy.intercept('PATCH', '/api/v1/tasks/**').as('patchTask');
cy.get('.cvat-constructor-viewer').within(() => {
cy.contains(new RegExp(`^${additionalLabel}$`))
.parents('.cvat-constructor-viewer-item')
@ -64,7 +64,7 @@ context('Changing a default value for an attribute.', () => {
cy.contains(new RegExp(`^${newCheckboxValue}$`)).click();
});
cy.contains('[type="submit"]', 'Done').click();
cy.wait('@patchTask').its('status').should('equal', 200);
cy.wait('@patchTask').its('response.statusCode').should('equal', 200);
});
it('Open a job, create an object. Attribute values are correct.', () => {

@ -20,9 +20,7 @@ context('Create a task with files from remote sources.', () => {
after(() => {
cy.goToTaskList();
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
});
describe(`Testing "${labelName}"`, () => {

@ -26,13 +26,13 @@ context('Export as a dataset.', () => {
describe(`Testing case "${caseId}"`, () => {
it('Go to Menu. Press "Export as a dataset" -> "CVAT for images".', () => {
cy.server().route('GET', '/api/v1/tasks/**/dataset**').as('exportDataset');
cy.intercept('GET', '/api/v1/tasks/**/dataset**').as('exportDataset');
cy.interactMenu('Export as a dataset');
cy.get('.cvat-menu-export-submenu-item').within(() => {
cy.contains('CVAT for images').click();
});
cy.wait('@exportDataset', { timeout: 5000 }).its('status').should('equal', 202);
cy.wait('@exportDataset').its('status').should('equal', 201);
cy.wait('@exportDataset', { timeout: 5000 }).its('response.statusCode').should('equal', 202);
cy.wait('@exportDataset').its('response.statusCode').should('equal', 201);
});
});
});

@ -0,0 +1,74 @@
// Copyright (C) 2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
/// <reference types="cypress" />
import { taskName, labelName } from '../../support/const';
context('Dump/Upload annotation.', { browser: '!firefox' }, () => {
const caseId = '52';
const createRectangleTrack2Points = {
points: 'By 2 Points',
type: 'Track',
labelName: labelName,
firstX: 250,
firstY: 350,
secondX: 350,
secondY: 450,
};
const dumpType = 'CVAT for images';
let annotationArchiveName = '';
before(() => {
cy.openTaskJob(taskName);
cy.createRectangle(createRectangleTrack2Points);
});
describe(`Testing case "${caseId}"`, () => {
it('Save job. Dump annotaion. Remove annotation. Save job.', () => {
cy.saveJob('PATCH', 200, 'saveJobDump');
cy.intercept('GET', '/api/v1/tasks/**/annotations**').as('dumpAnnotations');
cy.interactMenu('Dump annotations');
cy.get('.cvat-menu-dump-submenu-item').within(() => {
cy.contains(dumpType).click();
});
cy.wait('@dumpAnnotations', { timeout: 5000 }).its('response.statusCode').should('equal', 202);
cy.wait('@dumpAnnotations').its('response.statusCode').should('equal', 201);
cy.removeAnnotations();
cy.saveJob('PUT');
cy.get('#cvat_canvas_shape_1').should('not.exist');
cy.get('#cvat-objects-sidebar-state-item-1').should('not.exist');
cy.wait(2000); // Waiting for the full download.
cy.task('listFiles', 'cypress/fixtures').each((fileName) => {
if (fileName.includes(dumpType.toLowerCase())) {
annotationArchiveName = fileName;
}
});
});
it('Upload annotation.', () => {
cy.interactMenu('Upload annotations');
cy.contains('.cvat-menu-load-submenu-item', dumpType.split(' ')[0])
.should('be.visible')
.within(() => {
cy.get('.cvat-menu-load-submenu-item-button')
.click()
.get('input[type=file]')
.attachFile(annotationArchiveName);
});
cy.intercept('PUT', '/api/v1/jobs/**/annotations**').as('uploadAnnotationsPut');
cy.intercept('GET', '/api/v1/jobs/**/annotations**').as('uploadAnnotationsGet');
cy.get('.cvat-modal-content-load-job-annotation').within(() => {
cy.contains('button', 'Update').click();
});
cy.wait('@uploadAnnotationsPut', { timeout: 5000 }).its('response.statusCode').should('equal', 202);
cy.wait('@uploadAnnotationsPut').its('response.statusCode').should('equal', 201);
cy.wait('@uploadAnnotationsGet').its('response.statusCode').should('equal', 200);
cy.get('#cvat_canvas_shape_1').should('exist');
cy.get('#cvat-objects-sidebar-state-item-1').should('exist');
});
});
});

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -44,9 +44,7 @@ context('Cannot read property label of undefined', () => {
after(() => {
cy.goToTaskList();
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
});
describe(`Testing "${labelName}"`, () => {

@ -37,10 +37,10 @@ context('Check error сannot read property at saving job', () => {
});
it('Save job and go to previous frame at saving job', () => {
cy.server().route('PATCH', '/api/v1/jobs/**').as('saveJob');
cy.intercept('PATCH', '/api/v1/jobs/**').as('saveJob');
cy.saveJob();
cy.get('body').type('d');
cy.wait('@saveJob').its('status').should('equal', 200);
cy.wait('@saveJob').its('response.statusCode').should('equal', 200);
});
it('Page with the error is missing', () => {

@ -48,9 +48,7 @@ context('Rename a task.', () => {
after(() => {
cy.login();
cy.getTaskID(newNaskName).then(($taskID) => {
cy.deleteTask(newNaskName, $taskID);
});
cy.deleteTask(newNaskName);
});
describe(`Testing "${labelName}". Issue 2572.`, () => {

@ -61,14 +61,10 @@ context("Some parts of the Redux state (issues) isn't reset after chaning a task
after(() => {
cy.goToTaskList();
cy.getTaskID(taskName.firstTaskName).then(($taskID) => {
cy.deleteTask(taskName.firstTaskName, $taskID);
});
cy.deleteTask(taskName.firstTaskName);
cy.reload();
cy.closeModalUnsupportedPlatform();
cy.getTaskID(taskName.secondTaskName).then(($taskID) => {
cy.deleteTask(taskName.secondTaskName, $taskID);
});
cy.deleteTask(taskName.secondTaskName);
});
describe(`Testing "${labelName}"`, () => {

@ -129,9 +129,7 @@ context('Review pipeline feature', () => {
after(() => {
cy.goToTaskList();
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
});
describe(`Testing "${labelName}"`, () => {
@ -198,14 +196,14 @@ context('Review pipeline feature', () => {
});
it('Second user sends the job to review.', () => {
cy.server().route('POST', '/api/v1/server/logs').as('sendLogs');
cy.intercept('POST', '/api/v1/server/logs').as('sendLogs');
cy.interactMenu('Request a review');
cy.contains('.cvat-modal-content-save-job', 'The job has unsaved annotations')
.should('exist')
.within(() => {
cy.contains('[type="button"]', 'OK').click();
});
cy.wait('@sendLogs').its('status').should('equal', 201);
cy.wait('@sendLogs').its('response.statusCode').should('equal', 201);
cy.get('.cvat-request-review-dialog')
.should('exist')
.within(() => {

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -44,9 +44,7 @@ context('Multiple users. Assign task, job.', () => {
after(() => {
cy.login();
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
});
describe(`Testing case "${caseId}"`, () => {
@ -129,9 +127,7 @@ context('Multiple users. Assign task, job.', () => {
it('Third user login. Tries to delete task. The task can be opened.', () => {
cy.login(thirdUserName, thirdUser.password);
cy.contains('strong', taskName).should('exist');
cy.getTaskID(taskName).then(($taskID) => {
cy.deleteTask(taskName, $taskID);
});
cy.deleteTask(taskName);
cy.closeNotification('.cvat-notification-notice-delete-task-failed');
cy.contains('.cvat-item-task-name', taskName)
.parents('.cvat-tasks-list-item')

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -28,12 +28,12 @@ context('Check email verification system', () => {
describe(`Case: "${caseId}"`, () => {
it('Register user. Notification exist. The response status is successful.', () => {
cy.server().route('POST', '/api/v1/auth/register').as('userRegister');
cy.intercept('POST', '/api/v1/auth/register').as('userRegister');
cy.userRegistration(firstName, lastName, userName, emailAddr, password);
cy.get('.ant-notification-topRight')
.contains(`We have sent an email with a confirmation link to ${emailAddr}.`)
.should('exist');
cy.wait('@userRegister').its('status').should('eq', 201);
cy.wait('@userRegister').its('response.statusCode').should('eq', 201);
});
});
});

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -6,6 +6,8 @@
const { imageGenerator } = require('../plugins/imageGenerator/addPlugin');
const { createZipArchive } = require('../plugins/createZipArchive/addPlugin');
const fs = require('fs');
module.exports = (on, config) => {
require('@cypress/code-coverage/task')(on, config);
on('task', { imageGenerator });
@ -16,13 +18,20 @@ module.exports = (on, config) => {
return null;
},
});
on('task', {
listFiles(folderName) {
return fs.readdirSync(folderName);
},
});
// Try to resolve "Cypress failed to make a connection to the Chrome DevTools Protocol"
// https://github.com/cypress-io/cypress/issues/7450
on('before:browser:launch', (browser, launchOptions) => {
if (browser.name === 'chrome' && browser.isHeadless) {
launchOptions.args.push('--disable-gpu');
return launchOptions;
if (browser.name === 'chrome') {
if (browser.isHeadless) {
launchOptions.args.push('--disable-gpu');
}
}
return launchOptions;
});
return config;
};

@ -106,10 +106,10 @@ Cypress.Commands.add('openTask', (taskName) => {
cy.get('.cvat-task-details').should('exist');
});
Cypress.Commands.add('saveJob', (method = 'PATCH', status = 200) => {
cy.server().route(method, '/api/v1/jobs/**').as('saveJob');
Cypress.Commands.add('saveJob', (method = 'PATCH', status = 200, as = 'saveJob') => {
cy.intercept(method, '/api/v1/jobs/**').as(as);
cy.get('button').contains('Save').click({ force: true });
cy.wait('@saveJob').its('status').should('equal', status);
cy.wait(`@${as}`).its('response.statusCode').should('equal', status);
});
Cypress.Commands.add('getJobNum', (jobID) => {
@ -388,28 +388,26 @@ Cypress.Commands.add('createPolyline', (createPolylineParams) => {
cy.checkObjectParameters(createPolylineParams, 'POLYLINE');
});
Cypress.Commands.add('getTaskID', (taskName) => {
cy.contains('strong', taskName)
.parents('.cvat-tasks-list-item')
.within(() => {
cy.get('span')
.invoke('text')
.then((text) => {
return String(text.match(/^#\d+\:/g)).replace(/[^\d]/g, '');
Cypress.Commands.add('deleteTask', (taskName) => {
let taskId = '';
cy.contains('.cvat-item-task-name', taskName)
.parents('.cvat-task-item-description')
.find('.cvat-item-task-id')
.then(($taskId) => {
taskId = $taskId.text().replace(/[^\d]/g, '');
cy.contains('.cvat-item-task-name', taskName)
.parents('.cvat-tasks-list-item')
.find('.cvat-menu-icon')
.trigger('mouseover');
cy.get('.cvat-actions-menu').contains('Delete').click();
cy.get('.cvat-modal-confirm-delete-task')
.should('contain', `The task ${taskId} will be deleted`)
.within(() => {
cy.contains('button', 'Delete').click();
});
});
});
Cypress.Commands.add('deleteTask', (taskName, taskID) => {
cy.contains('strong', taskName).parents('.cvat-tasks-list-item').find('.cvat-menu-icon').trigger('mouseover');
cy.get('.cvat-actions-menu').contains('Delete').click();
cy.get('.cvat-modal-confirm-delete-task')
.should('contain', `The task ${taskID} will be deleted`)
.within(() => {
cy.contains('button', 'Delete').click();
});
});
Cypress.Commands.add('advancedConfiguration', (advancedConfigurationParams) => {
cy.contains('Advanced configuration').click();
if (advancedConfigurationParams.multiJobs) {

@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
@ -42,20 +42,8 @@ Cypress.Commands.add('openProject', (projectName) => {
cy.get('.cvat-project-details').should('exist');
});
Cypress.Commands.add('getProjectID', (projectName) => {
cy.contains('h4', projectName)
.parents('.cvat-project-details')
.within(() => {
cy.get('span')
.invoke('text')
.then((text) => {
return String(text.match(/#\d+/g)).replace(/[^\d]/g, '');
});
});
});
Cypress.Commands.add('deleteProject', (projectName, projectID, expectedResult = 'success') => {
cy.contains(projectName)
cy.contains('.cvat-projects-project-item-title', projectName)
.parents('.cvat-projects-project-item-card')
.within(() => {
cy.get('.cvat-porjects-project-item-description').within(() => {

@ -140,10 +140,10 @@ Cypress.Commands.add('submitReview', (decision, user) => {
cy.get('.cvat-submit-review-dialog').within(() => {
cy.contains(new RegExp(`^${decision}$`, 'g')).click();
if (decision === 'Review next') {
cy.server().route('GET', `/api/v1/users?search=${user}&limit=10`).as('searchUsers');
cy.intercept('GET', `/api/v1/users?search=${user}&limit=10`).as('searchUsers');
cy.get('.cvat-user-search-field').within(() => {
cy.get('input[type="search"]').clear().type(`${user}`);
cy.wait('@searchUsers').its('status').should('equal', 200);
cy.wait('@searchUsers').its('response.statusCode').should('equal', 200);
cy.get('input[type="search"]').type('{Enter}');
});
}

1462
tests/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@
},
"devDependencies": {
"@cypress/code-coverage": "^3.8.1",
"cypress": "^5.0.0",
"cypress": "^6.4.0",
"cypress-file-upload": "^5.0.2",
"cypress-localstorage-commands": "^1.3.1",
"cypress-plugin-tab": "^1.0.5"

Loading…
Cancel
Save