Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2020-01-02 00:12:11 +0300
committerJulius Härtl <jus@bitgrid.net>2020-01-04 13:31:51 +0300
commit08386c96cf2b942c0d93f32aa0d39505ad6510ac (patch)
treef3ee4dc1d65fd946148119c6cfa2c4b1c9acd79a /cypress
parent290af2b60216700e2a8f7d4c3b1e9ddf0a0f2394 (diff)
Cypress test skeleton
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'cypress')
-rw-r--r--cypress/Dockerfile12
-rw-r--r--cypress/docker-compose.yml14
-rw-r--r--cypress/fixtures/test.md1
-rw-r--r--cypress/integration/files.spec.js38
-rw-r--r--cypress/integration/viewer.spec.js87
-rw-r--r--cypress/plugins/index.js27
-rwxr-xr-xcypress/runLocal.sh19
-rw-r--r--cypress/server.sh7
-rw-r--r--cypress/support/commands.js117
-rw-r--r--cypress/support/index.js20
-rw-r--r--cypress/utils/index.js35
11 files changed, 377 insertions, 0 deletions
diff --git a/cypress/Dockerfile b/cypress/Dockerfile
new file mode 100644
index 000000000..123a952fa
--- /dev/null
+++ b/cypress/Dockerfile
@@ -0,0 +1,12 @@
+FROM nextcloudci/server:server-16
+
+RUN mkdir /var/www/html/data
+RUN chown -R www-data:www-data /var/www/html/data
+
+ENTRYPOINT /usr/local/bin/initAndRun.sh
+
+# FROM nextcloud:18-rc-apache
+
+
+#ENTRYPOINT []
+#CMD ["apache2-foreground"]
diff --git a/cypress/docker-compose.yml b/cypress/docker-compose.yml
new file mode 100644
index 000000000..048cafaa2
--- /dev/null
+++ b/cypress/docker-compose.yml
@@ -0,0 +1,14 @@
+version: '3'
+
+services:
+ nextcloud:
+ build:
+ context: .
+ restart: always
+ ports:
+ - 8081:80
+ environment:
+ CYPRESS_baseUrl:
+ APP_SOURCE: /home/runner/work/text/text
+ volumes:
+ - $APP_SOURCE:/var/www/html/apps/text
diff --git a/cypress/fixtures/test.md b/cypress/fixtures/test.md
new file mode 100644
index 000000000..62c4c3f8a
--- /dev/null
+++ b/cypress/fixtures/test.md
@@ -0,0 +1 @@
+## Hello world
diff --git a/cypress/integration/files.spec.js b/cypress/integration/files.spec.js
new file mode 100644
index 000000000..6f77be7db
--- /dev/null
+++ b/cypress/integration/files.spec.js
@@ -0,0 +1,38 @@
+/**
+ * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+describe('Files default view', function() {
+ before(function() {
+ cy.login('admin', 'admin')
+ })
+ after(function() {
+ cy.logout()
+ })
+
+ it('See the default files list', function() {
+ cy.get('#fileList tr').should('contain', 'welcome.txt')
+ })
+
+ it('Take screenshot', function() {
+ cy.screenshot()
+ })
+})
diff --git a/cypress/integration/viewer.spec.js b/cypress/integration/viewer.spec.js
new file mode 100644
index 000000000..36e22edf4
--- /dev/null
+++ b/cypress/integration/viewer.spec.js
@@ -0,0 +1,87 @@
+/**
+ * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+import { randHash } from '../utils/'
+const randUser = randHash()
+
+describe('Open test.md in viewer', function() {
+ before(function() {
+ // Init user
+ cy.nextcloudCreateUser(randUser, 'password')
+ cy.login(randUser, 'password')
+
+ // Upload test files
+ cy.uploadFile('test.md', 'text/markdown')
+ cy.visit('/apps/files')
+
+ // wait a bit for things to be settled
+ cy.wait(1000)
+ })
+ after(function() {
+ cy.logout()
+ })
+
+ it('See test.md in the list', function() {
+ cy.get('#fileList tr[data-file="test.md"]', { timeout: 10000 })
+ .should('contain', 'test.md')
+ })
+
+ it('Open the viewer on file click', function() {
+ cy.visit('/apps/files')
+ cy.openFile('test.md')
+ cy.get('#viewer-content').should('be.visible')
+ cy.get('#viewer-content .modal-title').should('contain', 'test.md')
+ cy.get('#viewer-content .modal-header button.icon-menu-sidebar-white-forced').should('be.visible')
+ cy.get('#viewer-content .modal-header button.icon-close').should('be.visible')
+
+ cy.wait(2000)
+ cy.get('#viewer-content', { timeout: 4000 })
+ .should('be.visible')
+ .and('have.class', 'modal-mask')
+ .and('not.have.class', 'icon-loading')
+ })
+
+ it('Has opened the file', function() {
+ cy.get('#viewer-content #editor .ProseMirror').should('contain', 'Hello world')
+ cy.get('#viewer-content #editor .ProseMirror h2').should('contain', 'Hello world')
+ })
+
+ it('Shows the menu bar icons', function() {
+ // FIXME those checks are failing since the parent container is currently at 0x0 size
+ // due to the way we make the text app be a full screen viewer
+ // cy.get('#viewer-content #editor .menubar .menubar-icons .icon-undo').should('be.visible')
+ // cy.get('#viewer-content #editor .menubar .menubar-icons .icon-redo').should('be.visible')
+ // cy.get('#viewer-content #editor .menubar .menubar-icons .icon-bold').should('be.visible')
+ })
+
+ it('Closes the editor', function() {
+ cy.get('.modal-header button.icon-close').click()
+ cy.get('#viewer-content').should('not.be.visible')
+ })
+
+ it('Take screenshot', function() {
+ // gif is impossible to match with existing screenshot
+ // just taking a screenshot to manually compare if needed
+ cy.screenshot()
+ })
+})
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
new file mode 100644
index 000000000..8431f105c
--- /dev/null
+++ b/cypress/plugins/index.js
@@ -0,0 +1,27 @@
+// ***********************************************************
+// 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')
+const browserify = require('@cypress/browserify-preprocessor')
+
+module.exports = (on) => {
+}
+
+module.exports = (on, config) => {
+
+ on('file:preprocessor', browserify())
+
+ addMatchImageSnapshotPlugin(on, config)
+}
diff --git a/cypress/runLocal.sh b/cypress/runLocal.sh
new file mode 100755
index 000000000..e3b277113
--- /dev/null
+++ b/cypress/runLocal.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+export CYPRESS_baseUrl=http://localhost:8081/index.php
+export APP_SOURCE=$PWD/..
+
+function finish {
+ docker-compose down
+}
+trap finish EXIT
+
+docker-compose up -d
+
+npm install --no-save wait-on
+$(npm bin)/wait-on -i 500 -t 240000 $CYPRESS_baseUrl || (cd cypress && docker-compose logs && exit 1)
+docker-compose exec -T nextcloud bash /var/www/html/apps/text/cypress/server.sh
+
+(cd .. && $(npm bin)/cypress $@)
+
+
diff --git a/cypress/server.sh b/cypress/server.sh
new file mode 100644
index 000000000..a50a2c5f0
--- /dev/null
+++ b/cypress/server.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+git clone https://github.com/nextcloud/viewer /var/www/html/apps/viewer
+su www-data -c "
+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/commands.js b/cypress/support/commands.js
new file mode 100644
index 000000000..7a0e0be8c
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,117 @@
+/**
+ * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+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({
+ whitelist: /^(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.url().should('include', route)
+})
+
+Cypress.Commands.add('logout', () => {
+ cy.get('#expanddiv li[data-id="logout"] a').then(logout => {
+ if (logout) {
+ cy.visit(logout[0].href)
+ }
+ })
+})
+
+Cypress.Commands.add('nextcloudCreateUser', (user, password) => {
+ cy.clearCookies()
+ cy.request({
+ method: 'POST',
+ url: `${Cypress.env('baseUrl')}/ocs/v1.php/cloud/users?format=json`,
+ form: true,
+ body: {
+ userid: user,
+ password: password
+ },
+ auth: { user: 'admin', pass: 'admin' },
+ headers: {
+ 'OCS-ApiRequest': 'true',
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ Authorization: 'Basic YWRtaW46YWRtaW4='
+ }
+ }).then(response => {
+ cy.log(`Created user ${user}`, response.status)
+ })
+})
+
+Cypress.Commands.add('uploadFile', (fileName, mimeType) => {
+ cy.fixture(fileName, 'base64')
+ .then(Cypress.Blob.base64StringToBlob)
+ .then(async blob => {
+ const file = new File([blob], fileName, { type: mimeType })
+ await cy.window().then(async window => {
+ await axios.put(`${Cypress.env('baseUrl')}/remote.php/webdav/${fileName}`, file, {
+ headers: {
+ requesttoken: window.OC.requestToken,
+ 'Content-Type': mimeType
+ }
+ }).then(response => {
+ cy.log(`Uploaded ${fileName}`, response.status)
+ })
+ })
+ })
+})
+
+Cypress.Commands.add('createFolder', dirName => {
+ cy.get('#controls .actions > .button.new').click()
+ cy.get('#controls .actions .newFileMenu a[data-action="folder"]').click()
+ cy.get('#controls .actions .newFileMenu a[data-action="folder"] input[type="text"]').type(dirName)
+ cy.get('#controls .actions .newFileMenu a[data-action="folder"] input.icon-confirm').click()
+ cy.log('Created folder', dirName)
+})
+
+Cypress.Commands.add('openFile', fileName => {
+ cy.get(`#fileList tr[data-file="${fileName}"] a.name`).click()
+ cy.wait(250)
+})
+
+Cypress.Commands.add('deleteFile', fileName => {
+ cy.get(`#fileList tr[data-file="${fileName}"] a.name .action-menu`).click()
+ cy.get(`#fileList tr[data-file="${fileName}"] a.name + .popovermenu .action-delete`).click()
+})
+
+Cypress.Commands.overwrite('matchImageSnapshot', (originalFn, subject, name, options) => {
+ // hide avatar because random colour break the visual regression tests
+ cy.window().then(win => {
+ const avatarDiv = win.document.querySelector('.avatardiv')
+ if (avatarDiv) {
+ avatarDiv.remove()
+ }
+ })
+ return originalFn(subject, name, options)
+})
diff --git a/cypress/support/index.js b/cypress/support/index.js
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/cypress/support/index.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.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')
diff --git a/cypress/utils/index.js b/cypress/utils/index.js
new file mode 100644
index 000000000..cee81c0f5
--- /dev/null
+++ b/cypress/utils/index.js
@@ -0,0 +1,35 @@
+/**
+ * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+const getSearchParams = url => {
+ return url
+ .split(/[?&]/)
+ .reduce((acc, cur) => {
+ const parts = cur.split('=')
+ parts[1] && (acc[parts[0]] = parts[1])
+ return acc
+ }, {})
+}
+
+const randHash = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10)
+
+export default { getSearchParams, randHash }