18169: Post review changes, Cypress tests added
[arvados-workbench2.git] / cypress / support / commands.js
index 929ffb83d849a357c18d74680d9e762f0b833bdc..07290e550aa3b6beceba61559a477216ef220435 100644 (file)
 
 const controllerURL = Cypress.env('controller_url');
 const systemToken = Cypress.env('system_token');
+let createdResources = [];
+
+// Clean up on a 'before' hook to allow post-mortem analysis on individual tests.
+beforeEach(function () {
+    if (createdResources.length === 0) {
+        return;
+    }
+    cy.log(`Cleaning ${createdResources.length} previously created resource(s)`);
+    createdResources.forEach(function({suffix, uuid}) {
+        // Don't fail when a resource isn't already there, some objects may have
+        // been removed, directly or indirectly, from the test that created them.
+        cy.deleteResource(systemToken, suffix, uuid, false);
+    });
+    createdResources = [];
+});
 
 Cypress.Commands.add(
     "doRequest", (method = 'GET', path = '', data = null, qs = null,
-        token = systemToken, auth = false, followRedirect = true) => {
+        token = systemToken, auth = false, followRedirect = true, failOnStatusCode = true) => {
     return cy.request({
         method: method,
         url: `${controllerURL.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`,
         body: data,
         qs: auth ? qs : Object.assign({ api_token: token }, qs),
         auth: auth ? { bearer: `${token}` } : undefined,
-        followRedirect: followRedirect
-    })
-}
-)
-
-// This resets the DB removing all content and seeding it with the fixtures.
-// TODO: Maybe we can add an optional param to avoid the loading part?
-Cypress.Commands.add(
-    "resetDB", () => {
-        cy.request('POST', `${controllerURL}/database/reset?api_token=${systemToken}`);
-    }
-)
+        followRedirect: followRedirect,
+        failOnStatusCode: failOnStatusCode
+    });
+});
 
 Cypress.Commands.add(
     "getUser", (username, first_name = '', last_name = '', is_admin = false, is_active = true) => {
@@ -148,14 +155,15 @@ Cypress.Commands.add(
         return cy.doRequest('POST', '/arvados/v1/' + suffix, data, null, token, true)
             .its('body').as('resource')
             .then(function () {
+                createdResources.push({suffix, uuid: this.resource.uuid});
                 return this.resource;
             })
     }
 )
 
 Cypress.Commands.add(
-    "deleteResource", (token, suffix, uuid) => {
-        return cy.doRequest('DELETE', '/arvados/v1/' + suffix + '/' + uuid)
+    "deleteResource", (token, suffix, uuid, failOnStatusCode = true) => {
+        return cy.doRequest('DELETE', '/arvados/v1/' + suffix + '/' + uuid, null, null, token, false, true, failOnStatusCode)
             .its('body').as('resource')
             .then(function () {
                 return this.resource;
@@ -175,6 +183,8 @@ Cypress.Commands.add(
 
 Cypress.Commands.add(
     "loginAs", (user) => {
+        cy.clearCookies()
+        cy.clearLocalStorage()
         cy.visit(`/token/?api_token=${user.token}`);
         cy.url({timeout: 10000}).should('contain', '/projects/');
         cy.get('div#root').should('contain', 'Arvados Workbench (zzzzz)');
@@ -182,6 +192,32 @@ Cypress.Commands.add(
     }
 )
 
+Cypress.Commands.add(
+    "testEditProjectOrCollection", (container, oldName, newName, newDescription, isProject = true) => {
+        cy.get(container).contains(oldName).rightclick();
+        cy.get('[data-cy=context-menu]').contains(isProject ? 'Edit project' : 'Edit collection').click();
+        cy.get('[data-cy=form-dialog]').within(() => {
+            cy.get('input[name=name]').clear().type(newName);
+            cy.get(isProject ? 'div[contenteditable=true]' : 'input[name=description]').clear().type(newDescription);
+            cy.get('[data-cy=form-submit-btn]').click();
+        });
+
+        cy.get(container).contains(newName).rightclick();
+        cy.get('[data-cy=context-menu]').contains(isProject ? 'Edit project' : 'Edit collection').click();
+        cy.get('[data-cy=form-dialog]').within(() => {
+            cy.get('input[name=name]').should('have.value', newName);
+
+            if (isProject) {
+                cy.get('span[data-text=true]').contains(newDescription);
+            } else {
+                cy.get('input[name=description]').should('have.value', newDescription);
+            }
+
+            cy.get('[data-cy=form-cancel-btn]').click();
+        });
+    }
+)
+
 Cypress.Commands.add(
     "doSearch", (searchTerm) => {
         cy.get('[data-cy=searchbar-input-field]').type(`{selectall}${searchTerm}{enter}`);
@@ -244,4 +280,42 @@ Cypress.Commands.add('createProject', ({
             cy.addToFavorites(user.token, user.user.uuid, project.uuid);
         }
     });
-});
\ No newline at end of file
+});
+
+Cypress.Commands.add(
+    'upload',
+    {
+        prevSubject: 'element',
+    },
+    (subject, file, fileName) => {
+        cy.window().then(window => {
+            const blob = b64toBlob(file, '', 512);
+            const testFile = new window.File([blob], fileName);
+
+            cy.wrap(subject).trigger('drop', {
+                dataTransfer: { files: [testFile] },
+            });
+        })
+    }
+)
+
+function b64toBlob(b64Data, contentType = '', sliceSize = 512) {
+    const byteCharacters = atob(b64Data)
+    const byteArrays = []
+
+    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+        const slice = byteCharacters.slice(offset, offset + sliceSize);
+
+        const byteNumbers = new Array(slice.length);
+        for (let i = 0; i < slice.length; i++) {
+            byteNumbers[i] = slice.charCodeAt(i);
+        }
+
+        const byteArray = new Uint8Array(byteNumbers);
+
+        byteArrays.push(byteArray);
+    }
+
+    const blob = new Blob(byteArrays, { type: contentType });
+    return blob
+}
\ No newline at end of file