diff options
author | Ferdinand Thiessen <rpm@fthiessen.de> | 2022-08-27 16:49:22 +0300 |
---|---|---|
committer | Ferdinand Thiessen <rpm@fthiessen.de> | 2022-09-13 18:57:51 +0300 |
commit | e89292f4d3e65d35faa1e9c42e13523896c89f72 (patch) | |
tree | cfaf139251b9cc2021f58829a32f40647b79d36a /cypress | |
parent | b86cc7b9f7c26039293c966d3c27564125886c9b (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.js | 74 | ||||
-rw-r--r-- | cypress/e2e/sections.spec.js | 179 |
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') + }) + }) +}) |