Improve tests (#944)

Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
Tilman Vatteroth 2021-01-11 23:22:11 +01:00 committed by GitHub
parent e0e5f2a7dd
commit 3db6bcf892
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 342 additions and 295 deletions

View file

@ -118,7 +118,7 @@ ij_typescript_import_sort_module_name = true
ij_typescript_import_use_node_resolution = true ij_typescript_import_use_node_resolution = true
ij_typescript_imports_wrap = on_every_item ij_typescript_imports_wrap = on_every_item
ij_typescript_indent_case_from_switch = true ij_typescript_indent_case_from_switch = true
ij_typescript_indent_chained_calls = false ij_typescript_indent_chained_calls = true
ij_typescript_indent_package_children = 0 ij_typescript_indent_package_children = 0
ij_typescript_jsdoc_include_types = false ij_typescript_jsdoc_include_types = false
ij_typescript_jsx_attribute_value = braces ij_typescript_jsx_attribute_value = braces

View file

@ -8,19 +8,21 @@ describe('Autocompletion', () => {
beforeEach(() => { beforeEach(() => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.btn.active.btn-outline-secondary > i.fa-columns') cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true }) cy.get('.CodeMirror')
.type('{backspace}') .click()
.get('textarea')
.as('codeinput')
}) })
describe('code block', () => { describe('code block', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```') .fill('```')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -32,8 +34,8 @@ describe('Autocompletion', () => {
.should('exist') .should('exist')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```') .fill('```')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -50,11 +52,11 @@ describe('Autocompletion', () => {
describe('container', () => { describe('container', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(':::') .fill(':::')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -66,8 +68,8 @@ describe('Autocompletion', () => {
.should('exist') .should('exist')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(':::') .fill(':::')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -85,11 +87,11 @@ describe('Autocompletion', () => {
describe('emoji', () => { describe('emoji', () => {
describe('normal emoji', () => { describe('normal emoji', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(':hedg') .fill(':hedg')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -99,8 +101,8 @@ describe('Autocompletion', () => {
.should('have.text', '🦔') .should('have.text', '🦔')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(':hedg') .fill(':hedg')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -115,11 +117,11 @@ describe('Autocompletion', () => {
describe('fork-awesome-icon', () => { describe('fork-awesome-icon', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(':fa-face') .fill(':fa-face')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -129,8 +131,8 @@ describe('Autocompletion', () => {
.should('exist') .should('exist')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(':fa-face') .fill(':fa-face')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -146,11 +148,11 @@ describe('Autocompletion', () => {
describe('header', () => { describe('header', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('#') .fill('#')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -160,8 +162,8 @@ describe('Autocompletion', () => {
.should('have.text', ' ') .should('have.text', ' ')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('#') .fill('#')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -176,11 +178,11 @@ describe('Autocompletion', () => {
describe('images', () => { describe('images', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('!') .fill('!')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -192,8 +194,8 @@ describe('Autocompletion', () => {
.should('have.attr', 'title', 'title') .should('have.attr', 'title', 'title')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('!') .fill('!')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -210,11 +212,11 @@ describe('Autocompletion', () => {
describe('links', () => { describe('links', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('[') .fill('[')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -226,8 +228,8 @@ describe('Autocompletion', () => {
.should('have.attr', 'title', 'title') .should('have.attr', 'title', 'title')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('[') .fill('[')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -244,11 +246,11 @@ describe('Autocompletion', () => {
describe('pdf', () => { describe('pdf', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{') .fill('{')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
@ -258,8 +260,8 @@ describe('Autocompletion', () => {
.should('exist') .should('exist')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{') .fill('{')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
@ -274,31 +276,31 @@ describe('Autocompletion', () => {
describe('collapsable blocks', () => { describe('collapsable blocks', () => {
it('via Enter', () => { it('via Enter', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('<d') .fill('<d')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('{enter}') .type('{enter}')
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', '</details>') // after selecting the hint, the last line of the inserted suggestion is active .should('have.text', '</details>') // after selecting the hint, the last line of the inserted suggestion is active
cy.get('.markdown-body > details') cy.get('.markdown-body > details')
.should('exist') .should('exist')
}) })
it('via doubleclick', () => { it('via doubleclick', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('<d') .fill('<d')
cy.get('.CodeMirror-hints > li') cy.get('.CodeMirror-hints > li')
.first() .first()
.dblclick() .dblclick()
cy.get('.CodeMirror-hints') cy.get('.CodeMirror-hints')
.should('not.exist') .should('not.exist')
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', '</details>') .should('have.text', '</details>')
cy.get('.markdown-body > details') cy.get('.markdown-body > details')
.should('exist') .should('exist')
}) })
}) })
}) })

View file

@ -13,22 +13,24 @@ describe('Code', () => {
}) })
cy.get('.btn.active.btn-outline-secondary > i.fa-columns') cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true }) cy.get('.CodeMirror')
.type('{backspace}') .click()
.get('textarea')
.as('codeinput')
}) })
describe('without = doesn\'t show gutter', () => { describe('without = doesn\'t show gutter', () => {
it('without wrapLines active', () => { it('without wrapLines active', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript \nlet x = 0\n```') .fill('```javascript \nlet x = 0\n```')
cy.get('.markdown-body > pre > code') cy.get('.markdown-body > pre > code')
.should('have.class', 'hljs') .should('have.class', 'hljs')
}) })
it('with wrapLines active', () => { it('with wrapLines active', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript!\nlet x = 0\n```') .fill('```javascript!\nlet x = 0\n```')
cy.get('.markdown-body > pre > code') cy.get('.markdown-body > pre > code')
.should('have.class', 'hljs') .should('have.class', 'hljs')
.should('have.class', 'wrapLines') .should('have.class', 'wrapLines')
@ -37,8 +39,8 @@ describe('Code', () => {
describe('with = shows gutter', () => { describe('with = shows gutter', () => {
it('without wrapLines active', () => { it('without wrapLines active', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript=\nlet x = 0\n```') .fill('```javascript=\nlet x = 0\n```')
cy.get('.markdown-body > pre > code') cy.get('.markdown-body > pre > code')
.should('have.class', 'hljs') .should('have.class', 'hljs')
.should('have.class', 'showGutter') .should('have.class', 'showGutter')
@ -48,8 +50,8 @@ describe('Code', () => {
}) })
it('with wrapLines active', () => { it('with wrapLines active', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript=! \nlet x = 0\n```') .fill('```javascript=! \nlet x = 0\n```')
cy.get('.markdown-body > pre > code') cy.get('.markdown-body > pre > code')
.should('have.class', 'hljs') .should('have.class', 'hljs')
.should('have.class', 'showGutter') .should('have.class', 'showGutter')
@ -62,8 +64,8 @@ describe('Code', () => {
describe('with = shows gutter and number is used as startline', () => { describe('with = shows gutter and number is used as startline', () => {
it('without wrapLines active', () => { it('without wrapLines active', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript=100\nlet x = 0\n```') .fill('```javascript=100\nlet x = 0\n```')
cy.get('.markdown-body > pre > code') cy.get('.markdown-body > pre > code')
.should('have.class', 'hljs') .should('have.class', 'hljs')
.should('have.class', 'showGutter') .should('have.class', 'showGutter')
@ -73,8 +75,8 @@ describe('Code', () => {
}) })
it('with wrapLines active', () => { it('with wrapLines active', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript=100! \nlet x = 0\n```') .fill('```javascript=100! \nlet x = 0\n```')
cy.get('.markdown-body > pre > code') cy.get('.markdown-body > pre > code')
.should('have.class', 'hljs') .should('have.class', 'hljs')
.should('have.class', 'showGutter') .should('have.class', 'showGutter')
@ -86,11 +88,11 @@ describe('Code', () => {
}) })
it('has a button', () => { it('has a button', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('```javascript \nlet x = 0\n```') .fill('```javascript \nlet x = 0\n```')
cy.get('.markdown-body > pre > div > button > i') cy.get('.markdown-body > pre > div > button > i')
.should('have.class', 'fa-files-o') .should('have.class', 'fa-files-o')
.click() .click()
cy.get('@copy').should('be.calledWithExactly', 'let x = 0\n'); cy.get('@copy').should('be.calledWithExactly', 'let x = 0\n')
}) })
}) })

View file

@ -12,80 +12,94 @@ describe('Document Title', () => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.btn.active.btn-outline-secondary > i.fa-columns') cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true }) cy.get('.CodeMirror')
.type('{backspace}') .click()
.get('textarea')
.as('codeinput')
}) })
describe('title should be yaml metadata title', () => { describe('title should be yaml metadata title', () => {
it('just yaml metadata title', () => { it('just yaml metadata title', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`---\ntitle: ${title}\n---`) .fill(`---\ntitle: ${title}\n---`)
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} - HedgeDoc @ ${branding.name}`)
}) })
it('yaml metadata title and opengraph title', () => { it('yaml metadata title and opengraph title', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`---\ntitle: ${title}\nopengraph:\n title: False title\n{backspace}{backspace}---`) .fill(`---\ntitle: ${title}\nopengraph:\n title: False title\n---`)
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} - HedgeDoc @ ${branding.name}`)
}) })
it('yaml metadata title, opengraph title and first heading', () => { it('yaml metadata title, opengraph title and first heading', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`---\ntitle: ${title}\nopengraph:\n title: False title\n{backspace}{backspace}---\n# a first title`) .fill(`---\ntitle: ${title}\nopengraph:\n title: False title\n---\n# a first title`)
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} - HedgeDoc @ ${branding.name}`)
}) })
}) })
describe('title should be opengraph title', () => { describe('title should be opengraph title', () => {
it('just opengraph title', () => { it('just opengraph title', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`---\nopengraph:\n title: ${title}\n{backspace}{backspace}---`) .fill(`---\nopengraph:\n title: ${title}\n---`)
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} - HedgeDoc @ ${branding.name}`)
}) })
it('opengraph title and first heading', () => { it('opengraph title and first heading', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`---\nopengraph:\n title: ${title}\n{backspace}{backspace}---\n# a first title`) .fill(`---\nopengraph:\n title: ${title}\n---\n# a first title`)
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} - HedgeDoc @ ${branding.name}`)
}) })
}) })
describe('title should be first heading', () => { describe('title should be first heading', () => {
it('just first heading', () => { it('just first heading', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`# ${title}`) .fill(`# ${title}`)
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} - HedgeDoc @ ${branding.name}`)
}) })
it('just first heading with alt-text instead of image', () => { it('just first heading with alt-text instead of image', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`# ${title} ![abc](https://dummyimage.com/48)`) .fill(`# ${title} ![abc](https://dummyimage.com/48)`)
cy.title().should('eq', `${title} abc - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} abc - HedgeDoc @ ${branding.name}`)
}) })
it('just first heading without link syntax', () => { it('just first heading without link syntax', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`# ${title} [link](https://hedgedoc.org)`) .fill(`# ${title} [link](https://hedgedoc.org)`)
cy.title().should('eq', `${title} link - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} link - HedgeDoc @ ${branding.name}`)
}) })
it('markdown syntax removed first', () => { it('markdown syntax removed first', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`# ${title} 1*2*3 4*5**`) .fill(`# ${title} 1*2*3 4*5**`)
cy.title().should('eq', `${title} 123 4*5** - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} 123 4*5** - HedgeDoc @ ${branding.name}`)
}) })
it('markdown syntax removed second', () => { it('markdown syntax removed second', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type(`# ${title} **1 2*`) .fill(`# ${title} **1 2*`)
cy.title().should('eq', `${title} *1 2 - HedgeDoc @ ${branding.name}`) cy.title()
.should('eq', `${title} *1 2 - HedgeDoc @ ${branding.name}`)
}) })
it('markdown syntax removed third', () => { it('markdown syntax removed third', () => {
cy.get('.CodeMirror textarea') cy.get('a')
.type(`# ${title} _asd_`) .get('@codeinput')
cy.title().should('eq', `${title} asd - HedgeDoc @ ${branding.name}`) .fill(`# ${title} _asd_`)
cy.title()
.should('eq', `${title} asd - HedgeDoc @ ${branding.name}`)
}) })
}) })
}) })

View file

@ -7,18 +7,25 @@
describe('Editor mode from URL parameter is used', () => { describe('Editor mode from URL parameter is used', () => {
it('mode view', () => { it('mode view', () => {
cy.visit('/n/features?view') cy.visit('/n/features?view')
cy.get('.splitter.left').should('have.class', 'd-none') cy.get('.splitter.left')
cy.get('.splitter.right').should('not.have.class', 'd-none') .should('have.class', 'd-none')
cy.get('.splitter.right')
.should('not.have.class', 'd-none')
}) })
it('mode both', () => { it('mode both', () => {
cy.visit('/n/features?both') cy.visit('/n/features?both')
cy.get('.splitter.left').should('not.have.class', 'd-none') cy.get('.splitter.left')
cy.get('.splitter.separator').should('exist') .should('not.have.class', 'd-none')
cy.get('.splitter.right').should('not.have.class', 'd-none') cy.get('.splitter.separator')
.should('exist')
cy.get('.splitter.right')
.should('not.have.class', 'd-none')
}) })
it('mode edit', () => { it('mode edit', () => {
cy.visit('/n/features?edit') cy.visit('/n/features?edit')
cy.get('.splitter.left').should('not.have.class', 'd-none') cy.get('.splitter.left')
cy.get('.splitter.right').should('have.class', 'd-none') .should('not.have.class', 'd-none')
cy.get('.splitter.right')
.should('have.class', 'd-none')
}) })
}) })

View file

@ -4,19 +4,18 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
const testTitle = 'testContent'
const testContent = `---\ntitle: ${testTitle}\n---\nThis is some test content`
describe('Export', () => { describe('Export', () => {
const testTitle = 'testContent'
const testContent = `---\ntitle: ${testTitle}\n---\nThis is some test content`
beforeEach(() => { beforeEach(() => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.btn.active.btn-outline-secondary > i.fa-columns') cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea') cy.get('.CodeMirror')
.type('{ctrl}a', { force: true }) .click()
.type('{backspace}') .get('textarea')
cy.get('.CodeMirror textarea') .fill(testContent)
.type(testContent)
}) })
it('Markdown', () => { it('Markdown', () => {
@ -28,27 +27,27 @@ describe('Export', () => {
.then((anchor) => ( .then((anchor) => (
new Cypress.Promise((resolve: any, _: any) => { new Cypress.Promise((resolve: any, _: any) => {
// Use XHR to get the blob that corresponds to the object URL. // Use XHR to get the blob that corresponds to the object URL.
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest()
xhr.open('GET', anchor.prop('href'), true); xhr.open('GET', anchor.prop('href'), true)
xhr.responseType = 'blob'; xhr.responseType = 'blob'
// Once loaded, use FileReader to get the string back from the blob. // Once loaded, use FileReader to get the string back from the blob.
xhr.onload = () => { xhr.onload = () => {
if (xhr.status === 200) { if (xhr.status === 200) {
const blob = xhr.response; const blob = xhr.response
const reader = new FileReader(); const reader = new FileReader()
reader.onload = () => { reader.onload = () => {
// Once we have a string, resolve the promise to let // Once we have a string, resolve the promise to let
// the Cypress chain continue, e.g. to assert on the result. // the Cypress chain continue, e.g. to assert on the result.
resolve(reader.result); resolve(reader.result)
}; }
reader.readAsText(blob); reader.readAsText(blob)
} }
}; }
xhr.send(); xhr.send()
}) })
)) ))
// Now the regular Cypress assertions should work. // Now the regular Cypress assertions should work.
.should('equal', testContent); .should('equal', testContent)
}) })
}) })

View file

@ -6,28 +6,30 @@
const imageUrl = 'http://example.com/non-existing.png' const imageUrl = 'http://example.com/non-existing.png'
describe('Upload', () => { describe('File upload', () => {
beforeEach(() => { beforeEach(() => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.btn.active.btn-outline-secondary > i.fa-columns') cy.get('.CodeMirror')
.should('exist') .click()
cy.get('.CodeMirror textarea') .get('textarea')
.type('{ctrl}a', { force: true }) .as('codeinput')
.type('{backspace}')
}) })
it('check that text drag\'n\'drop still works', () => { it('doesn\'t prevent drag\'n\'drop of plain text', () => {
const dataTransfer = new DataTransfer() const dataTransfer = new DataTransfer()
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('line 1\nline 2\nline3') .fill('line 1\nline 2\ndragline')
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror')
.click()
cy.get('.CodeMirror-line > span')
.last()
.dblclick() .dblclick()
cy.get('.CodeMirror-line > span > .cm-matchhighlight') cy.get('.CodeMirror-line > span > .cm-matchhighlight')
.trigger('dragstart', { dataTransfer }) .trigger('dragstart', { dataTransfer })
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span span') cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span span')
.trigger('drop', { dataTransfer }) .trigger('drop', { dataTransfer })
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span span') cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span span')
.should('have.text', 'linline3e 1') .should('have.text', 'lindraglinee 1')
}) })
describe('upload works', () => { describe('upload works', () => {
@ -60,7 +62,7 @@ describe('Upload', () => {
} }
cy.get('.CodeMirror-scroll').trigger('paste', pasteEvent) cy.get('.CodeMirror-scroll').trigger('paste', pasteEvent)
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', `![](${imageUrl})`) .should('have.text', `![](${imageUrl})`)
}) })
}) })
@ -75,13 +77,13 @@ describe('Upload', () => {
cy.get('.CodeMirror-scroll').trigger('dragenter', dropEvent) cy.get('.CodeMirror-scroll').trigger('dragenter', dropEvent)
cy.get('.CodeMirror-scroll').trigger('drop', dropEvent) cy.get('.CodeMirror-scroll').trigger('drop', dropEvent)
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', `![](${imageUrl})`) .should('have.text', `![](${imageUrl})`)
}) })
}) })
}) })
it('upload fails', () => { it('upload fails', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('not empty') .type('not empty')
cy.intercept({ cy.intercept({
method: 'POST', method: 'POST',
@ -91,8 +93,10 @@ describe('Upload', () => {
}) })
cy.get('.fa-upload') cy.get('.fa-upload')
.click() .click()
cy.get('input[type=file]') cy.fixture('acme.png').then(() => {
.attachFile({ filePath: 'acme.png', mimeType: 'image/png' }) cy.get('input[type=file]')
.attachFile({ filePath: 'acme.png', mimeType: 'image/png' })
})
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
.should('have.text', 'not empty') .should('have.text', 'not empty')
}) })

View file

@ -9,9 +9,6 @@ describe('Import markdown file', () => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.btn.active.btn-outline-secondary > i.fa-columns') cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
.should('exist') .should('exist')
cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true })
.type('{backspace}')
}) })
it('import on blank note', () => { it('import on blank note', () => {
@ -28,8 +25,11 @@ describe('Import markdown file', () => {
}) })
it('import on note with content', () => { it('import on note with content', () => {
cy.get('.CodeMirror textarea')
.type('test\nabc', { force: true }) cy.get('.CodeMirror')
.click()
.get('textarea')
.fill('test\nabc')
cy.get('button#editor-menu-import') cy.get('button#editor-menu-import')
.click() .click()
cy.get('.import-md-file') cy.get('.import-md-file')

View file

@ -4,52 +4,47 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
const tenChars = '0123456789' describe('The status bar text length info', () => {
const warningTestContent = ('0123456789'.repeat(10))
const dangerTestContent = ('0123456789'.repeat(20))
const tooMuchTestContent = `${dangerTestContent}a`
describe('status-bar text-length info', () => {
beforeEach(() => { beforeEach(() => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.CodeMirror ')
.click()
cy.get('.CodeMirror textarea') cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true }) .as('codeinput')
.type('{backspace}')
}) })
it('tooltip shows full remaining on empty text', () => { it('shows the maximal length of the document as number of available characters in the tooltip', () => {
cy.get('.status-bar div:nth-child(2) span:nth-child(2)') cy.get('.status-bar [data-cy="remainingCharacters"]')
.attribute('title') .attribute('title')
.should('contain', ' 200 ') .should('contain', ' 200 ')
}) })
it('color is warning on <= 100 chars remaining', () => { it('color is set to "warning" on <= 100 characters remaining', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.fill(tenChars.repeat(10)) .fill(warningTestContent)
cy.get('.status-bar div:nth-child(2) span:nth-child(2)') cy.get('.status-bar [data-cy="remainingCharacters"]')
.should('have.class', 'text-warning') .should('have.class', 'text-warning')
}) })
it('color is danger on <= 0 chars remaining', () => { it('color is set to danger on <= 0 characters remaining', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.fill(tenChars.repeat(20)) .fill(dangerTestContent)
cy.get('.status-bar div:nth-child(2) span:nth-child(2)') cy.get('.status-bar [data-cy="remainingCharacters"]')
.should('have.class', 'text-danger') .should('have.class', 'text-danger')
})
})
describe('show warning if content length > configured max length', () => {
beforeEach(() => {
cy.visit('/n/test')
cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true })
.type('{backspace}')
.fill(tenChars.repeat(20))
}) })
it('show warning alert in renderer and as modal', () => { it('shows a warning and opens a modal', () => {
cy.get('.CodeMirror textarea') cy.get('@codeinput')
.type('a') .fill(tooMuchTestContent)
cy.get('.modal-body.limit-warning') cy.get('[data-cy="limitReachedModal"]')
.should('be.visible')
cy.get('[data-cy="limitReachedMessage"]')
.should('be.visible') .should('be.visible')
cy.get('.splitter .alert-danger')
.should('be.visible')
}) })
}) })

View file

@ -1,37 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
describe('yaml-metadata: tags', () => {
beforeEach(() => {
cy.visit('/n/features')
cy.get('.CodeMirror textarea')
.type('{ctrl}a', { force: true })
.type('{backspace}')
})
it('show deprecation notice on old syntax', () => {
cy.get('.CodeMirror textarea')
.type('---\ntags: a, b, c\n---')
cy.get('.splitter.right .w-100.h-100 .alert.alert-warning')
.should('be.visible')
})
it('show no deprecation notice on yaml-array (1)', () => {
cy.get('.CodeMirror textarea')
.type('---\ntags: [\'a\', \'b\', \'c\']\n---')
cy.get('.splitter.right .w-100.h-100 .alert.alert-warning')
.should('not.exist')
})
it('show no deprecation notice on yaml-array (2)', () => {
cy.get('.CodeMirror textarea')
.type('---\ntags:\n - a\nb\nc\n')
.type('{backspace}{backspace}{backspace}{backspace}')
.type('---')
cy.get('.splitter.right .w-100.h-100 .alert.alert-warning')
.should('not.exist')
})
})

View file

@ -4,23 +4,38 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
const testText = 'textText'
const testLink = 'http://hedgedoc.org'
describe('Toolbar', () => { describe('Toolbar', () => {
const testText = 'textText'
const testLink = 'http://hedgedoc.org'
beforeEach(() => { beforeEach(() => {
cy.visit('/n/test') cy.visit('/n/test')
cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
.should('exist') cy.get('.CodeMirror')
cy.get('.CodeMirror textarea') .click()
.type('{ctrl}a', { force: true }) .get('textarea')
.type('{backspace}') .as('codeinput')
cy.viewport(1920, 1080)
}) })
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', () => { it('bold', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-bold') cy.get('.fa-bold')
.click() .click()
@ -29,8 +44,8 @@ describe('Toolbar', () => {
}) })
it('italic', () => { it('italic', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-italic') cy.get('.fa-italic')
.click() .click()
@ -39,8 +54,8 @@ describe('Toolbar', () => {
}) })
it('underline', () => { it('underline', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-underline') cy.get('.fa-underline')
.click() .click()
@ -49,8 +64,8 @@ describe('Toolbar', () => {
}) })
it('strikethrough', () => { it('strikethrough', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-strikethrough') cy.get('.fa-strikethrough')
.click() .click()
@ -59,8 +74,8 @@ describe('Toolbar', () => {
}) })
it('subscript', () => { it('subscript', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-subscript') cy.get('.fa-subscript')
.click() .click()
@ -69,8 +84,8 @@ describe('Toolbar', () => {
}) })
it('superscript', () => { it('superscript', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-superscript') cy.get('.fa-superscript')
.click() .click()
@ -79,8 +94,7 @@ describe('Toolbar', () => {
}) })
it('heading', () => { it('heading', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-header') cy.get('.fa-header')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -93,8 +107,8 @@ describe('Toolbar', () => {
describe('code', () => { describe('code', () => {
it('nothing selected empty line', () => { it('nothing selected empty line', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
.type('{backspace}') .type('{backspace}')
cy.get('.fa-code') cy.get('.fa-code')
@ -106,8 +120,8 @@ describe('Toolbar', () => {
}) })
it('nothing selected non line', () => { it('nothing selected non line', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
.type('{leftArrow}') .type('{leftArrow}')
cy.get('.fa-code') cy.get('.fa-code')
@ -121,8 +135,8 @@ describe('Toolbar', () => {
}) })
it('line selected', () => { it('line selected', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-code') cy.get('.fa-code')
.click() .click()
@ -136,8 +150,7 @@ describe('Toolbar', () => {
}) })
it('quote', () => { it('quote', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-quote-right') cy.get('.fa-quote-right')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -149,8 +162,7 @@ describe('Toolbar', () => {
}) })
it('unordered list', () => { it('unordered list', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-list') cy.get('.fa-list')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -162,8 +174,7 @@ describe('Toolbar', () => {
}) })
it('ordered list', () => { it('ordered list', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-list-ol') cy.get('.fa-list-ol')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -175,8 +186,7 @@ describe('Toolbar', () => {
}) })
it('todo list', () => { it('todo list', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-check-square') cy.get('.fa-check-square')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -189,8 +199,8 @@ describe('Toolbar', () => {
describe('link', () => { describe('link', () => {
it('with selection text', () => { it('with selection text', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-link') cy.get('.fa-link')
.click() .click()
@ -199,8 +209,7 @@ describe('Toolbar', () => {
}) })
it('without selection', () => { it('without selection', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-link') cy.get('.fa-link')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -208,8 +217,8 @@ describe('Toolbar', () => {
}) })
it('with selection link', () => { it('with selection link', () => {
cy.get('.CodeMirror textarea') fillTestLink()
.type(`${testLink}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-link') cy.get('.fa-link')
.click() .click()
@ -220,8 +229,8 @@ describe('Toolbar', () => {
describe('image', () => { describe('image', () => {
it('with selection', () => { it('with selection', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-picture-o') cy.get('.fa-picture-o')
.click() .click()
@ -230,8 +239,7 @@ describe('Toolbar', () => {
}) })
it('without selection', () => { it('without selection', () => {
cy.get('.CodeMirror textarea') fillTestText()
.type(`${testText}`)
cy.get('.fa-picture-o') cy.get('.fa-picture-o')
.click() .click()
cy.get('.CodeMirror-activeline > .CodeMirror-line > span') cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
@ -239,8 +247,8 @@ describe('Toolbar', () => {
}) })
it('with selection link', () => { it('with selection link', () => {
cy.get('.CodeMirror textarea') fillTestLink()
.type(`${testLink}`) cy.get('@codeinput')
.type('{ctrl}a') .type('{ctrl}a')
cy.get('.fa-picture-o') cy.get('.fa-picture-o')
.click() .click()
@ -312,9 +320,9 @@ describe('Toolbar', () => {
it('collapsable block', () => { it('collapsable block', () => {
cy.get('.fa-caret-square-o-down') cy.get('.fa-caret-square-o-down')
.click() .click()
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span') cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span')
.should('have.text', '<details>') .should('have.text', '<details>')
}) })
it('comment', () => { it('comment', () => {

View file

@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
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.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.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.get('[data-cy="yamlArrayDeprecationAlert"]')
.should('not.exist')
})
})

View file

@ -26,7 +26,7 @@ export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18
useTranslation() useTranslation()
return ( return (
<Modal show={show} onHide={onHide} animation={true} dialogClassName={`text-dark ${additionalClasses ?? ''}`} size={size}> <Modal data-cy={'limitReachedModal'} show={show} onHide={onHide} animation={true} dialogClassName={`text-dark ${additionalClasses ?? ''}`} size={size}>
<Modal.Header closeButton={!!closeButton}> <Modal.Header closeButton={!!closeButton}>
<Modal.Title> <Modal.Title>
<ShowIf condition={!!icon}> <ShowIf condition={!!icon}>

View file

@ -6,20 +6,18 @@ SPDX-License-Identifier: AGPL-3.0-only
import { TocAst } from 'markdown-it-toc-done-right' import { TocAst } from 'markdown-it-toc-done-right'
import React, { RefObject, useRef, useState } from 'react' import React, { RefObject, useRef, useState } from 'react'
import { Alert, Dropdown } from 'react-bootstrap' import { Dropdown } from 'react-bootstrap'
import { Trans } from 'react-i18next'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import useResizeObserver from 'use-resize-observer' import useResizeObserver from 'use-resize-observer'
import links from '../../../links.json'
import { ApplicationState } from '../../../redux' import { ApplicationState } from '../../../redux'
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
import { ShowIf } from '../../common/show-if/show-if' import { ShowIf } from '../../common/show-if/show-if'
import { FullMarkdownRenderer } from '../../markdown-renderer/full-markdown-renderer' import { FullMarkdownRenderer } from '../../markdown-renderer/full-markdown-renderer'
import { LineMarkerPosition } from '../../markdown-renderer/types' import { LineMarkerPosition } from '../../markdown-renderer/types'
import { TableOfContents } from '../table-of-contents/table-of-contents' import { TableOfContents } from '../table-of-contents/table-of-contents'
import { YAMLMetaData } from '../yaml-metadata/yaml-metadata' import { YAMLMetaData } from '../yaml-metadata/yaml-metadata'
import { useAdaptedLineMarkerCallback } from './use-adapted-line-markers-callback' import { useAdaptedLineMarkerCallback } from './use-adapted-line-markers-callback'
import { YamlArrayDeprecationAlert } from './yaml-array-deprecation-alert'
export interface DocumentRenderPaneProps { export interface DocumentRenderPaneProps {
extraClasses?: string extraClasses?: string
@ -58,11 +56,7 @@ export const DocumentRenderPane: React.FC<DocumentRenderPaneProps> = ({
<div className={'col-md'}/> <div className={'col-md'}/>
<div className={'bg-light flex-fill'}> <div className={'bg-light flex-fill'}>
<ShowIf condition={yamlDeprecatedTags}> <ShowIf condition={yamlDeprecatedTags}>
<Alert variant='warning' dir='auto'> <YamlArrayDeprecationAlert/>
<Trans i18nKey='editor.deprecatedTags' />
<br/>
<TranslatedExternalLink i18nKey={'common.readForMoreInfo'} href={links.faq} className={'text-primary'}/>
</Alert>
</ShowIf> </ShowIf>
<div > <div >
<FullMarkdownRenderer <FullMarkdownRenderer

View file

@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React from 'react'
import { Alert } from 'react-bootstrap'
import { Trans } from 'react-i18next';
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
import links from '../../../links.json'
export const YamlArrayDeprecationAlert: React.FC = () => {
return (
<Alert data-cy={'yamlArrayDeprecationAlert'} variant='warning' dir='auto'>
<Trans i18nKey='editor.deprecatedTags' />
<br/>
<TranslatedExternalLink i18nKey={'common.readForMoreInfo'} href={links.faq} className={'text-primary'}/>
</Alert>
);
}

View file

@ -19,8 +19,8 @@ export const MaxLengthWarningModal: React.FC<MaxLengthWarningModalProps> = ({ sh
useTranslation() useTranslation()
return ( return (
<CommonModal show={show} onHide={onHide} titleI18nKey={'editor.error.limitReached.title'} closeButton={true}> <CommonModal data-cy={'limitReachedModal'} show={show} onHide={onHide} titleI18nKey={'editor.error.limitReached.title'} closeButton={true}>
<Modal.Body className={'limit-warning'}> <Modal.Body>
<Trans i18nKey={'editor.error.limitReached.description'} values={{ maxLength }} /> <Trans i18nKey={'editor.error.limitReached.description'} values={{ maxLength }} />
<strong className='mt-2 d-block'><Trans i18nKey={'editor.error.limitReached.advice'}/></strong> <strong className='mt-2 d-block'><Trans i18nKey={'editor.error.limitReached.advice'}/></strong>
</Modal.Body> </Modal.Body>

View file

@ -67,6 +67,7 @@ export const StatusBar: React.FC<StatusBarInfo> = ({ position, selectedColumns,
<span>{t('editor.statusBar.lines', { lines: linesInDocument })}</span> <span>{t('editor.statusBar.lines', { lines: linesInDocument })}</span>
&nbsp;&nbsp; &nbsp;&nbsp;
<span <span
data-cy={'remainingCharacters'}
title={getLengthTooltip} title={getLengthTooltip}
className={remainingCharacters <= 0 ? 'text-danger' : remainingCharacters <= 100 ? 'text-warning' : ''} className={remainingCharacters <= 0 ? 'text-danger' : remainingCharacters <= 100 ? 'text-warning' : ''}
> >

View file

@ -62,7 +62,7 @@ export const BasicMarkdownRenderer: React.FC<BasicMarkdownRendererProps & Additi
return ( return (
<div className={`${className || ''} d-flex flex-column align-items-center ${wide ? 'wider' : ''}`}> <div className={`${className || ''} d-flex flex-column align-items-center ${wide ? 'wider' : ''}`}>
<ShowIf condition={content.length > maxLength}> <ShowIf condition={content.length > maxLength}>
<Alert variant='danger' dir={'auto'}> <Alert variant='danger' dir={'auto'} data-cy={'limitReachedMessage'}>
<Trans i18nKey={'editor.error.limitReached.description'} values={{ maxLength }}/> <Trans i18nKey={'editor.error.limitReached.description'} values={{ maxLength }}/>
</Alert> </Alert>
</ShowIf> </ShowIf>

View file

@ -14,7 +14,7 @@ export const DeprecationWarning: React.FC = () => {
useTranslation() useTranslation()
return ( return (
<Alert className={'mt-2'} variant={'warning'}> <Alert data-cy={'yaml'} className={'mt-2'} variant={'warning'}>
<Trans i18nKey={'renderer.sequence.deprecationWarning'}/> <Trans i18nKey={'renderer.sequence.deprecationWarning'}/>
&nbsp; &nbsp;
<TranslatedExternalLink i18nKey={'common.readForMoreInfo'} className={'text-primary'} href={links.faq}/> <TranslatedExternalLink i18nKey={'common.readForMoreInfo'} className={'text-primary'} href={links.faq}/>

View file

@ -82,7 +82,7 @@ ReactDOM.render(
) )
if (isTestMode()) { if (isTestMode()) {
console.log("This build runs in test mode") console.log("This build runs in test mode. This means:\n - No default content in the editor")
} }
// If you want your app to work offline and load faster, you can change // If you want your app to work offline and load faster, you can change