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:
authorFerdinand Thiessen <rpm@fthiessen.de>2022-06-25 01:10:50 +0300
committerVinicius Reis <vinicius.reis@nextcloud.com>2022-06-30 19:41:01 +0300
commitff1d6e497eb50de42be8909e30dc63c2adb5c8b3 (patch)
tree4f7f9178eaf51ec73ada5ed6d43bc946b715ae07
parent1efb92e2b5d605e56c7bb2ca27bc5b9c734d58d2 (diff)
Clean up cypress tests
1. Clean up lint issues of the cypress tests 2. Fix placed where .find was intended but .get was used 3. Remove duplicated code 4. Remove residues of cypress 10 migration 5. Add some documentation on available commands Signed-off-by: Ferdinand Thiessen <rpm@fthiessen.de>
-rw-r--r--cypress.config.js13
-rw-r--r--cypress/README.md33
-rw-r--r--cypress/e2e/ImageView.spec.js26
-rw-r--r--cypress/e2e/ListItem.spec.js35
-rw-r--r--cypress/e2e/Table.spec.js29
-rw-r--r--cypress/e2e/conflict.spec.js31
-rw-r--r--cypress/e2e/files.spec.js2
-rw-r--r--cypress/e2e/images.spec.js16
-rw-r--r--cypress/e2e/links.spec.js35
-rw-r--r--cypress/e2e/share.spec.js23
-rw-r--r--cypress/e2e/viewer.spec.js42
-rw-r--r--cypress/e2e/workspace.spec.js42
-rw-r--r--cypress/plugins/index.js22
-rw-r--r--cypress/support/commands.js20
-rw-r--r--cypress/support/e2e.js21
-rw-r--r--cypress/utils/index.js22
-rw-r--r--package.json4
17 files changed, 220 insertions, 196 deletions
diff --git a/cypress.config.js b/cypress.config.js
index 098b4ce7b..44562183c 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -5,12 +5,17 @@ module.exports = defineConfig({
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)
+ const browserify = require('@cypress/browserify-preprocessor')
+ const webpack = require('@cypress/webpack-preprocessor')
+ const webpackOptions = require('@nextcloud/webpack-vue-config')
+
+ webpackOptions.module.rules.push({ test: /\.md/, type: 'asset/source' })
+
+ on('file:preprocessor', browserify())
+ on('file:preprocessor', webpack({ webpackOptions }))
},
- // baseUrl: 'http://nextcloud.local/index.php/',
+
baseUrl: 'http://localhost:8081/index.php/',
experimentalSessionAndOrigin: true,
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
diff --git a/cypress/README.md b/cypress/README.md
new file mode 100644
index 000000000..e24a5bb40
--- /dev/null
+++ b/cypress/README.md
@@ -0,0 +1,33 @@
+# Cypress tests
+There are some custom cypress commands available making it easier to write tests,
+for example you can get the editor content and insert text by using
+
+```js
+cy.getContent()
+ .type('some test')
+```
+
+### Available custom commands
+| Command | Function | Parameters |
+| -------------------- | ---------------------- | ----------------------------------- |
+| `login` | Log in `user` | `user`, `password` |
+| `logout` | Logout | |
+| `nextcloudCreateUser`| Create a new user | `user`, `password` |
+| `nextcloudUpdateUser`| Update user setting | `user`, `password`, `key`, `value` |
+| `nextcloudDeleteUser`| Delete user | `user` |
+| `uploadFile` | Upload file | `fileName`, `mimeType`, `target` |
+| `createFile` | Create file | `target`, `content`, `mimeType` |
+| `moveFile` | Move a file | `path`, `destinationPath` |
+| `copyFile` | Copy file | `path`, `destinationPath` |
+| `createFolder` | Create a folder | `dirName` |
+| `shareFileToUser` | Share a file with user | `userId`, `password`, `path`, `targetUserId`|
+| `openFile` | Open file in Viewer / Editor | `fileName`, `clickParams` |
+| `getFile` | Get file list element of file | `fileName` |
+| `deleteFile` | Remove a file | `fileName` |
+| `reloadFileList` | Refresh the file list | |
+| `getEditor` | Get TipTap Editor element | |
+| `getContent` | Get editor content | |
+| `clearContent` | Clear the editor content | |
+| `getMenu` | Get editor menu bar | |
+| `getActionEntry` | Get menu entry | `name` |
+| `openWorkspace` | Open workspace and return Editor content | |
diff --git a/cypress/e2e/ImageView.spec.js b/cypress/e2e/ImageView.spec.js
index ae60df358..152b4921d 100644
--- a/cypress/e2e/ImageView.spec.js
+++ b/cypress/e2e/ImageView.spec.js
@@ -11,10 +11,6 @@ const createMarkdown = (fileName, content) => {
.then(refresh)
}
-// const closeModal = () => {
-// cy.get('.modal-header .header-close').click()
-// }
-
describe('Image View', () => {
before(() => {
// Init user
@@ -39,12 +35,12 @@ describe('Image View', () => {
cy.openFile(fileName)
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"]')
.should('have.attr', 'data-src')
.should('eq', '/github.png')
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] img')
.should('have.attr', 'src')
.should('contains', `/dav/files/${currentUser}/github.png`)
@@ -57,12 +53,12 @@ describe('Image View', () => {
cy.openFile(fileName)
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"]')
.should('have.attr', 'data-src')
.should('eq', 'child-folder/github.png')
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] img')
.should('have.attr', 'src')
.should('contains', `/dav/files/${currentUser}/child-folder/github.png`)
@@ -77,12 +73,12 @@ describe('Image View', () => {
cy.openFile(fileName, { force: true })
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"]')
.should('have.attr', 'data-src')
.should('eq', '../github.png')
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] img')
.should('have.attr', 'src')
.should('contains', `/dav/files/${currentUser}/github.png`)
@@ -98,7 +94,7 @@ describe('Image View', () => {
cy.openFile(fileName, { force: true })
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] img')
.should('have.attr', 'src')
.should('contains', `core/preview?fileId=${imageId}&file=${encodeURIComponent('/github.png')}`, { timeout: 5000 })
@@ -114,19 +110,19 @@ describe('Image View', () => {
cy.openFile(fileName)
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"]')
.should('have.class', 'image-view--failed')
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] svg')
.should('be.visible')
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] .image__error-message')
.should('be.visible')
- cy.getEditor()
+ cy.getContent()
.find('[data-component="image-view"] .image__caption input')
.should('have.value', 'yaha')
})
diff --git a/cypress/e2e/ListItem.spec.js b/cypress/e2e/ListItem.spec.js
index c45a8b2cc..c2a6be66c 100644
--- a/cypress/e2e/ListItem.spec.js
+++ b/cypress/e2e/ListItem.spec.js
@@ -1,14 +1,15 @@
+/* eslint-disable import/no-named-as-default */
import OrderedList from '@tiptap/extension-ordered-list'
import ListItem from '@tiptap/extension-list-item'
-import TaskList from './../../src/nodes/TaskList'
-import TaskItem from './../../src/nodes/TaskItem'
-import BulletList from './../../src/nodes/BulletList'
-import Markdown from './../../src/extensions/Markdown'
-import markdownit from './../../src/markdownit'
-import { createMarkdownSerializer } from './../../src/extensions/Markdown';
-import { findChildren, findChildrenByType } from 'prosemirror-utils'
-import createEditor from './../../src/tests/createEditor'
+/* eslint-enable import/no-named-as-default */
+import TaskList from './../../src/nodes/TaskList.js'
+import TaskItem from './../../src/nodes/TaskItem.js'
+import BulletList from './../../src/nodes/BulletList.js'
+import Markdown, { createMarkdownSerializer } from './../../src/extensions/Markdown.js'
+import { findChildren } from 'prosemirror-utils'
+import createEditor from './../../src/tests/createEditor.js'
import testData from '../fixtures/ListItem.md'
+import markdownit from './../../src/markdownit/index.js'
describe('ListItem extension integrated in the editor', () => {
@@ -24,7 +25,7 @@ describe('ListItem extension integrated in the editor', () => {
],
})
- for (const spec of testData.split(/#+\s+/)){
+ for (const spec of testData.split(/#+\s+/)) {
const [description, ...rest] = spec.split(/\n/)
const [input, output] = rest.join('\n').split(/\n\n---\n\n/)
if (!description) {
@@ -32,22 +33,24 @@ describe('ListItem extension integrated in the editor', () => {
}
it(description, () => {
expect(spec).to.include('\n')
+ /* eslint-disable no-unused-expressions */
expect(input).to.be.ok
expect(output).to.be.ok
+ /* eslint-enable no-unused-expressions */
loadMarkdown(input)
runCommands()
expectMarkdown(output.replace(/\n*$/, ''))
})
}
- function loadMarkdown(markdown) {
+ const loadMarkdown = (markdown) => {
const stripped = markdown.replace(/\t*/g, '')
editor.commands.setContent(markdownit.render(stripped))
}
- function runCommands() {
+ const runCommands = () => {
let found
- while (found = findCommand()) {
+ while ((found = findCommand())) {
const { node, pos } = found
const name = node.text
editor.commands.setTextSelection(pos)
@@ -56,19 +59,19 @@ describe('ListItem extension integrated in the editor', () => {
}
}
- function findCommand() {
+ const findCommand = () => {
const doc = editor.state.doc
return findChildren(doc, child => {
- return child.isText && editor.commands.hasOwnProperty(child.text)
+ return child.isText && Object.prototype.hasOwnProperty.call(editor.commands, child.text)
})[0]
}
- function expectMarkdown(markdown) {
+ const expectMarkdown = (markdown) => {
const stripped = markdown.replace(/\t*/g, '')
expect(getMarkdown()).to.equal(stripped)
}
- function getMarkdown() {
+ const getMarkdown = () => {
const serializer = createMarkdownSerializer(editor.schema)
return serializer.serialize(editor.state.doc)
}
diff --git a/cypress/e2e/Table.spec.js b/cypress/e2e/Table.spec.js
index e2484a401..fcf623551 100644
--- a/cypress/e2e/Table.spec.js
+++ b/cypress/e2e/Table.spec.js
@@ -1,10 +1,9 @@
-import EditableTable from './../../src/nodes/EditableTable'
-import Markdown from './../../src/extensions/Markdown'
-import markdownit from './../../src/markdownit'
-import { createMarkdownSerializer } from './../../src/extensions/Markdown';
-import { findChildren, findChildrenByType } from 'prosemirror-utils'
-import createEditor from './../../src/tests/createEditor'
+import { findChildren } from 'prosemirror-utils'
+import markdownit from './../../src/markdownit/index.js'
import testData from '../fixtures/Table.md'
+import createEditor from './../../src/tests/createEditor.js'
+import EditableTable from './../../src/nodes/EditableTable.js'
+import Markdown, { createMarkdownSerializer } from './../../src/extensions/Markdown.js'
describe('ListItem extension integrated in the editor', () => {
@@ -16,7 +15,7 @@ describe('ListItem extension integrated in the editor', () => {
],
})
- for (const spec of testData.split(/#+\s+/)){
+ for (const spec of testData.split(/#+\s+/)) {
const [description, ...rest] = spec.split(/\n/)
const [input, output] = rest.join('\n').split(/\n\n---\n\n/)
if (!description) {
@@ -24,21 +23,23 @@ describe('ListItem extension integrated in the editor', () => {
}
it(description, () => {
expect(spec).to.include('\n')
+ /* eslint-disable no-unused-expressions */
expect(input).to.be.ok
expect(output).to.be.ok
+ /* eslint-enable no-unused-expressions */
loadMarkdown(input)
runCommands()
expectMarkdown(output.replace(/\n*$/, ''))
})
}
- function loadMarkdown(markdown) {
+ const loadMarkdown = (markdown) => {
editor.commands.setContent(markdownit.render(markdown))
}
- function runCommands() {
+ const runCommands = () => {
let found
- while (found = findCommand()) {
+ while ((found = findCommand())) {
const name = found.node.text
editor.commands.setTextSelection(found.pos)
editor.commands[name]()
@@ -50,18 +51,18 @@ describe('ListItem extension integrated in the editor', () => {
}
}
- function findCommand() {
+ const findCommand = () => {
const doc = editor.state.doc
return findChildren(doc, child => {
- return child.isText && editor.commands.hasOwnProperty(child.text)
+ return child.isText && Object.prototype.hasOwnProperty.call(editor.commands, child.text)
})[0]
}
- function expectMarkdown(markdown) {
+ const expectMarkdown = (markdown) => {
expect(getMarkdown().replace(/\n$/, '')).to.equal(markdown)
}
- function getMarkdown() {
+ const getMarkdown = () => {
const serializer = createMarkdownSerializer(editor.schema)
return serializer.serialize(editor.state.doc)
}
diff --git a/cypress/e2e/conflict.spec.js b/cypress/e2e/conflict.spec.js
index e5949c34c..7af005234 100644
--- a/cypress/e2e/conflict.spec.js
+++ b/cypress/e2e/conflict.spec.js
@@ -3,7 +3,7 @@
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -20,17 +20,16 @@
*
*/
-import { randHash } from '../utils/'
+import { initUserAndFiles, randHash } from '../utils/index.js'
+
const randUser = randHash()
+const fileName = 'test.md'
describe('Open test.md in viewer', function() {
- before(function() {
- // Init user
- cy.nextcloudCreateUser(randUser, 'password')
- cy.login(randUser, 'password')
+ const getWrapper = () => cy.get('#editor-wrapper.has-conflicts.is-rich-editor')
- // Upload test files
- cy.uploadFile('test.md', 'text/markdown')
+ before(() => {
+ initUserAndFiles(randUser, fileName)
})
beforeEach(function() {
@@ -38,21 +37,23 @@ describe('Open test.md in viewer', function() {
})
it('displays conflicts', function() {
- cy.openFile('test.md')
+ cy.openFile(fileName)
cy.log('Inspect editor')
- const viewer = cy.get('#viewer')
- const editor = viewer.get('#editor .ProseMirror')
- editor.type('Hello you cruel conflicting world')
+ cy.getContent()
+ .type('Hello you cruel conflicting world')
cy.uploadFile('test.md', 'text/markdown')
cy.get('#viewer .modal-header button.header-close').click()
cy.get('#viewer').should('not.exist')
cy.openFile('test.md')
cy.get('#editor-container .document-status .icon-error')
- const wrapper = cy.get('#editor-wrapper.has-conflicts.is-rich-editor ')
- wrapper.get('#read-only-editor h2').should('contain', 'Hello world')
- wrapper.get('#editor h2').should('contain', 'Hello world')
+ getWrapper()
+ .get('#read-only-editor h2')
+ .should('contain', 'Hello world')
+ getWrapper()
+ .get('#editor h2')
+ .should('contain', 'Hello world')
cy.screenshot()
})
})
diff --git a/cypress/e2e/files.spec.js b/cypress/e2e/files.spec.js
index 3b5b8d470..34f23ea3d 100644
--- a/cypress/e2e/files.spec.js
+++ b/cypress/e2e/files.spec.js
@@ -3,7 +3,7 @@
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
diff --git a/cypress/e2e/images.spec.js b/cypress/e2e/images.spec.js
index 5c9d98032..357cf1570 100644
--- a/cypress/e2e/images.spec.js
+++ b/cypress/e2e/images.spec.js
@@ -3,7 +3,7 @@
*
* @author Julien Veyssier <eneiluj@posteo.net>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -20,7 +20,7 @@
*
*/
-import { randHash } from '../utils/'
+import { initUserAndFiles, randHash } from '../utils/index.js'
import 'cypress-file-upload'
const randUser = randHash()
@@ -47,7 +47,7 @@ function attachFile(name, requestAlias = null) {
/**
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
- * @param str string
+ * @param {string} str String to encode
*/
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {
@@ -58,7 +58,7 @@ function fixedEncodeURIComponent(str) {
/**
* Open the image action menu and click one action
*
- * @param actionName position of the action to be clicked
+ * @param {string} actionName position of the action to be clicked
*/
const clickOnImageAction = (actionName) => {
cy.getActionEntry('insert-image')
@@ -134,13 +134,7 @@ const waitForRequestAndCheckImage = (requestAlias, index) => {
describe('Test all image insertion methods', () => {
before(() => {
- // Init user
- cy.nextcloudCreateUser(randUser, 'password')
- cy.login(randUser, 'password')
-
- // Upload test files to user's storage
- cy.uploadFile('test.md', 'text/markdown')
- cy.uploadFile('empty.md', 'text/markdown')
+ initUserAndFiles(randUser, 'test.md', 'empty.md')
cy.uploadFile('github.png', 'image/png')
cy.nextcloudCreateUser(randUser2, 'password')
diff --git a/cypress/e2e/links.spec.js b/cypress/e2e/links.spec.js
index 6c9d759aa..a2586c3d3 100644
--- a/cypress/e2e/links.spec.js
+++ b/cypress/e2e/links.spec.js
@@ -1,23 +1,11 @@
-import { randHash } from '../utils/'
+import { initUserAndFiles, randHash } from '../utils/index.js'
const randUser = randHash()
-const fileName = 'empty.md'
-
-const getEditor = () => cy.getEditor().find('.ProseMirror')
-
-const clearContent = () => getEditor()
- .type('{selectall}')
- .type('{enter}')
+const fileName = 'test.md'
describe('test link marks', function() {
before(function() {
- // Init user
- cy.nextcloudCreateUser(randUser, 'password')
- cy.login(randUser, 'password')
-
- // Upload test files
- cy.uploadFile('test.md', 'text/markdown')
- cy.uploadFile(fileName, 'text/markdown')
+ initUserAndFiles(randUser, fileName)
})
beforeEach(function() {
@@ -25,7 +13,6 @@ describe('test link marks', function() {
onBeforeLoad(win) {
cy.stub(win, 'open')
.as('winOpen')
-
},
})
@@ -33,18 +20,18 @@ describe('test link marks', function() {
})
describe('autolink', function() {
- beforeEach(clearContent)
+ beforeEach(() => cy.clearContent())
it('with protocol', () => {
- cy.getFile('test.md')
+ cy.getFile(fileName)
.then($el => {
const id = $el.data('id')
const link = `${Cypress.env('baseUrl')}/file-name?fileId=${id}`
- getEditor()
+ cy.getContent()
.type(link)
- getEditor()
- .get(`a[href*="${Cypress.env('baseUrl')}`)
+ cy.getContent()
+ .find(`a[href*="${Cypress.env('baseUrl')}"]`)
.click({ force: true })
cy.get('@winOpen')
@@ -54,11 +41,11 @@ describe('test link marks', function() {
})
it('whithout protocol', () => {
- getEditor()
+ cy.getContent()
.type('google.com')
- getEditor()
- .get('a[href*="google.com"]')
+ cy.getContent()
+ .find('a[href*="google.com"]')
.click({ force: true })
cy.get('@winOpen')
diff --git a/cypress/e2e/share.spec.js b/cypress/e2e/share.spec.js
index ad1ccb31c..2dfc40ab0 100644
--- a/cypress/e2e/share.spec.js
+++ b/cypress/e2e/share.spec.js
@@ -1,10 +1,10 @@
-/*
+/**
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -21,7 +21,7 @@
*
*/
-import { randHash } from '../utils/'
+import { randHash } from '../utils/index.js'
const randUser = randHash()
describe('Open test.md in viewer', function() {
@@ -59,7 +59,8 @@ describe('Open test.md in viewer', function() {
cy.window().then(win => {
win.OC.appswebroots.files_texteditor = true
cy.getEditor().should('be.visible')
- .find('.ProseMirror').should('contain', 'Hello world')
+ cy.getContent()
+ .should('contain', 'Hello world')
.find('h2').should('contain', 'Hello world')
})
})
@@ -83,9 +84,9 @@ describe('Open test.md in viewer', function() {
cy.visit(href)
cy.window().then(win => {
win.OC.appswebroots.files_texteditor = true
- cy.getEditor()
- .should('be.visible')
- .find('.ProseMirror').should('contain', 'Hello world')
+ cy.getEditor().should('be.visible')
+ cy.getContent()
+ .should('contain', 'Hello world')
.find('h2').should('contain', 'Hello world')
cy.getMenu().should('be.visible')
@@ -103,7 +104,6 @@ describe('Open test.md in viewer', function() {
cy.get('#app-sidebar-vue')
.should('be.visible')
cy.get('#app-sidebar-vue a#sharing').trigger('click')
- // cy.get('#app-sidebar-vue button.new-share-link').trigger('click')
cy.get('#app-sidebar-vue a.sharing-entry__copy')
.should('have.attr', 'href').and('include', '/s/')
.then((href) => {
@@ -111,10 +111,11 @@ describe('Open test.md in viewer', function() {
cy.visit(href)
cy.window().then(win => {
win.OC.appswebroots.files_texteditor = true
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(1000)
- cy.getEditor()
- .should('be.visible')
- .find('.ProseMirror').should('contain', 'Hello world')
+ cy.getEditor().should('be.visible')
+ cy.getContent()
+ .should('contain', 'Hello world')
.find('h2').should('contain', 'Hello world')
cy.getMenu().should('be.visible')
diff --git a/cypress/e2e/viewer.spec.js b/cypress/e2e/viewer.spec.js
index 769337373..747f181b6 100644
--- a/cypress/e2e/viewer.spec.js
+++ b/cypress/e2e/viewer.spec.js
@@ -3,7 +3,7 @@
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -20,18 +20,14 @@
*
*/
-import { randHash } from '../utils/'
+import { initUserAndFiles, randHash } from '../utils/index.js'
const randUser = randHash()
describe('Open test.md in viewer', function() {
- before(function() {
- // Init user
- cy.nextcloudCreateUser(randUser, 'password')
- cy.login(randUser, 'password')
+ const getViewer = () => cy.get('#viewer')
- // Upload test files
- cy.uploadFile('test.md', 'text/markdown')
- cy.uploadFile('empty.md', 'text/markdown')
+ before(function() {
+ initUserAndFiles(randUser, 'test.md', 'empty.md')
})
beforeEach(function() {
@@ -47,18 +43,20 @@ describe('Open test.md in viewer', function() {
cy.openFile('test.md')
cy.log('Inspect viewer')
- const viewer = cy.get('#viewer')
- viewer.should('be.visible')
+ getViewer().should('be.visible')
.and('have.class', 'modal-mask')
.and('not.have.class', 'icon-loading')
- viewer.get('.modal-title').should('contain', 'test.md')
- viewer.get('.modal-header button.action-item__menutoggle')
+ getViewer()
+ .find('.modal-title').should('contain', 'test.md')
+ getViewer()
+ .find('.modal-header button.action-item__menutoggle')
.should('be.visible')
cy.log('Inspect editor')
- const editor = viewer.get('#editor .ProseMirror')
- editor.should('contain', 'Hello world')
- editor.get('h2').should('contain', 'Hello world')
+ cy.getContent()
+ .should('contain', 'Hello world')
+ cy.getContent()
+ .get('h2').should('contain', 'Hello world')
cy.log('Inspect menubar')
cy.getActionEntry('undo').should('be.visible')
@@ -71,17 +69,17 @@ describe('Open test.md in viewer', function() {
cy.openFile('empty.md')
cy.log('Inspect viewer')
- const viewer = cy.get('#viewer')
- viewer.should('be.visible')
+ getViewer().should('be.visible')
.and('have.class', 'modal-mask')
.and('not.have.class', 'icon-loading')
- viewer.get('.modal-title').should('contain', 'empty.md')
- viewer.get('.modal-header button.action-item__menutoggle')
+ getViewer()
+ .find('.modal-title').should('contain', 'empty.md')
+ getViewer()
+ .find('.modal-header button.action-item__menutoggle')
.should('be.visible')
cy.log('Inspect editor')
- const editor = viewer.get('#editor .ProseMirror')
- editor.should('contain', '')
+ cy.getContent().should('contain', '')
cy.log('Inspect menubar')
cy.getActionEntry('undo').should('be.visible')
diff --git a/cypress/e2e/workspace.spec.js b/cypress/e2e/workspace.spec.js
index 9273bc8d8..37bc71335 100644
--- a/cypress/e2e/workspace.spec.js
+++ b/cypress/e2e/workspace.spec.js
@@ -3,7 +3,7 @@
*
* @author Azul <azul@riseup.net>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -61,7 +61,9 @@ describe('Workspace', function() {
menuButton(button)
.click({ force: true })
.should('have.class', 'is-active')
- cy.get(`.ProseMirror ${tag}`).should('contain', 'Format me')
+ cy.getContent()
+ .find(`${tag}`)
+ .should('contain', 'Format me')
menuButton(button)
.click({ force: true })
.should('not.have.class', 'is-active')
@@ -74,20 +76,24 @@ describe('Workspace', function() {
.type('{selectall}')
menuBubbleButton('add-link').click()
cy.get('.menububble input').type('https://nextcloud.com{enter}')
- cy.get('.ProseMirror a')
+ cy.getContent()
+ .find('a')
.should('contain', 'Nextcloud')
.should('be.visible')
- cy.get('.ProseMirror a').invoke('attr', 'href')
+ cy.getContent()
+ .find('a').invoke('attr', 'href')
.should('include', 'https://nextcloud.com')
cy.window().then((win) => {
cy.stub(win, 'open').as('windowOpen')
})
- cy.get('.ProseMirror a').click()
+ cy.getContent()
+ .find('a').click()
cy.get('@windowOpen').should('be.calledWith', 'https://nextcloud.com/')
- cy.get('.ProseMirror').type('{selectall}')
+ cy.getContent().type('{selectall}')
menuBubbleButton('add-link').click()
cy.get('.menububble input').type('/team{enter}')
- cy.get('.ProseMirror a').click()
+ cy.getContent()
+ .find('a').click()
cy.get('@windowOpen').should('be.calledWith', 'https://nextcloud.com/team')
})
@@ -100,7 +106,8 @@ describe('Workspace', function() {
getSubmenuItem('headings', actionName).click()
- cy.get(`.ProseMirror ${heading}`)
+ cy.getContent()
+ .find(`${heading}`)
.should('contain', 'Heading')
getSubmenuItem('headings', actionName)
@@ -124,7 +131,8 @@ describe('Workspace', function() {
.click({ force: true })
.should('have.class', 'is-active')
- cy.get(`.ProseMirror ${tag}`).should('contain', 'List me')
+ cy.getContent()
+ .find(`${tag}`).should('contain', 'List me')
menuButton(button)
.click({ force: true })
@@ -155,13 +163,16 @@ describe('Workspace', function() {
return menuButton('table').click()
})
- cy.get('.ProseMirror').type('content')
- cy.get('.ProseMirror table tr:first-child th:first-child')
+ cy.getContent()
+ .type('content')
+ cy.getContent()
+ .find('table tr:first-child th:first-child')
.should('contain', 'content')
- cy.get('.ProseMirror [data-text-table-actions="settings"]').click()
+ cy.getContent()
+ .find('[data-text-table-actions="settings"]').click()
cy.get('[data-text-table-action="delete"]').click()
- cy.get('.ProseMirror')
+ cy.getContent()
.should('not.contain', 'content')
})
@@ -187,7 +198,8 @@ describe('Workspace', function() {
.click()
.then(() => {
// check content
- cy.get(`.ProseMirror .callout.callout--${type}`)
+ cy.getContent()
+ .find(`.callout.callout--${type}`)
.should('contain', 'Callout')
// disable
@@ -212,7 +224,7 @@ describe('Workspace', function() {
const actionName = `callout-${type}`
return getSubmenuItem('callouts', actionName)
.click()
- .then(() => cy.get(`.ProseMirror .callout.callout--${type}`))
+ .then(() => cy.getContent().find(`.callout.callout--${type}`))
.should('contain', 'Callout')
.then(() => {
last = type
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
deleted file mode 100644
index 6a2be1cea..000000000
--- a/cypress/plugins/index.js
+++ /dev/null
@@ -1,22 +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 browserify = require('@cypress/browserify-preprocessor')
-const webpack = require('@cypress/webpack-preprocessor')
-const webpackOptions = require('@nextcloud/webpack-vue-config')
-
-module.exports = (on, config) => {
- on('file:preprocessor', browserify())
- webpackOptions.module.rules.push({ test: /\.md/, type: 'asset/source' })
- on('file:preprocessor', webpack({webpackOptions}))
-}
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index afe36697f..e10fd9619 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -3,7 +3,7 @@
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -21,6 +21,8 @@
*/
import axios from '@nextcloud/axios'
+
+// eslint-disable-next-line no-unused-vars,node/no-extraneous-import
import regeneratorRuntime from 'regenerator-runtime'
const url = Cypress.config('baseUrl').replace(/\/index.php\/?$/g, '')
@@ -54,6 +56,7 @@ Cypress.Commands.add('nextcloudCreateUser', (user, password) => {
body: {
userid: user,
password,
+ language: 'en', // for tests that rely on the translated text
},
auth: { user: 'admin', pass: 'admin' },
headers: {
@@ -124,8 +127,6 @@ Cypress.Commands.add('createFile', (target, content, mimeType) => {
const blob = new Blob([content], { type: mimeType })
const file = new File([blob], fileName, { type: mimeType })
- const requestAlias = `request-${fileName}`
-
return cy.window()
.then(async window => {
const response = await axios.put(`${Cypress.env('baseUrl')}/remote.php/webdav/${target}`, file, {
@@ -187,6 +188,7 @@ Cypress.Commands.add('reloadFileList', () => {
Cypress.Commands.add('openFile', (fileName, params = {}) => {
cy.get(`#fileList tr[data-file="${fileName}"] a.name`).click(params)
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(250)
})
@@ -213,9 +215,19 @@ Cypress.Commands.add('getActionEntry', { prevSubject: 'optional' }, (subject, na
.find(`[data-text-action-entry="${name}"]`)
})
+Cypress.Commands.add('getContent', () => {
+ return cy.getEditor().find('.ProseMirror')
+})
+
+Cypress.Commands.add('clearContent', () => {
+ return cy.getContent()
+ .type('{selectall}')
+ .type('{del}')
+})
+
Cypress.Commands.add('openWorkspace', (subject, name) => {
cy.get('#rich-workspace .empty-workspace').click()
cy.getEditor().find('[data-text-el="editor-content-wrapper"]').click()
- return cy.getEditor().find('.ProseMirror')
+ return cy.getContent()
})
diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js
index d68db96df..73c0c67db 100644
--- a/cypress/support/e2e.js
+++ b/cypress/support/e2e.js
@@ -1,20 +1,3 @@
-// ***********************************************************
-// 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
-// ***********************************************************
+// This file is loaded before all e2e tests
-// Import commands.js using ES2015 syntax:
-import './commands'
-
-// Alternatively you can use CommonJS syntax:
-// require('./commands')
+import './commands.js'
diff --git a/cypress/utils/index.js b/cypress/utils/index.js
index 3df987f62..f25aa306a 100644
--- a/cypress/utils/index.js
+++ b/cypress/utils/index.js
@@ -3,7 +3,7 @@
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license GNU AGPL version 3 or any later version
+ * @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -30,4 +30,24 @@ export const getSearchParams = url => {
}, {})
}
+/**
+ * Creates a new user with default passwort `password` and upload one or multiple test files
+ * Can be used e.g. for a `before()`
+ *
+ * @param {string} userName Username of the user to create
+ * @param {...string} file one ore more markdown file names to create
+ */
+export function initUserAndFiles(userName, file) {
+ const files = [...arguments].slice(1)
+
+ // Init user
+ cy.nextcloudCreateUser(userName, 'password')
+ cy.login(userName, 'password')
+
+ // Upload test files
+ files.forEach(file => {
+ cy.uploadFile(file, 'text/markdown')
+ })
+}
+
export const randHash = () => Math.random().toString(36).replace(/[^a-z]+/g, '').slice(0, 10)
diff --git a/package.json b/package.json
index 277f269bf..946bd69cb 100644
--- a/package.json
+++ b/package.json
@@ -21,8 +21,8 @@
"watch": "NODE_ENV=development webpack --progress --watch --config webpack.js",
"build": "NODE_ENV=production webpack --progress --config webpack.js",
"build:package": "vite build",
- "lint": "eslint --ext .js,.vue src",
- "lint:fix": "eslint --ext .js,.vue src --fix",
+ "lint": "eslint --ext .js,.vue src cypress",
+ "lint:fix": "eslint --ext .js,.vue src cypress --fix",
"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css",
"stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix",
"test": "NODE_ENV=test jest",