mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-24 10:46:30 -05:00
Switch the base framework from Create React App to Next.JS
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
a979b6ffdd
commit
77a60c6c48
361 changed files with 5130 additions and 9605 deletions
1
.env.development
Normal file
1
.env.development
Normal file
|
@ -0,0 +1 @@
|
|||
NEXT_PUBLIC_USE_MOCK_API=true
|
|
@ -1 +1 @@
|
|||
INLINE_RUNTIME_CHUNK=false
|
||||
NEXT_PUBLIC_USE_MOCK_API=false
|
||||
|
|
1
.env.test
Normal file
1
.env.test
Normal file
|
@ -0,0 +1 @@
|
|||
NEXT_PUBLIC_USE_MOCK_API=true
|
44
.eslintrc.json
Normal file
44
.eslintrc.json
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"root": true,
|
||||
"parserOptions": {
|
||||
"tsconfigRootDir": "",
|
||||
"project": [
|
||||
"./tsconfig.json"
|
||||
]
|
||||
},
|
||||
"rules": {
|
||||
"no-use-before-define": "off",
|
||||
"no-debugger": "warn",
|
||||
"default-param-last": "off",
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"error",
|
||||
{
|
||||
"prefer": "type-imports",
|
||||
"disallowTypeAnnotations": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"testing-library"
|
||||
],
|
||||
"extends": [
|
||||
"next/core-web-vitals",
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/__tests__/**/*.[jt]s?(x)",
|
||||
"**/?(*.)+(spec|test).[jt]s?(x)"
|
||||
],
|
||||
"extends": ["plugin:testing-library/react"]
|
||||
}
|
||||
]
|
||||
}
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ '12', '14', '16' ]
|
||||
node: [ '14', '16' ]
|
||||
name: Test and build with NodeJS ${{ matrix.node }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
@ -38,6 +38,6 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile --prefer-offline
|
||||
- name: Test Project
|
||||
run: yarn test
|
||||
run: yarn test:ci
|
||||
- name: Build project
|
||||
run: yarn build:mock
|
||||
|
|
12
.github/workflows/e2e.yml
vendored
12
.github/workflows/e2e.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
|||
uses: actions/cache@v2.1.7
|
||||
id: build-cache
|
||||
with:
|
||||
path: build
|
||||
path: .next
|
||||
key: build-${{ github.sha }}
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
|
@ -56,8 +56,8 @@ jobs:
|
|||
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
name: next-build
|
||||
path: .next
|
||||
|
||||
end2end:
|
||||
name: Perform E2E Test in ${{ matrix.browser }}
|
||||
|
@ -79,13 +79,13 @@ jobs:
|
|||
- name: Download built frontend
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
name: next-build
|
||||
path: .next
|
||||
|
||||
- uses: cypress-io/github-action@v2
|
||||
with:
|
||||
browser: ${{ matrix.browser }}
|
||||
start: 'yarn serve:build'
|
||||
start: 'yarn start:ci'
|
||||
parallel: true
|
||||
record: true
|
||||
group: "UI - ${{ matrix.browser }}"
|
||||
|
|
31
.gitignore
vendored
31
.gitignore
vendored
|
@ -15,23 +15,36 @@
|
|||
# downloaded files during tests with cypress
|
||||
/cypress/downloads
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# ide
|
||||
.idea
|
||||
!.idea/dictionaries/hedgedoc.xml
|
||||
!.idea/copyright
|
||||
!.idea/prettier.xml
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
.eslintcache
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
# IDE
|
||||
.idea
|
||||
!.idea/dictionaries/hedgedoc.xml
|
||||
!.idea/copyright
|
||||
!.idea/prettier.xml
|
||||
|
|
11
.prettierrc.json
Normal file
11
.prettierrc.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"parser": "typescript",
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": true,
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "always"
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: LicenseRef-HedgeDoc-Icon-Usage-Guidelines
|
||||
SPDX-License-Identifier: CC0-1.0
|
31
README.md
31
README.md
|
@ -13,11 +13,12 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|||
[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/hedgedoc/react-client.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/hedgedoc/react-client/context:javascript)
|
||||
[![Total alerts](https://img.shields.io/lgtm/alerts/g/hedgedoc/react-client.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/hedgedoc/react-client/alerts/)
|
||||
|
||||
This is the new, improved and better looking frontend for HedgeDoc 2.0.
|
||||
Our goal is to recreate the current frontend in react and to improve it.
|
||||
This is the new, improved and better looking frontend for HedgeDoc 2.0. Our goal is to recreate the current frontend in
|
||||
react and to improve it.
|
||||
|
||||
## Preparation
|
||||
You need at least Node 12 (we recommend Node 16) and [yarn](https://yarnpkg.com/).
|
||||
|
||||
You need at least Node 14 (we recommend Node 16) and [yarn](https://yarnpkg.com/).
|
||||
|
||||
## Development mode
|
||||
|
||||
|
@ -25,13 +26,14 @@ You need at least Node 12 (we recommend Node 16) and [yarn](https://yarnpkg.com/
|
|||
2. Go inside the repo (e.g. `cd hedgedoc-react-client`)
|
||||
3. Run `yarn install`
|
||||
4. Either run
|
||||
- `yarn start` - Calls only mocked version of the api. Doesn't need a HedgeDoc backend.
|
||||
- `yarn start:for-real-backend` - Expects [a HedgeDoc backend server](https://github.com/hedgedoc/hedgedoc/tree/develop) running under [http://localhost:3000](http://localhost:3000))
|
||||
- `yarn dev` - Calls only mocked version of the api. Doesn't need a HedgeDoc backend.
|
||||
- `yarn start:for-real-backend` -
|
||||
Expects [a HedgeDoc backend server](https://github.com/hedgedoc/hedgedoc/tree/develop) running
|
||||
under [http://localhost:3000](http://localhost:3000))
|
||||
|
||||
This should run the app in the development mode and open [http://localhost:3001](http://localhost:3001) in your browser.
|
||||
|
||||
The page will reload if you make edits.
|
||||
You will also see any lint errors in the console.
|
||||
The page will reload if you make edits. You will also see any lint errors in the console.
|
||||
|
||||
### Tests
|
||||
|
||||
|
@ -45,25 +47,28 @@ Unit testing is done via jest.
|
|||
|
||||
We use [cypress](https://cypress.io) for e2e tests.
|
||||
|
||||
1. Start the frontend with `yarn start:test` in dev test mode or build a test build with `yarn build:test` which you can serve with `yarn serve:build`
|
||||
1. Start the frontend with `yarn dev:test` in dev test mode or build a test build with `yarn build:test` which you can
|
||||
serve with `yarn serve:build`
|
||||
Don't use the regular start/build command, or the tests will fail!
|
||||
2. Run `yarn cy:open` to open the cypress test loader
|
||||
3. Choose your browser and test
|
||||
4. Let the tests run
|
||||
|
||||
### Bundle analysis
|
||||
|
||||
You can inspect the generated production-bundle files to look for optimization issues.
|
||||
|
||||
1. Run `yarn analyze`
|
||||
2. Open the generated `build/report.html` in your favourite browser
|
||||
2. Open the generated `.next/server/analyze/server.html` in your favourite browser
|
||||
|
||||
## Production mode
|
||||
|
||||
1. Clone this repo (e.g. `git clone https://github.com/hedgedoc/react-client.git hedgedoc-react-client`)
|
||||
2. Go inside the repo (e.g. `cd hedgedoc-react-client`)
|
||||
3. Run `yarn install`
|
||||
4. Run `yarn build:production`
|
||||
4. Run `yarn build`
|
||||
|
||||
This will build the app in production mode and save it into the `build` folder.
|
||||
The production build is optimized for best performance, minimized
|
||||
and the filenames include a hash value of the content. Don't edit them by hand!
|
||||
This will build the app in production mode and save it into the `.next` folder. The production build is optimized for
|
||||
best performance, minimized and the filenames include a hash value of the content. Don't edit them by hand!
|
||||
|
||||
You can run the production build using the built-in server with `yarn start`.
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
if (!process.env.REACT_APP_BACKEND_BASE_URL) {
|
||||
console.error("==============\nREACT_APP_BACKEND_BASE_URL not set.\n Use this task only if you want to create a production build with a real backend. Otherwise use build:mock\n==============");
|
||||
process.exit(1);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const { when } = require('@craco/craco');
|
||||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
||||
|
||||
module.exports = {
|
||||
webpack: {
|
||||
plugins: {
|
||||
add: [
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{ from: 'node_modules/@hpcc-js/wasm/dist/graphvizlib.wasm', to: 'static/js' },
|
||||
{ from: 'node_modules/@hpcc-js/wasm/dist/expatlib.wasm', to: 'static/js' },
|
||||
{ from: 'node_modules/emoji-picker-element-data/en/emojibase/data.json', to: 'static/js/emoji-data.json' }
|
||||
],
|
||||
}),
|
||||
...when(Boolean(process.env.ANALYZE), () => [
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: "static",
|
||||
generateStatsFile: true
|
||||
})
|
||||
], [])
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ describe('Autocompletion works for', () => {
|
|||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line').contains('```abnf')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line').contains('```')
|
||||
cy.getMarkdownBody().findById('highlighted-code-block').should('exist')
|
||||
cy.getMarkdownBody().findByCypressId('highlighted-code-block').should('exist')
|
||||
})
|
||||
it('via doubleclick', () => {
|
||||
cy.setCodemirrorContent('```')
|
||||
|
@ -26,7 +26,7 @@ describe('Autocompletion works for', () => {
|
|||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(1) > .CodeMirror-line').contains('```abnf')
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(3) > .CodeMirror-line').contains('```')
|
||||
cy.getMarkdownBody().findById('highlighted-code-block').should('exist')
|
||||
cy.getMarkdownBody().findByCypressId('highlighted-code-block').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -109,14 +109,14 @@ describe('Autocompletion works for', () => {
|
|||
cy.get('@codeinput').type('{enter}')
|
||||
cy.get('.CodeMirror-hints').should('not.exist')
|
||||
cy.get('.CodeMirror-activeline').contains('![image alt](https:// "title")')
|
||||
cy.getMarkdownBody().find('.image-drop').should('exist')
|
||||
cy.getMarkdownBody().findByCypressId('image-placeholder-image-drop').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').contains('![image alt](https:// "title")')
|
||||
cy.getMarkdownBody().find('.image-drop').should('exist')
|
||||
cy.getMarkdownBody().findByCypressId('image-placeholder-image-drop').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -9,10 +9,14 @@ describe('Diagram codeblock ', () => {
|
|||
cy.visitTestEditor()
|
||||
})
|
||||
|
||||
it('renders markmap', () => {
|
||||
cy.setCodemirrorContent('```markmap\n- pro\n- contra\n```')
|
||||
cy.getMarkdownBody().findById('markmap').children().should('be.visible')
|
||||
})
|
||||
/*
|
||||
TODO: Readd test after fixing https://github.com/hedgedoc/react-client/issues/1709
|
||||
|
||||
it('renders markmap', () => {
|
||||
cy.setCodemirrorContent('```markmap\n- pro\n- contra\n```')
|
||||
cy.getMarkdownBody().findByCypressId('markmap').children().should('be.visible')
|
||||
})
|
||||
*/
|
||||
|
||||
it('renders vega-lite', () => {
|
||||
cy.setCodemirrorContent(
|
||||
|
@ -23,27 +27,27 @@ describe('Diagram codeblock ', () => {
|
|||
|
||||
it('renders graphviz', () => {
|
||||
cy.setCodemirrorContent('```graphviz\ngraph {\na -- b\n}\n```')
|
||||
cy.getMarkdownBody().findById('graphviz').children().should('be.visible')
|
||||
cy.getMarkdownBody().findByCypressId('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().findByCypressId('mermaid-frame').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders flowcharts', () => {
|
||||
cy.setCodemirrorContent('```flow\nst=>start: Start\ne=>end: End\nst->e\n```')
|
||||
cy.getMarkdownBody().findById('flowchart').children().should('be.visible')
|
||||
cy.getMarkdownBody().findByCypressId('flowchart').children().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders abc scores', () => {
|
||||
cy.setCodemirrorContent('```abc\nM:4/4\nK:G\n|:GABc dedB:|\n```')
|
||||
cy.getMarkdownBody().findById('abcjs').children().should('be.visible')
|
||||
cy.getMarkdownBody().findByCypressId('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().findById('csv-html-table').first().should('be.visible')
|
||||
cy.getMarkdownBody().findByCypressId('csv-html-table').first().should('be.visible')
|
||||
})
|
||||
|
||||
it('renders plantuml', () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ const title = 'This is a test title'
|
|||
describe('Document Title', () => {
|
||||
beforeEach(() => {
|
||||
cy.visitTestEditor()
|
||||
cy.getById('view-mode-both').should('exist')
|
||||
cy.getByCypressId('view-mode-both').should('exist')
|
||||
})
|
||||
|
||||
describe('title should be yaml metadata title', () => {
|
||||
|
|
|
@ -7,18 +7,18 @@
|
|||
describe('Editor mode from URL parameter is used', () => {
|
||||
it('mode view', () => {
|
||||
cy.visitTestEditor('view')
|
||||
cy.get('.splitter.left').should('not.be.visible')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
cy.getByCypressId('splitter-left').should('not.be.visible')
|
||||
cy.getByCypressId('splitter-right').should('be.visible')
|
||||
})
|
||||
it('mode both', () => {
|
||||
cy.visitTestEditor('both')
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.separator').should('exist')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
cy.getByCypressId('splitter-left').should('be.visible')
|
||||
cy.getByCypressId('splitter-separator').should('exist')
|
||||
cy.getByCypressId('splitter-right').should('be.visible')
|
||||
})
|
||||
it('mode edit', () => {
|
||||
cy.visitTestEditor('edit')
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.right').should('not.be.visible')
|
||||
cy.getByCypressId('splitter-left').should('be.visible')
|
||||
cy.getByCypressId('splitter-right').should('not.be.visible')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,8 +14,8 @@ describe('Export', () => {
|
|||
})
|
||||
|
||||
it('Markdown', () => {
|
||||
cy.getById('menu-export').click()
|
||||
cy.getById('menu-export-markdown').click()
|
||||
cy.getByCypressId('menu-export').click()
|
||||
cy.getByCypressId('menu-export-markdown').click()
|
||||
cy.get('a[download]')
|
||||
.then(
|
||||
(anchor) =>
|
||||
|
|
|
@ -40,8 +40,8 @@ describe('File upload', () => {
|
|||
)
|
||||
})
|
||||
it('via button', () => {
|
||||
cy.getById('editor-toolbar-upload-image-button').should('be.visible')
|
||||
cy.getById('editor-toolbar-upload-image-input').attachFixture({
|
||||
cy.getByCypressId('editor-toolbar-upload-image-button').should('be.visible')
|
||||
cy.getByCypressId('editor-toolbar-upload-image-input').attachFixture({
|
||||
filePath: 'demo.png',
|
||||
mimeType: 'image/png'
|
||||
})
|
||||
|
@ -86,8 +86,8 @@ describe('File upload', () => {
|
|||
statusCode: 400
|
||||
}
|
||||
)
|
||||
cy.getById('editor-toolbar-upload-image-button').should('be.visible')
|
||||
cy.getById('editor-toolbar-upload-image-input').attachFixture({
|
||||
cy.getByCypressId('editor-toolbar-upload-image-button').should('be.visible')
|
||||
cy.getByCypressId('editor-toolbar-upload-image-input').attachFixture({
|
||||
filePath: 'demo.png',
|
||||
mimeType: 'image/png'
|
||||
})
|
||||
|
|
|
@ -10,7 +10,7 @@ describe('Help Dialog', () => {
|
|||
})
|
||||
|
||||
it('ToDo-List', () => {
|
||||
cy.getById('editor-help-button').click()
|
||||
cy.getByCypressId('editor-help-button').click()
|
||||
cy.get('input[type="checkbox"]').should('exist').should('not.be.checked')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
const findHljsCodeBlock = () => {
|
||||
return cy.getMarkdownBody().find('.code-highlighter > code.hljs').should('be.visible')
|
||||
return cy.getMarkdownBody().findByCypressId('code-highlighter').should('be.visible')
|
||||
}
|
||||
|
||||
describe('Code', () => {
|
||||
|
@ -16,17 +16,18 @@ describe('Code', () => {
|
|||
describe('with just the language', () => {
|
||||
it("doesn't show a gutter", () => {
|
||||
cy.setCodemirrorContent('```javascript \nlet x = 0\n```')
|
||||
findHljsCodeBlock().should('not.have.class', 'showGutter')
|
||||
findHljsCodeBlock().should('have.attr', 'data-cypress-showgutter', 'false')
|
||||
|
||||
findHljsCodeBlock().find('.linenumber').should('not.be.visible')
|
||||
findHljsCodeBlock().findByCypressId('linenumber').should('not.be.visible')
|
||||
})
|
||||
|
||||
describe('and line wrapping', () => {
|
||||
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('have.attr', 'data-cypress-showgutter', 'false')
|
||||
findHljsCodeBlock().should('have.attr', 'data-cypress-wrapLines', 'true')
|
||||
|
||||
findHljsCodeBlock().find('.linenumber').should('not.be.visible')
|
||||
findHljsCodeBlock().findByCypressId('linenumber').should('not.be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -34,17 +35,18 @@ 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.attr', 'data-cypress-showgutter', 'true')
|
||||
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '1')
|
||||
findHljsCodeBlock().findByCypressId('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.attr', 'data-cypress-showgutter', 'true')
|
||||
findHljsCodeBlock().should('have.attr', 'data-cypress-wrapLines', 'true')
|
||||
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '1')
|
||||
findHljsCodeBlock().findByCypressId('linenumber').should('be.visible').text().should('eq', '1')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -52,45 +54,40 @@ 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.attr', 'data-cypress-showgutter', 'true')
|
||||
|
||||
findHljsCodeBlock().find('.linenumber').should('be.visible').text().should('eq', '100')
|
||||
findHljsCodeBlock().findByCypressId('linenumber').should('be.visible').text().should('eq', '100')
|
||||
})
|
||||
|
||||
it('shows the correct line number and continues in another codeblock', () => {
|
||||
cy.setCodemirrorContent('```javascript=100 \nlet x = 0\nlet y = 1\n```\n\n```javascript=+\nlet y = 2\n```\n')
|
||||
findHljsCodeBlock()
|
||||
.should('have.class', 'showGutter')
|
||||
.first()
|
||||
.find('.linenumber')
|
||||
.first()
|
||||
.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().should('have.attr', 'data-cypress-showgutter', 'true')
|
||||
findHljsCodeBlock().first().findByCypressId('linenumber').first().should('be.visible').text().should('eq', '100')
|
||||
findHljsCodeBlock().first().findByCypressId('linenumber').last().should('be.visible').text().should('eq', '101')
|
||||
findHljsCodeBlock().last().findByCypressId('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.attr', 'data-cypress-showgutter', 'true')
|
||||
findHljsCodeBlock().should('have.attr', 'data-cypress-wrapLines', 'true')
|
||||
findHljsCodeBlock().findByCypressId('linenumber').should('be.visible').text().should('eq', '100')
|
||||
})
|
||||
|
||||
it('shows the correct line number and continues in another codeblock', () => {
|
||||
cy.setCodemirrorContent('```javascript=100! \nlet x = 0\nlet y = 1\n```\n\n```javascript=+\nlet y = 2\n```\n')
|
||||
findHljsCodeBlock().should('have.attr', 'data-cypress-showgutter', 'true')
|
||||
findHljsCodeBlock().should('have.attr', 'data-cypress-wrapLines', 'true')
|
||||
findHljsCodeBlock()
|
||||
.should('have.class', 'showGutter')
|
||||
.should('have.class', 'wrapLines')
|
||||
.first()
|
||||
.find('.linenumber')
|
||||
.findByCypressId('linenumber')
|
||||
.first()
|
||||
.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().findByCypressId('linenumber').last().should('be.visible').text().should('eq', '101')
|
||||
findHljsCodeBlock().last().findByCypressId('linenumber').first().should('be.visible').text().should('eq', '102')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -98,7 +95,7 @@ describe('Code', () => {
|
|||
it('has a working copy button', () => {
|
||||
cy.setCodemirrorContent('```javascript \nlet x = 0\n```')
|
||||
|
||||
cy.getById('documentIframe').then((element: JQuery<HTMLElement>) => {
|
||||
cy.getByCypressId('documentIframe').then((element: JQuery<HTMLElement>) => {
|
||||
const frame = element.get(0) as HTMLIFrameElement
|
||||
if (frame === null || frame.contentWindow === null) {
|
||||
return cy.wrap(null)
|
||||
|
@ -107,7 +104,7 @@ describe('Code', () => {
|
|||
cy.spy(frame.contentWindow.navigator.clipboard, 'writeText').as('copy')
|
||||
})
|
||||
|
||||
cy.getIframeBody().findById('copy-code-button').click()
|
||||
cy.getIframeBody().findByCypressId('copy-code-button').click()
|
||||
|
||||
cy.get('@copy').should('be.calledWithExactly', 'let x = 0\n')
|
||||
})
|
||||
|
|
|
@ -11,12 +11,12 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('Cards', () => {
|
||||
cy.getById('history-card').should('be.visible')
|
||||
cy.getByCypressId('history-card').should('be.visible')
|
||||
})
|
||||
|
||||
it('Table', () => {
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-table').should('be.visible')
|
||||
cy.getByCypressId('history-mode-table').click()
|
||||
cy.getByCypressId('history-table').should('be.visible')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -39,13 +39,13 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('in table view', () => {
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-table').should('be.visible')
|
||||
cy.getById('history-entry-title').contains('Features')
|
||||
cy.getByCypressId('history-mode-table').click()
|
||||
cy.getByCypressId('history-table').should('be.visible')
|
||||
cy.getByCypressId('history-entry-title').contains('Features')
|
||||
})
|
||||
|
||||
it('in cards view', () => {
|
||||
cy.getById('history-entry-title').contains('Features')
|
||||
cy.getByCypressId('history-entry-title').contains('Features')
|
||||
})
|
||||
})
|
||||
describe('is untitled when not empty', () => {
|
||||
|
@ -66,13 +66,13 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('in table view', () => {
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-table').should('be.visible')
|
||||
cy.getById('history-entry-title').contains('Untitled')
|
||||
cy.getByCypressId('history-mode-table').click()
|
||||
cy.getByCypressId('history-table').should('be.visible')
|
||||
cy.getByCypressId('history-entry-title').contains('Untitled')
|
||||
})
|
||||
|
||||
it('in cards view', () => {
|
||||
cy.getById('history-entry-title').contains('Untitled')
|
||||
cy.getByCypressId('history-entry-title').contains('Untitled')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -90,17 +90,17 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('Cards', () => {
|
||||
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')
|
||||
cy.getByCypressId('history-card').should('be.visible')
|
||||
cy.getByCypressId('history-entry-pin-button').first().as('pin-button')
|
||||
cy.get('@pin-button').should('have.attr', 'data-cypress-pinned', 'true').click()
|
||||
cy.get('@pin-button').should('have.attr', 'data-cypress-pinned', 'false')
|
||||
})
|
||||
|
||||
it('Table', () => {
|
||||
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')
|
||||
cy.getByCypressId('history-mode-table').click()
|
||||
cy.getByCypressId('history-entry-pin-button').first().as('pin-button')
|
||||
cy.get('@pin-button').should('have.attr', 'data-cypress-pinned', 'true').click()
|
||||
cy.get('@pin-button').should('have.attr', 'data-cypress-pinned', 'false')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -112,15 +112,15 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('Cards', () => {
|
||||
cy.getById('history-card').should('be.visible')
|
||||
cy.getById('history-entry-pin-button').first().click()
|
||||
cy.getById('notification-toast').should('be.visible')
|
||||
cy.getByCypressId('history-card').should('be.visible')
|
||||
cy.getByCypressId('history-entry-pin-button').first().click()
|
||||
cy.getByCypressId('notification-toast').should('be.visible')
|
||||
})
|
||||
|
||||
it('Table', () => {
|
||||
cy.getById('history-mode-table').click()
|
||||
cy.getById('history-entry-pin-button').first().click()
|
||||
cy.getById('notification-toast').should('be.visible')
|
||||
cy.getByCypressId('history-mode-table').click()
|
||||
cy.getByCypressId('history-entry-pin-button').first().click()
|
||||
cy.getByCypressId('notification-toast').should('be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -136,37 +136,37 @@ describe('History', () => {
|
|||
})
|
||||
|
||||
it('works with valid file', () => {
|
||||
cy.getById('import-history-file-button').should('be.visible')
|
||||
cy.getById('import-history-file-input').attachFixture({
|
||||
cy.getByCypressId('import-history-file-button').should('be.visible')
|
||||
cy.getByCypressId('import-history-file-input').attachFixture({
|
||||
filePath: 'history.json',
|
||||
mimeType: 'application/json'
|
||||
})
|
||||
cy.getById('history-entry-title').should('have.length', 1).contains('cy-Test')
|
||||
cy.getByCypressId('history-entry-title').should('have.length', 1).contains('cy-Test')
|
||||
})
|
||||
|
||||
it('fails on invalid file', () => {
|
||||
cy.getById('import-history-file-button').should('be.visible')
|
||||
cy.getById('import-history-file-input').attachFixture({
|
||||
cy.getByCypressId('import-history-file-button').should('be.visible')
|
||||
cy.getByCypressId('import-history-file-input').attachFixture({
|
||||
filePath: 'invalid-history.txt',
|
||||
mimeType: 'text/plain'
|
||||
})
|
||||
cy.getById('notification-toast').should('be.visible')
|
||||
cy.getByCypressId('notification-toast').should('be.visible')
|
||||
})
|
||||
|
||||
it('works when selecting two files with the same name', () => {
|
||||
cy.getById('import-history-file-button').should('be.visible')
|
||||
cy.getById('import-history-file-input').attachFixture({
|
||||
cy.getByCypressId('import-history-file-button').should('be.visible')
|
||||
cy.getByCypressId('import-history-file-input').attachFixture({
|
||||
filePath: 'history.json',
|
||||
mimeType: 'application/json'
|
||||
})
|
||||
cy.getById('history-entry-title').should('have.length', 1).contains('cy-Test')
|
||||
cy.getById('import-history-file-button').should('be.visible')
|
||||
cy.getById('import-history-file-input').attachFixture({
|
||||
cy.getByCypressId('history-entry-title').should('have.length', 1).contains('cy-Test')
|
||||
cy.getByCypressId('import-history-file-button').should('be.visible')
|
||||
cy.getByCypressId('import-history-file-input').attachFixture({
|
||||
filePath: 'history-2.json',
|
||||
fileName: 'history.json',
|
||||
mimeType: 'application/json'
|
||||
})
|
||||
cy.getById('history-entry-title').should('have.length', 2).contains('cy-Test2')
|
||||
cy.getByCypressId('history-entry-title').should('have.length', 2).contains('cy-Test2')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('Iframe capsule', () => {
|
|||
|
||||
it('shows a clickable click shield instead of the iframe', () => {
|
||||
cy.setCodemirrorContent('<iframe src="https://example.org"></iframe>')
|
||||
cy.getMarkdownBody().findById('iframe-capsule-click-shield').should('exist').click()
|
||||
cy.getMarkdownBody().findByCypressId('iframe-capsule-click-shield').should('exist').click()
|
||||
cy.getMarkdownBody().find('iframe').should('exist').should('have.attr', 'src', 'https://example.org')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,9 +10,9 @@ describe('Import markdown file', () => {
|
|||
})
|
||||
|
||||
it('import on blank note', () => {
|
||||
cy.getById('menu-import').click()
|
||||
cy.getById('menu-import-markdown-button').should('be.visible')
|
||||
cy.getById('menu-import-markdown-input').attachFixture({
|
||||
cy.getByCypressId('menu-import').click()
|
||||
cy.getByCypressId('menu-import-markdown-button').should('be.visible')
|
||||
cy.getByCypressId('menu-import-markdown-input').attachFixture({
|
||||
filePath: 'import.md',
|
||||
mimeType: 'text/markdown'
|
||||
})
|
||||
|
@ -25,9 +25,9 @@ describe('Import markdown file', () => {
|
|||
|
||||
it('import on note with content', () => {
|
||||
cy.setCodemirrorContent('test\nabc')
|
||||
cy.getById('menu-import').click()
|
||||
cy.getById('menu-import-markdown-button').should('be.visible')
|
||||
cy.getById('menu-import-markdown-input').attachFixture({
|
||||
cy.getByCypressId('menu-import').click()
|
||||
cy.getByCypressId('menu-import-markdown-button').should('be.visible')
|
||||
cy.getByCypressId('menu-import-markdown-input').attachFixture({
|
||||
filePath: 'import.md',
|
||||
mimeType: 'text/markdown'
|
||||
})
|
||||
|
|
|
@ -22,39 +22,39 @@ describe('Intro page', () => {
|
|||
})
|
||||
cy.visit('/')
|
||||
|
||||
cy.getById('documentIframe').should('not.exist')
|
||||
cy.getByCypressId('documentIframe').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('features button', () => {
|
||||
it('is hidden when logged in', () => {
|
||||
cy.getById('features-button').should('not.exist')
|
||||
cy.getByCypressId('features-button').should('not.exist')
|
||||
})
|
||||
|
||||
it('is visible when logged out', () => {
|
||||
cy.logout()
|
||||
cy.getById('features-button').should('exist')
|
||||
cy.getByCypressId('features-button').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('sign in button', () => {
|
||||
it('is hidden when logged in', () => {
|
||||
cy.getById('sign-in-button').should('not.exist')
|
||||
cy.getByCypressId('sign-in-button').should('not.exist')
|
||||
})
|
||||
|
||||
it('is visible when logged out', () => {
|
||||
cy.logout()
|
||||
cy.getById('sign-in-button').should('exist')
|
||||
cy.getByCypressId('sign-in-button').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
describe('version dialog', () => {
|
||||
it('can be opened and closed', () => {
|
||||
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')
|
||||
cy.getByCypressId('version-modal').should('not.exist')
|
||||
cy.getByCypressId('show-version-modal').click()
|
||||
cy.getByCypressId('version-modal').should('be.visible')
|
||||
cy.getByCypressId('version-modal').find('.modal-header .close').click()
|
||||
cy.getByCypressId('version-modal').should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -12,7 +12,7 @@ describe('Languages', () => {
|
|||
})
|
||||
|
||||
it('all languages are available', () => {
|
||||
cy.getById('language-picker').find('option').as('languages')
|
||||
cy.getByCypressId('language-picker').find('option').as('languages')
|
||||
cy.get('@languages').should('have.length', 28)
|
||||
languages.forEach((language) => {
|
||||
cy.get('@languages').contains(language)
|
||||
|
@ -20,9 +20,9 @@ describe('Languages', () => {
|
|||
})
|
||||
|
||||
it('language changes affect the UI', () => {
|
||||
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')
|
||||
cy.getByCypressId('language-picker').select('English')
|
||||
cy.getByCypressId('new-note-button').find('span').contains('New note')
|
||||
cy.getByCypressId('language-picker').select('Deutsch')
|
||||
cy.getByCypressId('new-note-button').find('span').contains('Neue Notiz')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -12,9 +12,9 @@ describe('Links Intro', () => {
|
|||
})
|
||||
|
||||
it('History', () => {
|
||||
cy.getById('navLinkHistory').click()
|
||||
cy.getByCypressId('navLinkHistory').click()
|
||||
cy.url().should('include', '/history')
|
||||
cy.getById('navLinkIntro').click()
|
||||
cy.getByCypressId('navLinkIntro').click()
|
||||
cy.url().should('include', '/intro')
|
||||
})
|
||||
|
||||
|
@ -24,29 +24,29 @@ describe('Links Intro', () => {
|
|||
})
|
||||
|
||||
it('New guest note', () => {
|
||||
cy.getById('new-guest-note-button').click()
|
||||
cy.getByCypressId('new-guest-note-button').click()
|
||||
cy.url().should('include', '/new')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Menu Buttons logged in', () => {
|
||||
it('New note', () => {
|
||||
cy.getById('new-note-button').click()
|
||||
cy.getByCypressId('new-note-button').click()
|
||||
cy.url().should('include', '/new')
|
||||
})
|
||||
|
||||
describe('User Menu', () => {
|
||||
beforeEach(() => {
|
||||
cy.getById('user-dropdown').click()
|
||||
cy.getByCypressId('user-dropdown').click()
|
||||
})
|
||||
|
||||
it('Features', () => {
|
||||
cy.getById('user-dropdown-features-button').click()
|
||||
cy.getByCypressId('user-dropdown-features-button').click()
|
||||
cy.url().should('include', '/features')
|
||||
})
|
||||
|
||||
it('Profile', () => {
|
||||
cy.getById('user-dropdown-profile-button').click()
|
||||
cy.getByCypressId('user-dropdown-profile-button').click()
|
||||
cy.url().should('include', '/profile')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -13,14 +13,14 @@ describe('Link gets replaced with embedding: ', () => {
|
|||
|
||||
it('GitHub Gist', () => {
|
||||
cy.setCodemirrorContent('https://gist.github.com/schacon/1')
|
||||
cy.getMarkdownBody().findById('click-shield-gist').find('.preview-background').parent().click()
|
||||
cy.getMarkdownBody().findById('gh-gist').should('be.visible')
|
||||
cy.getMarkdownBody().findByCypressId('click-shield-gist').find('.preview-background').parent().click()
|
||||
cy.getMarkdownBody().findByCypressId('gh-gist').should('be.visible')
|
||||
})
|
||||
|
||||
it('YouTube', () => {
|
||||
cy.setCodemirrorContent('https://www.youtube.com/watch?v=YE7VzlLtp-4')
|
||||
cy.getMarkdownBody()
|
||||
.findById('click-shield-youtube')
|
||||
.findByCypressId('click-shield-youtube')
|
||||
.find('.preview-background')
|
||||
.should('have.attr', 'src', 'https://i.ytimg.com/vi/YE7VzlLtp-4/maxresdefault.jpg')
|
||||
.parent()
|
||||
|
@ -46,7 +46,7 @@ describe('Link gets replaced with embedding: ', () => {
|
|||
)
|
||||
cy.setCodemirrorContent('https://vimeo.com/23237102')
|
||||
cy.getMarkdownBody()
|
||||
.findById('click-shield-vimeo')
|
||||
.findByCypressId('click-shield-vimeo')
|
||||
.find('.preview-background')
|
||||
.should('have.attr', 'src', 'https://i.vimeocdn.com/video/503631401_640.jpg')
|
||||
.parent()
|
||||
|
@ -57,7 +57,7 @@ describe('Link gets replaced with embedding: ', () => {
|
|||
it('Asciinema', () => {
|
||||
cy.setCodemirrorContent('https://asciinema.org/a/117928')
|
||||
cy.getMarkdownBody()
|
||||
.findById('click-shield-asciinema')
|
||||
.findByCypressId('click-shield-asciinema')
|
||||
.find('.preview-background')
|
||||
.should('have.attr', 'src', 'https://asciinema.org/a/117928.png')
|
||||
.parent()
|
||||
|
|
|
@ -14,21 +14,21 @@ describe('The status bar text length info', () => {
|
|||
})
|
||||
|
||||
it('shows the maximal length of the document as number of available characters in the tooltip', () => {
|
||||
cy.getById('remainingCharacters').attribute('title').should('contain', ' 200 ')
|
||||
cy.getByCypressId('remainingCharacters').attribute('title').should('contain', ' 200 ')
|
||||
})
|
||||
|
||||
it('color is set to "warning" on <= 100 characters remaining', () => {
|
||||
cy.setCodemirrorContent(warningTestContent)
|
||||
cy.getById('remainingCharacters').should('have.class', 'text-warning')
|
||||
cy.getByCypressId('remainingCharacters').should('have.class', 'text-warning')
|
||||
})
|
||||
|
||||
it('color is set to danger on <= 0 characters remaining', () => {
|
||||
cy.setCodemirrorContent(dangerTestContent)
|
||||
cy.getById('remainingCharacters').should('have.class', 'text-danger')
|
||||
cy.getByCypressId('remainingCharacters').should('have.class', 'text-danger')
|
||||
})
|
||||
|
||||
it('opens a modal', () => {
|
||||
cy.setCodemirrorContent(tooMuchTestContent)
|
||||
cy.getById('limitReachedModal').should('be.visible')
|
||||
cy.getByCypressId('limitReachedModal').should('be.visible')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -29,63 +29,63 @@ describe('Motd', () => {
|
|||
it('shows the correct alert Motd text', () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getByCypressId('motd').contains(motdMockContent)
|
||||
})
|
||||
|
||||
it('can be dismissed', () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getById('motd-dismiss')
|
||||
cy.getByCypressId('motd').contains(motdMockContent)
|
||||
cy.getByCypressId('motd-dismiss')
|
||||
.click()
|
||||
.then(() => {
|
||||
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).to.equal(MOCK_LAST_MODIFIED)
|
||||
})
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getByCypressId('motd').should('not.exist')
|
||||
})
|
||||
|
||||
it("won't show again after dismiss and reload", () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getById('motd-dismiss')
|
||||
cy.getByCypressId('motd').contains(motdMockContent)
|
||||
cy.getByCypressId('motd-dismiss')
|
||||
.click()
|
||||
.then(() => {
|
||||
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).to.equal(MOCK_LAST_MODIFIED)
|
||||
})
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getByCypressId('motd').should('not.exist')
|
||||
cy.reload()
|
||||
cy.get('main').should('exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getByCypressId('motd').should('not.exist')
|
||||
})
|
||||
|
||||
it('will show again after reload without dismiss', () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getByCypressId('motd').contains(motdMockContent)
|
||||
cy.reload()
|
||||
cy.get('main').should('exist')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getByCypressId('motd').contains(motdMockContent)
|
||||
})
|
||||
|
||||
it("won't show again after dismiss and page navigation", () => {
|
||||
mockExistingMotd()
|
||||
cy.visit('/')
|
||||
cy.getById('motd').contains(motdMockContent)
|
||||
cy.getById('motd-dismiss')
|
||||
cy.getByCypressId('motd').contains(motdMockContent)
|
||||
cy.getByCypressId('motd-dismiss')
|
||||
.click()
|
||||
.then(() => {
|
||||
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).to.equal(MOCK_LAST_MODIFIED)
|
||||
})
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getById('navLinkHistory').click()
|
||||
cy.getByCypressId('motd').should('not.exist')
|
||||
cy.getByCypressId('navLinkHistory').click()
|
||||
cy.get('main').should('exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getByCypressId('motd').should('not.exist')
|
||||
})
|
||||
|
||||
it("won't show if no file exists", () => {
|
||||
cy.visit('/')
|
||||
cy.get('main').should('exist')
|
||||
cy.getById('motd').should('not.exist')
|
||||
cy.getByCypressId('motd').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -53,22 +53,22 @@ describe('profile page', () => {
|
|||
|
||||
describe('access tokens', () => {
|
||||
it('list existing tokens', () => {
|
||||
cy.getById('access-token-label').contains('cypress-App')
|
||||
cy.getByCypressId('access-token-label').contains('cypress-App')
|
||||
})
|
||||
|
||||
it('delete token', () => {
|
||||
cy.getById('access-token-delete-button').click()
|
||||
cy.getById('access-token-modal-delete').as('deletion-modal')
|
||||
cy.getByCypressId('access-token-delete-button').click()
|
||||
cy.getByCypressId('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.getById('access-token-add-button').should('be.disabled')
|
||||
cy.getById('access-token-add-input-label').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')
|
||||
cy.getByCypressId('access-token-add-button').should('be.disabled')
|
||||
cy.getByCypressId('access-token-add-input-label').type('cypress')
|
||||
cy.getByCypressId('access-token-modal-add').should('not.exist')
|
||||
cy.getByCypressId('access-token-add-button').should('not.be.disabled').click()
|
||||
cy.getByCypressId('access-token-modal-add')
|
||||
.should('be.visible')
|
||||
.find('input[readonly]')
|
||||
.should('have.value', 'c-y-p-r-e-s-s')
|
||||
|
|
|
@ -35,7 +35,7 @@ describe('Short code gets replaced or rendered: ', () => {
|
|||
describe('youtube', () => {
|
||||
it('renders click-shield', () => {
|
||||
cy.setCodemirrorContent(`{%youtube YE7VzlLtp-4 %}`)
|
||||
cy.getMarkdownBody().findById('click-shield-youtube')
|
||||
cy.getMarkdownBody().findByCypressId('click-shield-youtube')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -34,7 +34,7 @@ const initLoggedOutTestWithCustomAuthProviders = (
|
|||
describe('When logged-in, ', () => {
|
||||
it('sign-in button is hidden', () => {
|
||||
cy.visit('/')
|
||||
cy.getById('sign-in-button').should('not.exist')
|
||||
cy.getByCypressId('sign-in-button').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -42,7 +42,7 @@ describe('When logged-out ', () => {
|
|||
describe('and no auth-provider is enabled, ', () => {
|
||||
it('sign-in button is hidden', () => {
|
||||
initLoggedOutTestWithCustomAuthProviders(cy, {})
|
||||
cy.getById('sign-in-button').should('not.exist')
|
||||
cy.getByCypressId('sign-in-button').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -51,14 +51,14 @@ describe('When logged-out ', () => {
|
|||
initLoggedOutTestWithCustomAuthProviders(cy, {
|
||||
local: true
|
||||
})
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
cy.getByCypressId('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.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -67,7 +67,7 @@ describe('When logged-out ', () => {
|
|||
initLoggedOutTestWithCustomAuthProviders(cy, {
|
||||
saml: true
|
||||
})
|
||||
cy.getById('sign-in-button')
|
||||
cy.getByCypressId('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/auth/saml')
|
||||
|
@ -80,7 +80,7 @@ describe('When logged-out ', () => {
|
|||
saml: true,
|
||||
github: true
|
||||
})
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -90,7 +90,7 @@ describe('When logged-out ', () => {
|
|||
saml: true,
|
||||
local: true
|
||||
})
|
||||
cy.getById('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,33 +10,33 @@ describe('Split view', () => {
|
|||
})
|
||||
|
||||
it('can show both panes', () => {
|
||||
cy.getById('view-mode-both').click()
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
cy.getByCypressId('view-mode-both').click()
|
||||
cy.getByCypressId('splitter-left').should('be.visible')
|
||||
cy.getByCypressId('splitter-right').should('be.visible')
|
||||
})
|
||||
|
||||
it('can show only preview pane', () => {
|
||||
cy.getById('view-mode-preview').click()
|
||||
cy.get('.splitter.left').should('be.not.visible')
|
||||
cy.get('.splitter.right').should('be.visible')
|
||||
cy.getByCypressId('view-mode-preview').click()
|
||||
cy.getByCypressId('splitter-left').should('be.not.visible')
|
||||
cy.getByCypressId('splitter-right').should('be.visible')
|
||||
})
|
||||
|
||||
it('can show only editor pane', () => {
|
||||
cy.getById('view-mode-editor').click()
|
||||
cy.get('.splitter.left').should('be.visible')
|
||||
cy.get('.splitter.right').should('be.not.visible')
|
||||
cy.getByCypressId('view-mode-editor').click()
|
||||
cy.getByCypressId('splitter-left').should('be.visible')
|
||||
cy.getByCypressId('splitter-right').should('be.not.visible')
|
||||
})
|
||||
|
||||
it('can change the split by dragging', () => {
|
||||
cy.get('.splitter.left').then((leftPanebefore) => {
|
||||
cy.getByCypressId('splitter-left').then((leftPanebefore) => {
|
||||
const widthBefore = leftPanebefore.outerWidth()
|
||||
|
||||
cy.getById('view-mode-both').click()
|
||||
cy.get('.split-divider').should('be.visible').trigger('mousedown', { buttons: 1 })
|
||||
cy.getByCypressId('view-mode-both').click()
|
||||
cy.getByCypressId('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')
|
||||
cy.getByCypressId('split-divider').trigger('mouseup')
|
||||
|
||||
cy.get('.splitter.left').should('not.eq', widthBefore)
|
||||
cy.getByCypressId('splitter-left').should('not.eq', widthBefore)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -26,17 +26,17 @@ describe('Toolbar Buttons', () => {
|
|||
})
|
||||
|
||||
it('should format as bold', () => {
|
||||
cy.getById('format-bold').click()
|
||||
cy.getByCypressId('format-bold').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `**${testText}**`)
|
||||
})
|
||||
|
||||
it('should format as italic', () => {
|
||||
cy.getById('format-italic').click()
|
||||
cy.getByCypressId('format-italic').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `*${testText}*`)
|
||||
})
|
||||
|
||||
it('should format as underline', () => {
|
||||
cy.getById('format-underline').click()
|
||||
cy.getByCypressId('format-underline').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `++${testText}++`)
|
||||
})
|
||||
|
||||
|
@ -46,17 +46,17 @@ describe('Toolbar Buttons', () => {
|
|||
})
|
||||
|
||||
it('should format as subscript', () => {
|
||||
cy.getById('format-subscript').click()
|
||||
cy.getByCypressId('format-subscript').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `~${testText}~`)
|
||||
})
|
||||
|
||||
it('should format as superscript', () => {
|
||||
cy.getById('format-superscript').click()
|
||||
cy.getByCypressId('format-superscript').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `^${testText}^`)
|
||||
})
|
||||
|
||||
it('should format the line as code block', () => {
|
||||
cy.getById('format-code-block').click()
|
||||
cy.getByCypressId('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(
|
||||
|
@ -66,65 +66,65 @@ describe('Toolbar Buttons', () => {
|
|||
})
|
||||
|
||||
it('should format links', () => {
|
||||
cy.getById('format-link').click()
|
||||
cy.getByCypressId('format-link').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `[${testText}](https://)`)
|
||||
})
|
||||
|
||||
it('should format as image', () => {
|
||||
cy.getById('format-image').click()
|
||||
cy.getByCypressId('format-image').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `![${testText}](https://)`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should format line as heading', () => {
|
||||
cy.getById('format-heading').click()
|
||||
cy.getByCypressId('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.getById('format-code-block').click()
|
||||
cy.getByCypressId('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.getById('format-block-quote').click()
|
||||
cy.getByCypressId('format-block-quote').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `> ${testText}`)
|
||||
cy.getById('format-block-quote').click()
|
||||
cy.getByCypressId('format-block-quote').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `> > ${testText}`)
|
||||
})
|
||||
|
||||
it('should format as unordered list', () => {
|
||||
cy.getById('format-unordered-list').click()
|
||||
cy.getByCypressId('format-unordered-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- ${testText}`)
|
||||
cy.getById('format-unordered-list').click()
|
||||
cy.getByCypressId('format-unordered-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- - ${testText}`)
|
||||
})
|
||||
|
||||
it('should format as ordered list', () => {
|
||||
cy.getById('format-ordered-list').click()
|
||||
cy.getByCypressId('format-ordered-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `1. ${testText}`)
|
||||
cy.getById('format-ordered-list').click()
|
||||
cy.getByCypressId('format-ordered-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `1. 1. ${testText}`)
|
||||
})
|
||||
|
||||
it('should format as check list', () => {
|
||||
cy.getById('format-check-list').click()
|
||||
cy.getByCypressId('format-check-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- [ ] ${testText}`)
|
||||
cy.getById('format-check-list').click()
|
||||
cy.getByCypressId('format-check-list').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `- [ ] - [ ] ${testText}`)
|
||||
})
|
||||
|
||||
it('should insert links', () => {
|
||||
cy.getById('format-link').click()
|
||||
cy.getByCypressId('format-link').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `${testText}[](https://)`)
|
||||
})
|
||||
|
||||
it('should insert an empty image link', () => {
|
||||
cy.getById('format-image').click()
|
||||
cy.getByCypressId('format-image').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `${testText}![](https://)`)
|
||||
})
|
||||
})
|
||||
|
@ -137,30 +137,30 @@ describe('Toolbar Buttons', () => {
|
|||
})
|
||||
|
||||
it('should format as link', () => {
|
||||
cy.getById('format-link').click()
|
||||
cy.getByCypressId('format-link').click()
|
||||
cy.get('.CodeMirror-activeline > .CodeMirror-line > span').should('have.text', `[](${testLink})`)
|
||||
})
|
||||
|
||||
it('should format as image', () => {
|
||||
cy.getById('format-image').click()
|
||||
cy.getByCypressId('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.getById('format-code-block').click()
|
||||
cy.getByCypressId('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.getById('format-add-line').click()
|
||||
cy.getByCypressId('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.getById('format-collapsable-block').click()
|
||||
cy.getByCypressId('format-collapsable-block').click()
|
||||
cy.get('.CodeMirror-code > div:nth-of-type(2) > .CodeMirror-line > span span').should(
|
||||
'have.text',
|
||||
':::spoiler Toggle label'
|
||||
|
@ -168,36 +168,34 @@ describe('Toolbar Buttons', () => {
|
|||
})
|
||||
|
||||
it('should add a comment', () => {
|
||||
cy.getById('format-add-comment').click()
|
||||
cy.getByCypressId('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.getById('table-size-picker-popover').should('not.exist')
|
||||
cy.getById('table-size-picker-button').last().click()
|
||||
cy.getById('table-size-picker-popover').should('be.visible')
|
||||
cy.getByCypressId('table-size-picker-popover').should('not.exist')
|
||||
cy.getByCypressId('table-size-picker-button').last().click()
|
||||
cy.getByCypressId('table-size-picker-popover').should('be.visible')
|
||||
})
|
||||
|
||||
it('should select table size', () => {
|
||||
cy.getById('table-size-picker-popover')
|
||||
.find('.table-container > .table-cell:nth-of-type(25)')
|
||||
cy.getByCypressId('table-size-picker-popover')
|
||||
.find('[data-cypress-col=5][data-cypress-row=3]')
|
||||
.trigger('mouseover')
|
||||
cy.getById('table-size-picker-popover')
|
||||
.find('.table-container > .table-cell[data-cypress-selected="true"]')
|
||||
.should('have.length', 15)
|
||||
cy.getById('table-size-picker-popover').find('.popover-header').contains('5x3')
|
||||
cy.getById('table-size-picker-popover').find('.table-container > .table-cell:nth-of-type(25)').click()
|
||||
cy.getByCypressId('table-size-picker-popover').find('[data-cypress-selected="true"]').should('have.length', 15)
|
||||
cy.getByCypressId('table-size-picker-popover').find('.popover-header').contains('5x3')
|
||||
cy.getByCypressId('table-size-picker-popover').find('[data-cypress-col=5][data-cypress-row=3]').click()
|
||||
})
|
||||
|
||||
it('should open a custom table size in the modal', () => {
|
||||
cy.getById('custom-table-size-modal').should('not.exist')
|
||||
cy.getById('show-custom-table-modal').first().click()
|
||||
cy.getById('custom-table-size-modal').should('be.visible')
|
||||
cy.getById('custom-table-size-modal').find('input').first().type('5')
|
||||
cy.getById('custom-table-size-modal').find('input').last().type('3')
|
||||
cy.getById('custom-table-size-modal').find('.modal-footer > button').click()
|
||||
cy.getByCypressId('custom-table-size-modal').should('not.exist')
|
||||
cy.getByCypressId('show-custom-table-modal').first().click()
|
||||
cy.getByCypressId('custom-table-size-modal').should('be.visible')
|
||||
cy.getByCypressId('custom-table-size-modal').find('input').first().type('5')
|
||||
cy.getByCypressId('custom-table-size-modal').find('input').last().type('3')
|
||||
cy.getByCypressId('custom-table-size-modal').find('.modal-footer > button').click()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -227,7 +225,7 @@ describe('Toolbar Buttons', () => {
|
|||
describe('for the emoji-picker', () => {
|
||||
it('should open overlay', () => {
|
||||
cy.get('emoji-picker').should('not.be.visible')
|
||||
cy.getById('show-emoji-picker').click()
|
||||
cy.getByCypressId('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.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '0')
|
||||
cy.getByCypressId('sidebar-btn-document-info').click()
|
||||
cy.getByCypressId('document-info-modal').should('be.visible')
|
||||
cy.getByCypressId('document-info-word-count').should('have.text', '0')
|
||||
})
|
||||
|
||||
it('simple words', () => {
|
||||
cy.setCodemirrorContent('five words should be enough')
|
||||
cy.wait(500)
|
||||
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')
|
||||
cy.getByCypressId('sidebar-btn-document-info').click()
|
||||
cy.getByCypressId('document-info-modal').should('be.visible')
|
||||
cy.getByCypressId('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.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '2')
|
||||
cy.getByCypressId('sidebar-btn-document-info').click()
|
||||
cy.getByCypressId('document-info-modal').should('be.visible')
|
||||
cy.getByCypressId('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.getById('sidebar-btn-document-info').click()
|
||||
cy.getById('document-info-modal').should('be.visible')
|
||||
cy.getById('document-info-word-count').should('have.text', '3')
|
||||
cy.getByCypressId('sidebar-btn-document-info').click()
|
||||
cy.getByCypressId('document-info-modal').should('be.visible')
|
||||
cy.getByCypressId('document-info-word-count').should('have.text', '3')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,16 +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().findById('yamlArrayDeprecationAlert').should('be.visible')
|
||||
cy.getIframeBody().findByCypressId('yamlArrayDeprecationAlert').should('be.visible')
|
||||
})
|
||||
|
||||
it("isn't shown when using inline yaml-array", () => {
|
||||
cy.setCodemirrorContent("---\ntags: ['a', 'b', 'c']\n---")
|
||||
cy.getIframeBody().findById('yamlArrayDeprecationAlert').should('not.exist')
|
||||
cy.getIframeBody().findByCypressId('yamlArrayDeprecationAlert').should('not.exist')
|
||||
})
|
||||
|
||||
it("isn't shown when using multi line yaml-array", () => {
|
||||
cy.setCodemirrorContent('---\ntags:\n - a\n - b\n - c\n---')
|
||||
cy.getIframeBody().findById('yamlArrayDeprecationAlert').should('not.exist')
|
||||
cy.getIframeBody().findByCypressId('yamlArrayDeprecationAlert').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,19 +5,20 @@
|
|||
*/
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
getById(id: string): Chainable<Element>
|
||||
findById(id: string): Chainable<Element>
|
||||
getByCypressId(id: string): Chainable<Element>
|
||||
|
||||
findByCypressId(id: string): Chainable<Element>
|
||||
}
|
||||
}
|
||||
|
||||
const CYPRESS_ATTR = 'data-cypress-id'
|
||||
|
||||
Cypress.Commands.add('getById', (id: string) => {
|
||||
Cypress.Commands.add('getByCypressId', (id: string) => {
|
||||
return cy.get(`[${CYPRESS_ATTR}="${id}"]`)
|
||||
})
|
||||
|
||||
Cypress.Commands.add(
|
||||
'findById',
|
||||
'findByCypressId',
|
||||
{
|
||||
prevSubject: 'element'
|
||||
},
|
||||
|
|
|
@ -33,9 +33,9 @@ Cypress.Commands.add('getReveal', () => {
|
|||
})
|
||||
|
||||
Cypress.Commands.add('getMarkdownBody', () => {
|
||||
return cy.getIframeBody(RendererType.DOCUMENT).find('.markdown-body')
|
||||
return cy.getIframeBody(RendererType.DOCUMENT).findByCypressId('markdown-body')
|
||||
})
|
||||
|
||||
Cypress.Commands.add('getIntroBody', () => {
|
||||
return cy.getIframeBody(RendererType.INTRO).find('.markdown-body')
|
||||
return cy.getIframeBody(RendererType.INTRO).findByCypressId('markdown-body')
|
||||
})
|
||||
|
|
|
@ -15,6 +15,6 @@ declare namespace Cypress {
|
|||
}
|
||||
|
||||
Cypress.Commands.add('logout', () => {
|
||||
cy.getById('user-dropdown').click()
|
||||
cy.getById('user-dropdown-sign-out-button').click()
|
||||
cy.getByCypressId('user-dropdown').click()
|
||||
cy.getByCypressId('user-dropdown-sign-out-button').click()
|
||||
})
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.ts',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js']
|
||||
},
|
||||
output: {
|
||||
filename: 'bundle.js',
|
||||
path: path.resolve(__dirname, 'dist')
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@import "../../../node_modules/bootstrap/scss/functions";
|
||||
@import "../../../node_modules/bootstrap/scss/mixins";
|
||||
@import "~bootstrap/scss/functions";
|
||||
@import "~bootstrap/scss/mixins";
|
||||
|
||||
@import "reboot";
|
||||
@import "type";
|
|
@ -1,7 +1,7 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Original: Nicolas Gallagher and Jonathan Neal, Modified by the HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
|
|
@ -1,4 +1,4 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
11
global-styles/highlight-js.scss
Normal file
11
global-styles/highlight-js.scss
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@import '~highlight.js/styles/github';
|
||||
|
||||
body.dark {
|
||||
@import '~highlight.js/styles/github-dark';
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
@ -7,10 +7,17 @@
|
|||
@import "variables";
|
||||
@import "variables.light";
|
||||
@import "bootstrap-vendor/bootstrap";
|
||||
@import '../../node_modules/react-bootstrap-typeahead/css/Typeahead';
|
||||
@import "../../node_modules/@fontsource/source-sans-pro/index";
|
||||
@import "../../node_modules/twemoji-colr-font/twemoji";
|
||||
@import '../../node_modules/fork-awesome/css/fork-awesome.min';
|
||||
@import '~react-bootstrap-typeahead/css/Typeahead';
|
||||
@import "~@fontsource/source-sans-pro/index.css";
|
||||
@import "~twemoji-colr-font/twemoji";
|
||||
@import '~fork-awesome/css/fork-awesome.min.css';
|
||||
@import '~firacode/distr/fira_code';
|
||||
@import "typeahead";
|
||||
@import "./button-inside";
|
||||
@import "./highlight-js";
|
||||
@import "./github-markdown";
|
||||
@import "./markdown-tweaks";
|
||||
@import "./reveal";
|
||||
|
||||
.text-black, body.dark .text-black {
|
||||
color: $black;
|
||||
|
@ -24,7 +31,7 @@ body {
|
|||
background-color: $dark;
|
||||
}
|
||||
|
||||
#root {
|
||||
#__next {
|
||||
height: 100vh;
|
||||
}
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@import './github-markdown';
|
||||
|
||||
.markdown-body {
|
||||
position: relative;
|
||||
font-family: 'Source Sans Pro', "Twemoji", sans-serif;
|
||||
|
@ -22,8 +20,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.alert > p, .alert > ul {
|
||||
margin-bottom: 0;
|
||||
.alert {
|
||||
& > p, & > ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// This is necessary since we need to set this for all DOM Element that could be children of .markdown-body and since we support all of HTML that would literally be everything
|
||||
|
@ -33,7 +33,7 @@
|
|||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
a.heading-anchor {
|
||||
.heading-anchor {
|
||||
font-size: 0.75em;
|
||||
margin-top: 0.25em;
|
||||
opacity: 0.3;
|
||||
|
@ -64,5 +64,4 @@
|
|||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,9 +4,10 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@import '~reveal.js/dist/reveal.css';
|
||||
// Default mixins and settings -----------------
|
||||
@import "../../../node_modules/reveal.js/css/theme/template/mixins";
|
||||
@import "../../../node_modules/reveal.js/css/theme/template/settings";
|
||||
@import "~reveal.js/css/theme/template/mixins";
|
||||
@import "~reveal.js/css/theme/template/settings";
|
||||
// ---------------------------------------------
|
||||
|
||||
|
||||
|
@ -37,5 +38,5 @@ $heading4Size: 1.0em;
|
|||
|
||||
|
||||
// Theme template ------------------------------
|
||||
@import "../../../node_modules/reveal.js/css/theme/template/theme";
|
||||
@import "~reveal.js/css/theme/template/theme";
|
||||
// ---------------------------------------------
|
|
@ -125,6 +125,6 @@ $close-text-shadow: none;
|
|||
// Code
|
||||
$pre-color: $dark;
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/functions";
|
||||
@import "../../node_modules/bootstrap/scss/mixins";
|
||||
@import "../../node_modules/bootstrap/scss/variables";
|
||||
@import "~bootstrap/scss/functions";
|
||||
@import "~bootstrap/scss/mixins";
|
||||
@import "~bootstrap/scss/variables";
|
|
@ -1,4 +1,4 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
@ -8,9 +8,9 @@ $blue: #337ab7 !default;
|
|||
$cyan: #5EB7E0 !default;
|
||||
$dark: #222222 !default;
|
||||
|
||||
@import "../../node_modules/bootstrap/scss/functions";
|
||||
@import "../../node_modules/bootstrap/scss/mixins";
|
||||
@import "../../node_modules/bootstrap/scss/variables";
|
||||
@import "~bootstrap/scss/functions";
|
||||
@import "~bootstrap/scss/mixins";
|
||||
@import "~bootstrap/scss/variables";
|
||||
|
||||
$toast-background-color: $white;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/*!
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
24
jest.config.ts
Normal file
24
jest.config.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import nextJest from 'next/jest'
|
||||
|
||||
const createJestConfig = nextJest({
|
||||
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
|
||||
dir: './',
|
||||
})
|
||||
|
||||
// Add any custom config to be passed to Jest
|
||||
const customJestConfig = {
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||
moduleNameMapper: {
|
||||
// Handle module aliases (this will be automatically configured for you soon)
|
||||
'^@/components/(.*)$': '<rootDir>/components/$1',
|
||||
},
|
||||
testPathIgnorePatterns: ["/node_modules/", "/cypress/"]
|
||||
}
|
||||
|
||||
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
|
||||
module.exports = createJestConfig(customJestConfig)
|
11
jest.setup.ts
Normal file
11
jest.setup.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
// Optional: configure or set up a testing framework before each test.
|
||||
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`
|
||||
|
||||
// Used for __tests__/testing-library.js
|
||||
// Learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect'
|
5
next-env.d.ts
vendored
Normal file
5
next-env.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
|
@ -1,3 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: LicenseRef-HedgeDoc-Icon-Usage-Guidelines
|
||||
SPDX-License-Identifier: CC0-1.0
|
86
next.config.js
Normal file
86
next.config.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
console.log('Node env is', process.env.NODE_ENV)
|
||||
|
||||
if (process.env.NEXT_PUBLIC_USE_MOCK_API === 'true') {
|
||||
console.log('Uses mock API')
|
||||
} else if (!!process.env.NEXT_PUBLIC_BACKEND_BASE_URL) {
|
||||
console.log('Backend base url is', process.env.NEXT_PUBLIC_BACKEND_BASE_URL)
|
||||
} else {
|
||||
console.error(`==============
|
||||
Neither NEXT_PUBLIC_USE_MOCK_API or NEXT_PUBLIC_BACKEND_BASE_URL is set.
|
||||
If you want to create a production build we suggest that you set a backend url with NEXT_PUBLIC_BACKEND_BASE_URL.
|
||||
If you want to create a build that uses the mock api then use build:mock instead or set NEXT_PUBLIC_USE_MOCK_API to "true".
|
||||
==============`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (!!process.env.NEXT_PUBLIC_TEST_MODE) {
|
||||
console.log('Built in test mode')
|
||||
}
|
||||
|
||||
const path = require('path')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
||||
enabled: process.env.ANALYZE === 'true'
|
||||
})
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const rawNextConfig = {
|
||||
webpack: (config) => {
|
||||
config.module.rules.push({
|
||||
test: /\.svg$/i,
|
||||
issuer: /\.[jt]sx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: '@svgr/webpack',
|
||||
options: {
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeViewBox: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
config.plugins.push(
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{ from: path.join(__dirname, 'node_modules/@hpcc-js/wasm/dist/graphvizlib.wasm'), to: 'static/js' },
|
||||
{ from: path.join(__dirname, 'node_modules/@hpcc-js/wasm/dist/expatlib.wasm'), to: 'static/js' },
|
||||
{
|
||||
from: path.join(__dirname, 'node_modules/emoji-picker-element-data/en/emojibase/data.json'),
|
||||
to: 'static/js/emoji-data.json'
|
||||
}
|
||||
]
|
||||
})
|
||||
)
|
||||
return config
|
||||
},
|
||||
reactStrictMode: true,
|
||||
redirects: () => {
|
||||
return Promise.resolve([
|
||||
{
|
||||
source: '/',
|
||||
destination: '/intro',
|
||||
permanent: true
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
const completeNextConfig = withBundleAnalyzer(rawNextConfig)
|
||||
|
||||
module.exports = completeNextConfig
|
187
package.json
187
package.json
|
@ -1,69 +1,26 @@
|
|||
{
|
||||
"name": "react_client",
|
||||
"name": "@hedgedoc/react-client",
|
||||
"version": "0.0.1",
|
||||
"license": "AGPL-3.0",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"start": "cross-env PORT=3001 craco start",
|
||||
"start:test": "cross-env REACT_APP_TEST_MODE=true yarn start",
|
||||
"start:for-real-backend": "cross-env REACT_APP_BACKEND_BASE_URL=http://localhost:3000/ yarn start",
|
||||
"serve:build": "http-server build/ -s -p 3001 -P \"http://localhost:3001?\"",
|
||||
"build:test": "cross-env REACT_APP_TEST_MODE=true craco build",
|
||||
"build:mock": "cross-env craco build",
|
||||
"build:production": "(cross-env node check-build-env-vars.js) && (cross-env craco build)",
|
||||
"analyze": "cross-env ANALYZE=true yarn build:mock",
|
||||
"test": "craco test",
|
||||
"lint": "eslint --max-warnings=0 --ext .ts,.tsx src",
|
||||
"lint:fix": "eslint --fix --ext .ts,.tsx src",
|
||||
"build": "next build",
|
||||
"build:mock": "cross-env NEXT_PUBLIC_USE_MOCK_API=true next build",
|
||||
"build:test": "cross-env NEXT_PUBLIC_USE_MOCK_API=true NEXT_PUBLIC_TEST_MODE=true next build",
|
||||
"analyze": "cross-env ANALYZE=true next build",
|
||||
"dev": "cross-env PORT=3001 next dev",
|
||||
"dev:test": "cross-env PORT=3001 NEXT_PUBLIC_TEST_MODE=true next dev",
|
||||
"dev:for-real-backend": "cross-env PORT=3001 NEXT_PUBLIC_USE_MOCK_API=false NEXT_PUBLIC_BACKEND_BASE_URL=http://localhost:3000/ next dev",
|
||||
"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",
|
||||
"lint": "eslint --max-warnings=0 --ext .ts,.tsx src",
|
||||
"lint:fix": "eslint --fix --ext .ts,.tsx src",
|
||||
"start": "cross-env PORT=3001 next start",
|
||||
"start:ci": "cross-env NEXT_PUBLIC_USE_MOCK_API=true NEXT_PUBLIC_TEST_MODE=true PORT=3001 next start",
|
||||
"cy:open": "cypress open",
|
||||
"cy:run:chrome": "cypress run --browser chrome",
|
||||
"cy:run:firefox": "cypress run --browser firefox"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"parserOptions": {
|
||||
"tsconfigRootDir": "",
|
||||
"project": [
|
||||
"./tsconfig.json"
|
||||
]
|
||||
},
|
||||
"rules": {
|
||||
"no-use-before-define": "off",
|
||||
"no-debugger": "warn",
|
||||
"default-param-last": "off",
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"error",
|
||||
{
|
||||
"prefer": "type-imports",
|
||||
"disallowTypeAnnotations": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"react-app",
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
"parser": "typescript",
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": true,
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "always"
|
||||
"cy:run:firefox": "cypress run --browser firefox",
|
||||
"test": "jest --watch",
|
||||
"test:ci": "jest --ci"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
@ -77,71 +34,30 @@
|
|||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@craco/craco": "6.4.3",
|
||||
"@cypress/webpack-preprocessor": "5.11.0",
|
||||
"dependencies": {
|
||||
"@fontsource/source-sans-pro": "4.5.1",
|
||||
"@hedgedoc/html-to-react": "1.1.1",
|
||||
"@hedgedoc/markdown-it-image-size": "1.0.3",
|
||||
"@hedgedoc/markdown-it-task-lists": "1.0.3",
|
||||
"@matejmazur/react-katex": "3.1.3",
|
||||
"@redux-devtools/core": "3.9.1",
|
||||
"@testing-library/cypress": "8.0.2",
|
||||
"@testing-library/jest-dom": "5.16.1",
|
||||
"@testing-library/react": "12.1.2",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/codemirror": "5.60.5",
|
||||
"@types/d3-graphviz": "2.6.7",
|
||||
"@types/diff": "5.0.2",
|
||||
"@types/dompurify": "2.3.2",
|
||||
"@types/jest": "27.0.3",
|
||||
"@types/js-yaml": "4.0.5",
|
||||
"@types/luxon": "2.0.8",
|
||||
"@types/markdown-it": "12.2.3",
|
||||
"@types/markdown-it-container": "2.0.4",
|
||||
"@types/markdown-it-plantuml": "1.4.1",
|
||||
"@types/mermaid": "8.2.7",
|
||||
"@types/node": "16.11.17",
|
||||
"@types/react": "17.0.38",
|
||||
"@types/react-bootstrap-typeahead": "5.1.8",
|
||||
"@types/react-dom": "17.0.11",
|
||||
"@types/react-router": "5.1.17",
|
||||
"@types/react-router-bootstrap": "0.24.5",
|
||||
"@types/react-router-dom": "5.3.2",
|
||||
"@types/redux-devtools": "3.0.47",
|
||||
"@types/sass": "1.43.1",
|
||||
"@types/uuid": "8.3.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.8.0",
|
||||
"@typescript-eslint/parser": "5.8.0",
|
||||
"@svgr/webpack": "6.1.2",
|
||||
"abcjs": "6.0.0-beta.35",
|
||||
"bootstrap": "4.6.1",
|
||||
"codemirror": "5.65.0",
|
||||
"copy-webpack-plugin": "6.4.1",
|
||||
"copy-webpack-plugin": "10.2.0",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "9.2.0",
|
||||
"cypress-commands": "2.0.1",
|
||||
"cypress-file-upload": "6.0.0-beta.0",
|
||||
"d3-graphviz": "3.2.0",
|
||||
"diff": "5.0.0",
|
||||
"dompurify": "2.3.4",
|
||||
"emoji-picker-element": "1.10.0",
|
||||
"emoji-picker-element-data": "1.3.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-config-react-app": "6.0.0",
|
||||
"eslint-plugin-chai-friendly": "0.7.2",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-import": "2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "6.5.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "5.2.0",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"firacode": "6.2.0",
|
||||
"flowchart.js": "1.17.0",
|
||||
"fork-awesome": "1.2.0",
|
||||
"highlight.js": "11.3.1",
|
||||
"http-server": "14.0.0",
|
||||
"i18next": "21.6.3",
|
||||
"i18next": "21.6.4",
|
||||
"i18next-browser-languagedetector": "6.1.2",
|
||||
"i18next-resources-to-backend": "1.0.0",
|
||||
"js-yaml": "4.1.0",
|
||||
|
@ -166,38 +82,75 @@
|
|||
"markmap-common": "0.1.6",
|
||||
"markmap-lib": "0.12.0",
|
||||
"markmap-view": "0.2.7",
|
||||
"mermaid": "8.13.7",
|
||||
"mermaid": "8.13.8",
|
||||
"next": "12.0.7",
|
||||
"optional-js": "2.3.0",
|
||||
"prettier": "2.5.1",
|
||||
"react": "17.0.2",
|
||||
"react-bootstrap": "1.6.4",
|
||||
"react-bootstrap-typeahead": "5.2.1",
|
||||
"react-codemirror2": "7.2.1",
|
||||
"react-diff-viewer": "3.1.1",
|
||||
"react-dom": "17.0.2",
|
||||
"react-i18next": "11.15.1",
|
||||
"react-i18next": "11.15.2",
|
||||
"react-redux": "7.2.6",
|
||||
"react-router": "5.2.1",
|
||||
"react-router-bootstrap": "0.25.0",
|
||||
"react-router-dom": "5.3.0",
|
||||
"react-router-use-location-state": "2.5.0",
|
||||
"react-scripts": "4.0.3",
|
||||
"react-use": "17.3.1",
|
||||
"redux": "4.1.2",
|
||||
"redux-devtools-extension": "2.13.9",
|
||||
"reveal.js": "4.2.1",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"sass": "1.45.1",
|
||||
"ts-loader": "9.2.6",
|
||||
"ts-mockery": "1.2.0",
|
||||
"sharp": "0.29.3",
|
||||
"twemoji-colr-font": "0.0.4",
|
||||
"typescript": "4.5.4",
|
||||
"use-resize-observer": "8.0.0",
|
||||
"uuid": "8.3.2",
|
||||
"vega": "5.21.0",
|
||||
"vega-embed": "6.20.5",
|
||||
"vega-lite": "5.2.0",
|
||||
"webpack-bundle-analyzer": "4.5.0",
|
||||
"words-count": "2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "12.0.7",
|
||||
"@testing-library/cypress": "8.0.2",
|
||||
"@testing-library/jest-dom": "5.16.1",
|
||||
"@testing-library/react": "12.1.2",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/codemirror": "5.60.5",
|
||||
"@types/d3-graphviz": "2.6.7",
|
||||
"@types/diff": "5.0.2",
|
||||
"@types/dompurify": "2.3.2",
|
||||
"@types/js-yaml": "4.0.5",
|
||||
"@types/luxon": "2.0.8",
|
||||
"@types/markdown-it": "12.2.3",
|
||||
"@types/markdown-it-container": "2.0.4",
|
||||
"@types/markdown-it-plantuml": "1.4.1",
|
||||
"@types/mermaid": "8.2.7",
|
||||
"@types/node": "16.11.17",
|
||||
"@types/react": "17.0.38",
|
||||
"@types/react-bootstrap-typeahead": "5.1.8",
|
||||
"@types/react-dom": "17.0.11",
|
||||
"@types/sass": "1.43.1",
|
||||
"@types/uuid": "8.3.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.8.1",
|
||||
"@typescript-eslint/parser": "5.8.1",
|
||||
"cypress": "9.2.0",
|
||||
"cypress-commands": "2.0.1",
|
||||
"cypress-file-upload": "6.0.0-beta.0",
|
||||
"eslint": "8.5.0",
|
||||
"eslint-config-next": "12.0.7",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-chai-friendly": "0.7.2",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-import": "2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "6.5.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "5.2.0",
|
||||
"eslint-plugin-testing-library": "5.0.1",
|
||||
"jest": "27.4.5",
|
||||
"prettier": "2.5.1",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"redux-devtools-extension": "2.13.9",
|
||||
"ts-loader": "9.2.6",
|
||||
"ts-mockery": "1.2.0",
|
||||
"ts-node": "10.4.0",
|
||||
"typescript": "4.5.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
|
|
94
src/components/application-loader/animations.scss
Normal file
94
src/components/application-loader/animations.scss
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@keyframes animation-roll {
|
||||
0% {
|
||||
transform: translateX(calc(-100vw / 2 - 100%)) rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(calc(100vw / 2 + 100%)) rotateZ(720deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation-jump {
|
||||
0% {
|
||||
transform: scale(1, 1) translateY(0);
|
||||
}
|
||||
10% {
|
||||
transform: scale(1.1, .9) translateY(0);
|
||||
}
|
||||
30% {
|
||||
transform: scale(.9, 1.1) translateY(-100px);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05, .95) translateY(0);
|
||||
}
|
||||
57% {
|
||||
transform: scale(1, 1) translateY(-7px);
|
||||
}
|
||||
64% {
|
||||
transform: scale(1, 1) translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1, 1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation-shake {
|
||||
0% {
|
||||
transform: translate(1px, 1px) rotate(0deg);
|
||||
}
|
||||
10% {
|
||||
transform: translate(-1px, -2px) rotate(-1deg);
|
||||
}
|
||||
20% {
|
||||
transform: translate(-3px, 0px) rotate(1deg);
|
||||
}
|
||||
30% {
|
||||
transform: translate(3px, 2px) rotate(0deg);
|
||||
}
|
||||
40% {
|
||||
transform: translate(1px, -1px) rotate(1deg);
|
||||
}
|
||||
50% {
|
||||
transform: translate(-1px, 2px) rotate(-1deg);
|
||||
}
|
||||
60% {
|
||||
transform: translate(-3px, 1px) rotate(0deg);
|
||||
}
|
||||
70% {
|
||||
transform: translate(3px, 1px) rotate(-1deg);
|
||||
}
|
||||
80% {
|
||||
transform: translate(-1px, -1px) rotate(1deg);
|
||||
}
|
||||
90% {
|
||||
transform: translate(1px, 2px) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(1px, -2px) rotate(-1deg);
|
||||
}
|
||||
}
|
||||
|
||||
.animation-roll {
|
||||
transform-origin: center center;
|
||||
animation-duration: 4s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: animation-roll;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
|
||||
.animation-jump {
|
||||
transform-origin: bottom;
|
||||
animation-duration: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: animation-jump;
|
||||
animation-timing-function: cubic-bezier(0.280, 0.840, 0.420, 1);
|
||||
}
|
||||
|
||||
.animation-shake {
|
||||
animation: animation-shake 0.3s ease-in-out;
|
||||
}
|
|
@ -3,13 +3,8 @@
|
|||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.header-nav {
|
||||
.nav-link {
|
||||
border-bottom: 2px solid transparent
|
||||
}
|
||||
|
||||
.nav-link.active {
|
||||
border-bottom-color: #fff;
|
||||
export class ApplicationLoaderError extends Error {
|
||||
constructor(taskName: string) {
|
||||
super(`Task ${taskName} failed`)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.loader {
|
||||
@import "./animations.scss";
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&.middle, .middle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
.loader {
|
||||
@keyframes animation-roll {
|
||||
0% {
|
||||
transform: translateX(calc(-100vw / 2 - 100%)) rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(calc(100vw / 2 + 100%)) rotateZ(720deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation-jump {
|
||||
0% {
|
||||
transform: scale(1, 1) translateY(0);
|
||||
}
|
||||
10% {
|
||||
transform: scale(1.1, .9) translateY(0);
|
||||
}
|
||||
30% {
|
||||
transform: scale(.9, 1.1) translateY(-100px);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05, .95) translateY(0);
|
||||
}
|
||||
57% {
|
||||
transform: scale(1, 1) translateY(-7px);
|
||||
}
|
||||
64% {
|
||||
transform: scale(1, 1) translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1, 1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation-shake {
|
||||
0% {
|
||||
transform: translate(1px, 1px) rotate(0deg);
|
||||
}
|
||||
10% {
|
||||
transform: translate(-1px, -2px) rotate(-1deg);
|
||||
}
|
||||
20% {
|
||||
transform: translate(-3px, 0px) rotate(1deg);
|
||||
}
|
||||
30% {
|
||||
transform: translate(3px, 2px) rotate(0deg);
|
||||
}
|
||||
40% {
|
||||
transform: translate(1px, -1px) rotate(1deg);
|
||||
}
|
||||
50% {
|
||||
transform: translate(-1px, 2px) rotate(-1deg);
|
||||
}
|
||||
60% {
|
||||
transform: translate(-3px, 1px) rotate(0deg);
|
||||
}
|
||||
70% {
|
||||
transform: translate(3px, 1px) rotate(-1deg);
|
||||
}
|
||||
80% {
|
||||
transform: translate(-1px, -1px) rotate(1deg);
|
||||
}
|
||||
90% {
|
||||
transform: translate(1px, 2px) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(1px, -2px) rotate(-1deg);
|
||||
}
|
||||
}
|
||||
|
||||
.animation-roll {
|
||||
transform-origin: center center;
|
||||
animation-duration: 4s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: animation-roll;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
|
||||
.animation-jump {
|
||||
transform-origin: bottom;
|
||||
animation-duration: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: animation-jump;
|
||||
animation-timing-function: cubic-bezier(0.280, 0.840, 0.420, 1);
|
||||
}
|
||||
|
||||
.animation-shake {
|
||||
animation: animation-shake 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
|
||||
&.middle, .middle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.progress {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue