22208: Fix tests
[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 link to clipboard',
111             'Open with 3rd party client',
112             'API Details',
113             'Share',
114             'New project',
115             'Edit project',
116             'Move to',
117             'Move to trash',
118             'Freeze project',
119             'Add to favorites',
120         ];
121
122         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
123         cy.loginAs(activeUser);
124
125         // Create project
126         cy.get('[data-cy=side-panel-button]').click();
127         cy.get('[data-cy=side-panel-new-project]').click();
128         cy.get('[data-cy=form-dialog]')
129             .should('contain', 'New Project')
130             .within(() => {
131                 cy.get('[data-cy=name-field]').within(() => {
132                     cy.get('input').type(projName);
133                 });
134             });
135         cy.get('[data-cy=form-submit-btn]').should('exist').click();
136         cy.waitForDom().get('[data-cy=form-dialog]').should('not.exist');
137
138         for (let i = 0; i < msButtonTooltips.length; i++) {
139             cy.get('[data-cy=multiselect-button]').eq(i).should('exist');
140             cy.get('[data-cy=multiselect-button]').eq(i).trigger('mouseover');
141             cy.waitForDom();
142             cy.get('body').within(() => {
143                 cy.contains(msButtonTooltips[i]).should('exist');
144             });
145             cy.get('[data-cy=multiselect-button]').eq(i).trigger('mouseout');
146         }
147     });
148
149     it('should toggle description display', () => {
150         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
151
152         //a single line description shouldn't change the height of the card
153         const projDescription = 'Science! True daughter of Old Time thou art! Who alterest all things with thy peering eyes.';
154         //a multi-line description should change the height of the card
155         const multiLineProjDescription = '{enter}Why preyest thou thus upon the poet’s heart,{enter}Vulture, whose wings are dull realities?';
156
157         cy.loginAs(adminUser);
158
159         // Create project
160         cy.get('[data-cy=side-panel-button]').click();
161         cy.get('[data-cy=side-panel-new-project]').click();
162         cy.get('[data-cy=form-dialog]')
163             .should('contain', 'New Project')
164             .within(() => {
165                 cy.get('[data-cy=name-field]').within(() => {
166                     cy.get('input').type(projName);
167                 });
168             });
169         cy.get('[data-cy=form-submit-btn]').click();
170
171         //check for no description
172         cy.get('[data-cy=no-description').should('be.visible');
173
174         //add description
175         cy.get('[data-cy=side-panel-tree]').contains('Home Projects').click();
176         cy.get('[data-cy=project-panel] tbody tr').contains(projName).rightclick({ force: true });
177         cy.get('[data-cy=context-menu]').contains('Edit').click();
178         cy.get('[data-cy=form-dialog]').within(() => {
179             cy.get('div[contenteditable=true]').click().type(projDescription);
180             cy.get('[data-cy=form-submit-btn]').click();
181         });
182         cy.waitForDom();
183         cy.get('[data-cy=project-panel]').should('be.visible');
184         cy.get('[data-cy=project-panel] tbody tr').contains(projName).click({ force: true });
185         cy.get('[data-cy=project-details-card]').contains(projName).should('be.visible');
186
187         cy.get('[data-cy=project-details-card]').contains(projDescription).should('not.be.visible');
188         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 80);
189         cy.get('[data-cy=toggle-description]').click();
190         cy.waitForDom();
191         cy.get('[data-cy=project-details-card]').contains(projDescription).should('be.visible');
192         cy.get('[data-cy=project-details-card]').invoke('height').should('be.gt', 80);
193
194         // modify description to be multi-line
195         cy.get('[data-cy=side-panel-tree]').contains('Home Projects').click();
196         cy.get('[data-cy=project-panel] tbody tr').contains(projName).rightclick({ force: true });
197         cy.get('[data-cy=context-menu]').contains('Edit').click();
198         cy.get('[data-cy=form-dialog]').within(() => {
199             cy.get('div[contenteditable=true]').click().type(multiLineProjDescription);
200             cy.get('[data-cy=form-submit-btn]').click();
201         });
202         cy.get('[data-cy=project-panel] tbody tr').contains(projName).click({ force: true });
203         cy.get('[data-cy=project-details-card]').contains(projName).should('be.visible');
204
205         // card height should change if description is multi-line
206         cy.get('[data-cy=project-details-card]').contains(projDescription).should('not.be.visible');
207         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 80);
208         cy.get('[data-cy=toggle-description]').click();
209         cy.waitForDom();
210         cy.get('[data-cy=project-details-card]').invoke('height').should('be.gt', 130);
211         cy.get('[data-cy=toggle-description]').click();
212         cy.waitForDom();
213         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 80);
214     });
215
216     // The following test is enabled on Electron only, as Chromium and Firefox
217     // require permissions to access the clipboard.
218     it('should display key/value pairs',  { browser: 'electron' }, () => {
219         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
220         cy.loginAs(adminUser);
221
222         // Create project wih key/value pairs
223         cy.get('[data-cy=side-panel-button]').click();
224         cy.get('[data-cy=side-panel-new-project]').click();
225         cy.get('[data-cy=form-dialog]')
226             .should('contain', 'New Project')
227             .within(() => {
228                 cy.get('[data-cy=name-field]').within(() => {
229                     cy.get('input').type(projName);
230                 });
231             });
232
233         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('Animal');
234         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('Dog');
235         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
236
237         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('Importance');
238         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('Critical');
239         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
240
241         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('very long key');
242         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('very loooooooooooooooooooooooooooooooooooooooooooooooooooooong value');
243         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
244
245         cy.get('[data-cy=key-input]').should('be.visible').find('input').click().type('very long key 2');
246         cy.get('[data-cy=value-input]').should('be.visible').find('input').click().type('very loooooooooooooooooooooooooooooooooooooooooooooooooooooong value 2');
247         cy.get('[data-cy=property-add-btn]').should('be.visible').click();
248
249         cy.get('[data-cy=form-submit-btn]').click();
250
251         //toggle chips
252         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 95);
253         cy.get('[data-cy=toggle-chips]').click();
254         cy.waitForDom();
255         cy.get('[data-cy=project-details-card]').invoke('height').should('be.gt', 96);
256         cy.get('[data-cy=toggle-chips').click();
257         cy.waitForDom();
258         cy.get('[data-cy=project-details-card]').invoke('height').should('be.lt', 95);
259
260         //check for key/value pairs in project details card
261         // only run in electron because other browsers require permission for clipboard
262         if (Cypress.browser.name === 'electron') {
263             cy.get('[data-cy=project-details-card]').contains('Animal').should('be.visible');
264             cy.get('[data-cy=project-details-card]').contains('Importance').should('be.visible').click();
265             cy.waitForDom();
266                 cy.window().then((win) => {
267                     win.navigator.clipboard.readText().then((text) => {
268                         //wait is necessary due to known issue with cypress@13.7.1
269                         cy.wait(1000);
270                         expect(text).to.match(new RegExp(`Importance: Critical`));
271                     });
272                 });
273         }
274     });
275 });