fix(cypress): Replace flaky password-confirmation hack with conditional testing for the password modal

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
pull/40961/head
Ferdinand Thiessen 7 months ago
parent b6c35b3be0
commit add1d922ba
No known key found for this signature in database
GPG Key ID: 45FAE7268762B400

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/// <reference types="cypress-if" />
import { User } from '@nextcloud/cypress'
const admin = new User('admin', 'admin')
@ -37,7 +37,7 @@ describe('Settings: Create and delete users', function() {
cy.login(admin)
cy.listUsers().then((users) => {
cy.login(admin)
if (users.includes('john')) {
if ((users as string[]).includes('john')) {
// ensure created user is deleted
cy.deleteUser(john).login(admin)
// ensure deleted user is not present
@ -67,18 +67,8 @@ describe('Settings: Create and delete users', function() {
cy.get('button[type="submit"]').click()
})
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown on top of the New user modal
cy.get('body').find('.modal-container').then(($modals) => {
if ($modals.length > 1) {
cy.wrap($modals.first()).find('input[type="password"]').type(admin.password)
cy.wrap($modals.first()).find('button').contains('Confirm').click()
}
})
// Make sure no confirmation modal is shown
handlePasswordConfirmation(admin.password)
// see that the created user is in the list
cy.get('tbody.user-list__body tr[data-test="john"]').within(() => {
@ -112,18 +102,8 @@ describe('Settings: Create and delete users', function() {
cy.get('button[type="submit"]').click()
})
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown on top of the New user modal
cy.get('body').find('.modal-container').then(($modals) => {
if ($modals.length > 1) {
cy.wrap($modals.first()).find('input[type="password"]').type(admin.password)
cy.wrap($modals.first()).find('button').contains('Confirm').click()
}
})
// Make sure no confirmation modal is shown
handlePasswordConfirmation(admin.password)
// see that the created user is in the list
cy.get('tbody.user-list__body tr[data-test="john"]').within(() => {
@ -151,18 +131,8 @@ describe('Settings: Create and delete users', function() {
// And confirmation dialog accepted
cy.get('.oc-dialog button').contains(`Delete ${jdoe.userId}`).click()
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown
cy.get('body').find('.modal-container').then(($modal) => {
if ($modal.length > 0) {
cy.wrap($modal).find('input[type="password"]').type(admin.password)
cy.wrap($modal).find('button').contains('Confirm').click()
}
})
handlePasswordConfirmation(admin.password)
// deleted clicked the user is not shown anymore
cy.get(`tbody.user-list__body tr[data-test="${jdoe.userId}"]`).should('not.exist')

@ -31,3 +31,27 @@ export function assertNotExistOrNotVisible(element: JQuery<HTMLElement>) {
expect(doesNotExist || isNotVisible, 'does not exist or is not visible').to.be.true
}
/**
* Handle the confirm password dialog (if needed)
* @param adminPassword The admin password for the dialog
*/
export function handlePasswordConfirmation(adminPassword = 'admin') {
const handleModal = (context: Cypress.Chainable) => {
return context.contains('.modal-container', 'Confirm your password')
.if()
.if('visible')
.within(() => {
cy.get('input[type="password"]').type(adminPassword)
cy.get('button').contains('Confirm').click()
})
}
return cy.get('body')
.if()
.then(() => handleModal(cy.get('body')))
.else()
// Handle if inside a cy.within
.root().closest('body')
.then(($body) => handleModal(cy.wrap($body)))
}

@ -21,6 +21,7 @@
*/
import { User } from '@nextcloud/cypress'
import { handlePasswordConfirmation } from './usersUtils'
const admin = new User('admin', 'admin')
@ -46,18 +47,8 @@ describe('Settings: Create and delete groups', () => {
cy.get('input[placeholder="Group name"] ~ button').click()
})
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown
cy.get('body').find('.modal-container').then(($modals) => {
if ($modals.length > 0) {
cy.wrap($modals.first()).find('input[type="password"]').type(admin.password)
cy.wrap($modals.first()).find('button').contains('Confirm').click()
}
})
handlePasswordConfirmation(admin.password)
// see that the created group is in the list
cy.get('ul.app-navigation__list').within(() => {
@ -82,18 +73,13 @@ describe('Settings: Create and delete groups', () => {
// And confirmation dialog accepted
cy.get('.modal-container button').contains('Confirm').click()
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown on top of the Remove group modal
cy.get('body').find('.modal-container').then(($modals) => {
if ($modals.length > 1) {
cy.wrap($modals.first()).find('input[type="password"]').type(admin.password)
cy.wrap($modals.first()).find('button').contains('Confirm').click()
}
})
// Make sure no confirmation modal is shown
cy.get('body').contains('.modal-container', 'Confirm your password')
.if('visible')
.then(($modal) => {
cy.wrap($modal).find('input[type="password"]').type(admin.password)
cy.wrap($modal).find('button').contains('Confirm').click()
})
// deleted group is not shown anymore
cy.get('ul.app-navigation__list').within(() => {

@ -66,18 +66,8 @@ describe('Settings: Change user properties', function() {
cy.get('input[data-test="displayNameField"]').should('have.value', 'John Doe')
cy.get('input[data-test="displayNameField"] ~ button').click()
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown
cy.root().closest('body').find('.modal-container').then(($modal) => {
if ($modal.length > 0) {
cy.wrap($modal).find('input[type="password"]').type(admin.password)
cy.wrap($modal).find('button').contains('Confirm').click()
}
})
handlePasswordConfirmation(admin.password)
// see that the display name cell is done loading
cy.get('.user-row-text-field.icon-loading-small').should('exist')
@ -104,18 +94,8 @@ describe('Settings: Change user properties', function() {
cy.get('input[type="password"]').should('have.value', '123456')
cy.get('input[type="password"] ~ button').click()
// Ignore failure if modal is not shown
cy.once('fail', (error) => {
expect(error.name).to.equal('AssertionError')
expect(error).to.have.property('node', '.modal-container')
})
// Make sure no confirmation modal is shown
cy.root().closest('body').find('.modal-container').then(($modal) => {
if ($modal.length > 0) {
cy.wrap($modal).find('input[type="password"]').type(admin.password)
cy.wrap($modal).find('button').contains('Confirm').click()
}
})
handlePasswordConfirmation(admin.password)
// see that the password cell for user user0 is done loading
cy.get('.user-row-text-field.icon-loading-small').should('exist')

@ -25,6 +25,7 @@ import { addCommands, User } from '@nextcloud/cypress'
import { basename } from 'path'
// Add custom commands
import 'cypress-if'
import 'cypress-wait-until'
addCommands()

10
package-lock.json generated

@ -114,6 +114,7 @@
"babel-loader-exclude-node-modules-except": "^1.2.1",
"css-loader": "^6.8.1",
"cypress": "^13.3.0",
"cypress-if": "^1.10.5",
"cypress-wait-until": "^2.0.1",
"dockerode": "^4.0.0",
"eslint-plugin-cypress": "^2.14.0",
@ -9729,6 +9730,15 @@
"node": "^16.0.0 || ^18.0.0 || >=20.0.0"
}
},
"node_modules/cypress-if": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/cypress-if/-/cypress-if-1.10.5.tgz",
"integrity": "sha512-7EJSTvoUM+6XumIA7T0cU69dkkdUEmncvIuFFgQ3ry57m2kXc9vtNTCdGjfnGQgMBDRR6vtx7no1ZDDg8IOICA==",
"dev": true,
"dependencies": {
"debug": "^4.3.4"
}
},
"node_modules/cypress-wait-until": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.1.tgz",

@ -141,6 +141,7 @@
"babel-loader-exclude-node-modules-except": "^1.2.1",
"css-loader": "^6.8.1",
"cypress": "^13.3.0",
"cypress-if": "^1.10.5",
"cypress-wait-until": "^2.0.1",
"dockerode": "^4.0.0",
"eslint-plugin-cypress": "^2.14.0",

Loading…
Cancel
Save