test: add new tests for multiple examples

Added tests for CSS modules, Custom Documents and the Default Editor example
This commit is contained in:
Dominik Biedebach 2022-05-11 11:44:14 +02:00 committed by Dominik
parent 790aaeb915
commit 3d0074b294
15 changed files with 538 additions and 20 deletions

View File

@ -0,0 +1,172 @@
import './styles.scss'
import React from 'react'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import styles from './index.module.css'
const MenuBar = ({ editor }) => {
if (!editor) {
return null
}
return (
<div className={`toolbar ${styles.toolbar}`}>
<button
onClick={() => editor.chain().focus().toggleBold().run()}
className={editor.isActive('bold') ? 'is-active' : ''}
>
bold
</button>
<button
onClick={() => editor.chain().focus().toggleItalic().run()}
className={editor.isActive('italic') ? 'is-active' : ''}
>
italic
</button>
<button
onClick={() => editor.chain().focus().toggleStrike().run()}
className={editor.isActive('strike') ? 'is-active' : ''}
>
strike
</button>
<button
onClick={() => editor.chain().focus().toggleCode().run()}
className={editor.isActive('code') ? 'is-active' : ''}
>
code
</button>
<button onClick={() => editor.chain().focus().unsetAllMarks().run()}>
clear marks
</button>
<button onClick={() => editor.chain().focus().clearNodes().run()}>
clear nodes
</button>
<button
onClick={() => editor.chain().focus().setParagraph().run()}
className={editor.isActive('paragraph') ? 'is-active' : ''}
>
paragraph
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
className={editor.isActive('heading', { level: 1 }) ? 'is-active' : ''}
>
h1
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
className={editor.isActive('heading', { level: 2 }) ? 'is-active' : ''}
>
h2
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
className={editor.isActive('heading', { level: 3 }) ? 'is-active' : ''}
>
h3
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 4 }).run()}
className={editor.isActive('heading', { level: 4 }) ? 'is-active' : ''}
>
h4
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 5 }).run()}
className={editor.isActive('heading', { level: 5 }) ? 'is-active' : ''}
>
h5
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 6 }).run()}
className={editor.isActive('heading', { level: 6 }) ? 'is-active' : ''}
>
h6
</button>
<button
onClick={() => editor.chain().focus().toggleBulletList().run()}
className={editor.isActive('bulletList') ? 'is-active' : ''}
>
bullet list
</button>
<button
onClick={() => editor.chain().focus().toggleOrderedList().run()}
className={editor.isActive('orderedList') ? 'is-active' : ''}
>
ordered list
</button>
<button
onClick={() => editor.chain().focus().toggleCodeBlock().run()}
className={editor.isActive('codeBlock') ? 'is-active' : ''}
>
code block
</button>
<button
onClick={() => editor.chain().focus().toggleBlockquote().run()}
className={editor.isActive('blockquote') ? 'is-active' : ''}
>
blockquote
</button>
<button onClick={() => editor.chain().focus().setHorizontalRule().run()}>
horizontal rule
</button>
<button onClick={() => editor.chain().focus().setHardBreak().run()}>
hard break
</button>
<button onClick={() => editor.chain().focus().undo().run()}>
undo
</button>
<button onClick={() => editor.chain().focus().redo().run()}>
redo
</button>
</div>
)
}
export default () => {
const editor = useEditor({
extensions: [
StarterKit,
],
content: `
<h2>
Hi there,
</h2>
<p>
this is a <em>basic</em> example of <strong>tiptap</strong>. Sure, there are all kind of basic text styles youd probably expect from a text editor. But wait until you see the lists:
</p>
<ul>
<li>
Thats a bullet list with one
</li>
<li>
or two list items.
</li>
</ul>
<p>
Isnt that great? And all of that is editable. But wait, theres more. Lets try a code block:
</p>
<pre><code class="language-css">body {
display: none;
}</code></pre>
<p>
I know, I know, this is impressive. Its only the tip of the iceberg though. Give it a try and click a little bit around. Dont forget to check the other examples too.
</p>
<blockquote>
Wow, thats amazing. Good work, boy! 👏
<br />
Mom
</blockquote>
`,
})
return (
<div>
<MenuBar editor={editor} />
<EditorContent editor={editor} />
</div>
)
}

View File

@ -0,0 +1,4 @@
.toolbar {
background-color: red;
padding: 16px;
}

View File

@ -0,0 +1,11 @@
context('/src/Examples/CSSModules/React/', () => {
before(() => {
cy.visit('/src/Examples/CSSModules/React/')
})
it('should apply a randomly generated class that adds padding and background color to the toolbar', () => {
cy.get('.toolbar').should('exist')
cy.get('.toolbar').should('have.css', 'background-color', 'rgb(255, 0, 0)')
cy.get('.toolbar').should('have.css', 'padding', '16px')
})
})

