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-08-27 16:49:22 +0300
committerVinicius Reis <vinicius.reis@nextcloud.com>2022-09-01 15:34:41 +0300
commit359a16d7d27a2c07bb704ddc3b96139473716029 (patch)
treeb32013d580d1232a8dd344c4e15354159777105d /cypress
parentddc73ff28f76077c73b91b10f6671ffd383e8bf6 (diff)
Add tests for heading anchors and inter-page links
Also added a chai assertion for checking an element is currently shown in the viewport of the window. This is needed as the cypress visibility checks fail for tiptap elements, as they are overlaid by the author color / names. Signed-off-by: Ferdinand Thiessen <rpm@fthiessen.de>
Diffstat (limited to 'cypress')
-rw-r--r--cypress/e2e/outline.spec.js74
-rw-r--r--cypress/e2e/sections.spec.js124
-rw-r--r--cypress/support/chai.js16
-rw-r--r--cypress/support/commands.js4
-rw-r--r--cypress/support/e2e.js5
5 files changed, 147 insertions, 76 deletions
diff --git a/cypress/e2e/outline.spec.js b/cypress/e2e/outline.spec.js
deleted file mode 100644
index b441a65d6..000000000
--- a/cypress/e2e/outline.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import { randHash } from '../utils/index.js'
-
-const currentUser = randHash()
-
-const refresh = () => cy.get('.files-controls .crumb:not(.hidden) a')
- .last()
- .click({ force: true })
-
-const clickOutline = () => {
- cy.getActionEntry('headings')
- .click()
-
- cy.get('.v-popper__wrapper .open').getActionEntry('outline')
- .click()
-}
-
-const createMarkdown = (fileName, content) => {
- return cy.createFile(fileName, content, 'text/markdown')
- .then(refresh)
-}
-
-describe('Table of Contents', () => {
- before(() => {
- // Init user
- cy.nextcloudCreateUser(currentUser, 'password')
- cy.login(currentUser, 'password')
- })
-
- beforeEach(() => {
- cy.login(currentUser, 'password')
- })
-
- it('sidebar toc', () => {
- const fileName = 'toc.md'
-
- createMarkdown(fileName, '# T1 \n ## T2 \n ### T3 \n #### T4 \n ##### T5 \n ###### T6')
- .then(refresh)
- .then(() => cy.openFile(fileName, { force: true }))
- .then(clickOutline)
-
- cy.getOutline()
- .find('header')
- .should('exist')
-
- cy.getTOC()
- .find('ul li')
- .should('have.length', 6)
- cy.getTOC()
- .find('ul li')
- .each((el, index) => {
- cy.wrap(el)
- .should('have.attr', 'data-toc-level')
- .and('equal', String(index + 1))
-
- cy.wrap(el)
- .find('a')
- .should('have.attr', 'href')
- .and('equal', `#t${index + 1}`)
- })
- })
-
- it('empty toc', () => {
- const fileName = 'empty.md'
-
- createMarkdown(fileName, '')
- .then(refresh)
- .then(() => cy.openFile(fileName, { force: true }))
- .then(clickOutline)
-
- cy.getOutline()
- .find('ul')
- .should('be.empty')
- })
-})
diff --git a/cypress/e2e/sections.spec.js b/cypress/e2e/sections.spec.js
new file mode 100644
index 000000000..89a3991a3
--- /dev/null
+++ b/cypress/e2e/sections.spec.js
@@ -0,0 +1,124 @@
+import { initUserAndFiles, randHash } from '../utils/index.js'
+
+const currentUser = randHash()
+const fileName = 'test.md'
+
+const refresh = () => cy.get('.files-controls .crumb:not(.hidden) a')
+ .last()
+ .click({ force: true })
+
+const clickOutline = () => {
+ cy.getActionEntry('headings')
+ .click()
+
+ cy.get('.v-popper__wrapper .open').getActionEntry('outline')
+ .click()
+}
+
+describe('Content Sections', () => {
+ before(function() {
+ initUserAndFiles(currentUser, fileName)
+ })
+
+ beforeEach(function() {
+ cy.login(currentUser, 'password', {
+ onBeforeLoad(win) {
+ cy.stub(win, 'open')
+ .as('winOpen')
+ },
+ })
+
+ cy.openFile(fileName)
+ .then(() => cy.clearContent())
+ })
+
+ describe('Heading anchors', () => {
+ beforeEach(() => cy.clearContent())
+
+ it('Anchor exists', () => {
+ cy.getContent()
+ .type('# Heading\nText\n## Heading 2\nText\n## Heading 2')
+ .then(() => {
+ cy.getContent()
+ .find('a.anchor-link')
+ .should(($anchor) => {
+ expect($anchor).to.have.length(3)
+ expect($anchor.eq(0)).to.have.attr('href').and.equal('#heading')
+ expect($anchor.eq(1)).to.have.attr('href').and.equal('#heading-2')
+ expect($anchor.eq(2)).to.have.attr('href').and.equal('#heading-2--1')
+ })
+ })
+ })
+
+ it('Anchor scrolls into view', () => {
+ // Create link to top heading
+ cy.getContent()
+ .type('{selectAll}{backspace}move top\n{selectAll}')
+ .get('.menububble button[data-text-bubble-action="add-link"]')
+ .click({ force: true })
+ .then(() => {
+ cy.get('.menububble .menububble__input')
+ .type('{shift}')
+ .type('#top{enter}', { force: true })
+ })
+ // Insert content above link
+ cy.getContent()
+ .type('{moveToStart}\n{moveToStart}# top \n')
+ .type('lorem ipsum \n'.repeat(25))
+ .type('{moveToEnd}\n')
+ .find('h1#top')
+ .should('not.be.inViewport')
+ // Click link and test view moved to anchor
+ cy.getContent()
+ .find('a:not(.anchor-link)')
+ .click()
+ .then(() => {
+ cy.getContent()
+ .get('h1[id="top"]')
+ .should('be.inViewport')
+ })
+ })
+ })
+
+ describe('Table of Contents', () => {
+ beforeEach(() => cy.clearContent())
+
+ it('sidebar toc', () => {
+ cy.getContent()
+ .type('# T1 \n## T2 \n### T3 \n#### T4 \n##### T5 \n###### T6\n')
+ .then(refresh)
+ .then(() => cy.openFile(fileName, { force: true }))
+ .then(clickOutline)
+
+ cy.getOutline()
+ .find('header')
+ .should('exist')
+
+ cy.getTOC()
+ .find('ul li')
+ .should('have.length', 6)
+ cy.getTOC()
+ .find('ul li')
+ .each((el, index) => {
+ cy.wrap(el)
+ .should('have.attr', 'data-toc-level')
+ .and('equal', String(index + 1))
+
+ cy.wrap(el)
+ .find('a')
+ .should('have.attr', 'href')
+ .and('equal', `#t${index + 1}`)
+ })
+ })
+
+ it('empty toc', () => {
+ refresh()
+ .then(() => cy.openFile(fileName, { force: true }))
+ .then(clickOutline)
+
+ cy.getOutline()
+ .find('ul')
+ .should('be.empty')
+ })
+ })
+})
diff --git a/cypress/support/chai.js b/cypress/support/chai.js
new file mode 100644
index 000000000..77737e3bc
--- /dev/null
+++ b/cypress/support/chai.js
@@ -0,0 +1,16 @@
+export default _chai => {
+ _chai.Assertion.addMethod('inViewport', function() {
+ const subject = this._obj
+
+ const height = Cypress.$(cy.state('window')).height()
+ const width = Cypress.$(cy.state('window')).width()
+ const rect = subject[0].getBoundingClientRect()
+
+ this.assert(
+ rect.top < height && rect.bottom > 0 && rect.right <= width && rect.left >= 0,
+ 'expected #{this} to be in the viewport',
+ 'expected #{this} to not be in the viewport',
+ this._obj
+ )
+ })
+}
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 7076e4ef1..889745737 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -292,8 +292,8 @@ Cypress.Commands.add('getTOC', () => {
Cypress.Commands.add('clearContent', () => {
return cy.getContent()
- .type('{selectall}')
- .type('{del}')
+ .scrollIntoView()
+ .type('{selectAll}{backspace}', { force: true })
})
Cypress.Commands.add('openWorkspace', (subject, name) => {
diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js
index 73c0c67db..614793a73 100644
--- a/cypress/support/e2e.js
+++ b/cypress/support/e2e.js
@@ -1,3 +1,8 @@
// This file is loaded before all e2e tests
import './commands.js'
+import chaiExtension from './chai.js'
+
+before(() => {
+ chai.use(chaiExtension)
+})