385 lines
14 KiB
JavaScript
385 lines
14 KiB
JavaScript
// Copyright (C) CVAT.ai Corporation
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
/// <reference types="cypress" />
|
|
|
|
context('Requests page', () => {
|
|
const projectName = 'Project for testing requests page';
|
|
const mainLabelName = 'requests_page_label';
|
|
|
|
const cloudStorageData = {
|
|
displayName: 'Demo bucket',
|
|
resource: 'public',
|
|
manifest: 'manifest.jsonl',
|
|
endpointUrl: Cypress.config('minioUrl'),
|
|
};
|
|
|
|
const rectanglePayload = {
|
|
objectType: 'shape',
|
|
labelName: mainLabelName,
|
|
frame: 0,
|
|
type: 'rectangle',
|
|
points: [250, 64, 491, 228],
|
|
occluded: false,
|
|
};
|
|
|
|
const attrName = 'requests_attr';
|
|
const imagesCount = 3;
|
|
const imageFileName = `image_${mainLabelName}`;
|
|
const width = 800;
|
|
const height = 800;
|
|
const posX = 10;
|
|
const posY = 10;
|
|
const color = 'gray';
|
|
const archiveName = `${imageFileName}.zip`;
|
|
const archivePath = `cypress/fixtures/${archiveName}`;
|
|
const brokenArchiveName = `${imageFileName}_empty.zip`;
|
|
const brokenArchivePath = `cypress/fixtures/${brokenArchiveName}`;
|
|
const badAnnotationsName = `${imageFileName}_incorrect.xml`;
|
|
const badAnnotationsPath = `cypress/fixtures/${badAnnotationsName}`;
|
|
const imagesFolder = `cypress/fixtures/${imageFileName}`;
|
|
const directoryToArchive = imagesFolder;
|
|
const emptyDirectoryToArchive = `${imagesFolder}_empty`;
|
|
const annotationsArchiveNameLocal = 'requests_annotations_archive_local';
|
|
const annotationsArchiveNameCloud = 'requests_annotations_archive_cloud';
|
|
const backupArchiveName = 'requests_backup';
|
|
const exportFormat = 'CVAT for images';
|
|
let exportFileName;
|
|
|
|
const taskName = 'Annotation task for testing requests page';
|
|
const brokenTaskName = 'Broken Annotation task for testing requests page';
|
|
|
|
const data = {
|
|
projectID: null,
|
|
taskID: null,
|
|
cloudStorageID: null,
|
|
};
|
|
|
|
function checkRequestStatus(
|
|
selector,
|
|
innerCheck,
|
|
{
|
|
checkResourceLink, resourceLink,
|
|
} = { checkResourceLink: true, resourceLink: `/tasks/${data.taskID}` },
|
|
) {
|
|
cy.contains('.cvat-header-button', 'Requests').click();
|
|
cy.get(selector ? `.cvat-requests-card:contains("${selector}")` : '.cvat-requests-card')
|
|
.first()
|
|
.within(() => {
|
|
innerCheck();
|
|
if (checkResourceLink) {
|
|
cy.get('.cvat-requests-name').click();
|
|
}
|
|
});
|
|
|
|
if (checkResourceLink) {
|
|
cy.get('.cvat-spinner').should('not.exist');
|
|
|
|
if (resourceLink) {
|
|
cy.url().should('include', resourceLink);
|
|
} else {
|
|
cy.url().should('include', '/requests');
|
|
}
|
|
}
|
|
}
|
|
|
|
function openTask() {
|
|
cy.contains('.cvat-header-button', 'Tasks').should('be.visible').click();
|
|
cy.url().should('include', '/tasks');
|
|
cy.openTask(taskName);
|
|
}
|
|
|
|
before(() => {
|
|
cy.visit('/auth/login');
|
|
cy.login();
|
|
|
|
cy.imageGenerator(imagesFolder, imageFileName, width, height, color, posX, posY, mainLabelName, imagesCount);
|
|
cy.createZipArchive(directoryToArchive, badAnnotationsPath);
|
|
cy.createZipArchive(directoryToArchive, archivePath);
|
|
cy.createZipArchive(emptyDirectoryToArchive, brokenArchivePath);
|
|
|
|
data.cloudStorageID = cy.attachS3Bucket(cloudStorageData);
|
|
|
|
const defaultAttrValue = 'Requests attr';
|
|
const multiAttrParams = false;
|
|
const advancedConfigurationParams = false;
|
|
cy.goToProjectsList();
|
|
cy.createProjects(
|
|
projectName,
|
|
mainLabelName,
|
|
attrName,
|
|
defaultAttrValue,
|
|
multiAttrParams,
|
|
advancedConfigurationParams,
|
|
);
|
|
cy.openProject(projectName);
|
|
cy.url().then((url) => {
|
|
data.projectID = Number(url.split('/').slice(-1)[0].split('?')[0]);
|
|
|
|
const forProject = true;
|
|
const attachToProject = true;
|
|
let expectedResult = 'success';
|
|
cy.goToTaskList();
|
|
cy.createAnnotationTask(
|
|
taskName,
|
|
mainLabelName,
|
|
attrName,
|
|
defaultAttrValue,
|
|
archiveName,
|
|
multiAttrParams,
|
|
advancedConfigurationParams,
|
|
forProject,
|
|
attachToProject,
|
|
projectName,
|
|
expectedResult,
|
|
);
|
|
|
|
expectedResult = 'fail';
|
|
cy.goToTaskList();
|
|
cy.createAnnotationTask(
|
|
brokenTaskName,
|
|
mainLabelName,
|
|
attrName,
|
|
defaultAttrValue,
|
|
brokenArchiveName,
|
|
multiAttrParams,
|
|
advancedConfigurationParams,
|
|
forProject,
|
|
attachToProject,
|
|
projectName,
|
|
expectedResult,
|
|
);
|
|
|
|
cy.goToTaskList();
|
|
cy.openTask(taskName);
|
|
cy.url().then((taskUrl) => {
|
|
data.taskID = Number(taskUrl.split('/').slice(-1)[0].split('?')[0]);
|
|
cy.getJobIDFromIdx(0).then((jobID) => {
|
|
cy.headlessCreateObjects([rectanglePayload], jobID);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
after(() => {
|
|
cy.contains('.cvat-header-button', 'Cloud Storages').should('be.visible').click();
|
|
cy.url().should('include', '/cloudstorages');
|
|
cy.deleteCloudStorage(cloudStorageData.displayName);
|
|
|
|
cy.headlessDeleteProject(data.projectID);
|
|
});
|
|
|
|
describe('Requests page. Create a task.', () => {
|
|
beforeEach(() => {
|
|
cy.contains('.cvat-header-button', 'Requests').should('be.visible').click();
|
|
cy.url().should('include', '/requests');
|
|
});
|
|
|
|
it('Creating a task creates a request. Correct task can be opened.', () => {
|
|
checkRequestStatus(`Task #${data.taskID}`, () => {
|
|
cy.contains('Create Task').should('exist');
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
});
|
|
});
|
|
|
|
it('Creating a task creates a request. Incorrect task can not be opened.', () => {
|
|
checkRequestStatus('', () => {
|
|
cy.contains('Create Task').should('exist');
|
|
cy.get('.cvat-request-item-progress-failed').should('exist');
|
|
}, { resourceLink: '' });
|
|
});
|
|
});
|
|
|
|
describe('Requests page. Export a task.', () => {
|
|
beforeEach(openTask);
|
|
|
|
it('Export creates a request. Task can be opened from request. Export can be downloaded after page reload.', () => {
|
|
cy.exportTask({
|
|
type: 'annotations',
|
|
format: exportFormat,
|
|
archiveCustomName: annotationsArchiveNameLocal,
|
|
});
|
|
|
|
checkRequestStatus(`Task #${data.taskID}`, () => {
|
|
cy.contains('Export Annotations').should('exist');
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
cy.contains('Expires').should('exist');
|
|
cy.contains(exportFormat).should('exist');
|
|
});
|
|
|
|
cy.visit('/requests');
|
|
cy.downloadExport({ expectNotification: false }).then((file) => {
|
|
cy.verifyDownload(file);
|
|
exportFileName = file;
|
|
});
|
|
});
|
|
|
|
it('Export on cloud storage creates a request. Expire field does not exist.', () => {
|
|
cy.exportTask({
|
|
type: 'annotations',
|
|
format: exportFormat,
|
|
archiveCustomName: annotationsArchiveNameCloud,
|
|
targetStorage: {
|
|
location: 'Cloud storage',
|
|
cloudStorageId: data.cloudStorageID,
|
|
},
|
|
useDefaultLocation: false,
|
|
});
|
|
cy.waitForFileUploadToCloudStorage();
|
|
|
|
checkRequestStatus(`Task #${data.taskID}`, () => {
|
|
cy.contains('Export Annotations').should('exist');
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
cy.contains('Expires').should('not.exist');
|
|
cy.contains(exportFormat).should('exist');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Requests page. Import a task.', () => {
|
|
beforeEach(() => {
|
|
openTask();
|
|
cy.clickInTaskMenu('Upload annotations', true);
|
|
});
|
|
|
|
it('Import creates a request. Task can be opened from request.', () => {
|
|
cy.uploadAnnotations({
|
|
format: exportFormat.split(' ')[0],
|
|
filePath: exportFileName,
|
|
confirmModalClassName: '.cvat-modal-content-load-task-annotation',
|
|
waitAnnotationsGet: false,
|
|
});
|
|
|
|
checkRequestStatus(`Task #${data.taskID}`, () => {
|
|
cy.contains('Import Annotations').should('exist');
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
});
|
|
});
|
|
|
|
it('Import creates a request. Task can be opened from incorrect request.', () => {
|
|
cy.uploadAnnotations({
|
|
format: exportFormat.split(' ')[0],
|
|
filePath: badAnnotationsName,
|
|
confirmModalClassName: '.cvat-modal-content-load-task-annotation',
|
|
waitAnnotationsGet: false,
|
|
expectedResult: 'fail',
|
|
});
|
|
|
|
checkRequestStatus(`Task #${data.taskID}`, () => {
|
|
cy.contains('Import Annotations').should('exist');
|
|
cy.get('.cvat-request-item-progress-failed').should('exist');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Requests page. Project backup.', () => {
|
|
beforeEach(() => {
|
|
cy.contains('.cvat-header-button', 'Projects').should('be.visible').click();
|
|
cy.url().should('include', '/projects');
|
|
});
|
|
|
|
it('Export backup creates a request. Project can be opened.', () => {
|
|
cy.backupProject(
|
|
projectName,
|
|
backupArchiveName,
|
|
);
|
|
|
|
checkRequestStatus(`Project #${data.projectID}`, () => {
|
|
cy.contains('Export Backup').should('exist');
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
cy.contains('Expires').should('exist');
|
|
}, `/projects/${data.projectID}`);
|
|
cy.downloadExport().then((file) => {
|
|
cy.verifyDownload(file);
|
|
});
|
|
});
|
|
|
|
it('Import backup creates a request. Project can not be opened.', () => {
|
|
cy.restoreProject(
|
|
`${backupArchiveName}.zip`,
|
|
);
|
|
|
|
checkRequestStatus('', () => {
|
|
cy.contains('Import Backup').should('exist');
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
cy.get('.cvat-requests-name').should('not.exist');
|
|
}, { checkResourceLink: false });
|
|
|
|
cy.goToProjectsList();
|
|
cy.openProject(projectName);
|
|
cy.deleteProjectViaActions(projectName);
|
|
});
|
|
});
|
|
|
|
describe('Regression tests', () => {
|
|
beforeEach(openTask);
|
|
|
|
it('Export job in different formats from task page simultaneously.', () => {
|
|
cy.intercept('GET', '/api/requests/**', (req) => {
|
|
req.on('response', (res) => {
|
|
res.setDelay(5000);
|
|
});
|
|
});
|
|
|
|
cy.getJobIDFromIdx(0).then((jobID) => {
|
|
const closeExportNotification = () => {
|
|
cy.get('.ant-notification-notice').first().within((notification) => {
|
|
cy.contains('Export is finished').should('be.visible');
|
|
cy.get('span[aria-label="close"]').click();
|
|
cy.wrap(notification).should('not.exist');
|
|
});
|
|
};
|
|
|
|
const exportParams = {
|
|
type: 'dataset',
|
|
format: exportFormat,
|
|
archiveCustomName: 'job_annotations_cvat',
|
|
jobOnTaskPage: jobID,
|
|
};
|
|
|
|
cy.exportJob(exportParams);
|
|
const newExportParams = {
|
|
...exportParams,
|
|
format: 'COCO',
|
|
archiveCustomName: 'job_annotations_coco',
|
|
};
|
|
cy.exportJob(newExportParams);
|
|
|
|
closeExportNotification();
|
|
closeExportNotification();
|
|
|
|
cy.contains('.cvat-header-button', 'Requests').should('be.visible').click();
|
|
cy.url().should('include', '/requests');
|
|
|
|
cy.get(`.cvat-requests-card:contains("Job #${jobID}")`)
|
|
.should('have.length', 2)
|
|
.each((card) => {
|
|
cy.wrap(card).within(() => {
|
|
cy.get('.cvat-request-item-progress-success').should('exist');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Export task. Request for status fails, UI is not crushing', () => {
|
|
cy.intercept('GET', '/api/requests/**', {
|
|
statusCode: 500,
|
|
body: 'Network error',
|
|
});
|
|
|
|
cy.exportTask({
|
|
type: 'annotations',
|
|
format: exportFormat,
|
|
archiveCustomName: annotationsArchiveNameLocal,
|
|
});
|
|
|
|
cy.contains('Could not export dataset').should('be.visible');
|
|
cy.closeNotification('.ant-notification-notice-error');
|
|
|
|
cy.contains('.cvat-header-button', 'Requests').should('be.visible').click();
|
|
cy.get('.cvat-requests-page').should('be.visible');
|
|
});
|
|
});
|
|
});
|