View File

@ -0,0 +1,56 @@
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
ul,
ol {
padding: 0 1rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.1;
}
code {
background-color: rgba(#616161, 0.1);
color: #616161;
}
pre {
background: #0D0D0D;
color: #FFF;
font-family: 'JetBrainsMono', monospace;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
code {
color: inherit;
padding: 0;
background: none;
font-size: 0.8rem;
}
}
img {
max-width: 100%;
height: auto;
}
blockquote {
padding-left: 1rem;
border-left: 2px solid rgba(#0D0D0D, 0.1);
}
hr {
border: none;
border-top: 2px solid rgba(#0D0D0D, 0.1);
margin: 2rem 0;
}
}

View File

@ -1,3 +0,0 @@
h1 {
color: red;
}

View File

@ -0,0 +1,4 @@
.toolbar {
background-color: red;
padding: 16px;
}

View File

@ -3,15 +3,9 @@ context('/src/Examples/CSSModules/Vue/', () => {
cy.visit('/src/Examples/CSSModules/Vue/') cy.visit('/src/Examples/CSSModules/Vue/')
}) })
beforeEach(() => { it('should apply a randomly generated class that adds padding and background color to the toolbar', () => {
cy.get('.ProseMirror').then(([{ editor }]) => { cy.get('.toolbar').should('exist')
editor.commands.setContent('<h1>Example Text</h1>') cy.get('.toolbar').should('have.css', 'background-color', 'rgb(255, 0, 0)')
cy.get('.ProseMirror').type('{selectall}') cy.get('.toolbar').should('have.css', 'padding', '16px')
})
})
it('should apply a red headline style to h1', () => {
cy.get('.ProseMirror h1').should('exist')
cy.get('.ProseMirror h1').should('have.css', 'color', 'rgb(255, 0, 0)')
}) })
}) })

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="editor"> <div v-if="editor" class="toolbar" :class="styles.toolbar">
<button @click="editor.chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }"> <button @click="editor.chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }">
bold bold
</button> </button>
@ -70,7 +70,9 @@
<script> <script>
import { Editor, EditorContent } from '@tiptap/vue-3' import { Editor, EditorContent } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit' import StarterKit from '@tiptap/starter-kit'
import './index.css' import styles from './index.module.css'
console.log(styles)
export default { export default {
components: { components: {
@ -80,6 +82,7 @@ export default {
data() { data() {
return { return {
editor: null, editor: null,
styles,
} }
}, },
@ -89,7 +92,7 @@ export default {
StarterKit, StarterKit,
], ],
content: ` content: `
<h1> <h1 class="test">
This is a red headline This is a red headline
</h1> </h1>
<p> <p>

View File

@ -5,7 +5,7 @@ context('/src/Examples/Community/React/', () => {
it('should count the characters correctly', () => { it('should count the characters correctly', () => {
// check if count text is "44/280 characters" // check if count text is "44/280 characters"
cy.get('.character-count__text', { timeout: 25000 }).should('have.text', '44/280 characters') cy.get('.character-count__text').should('have.text', '44/280 characters')
// type in .ProseMirror // type in .ProseMirror
cy.get('.ProseMirror').type(' Hello World') cy.get('.ProseMirror').type(' Hello World')

View File

@ -5,7 +5,7 @@ context('/src/Examples/Community/Vue/', () => {
it('should count the characters correctly', () => { it('should count the characters correctly', () => {
// check if count text is "44/280 characters" // check if count text is "44/280 characters"
cy.get('.character-count__text', { timeout: 25000 }).should('have.text', '44/280 characters') cy.get('.character-count__text').should('have.text', '44/280 characters')
// type in .ProseMirror // type in .ProseMirror
cy.get('.ProseMirror').type(' Hello World') cy.get('.ProseMirror').type(' Hello World')

View File

@ -0,0 +1,46 @@
context('/src/Examples/CustomDocument/React/', () => {
beforeEach(() => {
cy.visit('/src/Examples/CustomDocument/React/')
})
it('should have a working tiptap instance', () => {
cy.get('.ProseMirror').then(([{ editor }]) => {
// eslint-disable-next-line
expect(editor).to.not.be.null
})
})
it('should have a headline and a paragraph', () => {
cy.get('.ProseMirror h1').should('exist').should('have.text', 'Itll always have a heading …')
cy.get('.ProseMirror p').should('exist').should('have.text', '… if you pass a custom document. Thats the beauty of having full control over the schema.')
})
it('should have a tooltip for a paragraph on a new line', () => {
cy.get('.ProseMirror').type('{enter}')
cy.get('.ProseMirror p[data-placeholder]').should('exist').should('have.attr', 'data-placeholder', 'Can you add some further context?')
})
it('should have a headline after clearing the document', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('.ProseMirror').focus()
cy.get('.ProseMirror h1[data-placeholder]')
.should('exist')
.should('have.attr', 'class', 'is-empty is-editor-empty')
.should('have.attr', 'data-placeholder', 'Whats the title?')
})
it('should have a headline after clearing the document & enter paragraph automatically after adding a headline', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}Hello world{enter}')
cy.get('.ProseMirror h1')
.should('exist')
.should('have.text', 'Hello world')
cy.get('.ProseMirror p[data-placeholder]')
.should('exist').
should('have.attr', 'data-placeholder', 'Can you add some further context?')
cy.get('.ProseMirror').type('This is a paragraph for this test document')
cy.get('.ProseMirror p')
.should('exist')
.should('have.text', 'This is a paragraph for this test document')
})
})

View File

@ -1,7 +1,48 @@
context('/src/Examples/CustomDocument/Vue/', () => { context('/src/Examples/CustomDocument/Vue/', () => {
before(() => { beforeEach(() => {
cy.visit('/src/Examples/CustomDocument/Vue/') cy.visit('/src/Examples/CustomDocument/Vue/')
}) })
// TODO: Write tests it('should have a working tiptap instance', () => {
cy.get('.ProseMirror').then(([{ editor }]) => {
// eslint-disable-next-line
expect(editor).to.not.be.null
})
})
it('should have a headline and a paragraph', () => {
cy.get('.ProseMirror h1').should('exist').should('have.text', 'Itll always have a heading …')
cy.get('.ProseMirror p').should('exist').should('have.text', '… if you pass a custom document. Thats the beauty of having full control over the schema.')
})
it('should have a tooltip for a paragraph on a new line', () => {
cy.get('.ProseMirror').type('{enter}')
cy.get('.ProseMirror p[data-placeholder]').should('exist').should('have.attr', 'data-placeholder', 'Can you add some further context?')
})
it('should have a headline after clearing the document', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.wait(100)
cy.get('.ProseMirror').focus()
cy.get('.ProseMirror h1[data-placeholder]')
.should('exist')
.should('have.attr', 'class', 'is-empty is-editor-empty')
.should('have.attr', 'data-placeholder', 'Whats the title?')
})
it('should have a headline after clearing the document & enter paragraph automatically after adding a headline', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}Hello world{enter}')
cy.wait(100)
cy.get('.ProseMirror h1')
.should('exist')
.should('have.text', 'Hello world')
cy.get('.ProseMirror p[data-placeholder]')
.should('exist')
.should('have.attr', 'data-placeholder', 'Can you add some further context?')
cy.get('.ProseMirror').type('This is a paragraph for this test document')
cy.get('.ProseMirror p')
.should('exist')
.should('have.text', 'This is a paragraph for this test document')
})
}) })

View File

@ -19,4 +19,99 @@ context('/src/Examples/Default/React/', () => {
.find('p') .find('p')
.should('contain', 'Example Text') .should('contain', 'Example Text')
}) })
const buttonMarks = [
{ label: 'bold', tag: 'strong' },
{ label: 'italic', tag: 'em' },
{ label: 'strike', tag: 's' },
]
buttonMarks.forEach(m => {
it(`should apply ${m.label} when the button is pressed`, () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('button').contains(m.label).click()
cy.get(`.ProseMirror ${m.tag}`).should('exist').should('have.text', 'Hello world')
})
})
it('should clear marks when the button is pressed', () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('button').contains('bold').click()
cy.get('.ProseMirror strong').should('exist').should('have.text', 'Hello world')
cy.get('button').contains('clear marks').click()
cy.get('.ProseMirror strong').should('not.exist')
})
it('should clear nodes when the button is pressed', () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('bullet list').click()
cy.get('.ProseMirror ul').should('exist').should('have.text', 'Hello world')
cy.get('.ProseMirror').type('{enter}A second item{enter}A third item{selectall}')
cy.get('button').contains('clear nodes').click()
cy.get('.ProseMirror ul').should('not.exist')
cy.get('.ProseMirror p').should('have.length', 3)
})
const buttonNodes = [
{ label: 'h1', tag: 'h1' },
{ label: 'h2', tag: 'h2' },
{ label: 'h3', tag: 'h3' },
{ label: 'h4', tag: 'h4' },
{ label: 'h5', tag: 'h5' },
{ label: 'h6', tag: 'h6' },
{ label: 'bullet list', tag: 'ul' },
{ label: 'ordered list', tag: 'ol' },
{ label: 'code block', tag: 'pre code' },
{ label: 'blockquote', tag: 'blockquote' },
]
buttonNodes.forEach(n => {
it(`should set ${n.label} when the button is pressed`, () => {
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}Hello world{selectall}')
cy.get('button').contains(n.label).click()
cy.get(`.ProseMirror ${n.tag}`).should('exist').should('have.text', 'Hello world')
cy.get('button').contains(n.label).click()
cy.get(`.ProseMirror ${n.tag}`).should('not.exist')
})
})
it('should add a hr when on the same line as a node', () => {
cy.get('.ProseMirror').type('{rightArrow}')
cy.get('button').contains('horizontal rule').click()
cy.get('.ProseMirror hr').should('exist')
cy.get('.ProseMirror h1').should('exist')
})
it('should add a hr when on a new line', () => {
cy.get('.ProseMirror').type('{rightArrow}{enter}')
cy.get('button').contains('horizontal rule').click()
cy.get('.ProseMirror hr').should('exist')
cy.get('.ProseMirror h1').should('exist')
})
it('should add a br', () => {
cy.get('.ProseMirror').type('{rightArrow}')
cy.get('button').contains('hard break').click()
cy.get('.ProseMirror h1 br').should('exist')
})
it('should undo', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('button').contains('undo').click()
cy.get('.ProseMirror').should('contain', 'Hello world')
})
it('should redo', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('button').contains('undo').click()
cy.get('.ProseMirror').should('contain', 'Hello world')
cy.get('button').contains('redo').click()
cy.get('.ProseMirror').should('not.contain', 'Hello world')
})
}) })

