Skip to content

Commit

Permalink
Merge pull request #169 from nextcloud/tests/setup-cypress
Browse files Browse the repository at this point in the history
Tests/setup cypress
  • Loading branch information
Florian authored Dec 12, 2023
2 parents bf6786f + 0b051c8 commit 835c46f
Show file tree
Hide file tree
Showing 8 changed files with 1,903 additions and 95 deletions.
164 changes: 164 additions & 0 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
name: Cypress

on:
pull_request:
push:
branches:
- main
- master
- stable*

concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true

env:
APP_NAME: health
CYPRESS_baseUrl: http://127.0.0.1:8081/index.php

jobs:
cypress:
runs-on: ubuntu-22.04

strategy:
fail-fast: false
matrix:
node-version: [ 16 ]
databases: [ 'mysql' ]
server-versions: [ 'stable25', 'stable27', 'master' ]
include:
- php-versions: 8.1

services:
mysql:
image: ghcr.io/nextcloud/continuous-integration-mariadb-10.6:latest
ports:
- 4444:3306/tcp
env:
MYSQL_ROOT_PASSWORD: rootpassword
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 5

steps:

- name: Checkout server
uses: actions/checkout@v3
with:
repository: nextcloud/server
ref: ${{ matrix.server-versions }}

- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Checkout viewer
uses: actions/checkout@v3
with:
repository: nextcloud/viewer
ref: ${{ matrix.server-versions }}
path: apps/viewer

- name: Register text Git reference
run: |
text_app_ref="$(if [ "${{ matrix.server-versions }}" = "master" ]; then echo -n "main"; else echo -n "${{ matrix.server-versions }}"; fi)"
echo "text_app_ref=$text_app_ref" >> $GITHUB_ENV
- name: Checkout text app
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
with:
repository: nextcloud/text
path: apps/text
ref: ${{ env.text_app_ref }}

- name: Checkout app
uses: actions/checkout@v3
with:
path: apps/${{ env.APP_NAME }}

- name: Set up node 16
uses: actions/setup-node@v3
with:
cache: 'npm'
cache-dependency-path: apps/${{ env.APP_NAME}}/package-lock.json
node-version: 16

- name: Install dependencies & build app
working-directory: apps/${{ env.APP_NAME }}
run: |
npm ci
TESTING=true npm run build --if-present
composer i --no-dev
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, zip, zlib, sqlite, pdo_sqlite, apcu, pgsql, pdo_pgsql,mysql, pdo_mysql
ini-values:
apc.enable_cli=on
coverage: none

- name: Set up Nextcloud
env:
DB_PORT: 4444
PHP_CLI_SERVER_WORKERS: 20
run: |
mkdir data
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
./occ config:system:set hashing_default_password --value=true --type=boolean
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
cat config/config.php
./occ user:list
./occ app:enable --force text
./occ app:enable --force ${{ env.APP_NAME }}
./occ config:system:set query_log_file --value '/home/runner/work/${{ env.APP_NAME }}/${{ env.APP_NAME }}/query.log'
php -S 127.0.0.1:8081 > /tmp/requestlog 2>&1 &
export OC_PASS=1234561
php occ user:add --password-from-env user1
php occ user:add --password-from-env user2
curl -v http://127.0.0.1:8081/index.php/login
cat data/nextcloud.log
- name: Cypress run
uses: cypress-io/github-action@v4
with:
wait-on: '${{ env.CYPRESS_baseUrl }}'
working-directory: 'apps/${{ env.APP_NAME }}'
config: defaultCommandTimeout=10000,video=false
env:
# https://github.com/cypress-io/github-action/issues/124
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }}
COMMIT_INFO_SHA: ${{ github.event.pull_request.head.sha }}
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
npm_package_name: ${{ env.APP_NAME }}

- name: Print logs
if: always()
run: |
cat /tmp/requestlog
cat data/nextcloud.log
- name: Upload test failure screenshots
uses: actions/upload-artifact@v2
if: failure()
with:
name: Upload screenshots
path: apps/${{ env.APP_NAME }}/cypress/screenshots/
retention-days: 5

- name: Upload nextcloud logs
uses: actions/upload-artifact@v2
if: failure()
with:
name: Upload nextcloud log
path: data/nextcloud.log
retention-days: 5
12 changes: 12 additions & 0 deletions cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { defineConfig } = require('cypress')

module.exports = defineConfig({
projectId: 'ixbf9n',
e2e: {
baseUrl: 'http://nextcloud.local/index.php/',
setupNodeEvents(on, config) {
// implement node event listeners here
},
pageLoadTimeout: 120000,
},
})
19 changes: 19 additions & 0 deletions cypress/e2e/health.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
let localUser

describe('The Home Page', () => {

before(function() {
cy.createRandomUser().then(user => {
localUser = user
})
})

beforeEach(function() {
cy.login(localUser)
cy.visit('apps/health')
})

it('successfully loads', () => {
cy.get('h2').contains('Welcome to your health center').should('be.visible')
})
})
4 changes: 4 additions & 0 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const { downloadFile } = require('cypress-downloadfile/lib/addPlugin')
module.exports = (on, config) => {
on('task', { downloadFile })
}
104 changes: 104 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
import { addCommands } from '@nextcloud/cypress'
require('cypress-downloadfile/lib/downloadFileCommand')

const url = Cypress.config('baseUrl').replace(/\/index.php\/?$/g, '')
Cypress.env('baseUrl', url)

addCommands()

Cypress.Commands.add('uploadFile', (fileName, mimeType, target) => {
return cy.fixture(fileName, 'binary')
.then(Cypress.Blob.binaryStringToBlob)
.then(blob => {
if (typeof target !== 'undefined') {
fileName = target
}
cy.request('/csrftoken')
.then(({ body }) => {
return cy.wrap(body.token)
})
.then(async (requesttoken) => {
return cy.request({
url: `${url}/remote.php/webdav/${fileName}`,
method: 'put',
body: blob.size > 0 ? blob : '',
// auth,
headers: {
requesttoken,
'Content-Type': mimeType,
},
})
}).then(response => {
const fileId = Number(
response.headers['oc-fileid']?.split('oc')?.[0],
)
cy.log(`Uploaded ${fileName}`,
response.status,
{ fileId },
)
return cy.wrap(fileId)
})
})
})

Cypress.Commands.add('ocsRequest', (user, options) => {
const auth = { user: user.userId, password: user.password }
return cy.request({
form: true,
auth,
headers: {
'OCS-ApiRequest': 'true',
'Content-Type': 'application/x-www-form-urlencoded',
},
...options,
})
})
Cypress.Commands.add('createGroup', (groupName) => {
cy.ocsRequest({ userId: 'admin', password: 'admin' }, {
method: 'POST',
url: `${url}/ocs/v2.php/cloud/groups`,
body: {
groupid: groupName,
displayname: groupName,
},
}).then(response => {
cy.log(`Group ${groupName} created.`, response.status)
})
})

Cypress.Commands.add('addUserToGroup', (userId, groupId) => {
cy.ocsRequest({ userId: 'admin', password: 'admin' }, {
method: 'POST',
url: `${url}/ocs/v2.php/cloud/users/${userId}/groups`,
body: {
groupid: groupId,
},
}).then(response => {
cy.log(`User ${userId} added to group ${groupId}.`, response.status)
})
})
20 changes: 20 additions & 0 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
Loading

0 comments on commit 835c46f

Please sign in to comment.