diff --git a/README.md b/README.md index 6149da14f2e..1ca36d9fb82 100644 --- a/README.md +++ b/README.md @@ -38,3 +38,16 @@ Currently this app requires the master branch of the [Viewer app](https://github ### 🧙 Advanced development stuff To build the Javascript whenever you make changes, instead of the full `make` you can also run `npm run build`. Or run `npm run watch` to rebuild on every file save. +#### 🐞 Testing the app +Currently this app uses three different kinds of tests: + +For testing the backend (PHP) [Psalm](https://psalm.dev/) and [PHPUnit](https://phpunit.de/) are used, +you can run the testcases (placed in `tests/`) using the composer scripts `psalm` and `test:unit`. + +For testing the frontend [jest](https://jestjs.io/) is used for unittests, whereas [cypress](https://www.cypress.io/) is used for end2end testing. +The unittests are also placed in `tests/`, the cypress tests are placed in `cypress/`. +You can run the tests using the package scripts `npm run test` (jest), and respective `npm run test:cypress` (cypress). + +Please note the cypress tests require a nextcloud server running, the if no running server is detected a docker container will be started, +this requires the current user to be in the `docker` group. +Or you might set the `CYPRESS_baseUrl` environment variable for a custom nextcloud server. \ No newline at end of file diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 00000000000..aed9f2dc3e8 --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,17 @@ +const { defineConfig } = require('cypress') + +module.exports = defineConfig({ + projectId: 'hx9gqy', + viewportWidth: 1280, + viewportHeight: 900, + e2e: { + // We've imported your old cypress plugins here. + // You may want to clean this up later by importing these. + setupNodeEvents(on, config) { + return require('./cypress/plugins/index.js')(on, config) + }, + baseUrl: 'http://localhost:8081/index.php/', + experimentalSessionAndOrigin: true, + specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', + }, +}) diff --git a/cypress.json b/cypress.json deleted file mode 100644 index 936edd8ab4e..00000000000 --- a/cypress.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "baseUrl": "https://localhost:8081/index.php/", - "projectId": "hx9gqy", - "viewportWidth": 1280, - "viewportHeight": 900, - "experimentalSessionAndOrigin": true -} diff --git a/cypress/Dockerfile b/cypress/Dockerfile index 4f2fc4495c7..ca343d110f1 100644 --- a/cypress/Dockerfile +++ b/cypress/Dockerfile @@ -1,12 +1,46 @@ -FROM nextcloudci/server:server-17 +FROM nextcloud:latest as source -RUN mkdir /var/www/html/data -RUN chown -R www-data:www-data /var/www/html/data +WORKDIR /tmp -ENTRYPOINT /usr/local/bin/initAndRun.sh +RUN set -ex; \ + apt-get update; \ + apt-get install -y --no-install-recommends git; -# FROM nextcloud:18-rc-apache +RUN set -ex; \ + git clone --depth 1 https://github.com/nextcloud/server.git ; \ + git clone --depth 1 https://github.com/nextcloud/viewer server/apps/viewer; +RUN set -ex; \ + cd server; \ + git submodule update --init; -#ENTRYPOINT [] -#CMD ["apache2-foreground"] +RUN cp -r -v /usr/src/nextcloud/config /tmp/server + +FROM nextcloud:latest + +RUN set -ex; \ + rm -rf /usr/src/nextcloud; + +COPY --from=source --chown=www-data:www-data /tmp/server /usr/src/nextcloud +COPY --chown=www-data:www-data ./server.sh /tmp/server.sh + +RUN set -ex; \ + cd /usr/src/nextcloud; \ + mkdir data; \ + mkdir custom_apps; \ + chown -R www-data:www-data config data apps custom_apps; + +ENV NEXTCLOUD_ADMIN_PASSWORD=admin +ENV NEXTCLOUD_ADMIN_USER=admin +ENV SQLITE_DATABASE=sqlite_db + +RUN set -ex; \ + cd /var/www/html; \ + NEXTCLOUD_UPDATE=1 bash -x /entrypoint.sh pwd; \ + chown -R www-data:www-data config data apps custom_apps; \ + bash -x /tmp/server.sh; \ + rm -rf /var/www/html/apps/text + +RUN set -ex; \ + cd /var/www/html; \ + ls -lah diff --git a/cypress/docker-compose.yml b/cypress/docker-compose.yml index 9e9eaddffa3..dc37d403d2c 100644 --- a/cypress/docker-compose.yml +++ b/cypress/docker-compose.yml @@ -1,14 +1,21 @@ version: '3' services: - nextcloud: + nextcloud_cypress: build: context: . + network: host restart: always ports: - 8081:80 environment: - CYPRESS_baseUrl: - APP_SOURCE: + - NEXTCLOUD_ADMIN_PASSWORD=admin + - NEXTCLOUD_ADMIN_USER=admin + - SQLITE_DATABASE=sqlite_db + - CYPRESS_baseUrl + - APP_SOURCE volumes: - - ${APP_SOURCE}:/var/www/html/apps/text + - type: bind + read_only: true + source: ${APP_SOURCE} + target: /var/www/html/custom_apps/text diff --git a/cypress/integration/ListItem.spec.js b/cypress/e2e/ListItem.spec.js similarity index 100% rename from cypress/integration/ListItem.spec.js rename to cypress/e2e/ListItem.spec.js diff --git a/cypress/integration/Table.spec.js b/cypress/e2e/Table.spec.js similarity index 100% rename from cypress/integration/Table.spec.js rename to cypress/e2e/Table.spec.js diff --git a/cypress/integration/files.spec.js b/cypress/e2e/files.spec.js similarity index 100% rename from cypress/integration/files.spec.js rename to cypress/e2e/files.spec.js diff --git a/cypress/integration/images.spec.js b/cypress/e2e/images.spec.js similarity index 100% rename from cypress/integration/images.spec.js rename to cypress/e2e/images.spec.js diff --git a/cypress/integration/links.spec.js b/cypress/e2e/links.spec.js similarity index 100% rename from cypress/integration/links.spec.js rename to cypress/e2e/links.spec.js diff --git a/cypress/integration/share.spec.js b/cypress/e2e/share.spec.js similarity index 100% rename from cypress/integration/share.spec.js rename to cypress/e2e/share.spec.js diff --git a/cypress/integration/viewer.spec.js b/cypress/e2e/viewer.spec.js similarity index 100% rename from cypress/integration/viewer.spec.js rename to cypress/e2e/viewer.spec.js diff --git a/cypress/integration/workspace.spec.js b/cypress/e2e/workspace.spec.js similarity index 100% rename from cypress/integration/workspace.spec.js rename to cypress/e2e/workspace.spec.js diff --git a/cypress/runLocal.sh b/cypress/runLocal.sh index 4150389cc34..843079ea7a4 100755 --- a/cypress/runLocal.sh +++ b/cypress/runLocal.sh @@ -1,38 +1,40 @@ #!/bin/bash -export CYPRESS_DIR=$(dirname -- "$(readlink -f "${BASH_SOURCE}")") -export CYPRESS_baseUrl=${CYPRESS_baseUrl:-http://localhost:8081/index.php} -export APP_SOURCE=$CYPRESS_DIR/.. +CYPRESS_DIR=$(dirname -- "$(readlink -f "${BASH_SOURCE}")") +CYPRESS_baseUrl=${CYPRESS_baseUrl:-http://localhost:8081/index.php} +APP_SOURCE=$CYPRESS_DIR/.. + +export CYPRESS_DIR +export CYPRESS_baseUrl +export APP_SOURCE function finish { docker-compose down } trap finish EXIT -cd $CYPRESS_DIR -if [ ! -f $(npm bin)/wait-on ] +cd "$CYPRESS_DIR" || exit +if [ ! -f "$(npm bin)/wait-on" ] then npm install --no-save wait-on fi # start server if it's not running yet -if $(npm bin)/wait-on -i 500 -t 1000 $CYPRESS_baseUrl 2> /dev/null +if "$(npm bin)/wait-on" -i 500 -t 1000 "$CYPRESS_baseUrl" 2> /dev/null then - echo Server is up at $CYPRESS_baseUrl + echo Server is up at "$CYPRESS_baseUrl" else - echo No server reached at $CYPRESS_baseUrl - starting containers. + echo No server reached at "$CYPRESS_baseUrl" - starting containers. docker-compose up -d - if $(npm bin)/wait-on -i 500 -t 240000 $CYPRESS_baseUrl 2> /dev/null + if "$(npm bin)/wait-on" -i 500 -t 240000 "$CYPRESS_baseUrl" 2> /dev/null then - docker-compose exec -T nextcloud bash /var/www/html/apps/text/cypress/server.sh + docker-compose exec -T nextcloud_cypress bash /var/www/html/custom_apps/text/cypress/server.sh else - echo Waiting for $CYPRESS_baseUrl timed out. + echo Waiting for "$CYPRESS_baseUrl" timed out. echo Container logs: docker-compose logs exit 1 fi fi -(cd .. && $(npm bin)/cypress $@) - - +(cd .. && "$(npm bin)/cypress" "$@") diff --git a/cypress/server.sh b/cypress/server.sh index a50a2c5f034..24f215d6328 100644 --- a/cypress/server.sh +++ b/cypress/server.sh @@ -1,6 +1,9 @@ #!/bin/bash -git clone https://github.com/nextcloud/viewer /var/www/html/apps/viewer -su www-data -c " +su -s /bin/bash www-data -c " +php /var/www/html/occ config:system:set debug --value='true' --type=boolean +export OC_PASS=1234561 +php /var/www/html/occ user:add --password-from-env user1 +php /var/www/html/occ user:add --password-from-env user2 php /var/www/html/occ app:enable viewer php /var/www/html/occ app:enable text php /var/www/html/occ app:list diff --git a/cypress/support/index.js b/cypress/support/e2e.js similarity index 100% rename from cypress/support/index.js rename to cypress/support/e2e.js diff --git a/package-lock.json b/package-lock.json index 821f4a44710..2673a82c1df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -77,7 +77,7 @@ "devDependencies": { "@babel/eslint-parser": "^7.18.2", "@cypress/browserify-preprocessor": "^3.0.2", - "@cypress/webpack-preprocessor": "^5.11.1", + "@cypress/webpack-preprocessor": "^5.12.0", "@nextcloud/babel-config": "^1.0.0", "@nextcloud/browserslist-config": "^2.2.0", "@nextcloud/eslint-config": "^8.0.0", @@ -86,7 +86,7 @@ "@nextcloud/webpack-vue-config": "^5.1.0", "@vue/test-utils": "^1.3.0", "@vue/vue2-jest": "^27.0.0", - "cypress": "^9.7.0", + "cypress": "^10.0.2", "cypress-file-upload": "^5.0.8", "eslint": "^8.17.0", "eslint-config-standard": "^17.0.0", @@ -1921,9 +1921,9 @@ } }, "node_modules/@cypress/webpack-preprocessor": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.11.1.tgz", - "integrity": "sha512-kfdF+W/Tns81rFplnqlgZ+t6V+FJ7vegeQCYolLyhh0nJ8eG3s5HvV/ak/zSlbQnaOmAuYiZIChJFVZLUWuNOA==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.12.0.tgz", + "integrity": "sha512-D/eLKKlgx6c/307FaCmjZGjFA64G29aA8KcCy6WqpNK/bSnRdPquMW2plemIsT/B80TK2DDKzZX/H3FcS41ZDA==", "dev": true, "dependencies": { "bluebird": "3.7.1", @@ -6798,9 +6798,9 @@ "dev": true }, "node_modules/cypress": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz", - "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.0.2.tgz", + "integrity": "sha512-7+C4KHYBcfZrawss+Gt5PlS35rfc6ySc59JcHDVsIMm1E/J35dqE41UEXpdtwIq3549umCerNWnFADzqib4kcA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -9274,20 +9274,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -20344,9 +20330,9 @@ } }, "@cypress/webpack-preprocessor": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.11.1.tgz", - "integrity": "sha512-kfdF+W/Tns81rFplnqlgZ+t6V+FJ7vegeQCYolLyhh0nJ8eG3s5HvV/ak/zSlbQnaOmAuYiZIChJFVZLUWuNOA==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.12.0.tgz", + "integrity": "sha512-D/eLKKlgx6c/307FaCmjZGjFA64G29aA8KcCy6WqpNK/bSnRdPquMW2plemIsT/B80TK2DDKzZX/H3FcS41ZDA==", "dev": true, "requires": { "bluebird": "3.7.1", @@ -24208,9 +24194,9 @@ } }, "cypress": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz", - "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.0.2.tgz", + "integrity": "sha512-7+C4KHYBcfZrawss+Gt5PlS35rfc6ySc59JcHDVsIMm1E/J35dqE41UEXpdtwIq3549umCerNWnFADzqib4kcA==", "dev": true, "requires": { "@cypress/request": "^2.88.10", @@ -26099,13 +26085,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", diff --git a/package.json b/package.json index 63f6e7a822d..6e60884d1fe 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css", "stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix", "test": "NODE_ENV=test jest", + "test:cypress": "cd cypress && ./runLocal.sh run", "test:coverage": "NODE_ENV=test jest --coverage" }, "browserslist": [ @@ -98,7 +99,7 @@ "devDependencies": { "@babel/eslint-parser": "^7.18.2", "@cypress/browserify-preprocessor": "^3.0.2", - "@cypress/webpack-preprocessor": "^5.11.1", + "@cypress/webpack-preprocessor": "^5.12.0", "@nextcloud/babel-config": "^1.0.0", "@nextcloud/browserslist-config": "^2.2.0", "@nextcloud/eslint-config": "^8.0.0", @@ -107,7 +108,7 @@ "@nextcloud/webpack-vue-config": "^5.1.0", "@vue/test-utils": "^1.3.0", "@vue/vue2-jest": "^27.0.0", - "cypress": "^9.7.0", + "cypress": "^10.0.2", "cypress-file-upload": "^5.0.8", "eslint": "^8.17.0", "eslint-config-standard": "^17.0.0",