mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-22 01:36:29 -05:00
Cypress-IDs and prettier for tests (#1634)
* Add cy.getById method and run prettier Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
parent
8a8bacc0aa
commit
d725b65140
53 changed files with 758 additions and 1203 deletions
|
@ -4,170 +4,111 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
describe('Autocompletion', () => {
|
||||
describe('Autocompletion works for', () => {
|
||||
beforeEach(() => {
|
||||
cy.visitTestEditor()
|
||||
cy.get('.CodeMirror')
|
||||
.click()
|
||||
.get('textarea')
|
||||
.as('codeinput')
|
||||
cy.get('.CodeMirror').click().get('textarea').as('codeinput')
|
||||
})
|
||||
|
||||
describe('code block', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent('```')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span')
|
||||
.should('have.text', '```abnf')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span span')
|
||||
.should('have.text', '```')
|
||||
cy.getMarkdownBody().find('.code-highlighter').should('exist')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should('have.text', '```abnf')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span > span').should('have.text', '```')
|
||||
cy.getMarkdownBody().findById('highlighted-code-block').should('exist')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('```')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span')
|
||||
.should('have.text', '```abnf')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span span')
|
||||
.should('have.text', '```')
|
||||
cy.getMarkdownBody().find('.code-highlighter').should('exist')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should('have.text', '```abnf')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span > span').should('have.text', '```')
|
||||
cy.getMarkdownBody().findById('highlighted-code-block').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('container', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent(':::')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span')
|
||||
.should('have.text', ':::success')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span span')
|
||||
.should('have.text', '::: ')
|
||||
cy.getMarkdownBody()
|
||||
.find('div.alert')
|
||||
.should('exist')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should('have.text', ':::success')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span > span').should('have.text', '::: ')
|
||||
cy.getMarkdownBody().find('div.alert').should('exist')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent(':::')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span')
|
||||
.should('have.text', ':::success')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span span')
|
||||
.should('have.text', '::: ')
|
||||
cy.getMarkdownBody()
|
||||
.find('div.alert')
|
||||
.should('exist')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should('have.text', ':::success')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span > span').should('have.text', '::: ')
|
||||
cy.getMarkdownBody().find('div.alert').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('emoji', () => {
|
||||
describe('normal emoji', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent(':hedg')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', ':hedgehog:')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', ':hedgehog:')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent(':hedg')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', ':hedgehog:')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', ':hedgehog:')
|
||||
})
|
||||
})
|
||||
|
||||
describe('fork-awesome-icon', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent(':fa-face')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', ':fa-facebook:')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', ':fa-facebook:')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent(':fa-face')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', ':fa-facebook:')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', ':fa-facebook:')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('header', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent('#')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '# ')
|
||||
cy.getMarkdownBody()
|
||||
.find('h1 ')
|
||||
.should('have.text', '\n ')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '# ')
|
||||
cy.getMarkdownBody().find('h1').should('have.text', '\n ')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('#')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '# ')
|
||||
cy.getMarkdownBody()
|
||||
.find('h1')
|
||||
.should('have.text', '\n ')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '# ')
|
||||
cy.getMarkdownBody().find('h1').should('have.text', '\n ')
|
||||
})
|
||||
})
|
||||
|
||||
describe('images', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent('!')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '![image alt](https:// "title")')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '![image alt](https:// "title")')
|
||||
cy.getMarkdownBody()
|
||||
.find('p > img')
|
||||
.should('have.attr', 'alt', 'image alt')
|
||||
|
@ -176,13 +117,9 @@ describe('Autocompletion', () => {
|
|||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('!')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '![image alt](https:// "title")')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '![image alt](https:// "title")')
|
||||
cy.getMarkdownBody()
|
||||
.find('p > img')
|
||||
.should('have.attr', 'alt', 'image alt')
|
||||
|
@ -192,16 +129,12 @@ describe('Autocompletion', () => {
|
|||
})
|
||||
|
||||
describe('links', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent('[')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '[link text](https:// "title") ')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '[link text](https:// "title") ')
|
||||
cy.getMarkdownBody()
|
||||
.find('p > a')
|
||||
.should('have.text', 'link text')
|
||||
|
@ -210,13 +143,9 @@ describe('Autocompletion', () => {
|
|||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('[')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '[link text](https:// "title") ')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '[link text](https:// "title") ')
|
||||
cy.getMarkdownBody()
|
||||
.find('p > a')
|
||||
.should('have.text', 'link text')
|
||||
|
@ -226,62 +155,38 @@ describe('Autocompletion', () => {
|
|||
})
|
||||
|
||||
describe('pdf', () => {
|
||||
it('via Enter', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent('{')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '{%pdf https:// %}')
|
||||
cy.getMarkdownBody()
|
||||
.find('p')
|
||||
.should('exist')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '{%pdf https:// %}')
|
||||
cy.getMarkdownBody().find('p').should('exist')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('{')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '{%pdf https:// %}')
|
||||
cy.getMarkdownBody()
|
||||
.find('p')
|
||||
.should('exist')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '{%pdf https:// %}')
|
||||
cy.getMarkdownBody().find('p').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('collapsable blocks', () => {
|
||||
it('via Enter', () => {
|
||||
describe('collapsible blocks', () => {
|
||||
it('via enter', () => {
|
||||
cy.setCodemirrorContent('<d')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('exist')
|
||||
cy.get('@codeinput')
|
||||
.type('{enter}')
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '</details>') // after selecting the hint, the last line of the inserted suggestion is active
|
||||
cy.getMarkdownBody()
|
||||
.find('details')
|
||||
.should('exist')
|
||||
cy.get('.CodeMirror-hints').should('exist')
|
||||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '</details>') // after selecting the hint, the last line of the inserted suggestion is active
|
||||
cy.getMarkdownBody().find('details').should('exist')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('<d')
|
||||
cy.get('.CodeMirror-hints > li')
|
||||
.first()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-hints')
|
||||
.should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', '</details>')
|
||||
cy.getMarkdownBody()
|
||||
.find('details')
|
||||
.should('exist')
|
||||
cy.get('.CodeMirror-hints > li').first().dblclick()
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', '</details>')
|
||||
cy.getMarkdownBody().find('details').should('exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,57 +11,39 @@ describe('Diagram codeblock ', () => {
|
|||
|
||||
it('renders markmap', () => {
|
||||
cy.setCodemirrorContent('```markmap\n- pro\n- contra\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id=markmap]')
|
||||
.children()
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().findById('markmap').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders vega-lite', () => {
|
||||
cy.setCodemirrorContent('```vega-lite\n{"$schema":"https://vega.github.io/schema/vega-lite/v4.json","data":{"values":[{"a":"","b":28}]},"mark":"bar","encoding":{"x":{"field":"a"},"y":{"field":"b"}}}\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('.vega-embed')
|
||||
.children()
|
||||
.should('be.visible')
|
||||
cy.setCodemirrorContent(
|
||||
'```vega-lite\n{"$schema":"https://vega.github.io/schema/vega-lite/v4.json","data":{"values":[{"a":"","b":28}]},"mark":"bar","encoding":{"x":{"field":"a"},"y":{"field":"b"}}}\n```'
|
||||
)
|
||||
cy.getMarkdownBody().find('.vega-embed').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders graphviz', () => {
|
||||
cy.setCodemirrorContent('```graphviz\ngraph {\na -- b\n}\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id=graphviz]')
|
||||
.children()
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().findById('graphviz').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders mermaid', () => {
|
||||
cy.setCodemirrorContent('```mermaid\ngraph TD;\n A-->B;\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('.mermaid')
|
||||
.children()
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().find('.mermaid').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders flowcharts', () => {
|
||||
cy.setCodemirrorContent('```flow\nst=>start: Start\ne=>end: End\nst->e\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id=flowchart]')
|
||||
.children()
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().findById('flowchart').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders abc scores', () => {
|
||||
cy.setCodemirrorContent('```abc\nM:4/4\nK:G\n|:GABc dedB:|\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('.abcjs-score')
|
||||
.children()
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().findById('abcjs').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders csv as table', () => {
|
||||
cy.setCodemirrorContent('```csv delimiter=; header\na;b;c;d\n1;2;3;4\n```')
|
||||
cy.getMarkdownBody()
|
||||
.find('.csv-html-table')
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().findById('csv-html-table').first().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders plantuml', () => {
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
describe("Document read only page", () => {
|
||||
describe('Document read only page', () => {
|
||||
it('renders the document mode', () => {
|
||||
cy.visit('/s/test')
|
||||
cy.getMarkdownBody().should("exist")
|
||||
cy.getMarkdownBody().should('exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,90 +10,74 @@ const title = 'This is a test title'
|
|||
describe('Document Title', () => {
|
||||
beforeEach(() => {
|
||||
cy.visitTestEditor()
|
||||
cy.get('.btn.active.btn-outline-secondary > i.fa-columns')
|
||||
.should('exist')
|
||||
cy.getById('view-mode-both').should('exist')
|
||||
})
|
||||
|
||||
describe('title should be yaml metadata title', () => {
|
||||
it('just yaml metadata title', () => {
|
||||
cy.setCodemirrorContent(`---\ntitle: ${ title }\n---`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`---\ntitle: ${title}\n---`)
|
||||
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('yaml metadata title and opengraph title', () => {
|
||||
cy.setCodemirrorContent(`---\ntitle: ${ title }\nopengraph:\n title: False title\n---`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`---\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.setCodemirrorContent(`---\ntitle: ${ title }\nopengraph:\n title: False title\n---\n# a first title`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`---\ntitle: ${title}\nopengraph:\n title: False title\n---\n# a first title`)
|
||||
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('title should be opengraph title', () => {
|
||||
it('just opengraph title', () => {
|
||||
cy.setCodemirrorContent(`---\nopengraph:\n title: ${ title }\n---`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`---\nopengraph:\n title: ${title}\n---`)
|
||||
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('opengraph title and first heading', () => {
|
||||
cy.setCodemirrorContent(`---\nopengraph:\n title: ${ title }\n---\n# a first title`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`---\nopengraph:\n title: ${title}\n---\n# a first title`)
|
||||
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('title should be first heading', () => {
|
||||
it('just first heading', () => {
|
||||
cy.setCodemirrorContent(`# ${ title }`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`# ${title}`)
|
||||
cy.title().should('eq', `${title} - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('just first heading with alt-text instead of image', () => {
|
||||
cy.setCodemirrorContent(`# ${ title } ![abc](https://dummyimage.com/48)`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } abc - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`# ${title} ![abc](https://dummyimage.com/48)`)
|
||||
cy.title().should('eq', `${title} abc - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('just first heading without link syntax', () => {
|
||||
cy.setCodemirrorContent(`# ${ title } [link](https://hedgedoc.org)`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } link - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`# ${title} [link](https://hedgedoc.org)`)
|
||||
cy.title().should('eq', `${title} link - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('markdown syntax removed first', () => {
|
||||
cy.setCodemirrorContent(`# ${ title } 1*2*3 4*5**`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } 123 4*5** - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`# ${title} 1*2*3 4*5**`)
|
||||
cy.title().should('eq', `${title} 123 4*5** - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('markdown syntax removed second', () => {
|
||||
cy.setCodemirrorContent(`# ${ title } **1 2*`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } *1 2 - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`# ${title} **1 2*`)
|
||||
cy.title().should('eq', `${title} *1 2 - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('markdown syntax removed third', () => {
|
||||
cy.setCodemirrorContent(`# ${ title } _asd_`)
|
||||
cy.title()
|
||||
.should('eq', `${ title } asd - HedgeDoc @ ${ branding.name }`)
|
||||
cy.setCodemirrorContent(`# ${title} _asd_`)
|
||||
cy.title().should('eq', `${title} asd - HedgeDoc @ ${branding.name}`)
|
||||
})
|
||||
|
||||
it('katex code looks right', () => {
|
||||
cy.setCodemirrorContent(`# $\\alpha$-foo`)
|
||||
cy.getIframeBody()
|
||||
.find('h1')
|
||||
.should('contain', 'α')
|
||||
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 }`)
|
||||
cy.getIframeBody().find('h1').should('contain', 'α')
|
||||
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}`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -7,25 +7,18 @@
|
|||
describe('Editor mode from URL parameter is used', () => {
|
||||
it('mode view', () => {
|
||||
cy.visitTestEditor('view')
|
||||
cy.get('.splitter.left')
|
||||
.should('have.class', 'd-none')
|
||||
cy.get('.splitter.right')
|
||||
.should('not.have.class', 'd-none')
|
||||
cy.get('.splitter.left').should('not.be.visible')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
})
|
||||
it('mode both', () => {
|
||||
cy.visitTestEditor('both')
|
||||
cy.get('.splitter.left')
|
||||
.should('not.have.class', 'd-none')
|
||||
cy.get('.splitter.separator')
|
||||
.should('exist')
|
||||
cy.get('.splitter.right')
|
||||
.should('not.have.class', 'd-none')
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.separator').should('exist')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
})
|
||||
it('mode edit', () => {
|
||||
cy.visitTestEditor('edit')
|
||||
cy.get('.splitter.left')
|
||||
.should('not.have.class', 'd-none')
|
||||
cy.get('.splitter.right')
|
||||
.should('have.class', 'd-none')
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.right').should('not.be.visible')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
describe('emojis', () => {
|
||||
|
||||
const HEDGEHOG_UNICODE_CHARACTER = '\n🦔\n'
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -14,20 +13,16 @@ describe('emojis', () => {
|
|||
|
||||
it('renders an emoji shortcode', () => {
|
||||
cy.setCodemirrorContent(':hedgehog:')
|
||||
cy.getMarkdownBody()
|
||||
.should('have.text', HEDGEHOG_UNICODE_CHARACTER)
|
||||
cy.getMarkdownBody().should('have.text', HEDGEHOG_UNICODE_CHARACTER)
|
||||
})
|
||||
|
||||
it('renders an emoji unicode character', () => {
|
||||
cy.setCodemirrorContent(HEDGEHOG_UNICODE_CHARACTER)
|
||||
cy.getMarkdownBody()
|
||||
.should('have.text', HEDGEHOG_UNICODE_CHARACTER)
|
||||
cy.getMarkdownBody().should('have.text', HEDGEHOG_UNICODE_CHARACTER)
|
||||
})
|
||||
|
||||
it('renders an fork awesome icon', () => {
|
||||
cy.setCodemirrorContent(':fa-matrix-org:')
|
||||
cy.getMarkdownBody()
|
||||
.find('i.fa.fa-matrix-org')
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().find('i.fa.fa-matrix-org').should('be.visible')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
describe('Export', () => {
|
||||
const testTitle = 'testContent'
|
||||
const testContent = `---\ntitle: ${ testTitle }\n---\nThis is some test content`
|
||||
const testContent = `---\ntitle: ${testTitle}\n---\nThis is some test content`
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visitTestEditor()
|
||||
|
@ -14,34 +14,33 @@ describe('Export', () => {
|
|||
})
|
||||
|
||||
it('Markdown', () => {
|
||||
cy.get('[data-cypress-id="menu-export"]')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="menu-export-markdown"]')
|
||||
.click()
|
||||
cy.getById('menu-export').click()
|
||||
cy.getById('menu-export-markdown').click()
|
||||
cy.get('a[download]')
|
||||
.then((anchor) => (
|
||||
new Cypress.Promise((resolve: any, _: any) => {
|
||||
// Use XHR to get the blob that corresponds to the object URL.
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.open('GET', anchor.prop('href'), true)
|
||||
xhr.responseType = 'blob'
|
||||
.then(
|
||||
(anchor) =>
|
||||
new Cypress.Promise((resolve: any, _: any) => {
|
||||
// Use XHR to get the blob that corresponds to the object URL.
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.open('GET', anchor.prop('href'), true)
|
||||
xhr.responseType = 'blob'
|
||||
|
||||
// Once loaded, use FileReader to get the string back from the blob.
|
||||
xhr.onload = () => {
|
||||
if (xhr.status === 200) {
|
||||
const blob = xhr.response
|
||||
const reader = new FileReader()
|
||||
reader.onload = () => {
|
||||
// Once we have a string, resolve the promise to let
|
||||
// the Cypress chain continue, e.g. to assert on the result.
|
||||
resolve(reader.result)
|
||||
// Once loaded, use FileReader to get the string back from the blob.
|
||||
xhr.onload = () => {
|
||||
if (xhr.status === 200) {
|
||||
const blob = xhr.response
|
||||
const reader = new FileReader()
|
||||
reader.onload = () => {
|
||||
// Once we have a string, resolve the promise to let
|
||||
// the Cypress chain continue, e.g. to assert on the result.
|
||||
resolve(reader.result)
|
||||
}
|
||||
reader.readAsText(blob)
|
||||
}
|
||||
reader.readAsText(blob)
|
||||
}
|
||||
}
|
||||
xhr.send()
|
||||
})
|
||||
))
|
||||
xhr.send()
|
||||
})
|
||||
)
|
||||
// Now the regular Cypress assertions should work.
|
||||
.should('equal', testContent)
|
||||
})
|
||||
|
|
|
@ -11,106 +11,93 @@ describe('File upload', () => {
|
|||
cy.visitTestEditor()
|
||||
})
|
||||
|
||||
it('doesn\'t prevent drag\'n\'drop of plain text', () => {
|
||||
it("doesn't prevent drag'n'drop of plain text", () => {
|
||||
const dataTransfer = new DataTransfer()
|
||||
cy.setCodemirrorContent('line 1\nline 2\ndragline')
|
||||
cy.get('.CodeMirror')
|
||||
.click()
|
||||
cy.get('.CodeMirror-line > span')
|
||||
.last()
|
||||
.dblclick()
|
||||
cy.get('.CodeMirror-line > span > .cm-matchhighlight')
|
||||
.trigger('dragstart', { dataTransfer })
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span span')
|
||||
.trigger('drop', { dataTransfer })
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span span')
|
||||
.should('have.text', 'lindraglinee 1')
|
||||
cy.get('.CodeMirror').click()
|
||||
cy.get('.CodeMirror-line > span').last().dblclick()
|
||||
cy.get('.CodeMirror-line > span > .cm-matchhighlight').trigger('dragstart', { dataTransfer })
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').trigger('drop', { dataTransfer })
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should(
|
||||
'have.text',
|
||||
'lindraglinee 1'
|
||||
)
|
||||
})
|
||||
|
||||
describe('upload works', () => {
|
||||
describe('works', () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: '/mock-backend/api/private/media/upload-post'
|
||||
}, {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
link: imageUrl
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: '/mock-backend/api/private/media/upload-post'
|
||||
},
|
||||
{
|
||||
statusCode: 200,
|
||||
body: {
|
||||
link: imageUrl
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
it('via button', () => {
|
||||
cy.get('.fa-upload')
|
||||
.click()
|
||||
cy.get('div.btn-group > input[type=file]')
|
||||
.attachFile({ filePath: 'demo.png', mimeType: 'image/png' })
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `![](${ imageUrl })`)
|
||||
cy.getById('editor-toolbar-upload-image-button').click()
|
||||
cy.getById('editor-toolbar-upload-image-input').attachFile({ filePath: 'demo.png', mimeType: 'image/png' })
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `![](${imageUrl})`)
|
||||
})
|
||||
|
||||
it('via paste', () => {
|
||||
cy.fixture('demo.png')
|
||||
.then((image: string) => {
|
||||
const pasteEvent = {
|
||||
clipboardData: {
|
||||
files: [Cypress.Blob.base64StringToBlob(image, 'image/png')],
|
||||
getData: (_: string) => ''
|
||||
}
|
||||
cy.fixture('demo.png').then((image: string) => {
|
||||
const pasteEvent = {
|
||||
clipboardData: {
|
||||
files: [Cypress.Blob.base64StringToBlob(image, 'image/png')],
|
||||
getData: (_: string) => ''
|
||||
}
|
||||
cy.get('.CodeMirror-scroll')
|
||||
.trigger('paste', pasteEvent)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `![](${ imageUrl })`)
|
||||
})
|
||||
}
|
||||
cy.get('.CodeMirror-scroll').trigger('paste', pasteEvent)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `![](${imageUrl})`)
|
||||
})
|
||||
})
|
||||
|
||||
it('via drag and drop', () => {
|
||||
cy.fixture('demo.png')
|
||||
.then((image: string) => {
|
||||
const dropEvent = {
|
||||
dataTransfer: {
|
||||
files: [Cypress.Blob.base64StringToBlob(image, 'image/png')],
|
||||
effectAllowed: 'uninitialized'
|
||||
}
|
||||
cy.fixture('demo.png').then((image: string) => {
|
||||
const dropEvent = {
|
||||
dataTransfer: {
|
||||
files: [Cypress.Blob.base64StringToBlob(image, 'image/png')],
|
||||
effectAllowed: 'uninitialized'
|
||||
}
|
||||
cy.get('.CodeMirror-scroll')
|
||||
.trigger('dragenter', dropEvent)
|
||||
cy.get('.CodeMirror-scroll')
|
||||
.trigger('drop', dropEvent)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `![](${ imageUrl })`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('upload fails', () => {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: '/mock-backend/api/private/media/upload-post'
|
||||
}, {
|
||||
statusCode: 400
|
||||
})
|
||||
cy.get('.fa-upload')
|
||||
.click()
|
||||
cy.fixture('demo.png')
|
||||
.then(() => {
|
||||
cy.get('input[type=file]')
|
||||
.attachFile({ filePath: 'demo.png', mimeType: 'image/png' })
|
||||
}
|
||||
cy.get('.CodeMirror-scroll').trigger('dragenter', dropEvent)
|
||||
cy.get('.CodeMirror-scroll').trigger('drop', dropEvent)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `![](${imageUrl})`)
|
||||
})
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span > span')
|
||||
.should('have.text', String.fromCharCode(8203)) //thanks codemirror....
|
||||
})
|
||||
})
|
||||
|
||||
it('text paste still works', () => {
|
||||
it('fails', () => {
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: '/mock-backend/api/private/media/upload-post'
|
||||
},
|
||||
{
|
||||
statusCode: 400
|
||||
}
|
||||
)
|
||||
cy.getById('editor-toolbar-upload-image-button').click()
|
||||
cy.fixture('demo.png').then(() => {
|
||||
cy.getById('editor-toolbar-upload-image-input').attachFile({ filePath: 'demo.png', mimeType: 'image/png' })
|
||||
})
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span > span').should('have.text', String.fromCharCode(8203)) //thanks codemirror....
|
||||
})
|
||||
|
||||
it('lets text paste still work', () => {
|
||||
const testText = 'a long test text'
|
||||
const pasteEvent = {
|
||||
clipboardData: {
|
||||
getData: (type = 'text') => testText
|
||||
}
|
||||
}
|
||||
cy.get('.CodeMirror-scroll')
|
||||
.trigger('paste', pasteEvent)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `${ testText }`)
|
||||
cy.get('.CodeMirror-scroll').trigger('paste', pasteEvent)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `${testText}`)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,10 +10,7 @@ describe('Help Dialog', () => {
|
|||
})
|
||||
|
||||
it('ToDo-List', () => {
|
||||
cy.get('.fa.fa-question-circle')
|
||||
.click()
|
||||
cy.get('input[type="checkbox"]')
|
||||
.should('exist')
|
||||
.should('not.be.checked')
|
||||
cy.getById('editor-help-button').click()
|
||||
cy.get('input[type="checkbox"]').should('exist').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,26 +14,19 @@ describe('Code', () => {
|
|||
})
|
||||
|
||||
describe('with just the language', () => {
|
||||
it('doesn\'t show a gutter', () => {
|
||||
it("doesn't show a gutter", () => {
|
||||
cy.setCodemirrorContent('```javascript \nlet x = 0\n```')
|
||||
findHljsCodeBlock()
|
||||
.should('not.have.class', 'showGutter')
|
||||
findHljsCodeBlock().should('not.have.class', 'showGutter')
|
||||
|
||||
findHljsCodeBlock()
|
||||
.find('.linenumber')
|
||||
.should('not.be.visible')
|
||||
findHljsCodeBlock().find('.linenumber').should('not.be.visible')
|
||||
})
|
||||
|
||||
describe('and line wrapping', () => {
|
||||
it('doesn\'t show a gutter', () => {
|
||||
it("doesn't show a gutter", () => {
|
||||
cy.setCodemirrorContent('```javascript! \nlet x = 0\n```')
|
||||
findHljsCodeBlock()
|
||||
.should('not.have.class', 'showGutter')
|
||||
.should('have.class', 'wrapLines')
|
||||
findHljsCodeBlock().should('not.have.class', 'showGutter').should('have.class', 'wrapLines')
|
||||
|
||||
findHljsCodeBlock()
|
||||
.find('.linenumber')
|
||||
.should('not.be.visible')
|
||||
findHljsCodeBlock().find('.linenumber').should('not.be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -41,28 +34,17 @@ describe('Code', () => {
|
|||
describe('with the language and show gutter', () => {
|
||||
it('shows the correct line number', () => {
|
||||
cy.setCodemirrorContent('```javascript= \nlet x = 0\n```')
|
||||
findHljsCodeBlock()
|
||||
.should('have.class', 'showGutter')
|
||||
findHljsCodeBlock().should('have.class', 'showGutter')
|
||||
|
||||
findHljsCodeBlock()
|
||||
.find('.linenumber')
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '1')
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '1')
|
||||
})
|
||||
|
||||
describe('and line wrapping', () => {
|
||||
it('shows the correct line number', () => {
|
||||
cy.setCodemirrorContent('```javascript=! \nlet x = 0\n```')
|
||||
findHljsCodeBlock()
|
||||
.should('have.class', 'showGutter')
|
||||
.should('have.class', 'wrapLines')
|
||||
findHljsCodeBlock().should('have.class', 'showGutter').should('have.class', 'wrapLines')
|
||||
|
||||
findHljsCodeBlock()
|
||||
.find('.linenumber')
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '1')
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '1')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -70,14 +52,9 @@ describe('Code', () => {
|
|||
describe('with the language, show gutter with a start number', () => {
|
||||
it('shows the correct line number', () => {
|
||||
cy.setCodemirrorContent('```javascript=100 \nlet x = 0\n```')
|
||||
findHljsCodeBlock()
|
||||
.should('have.class', 'showGutter')
|
||||
findHljsCodeBlock().should('have.class', 'showGutter')
|
||||
|
||||
findHljsCodeBlock()
|
||||
.find('.linenumber')
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '100')
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '100')
|
||||
})
|
||||
|
||||
it('shows the correct line number and continues in another codeblock', () => {
|
||||
|
@ -90,33 +67,15 @@ describe('Code', () => {
|
|||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '100')
|
||||
findHljsCodeBlock()
|
||||
.first()
|
||||
.find('.linenumber')
|
||||
.last()
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '101')
|
||||
findHljsCodeBlock()
|
||||
.last()
|
||||
.find('.linenumber')
|
||||
.first()
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '102')
|
||||
findHljsCodeBlock().first().find('.linenumber').last().should('be.visible').text().should('eq', '101')
|
||||
findHljsCodeBlock().last().find('.linenumber').first().should('be.visible').text().should('eq', '102')
|
||||
})
|
||||
|
||||
describe('and line wrapping', () => {
|
||||
it('shows the correct line number', () => {
|
||||
cy.setCodemirrorContent('```javascript=100! \nlet x = 0\n```')
|
||||
findHljsCodeBlock()
|
||||
.should('have.class', 'showGutter')
|
||||
.should('have.class', 'wrapLines')
|
||||
findHljsCodeBlock()
|
||||
.find('.linenumber')
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '100')
|
||||
findHljsCodeBlock().should('have.class', 'showGutter').should('have.class', 'wrapLines')
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '100')
|
||||
})
|
||||
|
||||
it('shows the correct line number and continues in another codeblock', () => {
|
||||
|
@ -130,20 +89,8 @@ describe('Code', () => {
|
|||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '100')
|
||||
findHljsCodeBlock()
|
||||
.first()
|
||||
.find('.linenumber')
|
||||
.last()
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '101')
|
||||
findHljsCodeBlock()
|
||||
.last()
|
||||
.find('.linenumber')
|
||||
.first()
|
||||
.should('be.visible')
|
||||
.text()
|
||||
.should('eq', '102')
|
||||
findHljsCodeBlock().first().find('.linenumber').last().should('be.visible').text().should('eq', '101')
|
||||
findHljsCodeBlock().last().find('.linenumber').first().should('be.visible').text().should('eq', '102')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -151,22 +98,17 @@ describe('Code', () => {
|
|||
it('has a working copy button', () => {
|
||||
cy.setCodemirrorContent('```javascript \nlet x = 0\n```')
|
||||
|
||||
cy.get(`iframe[data-cypress-id="documentIframe"]`)
|
||||
.then(($element: JQuery) => {
|
||||
const frame = $element[0] as HTMLIFrameElement
|
||||
if (frame === null || frame.contentWindow === null) {
|
||||
return cy.wrap(null)
|
||||
}
|
||||
cy.getById('documentIframe').then((element: JQuery<HTMLElement>) => {
|
||||
const frame = element.get(0) as HTMLIFrameElement
|
||||
if (frame === null || frame.contentWindow === null) {
|
||||
return cy.wrap(null)
|
||||
}
|
||||
|
||||
cy.spy(frame.contentWindow.navigator.clipboard, 'writeText')
|
||||
.as('copy')
|
||||
})
|
||||
cy.spy(frame.contentWindow.navigator.clipboard, 'writeText').as('copy')
|
||||
})
|
||||
|
||||
cy.getIframeBody()
|
||||
.find('[data-cypress-id="copy-code-button"]')
|
||||
.click()
|
||||
cy.getIframeBody().findById('copy-code-button').click()
|
||||
|
||||
cy.get('@copy')
|
||||
.should('be.calledWithExactly', 'let x = 0\n')
|
||||
cy.get('@copy').should('be.calledWithExactly', 'let x = 0\n')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,12 +11,12 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('Cards', () => {
|
||||
cy.get('div.card').should('be.visible')
|
||||
cy.getById('history-card').should('be.visible')
|
||||
})
|
||||
|
||||
it('Table', () => {
|
||||
cy.get('[data-cypress-id="history-mode-table"]').click()
|
||||
cy.get('[data-cypress-id="history-table"]').should('be.visible')
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-table').should('be.visible')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -39,13 +39,13 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('in table view', () => {
|
||||
cy.get('[data-cypress-id="history-mode-table"]').click()
|
||||
cy.get('[data-cypress-id="history-table"]').should('be.visible')
|
||||
cy.get('[data-cypress-id="history-entry-title"]').contains('Features')
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-table').should('be.visible')
|
||||
cy.getById('history-entry-title').contains('Features')
|
||||
})
|
||||
|
||||
it('in cards view', () => {
|
||||
cy.get('[data-cypress-id="history-entry-title"]').contains('Features')
|
||||
cy.getById('history-entry-title').contains('Features')
|
||||
})
|
||||
})
|
||||
describe('is untitled when not empty', () => {
|
||||
|
@ -66,13 +66,13 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('in table view', () => {
|
||||
cy.get('[data-cypress-id="history-mode-table"]').click()
|
||||
cy.get('[data-cypress-id="history-table"]').should('be.visible')
|
||||
cy.get('[data-cypress-id="history-entry-title"]').contains('Untitled')
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-table').should('be.visible')
|
||||
cy.getById('history-entry-title').contains('Untitled')
|
||||
})
|
||||
|
||||
it('in cards view', () => {
|
||||
cy.get('[data-cypress-id="history-entry-title"]').contains('Untitled')
|
||||
cy.getById('history-entry-title').contains('Untitled')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -90,15 +90,15 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('Cards', () => {
|
||||
cy.get('div.card').should('be.visible')
|
||||
cy.get('.history-pin.btn').first().as('pin-button')
|
||||
cy.getById('history-card').should('be.visible')
|
||||
cy.getById('history-entry-pin-button').first().as('pin-button')
|
||||
cy.get('@pin-button').should('have.class', 'pinned').click()
|
||||
cy.get('@pin-button').should('not.have.class', 'pinned')
|
||||
})
|
||||
|
||||
it('Table', () => {
|
||||
cy.get('i.fa-table').click()
|
||||
cy.get('.history-pin.btn').first().as('pin-button')
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-entry-pin-button').first().as('pin-button')
|
||||
cy.get('@pin-button').should('have.class', 'pinned').click()
|
||||
cy.get('@pin-button').should('not.have.class', 'pinned')
|
||||
})
|
||||
|
@ -112,15 +112,15 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('Cards', () => {
|
||||
cy.get('div.card').should('be.visible')
|
||||
cy.get('.fa-thumb-tack').first().click()
|
||||
cy.get('.notifications-area .toast').should('be.visible')
|
||||
cy.getById('history-card').should('be.visible')
|
||||
cy.getById('history-entry-pin-button').first().click()
|
||||
cy.getById('notification-toast').should('be.visible')
|
||||
})
|
||||
|
||||
it('Table', () => {
|
||||
cy.get('i.fa-table').click()
|
||||
cy.get('.fa-thumb-tack').first().click()
|
||||
cy.get('.notifications-area .toast').should('be.visible')
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-entry-pin-button').first().click()
|
||||
cy.getById('notification-toast').should('be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -136,43 +136,37 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('works with valid file', () => {
|
||||
cy.get('[data-cypress-id="import-history-file-button"]').click()
|
||||
cy.get('[data-cypress-id="import-history-file-input"]').attachFile({
|
||||
cy.getById('import-history-file-button').click()
|
||||
cy.getById('import-history-file-input').attachFile({
|
||||
filePath: 'history.json',
|
||||
mimeType: 'application/json'
|
||||
})
|
||||
cy.get('[data-cypress-id="history-entry-title"]')
|
||||
.should('have.length', 1)
|
||||
.contains('cy-Test')
|
||||
cy.getById('history-entry-title').should('have.length', 1).contains('cy-Test')
|
||||
})
|
||||
|
||||
it('fails on invalid file', () => {
|
||||
cy.get('[data-cypress-id="import-history-file-button"]').click()
|
||||
cy.get('[data-cypress-id="import-history-file-input"]').attachFile({
|
||||
cy.getById('import-history-file-button').click()
|
||||
cy.getById('import-history-file-input').attachFile({
|
||||
filePath: 'history.json.license',
|
||||
mimeType: 'text/plain'
|
||||
})
|
||||
cy.get('[data-cypress-id="notification-toast"]').should('be.visible')
|
||||
cy.getById('notification-toast').should('be.visible')
|
||||
})
|
||||
|
||||
it('works when selecting two files with the same name', () => {
|
||||
cy.get('[data-cypress-id="import-history-file-button"]').click()
|
||||
cy.get('[data-cypress-id="import-history-file-input"]').attachFile({
|
||||
cy.getById('import-history-file-button').click()
|
||||
cy.getById('import-history-file-input').attachFile({
|
||||
filePath: 'history.json',
|
||||
mimeType: 'application/json'
|
||||
})
|
||||
cy.get('[data-cypress-id="history-entry-title"]')
|
||||
.should('have.length', 1)
|
||||
.contains('cy-Test')
|
||||
cy.get('[data-cypress-id="import-history-file-button"]').click()
|
||||
cy.get('[data-cypress-id="import-history-file-input"]').attachFile({
|
||||
cy.getById('history-entry-title').should('have.length', 1).contains('cy-Test')
|
||||
cy.getById('import-history-file-button').click()
|
||||
cy.getById('import-history-file-input').attachFile({
|
||||
filePath: 'history-2.json',
|
||||
fileName: 'history.json',
|
||||
mimeType: 'application/json'
|
||||
})
|
||||
cy.get('[data-cypress-id="history-entry-title"]')
|
||||
.should('have.length', 2)
|
||||
.contains('cy-Test2')
|
||||
cy.getById('history-entry-title').should('have.length', 2).contains('cy-Test2')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,34 +10,33 @@ describe('Import markdown file', () => {
|
|||
})
|
||||
|
||||
it('import on blank note', () => {
|
||||
cy.get('[data-cypress-id="menu-import"]')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="menu-import-markdown"]')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="menu-import-markdown-input"]')
|
||||
.attachFile({ filePath: 'import.md', mimeType: 'text/markdown' })
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span')
|
||||
.should('have.text', '# Some short import test file')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span > span')
|
||||
.should('have.text', ':)')
|
||||
cy.getById('menu-import').click()
|
||||
cy.getById('menu-import-markdown').click()
|
||||
cy.getById('menu-import-markdown-input').attachFile({
|
||||
filePath: 'import.md',
|
||||
mimeType: 'text/markdown'
|
||||
})
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should(
|
||||
'have.text',
|
||||
'# Some short import test file'
|
||||
)
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span > span').should('have.text', ':)')
|
||||
})
|
||||
|
||||
it('import on note with content', () => {
|
||||
|
||||
cy.setCodemirrorContent('test\nabc')
|
||||
cy.get('[data-cypress-id="menu-import"]')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="menu-import-markdown"]')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="menu-import-markdown-input"]')
|
||||
.attachFile({ filePath: 'import.md', mimeType: 'text/markdown' })
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span')
|
||||
.should('have.text', 'test')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span > span')
|
||||
.should('have.text', 'abc')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span > span')
|
||||
.should('have.text', '# Some short import test file')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(4) > .CodeMirror-line > span > span')
|
||||
.should('have.text', ':)')
|
||||
cy.getById('menu-import').click()
|
||||
cy.getById('menu-import-markdown').click()
|
||||
cy.getById('menu-import-markdown-input').attachFile({
|
||||
filePath: 'import.md',
|
||||
mimeType: 'text/markdown'
|
||||
})
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line > span > span').should('have.text', 'test')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span > span').should('have.text', 'abc')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span > span').should(
|
||||
'have.text',
|
||||
'# Some short import test file'
|
||||
)
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(4) > .CodeMirror-line > span > span').should('have.text', ':)')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -13,58 +13,48 @@ describe('Intro page', () => {
|
|||
|
||||
describe('customizable content', () => {
|
||||
it('fetches and shows the correct intro page content', () => {
|
||||
cy.getMarkdownBody()
|
||||
.contains('test content')
|
||||
cy.getMarkdownBody().contains('test content')
|
||||
})
|
||||
|
||||
it('won\'t show anything if no content was found', () => {
|
||||
it("won't show anything if no content was found", () => {
|
||||
cy.intercept('/mock-backend/public/intro.md', {
|
||||
statusCode: 404
|
||||
})
|
||||
cy.visit('/')
|
||||
|
||||
cy.get(`iframe[data-cypress-id="documentIframe"]`)
|
||||
.should('not.exist')
|
||||
cy.getById('documentIframe').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('features button', () => {
|
||||
it('is hidden when logged in', () => {
|
||||
cy.get('[data-cypress-id="features-button"]')
|
||||
.should('not.exist')
|
||||
cy.getById('features-button').should('not.exist')
|
||||
})
|
||||
|
||||
it('is visible when logged out', () => {
|
||||
cy.logout()
|
||||
cy.get('[data-cypress-id="features-button"]')
|
||||
.should('exist')
|
||||
cy.getById('features-button').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('sign in button', () => {
|
||||
it('is hidden when logged in', () => {
|
||||
cy.get('[data-cypress-id="sign-in-button"]')
|
||||
.should('not.exist')
|
||||
cy.getById('sign-in-button').should('not.exist')
|
||||
})
|
||||
|
||||
it('is visible when logged out', () => {
|
||||
cy.logout()
|
||||
cy.get('[data-cypress-id="sign-in-button"]')
|
||||
.should('exist')
|
||||
cy.getById('sign-in-button').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('version dialog', () => {
|
||||
it('can be opened and closed', () => {
|
||||
cy.get('[data-cypress-id="version-modal"]')
|
||||
.should('not.exist')
|
||||
cy.get('[data-cypress-id="show-version-modal"]')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="version-modal"]')
|
||||
.should('be.visible')
|
||||
cy.get('[data-cypress-id="version-modal"] .modal-header .close')
|
||||
.click()
|
||||
cy.get('[data-cypress-id="version-modal"]')
|
||||
.should('not.exist')
|
||||
cy.getById('version-modal').should('not.exist')
|
||||
cy.getById('show-version-modal').click()
|
||||
cy.getById('version-modal').should('be.visible')
|
||||
cy.getById('version-modal').find('.modal-header .close').click()
|
||||
cy.getById('version-modal').should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -12,26 +12,17 @@ describe('Languages', () => {
|
|||
})
|
||||
|
||||
it('all languages are available', () => {
|
||||
cy.get('option')
|
||||
.as('languages')
|
||||
cy.get('@languages')
|
||||
.should('have.length', 28)
|
||||
languages.forEach(language => {
|
||||
cy.get('@languages')
|
||||
.contains(language)
|
||||
cy.getById('language-picker').find('option').as('languages')
|
||||
cy.get('@languages').should('have.length', 28)
|
||||
languages.forEach((language) => {
|
||||
cy.get('@languages').contains(language)
|
||||
})
|
||||
})
|
||||
|
||||
it('language changes affect the UI', () => {
|
||||
cy.get('select')
|
||||
.select('English')
|
||||
cy.get('.d-inline-flex.btn-primary')
|
||||
.find('span')
|
||||
.contains('New note')
|
||||
cy.get('select')
|
||||
.select('Deutsch')
|
||||
cy.get('.d-inline-flex.btn-primary')
|
||||
.find('span')
|
||||
.contains('Neue Notiz')
|
||||
cy.getById('language-picker').select('English')
|
||||
cy.getById('new-note-button').find('span').contains('New note')
|
||||
cy.getById('language-picker').select('Deutsch')
|
||||
cy.getById('new-note-button').find('span').contains('Neue Notiz')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,35 +11,11 @@ describe('Links Intro', () => {
|
|||
cy.visit('/')
|
||||
})
|
||||
|
||||
describe('Cover Buttons', () => {
|
||||
beforeEach(() => {
|
||||
cy.logout()
|
||||
})
|
||||
|
||||
it('Sign in Cover Button', () => {
|
||||
cy.get('.cover-button.btn-success')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/login')
|
||||
})
|
||||
|
||||
it('Features Cover Button', () => {
|
||||
cy.get('.cover-button.btn-primary')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/features')
|
||||
})
|
||||
})
|
||||
|
||||
it('History', () => {
|
||||
cy.get('#navLinkHistory')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/history')
|
||||
cy.get('#navLinkIntro')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/intro')
|
||||
cy.getById('navLinkHistory').click()
|
||||
cy.url().should('include', '/history')
|
||||
cy.getById('navLinkIntro').click()
|
||||
cy.url().should('include', '/intro')
|
||||
})
|
||||
|
||||
describe('Menu Buttons logged out', () => {
|
||||
|
@ -48,119 +24,31 @@ describe('Links Intro', () => {
|
|||
})
|
||||
|
||||
it('New guest note', () => {
|
||||
cy.get('.d-inline-flex.btn-primary')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/new')
|
||||
cy.getById('new-guest-note-button').click()
|
||||
cy.url().should('include', '/new')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Menu Buttons logged in', () => {
|
||||
it('New note', () => {
|
||||
cy.get('.d-inline-flex.btn-primary')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/new')
|
||||
cy.getById('new-note-button').click()
|
||||
cy.url().should('include', '/new')
|
||||
})
|
||||
|
||||
describe('User Menu', () => {
|
||||
beforeEach(() => {
|
||||
cy.get('#dropdown-user')
|
||||
.click()
|
||||
cy.getById('user-dropdown').click()
|
||||
})
|
||||
|
||||
it('Features', () => {
|
||||
cy.get('a.dropdown-item > i.fa-bolt')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/features')
|
||||
cy.getById('user-dropdown-features-button').click()
|
||||
cy.url().should('include', '/features')
|
||||
})
|
||||
|
||||
it('Profile', () => {
|
||||
cy.get('a.dropdown-item > i.fa-user')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/profile')
|
||||
cy.getById('user-dropdown-profile-button').click()
|
||||
cy.url().should('include', '/profile')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Feature Links', () => {
|
||||
it('Share-Notes', () => {
|
||||
cy.get('i.fa-bolt')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/features#Share-Notes')
|
||||
})
|
||||
|
||||
it('KaTeX', () => {
|
||||
cy.get('i.fa-bar-chart')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/features#MathJax')
|
||||
})
|
||||
|
||||
it('Slide-Mode', () => {
|
||||
cy.get('i.fa-television')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/features#Slide-Mode')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Powered By Links', () => {
|
||||
it('HedgeDoc', () => {
|
||||
cy.get('a[href="https://hedgedoc.org"]')
|
||||
.checkExternalLink('https://hedgedoc.org')
|
||||
})
|
||||
|
||||
it('Releases', () => {
|
||||
cy.get('a[href*="/n/release-notes"]')
|
||||
.click()
|
||||
cy.url()
|
||||
.should('include', '/n/release-notes')
|
||||
})
|
||||
|
||||
it('Privacy', () => {
|
||||
cy.get('a[href="https://example.com/privacy"]')
|
||||
.checkExternalLink('https://example.com/privacy')
|
||||
})
|
||||
|
||||
it('TermsOfUse', () => {
|
||||
cy.get('a[href="https://example.com/termsOfUse"]')
|
||||
.checkExternalLink('https://example.com/termsOfUse')
|
||||
})
|
||||
|
||||
it('Imprint', () => {
|
||||
cy.get('a[href="https://example.com/imprint"]')
|
||||
.checkExternalLink('https://example.com/imprint')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Follow us Links', () => {
|
||||
it('Github', () => {
|
||||
cy.get('a[href="https://github.com/hedgedoc/"]')
|
||||
.checkExternalLink('https://github.com/hedgedoc/')
|
||||
})
|
||||
|
||||
it('Discourse', () => {
|
||||
cy.get('a[href="https://community.hedgedoc.org"]')
|
||||
.checkExternalLink('https://community.hedgedoc.org')
|
||||
})
|
||||
|
||||
it('Matrix', () => {
|
||||
cy.get('a[href="https://matrix.to/#/#hedgedoc:matrix.org"]')
|
||||
.checkExternalLink('https://matrix.to/#/#hedgedoc:matrix.org')
|
||||
})
|
||||
|
||||
it('Mastodon', () => {
|
||||
cy.get('a[href="https://social.hedgedoc.org"]')
|
||||
.checkExternalLink('https://social.hedgedoc.org')
|
||||
})
|
||||
|
||||
it('POEditor', () => {
|
||||
cy.get('a[href="https://translate.hedgedoc.org"]')
|
||||
.checkExternalLink('https://translate.hedgedoc.org')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -13,19 +13,15 @@ describe('Link gets replaced with embedding: ', () => {
|
|||
|
||||
it('GitHub Gist', () => {
|
||||
cy.setCodemirrorContent('https://gist.github.com/schacon/1')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id="click-shield-gist"] .preview-background')
|
||||
.parent()
|
||||
.click()
|
||||
cy.getMarkdownBody()
|
||||
.find('iframe[data-cypress-id=gh-gist]')
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().findById('click-shield-gist').find('.preview-background').parent().click()
|
||||
cy.getMarkdownBody().findById('gh-gist').should('be.visible')
|
||||
})
|
||||
|
||||
it('YouTube', () => {
|
||||
cy.setCodemirrorContent('https://www.youtube.com/watch?v=YE7VzlLtp-4')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id="click-shield-youtube"] .preview-background')
|
||||
.findById('click-shield-youtube')
|
||||
.find('.preview-background')
|
||||
.should('have.attr', 'src', 'https://i.ytimg.com/vi/YE7VzlLtp-4/maxresdefault.jpg')
|
||||
.parent()
|
||||
.click()
|
||||
|
@ -35,36 +31,37 @@ describe('Link gets replaced with embedding: ', () => {
|
|||
})
|
||||
|
||||
it('Vimeo', () => {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: 'https://vimeo.com/api/v2/video/23237102.json'
|
||||
}, {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: 'https://vimeo.com/api/v2/video/23237102.json'
|
||||
},
|
||||
body: '[{"thumbnail_large": "https://i.vimeocdn.com/video/503631401_640.jpg"}]'
|
||||
})
|
||||
{
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: '[{"thumbnail_large": "https://i.vimeocdn.com/video/503631401_640.jpg"}]'
|
||||
}
|
||||
)
|
||||
cy.setCodemirrorContent('https://vimeo.com/23237102')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id="click-shield-vimeo"] .preview-background')
|
||||
.findById('click-shield-vimeo')
|
||||
.find('.preview-background')
|
||||
.should('have.attr', 'src', 'https://i.vimeocdn.com/video/503631401_640.jpg')
|
||||
.parent()
|
||||
.click()
|
||||
cy.getMarkdownBody()
|
||||
.find('iframe')
|
||||
.should('have.attr', 'src', 'https://player.vimeo.com/video/23237102?autoplay=1')
|
||||
cy.getMarkdownBody().find('iframe').should('have.attr', 'src', 'https://player.vimeo.com/video/23237102?autoplay=1')
|
||||
})
|
||||
|
||||
it('Asciinema', () => {
|
||||
cy.setCodemirrorContent('https://asciinema.org/a/117928')
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id="click-shield-asciinema"] .preview-background')
|
||||
.findById('click-shield-asciinema')
|
||||
.find('.preview-background')
|
||||
.should('have.attr', 'src', 'https://asciinema.org/a/117928.png')
|
||||
.parent()
|
||||
.click()
|
||||
cy.getMarkdownBody()
|
||||
.find('iframe')
|
||||
.should('have.attr', 'src', 'https://asciinema.org/a/117928/embed?autoplay=1')
|
||||
cy.getMarkdownBody().find('iframe').should('have.attr', 'src', 'https://asciinema.org/a/117928/embed?autoplay=1')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,39 +5,31 @@
|
|||
*/
|
||||
|
||||
describe('The status bar text length info', () => {
|
||||
const warningTestContent = ('0123456789'.repeat(10))
|
||||
const dangerTestContent = ('0123456789'.repeat(20))
|
||||
const tooMuchTestContent = `${ dangerTestContent }a`
|
||||
const warningTestContent = '0123456789'.repeat(10)
|
||||
const dangerTestContent = '0123456789'.repeat(20)
|
||||
const tooMuchTestContent = `${dangerTestContent}a`
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visitTestEditor()
|
||||
})
|
||||
|
||||
it('shows the maximal length of the document as number of available characters in the tooltip', () => {
|
||||
cy.get('.status-bar [data-cypress-id="remainingCharacters"]')
|
||||
.attribute('title')
|
||||
.should('contain', ' 200 ')
|
||||
cy.getById('remainingCharacters').attribute('title').should('contain', ' 200 ')
|
||||
})
|
||||
|
||||
it('color is set to "warning" on <= 100 characters remaining', () => {
|
||||
cy.setCodemirrorContent(warningTestContent)
|
||||
cy.get('.status-bar [data-cypress-id="remainingCharacters"]')
|
||||
.should('have.class', 'text-warning')
|
||||
cy.getById('remainingCharacters').should('have.class', 'text-warning')
|
||||
})
|
||||
|
||||
it('color is set to danger on <= 0 characters remaining', () => {
|
||||
cy.setCodemirrorContent(dangerTestContent)
|
||||
cy.get('.status-bar [data-cypress-id="remainingCharacters"]')
|
||||
.should('have.class', 'text-danger')
|
||||
cy.getById('remainingCharacters').should('have.class', 'text-danger')
|
||||
})
|
||||
|
||||
it('shows a warning and opens a modal', () => {
|
||||
cy.setCodemirrorContent(tooMuchTestContent)
|
||||
cy.get('[data-cypress-id="limitReachedModal"]')
|
||||
.should('be.visible')
|
||||
cy.getIframeBody()
|
||||
.find('[data-cypress-id="limitReachedMessage"]')
|
||||
.should('be.visible')
|
||||
cy.getById('limitReachedModal').should('be.visible')
|
||||
cy.getIframeBody().findById('limitReachedMessage').should('be.visible')
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -29,63 +29,63 @@ describe('Motd', () => {
|
|||
it('shows the correct alert Motd text', () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.get('[data-cypress-id="motd"]').contains(motdMockContent)
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
})
|
||||
|
||||
it('can be dismissed', () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.get('[data-cypress-id="motd"]').contains(motdMockContent)
|
||||
cy.get('button[data-cypress-id="motd-dismiss"]')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getById('motd-dismiss')
|
||||
.click()
|
||||
.then(() => {
|
||||
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).to.equal(MOCK_LAST_MODIFIED)
|
||||
})
|
||||
cy.get('[data-cypress-id="motd"]').should('not.exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
})
|
||||
|
||||
it("won't show again after dismiss and reload", () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.get('[data-cypress-id="motd"]').contains(motdMockContent)
|
||||
cy.get('button[data-cypress-id="motd-dismiss"]')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getById('motd-dismiss')
|
||||
.click()
|
||||
.then(() => {
|
||||
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).to.equal(MOCK_LAST_MODIFIED)
|
||||
})
|
||||
cy.get('[data-cypress-id="motd"]').should('not.exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.reload()
|
||||
cy.get('main').should('exist')
|
||||
cy.get('[data-cypress-id="motd"]').should('not.exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
})
|
||||
|
||||
it("will show again after reload without dismiss", () => {
|
||||
it('will show again after reload without dismiss', () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.get('[data-cypress-id="motd"]').contains(motdMockContent)
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.reload()
|
||||
cy.get('main').should('exist')
|
||||
cy.get('[data-cypress-id="motd"]').contains(motdMockContent)
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
})
|
||||
|
||||
it("won't show again after dismiss and page navigation", () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.get('[data-cypress-id="motd"]').contains(motdMockContent)
|
||||
cy.get('button[data-cypress-id="motd-dismiss"]')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getById('motd-dismiss')
|
||||
.click()
|
||||
.then(() => {
|
||||
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).to.equal(MOCK_LAST_MODIFIED)
|
||||
})
|
||||
cy.get('[data-cypress-id="motd"]').should('not.exist')
|
||||
cy.get('#navLinkHistory').click()
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getById('navLinkHistory').click()
|
||||
cy.get('main').should('exist')
|
||||
cy.get('[data-cypress-id="motd"]').should('not.exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
})
|
||||
|
||||
it("won't show if no file exists", () => {
|
||||
cy.visit('/')
|
||||
cy.get('main').should('exist')
|
||||
cy.get('[data-cypress-id="motd"]').should('not.exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -6,68 +6,65 @@
|
|||
|
||||
describe('profile page', () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept({
|
||||
url: '/mock-backend/api/private/tokens',
|
||||
method: 'GET'
|
||||
}, {
|
||||
body: [
|
||||
{
|
||||
label: 'cypress-App',
|
||||
created: 1601991518
|
||||
}
|
||||
]
|
||||
})
|
||||
cy.intercept({
|
||||
url: '/mock-backend/api/private/tokens',
|
||||
method: 'POST'
|
||||
}, {
|
||||
body: {
|
||||
label: 'cypress',
|
||||
secret: 'c-y-p-r-e-s-s',
|
||||
created: Date.now()
|
||||
cy.intercept(
|
||||
{
|
||||
url: '/mock-backend/api/private/tokens',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
body: [
|
||||
{
|
||||
label: 'cypress-App',
|
||||
created: 1601991518
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
cy.intercept({
|
||||
url: '/mock-backend/api/private/tokens/1601991518',
|
||||
method: 'DELETE'
|
||||
}, {
|
||||
body: []
|
||||
})
|
||||
)
|
||||
cy.intercept(
|
||||
{
|
||||
url: '/mock-backend/api/private/tokens',
|
||||
method: 'POST'
|
||||
},
|
||||
{
|
||||
body: {
|
||||
label: 'cypress',
|
||||
secret: 'c-y-p-r-e-s-s',
|
||||
created: Date.now()
|
||||
}
|
||||
}
|
||||
)
|
||||
cy.intercept(
|
||||
{
|
||||
url: '/mock-backend/api/private/tokens/1601991518',
|
||||
method: 'DELETE'
|
||||
},
|
||||
{
|
||||
body: []
|
||||
}
|
||||
)
|
||||
cy.visit('/profile')
|
||||
})
|
||||
|
||||
describe('access tokens', () => {
|
||||
it('list existing tokens', () => {
|
||||
cy.get('.card.access-tokens .list-group-item .text-start.col')
|
||||
.contains('cypress-App')
|
||||
cy.getById('access-token-label').contains('cypress-App')
|
||||
})
|
||||
|
||||
it('delete token', () => {
|
||||
cy.get('.modal-dialog')
|
||||
.should('not.exist')
|
||||
cy.get('.card.access-tokens .list-group-item .btn-danger')
|
||||
.click()
|
||||
cy.get('.modal-dialog')
|
||||
.should('be.visible')
|
||||
.get('.modal-footer .btn-danger')
|
||||
.click()
|
||||
cy.get('.modal-dialog')
|
||||
.should('not.exist')
|
||||
cy.getById('access-token-delete-button').click()
|
||||
cy.getById('access-token-modal-delete').as('deletion-modal')
|
||||
cy.get('@deletion-modal').should('be.visible').find('.modal-footer .btn-danger').click()
|
||||
cy.get('@deletion-modal').should('not.exist')
|
||||
})
|
||||
|
||||
it('add token', () => {
|
||||
cy.get('.card.access-tokens .btn-primary')
|
||||
.should('be.disabled')
|
||||
cy.get('.card.access-tokens input[type=text]')
|
||||
.type('cypress')
|
||||
cy.get('.modal-dialog')
|
||||
.should('not.exist')
|
||||
cy.get('.card.access-tokens .btn-primary')
|
||||
.should('not.be.disabled')
|
||||
.click()
|
||||
cy.get('.modal-dialog')
|
||||
cy.getById('access-token-add-button').should('be.disabled')
|
||||
cy.getById('access-token-add-input').type('cypress')
|
||||
cy.getById('access-token-modal-add').should('not.exist')
|
||||
cy.getById('access-token-add-button').should('not.be.disabled').click()
|
||||
cy.getById('access-token-modal-add')
|
||||
.should('be.visible')
|
||||
.get('.modal-dialog input[readonly]')
|
||||
.find('input[readonly]')
|
||||
.should('have.value', 'c-y-p-r-e-s-s')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -13,16 +13,9 @@ describe('Quote extra tags', function () {
|
|||
it('renders correctly', () => {
|
||||
cy.setCodemirrorContent('[name=testy mctestface]')
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('be.visible')
|
||||
.find('.fa-user')
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('be.visible').find('.fa-user').should('be.visible')
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('be.visible')
|
||||
.contains('testy mctestface')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('be.visible').contains('testy mctestface')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -30,16 +23,9 @@ describe('Quote extra tags', function () {
|
|||
it('renders correctly', () => {
|
||||
cy.setCodemirrorContent(`[time=always]`)
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('be.visible')
|
||||
.find('.fa-clock-o')
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('be.visible').find('.fa-clock-o').should('be.visible')
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('be.visible')
|
||||
.contains('always')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('be.visible').contains('always')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -47,24 +33,15 @@ describe('Quote extra tags', function () {
|
|||
it('renders correctly', () => {
|
||||
cy.setCodemirrorContent(`[color=#b51f08]`)
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('be.visible')
|
||||
.find('.fa-tag')
|
||||
.should('be.visible')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('be.visible').find('.fa-tag').should('be.visible')
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('be.visible')
|
||||
.should('have.css', 'color', 'rgb(181, 31, 8)')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('be.visible').should('have.css', 'color', 'rgb(181, 31, 8)')
|
||||
})
|
||||
|
||||
it('doesn\'t render in a blockquote and dyes the blockquote border', () => {
|
||||
it("doesn't render in a blockquote and dyes the blockquote border", () => {
|
||||
cy.setCodemirrorContent(`> [color=#b51f08] HedgeDoc`)
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('.blockquote-extra')
|
||||
.should('not.exist')
|
||||
cy.getMarkdownBody().find('.blockquote-extra').should('not.exist')
|
||||
|
||||
cy.getMarkdownBody()
|
||||
.find('blockquote')
|
||||
|
|
|
@ -21,26 +21,21 @@ describe('Short code gets replaced or rendered: ', () => {
|
|||
describe('slideshare', () => {
|
||||
it('renders a plain link', () => {
|
||||
cy.setCodemirrorContent(`{%slideshare example/123456789 %}`)
|
||||
cy.getMarkdownBody()
|
||||
.find('a')
|
||||
.should('have.attr', 'href', 'https://www.slideshare.net/example/123456789')
|
||||
cy.getMarkdownBody().find('a').should('have.attr', 'href', 'https://www.slideshare.net/example/123456789')
|
||||
})
|
||||
})
|
||||
|
||||
describe('speakerdeck', () => {
|
||||
it('renders a plain link', () => {
|
||||
cy.setCodemirrorContent(`{%speakerdeck example/123456789 %}`)
|
||||
cy.getMarkdownBody()
|
||||
.find('a')
|
||||
.should('have.attr', 'href', 'https://speakerdeck.com/example/123456789')
|
||||
cy.getMarkdownBody().find('a').should('have.attr', 'href', 'https://speakerdeck.com/example/123456789')
|
||||
})
|
||||
})
|
||||
|
||||
describe('youtube', () => {
|
||||
it('renders click-shield', () => {
|
||||
cy.setCodemirrorContent(`{%youtube YE7VzlLtp-4 %}`)
|
||||
cy.getMarkdownBody()
|
||||
.find('[data-cypress-id="click-shield-youtube"]')
|
||||
cy.getMarkdownBody().findById('click-shield-youtube')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -18,7 +18,10 @@ const authProvidersDisabled = {
|
|||
openid: false
|
||||
}
|
||||
|
||||
const initLoggedOutTestWithCustomAuthProviders = (cy: Cypress.cy, enabledProviders: Partial<typeof authProvidersDisabled>) => {
|
||||
const initLoggedOutTestWithCustomAuthProviders = (
|
||||
cy: Cypress.cy,
|
||||
enabledProviders: Partial<typeof authProvidersDisabled>
|
||||
) => {
|
||||
cy.loadConfig({
|
||||
authProviders: {
|
||||
...authProvidersDisabled,
|
||||
|
@ -32,8 +35,7 @@ const initLoggedOutTestWithCustomAuthProviders = (cy: Cypress.cy, enabledProvide
|
|||
describe('When logged-in, ', () => {
|
||||
it('sign-in button is hidden', () => {
|
||||
cy.visit('/')
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('not.exist')
|
||||
cy.getById('sign-in-button').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -41,8 +43,7 @@ describe('When logged-out ', () => {
|
|||
describe('and no auth-provider is enabled, ', () => {
|
||||
it('sign-in button is hidden', () => {
|
||||
initLoggedOutTestWithCustomAuthProviders(cy, {})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('not.exist')
|
||||
cy.getById('sign-in-button').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -51,27 +52,21 @@ describe('When logged-out ', () => {
|
|||
initLoggedOutTestWithCustomAuthProviders(cy, {
|
||||
internal: true
|
||||
})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('be.visible')
|
||||
.should('have.attr', 'href', '/login')
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
|
||||
it('sign-in button points to login route: ldap', () => {
|
||||
initLoggedOutTestWithCustomAuthProviders(cy, {
|
||||
ldap: true
|
||||
})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('be.visible')
|
||||
.should('have.attr', 'href', '/login')
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
|
||||
it('sign-in button points to login route: openid', () => {
|
||||
initLoggedOutTestWithCustomAuthProviders(cy, {
|
||||
openid: true
|
||||
})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('be.visible')
|
||||
.should('have.attr', 'href', '/login')
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -80,7 +75,7 @@ describe('When logged-out ', () => {
|
|||
initLoggedOutTestWithCustomAuthProviders(cy, {
|
||||
saml: true
|
||||
})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
cy.getById('sign-in-button')
|
||||
.should('be.visible')
|
||||
// The absolute URL is used because it is defined as API base URL absolute.
|
||||
.should('have.attr', 'href', '/mock-backend/api/private/auth/saml')
|
||||
|
@ -93,9 +88,7 @@ describe('When logged-out ', () => {
|
|||
saml: true,
|
||||
github: true
|
||||
})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('be.visible')
|
||||
.should('have.attr', 'href', '/login')
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -105,9 +98,7 @@ describe('When logged-out ', () => {
|
|||
saml: true,
|
||||
internal: true
|
||||
})
|
||||
cy.get('[data-cypress-id=sign-in-button]')
|
||||
.should('be.visible')
|
||||
.should('have.attr', 'href', '/login')
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
describe("Slideshow only page", () => {
|
||||
describe('Slideshow only page', () => {
|
||||
it('renders slide show mode', () => {
|
||||
cy.visit('/p/test')
|
||||
cy.getReveal().should("exist")
|
||||
cy.getReveal().should('exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,19 +10,19 @@ describe('Split view', () => {
|
|||
})
|
||||
|
||||
it('can show both panes', () => {
|
||||
cy.get('[data-cypress-id="view-mode-both"]').click()
|
||||
cy.getById('view-mode-both').click()
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
})
|
||||
|
||||
it('can show only preview pane', () => {
|
||||
cy.get('[data-cypress-id="view-mode-preview"]').click()
|
||||
cy.getById('view-mode-preview').click()
|
||||
cy.get('.splitter.left').should('be.not.visible')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
})
|
||||
|
||||
it('can show only editor pane', () => {
|
||||
cy.get('[data-cypress-id="view-mode-editor"]').click()
|
||||
cy.getById('view-mode-editor').click()
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.right').should('be.not.visible')
|
||||
})
|
||||
|
@ -31,7 +31,7 @@ describe('Split view', () => {
|
|||
cy.get('.splitter.left').then((leftPanebefore) => {
|
||||
const widthBefore = leftPanebefore.outerWidth()
|
||||
|
||||
cy.get('[data-cypress-id="view-mode-both"]').click()
|
||||
cy.getById('view-mode-both').click()
|
||||
cy.get('.split-divider').should('be.visible').trigger('mousedown', { buttons: 1 })
|
||||
cy.document().trigger('mousemove', { buttons: 1, pageX: 0, pageY: 0 })
|
||||
cy.get('.split-divider').trigger('mouseup')
|
||||
|
|
|
@ -17,31 +17,23 @@ describe('Task lists ', () => {
|
|||
describe('render with checkboxes ', () => {
|
||||
it('when unchecked', () => {
|
||||
cy.setCodemirrorContent(TEST_STRING_UNCHECKED)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.should('have.length', 6)
|
||||
cy.getMarkdownBody().find('input[type=checkbox]').should('have.length', 6)
|
||||
})
|
||||
|
||||
it('when checked lowercase', () => {
|
||||
cy.setCodemirrorContent(TEST_STRING_CHECKED_LOWER)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.should('have.length', 6)
|
||||
cy.getMarkdownBody().find('input[type=checkbox]').should('have.length', 6)
|
||||
})
|
||||
|
||||
it('when checked uppercase', () => {
|
||||
cy.setCodemirrorContent(TEST_STRING_CHECKED_UPPER)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.should('have.length', 6)
|
||||
cy.getMarkdownBody().find('input[type=checkbox]').should('have.length', 6)
|
||||
})
|
||||
})
|
||||
|
||||
it('do not render as checkboxes when invalid', () => {
|
||||
cy.setCodemirrorContent(TEST_STRING_INVALID)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.should('have.length', 0)
|
||||
cy.getMarkdownBody().find('input[type=checkbox]').should('have.length', 0)
|
||||
})
|
||||
|
||||
describe('are clickable and change the markdown source ', () => {
|
||||
|
@ -49,39 +41,30 @@ describe('Task lists ', () => {
|
|||
cy.setCodemirrorContent(TEST_STRING_UNCHECKED)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.each(box => {
|
||||
.each((box) => {
|
||||
box.trigger('click')
|
||||
})
|
||||
cy.get('.CodeMirror-line > span')
|
||||
.should('exist')
|
||||
.should('contain.text', '[x]')
|
||||
.should('not.contain.text', '[ ]')
|
||||
cy.get('.CodeMirror-line > span').should('exist').should('contain.text', '[x]').should('not.contain.text', '[ ]')
|
||||
})
|
||||
|
||||
it('from checked (lowercase) to unchecked', () => {
|
||||
cy.setCodemirrorContent(TEST_STRING_CHECKED_LOWER)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.each(box => {
|
||||
.each((box) => {
|
||||
box.trigger('click')
|
||||
})
|
||||
cy.get('.CodeMirror-line > span')
|
||||
.should('exist')
|
||||
.should('contain.text', '[ ]')
|
||||
.should('not.contain.text', '[x]')
|
||||
cy.get('.CodeMirror-line > span').should('exist').should('contain.text', '[ ]').should('not.contain.text', '[x]')
|
||||
})
|
||||
|
||||
it('from checked (uppercase) to unchecked', () => {
|
||||
cy.setCodemirrorContent(TEST_STRING_CHECKED_UPPER)
|
||||
cy.getMarkdownBody()
|
||||
.find('input[type=checkbox]')
|
||||
.each(box => {
|
||||
.each((box) => {
|
||||
box.trigger('click')
|
||||
})
|
||||
cy.get('.CodeMirror-line > span')
|
||||
.should('exist')
|
||||
.should('contain.text', '[ ]')
|
||||
.should('not.contain.text', '[X]')
|
||||
cy.get('.CodeMirror-line > span').should('exist').should('contain.text', '[ ]').should('not.contain.text', '[X]')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,295 +11,220 @@ describe('Toolbar Buttons', () => {
|
|||
beforeEach(() => {
|
||||
cy.visitTestEditor()
|
||||
|
||||
cy.get('.CodeMirror')
|
||||
.click()
|
||||
.get('textarea')
|
||||
.as('codeinput')
|
||||
cy.get('.CodeMirror').click().get('textarea').as('codeinput')
|
||||
})
|
||||
|
||||
describe('for single line text', () => {
|
||||
beforeEach(() => {
|
||||
cy.setCodemirrorContent(testText)
|
||||
cy.get('.CodeMirror-line > span')
|
||||
.should('exist')
|
||||
.should('have.text', testText)
|
||||
cy.get('.CodeMirror-line > span').should('exist').should('have.text', testText)
|
||||
})
|
||||
|
||||
describe('with selection', () => {
|
||||
beforeEach(() => {
|
||||
cy.get('@codeinput')
|
||||
.type('{ctrl}a')
|
||||
cy.get('@codeinput').type('{ctrl}a')
|
||||
})
|
||||
|
||||
it('should format as bold', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-bold"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `**${ testText }**`)
|
||||
cy.getById('format-bold').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `**${testText}**`)
|
||||
})
|
||||
|
||||
it('should format as italic', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-italic"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `*${ testText }*`)
|
||||
cy.getById('format-italic').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `*${testText}*`)
|
||||
})
|
||||
|
||||
it('should format as underline', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-underline"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `++${ testText }++`)
|
||||
cy.getById('format-underline').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `++${testText}++`)
|
||||
})
|
||||
|
||||
it('should format as strikethrough', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-strikethrough"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `~~${ testText }~~`)
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-strikethrough').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `~~${testText}~~`)
|
||||
})
|
||||
|
||||
it('should format as subscript', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-subscript"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `~${ testText }~`)
|
||||
cy.getById('format-subscript').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `~${testText}~`)
|
||||
})
|
||||
|
||||
it('should format as superscript', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-superscript"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `^${ testText }^`)
|
||||
cy.getById('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-cypress-id="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', '```')
|
||||
cy.getById('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-cypress-id="format-link"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `[${ testText }](https://)`)
|
||||
cy.getById('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-cypress-id="format-image"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `![${ testText }](https://)`)
|
||||
cy.getById('format-image').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `![${testText}](https://)`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should format line as heading', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-heading"]')
|
||||
.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 }`)
|
||||
cy.getById('format-heading').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}`)
|
||||
})
|
||||
|
||||
it('should format the line as code', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="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', '```')
|
||||
cy.getById('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-cypress-id="format-block-quote"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `> ${ testText }`)
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-block-quote"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `> > ${ testText }`)
|
||||
cy.getById('format-block-quote').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `> ${testText}`)
|
||||
cy.getById('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-cypress-id="format-unordered-list"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `- ${ testText }`)
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-unordered-list"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `- - ${ testText }`)
|
||||
cy.getById('format-unordered-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- ${testText}`)
|
||||
cy.getById('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-cypress-id="format-ordered-list"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `1. ${ testText }`)
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-ordered-list"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `1. 1. ${ testText }`)
|
||||
cy.getById('format-ordered-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `1. ${testText}`)
|
||||
cy.getById('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-cypress-id="format-check-list"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `- [ ] ${ testText }`)
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-check-list"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `- [ ] - [ ] ${ testText }`)
|
||||
cy.getById('format-check-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- [ ] ${testText}`)
|
||||
cy.getById('format-check-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- [ ] - [ ] ${testText}`)
|
||||
})
|
||||
|
||||
it('should insert links', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-link"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `${ testText }[](https://)`)
|
||||
cy.getById('format-link').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `${testText}[](https://)`)
|
||||
})
|
||||
|
||||
it('should insert an empty image link', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-image"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `${ testText }![](https://)`)
|
||||
cy.getById('format-image').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `${testText}![](https://)`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('for single line link with selection', () => {
|
||||
beforeEach(() => {
|
||||
cy.setCodemirrorContent(testLink)
|
||||
cy.get('.CodeMirror-line > span')
|
||||
.should('exist')
|
||||
.should('have.text', testLink)
|
||||
cy.get('@codeinput')
|
||||
.type('{ctrl}a')
|
||||
cy.get('.CodeMirror-line > span').should('exist').should('have.text', testLink)
|
||||
cy.get('@codeinput').type('{ctrl}a')
|
||||
})
|
||||
|
||||
it('should format as link', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-link"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `[](${ testLink })`)
|
||||
cy.getById('format-link').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `[](${testLink})`)
|
||||
})
|
||||
|
||||
it('should format as image', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="format-image"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span')
|
||||
.should('have.text', `![](${ testLink })`)
|
||||
cy.getById('format-image').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `![](${testLink})`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('for no text', () => {
|
||||
it('should add an empty code block', () => {
|
||||
cy.get('.btn-toolbar [data-cypress-id="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', '```')
|
||||
cy.getById('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-cypress-id="format-add-line"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span')
|
||||
.should('have.text', '----')
|
||||
cy.getById('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-cypress-id="format-collapsable-block"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span')
|
||||
.should('have.text', ':::spoiler Toggle label')
|
||||
cy.getById('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-cypress-id="format-add-comment"]')
|
||||
.click()
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span')
|
||||
.should('have.text', '> []')
|
||||
cy.getById('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('[data-cypress-id="show-table-overlay"]')
|
||||
.last()
|
||||
.click()
|
||||
cy.get('.table-picker-container')
|
||||
.should('be.visible')
|
||||
cy.get('.table-picker-container').should('not.be.visible')
|
||||
cy.getById('show-table-overlay').last().click()
|
||||
cy.get('.table-picker-container').should('be.visible')
|
||||
})
|
||||
|
||||
it('should open an overlay', () => {
|
||||
cy.get('.table-container > div:nth-of-type(25)')
|
||||
.trigger('mouseover')
|
||||
cy.get('.table-cell.bg-primary')
|
||||
.should('have.length', 15)
|
||||
cy.get('.table-picker-container > p')
|
||||
.contains('5x3')
|
||||
cy.get('.table-container > div:nth-of-type(25)')
|
||||
.click()
|
||||
cy.get('.table-container > div:nth-of-type(25)').trigger('mouseover')
|
||||
cy.get('.table-cell.bg-primary').should('have.length', 15)
|
||||
cy.get('.table-picker-container > p').contains('5x3')
|
||||
cy.get('.table-container > div:nth-of-type(25)').click()
|
||||
})
|
||||
|
||||
it('should open a modal for custom table sizes in the overlay', () => {
|
||||
cy.get('.modal-dialog')
|
||||
.should('not.exist')
|
||||
cy.get('[data-cypress-id="show-custom-table-modal"]')
|
||||
.first()
|
||||
.click()
|
||||
cy.get('.modal-dialog')
|
||||
.should('be.visible')
|
||||
cy.get('.modal-content > .d-flex > input')
|
||||
.first()
|
||||
.type('5')
|
||||
cy.get('.modal-content > .d-flex > input')
|
||||
.last()
|
||||
.type('3')
|
||||
cy.get('.modal-footer > button')
|
||||
.click()
|
||||
cy.get('.modal-dialog').should('not.exist')
|
||||
cy.getById('show-custom-table-modal').first().click()
|
||||
cy.get('.modal-dialog').should('be.visible')
|
||||
cy.get('.modal-content > .d-flex > input').first().type('5')
|
||||
cy.get('.modal-content > .d-flex > input').last().type('3')
|
||||
cy.get('.modal-footer > button').click()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span')
|
||||
.should('have.text', '| # 1 | # 2 | # 3 | # 4 | # 5 |')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span span')
|
||||
.should('have.text', '| ---- | ---- | ---- | ---- | ---- |')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(4) > .CodeMirror-line > span span')
|
||||
.should('have.text', '| Text | Text | Text | Text | Text |')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(5) > .CodeMirror-line > span span')
|
||||
.should('have.text', '| Text | Text | Text | Text | Text |')
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span ')
|
||||
.should('have.text', '| Text | Text | Text | Text | Text |')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span').should(
|
||||
'have.text',
|
||||
'| # 1 | # 2 | # 3 | # 4 | # 5 |'
|
||||
)
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line > span span').should(
|
||||
'have.text',
|
||||
'| ---- | ---- | ---- | ---- | ---- |'
|
||||
)
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(4) > .CodeMirror-line > span span').should(
|
||||
'have.text',
|
||||
'| Text | Text | Text | Text | Text |'
|
||||
)
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(5) > .CodeMirror-line > span span').should(
|
||||
'have.text',
|
||||
'| Text | Text | Text | Text | Text |'
|
||||
)
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span ').should(
|
||||
'have.text',
|
||||
'| Text | Text | Text | Text | Text |'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('for the emoji-picker', () => {
|
||||
it('should open overlay', () => {
|
||||
cy.get('emoji-picker')
|
||||
.should('not.be.visible')
|
||||
cy.get('[data-cypress-id="show-emoji-picker"]')
|
||||
.click()
|
||||
cy.get('emoji-picker')
|
||||
.should('be.visible')
|
||||
cy.get('emoji-picker').should('not.be.visible')
|
||||
cy.getById('show-emoji-picker').click()
|
||||
cy.get('emoji-picker').should('be.visible')
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -12,32 +12,32 @@ describe('Test word count with', () => {
|
|||
it('empty note', () => {
|
||||
cy.setCodemirrorContent('')
|
||||
cy.wait(500)
|
||||
cy.get('[data-cypress-id="sidebar-btn-document-info"]').click()
|
||||
cy.get('[data-cypress-id="document-info-modal"]').should('be.visible')
|
||||
cy.get('[data-cypress-id="document-info-word-count"]').should('have.text', '0')
|
||||
cy.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '0')
|
||||
})
|
||||
|
||||
it('simple words', () => {
|
||||
cy.setCodemirrorContent('five words should be enough')
|
||||
cy.wait(500)
|
||||
cy.get('[data-cypress-id="sidebar-btn-document-info"]').click()
|
||||
cy.get('[data-cypress-id="document-info-modal"]').should('be.visible')
|
||||
cy.get('[data-cypress-id="document-info-word-count"]').should('have.text', '5')
|
||||
cy.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '5')
|
||||
})
|
||||
|
||||
it('excluded codeblocks', () => {
|
||||
cy.setCodemirrorContent('```\nthis is should be ignored\n```\n\ntwo `words`')
|
||||
cy.wait(500)
|
||||
cy.get('[data-cypress-id="sidebar-btn-document-info"]').click()
|
||||
cy.get('[data-cypress-id="document-info-modal"]').should('be.visible')
|
||||
cy.get('[data-cypress-id="document-info-word-count"]').should('have.text', '2')
|
||||
cy.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '2')
|
||||
})
|
||||
|
||||
it('excluded images', () => {
|
||||
cy.setCodemirrorContent('![ignored alt text](https://dummyimage.com/48) not ignored text')
|
||||
cy.wait(500)
|
||||
cy.get('[data-cypress-id="sidebar-btn-document-info"]').click()
|
||||
cy.get('[data-cypress-id="document-info-modal"]').should('be.visible')
|
||||
cy.get('[data-cypress-id="document-info-word-count"]').should('have.text', '3')
|
||||
cy.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '3')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,22 +11,16 @@ describe('YAML Array for deprecated syntax of document tags in frontmatter', ()
|
|||
|
||||
it('is shown when using old syntax', () => {
|
||||
cy.setCodemirrorContent('---\ntags: a, b, c\n---')
|
||||
cy.getIframeBody()
|
||||
.find('[data-cypress-id="yamlArrayDeprecationAlert"]')
|
||||
.should('be.visible')
|
||||
cy.getIframeBody().findById('yamlArrayDeprecationAlert').should('be.visible')
|
||||
})
|
||||
|
||||
it('isn\'t shown when using inline yaml-array', () => {
|
||||
cy.setCodemirrorContent('---\ntags: [\'a\', \'b\', \'c\']\n---')
|
||||
cy.getIframeBody()
|
||||
.find('[data-cypress-id="yamlArrayDeprecationAlert"]')
|
||||
.should('not.exist')
|
||||
it("isn't shown when using inline yaml-array", () => {
|
||||
cy.setCodemirrorContent("---\ntags: ['a', 'b', 'c']\n---")
|
||||
cy.getIframeBody().findById('yamlArrayDeprecationAlert').should('not.exist')
|
||||
})
|
||||
|
||||
it('isn\'t shown when using multi line yaml-array', () => {
|
||||
it("isn't shown when using multi line yaml-array", () => {
|
||||
cy.setCodemirrorContent('---\ntags:\n - a\n - b\n - c\n---')
|
||||
cy.getIframeBody()
|
||||
.find('[data-cypress-id="yamlArrayDeprecationAlert"]')
|
||||
.should('not.exist')
|
||||
cy.getIframeBody().findById('yamlArrayDeprecationAlert').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -15,7 +15,5 @@ declare namespace Cypress {
|
|||
}
|
||||
|
||||
Cypress.Commands.add('checkExternalLink', { prevSubject: 'element' }, ($element: JQuery, url: string) => {
|
||||
cy.wrap($element)
|
||||
.should('have.attr', 'href', url)
|
||||
.should('have.attr', 'target', '_blank')
|
||||
cy.wrap($element).should('have.attr', 'href', url).should('have.attr', 'target', '_blank')
|
||||
})
|
||||
|
|
|
@ -50,9 +50,9 @@ export const config = {
|
|||
sourceCodeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
|
||||
issueTrackerUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
|
||||
},
|
||||
'iframeCommunication': {
|
||||
'editorOrigin': 'http://127.0.0.1:3001/',
|
||||
'rendererOrigin': 'http://127.0.0.1:3001/'
|
||||
iframeCommunication: {
|
||||
editorOrigin: 'http://127.0.0.1:3001/',
|
||||
rendererOrigin: 'http://127.0.0.1:3001/'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,26 +16,20 @@ declare namespace Cypress {
|
|||
}
|
||||
}
|
||||
|
||||
Cypress.Commands.add('fill', {
|
||||
prevSubject: 'element'
|
||||
}, (subject, value) => {
|
||||
return cy.wrap(subject)
|
||||
.invoke('val', value)
|
||||
.trigger('change', { force: true })
|
||||
})
|
||||
Cypress.Commands.add(
|
||||
'fill',
|
||||
{
|
||||
prevSubject: 'element'
|
||||
},
|
||||
(subject, value) => {
|
||||
return cy.wrap(subject).invoke('val', value).trigger('change', { force: true })
|
||||
}
|
||||
)
|
||||
|
||||
Cypress.Commands.add('setCodemirrorContent', (content: string) => {
|
||||
const line = content.split('\n')
|
||||
.find(value => value !== '')
|
||||
cy.get('.CodeMirror')
|
||||
.click()
|
||||
.get('textarea')
|
||||
.type('{ctrl}a')
|
||||
.type('{backspace}')
|
||||
.fill(content)
|
||||
const line = content.split('\n').find((value) => value !== '')
|
||||
cy.get('.CodeMirror').click().get('textarea').type('{ctrl}a').type('{backspace}').fill(content)
|
||||
if (line) {
|
||||
cy.get('.CodeMirror')
|
||||
.find('.CodeMirror-line')
|
||||
.should('contain.text', line)
|
||||
cy.get('.CodeMirror').find('.CodeMirror-line').should('contain.text', line)
|
||||
}
|
||||
})
|
||||
|
|
27
cypress/support/get-by-id.ts
Normal file
27
cypress/support/get-by-id.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
getById(id: string): Chainable<Element>
|
||||
findById(id: string): Chainable<Element>
|
||||
}
|
||||
}
|
||||
|
||||
const CYPRESS_ATTR = 'data-cypress-id'
|
||||
|
||||
Cypress.Commands.add('getById', (id: string) => {
|
||||
return cy.get(`[${CYPRESS_ATTR}="${id}"]`)
|
||||
})
|
||||
|
||||
Cypress.Commands.add(
|
||||
'findById',
|
||||
{
|
||||
prevSubject: 'element'
|
||||
},
|
||||
(parent: JQuery<HTMLElement>, id: string) => {
|
||||
return cy.wrap(parent).find(`[${CYPRESS_ATTR}="${id}"]`)
|
||||
}
|
||||
)
|
|
@ -24,6 +24,7 @@ import 'cypress-file-upload'
|
|||
import './checkLinks'
|
||||
import './config'
|
||||
import './fill'
|
||||
import './get-by-id'
|
||||
import './get-iframe-content'
|
||||
import './login'
|
||||
import './visit-test-editor'
|
||||
|
|
|
@ -15,8 +15,6 @@ declare namespace Cypress {
|
|||
}
|
||||
|
||||
Cypress.Commands.add('logout', () => {
|
||||
cy.get('#dropdown-user')
|
||||
.click()
|
||||
cy.get('.fa-sign-out')
|
||||
.click()
|
||||
cy.getById('user-dropdown').click()
|
||||
cy.getById('user-dropdown-sign-out-button').click()
|
||||
})
|
||||
|
|
|
@ -13,26 +13,26 @@ declare namespace Cypress {
|
|||
export const testNoteId = 'test'
|
||||
|
||||
Cypress.Commands.add('visitTestEditor', (query?: string) => {
|
||||
return cy.visit(`/n/${ testNoteId }${ query ? `?${ query }` : '' }`)
|
||||
return cy.visit(`/n/${testNoteId}${query ? `?${query}` : ''}`)
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.intercept(`/mock-backend/api/private/notes/${ testNoteId }-get`, {
|
||||
"content": "",
|
||||
"metadata": {
|
||||
"id": "mock_note_id",
|
||||
"alias": "mockNote",
|
||||
"version": 2,
|
||||
"viewCount": 0,
|
||||
"updateTime": "2021-04-24T09:27:51.000Z",
|
||||
"updateUser": {
|
||||
"userName": "test",
|
||||
"displayName": "Testy",
|
||||
"photo": "",
|
||||
"email": ""
|
||||
cy.intercept(`/mock-backend/api/private/notes/${testNoteId}-get`, {
|
||||
content: '',
|
||||
metadata: {
|
||||
id: 'mock_note_id',
|
||||
alias: 'mockNote',
|
||||
version: 2,
|
||||
viewCount: 0,
|
||||
updateTime: '2021-04-24T09:27:51.000Z',
|
||||
updateUser: {
|
||||
userName: 'test',
|
||||
displayName: 'Testy',
|
||||
photo: '',
|
||||
email: ''
|
||||
},
|
||||
"createTime": "2021-04-24T09:27:51.000Z",
|
||||
"editedBy": []
|
||||
createTime: '2021-04-24T09:27:51.000Z',
|
||||
editedBy: []
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
"test": "craco test",
|
||||
"lint": "eslint --max-warnings=0 --ext .ts,.tsx src",
|
||||
"lint:fix": "eslint --fix --ext .ts,.tsx src",
|
||||
"format": "prettier -c \"src/**/*.{ts,tsx,js}\"",
|
||||
"format:fix": "prettier -w \"src/**/*.{ts,tsx,js}\"",
|
||||
"format": "prettier -c \"src/**/*.{ts,tsx,js}\" \"cypress/**/*.{ts,tsx}\"",
|
||||
"format:fix": "prettier -w \"src/**/*.{ts,tsx,js}\" \"cypress/**/*.{ts,tsx}\"",
|
||||
"eject": "react-scripts eject",
|
||||
"cy:open": "cypress open",
|
||||
"cy:run:chrome": "cypress run --browser chrome",
|
||||
|
|
|
@ -22,12 +22,13 @@ export const DeletionModal: React.FC<DeletionModalProps> = ({
|
|||
onConfirm,
|
||||
deletionButtonI18nKey,
|
||||
icon,
|
||||
children
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true}>
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true} {...props}>
|
||||
<Modal.Body className='text-dark'>{children}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant='danger' onClick={onConfirm}>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import { Modal } from 'react-bootstrap'
|
||||
import type { CommonModalProps } from './common-modal'
|
||||
import { CommonModal } from './common-modal'
|
||||
|
||||
export const ErrorModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, icon, children }) => {
|
||||
return (
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true}>
|
||||
<Modal.Body className='text-dark text-center'>{children}</Modal.Body>
|
||||
</CommonModal>
|
||||
)
|
||||
}
|
|
@ -9,6 +9,7 @@ import { Button } from 'react-bootstrap'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
||||
import { HelpModal } from './help-modal'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export const HelpButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -18,6 +19,7 @@ export const HelpButton: React.FC = () => {
|
|||
return (
|
||||
<Fragment>
|
||||
<Button
|
||||
{...cypressId('editor-help-button')}
|
||||
title={t('editor.documentBar.help')}
|
||||
className='ml-2 text-secondary'
|
||||
size='sm'
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon'
|
|||
import { UploadInput } from '../../sidebar/upload-input'
|
||||
import { handleUpload } from '../upload-handler'
|
||||
import { supportedMimeTypes } from '../../../common/upload-image-mimetypes'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface UploadImageButtonProps {
|
||||
editor?: Editor
|
||||
|
@ -42,10 +43,19 @@ export const UploadImageButton: React.FC<UploadImageButtonProps> = ({ editor })
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<Button variant='light' onClick={buttonClick} title={t('editor.editorToolbar.uploadImage')}>
|
||||
<Button
|
||||
variant='light'
|
||||
onClick={buttonClick}
|
||||
title={t('editor.editorToolbar.uploadImage')}
|
||||
{...cypressId('editor-toolbar-upload-image-button')}>
|
||||
<ForkAwesomeIcon icon={'upload'} />
|
||||
</Button>
|
||||
<UploadInput onLoad={onUploadImage} acceptedFiles={acceptedMimeTypes} onClickRef={clickRef} />
|
||||
<UploadInput
|
||||
onLoad={onUploadImage}
|
||||
acceptedFiles={acceptedMimeTypes}
|
||||
onClickRef={clickRef}
|
||||
{...cypressId('editor-toolbar-upload-image-input')}
|
||||
/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export const HistoryCard: React.FC<HistoryEntryProps & HistoryEventHandlers> = (
|
|||
const entryTitle = useHistoryEntryTitle(entry)
|
||||
|
||||
return (
|
||||
<div className='p-2 col-xs-12 col-sm-6 col-md-6 col-lg-4'>
|
||||
<div className='p-2 col-xs-12 col-sm-6 col-md-6 col-lg-4' {...cypressId('history-card')}>
|
||||
<Card className='card-min-height' text={'dark'} bg={'light'}>
|
||||
<Card.Body className='p-2 d-flex flex-row justify-content-between'>
|
||||
<div className={'d-flex flex-column'}>
|
||||
|
|
|
@ -8,6 +8,7 @@ import React from 'react'
|
|||
import { Button } from 'react-bootstrap'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import './pin-button.scss'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface PinButtonProps {
|
||||
isPinned: boolean
|
||||
|
@ -21,7 +22,8 @@ export const PinButton: React.FC<PinButtonProps> = ({ isPinned, onPinClick, isDa
|
|||
<Button
|
||||
variant={isDark ? 'secondary' : 'light'}
|
||||
className={`history-pin ${className || ''} ${isPinned ? 'pinned' : ''}`}
|
||||
onClick={onPinClick}>
|
||||
onClick={onPinClick}
|
||||
{...cypressId('history-entry-pin-button')}>
|
||||
<ForkAwesomeIcon icon='thumb-tack' />
|
||||
</Button>
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ import React, { useCallback, useMemo } from 'react'
|
|||
import { Form } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('LanguagePicker')
|
||||
const languages = {
|
||||
|
@ -81,7 +82,13 @@ export const LanguagePicker: React.FC = () => {
|
|||
)
|
||||
|
||||
return (
|
||||
<Form.Control as='select' size='sm' className='mb-2 mx-auto w-auto' value={languageCode} onChange={onChangeLang}>
|
||||
<Form.Control
|
||||
as='select'
|
||||
size='sm'
|
||||
className='mb-2 mx-auto w-auto'
|
||||
value={languageCode}
|
||||
onChange={onChangeLang}
|
||||
{...cypressId('language-picker')}>
|
||||
{languageOptions}
|
||||
</Form.Control>
|
||||
)
|
||||
|
|
|
@ -14,6 +14,7 @@ import { NewUserNoteButton } from '../new-user-note-button'
|
|||
import { SignInButton } from '../sign-in-button'
|
||||
import { UserDropdown } from '../user-dropdown'
|
||||
import './header-bar.scss'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const HeaderBar: React.FC = () => {
|
||||
useTranslation()
|
||||
|
@ -22,10 +23,10 @@ const HeaderBar: React.FC = () => {
|
|||
return (
|
||||
<Navbar className='justify-content-between'>
|
||||
<div className='nav header-nav'>
|
||||
<HeaderNavLink to='/intro' id='navLinkIntro'>
|
||||
<HeaderNavLink to='/intro' {...cypressId('navLinkIntro')}>
|
||||
<Trans i18nKey='landing.navigation.intro' />
|
||||
</HeaderNavLink>
|
||||
<HeaderNavLink to='/history' id='navLinkHistory'>
|
||||
<HeaderNavLink to='/history' {...cypressId('navLinkHistory')}>
|
||||
<Trans i18nKey='landing.navigation.history' />
|
||||
</HeaderNavLink>
|
||||
</div>
|
||||
|
|
|
@ -7,17 +7,18 @@
|
|||
import React from 'react'
|
||||
import { Nav } from 'react-bootstrap'
|
||||
import { LinkContainer } from 'react-router-bootstrap'
|
||||
import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export interface HeaderNavLinkProps {
|
||||
export interface HeaderNavLinkProps extends PropsWithDataCypressId {
|
||||
to: string
|
||||
id: string
|
||||
}
|
||||
|
||||
export const HeaderNavLink: React.FC<HeaderNavLinkProps> = ({ to, id, children }) => {
|
||||
export const HeaderNavLink: React.FC<HeaderNavLinkProps> = ({ to, children, ...props }) => {
|
||||
return (
|
||||
<Nav.Item>
|
||||
<LinkContainer to={to}>
|
||||
<Nav.Link id={id} className='text-light' href={to}>
|
||||
<Nav.Link className='text-light' href={to} {...cypressId(props)}>
|
||||
{children}
|
||||
</Nav.Link>
|
||||
</LinkContainer>
|
||||
|
|
|
@ -9,12 +9,17 @@ import { Button } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { LinkContainer } from 'react-router-bootstrap'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const NewGuestNoteButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<LinkContainer to={'/new'} title={t('landing.navigation.newGuestNote')}>
|
||||
<Button variant='primary' size='sm' className='d-inline-flex align-items-center'>
|
||||
<Button
|
||||
variant='primary'
|
||||
size='sm'
|
||||
className='d-inline-flex align-items-center'
|
||||
{...cypressId('new-guest-note-button')}>
|
||||
<ForkAwesomeIcon icon='plus' className='mx-1' />
|
||||
<span>
|
||||
<Trans i18nKey='landing.navigation.newGuestNote' />
|
||||
|
|
|
@ -9,12 +9,17 @@ import { Button } from 'react-bootstrap'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { LinkContainer } from 'react-router-bootstrap'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const NewUserNoteButton: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<LinkContainer to={'/new'} title={t('landing.navigation.newNote')}>
|
||||
<Button variant='primary' size='sm' className='d-inline-flex align-items-center'>
|
||||
<Button
|
||||
variant='primary'
|
||||
size='sm'
|
||||
className='d-inline-flex align-items-center'
|
||||
{...cypressId('new-note-button')}>
|
||||
<ForkAwesomeIcon icon='plus' className='mx-1' />
|
||||
<span>
|
||||
<Trans i18nKey='landing.navigation.newNote' />
|
||||
|
|
|
@ -12,6 +12,7 @@ import { clearUser } from '../../../redux/user/methods'
|
|||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import { UserAvatar } from '../../common/user-avatar/user-avatar'
|
||||
import { useApplicationState } from '../../../hooks/common/use-application-state'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
export const UserDropdown: React.FC = () => {
|
||||
useTranslation()
|
||||
|
@ -23,19 +24,19 @@ export const UserDropdown: React.FC = () => {
|
|||
|
||||
return (
|
||||
<Dropdown alignRight>
|
||||
<Dropdown.Toggle size='sm' variant='dark' id='dropdown-user' className={'d-flex align-items-center'}>
|
||||
<Dropdown.Toggle size='sm' variant='dark' {...cypressId('user-dropdown')} className={'d-flex align-items-center'}>
|
||||
<UserAvatar name={user.name} photo={user.photo} />
|
||||
</Dropdown.Toggle>
|
||||
|
||||
<Dropdown.Menu className='text-start'>
|
||||
<LinkContainer to={'/n/features'}>
|
||||
<Dropdown.Item dir='auto'>
|
||||
<Dropdown.Item dir='auto' {...cypressId('user-dropdown-features-button')}>
|
||||
<ForkAwesomeIcon icon='bolt' fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey='editor.help.documents.features' />
|
||||
</Dropdown.Item>
|
||||
</LinkContainer>
|
||||
<LinkContainer to={'/profile'}>
|
||||
<Dropdown.Item dir='auto'>
|
||||
<Dropdown.Item dir='auto' {...cypressId('user-dropdown-profile-button')}>
|
||||
<ForkAwesomeIcon icon='user' fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey='profile.userProfile' />
|
||||
</Dropdown.Item>
|
||||
|
@ -44,7 +45,8 @@ export const UserDropdown: React.FC = () => {
|
|||
dir='auto'
|
||||
onClick={() => {
|
||||
clearUser()
|
||||
}}>
|
||||
}}
|
||||
{...cypressId('user-dropdown-sign-out-button')}>
|
||||
<ForkAwesomeIcon icon='sign-out' fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey='login.signOut' />
|
||||
</Dropdown.Item>
|
||||
|
|
|
@ -8,6 +8,7 @@ import React, { useEffect, useRef } from 'react'
|
|||
import './abc.scss'
|
||||
import { Logger } from '../../../../utils/logger'
|
||||
import type { CodeProps } from '../../replace-components/code-block-component-replacer'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('AbcFrame')
|
||||
|
||||
|
@ -28,5 +29,5 @@ export const AbcFrame: React.FC<CodeProps> = ({ code }) => {
|
|||
})
|
||||
}, [code])
|
||||
|
||||
return <div ref={container} className={'abcjs-score bg-white text-black svg-container'} />
|
||||
return <div ref={container} className={'abcjs-score bg-white text-black svg-container'} {...cypressId('abcjs')} />
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import React, { useMemo } from 'react'
|
||||
import { parseCsv } from './csv-parser'
|
||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||
|
||||
export interface CsvTableProps {
|
||||
code: string
|
||||
|
@ -63,7 +64,7 @@ export const CsvTable: React.FC<CsvTableProps> = ({
|
|||
)
|
||||
|
||||
return (
|
||||
<table className={'csv-html-table table-striped'}>
|
||||
<table className={'csv-html-table table-striped'} {...cypressId('csv-html-table')}>
|
||||
{renderTableHeader}
|
||||
{renderTableBody}
|
||||
</table>
|
||||
|
|
|
@ -66,7 +66,7 @@ export const HighlightedCode: React.FC<HighlightedCodeProps> = ({ code, language
|
|||
}, [code, language, startLineNumber])
|
||||
|
||||
return (
|
||||
<div className={'code-highlighter'}>
|
||||
<div className={'code-highlighter'} {...cypressId('highlighted-code-block')}>
|
||||
<code className={`hljs ${startLineNumber !== undefined ? 'showGutter' : ''} ${wrapLines ? 'wrapLines' : ''}`}>
|
||||
{dom}
|
||||
</code>
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
import { MarkdownExtension } from '../markdown-extension'
|
||||
import type MarkdownIt from 'markdown-it'
|
||||
import plantuml from 'markdown-it-plantuml'
|
||||
import type Renderer from 'markdown-it/lib/renderer'
|
||||
import type { RenderRule } from 'markdown-it/lib/renderer'
|
||||
import type Renderer from 'markdown-it/lib/renderer'
|
||||
import type Token from 'markdown-it/lib/token'
|
||||
import type { Options } from 'markdown-it/lib'
|
||||
import type { ComponentReplacer } from '../../replace-components/component-replacer'
|
||||
|
|
|
@ -14,9 +14,9 @@ import type { AccessToken } from '../../../api/tokens/types'
|
|||
import { CopyableField } from '../../common/copyable/copyable-field/copyable-field'
|
||||
import { IconButton } from '../../common/icon-button/icon-button'
|
||||
import { CommonModal } from '../../common/modals/common-modal'
|
||||
import { DeletionModal } from '../../common/modals/deletion-modal'
|
||||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import { Logger } from '../../../utils/logger'
|
||||
import { cypressId } from '../../../utils/cypress-attribute'
|
||||
|
||||
const log = new Logger('ProfileAccessTokens')
|
||||
|
||||
|
@ -108,7 +108,9 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
return (
|
||||
<ListGroup.Item className='bg-dark' key={token.created}>
|
||||
<Row>
|
||||
<Col className='text-start'>{token.label}</Col>
|
||||
<Col className='text-start' {...cypressId('access-token-label')}>
|
||||
{token.label}
|
||||
</Col>
|
||||
<Col className='text-start text-white-50'>
|
||||
<Trans
|
||||
i18nKey='profile.accessTokens.created'
|
||||
|
@ -120,7 +122,12 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
/>
|
||||
</Col>
|
||||
<Col xs='auto'>
|
||||
<IconButton icon='trash-o' variant='danger' onClick={() => selectForDeletion(token.created)} />
|
||||
<IconButton
|
||||
icon='trash-o'
|
||||
variant='danger'
|
||||
onClick={() => selectForDeletion(token.created)}
|
||||
{...cypressId('access-token-delete-button')}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</ListGroup.Item>
|
||||
|
@ -140,10 +147,16 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
onChange={(event: ChangeEvent<HTMLInputElement>) => setNewTokenLabel(event.target.value)}
|
||||
isValid={newTokenSubmittable}
|
||||
required
|
||||
{...cypressId('access-token-add-input')}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={'auto'}>
|
||||
<Button type='submit' variant='primary' size='sm' disabled={!newTokenSubmittable}>
|
||||
<Button
|
||||
type='submit'
|
||||
variant='primary'
|
||||
size='sm'
|
||||
disabled={!newTokenSubmittable}
|
||||
{...cypressId('access-token-add-button')}>
|
||||
<Trans i18nKey='profile.accessTokens.createToken' />
|
||||
</Button>
|
||||
</Col>
|
||||
|
@ -155,7 +168,8 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
<CommonModal
|
||||
show={showAddedModal}
|
||||
onHide={() => setShowAddedModal(false)}
|
||||
titleI18nKey='profile.modal.addedAccessToken.title'>
|
||||
titleI18nKey='profile.modal.addedAccessToken.title'
|
||||
{...cypressId('access-token-modal-add')}>
|
||||
<Modal.Body>
|
||||
<Trans i18nKey='profile.modal.addedAccessToken.message' />
|
||||
<br />
|
||||
|
@ -168,14 +182,20 @@ export const ProfileAccessTokens: React.FC = () => {
|
|||
</Modal.Footer>
|
||||
</CommonModal>
|
||||
|
||||
<DeletionModal
|
||||
onConfirm={deleteToken}
|
||||
deletionButtonI18nKey={'common.delete'}
|
||||
<CommonModal
|
||||
show={showDeleteModal}
|
||||
onHide={() => setShowDeleteModal(false)}
|
||||
titleI18nKey={'profile.modal.deleteAccessToken.title'}>
|
||||
<Trans i18nKey='profile.modal.deleteAccessToken.message' />
|
||||
</DeletionModal>
|
||||
titleI18nKey={'profile.modal.deleteAccessToken.title'}
|
||||
{...cypressId('access-token-modal-delete')}>
|
||||
<Modal.Body>
|
||||
<Trans i18nKey='profile.modal.deleteAccessToken.message' />
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant='danger' onClick={deleteToken}>
|
||||
<Trans i18nKey={'common.delete'} />
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</CommonModal>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue