mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-22 17:56:30 -05:00
Add e2e tests for diagrams and embeddings (#1025)
This commit is contained in:
parent
c2664b68f0
commit
f9809a4edf
9 changed files with 187 additions and 14 deletions
74
cypress/integration/diagrams.spec.ts
Normal file
74
cypress/integration/diagrams.spec.ts
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe('Diagram codeblock ', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visitTestEditor()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders markmap', () => {
|
||||||
|
cy.codemirrorFill('```markmap\n- pro\n- contra\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('[data-cy=markmap]')
|
||||||
|
.children()
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders vega-lite', () => {
|
||||||
|
cy.codemirrorFill('```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.codemirrorFill('```graphviz\ngraph {\na -- b\n}\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('[data-cy=graphviz]')
|
||||||
|
.children()
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders mermaid', () => {
|
||||||
|
cy.codemirrorFill('```mermaid\ngraph TD;\n A-->B;\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.mermaid')
|
||||||
|
.children()
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders flowcharts', () => {
|
||||||
|
cy.codemirrorFill('```flow\nst=>start: Start\ne=>end: End\nst->e\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('[data-cy=flowchart]')
|
||||||
|
.children()
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders abc scores', () => {
|
||||||
|
cy.codemirrorFill('```abc\nM:4/4\nK:G\n|:GABc dedB:|\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.abcjs-score')
|
||||||
|
.children()
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders csv as table', () => {
|
||||||
|
cy.codemirrorFill('```csv delimiter=; header\na;b;c;d\n1;2;3;4\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.csv-html-table')
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders plantuml', () => {
|
||||||
|
cy.codemirrorFill('```plantuml\nclass Example\n```')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('img')
|
||||||
|
// PlantUML uses base64 encoded version of zip-deflated PlantUML code in the request URL.
|
||||||
|
.should('have.attr', 'src', 'http://mock-plantuml.local/svg/SoWkIImgAStDuKhEIImkLd2jICmjo4dbSaZDIm6A0W00')
|
||||||
|
})
|
||||||
|
})
|
69
cypress/integration/linkEmbedder.spec.ts
Normal file
69
cypress/integration/linkEmbedder.spec.ts
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe('Link gets replaced with embedding: ', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visitTestEditor()
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO Add general testing of one-click-embedding component. The tests below just test a specific use of the component.
|
||||||
|
|
||||||
|
it('GitHub Gist', () => {
|
||||||
|
cy.codemirrorFill('https://gist.github.com/schacon/1')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.one-click-embedding.gist-frame')
|
||||||
|
.click()
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('iframe[data-cy=gh-gist]')
|
||||||
|
.should('be.visible')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('YouTube', () => {
|
||||||
|
cy.codemirrorFill('https://www.youtube.com/watch?v=YE7VzlLtp-4')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.one-click-embedding-preview')
|
||||||
|
.should('have.attr', 'src', 'https://i.ytimg.com/vi/YE7VzlLtp-4/maxresdefault.jpg')
|
||||||
|
.parent()
|
||||||
|
.click()
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('iframe')
|
||||||
|
.should('have.attr', 'src', 'https://www.youtube-nocookie.com/embed/YE7VzlLtp-4?autoplay=1')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Vimeo', () => {
|
||||||
|
cy.intercept({
|
||||||
|
method: 'GET',
|
||||||
|
url: 'https://vimeo.com/api/v2/video/23237102.json'
|
||||||
|
}, {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
},
|
||||||
|
body: '[{"thumbnail_large": "https://i.vimeocdn.com/video/503631401_640.jpg"}]'
|
||||||
|
})
|
||||||
|
cy.codemirrorFill('https://vimeo.com/23237102')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.one-click-embedding-preview')
|
||||||
|
.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')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Asciinema', () => {
|
||||||
|
cy.codemirrorFill('https://asciinema.org/a/117928')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.one-click-embedding-preview')
|
||||||
|
.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')
|
||||||
|
})
|
||||||
|
})
|
|
@ -4,12 +4,12 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
describe('Short code', () => {
|
describe('Short code gets replaced or rendered: ', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visitTestEditor()
|
cy.visitTestEditor()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('for pdfs', () => {
|
describe('pdf', () => {
|
||||||
it('renders a plain link', () => {
|
it('renders a plain link', () => {
|
||||||
cy.codemirrorFill(`{%pdf https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf %}`)
|
cy.codemirrorFill(`{%pdf https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf %}`)
|
||||||
cy.getMarkdownBody()
|
cy.getMarkdownBody()
|
||||||
|
@ -17,4 +17,30 @@ describe('Short code', () => {
|
||||||
.should('have.attr', 'href', 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf')
|
.should('have.attr', 'href', 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('slideshare', () => {
|
||||||
|
it('renders a plain link', () => {
|
||||||
|
cy.codemirrorFill(`{%slideshare example/123456789 %}`)
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'https://www.slideshare.net/example/123456789')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('speakerdeck', () => {
|
||||||
|
it('renders a plain link', () => {
|
||||||
|
cy.codemirrorFill(`{%speakerdeck example/123456789 %}`)
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'https://speakerdeck.com/example/123456789')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('youtube', () => {
|
||||||
|
it('renders one-click-embedding', () => {
|
||||||
|
cy.codemirrorFill(`{%youtube YE7VzlLtp-4 %}`)
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('.one-click-embedding.embed-responsive-item')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -45,6 +45,7 @@ beforeEach(() => {
|
||||||
termsOfUse: 'https://example.com/termsOfUse',
|
termsOfUse: 'https://example.com/termsOfUse',
|
||||||
imprint: 'https://example.com/imprint'
|
imprint: 'https://example.com/imprint'
|
||||||
},
|
},
|
||||||
|
plantumlServer: 'http://mock-plantuml.local',
|
||||||
version: {
|
version: {
|
||||||
version: 'mock',
|
version: 'mock',
|
||||||
sourceCodeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
|
sourceCodeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
|
||||||
|
|
|
@ -57,6 +57,6 @@ export const FlowChart: React.FC<FlowChartProps> = ({ code }) => {
|
||||||
<Trans i18nKey={ 'renderer.flowchart.invalidSyntax' }/>
|
<Trans i18nKey={ 'renderer.flowchart.invalidSyntax' }/>
|
||||||
</Alert>)
|
</Alert>)
|
||||||
} else {
|
} else {
|
||||||
return <div ref={ diagramRef } className={ 'text-center' }/>
|
return <div ref={ diagramRef } data-cy={ 'flowchart' } className={ 'text-center' }/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ export const GistFrame: React.FC<GistFrameProps> = ({ id }) => {
|
||||||
return (
|
return (
|
||||||
<iframe
|
<iframe
|
||||||
sandbox="allow-scripts allow-top-navigation-by-user-activation allow-popups"
|
sandbox="allow-scripts allow-top-navigation-by-user-activation allow-popups"
|
||||||
|
data-cy={ 'gh-gist' }
|
||||||
width='100%'
|
width='100%'
|
||||||
height={ `${ frameHeight }px` }
|
height={ `${ frameHeight }px` }
|
||||||
frameBorder='0'
|
frameBorder='0'
|
||||||
|
|
|
@ -55,12 +55,14 @@ export const GraphvizFrame: React.FC<GraphvizFrameProps> = ({ code }) => {
|
||||||
})
|
})
|
||||||
}, [code, error, showError])
|
}, [code, error, showError])
|
||||||
|
|
||||||
return <Fragment>
|
return (
|
||||||
<ShowIf condition={ !!error }>
|
<Fragment>
|
||||||
<Alert variant={ 'warning' }>{ error }</Alert>
|
<ShowIf condition={ !!error }>
|
||||||
</ShowIf>
|
<Alert variant={ 'warning' }>{ error }</Alert>
|
||||||
<div className={ 'text-center overflow-x-auto' } ref={ container }/>
|
</ShowIf>
|
||||||
</Fragment>
|
<div className={ 'text-center overflow-x-auto' } data-cy={ 'graphviz' } ref={ container }/>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GraphvizFrame
|
export default GraphvizFrame
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Fragment, useEffect, useRef, useState } from 'react'
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { LockButton } from '../../../common/lock-button/lock-button'
|
import { LockButton } from '../../../common/lock-button/lock-button'
|
||||||
import '../../utils/button-inside.scss'
|
import '../../utils/button-inside.scss'
|
||||||
|
@ -64,12 +64,12 @@ export const MarkmapFrame: React.FC<MarkmapFrameProps> = ({ code }) => {
|
||||||
}, [code])
|
}, [code])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<div data-cy={ 'markmap' }>
|
||||||
<div className={ 'text-center' } ref={ diagramContainer }/>
|
<div className={ 'text-center' } ref={ diagramContainer }/>
|
||||||
<div className={ 'text-right button-inside' }>
|
<div className={ 'text-right button-inside' }>
|
||||||
<LockButton locked={ disablePanAndZoom } onLockedChanged={ (newState => setDisablePanAndZoom(newState)) }
|
<LockButton locked={ disablePanAndZoom } onLockedChanged={ (newState => setDisablePanAndZoom(newState)) }
|
||||||
title={ disablePanAndZoom ? t('renderer.markmap.locked') : t('renderer.markmap.unlocked') }/>
|
title={ disablePanAndZoom ? t('renderer.markmap.locked') : t('renderer.markmap.unlocked') }/>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,9 @@ export const YouTubeFrame: React.FC<YouTubeFrameProps> = ({ id }) => {
|
||||||
return (
|
return (
|
||||||
<OneClickEmbedding containerClassName={ 'embed-responsive embed-responsive-16by9' }
|
<OneClickEmbedding containerClassName={ 'embed-responsive embed-responsive-16by9' }
|
||||||
previewContainerClassName={ 'embed-responsive-item' } hoverIcon={ 'youtube-play' }
|
previewContainerClassName={ 'embed-responsive-item' } hoverIcon={ 'youtube-play' }
|
||||||
loadingImageUrl={ `//i.ytimg.com/vi/${ id }/maxresdefault.jpg` }>
|
loadingImageUrl={ `https://i.ytimg.com/vi/${ id }/maxresdefault.jpg` }>
|
||||||
<iframe className='embed-responsive-item' title={ `youtube video of ${ id }` }
|
<iframe className='embed-responsive-item' title={ `youtube video of ${ id }` }
|
||||||
src={ `//www.youtube-nocookie.com/embed/${ id }?autoplay=1` }
|
src={ `https://www.youtube-nocookie.com/embed/${ id }?autoplay=1` }
|
||||||
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"/>
|
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"/>
|
||||||
</OneClickEmbedding>
|
</OneClickEmbedding>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue