]> git.arvados.org - arvados.git/blob - services/workbench2/cypress/e2e/details-card.cy.js
22845: added tbody assertions in test
[arvados.git] / services / workbench2 / cypress / e2e / details-card.cy.js
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 describe('User Details Card tests', function () {
6     let activeUser;
7     let adminUser;
8
9     before(function () {
10         // Only set up common users once. These aren't set up as aliases because
11         // aliases are cleaned up after every test. Also it doesn't make sense
12         // to set the same users on beforeEach() over and over again, so we
13         // separate a little from Cypress' 'Best Practices' here.
14         cy.getUser('admin', 'Admin', 'User', true, true)
15             .as('adminUser')
16             .then(function () {
17                 adminUser = this.adminUser;
18             });
19         cy.getUser('activeUser1', 'Active', 'User', false, true)
20             .as('activeUser')
21             .then(function () {
22                 activeUser = this.activeUser;
23             });
24         cy.on('uncaught:exception', (err, runnable) => {
25             console.error(err);
26         });
27     });
28
29     beforeEach(function () {
30         cy.clearCookies();
31         cy.clearLocalStorage();
32     });
33
34     it('should display the user details card', () => {
35         cy.loginAs(adminUser);
36
37         cy.get('[data-cy=user-details-card]').should('be.visible');
38         cy.get('[data-cy=user-details-card]').contains(adminUser.user.full_name).should('be.visible');
39     });
40
41     it('shows the appropriate buttons in the multiselect toolbar', () => {
42         const msButtonTooltips = ['View details', 'User account', 'API Details'];
43
44         cy.loginAs(activeUser);
45
46         cy.get('[data-cy=multiselect-button]').should('have.length', msButtonTooltips.length);
47
48         for (let i = 0; i < msButtonTooltips.length; i++) {
49             cy.get('[data-cy=multiselect-button]').eq(i).trigger('mouseover');
50             cy.get('body').contains(msButtonTooltips[i]).should('exist');
51             cy.get('[data-cy=multiselect-button]').eq(i).trigger('mouseout');
52         }
53     });
54 });
55
56 describe('Project Details Card tests', function () {
57     let activeUser;
58     let adminUser;
59
60     before(function () {
61         // Only set up common users once. These aren't set up as aliases because
62         // aliases are cleaned up after every test. Also it doesn't make sense
63         // to set the same users on beforeEach() over and over again, so we
64         // separate a little from Cypress' 'Best Practices' here.
65         cy.getUser('admin', 'Admin', 'User', true, true)
66             .as('adminUser')
67             .then(function () {
68                 adminUser = this.adminUser;
69             });
70         cy.getUser('activeUser1', 'Active', 'User', false, true)
71             .as('activeUser')
72             .then(function () {
73                 activeUser = this.activeUser;
74             });
75         cy.on('uncaught:exception', (err, runnable) => {
76             console.error(err);
77         });
78     });
79
80     beforeEach(function () {
81         cy.clearCookies();
82         cy.clearLocalStorage();
83     });
84
85     it('should display the project details card', () => {
86         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
87         cy.loginAs(adminUser);
88
89         // Create project
90         cy.get('[data-cy=side-panel-button]').click();
91         cy.get('[data-cy=side-panel-new-project]').click();
92         cy.get('[data-cy=form-dialog]')
93             .should('contain', 'New Project')
94             .within(() => {
95                 cy.get('[data-cy=name-field]').within(() => {
96                     cy.get('input').type(projName);
97                 });
98             });
99         cy.get('[data-cy=form-submit-btn]').click();
100         cy.waitForDom().get('[data-cy=form-dialog]').should('not.exist');
101
102         cy.get('[data-cy=project-details-card]').should('be.visible');
103         cy.get('[data-cy=project-details-card]').contains(projName).should('be.visible');
104     });
105
106     it('shows the appropriate buttons in the multiselect toolbar', () => {
107         const msButtonTooltips = [
108             'View details',
109             'Open in new tab',
110             'Copy UUID',
111             'Share',
112             'Edit project',
113             'Move to trash',
114             'New project',
115             'Move to',
116             'Freeze project',
117             'Add to favorites',
118             'Copy link to clipboard',
119             'Open with 3rd party client',
120             'API Details',
121         ];
122
123         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
124         cy.loginAs(activeUser);
125
126         // Create project
127         cy.get('[data-cy=side-panel-button]').click();
128         cy.get('[data-cy=side-panel-new-project]').click();
129         cy.get('[data-cy=form-dialog]')
130             .should('contain', 'New Project')
131             .within(() => {
132                 cy.get('[data-cy=name-field]').within(() => {
133                     cy.get('input').type(projName);
134                 });
135             });
136         cy.get('[data-cy=form-submit-btn]').should('exist').click();
137         cy.waitForDom().get('[data-cy=form-dialog]').should('not.exist');
138
139         for (let i = 0; i < msButtonTooltips.length; i++) {
140             cy.get('[data-cy=multiselect-button]').eq(i).should('exist');
141             cy.get('[data-cy=multiselect-button]').eq(i).trigger('mouseover');
142             cy.waitForDom();
143             cy.get('body').within(() => {
144                 cy.contains(msButtonTooltips[i]).should('exist');
145             });
146             cy.get('[data-cy=multiselect-button]').eq(i).trigger('mouseout');
147         }
148     });
149
150     it('should toggle description display', () => {
151         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
152
153         //a single line description shouldn't change the height of the card
154         const projDescription = 'Science! True daughter of Old Time thou art! Who alterest all things with thy peering eyes.';
155         //a multi-line description should change the height of the card
156         const multiLineProjDescription = '{enter}Why preyest thou thus upon the poet’s heart,{enter}Vulture, whose wings are dull realities?';
157
158         cy.loginAs(adminUser);
159
160         // Create project
161         cy.get('[data-cy=side-panel-button]').click();
162         cy.get('[data-cy=side-panel-new-project]').click();
163         cy.get('[data-cy=form-dialog]')
164             .should('contain', 'New Project')
165             .within(() => {
166                 cy.get('[data-cy=name-field]').within(() => {
167                     cy.get('input').type(projName);
168                 });
169             });
170         cy.get('[data-cy=form-submit-btn]').click();
171
172         //check for no description
173         cy.get('[data-cy=no-description').should('be.visible');
174
175         //add description
176         cy.get('[data-cy=side-panel-tree]').contains('Home Projects').click();
177         cy.get('[data-cy=project-panel]').should('exist');
178         cy.get('[data-cy=project-panel] tbody tr').contains(projName).rightclick({ force: true });
179         cy.get('[data-cy=context-menu]').contains('Edit').click();
180         cy.get('[data-cy=form-dialog]').within(() => {
181             cy.get('div[contenteditable=true]').click().type(projDescription);
182             cy.get('[data-cy=form-submit-btn]').click();
183         });
184         cy.waitForDom();
185         cy.get('[data-cy=project-panel]').should('be.visible');
186         cy.get('[data-cy=project-panel]').should('exist');
187         cy.get('[data-cy=project-panel] tbody tr').contains(projName).click({ force: true });
188         cy.get('[data-cy=project-details-card]').contains(projName).should('be.visible');
189
190         cy.get('[data-cy=project-details-card]').contains(projDescription).should('not.be.visible');
191         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 80);
192         cy.get('[data-cy=toggle-description]').click();
193         cy.waitForDom();
194         cy.get('[data-cy=project-details-card]').contains(projDescription).should('be.visible');
195         cy.get('[data-cy=project-details-card]').invoke('height').should('be.gt', 80);
196
197         // modify description to be multi-line
198         cy.get('[data-cy=side-panel-tree]').contains('Home Projects').click();
199         cy.get('[data-cy=project-panel]').should('exist');
200         cy.get('[data-cy=project-panel] tbody tr').contains(projName).rightclick({ force: true });
201         cy.get('[data-cy=context-menu]').contains('Edit').click();
202         cy.get('[data-cy=form-dialog]').within(() => {
203             cy.get('div[contenteditable=true]').click().type(multiLineProjDescription);
204             cy.get('[data-cy=form-submit-btn]').click();
205         });
206         cy.get('[data-cy=project-panel]').should('exist');
207         cy.get('[data-cy=project-panel] tbody tr').contains(projName).click({ force: true });
208         cy.get('[data-cy=project-details-card]').contains(projName).should('be.visible');
209
210
211         // card height should change if description is multi-line
212         cy.get('[data-cy=project-details-card]').contains(projDescription).should('not.be.visible');
213         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 80);
214         cy.get('[data-cy=toggle-description]').click();
215         cy.waitForDom();
216         cy.get('[data-cy=project-details-card]').invoke('height').should('be.gt', 130);
217         cy.get('[data-cy=toggle-description]').click();
218         cy.waitForDom();
219         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 80);
220     });
221
222     // The following test is enabled on Electron only, as Chromium and Firefox
223     // require permissions to access the clipboard.
224     it('should display key/value pairs',  { browser: 'electron' }, () => {
225         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
226         cy.loginAs(adminUser);
227
228         // Create project wih key/value pairs
229         cy.get('[data-cy=side-panel-button]').click();
230         cy.get('[data-cy=side-panel-new-project]').click();
231         cy.get('[data-cy=form-dialog]')
232             .should('contain', 'New Project')
233             .within(() => {
234                 cy.get('[data-cy=name-field]').within(() => {
235                     cy.get('input').type(projName);
236                 });
237             });
238
239         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('Animal');
240         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('Dog');
241         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
242
243         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('Importance');
244         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('Critical');
245         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
246
247         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('very long key');
248         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('very loooooooooooooooooooooooooooooooooooooooooooooooooooooong value');
249         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
250
251         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('very long key 2');
252         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('very loooooooooooooooooooooooooooooooooooooooooooooooooooooong value 2');
253         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
254
255         cy.get('[data-cy=form-submit-btn]').click();
256
257         //toggle chips
258         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 95);
259         cy.get('[data-cy=toggle-description]').click();
260         cy.waitForDom();
261         cy.get('[data-cy=project-details-card]').invoke('height').should('be.gt', 96);
262         cy.get('[data-cy=toggle-description').click();
263         cy.waitForDom();
264         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 95);
265
266         //check for key/value pairs in project details card
267         // only run in electron because other browsers require permission for clipboard
268         if (Cypress.browser.name === 'electron') {
269             cy.get('[data-cy=toggle-description]').click();
270             cy.waitForDom();
271             cy.get('[data-cy=project-details-card]').contains('Animal').should('be.visible');
272             cy.get('[data-cy=project-details-card]').contains('Importance').should('be.visible').click();
273             cy.waitForDom();
274                 cy.window().then((win) => {
275                     win.navigator.clipboard.readText().then((text) => {
276                         //wait is necessary due to known issue with cypress@13.7.1
277                         cy.wait(1000);
278                         expect(text).to.match(new RegExp(`Importance: Critical`));
279                     });
280                 });
281         }
282     });
283 });