View File

@ -19,4 +19,99 @@ context('/src/Examples/Default/Vue/', () => {
.find('p') .find('p')
.should('contain', 'Example Text') .should('contain', 'Example Text')
}) })
const buttonMarks = [
{ label: 'bold', tag: 'strong' },
{ label: 'italic', tag: 'em' },
{ label: 'strike', tag: 's' },
]
buttonMarks.forEach(m => {
it(`should apply ${m.label} when the button is pressed`, () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('button').contains(m.label).click()
cy.get(`.ProseMirror ${m.tag}`).should('exist').should('have.text', 'Hello world')
})
})
it('should clear marks when the button is pressed', () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}')
cy.get('button').contains('bold').click()
cy.get('.ProseMirror strong').should('exist').should('have.text', 'Hello world')
cy.get('button').contains('clear marks').click()
cy.get('.ProseMirror strong').should('not.exist')
})
it('should clear nodes when the button is pressed', () => {
cy.get('.ProseMirror').type('{selectall}Hello world')
cy.get('button').contains('bullet list').click()
cy.get('.ProseMirror ul').should('exist').should('have.text', 'Hello world')
cy.get('.ProseMirror').type('{enter}A second item{enter}A third item{selectall}')
cy.get('button').contains('clear nodes').click()
cy.get('.ProseMirror ul').should('not.exist')
cy.get('.ProseMirror p').should('have.length', 3)
})
const buttonNodes = [
{ label: 'h1', tag: 'h1' },
{ label: 'h2', tag: 'h2' },
{ label: 'h3', tag: 'h3' },
{ label: 'h4', tag: 'h4' },
{ label: 'h5', tag: 'h5' },
{ label: 'h6', tag: 'h6' },
{ label: 'bullet list', tag: 'ul' },
{ label: 'ordered list', tag: 'ol' },
{ label: 'code block', tag: 'pre code' },
{ label: 'blockquote', tag: 'blockquote' },
]
buttonNodes.forEach(n => {
it(`should set ${n.label} when the button is pressed`, () => {
cy.get('button').contains('paragraph').click()
cy.get('.ProseMirror').type('{selectall}Hello world{selectall}')
cy.get('button').contains(n.label).click()
cy.get(`.ProseMirror ${n.tag}`).should('exist').should('have.text', 'Hello world')
cy.get('button').contains(n.label).click()
cy.get(`.ProseMirror ${n.tag}`).should('not.exist')
})
})
it('should add a hr when on the same line as a node', () => {
cy.get('.ProseMirror').type('{rightArrow}')
cy.get('button').contains('horizontal rule').click()
cy.get('.ProseMirror hr').should('exist')
cy.get('.ProseMirror h1').should('exist')
})
it('should add a hr when on a new line', () => {
cy.get('.ProseMirror').type('{rightArrow}{enter}')
cy.get('button').contains('horizontal rule').click()
cy.get('.ProseMirror hr').should('exist')
cy.get('.ProseMirror h1').should('exist')
})
it('should add a br', () => {
cy.get('.ProseMirror').type('{rightArrow}')
cy.get('button').contains('hard break').click()
cy.get('.ProseMirror h1 br').should('exist')
})
it('should undo', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('button').contains('undo').click()
cy.get('.ProseMirror').should('contain', 'Hello world')
})
it('should redo', () => {
cy.get('.ProseMirror').type('{selectall}{backspace}')
cy.get('button').contains('undo').click()
cy.get('.ProseMirror').should('contain', 'Hello world')
cy.get('button').contains('redo').click()
cy.get('.ProseMirror').should('not.contain', 'Hello world')
})
}) })