20251: Fix flaky collection file browser by using race-free state update callback
[arvados-workbench2.git] / cypress / integration / virtual-machine-admin.spec.js
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 describe('Virtual machine login manage tests', function() {
6     let activeUser;
7     let adminUser;
8
9     const vmHost = `vm-${Math.floor(999999 * Math.random())}.host`;
10
11     before(function() {
12         // Only set up common users once. These aren't set up as aliases because
13         // aliases are cleaned up after every test. Also it doesn't make sense
14         // to set the same users on beforeEach() over and over again, so we
15         // separate a little from Cypress' 'Best Practices' here.
16         cy.getUser('admin', 'VMAdmin', 'User', true, true)
17             .as('adminUser').then(function() {
18                 adminUser = this.adminUser;
19             }
20         );
21         cy.getUser('user', 'VMActive', 'User', false, true)
22             .as('activeUser').then(function() {
23                 activeUser = this.activeUser;
24             }
25         );
26     });
27
28     it('adds and removes vm logins', function() {
29         cy.loginAs(adminUser);
30         cy.createVirtualMachine(adminUser.token, {hostname: vmHost});
31
32         // Navigate to VM admin
33         cy.get('header button[title="Admin Panel"]').click();
34         cy.get('#admin-menu').contains('Virtual Machines').click();
35
36         // Add login permission to admin
37         cy.get('[data-cy=vm-admin-table]')
38             .contains(vmHost)
39             .parents('tr')
40             .within(() => {
41                 cy.get('button[title="Add Login Permission"]').click();
42             });
43         cy.get('[data-cy=form-dialog]')
44             .should('contain', 'Add login permission')
45             .within(() => {
46                 cy.get('label')
47                   .contains('Search for user')
48                   .parent()
49                   .within(() => {
50                     cy.get('input').type('VMAdmin');
51                   })
52             });
53         cy.get('[role=tooltip]').click();
54         cy.get('[data-cy=form-dialog]').as('add-login-dialog')
55             .should('contain', 'Add login permission')
56             .within(() => {
57                 cy.get('label')
58                   .contains('Add groups')
59                   .parent()
60                   .within(() => {
61                     cy.get('input').type('docker ');
62                     // Veryfy submit enabled (form has changed)
63                     cy.get('@add-login-dialog').within(() => {
64                         cy.get('[data-cy=form-submit-btn]').should('be.enabled');
65                     });
66                     cy.get('input').type('sudo');
67                     // Veryfy submit disabled (partial input in chips)
68                     cy.get('@add-login-dialog').within(() => {
69                         cy.get('[data-cy=form-submit-btn]').should('be.disabled');
70                     });
71                     cy.get('input').type('{enter}');
72                   })
73             });
74         cy.get('[data-cy=form-dialog]').within(() => {
75             cy.get('[data-cy=form-submit-btn]').click();
76         });
77
78         cy.get('[data-cy=vm-admin-table]')
79             .contains(vmHost)
80             .parents('tr')
81             .within(() => {
82                 cy.get('td').contains('admin');
83         });
84
85         // Add login permission to activeUser
86         cy.get('[data-cy=vm-admin-table]')
87             .contains(vmHost)
88             .parents('tr')
89             .within(() => {
90                 cy.get('button[title="Add Login Permission"]').click();
91             });
92         cy.get('[data-cy=form-dialog]')
93             .should('contain', 'Add login permission')
94             .within(() => {
95                 cy.get('label')
96                   .contains('Search for user')
97                   .parent()
98                   .within(() => {
99                     cy.get('input').type('VMActive user');
100                   })
101             });
102         cy.get('[role=tooltip]').click();
103         cy.get('[data-cy=form-dialog]').within(() => {
104             cy.get('[data-cy=form-submit-btn]').click();
105         });
106
107         cy.get('[data-cy=vm-admin-table]')
108             .contains(vmHost)
109             .parents('tr')
110             .within(() => {
111                 cy.get('td').contains('user');
112         });
113
114         // Check admin's vm page for login
115         cy.get('header button[title="Account Management"]').click();
116         cy.get('#account-menu').contains('Virtual Machines').click();
117
118         cy.get('[data-cy=vm-user-table]')
119             .contains(vmHost)
120             .parents('tr')
121             .within(() => {
122                 cy.get('td').contains('admin');
123                 cy.get('td').contains('docker');
124                 cy.get('td').contains('sudo');
125                 cy.get('td').contains('ssh admin@' + vmHost);
126         });
127
128         // Check activeUser's vm page for login
129         cy.loginAs(activeUser);
130         cy.get('header button[title="Account Management"]').click();
131         cy.get('#account-menu').contains('Virtual Machines').click();
132
133         cy.get('[data-cy=vm-user-table]')
134             .contains(vmHost)
135             .parents('tr')
136             .within(() => {
137                 cy.get('td').contains('user');
138                 cy.get('td').should('not.contain', 'docker');
139                 cy.get('td').should('not.contain', 'sudo');
140                 cy.get('td').contains('ssh user@' + vmHost);
141         });
142
143         // Edit login permissions
144         cy.loginAs(adminUser);
145         cy.get('header button[title="Admin Panel"]').click();
146         cy.get('#admin-menu').contains('Virtual Machines').click();
147
148         cy.get('[data-cy=vm-admin-table]')
149             .contains('admin'); // Wait for page to finish
150
151         cy.get('[data-cy=vm-admin-table]')
152             .contains(vmHost)
153             .parents('tr')
154             .contains('admin')
155             .click();
156
157         cy.get('[data-cy=form-dialog]')
158             .should('contain', 'Update login permission')
159             .within(() => {
160                 cy.get('label')
161                     .contains('Add groups')
162                     .parent()
163                     .as('groupInput');
164             });
165
166         cy.get('@groupInput').within(() => {
167             cy.get('div[role=button]').contains('sudo').parent().find('svg').click();
168             cy.get('div[role=button]').contains('docker').parent().find('svg').click();
169         });
170
171         cy.get('[data-cy=form-dialog]').within(() => {
172             cy.get('[data-cy=form-submit-btn]').click();
173         });
174
175         // Wait for page to finish loading
176         cy.get('[data-cy=vm-admin-table]')
177             .contains(vmHost)
178             .parents('tr')
179             .within(() => {
180                 cy.get('div[role=button]')
181                     .parent()
182                     .first()
183                     .contains('admin')
184             });
185
186         cy.get('[data-cy=vm-admin-table]')
187             .contains(vmHost)
188             .parents('tr')
189             .contains('user')
190             .click();
191
192         cy.get('[data-cy=form-dialog]')
193             .should('contain', 'Update login permission')
194             .within(() => {
195                 cy.get('label')
196                     .contains('Add groups')
197                     .parent()
198                     .within(() => {
199                         cy.get('input').type('docker{enter}');
200                     })
201             });
202
203         cy.get('[data-cy=form-dialog]').within(() => {
204             cy.get('[data-cy=form-submit-btn]').click();
205         });
206
207         // Verify new login permissions
208         // Check admin's vm page for login
209         cy.get('header button[title="Account Management"]').click();
210         cy.get('#account-menu').contains('Virtual Machines').click();
211
212         cy.get('[data-cy=vm-user-table]')
213             .contains(vmHost)
214             .parents('tr')
215             .within(() => {
216                 cy.get('td').contains('admin');
217                 cy.get('td').should('not.contain', 'docker');
218                 cy.get('td').should('not.contain', 'sudo');
219                 cy.get('td').contains('ssh admin@' + vmHost);
220         });
221
222         // Verify new login permissions
223         // Check activeUser's vm page for login
224         cy.loginAs(activeUser);
225         cy.get('header button[title="Account Management"]').click();
226         cy.get('#account-menu').contains('Virtual Machines').click();
227
228         cy.get('[data-cy=vm-user-table]')
229             .contains(vmHost)
230             .parents('tr')
231             .within(() => {
232                 cy.get('td').contains('user');
233                 cy.get('td').contains('docker');
234                 cy.get('td').should('not.contain', 'sudo');
235                 cy.get('td').contains('ssh user@' + vmHost);
236         });
237
238         // Remove login permissions
239         cy.loginAs(adminUser);
240         cy.get('header button[title="Admin Panel"]').click();
241         cy.get('#admin-menu').contains('Virtual Machines').click();
242
243         cy.get('[data-cy=vm-admin-table]')
244             .contains('user'); // Wait for page to finish
245
246         cy.get('[data-cy=vm-admin-table]')
247             .contains(vmHost)
248             .parents('tr')
249             .as('vmRow')
250             .contains('user')
251             .parents('[role=button]')
252             .find('svg')
253             .as('removeButton');
254         cy.get('@removeButton').click();
255         cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
256
257         cy.get('@vmRow')
258             .within(() => {
259                 cy.get('div[role=button]').should('not.contain', 'user');
260                 cy.get('div[role=button]').should('have.length', 1)
261             });
262
263         cy.get('@vmRow')
264             .find('div[role=button]')
265             .contains('admin')
266             .parents('[role=button]')
267             .find('svg')
268             .as('removeButton');
269         cy.get('@removeButton').click();
270         cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
271
272         cy.get('[data-cy=vm-admin-table]')
273             .contains(vmHost)
274             .parents('tr')
275             .within(() => {
276                 cy.get('div[role=button]').should('not.contain', 'admin');
277             });
278
279         // Check admin's vm page for login
280         cy.get('header button[title="Account Management"]').click();
281         cy.get('#account-menu').contains('Virtual Machines').click();
282
283         cy.get('[data-cy=vm-user-panel]')
284             .should('not.contain', vmHost);
285
286         // Check activeUser's vm page for login
287         cy.loginAs(activeUser);
288         cy.get('header button[title="Account Management"]').click();
289         cy.get('#account-menu').contains('Virtual Machines').click();
290
291         cy.get('[data-cy=vm-user-panel]')
292             .should('not.contain', vmHost);
293     });
294 });