diff options
author | Louis Chemineau <louis@chmn.me> | 2023-01-04 15:36:33 +0100 |
---|---|---|
committer | Louis Chemineau <louis@chmn.me> | 2023-01-04 17:54:47 +0100 |
commit | 74308c64ffc3bfc58d5172abb32c66a5a6e40b8a (patch) | |
tree | 0f6130fb1d07215d5728e6a9bccd95dab77753c6 /cypress | |
parent | df8d5fdad4d9493186e485660558ef2cfbefa8d6 (diff) |
Fix cypress workflow
Signed-off-by: Louis Chemineau <louis@chmn.me>
Diffstat (limited to 'cypress')
-rw-r--r-- | cypress/docker-compose.yml | 10 | ||||
-rw-r--r-- | cypress/e2e/0.setup.cy.js (renamed from cypress/integration/0.setup.spec.js) | 8 | ||||
-rw-r--r-- | cypress/e2e/post.cy.js (renamed from cypress/integration/post.spec.js) | 30 | ||||
-rwxr-xr-x | cypress/initserver.sh | 2 | ||||
-rw-r--r-- | cypress/plugins/index.js | 20 | ||||
-rwxr-xr-x | cypress/start.sh | 15 | ||||
-rw-r--r-- | cypress/support/commands.js | 60 | ||||
-rw-r--r-- | cypress/support/e2e.js (renamed from cypress/support/index.js) | 7 |
8 files changed, 61 insertions, 91 deletions
diff --git a/cypress/docker-compose.yml b/cypress/docker-compose.yml index 59712508..d5a466ba 100644 --- a/cypress/docker-compose.yml +++ b/cypress/docker-compose.yml @@ -1,16 +1,18 @@ -version: '3' +version: '3.7' services: nextcloud: - image: nextcloudci/server + image: ghcr.io/nextcloud/continuous-integration-shallow-server ports: - 8082:80 environment: CYPRESS_baseUrl: "http://127.0.0.1:8082/index.php" - BRANCH: master + BRANCH: "${BRANCH:-master}" volumes: - - ../:/var/www/html/apps/social + # Using fallback to make sure this script doesn't mess + # with the mounting if APP_NAME is not provided. + - ../:/var/www/html/apps/${APP_NAME:-social} - ./initserver.sh:/initserver.sh diff --git a/cypress/integration/0.setup.spec.js b/cypress/e2e/0.setup.cy.js index 7c05bebb..2ad54887 100644 --- a/cypress/integration/0.setup.spec.js +++ b/cypress/e2e/0.setup.cy.js @@ -1,4 +1,4 @@ -let userId = 'janedoe' + Date.now(); +const userId = 'janedoe' + Date.now() describe('Social app setup', function() { before(function() { @@ -6,10 +6,6 @@ describe('Social app setup', function() { cy.login(userId, 'p4ssw0rd') }) - beforeEach(() => { - Cypress.Cookies.preserveOnce('nc_username', 'nc_token', 'nc_session_id', 'oc_sessionPassphrase'); - }) - it('See the welcome message', function() { cy.visit('/apps/social/') cy.get('.social__welcome').should('contain', 'Nextcloud becomes part of the federated social networks!') @@ -26,7 +22,7 @@ describe('Social app setup', function() { cy.get('.app-navigation').contains('Direct messages').click() cy.get('.emptycontent').should('be.visible').contains('No direct messages found') cy.get('.app-navigation').contains('Profile').click() - cy.get('.emptycontent').should('be.visible').contains('You haven\'t tooted yet') + cy.get('.emptycontent').should('be.visible').contains('You have not tooted yet') }) }) diff --git a/cypress/integration/post.spec.js b/cypress/e2e/post.cy.js index 10216eb7..27292b50 100644 --- a/cypress/integration/post.spec.js +++ b/cypress/e2e/post.cy.js @@ -20,15 +20,17 @@ * */ -let userId = 'janedoe' + Date.now(); +const userId = 'janedoe' + Date.now() describe('Create posts', function() { before(function() { // ensure that the admin account is initialized for social cy.login('admin', 'admin', '/apps/social/') - + cy.nextcloudCreateUser(userId, 'p4ssw0rd') + cy.logout() + cy.login(userId, 'p4ssw0rd', '/apps/social/') cy.get('.app-content').should('be.visible') }) @@ -37,10 +39,6 @@ describe('Create posts', function() { cy.screenshot() }) - beforeEach(() => { - Cypress.Cookies.preserveOnce('nc_username', 'nc_token', 'nc_session_id', 'oc_sessionPassphrase'); - }) - it('See the empty content illustration', function() { cy.get('.emptycontent').should('be.visible').contains('No posts found') }) @@ -49,19 +47,19 @@ describe('Create posts', function() { cy.visit('/apps/social/') cy.server() cy.route('POST', '/index.php/apps/social/api/v1/post').as('postMessage') - cy.get('.new-post input[type=submit]') + cy.get('.new-post button[type=submit]') .should('be.disabled') cy.get('.new-post').find('[contenteditable]').type('Hello world') - cy.get('.new-post input[type=submit]') + cy.get('.new-post button[type=submit]') .should('not.be.disabled') - cy.get('.new-post input[type=submit]') + cy.get('.new-post button[type=submit]') .click() cy.wait('@postMessage') cy.get('.social__timeline div.timeline-entry:first-child').should('contain', 'Hello world') }) it('No longer see the empty content illustration', function() { - cy.get('.emptycontent').should('not.be.visible') + cy.get('.emptycontent').should('not.exist') }) it('Write a post to followers with shift enter', function() { @@ -78,11 +76,11 @@ describe('Create posts', function() { cy.server() cy.route('POST', '/index.php/apps/social/api/v1/post').as('postMessage') cy.route('GET', '/index.php/apps/social/api/v1/global/accounts/search') - cy.get('.new-post').find('[contenteditable]').type('@adm', {delay: 500}) + cy.get('.new-post').find('[contenteditable]').type('@adm', { delay: 500 }) cy.get('.tribute-container').should('be.visible') cy.get('.tribute-container ul li:first').contains('admin') - cy.get('.new-post').find('[contenteditable]').type('{enter} Hello there', {delay: 100, force: true}) - cy.get('.new-post input[type=submit]') + cy.get('.new-post').find('[contenteditable]').type('{enter} Hello there', { delay: 100, force: true }) + cy.get('.new-post button[type=submit]') .click() cy.wait('@postMessage') cy.get('.social__timeline div.timeline-entry:first-child').should('contain', '@admin') @@ -93,9 +91,9 @@ describe('Create posts', function() { cy.server() cy.route('POST', '/index.php/apps/social/api/v1/post').as('postMessage') cy.route('GET', '/index.php/apps/social/api/v1/global/accounts/search') - cy.get('.new-post').find('[contenteditable]').click({force: true}).type('@adm{enter} Hello world', {delay: 500, force: true}) + cy.get('.new-post').find('[contenteditable]').click({ force: true }).type('@adm{enter} Hello world', { delay: 500, force: true }) cy.wait(500) - cy.get('.new-post input[type=submit]').should('not.be.disabled') + cy.get('.new-post button[type=submit]').should('not.be.disabled') const visibilityButton = cy.get('.new-post .options > div > button') visibilityButton.should('have.class', 'icon-contacts-dark') @@ -105,7 +103,7 @@ describe('Create posts', function() { visibilityButton.click() cy.get('.new-post-form .popovermenu').should('not.be.visible') - cy.get('.new-post input[type=submit]') + cy.get('.new-post button[type=submit]') .click() cy.wait('@postMessage') cy.get('.social__timeline div.timeline-entry:first-child').should('contain', 'Hello world').should('contain', '@admin') diff --git a/cypress/initserver.sh b/cypress/initserver.sh index 4d997b58..3921fd48 100755 --- a/cypress/initserver.sh +++ b/cypress/initserver.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash echo "APP_NAME: $APP_NAME" +echo "BRANCH: $BRANCH" + chown -R www-data:www-data /var/www/html/data su www-data -c " diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index e1d51dd1..00000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -const { - addMatchImageSnapshotPlugin -} = require('cypress-image-snapshot/plugin') - -module.exports = (on, config) => { - addMatchImageSnapshotPlugin(on, config) -} diff --git a/cypress/start.sh b/cypress/start.sh index b55fef2b..dc97d6a5 100755 --- a/cypress/start.sh +++ b/cypress/start.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # RUN THIS SCRIPT FROM THE ROOT FOLDER OF YOUR APP APP_NAME=${PWD##*/} +CYPRESS_baseUrl=http://127.0.0.1:8082/index.php if [[ $APP_NAME == "cypress" ]] then @@ -8,13 +9,11 @@ then else echo "Launching docker server for the $APP_NAME app" cd cypress - docker-compose up -d - echo -n "Waiting for server start " - until [[ $(docker-compose exec -u www-data -T nextcloud php ./occ status --output=json) == *"\"installed\":true"* ]] - do - echo -n "." - done - echo "" + docker-compose pull + docker-compose up -d --force-recreate + npm run wait-on $CYPRESS_baseUrl + echo "Nextcloud successfully installed" docker-compose exec --env APP_NAME=$APP_NAME -T nextcloud bash /initserver.sh - docker-compose exec -u www-data -T nextcloud php ./occ social:reset -n + docker-compose exec -u www-data -T nextcloud php ./occ social:reset -n + echo "Nextcloud successfully configured" fi diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 7b65139a..e9177ca4 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -20,37 +20,45 @@ * */ -import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command' import axios from '@nextcloud/axios' -addMatchImageSnapshotCommand() - const url = Cypress.config('baseUrl').replace(/\/index.php\/?$/g, '') Cypress.env('baseUrl', url) Cypress.Commands.add('login', (user, password, route = '/apps/files') => { - cy.clearCookies(); + Cypress.Cookies.defaults({ + preserve: /^(oc|nc)/, + }) cy.visit(route) cy.get('input[name=user]').type(user) cy.get('input[name=password]').type(password) - cy.get('#submit-wrapper input[type=submit]').click() + cy.get('form[name=login] [type=submit]').click() cy.url().should('include', route) }) Cypress.Commands.add('logout', () => { - if (Cypress.$("input[name=user]").length > 0) { - // already logged out - } else { - cy.get('#expanddiv li[data-id="logout"] a').then(logout => { - if (logout) { - cy.visit(logout[0].href) + cy.getCookies() + .then(cookies => { + if (cookies.length === 0) { + cy.log('Not logged, skipping logout...') + return } + + return cy.get('body') + .then($body => { + const $settingsButton = $body.find('#settings #expand') + if ($settingsButton.length === 0) { + cy.log('Not logged in.') + return + } + + $settingsButton.click() + cy.contains('Log out').click() + }) }) - } }) Cypress.Commands.add('nextcloudCreateUser', (user, password) => { - cy.clearCookies(); cy.request({ method: 'POST', url: `${Cypress.env('baseUrl')}/ocs/v1.php/cloud/users?format=json`, @@ -61,13 +69,12 @@ Cypress.Commands.add('nextcloudCreateUser', (user, password) => { }, auth: { user: 'admin', pass: 'admin' }, headers: { - 'OCS-ApiRequest': 'true', 'Content-Type': 'application/x-www-form-urlencoded', - Authorization: `Basic ${btoa('admin:admin')}`, + 'OCS-ApiRequest': 'true', + Authorization: `Basic ${Buffer.from('admin:admin').toString('base64')}`, }, - }).then(response => { - cy.log(`Created user ${user}`, response.status) }) + cy.clearCookies() }) Cypress.Commands.add('uploadFile', (fileName, mimeType, path = '') => { @@ -82,7 +89,7 @@ Cypress.Commands.add('uploadFile', (fileName, mimeType, path = '') => { headers: { requesttoken: window.OC.requestToken, 'Content-Type': mimeType, - } + }, }).then(response => { cy.log(`Uploaded ${fileName}`, response) }) @@ -122,7 +129,7 @@ Cypress.Commands.add('deleteFile', fileName => { * Create a share link and return the share url * * @param {string} path the file/folder path - * @returns {string} the share link url + * @return {string} the share link url */ Cypress.Commands.add('createLinkShare', path => { return cy.window().then(async window => { @@ -133,26 +140,15 @@ Cypress.Commands.add('createLinkShare', path => { }, { headers: { requesttoken: window.OC.requestToken, - } + }, }) if (!('ocs' in request.data) || !('token' in request.data.ocs.data && request.data.ocs.data.token.length > 0)) { throw request } cy.log('Share link created', request.data.ocs.data.token) return cy.wrap(request.data.ocs.data.token) - } catch(error) { + } catch (error) { console.error(error) } }).should('have.length', 15) }) - -Cypress.Commands.overwrite('matchImageSnapshot', (originalFn, subject, name, options) => { - // hide avatar because random colour break the visual regression tests - cy.window().then(window => { - const avatarDiv = window.document.querySelector('.avatardiv') - if (avatarDiv) { - avatarDiv.remove() - } - }) - return originalFn(subject, name, options) -}) diff --git a/cypress/support/index.js b/cypress/support/e2e.js index d68db96d..8d34bd6e 100644 --- a/cypress/support/index.js +++ b/cypress/support/e2e.js @@ -1,5 +1,5 @@ // *********************************************************** -// This example support/index.js is processed and +// This example support/e2e.js is processed and // loaded automatically before your test files. // // This is a great place to put global configuration and @@ -14,7 +14,4 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') +import './commands.js' |