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
committerFerdinand Thiessen <rpm@fthiessen.de>2022-09-13 18:57:51 +0300
commite89292f4d3e65d35faa1e9c42e13523896c89f72 (patch)
treecfaf139251b9cc2021f58829a32f40647b79d36a /cypress
parentb86cc7b9f7c26039293c966d3c27564125886c9b (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.js179
2 files changed, 179 insertions, 74 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..4f220cd53
--- /dev/null
+++ b/cypress/e2e/sections.spec.js
@@ -0,0 +1,179 @@
+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.heading-anchor')
+ .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 ID is updated', () => {
+ cy.clearContent()
+ .type('# Heading 1{enter}')
+ .then(() => {
+ cy.getContent()
+ .find('h1')
+ .should('have.attr', 'id')
+ .and('equal', 'heading-1')
+ cy.getContent()
+ .find('a.heading-anchor')
+ .should('have.attr', 'href')
+ .and('equal', '#heading-1')
+ })
+ cy.then(() => {
+ cy.getContent()
+ .type('{backspace}{backspace}2{enter}')
+ .then(() => {
+ cy.getContent()
+ .find('h1')
+ .should('have.attr', 'id')
+ .and('equal', 'heading-2')
+ cy.getContent()
+ .find('a.heading-anchor')
+ .should('have.attr', 'href')
+ .and('equal', '#heading-2')
+ })
+ })
+ })
+
+ it('Anchor scrolls into view', () => {
+ // Create link to top heading
+ cy.clearContent()
+ .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(.heading-anchor)')
+ .click()
+ .then(() => {
+ cy.getContent()
+ .get('h1[id="top"]')
+ .should('be.inViewport')
+ })
+ })
+
+ it('Can change heading level', () => {
+ // Issue #2868
+ cy.getContent()
+ .type('# Heading 1{enter}')
+ .then(() => {
+ cy.getContent()
+ .find('h1')
+ .should('have.attr', 'id')
+ .and('equal', 'heading-1')
+ })
+ cy.then(() => {
+ cy.getContent()
+ .type('{selectAll}')
+ .then(() => {
+ cy.getActionEntry('headings')
+ .click()
+ cy.get('.v-popper__wrapper .open').getActionEntry('headings-h3')
+ .click()
+ cy.getContent()
+ .find('h3')
+ .should('have.attr', 'id')
+ .and('equal', 'heading-1')
+ })
+ })
+ })
+ })
+
+ 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')
+ })
+ })
+})