diff --git a/cypress/integration/autocompletion.spec.ts b/cypress/integration/autocompletion.spec.ts index 863617c57..01149a789 100644 --- a/cypress/integration/autocompletion.spec.ts +++ b/cypress/integration/autocompletion.spec.ts @@ -7,9 +7,6 @@ describe('Autocompletion', () => { beforeEach(() => { cy.visit('/n/test') - cy.get('.btn.active.btn-outline-secondary > i.fa-columns') - .should('exist') - cy.get('.CodeMirror') .click() .get('textarea') @@ -18,8 +15,7 @@ describe('Autocompletion', () => { describe('code block', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill('```') + cy.codemirrorFill('```') cy.get('.CodeMirror-hints') .should('exist') cy.get('@codeinput') @@ -34,8 +30,7 @@ describe('Autocompletion', () => { .should('exist') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill('```') + cy.codemirrorFill('```') cy.get('.CodeMirror-hints > li') .first() .dblclick() @@ -52,8 +47,7 @@ describe('Autocompletion', () => { describe('container', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill(':::') + cy.codemirrorFill(':::') cy.get('.CodeMirror-hints') .should('exist') cy.get('@codeinput') @@ -68,8 +62,7 @@ describe('Autocompletion', () => { .should('exist') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill(':::') + cy.codemirrorFill(':::') cy.get('.CodeMirror-hints > li') .first() .dblclick() @@ -148,8 +141,7 @@ describe('Autocompletion', () => { describe('header', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill('#') + cy.codemirrorFill('#') cy.get('.CodeMirror-hints') .should('exist') cy.get('@codeinput') @@ -162,8 +154,7 @@ describe('Autocompletion', () => { .should('have.text', ' ') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill('#') + cy.codemirrorFill('#') cy.get('.CodeMirror-hints > li') .first() .dblclick() @@ -178,8 +169,7 @@ describe('Autocompletion', () => { describe('images', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill('!') + cy.codemirrorFill('!') cy.get('.CodeMirror-hints') .should('exist') cy.get('@codeinput') @@ -194,8 +184,7 @@ describe('Autocompletion', () => { .should('have.attr', 'title', 'title') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill('!') + cy.codemirrorFill('!') cy.get('.CodeMirror-hints > li') .first() .dblclick() @@ -212,8 +201,7 @@ describe('Autocompletion', () => { describe('links', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill('[') + cy.codemirrorFill('[') cy.get('.CodeMirror-hints') .should('exist') cy.get('@codeinput') @@ -228,8 +216,7 @@ describe('Autocompletion', () => { .should('have.attr', 'title', 'title') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill('[') + cy.codemirrorFill('[') cy.get('.CodeMirror-hints > li') .first() .dblclick() @@ -246,8 +233,7 @@ describe('Autocompletion', () => { describe('pdf', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill('{') + cy.codemirrorFill('{') cy.get('.CodeMirror-hints') .should('exist') cy.get('@codeinput') @@ -260,8 +246,7 @@ describe('Autocompletion', () => { .should('exist') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill('{') + cy.codemirrorFill('{') cy.get('.CodeMirror-hints > li') .first() .dblclick() @@ -276,8 +261,7 @@ describe('Autocompletion', () => { describe('collapsable blocks', () => { it('via Enter', () => { - cy.get('@codeinput') - .fill(' { .should('exist') }) it('via doubleclick', () => { - cy.get('@codeinput') - .fill(' li') .first() .dblclick() diff --git a/cypress/integration/documentTitle.spec.ts b/cypress/integration/documentTitle.spec.ts index 424bf1c1e..7233773ba 100644 --- a/cypress/integration/documentTitle.spec.ts +++ b/cypress/integration/documentTitle.spec.ts @@ -12,31 +12,23 @@ describe('Document Title', () => { cy.visit('/n/test') cy.get('.btn.active.btn-outline-secondary > i.fa-columns') .should('exist') - - cy.get('.CodeMirror') - .click() - .get('textarea') - .as('codeinput') }) describe('title should be yaml metadata title', () => { it('just yaml metadata title', () => { - cy.get('@codeinput') - .fill(`---\ntitle: ${title}\n---`) + cy.codemirrorFill(`---\ntitle: ${title}\n---`) cy.title() .should('eq', `${title} - HedgeDoc @ ${branding.name}`) }) it('yaml metadata title and opengraph title', () => { - cy.get('@codeinput') - .fill(`---\ntitle: ${title}\nopengraph:\n title: False title\n---`) + cy.codemirrorFill(`---\ntitle: ${title}\nopengraph:\n title: False title\n---`) cy.title() .should('eq', `${title} - HedgeDoc @ ${branding.name}`) }) it('yaml metadata title, opengraph title and first heading', () => { - cy.get('@codeinput') - .fill(`---\ntitle: ${title}\nopengraph:\n title: False title\n---\n# a first title`) + cy.codemirrorFill(`---\ntitle: ${title}\nopengraph:\n title: False title\n---\n# a first title`) cy.title() .should('eq', `${title} - HedgeDoc @ ${branding.name}`) }) @@ -44,15 +36,13 @@ describe('Document Title', () => { describe('title should be opengraph title', () => { it('just opengraph title', () => { - cy.get('@codeinput') - .fill(`---\nopengraph:\n title: ${title}\n---`) + cy.codemirrorFill(`---\nopengraph:\n title: ${title}\n---`) cy.title() .should('eq', `${title} - HedgeDoc @ ${branding.name}`) }) it('opengraph title and first heading', () => { - cy.get('@codeinput') - .fill(`---\nopengraph:\n title: ${title}\n---\n# a first title`) + cy.codemirrorFill(`---\nopengraph:\n title: ${title}\n---\n# a first title`) cy.title() .should('eq', `${title} - HedgeDoc @ ${branding.name}`) }) @@ -60,54 +50,47 @@ describe('Document Title', () => { describe('title should be first heading', () => { it('just first heading', () => { - cy.get('@codeinput') - .fill(`# ${title}`) + cy.codemirrorFill(`# ${title}`) cy.title() .should('eq', `${title} - HedgeDoc @ ${branding.name}`) }) it('just first heading with alt-text instead of image', () => { - cy.get('@codeinput') - .fill(`# ${title} ![abc](https://dummyimage.com/48)`) + cy.codemirrorFill(`# ${title} ![abc](https://dummyimage.com/48)`) cy.title() .should('eq', `${title} abc - HedgeDoc @ ${branding.name}`) }) it('just first heading without link syntax', () => { - cy.get('@codeinput') - .fill(`# ${title} [link](https://hedgedoc.org)`) + cy.codemirrorFill(`# ${title} [link](https://hedgedoc.org)`) cy.title() .should('eq', `${title} link - HedgeDoc @ ${branding.name}`) }) it('markdown syntax removed first', () => { - cy.get('@codeinput') - .fill(`# ${title} 1*2*3 4*5**`) + cy.codemirrorFill(`# ${title} 1*2*3 4*5**`) cy.title() .should('eq', `${title} 123 4*5** - HedgeDoc @ ${branding.name}`) }) it('markdown syntax removed second', () => { - cy.get('@codeinput') - .fill(`# ${title} **1 2*`) + cy.codemirrorFill(`# ${title} **1 2*`) cy.title() .should('eq', `${title} *1 2 - HedgeDoc @ ${branding.name}`) }) it('markdown syntax removed third', () => { - cy.get('@codeinput') - .fill(`# ${title} _asd_`) + cy.codemirrorFill(`# ${title} _asd_`) cy.title() .should('eq', `${title} asd - HedgeDoc @ ${branding.name}`) }) it('katex code looks right', () => { - cy.get('@codeinput') - .fill(`# $\\alpha$-foo`) + cy.codemirrorFill(`# $\\alpha$-foo`) cy.get('.markdown-body > h1') .should('contain', 'α') - cy.get('@codeinput') - .type('\n\ntest\n') + cy.get('.CodeMirror textarea') + .type('{Enter}{Enter}{Enter}{Enter}{Enter}') //This is a workaround because I don't know how to make sure, that the title gets updated in time. cy.title() .should('eq', `α-foo - HedgeDoc @ ${branding.name}`) }) diff --git a/cypress/integration/export.spec.ts b/cypress/integration/export.spec.ts index 05ebfdf89..b69e7ef36 100644 --- a/cypress/integration/export.spec.ts +++ b/cypress/integration/export.spec.ts @@ -10,12 +10,7 @@ describe('Export', () => { beforeEach(() => { cy.visit('/n/test') - cy.get('.btn.active.btn-outline-secondary > i.fa-columns') - .should('exist') - cy.get('.CodeMirror') - .click() - .get('textarea') - .fill(testContent) + cy.codemirrorFill(testContent) }) it('Markdown', () => { diff --git a/cypress/integration/fileUpload.spec.ts b/cypress/integration/fileUpload.spec.ts index 8e2866459..80d2f0df7 100644 --- a/cypress/integration/fileUpload.spec.ts +++ b/cypress/integration/fileUpload.spec.ts @@ -9,16 +9,11 @@ const imageUrl = 'http://example.com/non-existing.png' describe('File upload', () => { beforeEach(() => { cy.visit('/n/test') - cy.get('.CodeMirror') - .click() - .get('textarea') - .as('codeinput') }) it('doesn\'t prevent drag\'n\'drop of plain text', () => { const dataTransfer = new DataTransfer() - cy.get('@codeinput') - .fill('line 1\nline 2\ndragline') + cy.codemirrorFill('line 1\nline 2\ndragline') cy.get('.CodeMirror') .click() cy.get('.CodeMirror-line > span') @@ -83,8 +78,6 @@ describe('File upload', () => { }) it('upload fails', () => { - cy.get('@codeinput') - .type('not empty') cy.intercept({ method: 'POST', url: '/api/v2/media/upload' @@ -97,8 +90,8 @@ describe('File upload', () => { cy.get('input[type=file]') .attachFile({ filePath: 'acme.png', mimeType: 'image/png' }) }) - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', 'not empty') + cy.get('.CodeMirror-activeline > .CodeMirror-line > span > span') + .should('have.text', String.fromCharCode(8203)) //thanks codemirror.... }) it('text paste still works', () => { diff --git a/cypress/integration/helpDialog.spec.ts b/cypress/integration/helpDialog.spec.ts index 27a654c0f..d9dce7561 100644 --- a/cypress/integration/helpDialog.spec.ts +++ b/cypress/integration/helpDialog.spec.ts @@ -7,8 +7,6 @@ describe('Help Dialog', () => { beforeEach(() => { cy.visit('/n/test') - cy.get('.btn.active.btn-outline-secondary > i.fa-columns') - .should('exist') }) it('ToDo-List', () => { diff --git a/cypress/integration/highlightedCodeBlock.spec.ts b/cypress/integration/highlightedCodeBlock.spec.ts index 1da2f8522..db3a08ecc 100644 --- a/cypress/integration/highlightedCodeBlock.spec.ts +++ b/cypress/integration/highlightedCodeBlock.spec.ts @@ -11,19 +11,11 @@ describe('Code', () => { cy.spy(win.navigator.clipboard, 'writeText').as('copy') } }) - cy.get('.btn.active.btn-outline-secondary > i.fa-columns') - .should('exist') - - cy.get('.CodeMirror ') - .click() - cy.get('.CodeMirror textarea') - .as('codeinput') }) describe('with just the language', () => { it('doesn\'t show a gutter', () => { - cy.get('@codeinput') - .fill('```javascript \nlet x = 0\n```') + cy.codemirrorFill('```javascript \nlet x = 0\n```') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('not.have.class', 'showGutter') @@ -33,8 +25,7 @@ describe('Code', () => { describe('and line wrapping', () => { it('doesn\'t show a gutter', () => { - cy.get('@codeinput') - .fill('```javascript! \nlet x = 0\n```') + cy.codemirrorFill('```javascript! \nlet x = 0\n```') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('not.have.class', 'showGutter') @@ -47,8 +38,7 @@ describe('Code', () => { describe('with the language and show gutter', () => { it('shows the correct line number', () => { - cy.get('@codeinput') - .fill('```javascript= \nlet x = 0\n```') + cy.codemirrorFill('```javascript= \nlet x = 0\n```') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('have.class', 'showGutter') @@ -60,8 +50,7 @@ describe('Code', () => { describe('and line wrapping', () => { it('shows the correct line number', () => { - cy.get('@codeinput') - .fill('```javascript=! \nlet x = 0\n```') + cy.codemirrorFill('```javascript=! \nlet x = 0\n```') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('have.class', 'showGutter') @@ -76,8 +65,7 @@ describe('Code', () => { describe('with the language, show gutter with a start number', () => { it('shows the correct line number', () => { - cy.get('@codeinput') - .fill('```javascript=100 \nlet x = 0\n```') + cy.codemirrorFill('```javascript=100 \nlet x = 0\n```') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('have.class', 'showGutter') @@ -88,8 +76,7 @@ describe('Code', () => { }) it('shows the correct line number and continues in another codeblock', () => { - cy.get('@codeinput') - .fill('```javascript=100 \nlet x = 0\nlet y = 1\n```\n\n```javascript=+\nlet y = 2\n```\n') + cy.codemirrorFill('```javascript=100 \nlet x = 0\nlet y = 1\n```\n\n```javascript=+\nlet y = 2\n```\n') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('have.class', 'showGutter') @@ -117,8 +104,7 @@ describe('Code', () => { describe('and line wrapping', () => { it('shows the correct line number', () => { - cy.get('@codeinput') - .fill('```javascript=100! \nlet x = 0\n```') + cy.codemirrorFill('```javascript=100! \nlet x = 0\n```') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('have.class', 'showGutter') @@ -130,8 +116,7 @@ describe('Code', () => { }) it('shows the correct line number and continues in another codeblock', () => { - cy.get('@codeinput') - .fill('```javascript=100! \nlet x = 0\nlet y = 1\n```\n\n```javascript=+\nlet y = 2\n```\n') + cy.codemirrorFill('```javascript=100! \nlet x = 0\nlet y = 1\n```\n\n```javascript=+\nlet y = 2\n```\n') cy.get('.markdown-body > pre > code.hljs') .should('be.visible') .should('have.class', 'showGutter') @@ -161,8 +146,7 @@ describe('Code', () => { }) it('has a working copy button', () => { - cy.get('@codeinput') - .fill('```javascript \nlet x = 0\n```') + cy.codemirrorFill('```javascript \nlet x = 0\n```') cy.get('.markdown-body > pre > div > button > i') .should('have.class', 'fa-files-o') .click() diff --git a/cypress/integration/import.spec.ts b/cypress/integration/import.spec.ts index 1fe81f0da..bac29cebd 100644 --- a/cypress/integration/import.spec.ts +++ b/cypress/integration/import.spec.ts @@ -7,8 +7,6 @@ describe('Import markdown file', () => { beforeEach(() => { cy.visit('/n/test') - cy.get('.btn.active.btn-outline-secondary > i.fa-columns') - .should('exist') }) it('import on blank note', () => { @@ -26,10 +24,7 @@ describe('Import markdown file', () => { it('import on note with content', () => { - cy.get('.CodeMirror') - .click() - .get('textarea') - .fill('test\nabc') + cy.codemirrorFill('test\nabc') cy.get('button#editor-menu-import') .click() cy.get('.import-md-file') diff --git a/cypress/integration/maxLength.spec.ts b/cypress/integration/maxLength.spec.ts index 79ac62296..850ea57c5 100644 --- a/cypress/integration/maxLength.spec.ts +++ b/cypress/integration/maxLength.spec.ts @@ -11,11 +11,6 @@ describe('The status bar text length info', () => { beforeEach(() => { cy.visit('/n/test') - - cy.get('.CodeMirror ') - .click() - cy.get('.CodeMirror textarea') - .as('codeinput') }) it('shows the maximal length of the document as number of available characters in the tooltip', () => { @@ -25,22 +20,19 @@ describe('The status bar text length info', () => { }) it('color is set to "warning" on <= 100 characters remaining', () => { - cy.get('@codeinput') - .fill(warningTestContent) + cy.codemirrorFill(warningTestContent) cy.get('.status-bar [data-cy="remainingCharacters"]') .should('have.class', 'text-warning') }) it('color is set to danger on <= 0 characters remaining', () => { - cy.get('@codeinput') - .fill(dangerTestContent) + cy.codemirrorFill(dangerTestContent) cy.get('.status-bar [data-cy="remainingCharacters"]') .should('have.class', 'text-danger') }) it('shows a warning and opens a modal', () => { - cy.get('@codeinput') - .fill(tooMuchTestContent) + cy.codemirrorFill(tooMuchTestContent) cy.get('[data-cy="limitReachedModal"]') .should('be.visible') cy.get('[data-cy="limitReachedMessage"]') diff --git a/cypress/integration/toolbar.spec.ts b/cypress/integration/toolbar.spec.ts index 6d4e39138..1166ae71b 100644 --- a/cypress/integration/toolbar.spec.ts +++ b/cypress/integration/toolbar.spec.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -describe('Toolbar', () => { +describe('Toolbar Buttons', () => { const testText = 'textText' const testLink = 'http://hedgedoc.org' @@ -17,258 +17,238 @@ describe('Toolbar', () => { .as('codeinput') }) - const fillTestText = () => { - cy.get('@codeinput') - .fill(testText) - cy.get('.CodeMirror-line > span') - .should("exist") - .should('have.text', testText) - } - - const fillTestLink = () => { - cy.get('@codeinput') - .fill(testLink) - cy.get('.CodeMirror-line > span') - .should("exist") - .should('have.text', testLink) - } - - it('bold', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-bold') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `**${testText}**`) - }) - - it('italic', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-italic') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `*${testText}*`) - }) - - it('underline', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-underline') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `++${testText}++`) - }) - - it('strikethrough', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-strikethrough') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `~~${testText}~~`) - }) - - it('subscript', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-subscript') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `~${testText}~`) - }) - - it('superscript', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-superscript') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `^${testText}^`) - }) - - it('heading', () => { - fillTestText() - cy.get('.fa-header') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `# ${testText}`) - cy.get('.fa-header') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `## ${testText}`) - }) - - describe('code', () => { - it('nothing selected empty line', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - .type('{backspace}') - cy.get('.fa-code') - .click() - cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span') - .should('have.text', '```') - cy.get('.CodeMirror-code > div.CodeMirror-activeline > .CodeMirror-line > span span') - .should('have.text', '```') - }) - - it('nothing selected non line', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - .type('{leftArrow}') - cy.get('.fa-code') - .click() - cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span') - .should('have.text', '```') - cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') + describe('for single line text', () => { + beforeEach(() => { + cy.codemirrorFill(testText) + cy.get('.CodeMirror-line > span') + .should("exist") .should('have.text', testText) - cy.get('.CodeMirror-code > div.CodeMirror-activeline > .CodeMirror-line > span span') - .should('have.text', '```') }) - it('line selected', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-code') - .click() - cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span') - .should('have.text', '```') - cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') - .should('have.text', testText) - cy.get('.CodeMirror-code > div.CodeMirror-activeline > .CodeMirror-line > span span') - .should('have.text', '```') + describe('with selection', () => { + beforeEach(() => { + cy.get('@codeinput') + .type('{ctrl}a') + }) + + it('should format as bold', () => { + cy.get('.btn-toolbar [data-cy="format-bold"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `**${testText}**`) + }) + + it('should format as italic', () => { + cy.get('.btn-toolbar [data-cy="format-italic"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `*${testText}*`) + }) + + it('should format as underline', () => { + cy.get('.btn-toolbar [data-cy="format-underline"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `++${testText}++`) + }) + + it('should format as strikethrough', () => { + cy.get('.btn-toolbar [data-cy="format-strikethrough"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `~~${testText}~~`) + }) + + it('should format as subscript', () => { + cy.get('.btn-toolbar [data-cy="format-subscript"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `~${testText}~`) + }) + + it('should format as superscript', () => { + cy.get('.btn-toolbar [data-cy="format-superscript"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `^${testText}^`) + }) + + it('should format the line as code block', () => { + cy.get('.btn-toolbar [data-cy="format-code-block"]') + .click() + cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span') + .should('have.text', '```') + cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') + .should('have.text', testText) + cy.get('.CodeMirror-code > div.CodeMirror-activeline > .CodeMirror-line > span span') + .should('have.text', '```') + }) + + it('should format links', () => { + cy.get('.btn-toolbar [data-cy="format-link"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `[${testText}](https://)`) + }) + + it('should format as image', () => { + cy.get('.btn-toolbar [data-cy="format-image"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `![${testText}](https://)`) + }) }) - }) - it('quote', () => { - fillTestText() - cy.get('.fa-quote-right') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `> ${testText}`) - cy.get('.fa-quote-right') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `> > ${testText}`) - }) - - it('unordered list', () => { - fillTestText() - cy.get('.fa-list') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `- ${testText}`) - cy.get('.fa-list') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `- - ${testText}`) - }) - - it('ordered list', () => { - fillTestText() - cy.get('.fa-list-ol') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `1. ${testText}`) - cy.get('.fa-list-ol') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `1. 1. ${testText}`) - }) - - it('todo list', () => { - fillTestText() - cy.get('.fa-check-square') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `- [ ] ${testText}`) - cy.get('.fa-check-square') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `- [ ] - [ ] ${testText}`) - }) - - describe('link', () => { - it('with selection text', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-link') + it('should format line as heading', () => { + cy.get('.btn-toolbar [data-cy="format-heading"]') .click() cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `[${testText}](https://)`) + .should('have.text', `# ${testText}`) + cy.get('.btn-toolbar [data-cy="format-heading"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `## ${testText}`) }) - it('without selection', () => { - fillTestText() - cy.get('.fa-link') + it('should format the line as code', () => { + cy.get('.btn-toolbar [data-cy="format-code-block"]') + .click() + cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span') + .should('have.text', '```') + cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') + .should('have.text', testText) + cy.get('.CodeMirror-code > div.CodeMirror-activeline > .CodeMirror-line > span span') + .should('have.text', '```') + }) + + it('should add a quote', () => { + cy.get('.btn-toolbar [data-cy="format-block-quote"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `> ${testText}`) + cy.get('.btn-toolbar [data-cy="format-block-quote"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `> > ${testText}`) + }) + + it('should format as unordered list', () => { + cy.get('.btn-toolbar [data-cy="format-unordered-list"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `- ${testText}`) + cy.get('.btn-toolbar [data-cy="format-unordered-list"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `- - ${testText}`) + }) + + it('should format as ordered list', () => { + cy.get('.btn-toolbar [data-cy="format-ordered-list"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `1. ${testText}`) + cy.get('.btn-toolbar [data-cy="format-ordered-list"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `1. 1. ${testText}`) + }) + + it('should format as check list', () => { + cy.get('.btn-toolbar [data-cy="format-check-list"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `- [ ] ${testText}`) + cy.get('.btn-toolbar [data-cy="format-check-list"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `- [ ] - [ ] ${testText}`) + }) + + it('should insert links', () => { + cy.get('.btn-toolbar [data-cy="format-link"]') .click() cy.get('.CodeMirror-activeline > .CodeMirror-line > span') .should('have.text', `${testText}[](https://)`) }) - it('with selection link', () => { - fillTestLink() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-link') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `[](${testLink})`) - }) - }) - - describe('image', () => { - it('with selection', () => { - fillTestText() - cy.get('@codeinput') - .type('{ctrl}a') - cy.get('.fa-picture-o') - .click() - cy.get('.CodeMirror-activeline > .CodeMirror-line > span') - .should('have.text', `![${testText}](https://)`) - }) - - it('without selection', () => { - fillTestText() - cy.get('.fa-picture-o') + it('should insert an empty image link', () => { + cy.get('.btn-toolbar [data-cy="format-image"]') .click() cy.get('.CodeMirror-activeline > .CodeMirror-line > span') .should('have.text', `${testText}![](https://)`) }) + }) - it('with selection link', () => { - fillTestLink() + describe('for single line link with selection', () => { + beforeEach(() => { + cy.codemirrorFill(testLink) + cy.get('.CodeMirror-line > span') + .should("exist") + .should('have.text', testLink) cy.get('@codeinput') .type('{ctrl}a') - cy.get('.fa-picture-o') + }) + + it('should format as link', () => { + cy.get('.btn-toolbar [data-cy="format-link"]') + .click() + cy.get('.CodeMirror-activeline > .CodeMirror-line > span') + .should('have.text', `[](${testLink})`) + }) + + it('should format as image', () => { + cy.get('.btn-toolbar [data-cy="format-image"]') .click() cy.get('.CodeMirror-activeline > .CodeMirror-line > span') .should('have.text', `![](${testLink})`) }) }) - describe('table', () => { + describe('for no text', () => { + it('should add an empty code block', () => { + cy.get('.btn-toolbar [data-cy="format-code-block"]') + .click() + cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span') + .should('have.text', '```') + cy.get('.CodeMirror-code > div.CodeMirror-activeline > .CodeMirror-line > span span') + .should('have.text', '```') + }) + + it('should insert lines', () => { + cy.get('.btn-toolbar [data-cy="format-add-line"]') + .click() + cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') + .should('have.text', '----') + }) + + it('should add a collapsable block', () => { + cy.get('.btn-toolbar [data-cy="format-collapsable-block"]') + .click() + cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') + .should('have.text', ':::spoiler Toggle label') + }) + + it('should add a comment', () => { + cy.get('.btn-toolbar [data-cy="format-add-comment"]') + .click() + cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') + .should('have.text', '> []') + }) + }) + + describe('for new tables', () => { beforeEach(() => { cy.get('.table-picker-container') .should('not.be.visible') - cy.get('.fa-table') + cy.get('[data-cy="show-table-overlay"]') .last() .click() cy.get('.table-picker-container') .should('be.visible') }) - it('overlay', () => { + it('should open an overlay', () => { cy.get('.table-container > div:nth-of-type(25)') .trigger('mouseover') cy.get('.table-cell.bg-primary') @@ -279,10 +259,10 @@ describe('Toolbar', () => { .click() }) - it('custom', () => { + it('should open a modal for custom table sizes in the overlay', () => { cy.get('.modal-dialog') .should('not.exist') - cy.get('.fa-table') + cy.get('[data-cy="show-custom-table-modal"]') .first() .click() cy.get('.modal-dialog') @@ -311,32 +291,11 @@ describe('Toolbar', () => { }) }) - it('line', () => { - cy.get('.fa-minus') - .click() - cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') - .should('have.text', '----') - }) - - it('collapsable block', () => { - cy.get('.fa-caret-square-o-down') - .click() - cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') - .should('have.text', ':::spoiler Toggle label') - }) - - it('comment', () => { - cy.get('.fa-comment') - .click() - cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') - .should('have.text', '> []') - }) - - describe('emoji-picker', () => { - it('show when clicked', () => { + describe('for the emoji-picker', () => { + it('should open overlay', () => { cy.get('emoji-picker') .should('not.be.visible') - cy.get('.fa-smile-o') + cy.get('[data-cy="show-emoji-picker"]') .click() cy.get('emoji-picker') .should('be.visible') diff --git a/cypress/integration/yamlArrayDeprecationMessage.spec.ts b/cypress/integration/yamlArrayDeprecationMessage.spec.ts index 4747ab111..e55cb293f 100644 --- a/cypress/integration/yamlArrayDeprecationMessage.spec.ts +++ b/cypress/integration/yamlArrayDeprecationMessage.spec.ts @@ -7,30 +7,22 @@ describe('YAML Array for deprecated syntax of document tags in frontmatter', () => { beforeEach(() => { cy.visit('/n/features') - - cy.get('.CodeMirror') - .click() - .get('textarea') - .as('codeinput') }) it('is shown when using old syntax', () => { - cy.get('@codeinput') - .fill('---\ntags: a, b, c\n---') + cy.codemirrorFill('---\ntags: a, b, c\n---') cy.get('[data-cy="yamlArrayDeprecationAlert"]') .should('be.visible') }) it('isn\'t shown when using inline yaml-array', () => { - cy.get('@codeinput') - .fill('---\ntags: [\'a\', \'b\', \'c\']\n---') + cy.codemirrorFill('---\ntags: [\'a\', \'b\', \'c\']\n---') cy.get('[data-cy="yamlArrayDeprecationAlert"]') .should('not.exist') }) it('isn\'t shown when using multi line yaml-array', () => { - cy.get('@codeinput') - .fill('---\ntags:\n - a\n - b\n - c\n---') + cy.codemirrorFill('---\ntags:\n - a\n - b\n - c\n---') cy.get('[data-cy="yamlArrayDeprecationAlert"]') .should('not.exist') }) diff --git a/cypress/support/fill.ts b/cypress/support/fill.ts index b574898a8..97ca7ee5c 100644 --- a/cypress/support/fill.ts +++ b/cypress/support/fill.ts @@ -12,12 +12,26 @@ declare namespace Cypress { * @example cy.get(input).fill('content') */ fill (value: string): Chainable + codemirrorFill (value: string): Chainable } } Cypress.Commands.add('fill', { prevSubject: 'element' }, (subject, value) => { - cy.wrap(subject).invoke('val', value) - .trigger('change', { force: true }) + return cy.wrap(subject) + .invoke('val', value) + .trigger('change', { force: true }) +}) + +Cypress.Commands.add('codemirrorFill', (content: string) => { + const line = content.split("\n").find(value => value !== ''); + cy.get('.CodeMirror') + .click() + .get('textarea') + .fill(content) + if(line) { + cy.get('.CodeMirror') + .contains('.CodeMirror-line', line) + } }) diff --git a/src/components/editor/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx b/src/components/editor/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx index ffed87183..5d5ff3c76 100644 --- a/src/components/editor/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx +++ b/src/components/editor/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx @@ -29,7 +29,7 @@ export const EmojiPickerButton: React.FC = ({ editor }) addEmoji(emoji, editor) }} onDismiss={() => setShowEmojiPicker(false)}/> - diff --git a/src/components/editor/editor-pane/tool-bar/table-picker/table-picker-button.tsx b/src/components/editor/editor-pane/tool-bar/table-picker/table-picker-button.tsx index 8864ba6dd..4896d7b3e 100644 --- a/src/components/editor/editor-pane/tool-bar/table-picker/table-picker-button.tsx +++ b/src/components/editor/editor-pane/tool-bar/table-picker/table-picker-button.tsx @@ -30,7 +30,7 @@ export const TablePickerButton: React.FC = ({ editor }) addTable(editor, rows, cols) }} /> - diff --git a/src/components/editor/editor-pane/tool-bar/table-picker/table-picker.tsx b/src/components/editor/editor-pane/tool-bar/table-picker/table-picker.tsx index 26b88588f..d90507964 100644 --- a/src/components/editor/editor-pane/tool-bar/table-picker/table-picker.tsx +++ b/src/components/editor/editor-pane/tool-bar/table-picker/table-picker.tsx @@ -72,7 +72,7 @@ export const TablePicker: React.FC = ({ show, onDismiss, onTab ))}
- = ({ editor }) => { return ( - - - - - - - - - - - - - - = ({ editor }) => { - - -