mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-20 00:36:44 +02:00
Compare commits
1 Commits
9.0.1
...
feature/Ad
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a69b7090cc |
8
.ackrc
8
.ackrc
@@ -1,4 +1,4 @@
|
||||
--ignore-dir=dist
|
||||
--ignore-file=match:/^yarn\.lock$/
|
||||
--ignore-file=match:/^yarn-error\.log$/
|
||||
--ignore-dir=coverage
|
||||
--ignore-dir=dist
|
||||
--ignore-file=match:/^yarn\.lock$/
|
||||
--ignore-file=match:/^yarn-error\.log$/
|
||||
--ignore-dir=coverage
|
||||
|
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"@commitlint/config-conventional"
|
||||
]
|
||||
}
|
@@ -1,11 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
indent_size = 4
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
indent_size = 4
|
||||
|
@@ -1,2 +1 @@
|
||||
dist/**
|
||||
.github/**
|
||||
**/*.spec.js
|
@@ -2,37 +2,19 @@
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"jest/globals": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "@babel/eslint-parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": true
|
||||
},
|
||||
"sourceType": "module"
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": true
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": ["eslint:recommended", "plugin:jsdoc/recommended", "plugin:markdown/recommended", "plugin:prettier/recommended"],
|
||||
"plugins": ["html", "jest", "jsdoc", "prettier"],
|
||||
"extends": ["prettier", "eslint:recommended"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"no-prototype-builtins": 0,
|
||||
"no-unused-vars": 0,
|
||||
"jsdoc/check-indentation": 0,
|
||||
"jsdoc/check-alignment": 0,
|
||||
"jsdoc/check-line-alignment": 0,
|
||||
"jsdoc/multiline-blocks": 0,
|
||||
"jsdoc/newline-after-description": 0,
|
||||
"jsdoc/tag-lines": 0,
|
||||
"no-empty": ["error", { "allowEmptyCatch": true }]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "./**/*.html",
|
||||
"rules": {
|
||||
"no-undef": "off",
|
||||
"jsdoc/require-jsdoc": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
"prettier/prettier": ["error"]
|
||||
}
|
||||
}
|
||||
|
24
.github/FUNDING.yml
vendored
24
.github/FUNDING.yml
vendored
@@ -1,12 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [knsv]
|
||||
#patreon: # Replace with a single Patreon username
|
||||
#open_collective: # Replace with a single Open Collective username
|
||||
#ko_fi: # Replace with a single Ko-fi username
|
||||
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
#liberapay: # Replace with a single Liberapay username
|
||||
#issuehunt: # Replace with a single IssueHunt username
|
||||
#otechie: # Replace with a single Otechie username
|
||||
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [knsv]
|
||||
#patreon: # Replace with a single Patreon username
|
||||
#open_collective: # Replace with a single Open Collective username
|
||||
#ko_fi: # Replace with a single Ko-fi username
|
||||
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
#liberapay: # Replace with a single Liberapay username
|
||||
#issuehunt: # Replace with a single IssueHunt username
|
||||
#otechie: # Replace with a single Otechie username
|
||||
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
|
40
.github/ISSUE_TEMPLATE/feature_request.md
vendored
40
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
30
.github/ISSUE_TEMPLATE/question.md
vendored
30
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,15 +1,15 @@
|
||||
---
|
||||
name: Question
|
||||
about: Get some help from the community.
|
||||
title: ''
|
||||
labels: 'Help wanted!, Type: Other'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Help us help you!
|
||||
You want an answer. Here are some ways to get it quicker:
|
||||
* Use a clear and concise title.
|
||||
* Try to pose a clear and concise question.
|
||||
* Include as much, or as little, code as necessary.
|
||||
* Don't be shy to give us some screenshots, if it helps!
|
||||
---
|
||||
name: Question
|
||||
about: Get some help from the community.
|
||||
title: ''
|
||||
labels: 'Help wanted!, Type: Other'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Help us help you!
|
||||
You want an answer. Here are some ways to get it quicker:
|
||||
* Use a clear and concise title.
|
||||
* Try to pose a clear and concise question.
|
||||
* Include as much, or as little, code as necessary.
|
||||
* Don't be shy to give us some screenshots, if it helps!
|
||||
|
26
.github/pull_request_template.md
vendored
26
.github/pull_request_template.md
vendored
@@ -1,13 +1,13 @@
|
||||
## :bookmark_tabs: Summary
|
||||
Brief description about the content of your PR.
|
||||
|
||||
Resolves #<your issue id here>
|
||||
|
||||
## :straight_ruler: Design Decisions
|
||||
Describe the way your implementation works or what design decisions you made if applicable.
|
||||
|
||||
### :clipboard: Tasks
|
||||
Make sure you
|
||||
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] :computer: have added unit/e2e tests (if appropriate)
|
||||
- [ ] :bookmark: targeted `develop` branch
|
||||
## :bookmark_tabs: Summary
|
||||
Brief description about the content of your PR.
|
||||
|
||||
Resolves #<your issue id here>
|
||||
|
||||
## :straight_ruler: Design Decisions
|
||||
Describe the way your implementation works or what design decisions you made if applicable.
|
||||
|
||||
### :clipboard: Tasks
|
||||
Make sure you
|
||||
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] :computer: have added unit/e2e tests (if appropriate)
|
||||
- [ ] :bookmark: targeted `develop` branch
|
||||
|
50
.github/release-drafter.yml
vendored
50
.github/release-drafter.yml
vendored
@@ -1,25 +1,25 @@
|
||||
name-template: '$NEXT_PATCH_VERSION'
|
||||
tag-template: '$NEXT_PATCH_VERSION'
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'Type: Enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
labels:
|
||||
- 'Type: Bug / Error'
|
||||
- title: '🧰 Maintenance'
|
||||
label: 'Type: Other'
|
||||
change-template: '- $TITLE (#$NUMBER) @$AUTHOR'
|
||||
sort-by: title
|
||||
sort-direction: ascending
|
||||
branches:
|
||||
- develop
|
||||
exclude-labels:
|
||||
- 'Skip changelog'
|
||||
no-changes-template: 'This release contains minor changes and bugfixes.'
|
||||
template: |
|
||||
# Release Notes
|
||||
|
||||
$CHANGES
|
||||
|
||||
🎉 **Thanks to all contributors helping with this release!** 🎉
|
||||
name-template: '$NEXT_PATCH_VERSION'
|
||||
tag-template: '$NEXT_PATCH_VERSION'
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'Type: Enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
labels:
|
||||
- 'Type: Bug / Error'
|
||||
- title: '🧰 Maintenance'
|
||||
label: 'Type: Other'
|
||||
change-template: '- $TITLE (#$NUMBER) @$AUTHOR'
|
||||
sort-by: title
|
||||
sort-direction: ascending
|
||||
branches:
|
||||
- develop
|
||||
exclude-labels:
|
||||
- 'Skip changelog'
|
||||
no-changes-template: 'This release contains minor changes and bugfixes.'
|
||||
template: |
|
||||
# Release Notes
|
||||
|
||||
$CHANGES
|
||||
|
||||
🎉 **Thanks to all contributors helping with this release!** 🎉
|
||||
|
38
.github/stale.yml
vendored
38
.github/stale.yml
vendored
@@ -1,19 +1,19 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Retained
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Inactive
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
If you are still interested in this issue and it is still relevant you can comment to revive it.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been been automatically closed due to a lack of activity.
|
||||
This is done to maintain a clean list of issues that the community is interested in developing.
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Retained
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Inactive
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
If you are still interested in this issue and it is still relevant you can comment to revive it.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been been automatically closed due to a lack of activity.
|
||||
This is done to maintain a clean list of issues that the community is interested in developing.
|
||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -9,10 +9,10 @@ jobs:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
cache: yarn
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
32
.github/workflows/check-readme-in-sync.yml
vendored
32
.github/workflows/check-readme-in-sync.yml
vendored
@@ -1,32 +0,0 @@
|
||||
# Reference: https://github.com/Yash-Singh1/eslint-plugin-userscripts/blob/main/.github/workflows/readme-in-sync.yml
|
||||
|
||||
name: Check if README and docs/README are in sync
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- gh-pages
|
||||
pull_request:
|
||||
branches:
|
||||
- gh-pages
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check for difference in README.md and docs/README.md
|
||||
run: |
|
||||
if [ -z "$(diff README.md docs/README.md --brief)" ]
|
||||
then
|
||||
echo "README.md and docs/README.md are in sync"
|
||||
else
|
||||
echo "Make sure that README.md and docs/README.md are in sync"
|
||||
echo
|
||||
echo "Difference:"
|
||||
echo
|
||||
diff README.md docs/README.md -u
|
||||
exit 1
|
||||
fi
|
38
.github/workflows/checks
vendored
38
.github/workflows/checks
vendored
@@ -1,19 +1,19 @@
|
||||
on: [push]
|
||||
|
||||
name: Static analysis
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: check tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: testomatio/check-tests@stable
|
||||
with:
|
||||
framework: cypress
|
||||
tests: "./cypress/integration/**/**.spec.js"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
has-tests-label: true
|
||||
|
||||
on: [push]
|
||||
|
||||
name: Static analysis
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: check tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: testomatio/check-tests@stable
|
||||
with:
|
||||
framework: cypress
|
||||
tests: "./cypress/integration/**/**.spec.js"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
has-tests-label: true
|
||||
|
||||
|
6
.github/workflows/e2e.yml
vendored
6
.github/workflows/e2e.yml
vendored
@@ -9,10 +9,10 @@ jobs:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2.3.4
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
cache: yarn
|
||||
node-version: ${{ matrix.node-version }}
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
- name: Run E2E Tests
|
||||
run: yarn e2e
|
||||
env:
|
||||
# PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
|
||||
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
#- name: Post Upload Test Results
|
||||
|
13
.github/workflows/lock-closed-issue.yml
vendored
Normal file
13
.github/workflows/lock-closed-issue.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Lock closed issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Dunning-Kruger/lock-issues@v1.1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
@@ -1,13 +0,0 @@
|
||||
name: Validate PR Labeler Configuration
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
pr-labeler:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Validate Configuration
|
||||
uses: Yash-Singh1/pr-labeler-config-validator@releases/v0.0.3
|
||||
with:
|
||||
configuration-path: .github/pr-labeler.yml
|
@@ -9,9 +9,9 @@ jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.x
|
||||
- name: Install Yarn
|
||||
|
4
.github/workflows/release-publish.yml
vendored
4
.github/workflows/release-publish.yml
vendored
@@ -8,11 +8,11 @@ jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: fregante/setup-git-user@v1
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.x
|
||||
- name: Install Yarn
|
||||
|
26
.github/workflows/unlock-reopened-issues.yml
vendored
26
.github/workflows/unlock-reopened-issues.yml
vendored
@@ -1,13 +1,13 @@
|
||||
name: Unlock reopened issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [reopened]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Dunning-Kruger/unlock-issues@v1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
name: Unlock reopened issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [reopened]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Dunning-Kruger/unlock-issues@v1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
18
.github/workflows/update-browserlist.yml
vendored
18
.github/workflows/update-browserlist.yml
vendored
@@ -1,18 +0,0 @@
|
||||
name: Update Browserslist
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 7 * * 1'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: npx browserslist@latest --update-db
|
||||
- name: Commit changes
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
author_name: ${{ github.actor }}
|
||||
author_email: ${{ github.actor }}@users.noreply.github.com
|
||||
message: 'chore: update browsers list'
|
10
.gitignore
vendored
10
.gitignore
vendored
@@ -4,7 +4,8 @@ node_modules/
|
||||
coverage/
|
||||
.idea/
|
||||
|
||||
dist
|
||||
dist/*.js
|
||||
dist/*.map
|
||||
|
||||
yarn-error.log
|
||||
.npmrc
|
||||
@@ -12,6 +13,10 @@ token
|
||||
|
||||
package-lock.json
|
||||
|
||||
dist/classTest.html
|
||||
|
||||
dist/sequenceTest.html
|
||||
|
||||
.vscode/
|
||||
cypress/platform/current.html
|
||||
cypress/platform/experimental.html
|
||||
@@ -20,6 +25,3 @@ local/
|
||||
_site
|
||||
Gemfile.lock
|
||||
/.vs
|
||||
|
||||
cypress/screenshots/
|
||||
cypress/snapshots/
|
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
# . "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
# npx --no-install commitlint --edit $1
|
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn pre-commit
|
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"*.{js,html,md}": [
|
||||
"yarn lint:fix"
|
||||
]
|
||||
}
|
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"singleQuote": true,
|
||||
"endOfLine": "auto"
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"endOfLine": "auto",
|
||||
"plugins": [
|
||||
"prettier-plugin-jsdoc"
|
||||
],
|
||||
"printWidth": 100,
|
||||
"singleQuote": true
|
||||
}
|
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"ecmaVersion": 6,
|
||||
"libs": [
|
||||
"browser"
|
||||
],
|
||||
"loadEagerly": [
|
||||
"path/to/your/js/**/*.js"
|
||||
],
|
||||
"dontLoad": [
|
||||
"node_modules/**",
|
||||
"path/to/your/js/**/*.js"
|
||||
],
|
||||
"plugins": {
|
||||
"modules": {},
|
||||
"es_modules": {},
|
||||
"node": {},
|
||||
"doc_comment": {
|
||||
"fullDocs": true,
|
||||
"strong": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"ecmaVersion": 6,
|
||||
"libs": [
|
||||
"browser"
|
||||
],
|
||||
"loadEagerly": [
|
||||
"path/to/your/js/**/*.js"
|
||||
],
|
||||
"dontLoad": [
|
||||
"node_modules/**",
|
||||
"path/to/your/js/**/*.js"
|
||||
],
|
||||
"plugins": {
|
||||
"modules": {},
|
||||
"es_modules": {},
|
||||
"node": {},
|
||||
"doc_comment": {
|
||||
"fullDocs": true,
|
||||
"strong": true
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
const { Generator } = require('jison');
|
||||
const validate = require('schema-utils');
|
||||
|
||||
const schema = {
|
||||
title: 'Jison Parser options',
|
||||
type: 'object',
|
||||
properties: {
|
||||
'token-stack': {
|
||||
type: 'boolean',
|
||||
},
|
||||
debug: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
};
|
||||
|
||||
module.exports = function jisonLoader(source) {
|
||||
const options = this.getOptions();
|
||||
(validate.validate || validate)(schema, options, {
|
||||
name: 'Jison Loader',
|
||||
baseDataPath: 'options',
|
||||
});
|
||||
return new Generator(source, options).generate();
|
||||
};
|
@@ -1,45 +0,0 @@
|
||||
import { merge, mergeWithCustomize, customizeObject } from 'webpack-merge';
|
||||
import nodeExternals from 'webpack-node-externals';
|
||||
import baseConfig from './webpack.config.base';
|
||||
|
||||
export default (_env, args) => {
|
||||
switch (args.mode) {
|
||||
case 'development':
|
||||
return [
|
||||
baseConfig,
|
||||
merge(baseConfig, {
|
||||
externals: [nodeExternals()],
|
||||
output: {
|
||||
filename: '[name].core.js',
|
||||
},
|
||||
}),
|
||||
];
|
||||
case 'production':
|
||||
return [
|
||||
// umd
|
||||
merge(baseConfig, {
|
||||
output: {
|
||||
filename: '[name].min.js',
|
||||
},
|
||||
}),
|
||||
// esm
|
||||
mergeWithCustomize({
|
||||
customizeObject: customizeObject({
|
||||
'output.library': 'replace',
|
||||
}),
|
||||
})(baseConfig, {
|
||||
experiments: {
|
||||
outputModule: true,
|
||||
},
|
||||
output: {
|
||||
library: {
|
||||
type: 'module',
|
||||
},
|
||||
filename: '[name].esm.min.mjs',
|
||||
},
|
||||
}),
|
||||
];
|
||||
default:
|
||||
throw new Error('No matching configuration was found!');
|
||||
}
|
||||
};
|
@@ -1,54 +0,0 @@
|
||||
import path from 'path';
|
||||
|
||||
export const resolveRoot = (...relativePath) => path.resolve(__dirname, '..', ...relativePath);
|
||||
|
||||
export default {
|
||||
amd: false, // https://github.com/lodash/lodash/issues/3052
|
||||
target: 'web',
|
||||
entry: {
|
||||
mermaid: './src/mermaid.js',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.wasm', '.mjs', '.js', '.json', '.jison'],
|
||||
fallback: {
|
||||
fs: false, // jison generated code requires 'fs'
|
||||
path: require.resolve('path-browserify'),
|
||||
},
|
||||
},
|
||||
output: {
|
||||
path: resolveRoot('./dist'),
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
name: 'mermaid',
|
||||
type: 'umd',
|
||||
export: 'default',
|
||||
},
|
||||
globalObject: 'typeof self !== "undefined" ? self : this',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
include: [resolveRoot('./src'), resolveRoot('./node_modules/dagre-d3-renderer/lib')],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{
|
||||
// load scss to string
|
||||
test: /\.scss$/,
|
||||
use: ['css-to-string-loader', 'css-loader', 'sass-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.jison$/,
|
||||
use: {
|
||||
loader: path.resolve(__dirname, './loaders/jison.js'),
|
||||
options: {
|
||||
'token-stack': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
devtool: 'source-map',
|
||||
};
|
@@ -1,37 +0,0 @@
|
||||
import baseConfig, { resolveRoot } from './webpack.config.base';
|
||||
import { merge } from 'webpack-merge';
|
||||
|
||||
export default merge(baseConfig, {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
mermaid: './src/mermaid.js',
|
||||
e2e: './cypress/platform/viewer.js',
|
||||
'bundle-test': './cypress/platform/bundle-test.js',
|
||||
},
|
||||
output: {
|
||||
globalObject: 'window',
|
||||
},
|
||||
devServer: {
|
||||
compress: true,
|
||||
port: 9000,
|
||||
static: [
|
||||
{ directory: resolveRoot('cypress', 'platform') },
|
||||
{ directory: resolveRoot('dist') },
|
||||
{ directory: resolveRoot('demos') },
|
||||
],
|
||||
},
|
||||
externals: {
|
||||
mermaid: 'mermaid',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
1724
CHANGELOG.md
1724
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -114,7 +114,7 @@ Finally, if it is not in the documentation, no one will know about it and then *
|
||||
|
||||
The docs are located in the docs folder and are ofc written in markdown. Just pick the right section and start typing. If you want to add to the structure as in adding a new section and new file you do that via the _navbar.md.
|
||||
|
||||
The changes in master is reflected in http://mermaid-js.github.io/mermaid/ once released the updates are committed to https://mermaid-js.github.io/#/
|
||||
The changes in master is reflected in http://mermaid-js.github.io/mermaid/ once released the updates are commited to https://mermaid-js.github.io/#/
|
||||
|
||||
## Last words
|
||||
|
||||
|
273
README.md
273
README.md
@@ -1,4 +1,4 @@
|
||||
# mermaid [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
# mermaid [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [](https://percy.io/Mermaid/mermaid)
|
||||
|
||||
English | [简体中文](./README.zh-CN.md)
|
||||
|
||||
@@ -18,10 +18,11 @@ Mermaid is a Javascript based diagramming and charting tool that uses Markdown-i
|
||||
> Doc-Rot is a Catch-22 that Mermaid helps to solve.
|
||||
|
||||
Diagramming and documentation costs precious developer time and gets outdated quickly.
|
||||
But not having diagrams or docs ruins productivity and hurts organizational learning.<br/>
|
||||
Mermaid addresses this problem by enabling users to create easily modifiable diagrams, it can also be made part of production scripts (and other pieces of code).<br/>
|
||||
<br/>
|
||||
Mermaid allows even non-programmers to easily create detailed and diagrams through the [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/).<br/>
|
||||
But not having diagrams or docs ruins productivity and hurts organizational learning. <br/>
|
||||
Mermaid addresses this problem by cutting the time, effort and tooling that is required to create modifiable diagrams and charts, for smarter and more reusable content.
|
||||
The text definitions for Mermaid diagrams allows for it to be updated easily, it can also be made part of production scripts (and other pieces of code).
|
||||
So less time needs to be spent on documenting, as a separate and laborious task. <br/>
|
||||
Even non-programmers can create diagrams through the [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/).<br/>
|
||||
[Tutorials](./docs/Tutorials.md) has video tutorials.
|
||||
Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
|
||||
|
||||
@@ -33,30 +34,33 @@ For a more detailed introduction to Mermaid and some of its more basic uses, loo
|
||||
|
||||
## Examples
|
||||
|
||||
__The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here jump into the [text syntax](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference).__
|
||||
__The following are some examples of the diagrams, charts and graphs that can be made using Mermaid and the Markdown-inspired text specific to it. Click here jump into the [text syntax](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference).__
|
||||
<table>
|
||||
<!-- <Flowchart> -->
|
||||
|
||||
## Flowchart [<a href="https://mermaid-js.github.io/mermaid/#/flowchart">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
|
||||
```
|
||||
flowchart LR
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Flow</b></br>
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/flowchart">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
graph TD
|
||||
A[Hard] -->|Text| B(Round)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result 1]
|
||||
C -->|Two| E[Result 2]
|
||||
```
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Hard] -->|Text| B(Round)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result 1]
|
||||
C -->|Two| E[Result 2]
|
||||
```
|
||||
|
||||
|
||||
## Sequence diagram [<a href="https://mermaid-js.github.io/mermaid/#/sequenceDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-flow.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Flowchart> -->
|
||||
<!-- <Sequence> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Sequence</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/sequenceDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
@@ -66,48 +70,43 @@ Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
|
||||
## Gantt chart [<a href="https://mermaid-js.github.io/mermaid/#/gantt">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-sequence.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Sequence> -->
|
||||
<!-- <Gantt> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Gantt</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/gantt">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
gantt
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
```
|
||||
```mermaid
|
||||
gantt
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
```
|
||||
|
||||
## Class diagram [<a href="https://mermaid-js.github.io/mermaid/#/classDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
|
||||
```
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-gantt.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Gantt> -->
|
||||
<!-- <Class> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Class</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/classDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<Interface>> Class01
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
@@ -117,32 +116,23 @@ Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
class Class10 {
|
||||
<<service>>
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
```
|
||||
```mermaid
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<Interface>> Class01
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
```
|
||||
|
||||
## State diagram [<a href="https://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-class.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Class> -->
|
||||
<!-- <State> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>State</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
@@ -150,36 +140,46 @@ Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
|
||||
### Pie chart [<a href="https://mermaid-js.github.io/mermaid/#/pie">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-state.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </State> -->
|
||||
<!-- <Pie> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Pie</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/pie">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
pie
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
```
|
||||
```mermaid
|
||||
pie
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
```
|
||||
|
||||
## Git graph [experimental - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
|
||||
## User Journey diagram [<a href="https://mermaid-js.github.io/mermaid/#/user-journey">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-pie.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Pie> -->
|
||||
<!-- <Git> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Git</b><br />
|
||||
[experimental - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td colspan="2" align="center"><i>Coming soon!</i></td>
|
||||
</tr>
|
||||
<!-- </Git> -->
|
||||
<!-- <Journey> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>User Journey</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/user-journey">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
@@ -189,30 +189,14 @@ pie
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
```
|
||||
```mermaid
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img alt="User Journey Diagram" src="img/gray-user-journey.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Journey> -->
|
||||
|
||||
### Release
|
||||
|
||||
For those who have the permission to do so:
|
||||
|
||||
Update version number in `package.json`.
|
||||
|
||||
```sh
|
||||
npm publish
|
||||
```
|
||||
|
||||
The above command generates files into the `dist` folder and publishes them to npmjs.org.
|
||||
</table>
|
||||
|
||||
## Related projects
|
||||
|
||||
@@ -220,27 +204,16 @@ The above command generates files into the `dist` folder and publishes them to n
|
||||
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
||||
- [HTTP Server](https://github.com/TomWright/mermaid-server)
|
||||
|
||||
## Contributors [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||
## Contributors [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+wanted%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||
|
||||
Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
|
||||
|
||||
Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
|
||||
|
||||
## Security and safe diagrams
|
||||
|
||||
For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitise the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
|
||||
|
||||
As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing javascript in the code from being executed. This is a great step forward for better security.
|
||||
|
||||
*Unfortunately you can not have a cake and eat it at the same time which in this case means that some of the interactive functionality gets blocked along with the possible malicious code.*
|
||||
|
||||
## Reporting vulnerabilities
|
||||
To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue.
|
||||
|
||||
## Appreciation
|
||||
A quick note from Knut Sveidqvist:
|
||||
>*Many thanks to the [d3](https://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!*
|
||||
>*Thanks also to the [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.*
|
||||
>*Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!*
|
||||
>*Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.*
|
||||
>*Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017.*
|
||||
>
|
||||
>*Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!*
|
||||
|
275
README.zh-CN.md
275
README.zh-CN.md
@@ -1,4 +1,4 @@
|
||||
# mermaid [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
# mermaid [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [](https://percy.io/Mermaid/mermaid)
|
||||
|
||||
[English](./README.md) | 简体中文
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
<!-- <Main description> -->
|
||||
Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。Mermaid 诞生的主要目的是让文档的更新能够及时跟上开发进度。
|
||||
|
||||
> Doc-Rot 是 Mermaid 致力于解决的一个难题。
|
||||
> Mermaid 致力于解决 Doc-Rot 这个令人头疼的问题。
|
||||
|
||||
绘图和编写文档花费了开发者宝贵的开发时间,而且随着业务的变更,它很快就会过期。 但是如果缺少了图表或文档,对于生产力和团队新人的业务学习都会产生巨大的阻碍。 <br/>
|
||||
Mermaid 通过允许用户创建便于修改的图表来解决这一难题,它也可以作为生产脚本(或其他代码)的一部分。<br/>
|
||||
<br/>
|
||||
Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/) 轻松创建详细的图表。<br/>
|
||||
你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
|
||||
Mermaid 通过减少创建可修改的图表所需要的时间、精力和工具来解决这一难题,从而提高了内容的智能化和可重用性。 作为一个基于文本的绘图工具, Mermaid 天生就易于维护和更新,它也可以作为生产脚本(或其他代码)的一部分,使得文档编写变得更加简单。 有了它之后,开发者可以从维护文档这个与开发割离且麻烦的任务中解放出来。 <br/>
|
||||
即使是从未接触过编程的非专业人员也可以通过 [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/)来创建图表。<br/>
|
||||
你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程。
|
||||
U也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
|
||||
|
||||
如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md) and [用法](./docs/usage.md).
|
||||
|
||||
@@ -31,30 +31,33 @@ Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://merma
|
||||
|
||||
## 示例
|
||||
|
||||
__下面是一些可以使用 Mermaid 创建的图表示例。点击 [语法](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference) 查看详情。__
|
||||
__下面是一些使用 Mermaid 和类 Markdown 语法创建的图表示例。点击 [语法](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference) 查看详情__
|
||||
<table>
|
||||
<!-- <Flowchart> -->
|
||||
|
||||
## 流程图 [<a href="https://mermaid-js.github.io/mermaid/#/flowchart">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
|
||||
```
|
||||
flowchart LR
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>流程图</b></br>
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/flowchart">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
graph TD
|
||||
A[Hard] -->|Text| B(Round)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result 1]
|
||||
C -->|Two| E[Result 2]
|
||||
```
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Hard] -->|Text| B(Round)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result 1]
|
||||
C -->|Two| E[Result 2]
|
||||
```
|
||||
|
||||
## 时序图 [<a href="https://mermaid-js.github.io/mermaid/#/sequenceDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-flow.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Flowchart> -->
|
||||
<!-- <Sequence> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>时序图</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/sequenceDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
@@ -64,48 +67,43 @@ Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
|
||||
## 甘特图 [<a href="https://mermaid-js.github.io/mermaid/#/gantt">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-sequence.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Sequence> -->
|
||||
<!-- <Gantt> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>甘特图</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/gantt">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
gantt
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
```
|
||||
```mermaid
|
||||
gantt
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
```
|
||||
|
||||
## 类图 [<a href="https://mermaid-js.github.io/mermaid/#/classDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
|
||||
```
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-gantt.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Gantt> -->
|
||||
<!-- <Class> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>类图</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/classDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<Interface>> Class01
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
@@ -115,33 +113,23 @@ Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
class Class10 {
|
||||
<<service>>
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
```
|
||||
```mermaid
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<Interface>> Class01
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
```
|
||||
|
||||
## 状态图 [<a href="https://mermaid-js.github.io/mermaid/#/stateDiagram">文档</a> - <a href="https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-class.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Class> -->
|
||||
<!-- <State> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>状态图</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/stateDiagram">文档</a> - <a href="https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
@@ -149,37 +137,46 @@ Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
|
||||
## 饼图 [<a href="https://mermaid-js.github.io/mermaid/#/pie">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-state.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </State> -->
|
||||
<!-- <Pie> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>饼图</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/pie">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
pie
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
```
|
||||
```mermaid
|
||||
pie
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
```
|
||||
|
||||
## Git图 [实验特性 - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
|
||||
## 用户体验旅程图 [<a href="https://mermaid-js.github.io/mermaid/#/user-journey">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-pie.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Pie> -->
|
||||
<!-- <Git> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Git图</b><br />
|
||||
[实验特性 - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td colspan="2" align="center"><i>敬请期待!</i></td>
|
||||
</tr>
|
||||
<!-- </Git> -->
|
||||
<!-- <Journey> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>用户体验旅程图</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/user-journey">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
@@ -189,30 +186,14 @@ pie
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
```
|
||||
```mermaid
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
```
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img alt="User Journey Diagram" src="img/gray-user-journey.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Journey> -->
|
||||
|
||||
### 发布
|
||||
|
||||
对于有权限的同学来说,你可以通过以下步骤来完成发布操作:
|
||||
|
||||
更新 `package.json` 中的版本号,然后执行如下命令:
|
||||
|
||||
```sh
|
||||
npm publish
|
||||
```
|
||||
|
||||
以上的命令会将文件打包到 `dist` 目录并发布至 npmjs.org.
|
||||
</table>
|
||||
|
||||
## 相关项目
|
||||
|
||||
@@ -220,28 +201,16 @@ npm publish
|
||||
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
||||
- [HTTP Server](https://github.com/TomWright/mermaid-server)
|
||||
|
||||
## 贡献者 [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||
## 贡献者 [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+wanted%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||
|
||||
Mermaid 是一个不断发展中的社区,并且还在接收新的贡献者。有很多不同的方式可以参与进来,而且我们还在寻找额外的帮助。如果你想知道如何开始贡献,请查看 [这个 issue](https://github.com/mermaid-js/mermaid/issues/866)。
|
||||
|
||||
关于如何贡献的详细信息可以在 [贡献指南](CONTRIBUTING.md) 中找到。
|
||||
|
||||
## 安全
|
||||
|
||||
对于公开网站来说,从互联网上的用户处检索文本、存储供后续在浏览器中展示的内容可能是不安全的,理由是用户的内容可能嵌入一些数据加载完成之后就会运行的恶意脚本,这些对于 Mermaid 来说毫无疑问是一个风险,尤其是 mermaid 图表还包含了许多在 html 中使用的字符,这意味着我们难以使用常规的手段来过滤不安全代码,因为这些常规手段会造成图表损坏。我们仍然在努力对获取到的代码进行安全过滤并不断完善我们的程序,但很难保证没有漏洞。
|
||||
|
||||
作为拥有外部用户的网站的额外安全级别,我们很高兴推出一个新的安全级别,其中的图表在沙盒 iframe 中渲染,防止代码中的 javascript 被执行,这是在安全性方面迈出的一大步。
|
||||
|
||||
*很不幸的是,鱼与熊掌不可兼得,在这个场景下它意味着在可能的恶意代码被阻止时,也会损失部分交互能力*。
|
||||
|
||||
## 报告漏洞
|
||||
|
||||
如果想要报告漏洞,请发送邮件到 security@mermaid.live, 并附上问题的描述、复现问题的步骤、受影响的版本,以及解决问题的方案(如果有的话)。
|
||||
|
||||
## 鸣谢
|
||||
来自 Knut Sveidqvist:
|
||||
>*特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库! *
|
||||
>*同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。*
|
||||
>*特别感谢 [d3](http://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库! *
|
||||
>*同样感谢 [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。*
|
||||
>*感谢 [Tyler Long](https://github.com/tylerlong) 从 2017年四月开始成为了项目的合作者。*
|
||||
>
|
||||
>*感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!*
|
||||
|
@@ -1,3 +1,3 @@
|
||||
export const curveBasis = 'basis';
|
||||
export const curveLinear = 'linear';
|
||||
export const curveCardinal = 'cardinal';
|
||||
export const curveBasis = 'basis'
|
||||
export const curveLinear = 'linear'
|
||||
export const curveCardinal = 'cardinal'
|
||||
|
71
__mocks__/d3.js
vendored
71
__mocks__/d3.js
vendored
@@ -1,10 +1,11 @@
|
||||
/* eslint-env jest */
|
||||
let NewD3 = function () {
|
||||
function returnThis() {
|
||||
return this;
|
||||
function returnThis () {
|
||||
return this
|
||||
}
|
||||
return {
|
||||
append: function () {
|
||||
return NewD3();
|
||||
return NewD3()
|
||||
},
|
||||
lower: returnThis,
|
||||
attr: returnThis,
|
||||
@@ -15,47 +16,41 @@ let NewD3 = function () {
|
||||
getBBox: function () {
|
||||
return {
|
||||
height: 10,
|
||||
width: 20,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
width: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const select = function () {
|
||||
return new NewD3();
|
||||
};
|
||||
return new NewD3()
|
||||
}
|
||||
|
||||
export const selectAll = function () {
|
||||
return new NewD3();
|
||||
};
|
||||
return new NewD3()
|
||||
}
|
||||
|
||||
export const curveBasis = 'basis';
|
||||
export const curveLinear = 'linear';
|
||||
export const curveCardinal = 'cardinal';
|
||||
export const curveBasis = 'basis'
|
||||
export const curveLinear = 'linear'
|
||||
export const curveCardinal = 'cardinal'
|
||||
|
||||
export const MockD3 = (name, parent) => {
|
||||
const children = [];
|
||||
const children = []
|
||||
const elem = {
|
||||
get __children() {
|
||||
return children;
|
||||
},
|
||||
get __name() {
|
||||
return name;
|
||||
},
|
||||
get __parent() {
|
||||
return parent;
|
||||
},
|
||||
};
|
||||
get __children () { return children },
|
||||
get __name () { return name },
|
||||
get __parent () { return parent }
|
||||
}
|
||||
elem.append = (name) => {
|
||||
const mockElem = MockD3(name, elem);
|
||||
children.push(mockElem);
|
||||
return mockElem;
|
||||
};
|
||||
elem.lower = jest.fn(() => elem);
|
||||
elem.attr = jest.fn(() => elem);
|
||||
elem.text = jest.fn(() => elem);
|
||||
elem.style = jest.fn(() => elem);
|
||||
return elem;
|
||||
};
|
||||
const mockElem = MockD3(name, elem)
|
||||
children.push(mockElem)
|
||||
return mockElem
|
||||
}
|
||||
elem.lower = jest.fn(() => elem)
|
||||
elem.attr = jest.fn(() => elem)
|
||||
elem.text = jest.fn(() => elem)
|
||||
elem.style = jest.fn(() => elem)
|
||||
return elem
|
||||
}
|
||||
|
@@ -1,3 +1 @@
|
||||
{
|
||||
"video": false
|
||||
}
|
||||
{ "video": false }
|
||||
|
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"cypress/globals": true
|
||||
},
|
||||
"extends": ["plugin:cypress/recommended"],
|
||||
"plugins": ["cypress"],
|
||||
"rules":{
|
||||
"cypress/no-unnecessary-waiting": 0
|
||||
}
|
||||
}
|
@@ -2,16 +2,15 @@
|
||||
|
||||
context('Actions', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/actions');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/actions')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/interacting-with-elements
|
||||
|
||||
it('.type() - type into a DOM element', () => {
|
||||
// https://on.cypress.io/type
|
||||
cy.get('.action-email')
|
||||
.type('fake@email.com')
|
||||
.should('have.value', 'fake@email.com')
|
||||
.type('fake@email.com').should('have.value', 'fake@email.com')
|
||||
|
||||
// .type() with special character sequences
|
||||
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
|
||||
@@ -25,52 +24,48 @@ context('Actions', () => {
|
||||
|
||||
// Delay each keypress by 0.1 sec
|
||||
.type('slow.typing@email.com', { delay: 100 })
|
||||
.should('have.value', 'slow.typing@email.com');
|
||||
.should('have.value', 'slow.typing@email.com')
|
||||
|
||||
cy.get('.action-disabled')
|
||||
// Ignore error checking prior to type
|
||||
// like whether the input is visible or disabled
|
||||
.type('disabled error checking', { force: true })
|
||||
.should('have.value', 'disabled error checking');
|
||||
});
|
||||
.should('have.value', 'disabled error checking')
|
||||
})
|
||||
|
||||
it('.focus() - focus on a DOM element', () => {
|
||||
// https://on.cypress.io/focus
|
||||
cy.get('.action-focus')
|
||||
.focus()
|
||||
cy.get('.action-focus').focus()
|
||||
.should('have.class', 'focus')
|
||||
.prev()
|
||||
.should('have.attr', 'style', 'color: orange;');
|
||||
});
|
||||
.prev().should('have.attr', 'style', 'color: orange;')
|
||||
})
|
||||
|
||||
it('.blur() - blur off a DOM element', () => {
|
||||
// https://on.cypress.io/blur
|
||||
cy.get('.action-blur')
|
||||
.type('About to blur')
|
||||
.blur()
|
||||
cy.get('.action-blur').type('About to blur').blur()
|
||||
.should('have.class', 'error')
|
||||
.prev()
|
||||
.should('have.attr', 'style', 'color: red;');
|
||||
});
|
||||
.prev().should('have.attr', 'style', 'color: red;')
|
||||
})
|
||||
|
||||
it('.clear() - clears an input or textarea element', () => {
|
||||
// https://on.cypress.io/clear
|
||||
cy.get('.action-clear')
|
||||
.type('Clear this text')
|
||||
cy.get('.action-clear').type('Clear this text')
|
||||
.should('have.value', 'Clear this text')
|
||||
.clear()
|
||||
.should('have.value', '');
|
||||
});
|
||||
.should('have.value', '')
|
||||
})
|
||||
|
||||
it('.submit() - submit a form', () => {
|
||||
// https://on.cypress.io/submit
|
||||
cy.get('.action-form').find('[type="text"]').type('HALFOFF');
|
||||
cy.get('.action-form').submit().next().should('contain', 'Your form has been submitted!');
|
||||
});
|
||||
cy.get('.action-form')
|
||||
.find('[type="text"]').type('HALFOFF')
|
||||
cy.get('.action-form').submit()
|
||||
.next().should('contain', 'Your form has been submitted!')
|
||||
})
|
||||
|
||||
it('.click() - click on a DOM element', () => {
|
||||
// https://on.cypress.io/click
|
||||
cy.get('.action-btn').click();
|
||||
cy.get('.action-btn').click()
|
||||
|
||||
// You can click on 9 specific positions of an element:
|
||||
// -----------------------------------
|
||||
@@ -86,16 +81,16 @@ context('Actions', () => {
|
||||
// -----------------------------------
|
||||
|
||||
// clicking in the center of the element is the default
|
||||
cy.get('#action-canvas').click();
|
||||
cy.get('#action-canvas').click()
|
||||
|
||||
cy.get('#action-canvas').click('topLeft');
|
||||
cy.get('#action-canvas').click('top');
|
||||
cy.get('#action-canvas').click('topRight');
|
||||
cy.get('#action-canvas').click('left');
|
||||
cy.get('#action-canvas').click('right');
|
||||
cy.get('#action-canvas').click('bottomLeft');
|
||||
cy.get('#action-canvas').click('bottom');
|
||||
cy.get('#action-canvas').click('bottomRight');
|
||||
cy.get('#action-canvas').click('topLeft')
|
||||
cy.get('#action-canvas').click('top')
|
||||
cy.get('#action-canvas').click('topRight')
|
||||
cy.get('#action-canvas').click('left')
|
||||
cy.get('#action-canvas').click('right')
|
||||
cy.get('#action-canvas').click('bottomLeft')
|
||||
cy.get('#action-canvas').click('bottom')
|
||||
cy.get('#action-canvas').click('bottomRight')
|
||||
|
||||
// .click() accepts an x and y coordinate
|
||||
// that controls where the click occurs :)
|
||||
@@ -107,83 +102,90 @@ context('Actions', () => {
|
||||
.click(100, 185)
|
||||
.click(125, 190)
|
||||
.click(150, 185)
|
||||
.click(170, 165);
|
||||
.click(170, 165)
|
||||
|
||||
// click multiple elements by passing multiple: true
|
||||
cy.get('.action-labels>.label').click({ multiple: true });
|
||||
cy.get('.action-labels>.label').click({ multiple: true })
|
||||
|
||||
// Ignore error checking prior to clicking
|
||||
cy.get('.action-opacity>.btn').click({ force: true });
|
||||
});
|
||||
cy.get('.action-opacity>.btn').click({ force: true })
|
||||
})
|
||||
|
||||
it('.dblclick() - double click on a DOM element', () => {
|
||||
// https://on.cypress.io/dblclick
|
||||
|
||||
// Our app has a listener on 'dblclick' event in our 'scripts.js'
|
||||
// that hides the div and shows an input on double click
|
||||
cy.get('.action-div').dblclick().should('not.be.visible');
|
||||
cy.get('.action-input-hidden').should('be.visible');
|
||||
});
|
||||
cy.get('.action-div').dblclick().should('not.be.visible')
|
||||
cy.get('.action-input-hidden').should('be.visible')
|
||||
})
|
||||
|
||||
it('.check() - check a checkbox or radio element', () => {
|
||||
// https://on.cypress.io/check
|
||||
|
||||
// By default, .check() will check all
|
||||
// matching checkbox or radio elements in succession, one after another
|
||||
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]').check().should('be.checked');
|
||||
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
|
||||
.check().should('be.checked')
|
||||
|
||||
cy.get('.action-radios [type="radio"]').not('[disabled]').check().should('be.checked');
|
||||
cy.get('.action-radios [type="radio"]').not('[disabled]')
|
||||
.check().should('be.checked')
|
||||
|
||||
// .check() accepts a value argument
|
||||
cy.get('.action-radios [type="radio"]').check('radio1').should('be.checked');
|
||||
cy.get('.action-radios [type="radio"]')
|
||||
.check('radio1').should('be.checked')
|
||||
|
||||
// .check() accepts an array of values
|
||||
cy.get('.action-multiple-checkboxes [type="checkbox"]')
|
||||
.check(['checkbox1', 'checkbox2'])
|
||||
.should('be.checked');
|
||||
.check(['checkbox1', 'checkbox2']).should('be.checked')
|
||||
|
||||
// Ignore error checking prior to checking
|
||||
cy.get('.action-checkboxes [disabled]').check({ force: true }).should('be.checked');
|
||||
cy.get('.action-checkboxes [disabled]')
|
||||
.check({ force: true }).should('be.checked')
|
||||
|
||||
cy.get('.action-radios [type="radio"]').check('radio3', { force: true }).should('be.checked');
|
||||
});
|
||||
cy.get('.action-radios [type="radio"]')
|
||||
.check('radio3', { force: true }).should('be.checked')
|
||||
})
|
||||
|
||||
it('.uncheck() - uncheck a checkbox element', () => {
|
||||
// https://on.cypress.io/uncheck
|
||||
|
||||
// By default, .uncheck() will uncheck all matching
|
||||
// checkbox elements in succession, one after another
|
||||
cy.get('.action-check [type="checkbox"]').not('[disabled]').uncheck().should('not.be.checked');
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.not('[disabled]')
|
||||
.uncheck().should('not.be.checked')
|
||||
|
||||
// .uncheck() accepts a value argument
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.check('checkbox1')
|
||||
.uncheck('checkbox1')
|
||||
.should('not.be.checked');
|
||||
.uncheck('checkbox1').should('not.be.checked')
|
||||
|
||||
// .uncheck() accepts an array of values
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.check(['checkbox1', 'checkbox3'])
|
||||
.uncheck(['checkbox1', 'checkbox3'])
|
||||
.should('not.be.checked');
|
||||
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
|
||||
|
||||
// Ignore error checking prior to unchecking
|
||||
cy.get('.action-check [disabled]').uncheck({ force: true }).should('not.be.checked');
|
||||
});
|
||||
cy.get('.action-check [disabled]')
|
||||
.uncheck({ force: true }).should('not.be.checked')
|
||||
})
|
||||
|
||||
it('.select() - select an option in a <select> element', () => {
|
||||
// https://on.cypress.io/select
|
||||
|
||||
// Select option(s) with matching text content
|
||||
cy.get('.action-select').select('apples');
|
||||
cy.get('.action-select').select('apples')
|
||||
|
||||
cy.get('.action-select-multiple').select(['apples', 'oranges', 'bananas']);
|
||||
cy.get('.action-select-multiple')
|
||||
.select(['apples', 'oranges', 'bananas'])
|
||||
|
||||
// Select option(s) with matching value
|
||||
cy.get('.action-select').select('fr-bananas');
|
||||
cy.get('.action-select').select('fr-bananas')
|
||||
|
||||
cy.get('.action-select-multiple').select(['fr-apples', 'fr-oranges', 'fr-bananas']);
|
||||
});
|
||||
cy.get('.action-select-multiple')
|
||||
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
|
||||
})
|
||||
|
||||
it('.scrollIntoView() - scroll an element into view', () => {
|
||||
// https://on.cypress.io/scrollintoview
|
||||
@@ -192,21 +194,27 @@ context('Actions', () => {
|
||||
// because they're not within
|
||||
// the viewable area of their parent
|
||||
// (we need to scroll to see them)
|
||||
cy.get('#scroll-horizontal button').should('not.be.visible');
|
||||
cy.get('#scroll-horizontal button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// scroll the button into view, as if the user had scrolled
|
||||
cy.get('#scroll-horizontal button').scrollIntoView().should('be.visible');
|
||||
cy.get('#scroll-horizontal button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
|
||||
cy.get('#scroll-vertical button').should('not.be.visible');
|
||||
cy.get('#scroll-vertical button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// Cypress handles the scroll direction needed
|
||||
cy.get('#scroll-vertical button').scrollIntoView().should('be.visible');
|
||||
cy.get('#scroll-vertical button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
|
||||
cy.get('#scroll-both button').should('not.be.visible');
|
||||
cy.get('#scroll-both button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// Cypress knows to scroll to the right and down
|
||||
cy.get('#scroll-both button').scrollIntoView().should('be.visible');
|
||||
});
|
||||
cy.get('#scroll-both button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('.trigger() - trigger an event on a DOM element', () => {
|
||||
// https://on.cypress.io/trigger
|
||||
@@ -220,12 +228,12 @@ context('Actions', () => {
|
||||
cy.get('.trigger-input-range')
|
||||
.invoke('val', 25)
|
||||
.trigger('change')
|
||||
.get('input[type=range]')
|
||||
.siblings('p')
|
||||
.should('have.text', '25');
|
||||
});
|
||||
.get('input[type=range]').siblings('p')
|
||||
.should('have.text', '25')
|
||||
})
|
||||
|
||||
it('cy.scrollTo() - scroll the window or element to a position', () => {
|
||||
|
||||
// https://on.cypress.io/scrollTo
|
||||
|
||||
// You can scroll to 9 specific positions of an element:
|
||||
@@ -243,22 +251,22 @@ context('Actions', () => {
|
||||
|
||||
// if you chain .scrollTo() off of cy, we will
|
||||
// scroll the entire window
|
||||
cy.scrollTo('bottom');
|
||||
cy.scrollTo('bottom')
|
||||
|
||||
cy.get('#scrollable-horizontal').scrollTo('right');
|
||||
cy.get('#scrollable-horizontal').scrollTo('right')
|
||||
|
||||
// or you can scroll to a specific coordinate:
|
||||
// (x axis, y axis) in pixels
|
||||
cy.get('#scrollable-vertical').scrollTo(250, 250);
|
||||
cy.get('#scrollable-vertical').scrollTo(250, 250)
|
||||
|
||||
// or you can scroll to a specific percentage
|
||||
// of the (width, height) of the element
|
||||
cy.get('#scrollable-both').scrollTo('75%', '25%');
|
||||
cy.get('#scrollable-both').scrollTo('75%', '25%')
|
||||
|
||||
// control the easing of the scroll (default is 'swing')
|
||||
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' });
|
||||
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
|
||||
|
||||
// control the duration of the scroll (in ms)
|
||||
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 });
|
||||
});
|
||||
});
|
||||
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
|
||||
})
|
||||
})
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
context('Aliasing', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/aliasing');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/aliasing')
|
||||
})
|
||||
|
||||
it('.as() - alias a DOM element for later use', () => {
|
||||
// https://on.cypress.io/as
|
||||
@@ -12,25 +12,31 @@ context('Aliasing', () => {
|
||||
// We don't have to traverse to the element
|
||||
// later in our code, we reference it with @
|
||||
|
||||
cy.get('.as-table').find('tbody>tr').first().find('td').first().find('button').as('firstBtn');
|
||||
cy.get('.as-table').find('tbody>tr')
|
||||
.first().find('td').first()
|
||||
.find('button').as('firstBtn')
|
||||
|
||||
// when we reference the alias, we place an
|
||||
// @ in front of its name
|
||||
cy.get('@firstBtn').click();
|
||||
cy.get('@firstBtn').click()
|
||||
|
||||
cy.get('@firstBtn').should('have.class', 'btn-success').and('contain', 'Changed');
|
||||
});
|
||||
cy.get('@firstBtn')
|
||||
.should('have.class', 'btn-success')
|
||||
.and('contain', 'Changed')
|
||||
})
|
||||
|
||||
it('.as() - alias a route for later use', () => {
|
||||
|
||||
// Alias the route to wait for its response
|
||||
cy.server();
|
||||
cy.route('GET', 'comments/*').as('getComment');
|
||||
cy.server()
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click();
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
cy.wait('@getComment').its('status').should('eq', 200);
|
||||
});
|
||||
});
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
|
||||
})
|
||||
})
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
context('Assertions', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/assertions');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/assertions')
|
||||
})
|
||||
|
||||
describe('Implicit Assertions', () => {
|
||||
it('.should() - make an assertion about the current subject', () => {
|
||||
@@ -23,7 +23,7 @@ context('Assertions', () => {
|
||||
// first need to invoke jQuery method text()
|
||||
// and then match using regular expression
|
||||
.invoke('text')
|
||||
.should('match', /column content/i);
|
||||
.should('match', /column content/i)
|
||||
|
||||
// a better way to check element's text content against a regular expression
|
||||
// is to use "cy.contains"
|
||||
@@ -32,33 +32,33 @@ context('Assertions', () => {
|
||||
.find('tbody tr:last')
|
||||
// finds first <td> element with text content matching regular expression
|
||||
.contains('td', /column content/i)
|
||||
.should('be.visible');
|
||||
.should('be.visible')
|
||||
|
||||
// for more information about asserting element's text
|
||||
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
|
||||
});
|
||||
})
|
||||
|
||||
it('.and() - chain multiple assertions together', () => {
|
||||
// https://on.cypress.io/and
|
||||
cy.get('.assertions-link')
|
||||
.should('have.class', 'active')
|
||||
.and('have.attr', 'href')
|
||||
.and('include', 'cypress.io');
|
||||
});
|
||||
});
|
||||
.and('include', 'cypress.io')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Explicit Assertions', () => {
|
||||
// https://on.cypress.io/assertions
|
||||
it('expect - make an assertion about a specified subject', () => {
|
||||
// We can use Chai's BDD style assertions
|
||||
expect(true).to.be.true;
|
||||
const o = { foo: 'bar' };
|
||||
expect(true).to.be.true
|
||||
const o = { foo: 'bar' }
|
||||
|
||||
expect(o).to.equal(o);
|
||||
expect(o).to.deep.equal({ foo: 'bar' });
|
||||
expect(o).to.equal(o)
|
||||
expect(o).to.deep.equal({ foo: 'bar' })
|
||||
// matching text using regular expression
|
||||
expect('FooBar').to.match(/bar$/i);
|
||||
});
|
||||
expect('FooBar').to.match(/bar$/i)
|
||||
})
|
||||
|
||||
it('pass your own callback function to should()', () => {
|
||||
// Pass a function to should that can have any number
|
||||
@@ -71,14 +71,14 @@ context('Assertions', () => {
|
||||
// https://on.cypress.io/$
|
||||
// return an array of texts from all of the p's
|
||||
// @ts-ignore TS6133 unused variable
|
||||
const texts = $p.map((i, el) => Cypress.$(el).text());
|
||||
const texts = $p.map((i, el) => Cypress.$(el).text())
|
||||
|
||||
// jquery map returns jquery object
|
||||
// and .get() convert this to simple array
|
||||
const paragraphs = texts.get();
|
||||
const paragraphs = texts.get()
|
||||
|
||||
// array should have length of 3
|
||||
expect(paragraphs, 'has 3 paragraphs').to.have.length(3);
|
||||
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
|
||||
|
||||
// use second argument to expect(...) to provide clear
|
||||
// message with each assertion
|
||||
@@ -86,27 +86,27 @@ context('Assertions', () => {
|
||||
'Some text from first p',
|
||||
'More text from second p',
|
||||
'And even more text from third p',
|
||||
]);
|
||||
});
|
||||
});
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
it('finds element by class name regex', () => {
|
||||
cy.get('.docs-header')
|
||||
.find('div')
|
||||
// .should(cb) callback function will be retried
|
||||
.should(($div) => {
|
||||
expect($div).to.have.length(1);
|
||||
expect($div).to.have.length(1)
|
||||
|
||||
const className = $div[0].className;
|
||||
const className = $div[0].className
|
||||
|
||||
expect(className).to.match(/heading-/);
|
||||
expect(className).to.match(/heading-/)
|
||||
})
|
||||
// .then(cb) callback is not retried,
|
||||
// it either passes or fails
|
||||
.then(($div) => {
|
||||
expect($div, 'text content').to.have.text('Introduction');
|
||||
});
|
||||
});
|
||||
expect($div, 'text content').to.have.text('Introduction')
|
||||
})
|
||||
})
|
||||
|
||||
it('can throw any error', () => {
|
||||
cy.get('.docs-header')
|
||||
@@ -114,56 +114,55 @@ context('Assertions', () => {
|
||||
.should(($div) => {
|
||||
if ($div.length !== 1) {
|
||||
// you can throw your own errors
|
||||
throw new Error('Did not find 1 element');
|
||||
throw new Error('Did not find 1 element')
|
||||
}
|
||||
|
||||
const className = $div[0].className;
|
||||
const className = $div[0].className
|
||||
|
||||
if (!className.match(/heading-/)) {
|
||||
throw new Error(`Could not find class "heading-" in ${className}`);
|
||||
throw new Error(`Could not find class "heading-" in ${className}`)
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
it('matches unknown text between two elements', () => {
|
||||
/**
|
||||
* Text from the first element.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
let text;
|
||||
*/
|
||||
let text
|
||||
|
||||
/**
|
||||
* Normalizes passed text, useful before comparing text with spaces and different capitalization.
|
||||
*
|
||||
* Normalizes passed text,
|
||||
* useful before comparing text with spaces and different capitalization.
|
||||
* @param {string} s Text to normalize
|
||||
*/
|
||||
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase();
|
||||
*/
|
||||
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
|
||||
|
||||
cy.get('.two-elements')
|
||||
.find('.first')
|
||||
.then(($first) => {
|
||||
// save text from the first element
|
||||
text = normalizeText($first.text());
|
||||
});
|
||||
text = normalizeText($first.text())
|
||||
})
|
||||
|
||||
cy.get('.two-elements')
|
||||
.find('.second')
|
||||
.should(($div) => {
|
||||
// we can massage text before comparing
|
||||
const secondText = normalizeText($div.text());
|
||||
const secondText = normalizeText($div.text())
|
||||
|
||||
expect(secondText, 'second text').to.equal(text);
|
||||
});
|
||||
});
|
||||
expect(secondText, 'second text').to.equal(text)
|
||||
})
|
||||
})
|
||||
|
||||
it('assert - assert shape of an object', () => {
|
||||
const person = {
|
||||
name: 'Joe',
|
||||
age: 20,
|
||||
};
|
||||
}
|
||||
|
||||
assert.isObject(person, 'value is object');
|
||||
});
|
||||
});
|
||||
});
|
||||
assert.isObject(person, 'value is object')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -2,54 +2,55 @@
|
||||
|
||||
context('Connectors', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/connectors');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/connectors')
|
||||
})
|
||||
|
||||
it('.each() - iterate over an array of elements', () => {
|
||||
// https://on.cypress.io/each
|
||||
cy.get('.connectors-each-ul>li').each(($el, index, $list) => {
|
||||
console.log($el, index, $list);
|
||||
});
|
||||
});
|
||||
cy.get('.connectors-each-ul>li')
|
||||
.each(($el, index, $list) => {
|
||||
console.log($el, index, $list)
|
||||
})
|
||||
})
|
||||
|
||||
it('.its() - get properties on the current subject', () => {
|
||||
// https://on.cypress.io/its
|
||||
cy.get('.connectors-its-ul>li')
|
||||
// calls the 'length' property yielding that value
|
||||
.its('length')
|
||||
.should('be.gt', 2);
|
||||
});
|
||||
.should('be.gt', 2)
|
||||
})
|
||||
|
||||
it('.invoke() - invoke a function on the current subject', () => {
|
||||
// our div is hidden in our script.js
|
||||
// $('.connectors-div').hide()
|
||||
|
||||
// https://on.cypress.io/invoke
|
||||
cy.get('.connectors-div')
|
||||
.should('be.hidden')
|
||||
cy.get('.connectors-div').should('be.hidden')
|
||||
// call the jquery method 'show' on the 'div.container'
|
||||
.invoke('show')
|
||||
.should('be.visible');
|
||||
});
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('.spread() - spread an array as individual args to callback function', () => {
|
||||
// https://on.cypress.io/spread
|
||||
const arr = ['foo', 'bar', 'baz'];
|
||||
const arr = ['foo', 'bar', 'baz']
|
||||
|
||||
cy.wrap(arr).spread((foo, bar, baz) => {
|
||||
expect(foo).to.eq('foo');
|
||||
expect(bar).to.eq('bar');
|
||||
expect(baz).to.eq('baz');
|
||||
});
|
||||
});
|
||||
expect(foo).to.eq('foo')
|
||||
expect(bar).to.eq('bar')
|
||||
expect(baz).to.eq('baz')
|
||||
})
|
||||
})
|
||||
|
||||
it('.then() - invoke a callback function with the current subject', () => {
|
||||
// https://on.cypress.io/then
|
||||
cy.get('.connectors-list > li').then(($lis) => {
|
||||
expect($lis, '3 items').to.have.length(3);
|
||||
expect($lis.eq(0), 'first item').to.contain('Walk the dog');
|
||||
expect($lis.eq(1), 'second item').to.contain('Feed the cat');
|
||||
expect($lis.eq(2), 'third item').to.contain('Write JavaScript');
|
||||
});
|
||||
});
|
||||
});
|
||||
cy.get('.connectors-list > li')
|
||||
.then(($lis) => {
|
||||
expect($lis, '3 items').to.have.length(3)
|
||||
expect($lis.eq(0), 'first item').to.contain('Walk the dog')
|
||||
expect($lis.eq(1), 'second item').to.contain('Feed the cat')
|
||||
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -2,78 +2,77 @@
|
||||
|
||||
context('Cookies', () => {
|
||||
beforeEach(() => {
|
||||
Cypress.Cookies.debug(true);
|
||||
Cypress.Cookies.debug(true)
|
||||
|
||||
cy.visit('https://example.cypress.io/commands/cookies');
|
||||
cy.visit('https://example.cypress.io/commands/cookies')
|
||||
|
||||
// clear cookies again after visiting to remove
|
||||
// any 3rd party cookies picked up such as cloudflare
|
||||
cy.clearCookies();
|
||||
});
|
||||
cy.clearCookies()
|
||||
})
|
||||
|
||||
it('cy.getCookie() - get a browser cookie', () => {
|
||||
// https://on.cypress.io/getcookie
|
||||
cy.get('#getCookie .set-a-cookie').click();
|
||||
cy.get('#getCookie .set-a-cookie').click()
|
||||
|
||||
// cy.getCookie() yields a cookie object
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC');
|
||||
});
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
||||
})
|
||||
|
||||
it('cy.getCookies() - get browser cookies', () => {
|
||||
// https://on.cypress.io/getcookies
|
||||
cy.getCookies().should('be.empty');
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.get('#getCookies .set-a-cookie').click();
|
||||
cy.get('#getCookies .set-a-cookie').click()
|
||||
|
||||
// cy.getCookies() yields an array of cookies
|
||||
cy.getCookies()
|
||||
.should('have.length', 1)
|
||||
.should((cookies) => {
|
||||
// each cookie has these properties
|
||||
expect(cookies[0]).to.have.property('name', 'token');
|
||||
expect(cookies[0]).to.have.property('value', '123ABC');
|
||||
expect(cookies[0]).to.have.property('httpOnly', false);
|
||||
expect(cookies[0]).to.have.property('secure', false);
|
||||
expect(cookies[0]).to.have.property('domain');
|
||||
expect(cookies[0]).to.have.property('path');
|
||||
});
|
||||
});
|
||||
cy.getCookies().should('have.length', 1).should((cookies) => {
|
||||
|
||||
// each cookie has these properties
|
||||
expect(cookies[0]).to.have.property('name', 'token')
|
||||
expect(cookies[0]).to.have.property('value', '123ABC')
|
||||
expect(cookies[0]).to.have.property('httpOnly', false)
|
||||
expect(cookies[0]).to.have.property('secure', false)
|
||||
expect(cookies[0]).to.have.property('domain')
|
||||
expect(cookies[0]).to.have.property('path')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.setCookie() - set a browser cookie', () => {
|
||||
// https://on.cypress.io/setcookie
|
||||
cy.getCookies().should('be.empty');
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.setCookie('foo', 'bar');
|
||||
cy.setCookie('foo', 'bar')
|
||||
|
||||
// cy.getCookie() yields a cookie object
|
||||
cy.getCookie('foo').should('have.property', 'value', 'bar');
|
||||
});
|
||||
cy.getCookie('foo').should('have.property', 'value', 'bar')
|
||||
})
|
||||
|
||||
it('cy.clearCookie() - clear a browser cookie', () => {
|
||||
// https://on.cypress.io/clearcookie
|
||||
cy.getCookie('token').should('be.null');
|
||||
cy.getCookie('token').should('be.null')
|
||||
|
||||
cy.get('#clearCookie .set-a-cookie').click();
|
||||
cy.get('#clearCookie .set-a-cookie').click()
|
||||
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC');
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
||||
|
||||
// cy.clearCookies() yields null
|
||||
cy.clearCookie('token').should('be.null');
|
||||
cy.clearCookie('token').should('be.null')
|
||||
|
||||
cy.getCookie('token').should('be.null');
|
||||
});
|
||||
cy.getCookie('token').should('be.null')
|
||||
})
|
||||
|
||||
it('cy.clearCookies() - clear browser cookies', () => {
|
||||
// https://on.cypress.io/clearcookies
|
||||
cy.getCookies().should('be.empty');
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.get('#clearCookies .set-a-cookie').click();
|
||||
cy.get('#clearCookies .set-a-cookie').click()
|
||||
|
||||
cy.getCookies().should('have.length', 1);
|
||||
cy.getCookies().should('have.length', 1)
|
||||
|
||||
// cy.clearCookies() yields null
|
||||
cy.clearCookies();
|
||||
cy.clearCookies()
|
||||
|
||||
cy.getCookies().should('be.empty');
|
||||
});
|
||||
});
|
||||
cy.getCookies().should('be.empty')
|
||||
})
|
||||
})
|
||||
|
@@ -2,85 +2,81 @@
|
||||
|
||||
context('Cypress.Commands', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/custom-commands
|
||||
|
||||
it('.add() - create a custom command', () => {
|
||||
Cypress.Commands.add(
|
||||
'console',
|
||||
{
|
||||
prevSubject: true,
|
||||
},
|
||||
(subject, method) => {
|
||||
// the previous subject is automatically received
|
||||
// and the commands arguments are shifted
|
||||
Cypress.Commands.add('console', {
|
||||
prevSubject: true,
|
||||
}, (subject, method) => {
|
||||
// the previous subject is automatically received
|
||||
// and the commands arguments are shifted
|
||||
|
||||
// allow us to change the console method used
|
||||
method = method || 'log';
|
||||
// allow us to change the console method used
|
||||
method = method || 'log'
|
||||
|
||||
// log the subject to the console
|
||||
// @ts-ignore TS7017
|
||||
console[method]('The subject is', subject);
|
||||
// log the subject to the console
|
||||
// @ts-ignore TS7017
|
||||
console[method]('The subject is', subject)
|
||||
|
||||
// whatever we return becomes the new subject
|
||||
// we don't want to change the subject so
|
||||
// we return whatever was passed in
|
||||
return subject;
|
||||
}
|
||||
);
|
||||
// whatever we return becomes the new subject
|
||||
// we don't want to change the subject so
|
||||
// we return whatever was passed in
|
||||
return subject
|
||||
})
|
||||
|
||||
// @ts-ignore TS2339
|
||||
cy.get('button')
|
||||
.console('info')
|
||||
.then(($button) => {
|
||||
// subject is still $button
|
||||
});
|
||||
});
|
||||
});
|
||||
cy.get('button').console('info').then(($button) => {
|
||||
// subject is still $button
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.Cookies', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/cookies
|
||||
it('.debug() - enable or disable debugging', () => {
|
||||
Cypress.Cookies.debug(true);
|
||||
Cypress.Cookies.debug(true)
|
||||
|
||||
// Cypress will now log in the console when
|
||||
// cookies are set or cleared
|
||||
cy.setCookie('fakeCookie', '123ABC');
|
||||
cy.clearCookie('fakeCookie');
|
||||
cy.setCookie('fakeCookie', '123ABC');
|
||||
cy.clearCookie('fakeCookie');
|
||||
cy.setCookie('fakeCookie', '123ABC');
|
||||
});
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
cy.clearCookie('fakeCookie')
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
cy.clearCookie('fakeCookie')
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
})
|
||||
|
||||
it('.preserveOnce() - preserve cookies by key', () => {
|
||||
// normally cookies are reset after each test
|
||||
cy.getCookie('fakeCookie').should('not.be.ok');
|
||||
cy.getCookie('fakeCookie').should('not.be.ok')
|
||||
|
||||
// preserving a cookie will not clear it when
|
||||
// the next test starts
|
||||
cy.setCookie('lastCookie', '789XYZ');
|
||||
Cypress.Cookies.preserveOnce('lastCookie');
|
||||
});
|
||||
cy.setCookie('lastCookie', '789XYZ')
|
||||
Cypress.Cookies.preserveOnce('lastCookie')
|
||||
})
|
||||
|
||||
it('.defaults() - set defaults for all cookies', () => {
|
||||
// now any cookie with the name 'session_id' will
|
||||
// not be cleared before each new test runs
|
||||
Cypress.Cookies.defaults({
|
||||
whitelist: 'session_id',
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.Server', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// Permanently override server options for
|
||||
// all instances of cy.server()
|
||||
@@ -90,71 +86,71 @@ context('Cypress.Server', () => {
|
||||
Cypress.Server.defaults({
|
||||
delay: 0,
|
||||
force404: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.arch', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get CPU architecture name of underlying OS', () => {
|
||||
// https://on.cypress.io/arch
|
||||
expect(Cypress.arch).to.exist;
|
||||
});
|
||||
});
|
||||
expect(Cypress.arch).to.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.config()', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get and set configuration options', () => {
|
||||
// https://on.cypress.io/config
|
||||
let myConfig = Cypress.config();
|
||||
let myConfig = Cypress.config()
|
||||
|
||||
expect(myConfig).to.have.property('animationDistanceThreshold', 5);
|
||||
expect(myConfig).to.have.property('baseUrl', null);
|
||||
expect(myConfig).to.have.property('defaultCommandTimeout', 4000);
|
||||
expect(myConfig).to.have.property('requestTimeout', 5000);
|
||||
expect(myConfig).to.have.property('responseTimeout', 30000);
|
||||
expect(myConfig).to.have.property('viewportHeight', 660);
|
||||
expect(myConfig).to.have.property('viewportWidth', 1000);
|
||||
expect(myConfig).to.have.property('pageLoadTimeout', 60000);
|
||||
expect(myConfig).to.have.property('waitForAnimations', true);
|
||||
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
|
||||
expect(myConfig).to.have.property('baseUrl', null)
|
||||
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
|
||||
expect(myConfig).to.have.property('requestTimeout', 5000)
|
||||
expect(myConfig).to.have.property('responseTimeout', 30000)
|
||||
expect(myConfig).to.have.property('viewportHeight', 660)
|
||||
expect(myConfig).to.have.property('viewportWidth', 1000)
|
||||
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
|
||||
expect(myConfig).to.have.property('waitForAnimations', true)
|
||||
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(60000);
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
|
||||
|
||||
// this will change the config for the rest of your tests!
|
||||
Cypress.config('pageLoadTimeout', 20000);
|
||||
Cypress.config('pageLoadTimeout', 20000)
|
||||
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(20000);
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
|
||||
|
||||
Cypress.config('pageLoadTimeout', 60000);
|
||||
});
|
||||
});
|
||||
Cypress.config('pageLoadTimeout', 60000)
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.dom', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/dom
|
||||
it('.isHidden() - determine if a DOM element is hidden', () => {
|
||||
let hiddenP = Cypress.$('.dom-p p.hidden').get(0);
|
||||
let visibleP = Cypress.$('.dom-p p.visible').get(0);
|
||||
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
|
||||
let visibleP = Cypress.$('.dom-p p.visible').get(0)
|
||||
|
||||
// our first paragraph has css class 'hidden'
|
||||
expect(Cypress.dom.isHidden(hiddenP)).to.be.true;
|
||||
expect(Cypress.dom.isHidden(visibleP)).to.be.false;
|
||||
});
|
||||
});
|
||||
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
|
||||
expect(Cypress.dom.isHidden(visibleP)).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.env()', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// We can set environment variables for highly dynamic values
|
||||
|
||||
@@ -165,61 +161,62 @@ context('Cypress.env()', () => {
|
||||
Cypress.env({
|
||||
host: 'veronica.dev.local',
|
||||
api_server: 'http://localhost:8888/v1/',
|
||||
});
|
||||
})
|
||||
|
||||
// get environment variable
|
||||
expect(Cypress.env('host')).to.eq('veronica.dev.local');
|
||||
expect(Cypress.env('host')).to.eq('veronica.dev.local')
|
||||
|
||||
// set environment variable
|
||||
Cypress.env('api_server', 'http://localhost:8888/v2/');
|
||||
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/');
|
||||
Cypress.env('api_server', 'http://localhost:8888/v2/')
|
||||
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
|
||||
|
||||
// get all environment variable
|
||||
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local');
|
||||
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/');
|
||||
});
|
||||
});
|
||||
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
|
||||
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.log', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Control what is printed to the Command Log', () => {
|
||||
// https://on.cypress.io/cypress-log
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.platform', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get underlying OS name', () => {
|
||||
// https://on.cypress.io/platform
|
||||
expect(Cypress.platform).to.be.exist;
|
||||
});
|
||||
});
|
||||
expect(Cypress.platform).to.be.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.version', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get current version of Cypress being run', () => {
|
||||
// https://on.cypress.io/version
|
||||
expect(Cypress.version).to.be.exist;
|
||||
});
|
||||
});
|
||||
expect(Cypress.version).to.be.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.spec', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get current spec information', () => {
|
||||
// https://on.cypress.io/spec
|
||||
// wrap the object so we can inspect it easily by clicking in the command log
|
||||
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute']);
|
||||
});
|
||||
});
|
||||
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute'])
|
||||
})
|
||||
})
|
||||
|
@@ -3,18 +3,18 @@
|
||||
/// JSON fixture file can be loaded directly using
|
||||
// the built-in JavaScript bundler
|
||||
// @ts-ignore
|
||||
const requiredExample = require('../../fixtures/example');
|
||||
const requiredExample = require('../../fixtures/example')
|
||||
|
||||
context('Files', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/files');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/files')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
// load example.json fixture file and store
|
||||
// in the test context object
|
||||
cy.fixture('example.json').as('example');
|
||||
});
|
||||
cy.fixture('example.json').as('example')
|
||||
})
|
||||
|
||||
it('cy.fixture() - load a fixture', () => {
|
||||
// https://on.cypress.io/fixture
|
||||
@@ -22,58 +22,57 @@ context('Files', () => {
|
||||
// Instead of writing a response inline you can
|
||||
// use a fixture file's content.
|
||||
|
||||
cy.server();
|
||||
cy.fixture('example.json').as('comment');
|
||||
cy.server()
|
||||
cy.fixture('example.json').as('comment')
|
||||
// when application makes an Ajax request matching "GET comments/*"
|
||||
// Cypress will intercept it and reply with object
|
||||
// from the "comment" alias
|
||||
cy.route('GET', 'comments/*', '@comment').as('getComment');
|
||||
cy.route('GET', 'comments/*', '@comment').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click();
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment')
|
||||
.its('responseBody')
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data');
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
|
||||
// you can also just write the fixture in the route
|
||||
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment');
|
||||
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click();
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment')
|
||||
.its('responseBody')
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data');
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
|
||||
// or write fx to represent fixture
|
||||
// by default it assumes it's .json
|
||||
cy.route('GET', 'comments/*', 'fx:example').as('getComment');
|
||||
cy.route('GET', 'comments/*', 'fx:example').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click();
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment')
|
||||
.its('responseBody')
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data');
|
||||
});
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
})
|
||||
|
||||
it('cy.fixture() or require - load a fixture', function () {
|
||||
// we are inside the "function () { ... }"
|
||||
// callback and can use test context object "this"
|
||||
// "this.example" was loaded in "beforeEach" function callback
|
||||
expect(this.example, 'fixture in the test context').to.deep.equal(requiredExample);
|
||||
expect(this.example, 'fixture in the test context')
|
||||
.to.deep.equal(requiredExample)
|
||||
|
||||
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
|
||||
// @ts-ignore
|
||||
cy.wrap(this.example, 'fixture vs require').should('deep.equal', requiredExample);
|
||||
});
|
||||
cy.wrap(this.example, 'fixture vs require')
|
||||
.should('deep.equal', requiredExample)
|
||||
})
|
||||
|
||||
it('cy.readFile() - read a files contents', () => {
|
||||
// https://on.cypress.io/readfile
|
||||
@@ -81,9 +80,9 @@ context('Files', () => {
|
||||
// You can read a file and yield its contents
|
||||
// The filePath is relative to your project's root.
|
||||
cy.readFile('cypress.json').then((json) => {
|
||||
expect(json).to.be.an('object');
|
||||
});
|
||||
});
|
||||
expect(json).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.writeFile() - write to a file', () => {
|
||||
// https://on.cypress.io/writefile
|
||||
@@ -92,12 +91,13 @@ context('Files', () => {
|
||||
|
||||
// Use a response from a request to automatically
|
||||
// generate a fixture file for use later
|
||||
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
|
||||
cy.writeFile('cypress/fixtures/users.json', response.body);
|
||||
});
|
||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
||||
.then((response) => {
|
||||
cy.writeFile('cypress/fixtures/users.json', response.body)
|
||||
})
|
||||
cy.fixture('users').should((users) => {
|
||||
expect(users[0].name).to.exist;
|
||||
});
|
||||
expect(users[0].name).to.exist
|
||||
})
|
||||
|
||||
// JavaScript arrays and objects are stringified
|
||||
// and formatted into text.
|
||||
@@ -105,10 +105,10 @@ context('Files', () => {
|
||||
id: 8739,
|
||||
name: 'Jane',
|
||||
email: 'jane@example.com',
|
||||
});
|
||||
})
|
||||
|
||||
cy.fixture('profile').should((profile) => {
|
||||
expect(profile.name).to.eq('Jane');
|
||||
});
|
||||
});
|
||||
});
|
||||
expect(profile.name).to.eq('Jane')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -2,57 +2,51 @@
|
||||
|
||||
context('Local Storage', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/local-storage');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/local-storage')
|
||||
})
|
||||
// Although local storage is automatically cleared
|
||||
// in between tests to maintain a clean state
|
||||
// sometimes we need to clear the local storage manually
|
||||
|
||||
it('cy.clearLocalStorage() - clear all data in local storage', () => {
|
||||
// https://on.cypress.io/clearlocalstorage
|
||||
cy.get('.ls-btn')
|
||||
.click()
|
||||
.should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red');
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue');
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta');
|
||||
});
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
// clearLocalStorage() yields the localStorage object
|
||||
cy.clearLocalStorage().should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null;
|
||||
expect(ls.getItem('prop2')).to.be.null;
|
||||
expect(ls.getItem('prop3')).to.be.null;
|
||||
});
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.be.null
|
||||
expect(ls.getItem('prop3')).to.be.null
|
||||
})
|
||||
|
||||
// Clear key matching string in Local Storage
|
||||
cy.get('.ls-btn')
|
||||
.click()
|
||||
.should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red');
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue');
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta');
|
||||
});
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
cy.clearLocalStorage('prop1').should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null;
|
||||
expect(ls.getItem('prop2')).to.eq('blue');
|
||||
expect(ls.getItem('prop3')).to.eq('magenta');
|
||||
});
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.eq('blue')
|
||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
// Clear keys matching regex in Local Storage
|
||||
cy.get('.ls-btn')
|
||||
.click()
|
||||
.should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red');
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue');
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta');
|
||||
});
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
cy.clearLocalStorage(/prop1|2/).should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null;
|
||||
expect(ls.getItem('prop2')).to.be.null;
|
||||
expect(ls.getItem('prop3')).to.eq('magenta');
|
||||
});
|
||||
});
|
||||
});
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.be.null
|
||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -2,31 +2,31 @@
|
||||
|
||||
context('Location', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/location');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/location')
|
||||
})
|
||||
|
||||
it('cy.hash() - get the current URL hash', () => {
|
||||
// https://on.cypress.io/hash
|
||||
cy.hash().should('be.empty');
|
||||
});
|
||||
cy.hash().should('be.empty')
|
||||
})
|
||||
|
||||
it('cy.location() - get window.location', () => {
|
||||
// https://on.cypress.io/location
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.be.empty;
|
||||
expect(location.href).to.eq('https://example.cypress.io/commands/location');
|
||||
expect(location.host).to.eq('example.cypress.io');
|
||||
expect(location.hostname).to.eq('example.cypress.io');
|
||||
expect(location.origin).to.eq('https://example.cypress.io');
|
||||
expect(location.pathname).to.eq('/commands/location');
|
||||
expect(location.port).to.eq('');
|
||||
expect(location.protocol).to.eq('https:');
|
||||
expect(location.search).to.be.empty;
|
||||
});
|
||||
});
|
||||
expect(location.hash).to.be.empty
|
||||
expect(location.href).to.eq('https://example.cypress.io/commands/location')
|
||||
expect(location.host).to.eq('example.cypress.io')
|
||||
expect(location.hostname).to.eq('example.cypress.io')
|
||||
expect(location.origin).to.eq('https://example.cypress.io')
|
||||
expect(location.pathname).to.eq('/commands/location')
|
||||
expect(location.port).to.eq('')
|
||||
expect(location.protocol).to.eq('https:')
|
||||
expect(location.search).to.be.empty
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.url() - get the current URL', () => {
|
||||
// https://on.cypress.io/url
|
||||
cy.url().should('eq', 'https://example.cypress.io/commands/location');
|
||||
});
|
||||
});
|
||||
cy.url().should('eq', 'https://example.cypress.io/commands/location')
|
||||
})
|
||||
})
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
context('Misc', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/misc');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/misc')
|
||||
})
|
||||
|
||||
it('.end() - end the command chain', () => {
|
||||
// https://on.cypress.io/end
|
||||
@@ -12,12 +12,12 @@ context('Misc', () => {
|
||||
// and force Cypress to re-query from the root element
|
||||
cy.get('.misc-table').within(() => {
|
||||
// ends the current chain and yields null
|
||||
cy.contains('Cheryl').click().end();
|
||||
cy.contains('Cheryl').click().end()
|
||||
|
||||
// queries the entire table again
|
||||
cy.contains('Charles').click();
|
||||
});
|
||||
});
|
||||
cy.contains('Charles').click()
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.exec() - execute a system command', () => {
|
||||
// https://on.cypress.io/exec
|
||||
@@ -25,36 +25,40 @@ context('Misc', () => {
|
||||
// execute a system command.
|
||||
// so you can take actions necessary for
|
||||
// your test outside the scope of Cypress.
|
||||
cy.exec('echo Jane Lane').its('stdout').should('contain', 'Jane Lane');
|
||||
cy.exec('echo Jane Lane')
|
||||
.its('stdout').should('contain', 'Jane Lane')
|
||||
|
||||
// we can use Cypress.platform string to
|
||||
// select appropriate command
|
||||
// https://on.cypress/io/platform
|
||||
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`);
|
||||
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
|
||||
|
||||
if (Cypress.platform === 'win32') {
|
||||
cy.exec('print cypress.json').its('stderr').should('be.empty');
|
||||
cy.exec('print cypress.json')
|
||||
.its('stderr').should('be.empty')
|
||||
} else {
|
||||
cy.exec('cat cypress.json').its('stderr').should('be.empty');
|
||||
cy.exec('cat cypress.json')
|
||||
.its('stderr').should('be.empty')
|
||||
|
||||
cy.exec('pwd').its('code').should('eq', 0);
|
||||
cy.exec('pwd')
|
||||
.its('code').should('eq', 0)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
it('cy.focused() - get the DOM element that has focus', () => {
|
||||
// https://on.cypress.io/focused
|
||||
cy.get('.misc-form').find('#name').click();
|
||||
cy.focused().should('have.id', 'name');
|
||||
cy.get('.misc-form').find('#name').click()
|
||||
cy.focused().should('have.id', 'name')
|
||||
|
||||
cy.get('.misc-form').find('#description').click();
|
||||
cy.focused().should('have.id', 'description');
|
||||
});
|
||||
cy.get('.misc-form').find('#description').click()
|
||||
cy.focused().should('have.id', 'description')
|
||||
})
|
||||
|
||||
context('Cypress.Screenshot', function () {
|
||||
it('cy.screenshot() - take a screenshot', () => {
|
||||
// https://on.cypress.io/screenshot
|
||||
cy.screenshot('my-image');
|
||||
});
|
||||
cy.screenshot('my-image')
|
||||
})
|
||||
|
||||
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
|
||||
Cypress.Screenshot.defaults({
|
||||
@@ -64,14 +68,16 @@ context('Misc', () => {
|
||||
scale: false,
|
||||
disableTimersAndAnimations: true,
|
||||
screenshotOnRunFailure: true,
|
||||
beforeScreenshot() {},
|
||||
afterScreenshot() {},
|
||||
});
|
||||
});
|
||||
});
|
||||
beforeScreenshot () { },
|
||||
afterScreenshot () { },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.wrap() - wrap an object', () => {
|
||||
// https://on.cypress.io/wrap
|
||||
cy.wrap({ foo: 'bar' }).should('have.property', 'foo').and('include', 'bar');
|
||||
});
|
||||
});
|
||||
cy.wrap({ foo: 'bar' })
|
||||
.should('have.property', 'foo')
|
||||
.and('include', 'bar')
|
||||
})
|
||||
})
|
||||
|
@@ -2,38 +2,38 @@
|
||||
|
||||
context('Navigation', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io');
|
||||
cy.get('.navbar-nav').contains('Commands').click();
|
||||
cy.get('.dropdown-menu').contains('Navigation').click();
|
||||
});
|
||||
cy.visit('https://example.cypress.io')
|
||||
cy.get('.navbar-nav').contains('Commands').click()
|
||||
cy.get('.dropdown-menu').contains('Navigation').click()
|
||||
})
|
||||
|
||||
it("cy.go() - go back or forward in the browser's history", () => {
|
||||
it('cy.go() - go back or forward in the browser\'s history', () => {
|
||||
// https://on.cypress.io/go
|
||||
|
||||
cy.location('pathname').should('include', 'navigation');
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
|
||||
cy.go('back');
|
||||
cy.location('pathname').should('not.include', 'navigation');
|
||||
cy.go('back')
|
||||
cy.location('pathname').should('not.include', 'navigation')
|
||||
|
||||
cy.go('forward');
|
||||
cy.location('pathname').should('include', 'navigation');
|
||||
cy.go('forward')
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
|
||||
// clicking back
|
||||
cy.go(-1);
|
||||
cy.location('pathname').should('not.include', 'navigation');
|
||||
cy.go(-1)
|
||||
cy.location('pathname').should('not.include', 'navigation')
|
||||
|
||||
// clicking forward
|
||||
cy.go(1);
|
||||
cy.location('pathname').should('include', 'navigation');
|
||||
});
|
||||
cy.go(1)
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
})
|
||||
|
||||
it('cy.reload() - reload the page', () => {
|
||||
// https://on.cypress.io/reload
|
||||
cy.reload();
|
||||
cy.reload()
|
||||
|
||||
// reload the page without using the cache
|
||||
cy.reload(true);
|
||||
});
|
||||
cy.reload(true)
|
||||
})
|
||||
|
||||
it('cy.visit() - visit a remote url', () => {
|
||||
// https://on.cypress.io/visit
|
||||
@@ -43,14 +43,14 @@ context('Navigation', () => {
|
||||
// Pass options to the visit
|
||||
cy.visit('https://example.cypress.io/commands/navigation', {
|
||||
timeout: 50000, // increase total time for the visit to resolve
|
||||
onBeforeLoad(contentWindow) {
|
||||
onBeforeLoad (contentWindow) {
|
||||
// contentWindow is the remote page's window object
|
||||
expect(typeof contentWindow === 'object').to.be.true;
|
||||
expect(typeof contentWindow === 'object').to.be.true
|
||||
},
|
||||
onLoad(contentWindow) {
|
||||
onLoad (contentWindow) {
|
||||
// contentWindow is the remote page's window object
|
||||
expect(typeof contentWindow === 'object').to.be.true;
|
||||
expect(typeof contentWindow === 'object').to.be.true
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
context('Network Requests', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/network-requests');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/network-requests')
|
||||
})
|
||||
|
||||
// Manage AJAX / XHR requests in your app
|
||||
|
||||
@@ -13,56 +13,59 @@ context('Network Requests', () => {
|
||||
cy.server().should((server) => {
|
||||
// the default options on server
|
||||
// you can override any of these options
|
||||
expect(server.delay).to.eq(0);
|
||||
expect(server.method).to.eq('GET');
|
||||
expect(server.status).to.eq(200);
|
||||
expect(server.headers).to.be.null;
|
||||
expect(server.response).to.be.null;
|
||||
expect(server.onRequest).to.be.undefined;
|
||||
expect(server.onResponse).to.be.undefined;
|
||||
expect(server.onAbort).to.be.undefined;
|
||||
expect(server.delay).to.eq(0)
|
||||
expect(server.method).to.eq('GET')
|
||||
expect(server.status).to.eq(200)
|
||||
expect(server.headers).to.be.null
|
||||
expect(server.response).to.be.null
|
||||
expect(server.onRequest).to.be.undefined
|
||||
expect(server.onResponse).to.be.undefined
|
||||
expect(server.onAbort).to.be.undefined
|
||||
|
||||
// These options control the server behavior
|
||||
// affecting all requests
|
||||
|
||||
// pass false to disable existing route stubs
|
||||
expect(server.enable).to.be.true;
|
||||
expect(server.enable).to.be.true
|
||||
// forces requests that don't match your routes to 404
|
||||
expect(server.force404).to.be.false;
|
||||
expect(server.force404).to.be.false
|
||||
// whitelists requests from ever being logged or stubbed
|
||||
expect(server.whitelist).to.be.a('function');
|
||||
});
|
||||
expect(server.whitelist).to.be.a('function')
|
||||
})
|
||||
|
||||
cy.server({
|
||||
method: 'POST',
|
||||
delay: 1000,
|
||||
status: 422,
|
||||
response: {},
|
||||
});
|
||||
})
|
||||
|
||||
// any route commands will now inherit the above options
|
||||
// from the server. anything we pass specifically
|
||||
// to route will override the defaults though.
|
||||
});
|
||||
})
|
||||
|
||||
it('cy.request() - make an XHR request', () => {
|
||||
// https://on.cypress.io/request
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments').should((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body).to.have.length(500);
|
||||
expect(response).to.have.property('headers');
|
||||
expect(response).to.have.property('duration');
|
||||
});
|
||||
});
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
||||
.should((response) => {
|
||||
expect(response.status).to.eq(200)
|
||||
expect(response.body).to.have.length(500)
|
||||
expect(response).to.have.property('headers')
|
||||
expect(response).to.have.property('duration')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('cy.request() - verify response using BDD syntax', () => {
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments').then((response) => {
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
||||
.then((response) => {
|
||||
// https://on.cypress.io/assertions
|
||||
expect(response).property('status').to.equal(200);
|
||||
expect(response).property('body').to.have.length(500);
|
||||
expect(response).to.include.keys('headers', 'duration');
|
||||
});
|
||||
});
|
||||
expect(response).property('status').to.equal(200)
|
||||
expect(response).property('body').to.have.length(500)
|
||||
expect(response).to.include.keys('headers', 'duration')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() with query parameters', () => {
|
||||
// will execute request
|
||||
@@ -74,42 +77,42 @@ context('Network Requests', () => {
|
||||
id: 3,
|
||||
},
|
||||
})
|
||||
.its('body')
|
||||
.should('be.an', 'array')
|
||||
.and('have.length', 1)
|
||||
.its('0') // yields first element of the array
|
||||
.should('contain', {
|
||||
postId: 1,
|
||||
id: 3,
|
||||
});
|
||||
});
|
||||
.its('body')
|
||||
.should('be.an', 'array')
|
||||
.and('have.length', 1)
|
||||
.its('0') // yields first element of the array
|
||||
.should('contain', {
|
||||
postId: 1,
|
||||
id: 3,
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() - pass result to the second request', () => {
|
||||
// first, let's find out the userId of the first user we have
|
||||
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
||||
.its('body.0') // yields the first element of the returned list
|
||||
.then((user) => {
|
||||
expect(user).property('id').to.be.a('number');
|
||||
expect(user).property('id').to.be.a('number')
|
||||
// make a new post on behalf of the user
|
||||
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
||||
userId: user.id,
|
||||
title: 'Cypress Test Runner',
|
||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||
});
|
||||
})
|
||||
})
|
||||
// note that the value here is the returned value of the 2nd request
|
||||
// which is the new post object
|
||||
.then((response) => {
|
||||
expect(response).property('status').to.equal(201); // new entity created
|
||||
expect(response).property('status').to.equal(201) // new entity created
|
||||
expect(response).property('body').to.contain({
|
||||
id: 101, // there are already 100 posts, so new entity gets id 101
|
||||
title: 'Cypress Test Runner',
|
||||
});
|
||||
})
|
||||
// we don't know the user id here - since it was in above closure
|
||||
// so in this test just confirm that the property is there
|
||||
expect(response.body).property('userId').to.be.a('number');
|
||||
});
|
||||
});
|
||||
expect(response.body).property('userId').to.be.a('number')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() - save response in the shared test context', () => {
|
||||
// https://on.cypress.io/variables-and-aliases
|
||||
@@ -128,48 +131,47 @@ context('Network Requests', () => {
|
||||
title: 'Cypress Test Runner',
|
||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||
})
|
||||
.its('body')
|
||||
.as('post'); // save the new post from the response
|
||||
.its('body').as('post') // save the new post from the response
|
||||
})
|
||||
.then(function () {
|
||||
// When this callback runs, both "cy.request" API commands have finished
|
||||
// and the test context has "user" and "post" objects set.
|
||||
// Let's verify them.
|
||||
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id);
|
||||
});
|
||||
});
|
||||
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.route() - route responses to matching requests', () => {
|
||||
// https://on.cypress.io/route
|
||||
|
||||
let message = 'whoa, this comment does not exist';
|
||||
let message = 'whoa, this comment does not exist'
|
||||
|
||||
cy.server();
|
||||
cy.server()
|
||||
|
||||
// Listen to GET to comments/1
|
||||
cy.route('GET', 'comments/*').as('getComment');
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click();
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
cy.wait('@getComment').its('status').should('eq', 200);
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
|
||||
// Listen to POST to comments
|
||||
cy.route('POST', '/comments').as('postComment');
|
||||
cy.route('POST', '/comments').as('postComment')
|
||||
|
||||
// we have code that posts a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-post').click();
|
||||
cy.wait('@postComment');
|
||||
cy.get('.network-post').click()
|
||||
cy.wait('@postComment')
|
||||
|
||||
// get the route
|
||||
cy.get('@postComment').should((xhr) => {
|
||||
expect(xhr.requestBody).to.include('email');
|
||||
expect(xhr.requestHeaders).to.have.property('Content-Type');
|
||||
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()');
|
||||
});
|
||||
expect(xhr.requestBody).to.include('email')
|
||||
expect(xhr.requestHeaders).to.have.property('Content-Type')
|
||||
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
|
||||
})
|
||||
|
||||
// Stub a response to PUT comments/ ****
|
||||
cy.route({
|
||||
@@ -178,15 +180,15 @@ context('Network Requests', () => {
|
||||
status: 404,
|
||||
response: { error: message },
|
||||
delay: 500,
|
||||
}).as('putComment');
|
||||
}).as('putComment')
|
||||
|
||||
// we have code that puts a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-put').click();
|
||||
cy.get('.network-put').click()
|
||||
|
||||
cy.wait('@putComment');
|
||||
cy.wait('@putComment')
|
||||
|
||||
// our 404 statusCode logic in scripts.js executed
|
||||
cy.get('.network-put-comment').should('contain', message);
|
||||
});
|
||||
});
|
||||
cy.get('.network-put-comment').should('contain', message)
|
||||
})
|
||||
})
|
||||
|
@@ -2,8 +2,8 @@
|
||||
|
||||
context('Querying', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/querying');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/querying')
|
||||
})
|
||||
|
||||
// The most commonly used query is 'cy.get()', you can
|
||||
// think of this like the '$' in jQuery
|
||||
@@ -11,65 +11,77 @@ context('Querying', () => {
|
||||
it('cy.get() - query DOM elements', () => {
|
||||
// https://on.cypress.io/get
|
||||
|
||||
cy.get('#query-btn').should('contain', 'Button');
|
||||
cy.get('#query-btn').should('contain', 'Button')
|
||||
|
||||
cy.get('.query-btn').should('contain', 'Button');
|
||||
cy.get('.query-btn').should('contain', 'Button')
|
||||
|
||||
cy.get('#querying .well>button:first').should('contain', 'Button');
|
||||
cy.get('#querying .well>button:first').should('contain', 'Button')
|
||||
// ↲
|
||||
// Use CSS selectors just like jQuery
|
||||
|
||||
cy.get('[data-test-id="test-example"]').should('have.class', 'example');
|
||||
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
|
||||
|
||||
// 'cy.get()' yields jQuery object, you can get its attribute
|
||||
// by invoking `.attr()` method
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.invoke('attr', 'data-test-id')
|
||||
.should('equal', 'test-example');
|
||||
.should('equal', 'test-example')
|
||||
|
||||
// or you can get element's CSS property
|
||||
cy.get('[data-test-id="test-example"]').invoke('css', 'position').should('equal', 'static');
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.invoke('css', 'position')
|
||||
.should('equal', 'static')
|
||||
|
||||
// or use assertions directly during 'cy.get()'
|
||||
// https://on.cypress.io/assertions
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.should('have.attr', 'data-test-id', 'test-example')
|
||||
.and('have.css', 'position', 'static');
|
||||
});
|
||||
.and('have.css', 'position', 'static')
|
||||
})
|
||||
|
||||
it('cy.contains() - query DOM elements with matching content', () => {
|
||||
// https://on.cypress.io/contains
|
||||
cy.get('.query-list').contains('bananas').should('have.class', 'third');
|
||||
cy.get('.query-list')
|
||||
.contains('bananas')
|
||||
.should('have.class', 'third')
|
||||
|
||||
// we can pass a regexp to `.contains()`
|
||||
cy.get('.query-list').contains(/^b\w+/).should('have.class', 'third');
|
||||
cy.get('.query-list')
|
||||
.contains(/^b\w+/)
|
||||
.should('have.class', 'third')
|
||||
|
||||
cy.get('.query-list').contains('apples').should('have.class', 'first');
|
||||
cy.get('.query-list')
|
||||
.contains('apples')
|
||||
.should('have.class', 'first')
|
||||
|
||||
// passing a selector to contains will
|
||||
// yield the selector containing the text
|
||||
cy.get('#querying').contains('ul', 'oranges').should('have.class', 'query-list');
|
||||
cy.get('#querying')
|
||||
.contains('ul', 'oranges')
|
||||
.should('have.class', 'query-list')
|
||||
|
||||
cy.get('.query-button').contains('Save Form').should('have.class', 'btn');
|
||||
});
|
||||
cy.get('.query-button')
|
||||
.contains('Save Form')
|
||||
.should('have.class', 'btn')
|
||||
})
|
||||
|
||||
it('.within() - query DOM elements within a specific element', () => {
|
||||
// https://on.cypress.io/within
|
||||
cy.get('.query-form').within(() => {
|
||||
cy.get('input:first').should('have.attr', 'placeholder', 'Email');
|
||||
cy.get('input:last').should('have.attr', 'placeholder', 'Password');
|
||||
});
|
||||
});
|
||||
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
|
||||
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.root() - query the root DOM element', () => {
|
||||
// https://on.cypress.io/root
|
||||
|
||||
// By default, root is the document
|
||||
cy.root().should('match', 'html');
|
||||
cy.root().should('match', 'html')
|
||||
|
||||
cy.get('.query-ul').within(() => {
|
||||
// In this within, the root is now the ul DOM element
|
||||
cy.root().should('have.class', 'query-ul');
|
||||
});
|
||||
});
|
||||
});
|
||||
cy.root().should('have.class', 'query-ul')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -3,92 +3,93 @@
|
||||
context('Spies, Stubs, and Clock', () => {
|
||||
it('cy.spy() - wrap a method in a spy', () => {
|
||||
// https://on.cypress.io/spy
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
foo() {},
|
||||
};
|
||||
foo () {},
|
||||
}
|
||||
|
||||
const spy = cy.spy(obj, 'foo').as('anyArgs');
|
||||
const spy = cy.spy(obj, 'foo').as('anyArgs')
|
||||
|
||||
obj.foo();
|
||||
obj.foo()
|
||||
|
||||
expect(spy).to.be.called;
|
||||
});
|
||||
expect(spy).to.be.called
|
||||
})
|
||||
|
||||
it('cy.spy() retries until assertions pass', () => {
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
/**
|
||||
* Prints the argument passed
|
||||
*
|
||||
* @param x {any}
|
||||
*/
|
||||
foo(x) {
|
||||
console.log('obj.foo called with', x);
|
||||
*/
|
||||
foo (x) {
|
||||
console.log('obj.foo called with', x)
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
cy.spy(obj, 'foo').as('foo');
|
||||
cy.spy(obj, 'foo').as('foo')
|
||||
|
||||
setTimeout(() => {
|
||||
obj.foo('first');
|
||||
}, 500);
|
||||
obj.foo('first')
|
||||
}, 500)
|
||||
|
||||
setTimeout(() => {
|
||||
obj.foo('second');
|
||||
}, 2500);
|
||||
obj.foo('second')
|
||||
}, 2500)
|
||||
|
||||
cy.get('@foo').should('have.been.calledTwice');
|
||||
});
|
||||
cy.get('@foo').should('have.been.calledTwice')
|
||||
})
|
||||
|
||||
it('cy.stub() - create a stub and/or replace a function with stub', () => {
|
||||
// https://on.cypress.io/stub
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
/**
|
||||
* Prints both arguments to the console
|
||||
*
|
||||
* prints both arguments to the console
|
||||
* @param a {string}
|
||||
* @param b {string}
|
||||
*/
|
||||
foo(a, b) {
|
||||
console.log('a', a, 'b', b);
|
||||
*/
|
||||
foo (a, b) {
|
||||
console.log('a', a, 'b', b)
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const stub = cy.stub(obj, 'foo').as('foo');
|
||||
const stub = cy.stub(obj, 'foo').as('foo')
|
||||
|
||||
obj.foo('foo', 'bar');
|
||||
obj.foo('foo', 'bar')
|
||||
|
||||
expect(stub).to.be.called;
|
||||
});
|
||||
expect(stub).to.be.called
|
||||
})
|
||||
|
||||
it('cy.clock() - control time in the browser', () => {
|
||||
// https://on.cypress.io/clock
|
||||
|
||||
// create the date in UTC so its always the same
|
||||
// no matter what local timezone the browser is running in
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime();
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
||||
|
||||
cy.clock(now);
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||
cy.get('#clock-div').click().should('have.text', '1489449600');
|
||||
});
|
||||
cy.clock(now)
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
cy.get('#clock-div').click()
|
||||
.should('have.text', '1489449600')
|
||||
})
|
||||
|
||||
it('cy.tick() - move time in the browser', () => {
|
||||
// https://on.cypress.io/tick
|
||||
|
||||
// create the date in UTC so its always the same
|
||||
// no matter what local timezone the browser is running in
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime();
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
||||
|
||||
cy.clock(now);
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||
cy.get('#tick-div').click().should('have.text', '1489449600');
|
||||
cy.tick(10000); // 10 seconds passed
|
||||
cy.get('#tick-div').click().should('have.text', '1489449610');
|
||||
});
|
||||
});
|
||||
cy.clock(now)
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
cy.get('#tick-div').click()
|
||||
.should('have.text', '1489449600')
|
||||
cy.tick(10000) // 10 seconds passed
|
||||
cy.get('#tick-div').click()
|
||||
.should('have.text', '1489449610')
|
||||
})
|
||||
})
|
||||
|
@@ -2,96 +2,120 @@
|
||||
|
||||
context('Traversal', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/traversal');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/traversal')
|
||||
})
|
||||
|
||||
it('.children() - get child DOM elements', () => {
|
||||
// https://on.cypress.io/children
|
||||
cy.get('.traversal-breadcrumb').children('.active').should('contain', 'Data');
|
||||
});
|
||||
cy.get('.traversal-breadcrumb')
|
||||
.children('.active')
|
||||
.should('contain', 'Data')
|
||||
})
|
||||
|
||||
it('.closest() - get closest ancestor DOM element', () => {
|
||||
// https://on.cypress.io/closest
|
||||
cy.get('.traversal-badge').closest('ul').should('have.class', 'list-group');
|
||||
});
|
||||
cy.get('.traversal-badge')
|
||||
.closest('ul')
|
||||
.should('have.class', 'list-group')
|
||||
})
|
||||
|
||||
it('.eq() - get a DOM element at a specific index', () => {
|
||||
// https://on.cypress.io/eq
|
||||
cy.get('.traversal-list>li').eq(1).should('contain', 'siamese');
|
||||
});
|
||||
cy.get('.traversal-list>li')
|
||||
.eq(1).should('contain', 'siamese')
|
||||
})
|
||||
|
||||
it('.filter() - get DOM elements that match the selector', () => {
|
||||
// https://on.cypress.io/filter
|
||||
cy.get('.traversal-nav>li').filter('.active').should('contain', 'About');
|
||||
});
|
||||
cy.get('.traversal-nav>li')
|
||||
.filter('.active').should('contain', 'About')
|
||||
})
|
||||
|
||||
it('.find() - get descendant DOM elements of the selector', () => {
|
||||
// https://on.cypress.io/find
|
||||
cy.get('.traversal-pagination').find('li').find('a').should('have.length', 7);
|
||||
});
|
||||
cy.get('.traversal-pagination')
|
||||
.find('li').find('a')
|
||||
.should('have.length', 7)
|
||||
})
|
||||
|
||||
it('.first() - get first DOM element', () => {
|
||||
// https://on.cypress.io/first
|
||||
cy.get('.traversal-table td').first().should('contain', '1');
|
||||
});
|
||||
cy.get('.traversal-table td')
|
||||
.first().should('contain', '1')
|
||||
})
|
||||
|
||||
it('.last() - get last DOM element', () => {
|
||||
// https://on.cypress.io/last
|
||||
cy.get('.traversal-buttons .btn').last().should('contain', 'Submit');
|
||||
});
|
||||
cy.get('.traversal-buttons .btn')
|
||||
.last().should('contain', 'Submit')
|
||||
})
|
||||
|
||||
it('.next() - get next sibling DOM element', () => {
|
||||
// https://on.cypress.io/next
|
||||
cy.get('.traversal-ul').contains('apples').next().should('contain', 'oranges');
|
||||
});
|
||||
cy.get('.traversal-ul')
|
||||
.contains('apples').next().should('contain', 'oranges')
|
||||
})
|
||||
|
||||
it('.nextAll() - get all next sibling DOM elements', () => {
|
||||
// https://on.cypress.io/nextall
|
||||
cy.get('.traversal-next-all').contains('oranges').nextAll().should('have.length', 3);
|
||||
});
|
||||
cy.get('.traversal-next-all')
|
||||
.contains('oranges')
|
||||
.nextAll().should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.nextUntil() - get next sibling DOM elements until next el', () => {
|
||||
// https://on.cypress.io/nextuntil
|
||||
cy.get('#veggies').nextUntil('#nuts').should('have.length', 3);
|
||||
});
|
||||
cy.get('#veggies')
|
||||
.nextUntil('#nuts').should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.not() - remove DOM elements from set of DOM elements', () => {
|
||||
// https://on.cypress.io/not
|
||||
cy.get('.traversal-disabled .btn').not('[disabled]').should('not.contain', 'Disabled');
|
||||
});
|
||||
cy.get('.traversal-disabled .btn')
|
||||
.not('[disabled]').should('not.contain', 'Disabled')
|
||||
})
|
||||
|
||||
it('.parent() - get parent DOM element from DOM elements', () => {
|
||||
// https://on.cypress.io/parent
|
||||
cy.get('.traversal-mark').parent().should('contain', 'Morbi leo risus');
|
||||
});
|
||||
cy.get('.traversal-mark')
|
||||
.parent().should('contain', 'Morbi leo risus')
|
||||
})
|
||||
|
||||
it('.parents() - get parent DOM elements from DOM elements', () => {
|
||||
// https://on.cypress.io/parents
|
||||
cy.get('.traversal-cite').parents().should('match', 'blockquote');
|
||||
});
|
||||
cy.get('.traversal-cite')
|
||||
.parents().should('match', 'blockquote')
|
||||
})
|
||||
|
||||
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
|
||||
// https://on.cypress.io/parentsuntil
|
||||
cy.get('.clothes-nav').find('.active').parentsUntil('.clothes-nav').should('have.length', 2);
|
||||
});
|
||||
cy.get('.clothes-nav')
|
||||
.find('.active')
|
||||
.parentsUntil('.clothes-nav')
|
||||
.should('have.length', 2)
|
||||
})
|
||||
|
||||
it('.prev() - get previous sibling DOM element', () => {
|
||||
// https://on.cypress.io/prev
|
||||
cy.get('.birds').find('.active').prev().should('contain', 'Lorikeets');
|
||||
});
|
||||
cy.get('.birds').find('.active')
|
||||
.prev().should('contain', 'Lorikeets')
|
||||
})
|
||||
|
||||
it('.prevAll() - get all previous sibling DOM elements', () => {
|
||||
// https://on.cypress.io/prevAll
|
||||
cy.get('.fruits-list').find('.third').prevAll().should('have.length', 2);
|
||||
});
|
||||
cy.get('.fruits-list').find('.third')
|
||||
.prevAll().should('have.length', 2)
|
||||
})
|
||||
|
||||
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
|
||||
// https://on.cypress.io/prevUntil
|
||||
cy.get('.foods-list').find('#nuts').prevUntil('#veggies').should('have.length', 3);
|
||||
});
|
||||
cy.get('.foods-list').find('#nuts')
|
||||
.prevUntil('#veggies').should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.siblings() - get all sibling DOM elements', () => {
|
||||
// https://on.cypress.io/siblings
|
||||
cy.get('.traversal-pills .active').siblings().should('have.length', 2);
|
||||
});
|
||||
});
|
||||
cy.get('.traversal-pills .active')
|
||||
.siblings().should('have.length', 2)
|
||||
})
|
||||
})
|
||||
|
@@ -2,128 +2,132 @@
|
||||
|
||||
context('Utilities', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/utilities');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/utilities')
|
||||
})
|
||||
|
||||
it('Cypress._ - call a lodash method', () => {
|
||||
// https://on.cypress.io/_
|
||||
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
|
||||
let ids = Cypress._.chain(response.body).map('id').take(3).value();
|
||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
||||
.then((response) => {
|
||||
let ids = Cypress._.chain(response.body).map('id').take(3).value()
|
||||
|
||||
expect(ids).to.deep.eq([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
expect(ids).to.deep.eq([1, 2, 3])
|
||||
})
|
||||
})
|
||||
|
||||
it('Cypress.$ - call a jQuery method', () => {
|
||||
// https://on.cypress.io/$
|
||||
let $li = Cypress.$('.utility-jquery li:first');
|
||||
let $li = Cypress.$('.utility-jquery li:first')
|
||||
|
||||
cy.wrap($li).should('not.have.class', 'active').click().should('have.class', 'active');
|
||||
});
|
||||
cy.wrap($li)
|
||||
.should('not.have.class', 'active')
|
||||
.click()
|
||||
.should('have.class', 'active')
|
||||
})
|
||||
|
||||
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
|
||||
// https://on.cypress.io/blob
|
||||
cy.get('.utility-blob').then(($div) =>
|
||||
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
||||
// get the dataUrl string for the javascript-logo
|
||||
Cypress.Blob.imgSrcToDataURL(
|
||||
'https://example.cypress.io/assets/img/javascript-logo.png',
|
||||
undefined,
|
||||
'anonymous'
|
||||
).then((dataUrl) => {
|
||||
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
||||
// get the dataUrl string for the javascript-logo
|
||||
Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
|
||||
.then((dataUrl) => {
|
||||
// create an <img> element and set its src to the dataUrl
|
||||
let img = Cypress.$('<img />', { src: dataUrl });
|
||||
let img = Cypress.$('<img />', { src: dataUrl })
|
||||
|
||||
// need to explicitly return cy here since we are initially returning
|
||||
// the Cypress.Blob.imgSrcToDataURL promise to our test
|
||||
// append the image
|
||||
$div.append(img);
|
||||
$div.append(img)
|
||||
|
||||
cy.get('.utility-blob img').click().should('have.attr', 'src', dataUrl);
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.get('.utility-blob img').click()
|
||||
.should('have.attr', 'src', dataUrl)
|
||||
}))
|
||||
})
|
||||
|
||||
it('Cypress.minimatch - test out glob patterns against strings', () => {
|
||||
// https://on.cypress.io/minimatch
|
||||
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
|
||||
matchBase: true,
|
||||
});
|
||||
})
|
||||
|
||||
expect(matching, 'matching wildcard').to.be.true;
|
||||
expect(matching, 'matching wildcard').to.be.true
|
||||
|
||||
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
|
||||
matchBase: true,
|
||||
});
|
||||
expect(matching, 'comments').to.be.false;
|
||||
})
|
||||
expect(matching, 'comments').to.be.false
|
||||
|
||||
// ** matches against all downstream path segments
|
||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
|
||||
matchBase: true,
|
||||
});
|
||||
expect(matching, 'comments').to.be.true;
|
||||
})
|
||||
expect(matching, 'comments').to.be.true
|
||||
|
||||
// whereas * matches only the next path segment
|
||||
|
||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
|
||||
matchBase: false,
|
||||
});
|
||||
expect(matching, 'comments').to.be.false;
|
||||
});
|
||||
})
|
||||
expect(matching, 'comments').to.be.false
|
||||
})
|
||||
|
||||
|
||||
it('Cypress.moment() - format or parse dates using a moment method', () => {
|
||||
// https://on.cypress.io/moment
|
||||
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A');
|
||||
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
|
||||
|
||||
expect(time).to.be.a('string');
|
||||
expect(time).to.be.a('string')
|
||||
|
||||
cy.get('.utility-moment').contains('3:38 PM').should('have.class', 'badge');
|
||||
cy.get('.utility-moment').contains('3:38 PM')
|
||||
.should('have.class', 'badge')
|
||||
|
||||
// the time in the element should be between 3pm and 5pm
|
||||
const start = Cypress.moment('3:00 PM', 'LT');
|
||||
const end = Cypress.moment('5:00 PM', 'LT');
|
||||
const start = Cypress.moment('3:00 PM', 'LT')
|
||||
const end = Cypress.moment('5:00 PM', 'LT')
|
||||
|
||||
cy.get('.utility-moment .badge').should(($el) => {
|
||||
// parse American time like "3:38 PM"
|
||||
const m = Cypress.moment($el.text().trim(), 'LT');
|
||||
cy.get('.utility-moment .badge')
|
||||
.should(($el) => {
|
||||
// parse American time like "3:38 PM"
|
||||
const m = Cypress.moment($el.text().trim(), 'LT')
|
||||
|
||||
// display hours + minutes + AM|PM
|
||||
const f = 'h:mm A';
|
||||
// display hours + minutes + AM|PM
|
||||
const f = 'h:mm A'
|
||||
|
||||
expect(m.isBetween(start, end),
|
||||
`${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
expect(
|
||||
m.isBetween(start, end),
|
||||
`${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`
|
||||
).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
it('Cypress.Promise - instantiate a bluebird promise', () => {
|
||||
// https://on.cypress.io/promise
|
||||
let waited = false;
|
||||
let waited = false
|
||||
|
||||
/** @returns Bluebird<string> */
|
||||
function waitOneSecond() {
|
||||
/**
|
||||
* @return Bluebird<string>
|
||||
*/
|
||||
function waitOneSecond () {
|
||||
// return a promise that resolves after 1 second
|
||||
// @ts-ignore TS2351 (new Cypress.Promise)
|
||||
return new Cypress.Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// set waited to true
|
||||
waited = true;
|
||||
waited = true
|
||||
|
||||
// resolve with 'foo' string
|
||||
resolve('foo');
|
||||
}, 1000);
|
||||
});
|
||||
resolve('foo')
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
cy.then(() =>
|
||||
// return a promise to cy.then() that
|
||||
// is awaited until it resolves
|
||||
// return a promise to cy.then() that
|
||||
// is awaited until it resolves
|
||||
// @ts-ignore TS7006
|
||||
waitOneSecond().then((str) => {
|
||||
expect(str).to.eq('foo');
|
||||
expect(waited).to.be.true;
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
expect(str).to.eq('foo')
|
||||
expect(waited).to.be.true
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
@@ -2,22 +2,22 @@
|
||||
|
||||
context('Viewport', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/viewport');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/viewport')
|
||||
})
|
||||
|
||||
it('cy.viewport() - set the viewport size and dimension', () => {
|
||||
// https://on.cypress.io/viewport
|
||||
|
||||
cy.get('#navbar').should('be.visible');
|
||||
cy.viewport(320, 480);
|
||||
cy.get('#navbar').should('be.visible')
|
||||
cy.viewport(320, 480)
|
||||
|
||||
// the navbar should have collapse since our screen is smaller
|
||||
cy.get('#navbar').should('not.be.visible');
|
||||
cy.get('.navbar-toggle').should('be.visible').click();
|
||||
cy.get('.nav').find('a').should('be.visible');
|
||||
cy.get('#navbar').should('not.be.visible')
|
||||
cy.get('.navbar-toggle').should('be.visible').click()
|
||||
cy.get('.nav').find('a').should('be.visible')
|
||||
|
||||
// lets see what our app looks like on a super large screen
|
||||
cy.viewport(2999, 2999);
|
||||
cy.viewport(2999, 2999)
|
||||
|
||||
// cy.viewport() accepts a set of preset sizes
|
||||
// to easily set the screen to a device's width and height
|
||||
@@ -25,35 +25,35 @@ context('Viewport', () => {
|
||||
// We added a cy.wait() between each viewport change so you can see
|
||||
// the change otherwise it is a little too fast to see :)
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
cy.wait(200);
|
||||
cy.viewport('macbook-13');
|
||||
cy.wait(200);
|
||||
cy.viewport('macbook-11');
|
||||
cy.wait(200);
|
||||
cy.viewport('ipad-2');
|
||||
cy.wait(200);
|
||||
cy.viewport('ipad-mini');
|
||||
cy.wait(200);
|
||||
cy.viewport('iphone-6+');
|
||||
cy.wait(200);
|
||||
cy.viewport('iphone-6');
|
||||
cy.wait(200);
|
||||
cy.viewport('iphone-5');
|
||||
cy.wait(200);
|
||||
cy.viewport('iphone-4');
|
||||
cy.wait(200);
|
||||
cy.viewport('iphone-3');
|
||||
cy.wait(200);
|
||||
cy.viewport('macbook-15')
|
||||
cy.wait(200)
|
||||
cy.viewport('macbook-13')
|
||||
cy.wait(200)
|
||||
cy.viewport('macbook-11')
|
||||
cy.wait(200)
|
||||
cy.viewport('ipad-2')
|
||||
cy.wait(200)
|
||||
cy.viewport('ipad-mini')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-6+')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-6')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-5')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-4')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-3')
|
||||
cy.wait(200)
|
||||
|
||||
// cy.viewport() accepts an orientation for all presets
|
||||
// the default orientation is 'portrait'
|
||||
cy.viewport('ipad-2', 'portrait');
|
||||
cy.wait(200);
|
||||
cy.viewport('iphone-4', 'landscape');
|
||||
cy.wait(200);
|
||||
cy.viewport('ipad-2', 'portrait')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-4', 'landscape')
|
||||
cy.wait(200)
|
||||
|
||||
// The viewport will be reset back to the default dimensions
|
||||
// in between tests (the default can be set in cypress.json)
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
@@ -2,32 +2,33 @@
|
||||
|
||||
context('Waiting', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/waiting');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/waiting')
|
||||
})
|
||||
// BE CAREFUL of adding unnecessary wait times.
|
||||
// https://on.cypress.io/best-practices#Unnecessary-Waiting
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
it('cy.wait() - wait for a specific amount of time', () => {
|
||||
cy.get('.wait-input1').type('Wait 1000ms after typing');
|
||||
cy.wait(1000);
|
||||
cy.get('.wait-input2').type('Wait 1000ms after typing');
|
||||
cy.wait(1000);
|
||||
cy.get('.wait-input3').type('Wait 1000ms after typing');
|
||||
cy.wait(1000);
|
||||
});
|
||||
cy.get('.wait-input1').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
cy.get('.wait-input2').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
cy.get('.wait-input3').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
})
|
||||
|
||||
it('cy.wait() - wait for a specific route', () => {
|
||||
cy.server();
|
||||
cy.server()
|
||||
|
||||
// Listen to GET to comments/1
|
||||
cy.route('GET', 'comments/*').as('getComment');
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click();
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// wait for GET comments/1
|
||||
cy.wait('@getComment').its('status').should('eq', 200);
|
||||
});
|
||||
});
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
})
|
||||
|
||||
})
|
||||
|
@@ -2,21 +2,21 @@
|
||||
|
||||
context('Window', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/window');
|
||||
});
|
||||
cy.visit('https://example.cypress.io/commands/window')
|
||||
})
|
||||
|
||||
it('cy.window() - get the global window object', () => {
|
||||
// https://on.cypress.io/window
|
||||
cy.window().should('have.property', 'top');
|
||||
});
|
||||
cy.window().should('have.property', 'top')
|
||||
})
|
||||
|
||||
it('cy.document() - get the document object', () => {
|
||||
// https://on.cypress.io/document
|
||||
cy.document().should('have.property', 'charset').and('eq', 'UTF-8');
|
||||
});
|
||||
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
|
||||
})
|
||||
|
||||
it('cy.title() - get the title', () => {
|
||||
// https://on.cypress.io/title
|
||||
cy.title().should('include', 'Kitchen Sink');
|
||||
});
|
||||
});
|
||||
cy.title().should('include', 'Kitchen Sink')
|
||||
})
|
||||
})
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
@@ -1,9 +1,11 @@
|
||||
/* eslint-env jest */
|
||||
/* global cy */
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
export const mermaidUrl = (graphStr, options, api) => {
|
||||
const obj = {
|
||||
code: graphStr,
|
||||
mermaid: options,
|
||||
mermaid: options
|
||||
};
|
||||
const objStr = JSON.stringify(obj);
|
||||
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);
|
||||
@@ -47,11 +49,7 @@ export const imgSnapshotTest = (graphStr, _options, api) => {
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('svg');
|
||||
// cy.percySnapshot();
|
||||
// Default name to test title
|
||||
const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
|
||||
|
||||
cy.matchImageSnapshot(name);
|
||||
cy.percySnapshot();
|
||||
};
|
||||
|
||||
export const renderGraph = (graphStr, options, api) => {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { renderGraph } from '../../helpers/util';
|
||||
/* eslint-env jest */
|
||||
describe('Configuration', () => {
|
||||
describe('arrowMarkerAbsolute', () => {
|
||||
it('should handle default value false of arrowMarkerAbsolute', () => {
|
||||
@@ -10,14 +11,12 @@ describe('Configuration', () => {
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{}
|
||||
{ }
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path')
|
||||
.first()
|
||||
.should('have.attr', 'marker-end')
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
@@ -30,14 +29,12 @@ describe('Configuration', () => {
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{}
|
||||
{ }
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path')
|
||||
.first()
|
||||
.should('have.attr', 'marker-end')
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
@@ -51,15 +48,13 @@ describe('Configuration', () => {
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{
|
||||
arrowMarkerAbsolute: false,
|
||||
arrowMarkerAbsolute: false
|
||||
}
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path')
|
||||
.first()
|
||||
.should('have.attr', 'marker-end')
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
@@ -73,15 +68,13 @@ describe('Configuration', () => {
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{
|
||||
arrowMarkerAbsolute: 'false',
|
||||
arrowMarkerAbsolute: "false"
|
||||
}
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path')
|
||||
.first()
|
||||
.should('have.attr', 'marker-end')
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
@@ -95,13 +88,11 @@ describe('Configuration', () => {
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{
|
||||
arrowMarkerAbsolute: true,
|
||||
arrowMarkerAbsolute: true
|
||||
}
|
||||
);
|
||||
|
||||
cy.get('.edgePath path')
|
||||
.first()
|
||||
.should('have.attr', 'marker-end')
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(http://localhost');
|
||||
});
|
||||
@@ -111,9 +102,7 @@ describe('Configuration', () => {
|
||||
cy.visit(url);
|
||||
|
||||
cy.get('svg');
|
||||
cy.matchImageSnapshot(
|
||||
'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives'
|
||||
);
|
||||
cy.percySnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,10 +1,13 @@
|
||||
/* eslint-env jest */
|
||||
describe('Interaction', () => {
|
||||
describe('Interaction - security level loose', () => {
|
||||
it('Graph: should handle a click on a node with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-Function-2').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-Function-2')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||
});
|
||||
@@ -12,7 +15,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-FunctionArg-18').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-FunctionArg-18')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
|
||||
});
|
||||
@@ -20,7 +25,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-FunctionArg-22"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-FunctionArg-22"]')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
|
||||
});
|
||||
@@ -28,9 +35,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('#flowchart-URL-3').click();
|
||||
cy.get('body')
|
||||
.find('#flowchart-URL-3')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -38,9 +47,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-2URL-7"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-2URL-7"]')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -49,7 +60,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-Function-10').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-Function-10')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||
});
|
||||
@@ -57,7 +70,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-1Function-14"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-1Function-14"]')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||
});
|
||||
@@ -65,9 +80,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('#flowchart-URL-11').click();
|
||||
cy.get('body')
|
||||
.find('#flowchart-URL-11')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -75,9 +92,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-2URL-15"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-2URL-15"]')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -86,9 +105,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('rect#cl1').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('rect#cl1')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -96,9 +117,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('text#cl1-text').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('text#cl1-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -106,7 +129,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('rect#cl2').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('rect#cl2')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
@@ -114,7 +139,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('rect#cl3').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('rect#cl3')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
|
||||
});
|
||||
@@ -123,7 +150,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('text#cl2-text').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('text#cl2-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
@@ -131,10 +160,13 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('text#cl3-text').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('text#cl3-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Interaction - security level tight', () => {
|
||||
@@ -142,7 +174,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-Function-2').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-Function-2')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.exist');
|
||||
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
@@ -151,7 +185,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-1Function-6"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-1Function-6"]')
|
||||
.click();
|
||||
|
||||
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
cy.get('.created-by-click').should('not.exist');
|
||||
@@ -160,9 +196,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-URL-3').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-URL-3')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -170,9 +208,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-2URL-7"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-2URL-7"]')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -181,9 +221,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('rect#cl1').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('rect#cl1')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -191,9 +233,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('text#cl1-text').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('text#cl1-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -201,19 +245,23 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('rect#cl2').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('rect#cl2')
|
||||
.click({ force: true });
|
||||
|
||||
// cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||
cy.get('.created-by-gant-click').should('not.exist');
|
||||
cy.get('.created-by-gant-click').should('not.exist')
|
||||
});
|
||||
it('should handle a click on a task with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('text#cl2-text').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('text#cl2-text')
|
||||
.click({ force: true });
|
||||
|
||||
// cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||
cy.get('.created-by-gant-click').should('not.exist');
|
||||
cy.get('.created-by-gant-click').should('not.exist')
|
||||
});
|
||||
});
|
||||
|
||||
@@ -222,7 +270,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_other.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-Function-2').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-Function-2')
|
||||
.click();
|
||||
|
||||
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
cy.get('.created-by-click').should('not.exist');
|
||||
@@ -231,7 +281,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_other.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g[id="flowchart-1Function-6"]').click();
|
||||
cy.get('body')
|
||||
.find('g[id="flowchart-1Function-6"]')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.exist');
|
||||
cy.get('.created-by-click').should('not.exist');
|
||||
@@ -240,9 +292,11 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_other.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('g#flowchart-URL-3').click();
|
||||
cy.get('body')
|
||||
.find('g#flowchart-URL-3')
|
||||
.click();
|
||||
|
||||
cy.location().should((location) => {
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
@@ -251,7 +305,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_other.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('rect#cl2').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('rect#cl2')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('not.exist');
|
||||
});
|
||||
@@ -259,7 +315,9 @@ describe('Interaction', () => {
|
||||
const url = 'http://localhost:9000/click_security_other.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body').find('text#cl2-text').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('text#cl2-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('not.exist');
|
||||
});
|
||||
|
@@ -1,19 +1,22 @@
|
||||
/* eslint-env jest */
|
||||
describe('Rerendering', () => {
|
||||
it('should be able to render after an error has occured', () => {
|
||||
const url = 'http://localhost:9000/render-after-error.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('#graphDiv').should('exist');
|
||||
});
|
||||
it('should be able to render after an error has occured', () => {
|
||||
const url = 'http://localhost:9000/render-after-error.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('#graphDiv').should('exist');
|
||||
});
|
||||
|
||||
it('should be able to render and rerender a graph via API', () => {
|
||||
const url = 'http://localhost:9000/rerender.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
|
||||
it('should be able to render and rerender a graph via API', () => {
|
||||
const url = 'http://localhost:9000/rerender.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
|
||||
|
||||
cy.get('body').find('#rerender').click({ force: true });
|
||||
cy.get('body')
|
||||
.find('#rerender')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
|
||||
});
|
||||
cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
|
||||
});
|
||||
});
|
||||
|
@@ -1,15 +1,20 @@
|
||||
/* eslint-env jest */
|
||||
describe('Sequencediagram', () => {
|
||||
it('should render a simple sequence diagrams', () => {
|
||||
const url = 'http://localhost:9000/webpackUsage.html';
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('body').find('svg').should('have.length', 1);
|
||||
cy.get('body')
|
||||
.find('svg')
|
||||
.should('have.length', 1);
|
||||
});
|
||||
it('should handle html escapings properly', () => {
|
||||
const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('body').find('svg').should('have.length', 1);
|
||||
cy.get('body')
|
||||
.find('svg')
|
||||
.should('have.length', 1);
|
||||
|
||||
cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
|
||||
});
|
||||
|
@@ -1,132 +1,82 @@
|
||||
/* eslint-env jest */
|
||||
import { mermaidUrl } from '../../helpers/util.js';
|
||||
|
||||
/* eslint-disable */
|
||||
describe('XSS', () => {
|
||||
it('should handle xss in tags', () => {
|
||||
const str =
|
||||
'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
|
||||
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
|
||||
|
||||
const url = mermaidUrl(str, {}, true);
|
||||
const url = mermaidUrl(str,{}, true);
|
||||
|
||||
cy.visit(url);
|
||||
cy.wait(1000).then(() => {
|
||||
cy.wait(1000).then(()=>{
|
||||
cy.get('.mermaid').should('exist');
|
||||
});
|
||||
cy.get('svg');
|
||||
});
|
||||
cy.get('svg')
|
||||
})
|
||||
|
||||
it('should not allow tags in the css', () => {
|
||||
const str =
|
||||
'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
|
||||
const str = 'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
|
||||
|
||||
const url = mermaidUrl(
|
||||
str,
|
||||
{
|
||||
theme: 'default',
|
||||
flowchart: {
|
||||
htmlMode: false,
|
||||
},
|
||||
},
|
||||
true
|
||||
);
|
||||
const url = mermaidUrl(str,{
|
||||
"theme": "default",
|
||||
"flowchart": {
|
||||
"htmlMode": false
|
||||
}
|
||||
}, true);
|
||||
|
||||
cy.visit(url);
|
||||
cy.wait(1000).then(() => {
|
||||
cy.wait(1000).then(()=>{
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
it('should handle xss in tags in non-html mode', () => {
|
||||
const str =
|
||||
'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
|
||||
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
|
||||
|
||||
const url = mermaidUrl(
|
||||
str,
|
||||
{
|
||||
theme: 'default',
|
||||
flowchart: {
|
||||
htmlMode: false,
|
||||
},
|
||||
},
|
||||
true
|
||||
);
|
||||
const url = mermaidUrl(str,{
|
||||
"theme": "default",
|
||||
"flowchart": {
|
||||
"htmlMode": false
|
||||
}
|
||||
}, true);
|
||||
|
||||
cy.visit(url);
|
||||
cy.wait(1000);
|
||||
cy.wait(1000)
|
||||
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
})
|
||||
|
||||
it('should not allow changing the __proto__ attribute using config', () => {
|
||||
cy.visit('http://localhost:9000/xss2.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
})
|
||||
it('should not allow maniplulating htmlLabels into a false positive', () => {
|
||||
cy.visit('http://localhost:9000/xss4.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
})
|
||||
it('should not allow maniplulating antiscript to run javascript', () => {
|
||||
cy.visit('http://localhost:9000/xss5.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
})
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror', () => {
|
||||
cy.visit('http://localhost:9000/xss6.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
})
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre wrapper', () => {
|
||||
cy.visit('http://localhost:9000/xss8.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
})
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||
cy.visit('http://localhost:9000/xss9.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||
cy.visit('http://localhost:9000/xss10.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||
cy.visit('http://localhost:9000/xss11.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||
cy.visit('http://localhost:9000/xss12.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||
cy.visit('http://localhost:9000/xss13.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should not allow maniplulating antiscript to run javascript iframes in class diagrams', () => {
|
||||
cy.visit('http://localhost:9000/xss14.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should sanitize cardinalities properly in class diagrams', () => {
|
||||
cy.visit('http://localhost:9000/xss18.html');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should sanitize colons properly', () => {
|
||||
cy.visit('http://localhost:9000/xss20.html');
|
||||
cy.wait(1000);
|
||||
cy.get('a').click('');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
it('should sanitize colons properly', () => {
|
||||
cy.visit('http://localhost:9000/xss21.html');
|
||||
cy.wait(1000);
|
||||
cy.get('a').click('');
|
||||
cy.wait(1000);
|
||||
cy.get('#the-malware').should('not.exist');
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
})
|
||||
|
@@ -1,8 +1,10 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
describe('Class diagram V2', () => {
|
||||
it('0: should render a simple class diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
|
||||
it('0: should render a simple class diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram-v2
|
||||
|
||||
classA -- classB : Inheritance
|
||||
@@ -11,10 +13,10 @@ describe('Class diagram V2', () => {
|
||||
classB -- classD
|
||||
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('1: should render a simple class diagram', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -45,7 +47,7 @@ describe('Class diagram V2', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -74,7 +76,8 @@ describe('Class diagram V2', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -92,7 +95,7 @@ describe('Class diagram V2', () => {
|
||||
Class01 : +int publicGorilla
|
||||
Class01 : #int protectedMarmoset
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -100,7 +103,7 @@ describe('Class diagram V2', () => {
|
||||
it('should render multiple class diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
[
|
||||
`
|
||||
`
|
||||
classDiagram-v2
|
||||
Class01 "1" <|--|> "*" AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
@@ -122,7 +125,7 @@ describe('Class diagram V2', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
`
|
||||
`
|
||||
classDiagram-v2
|
||||
Class01 "1" <|--|> "*" AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
@@ -145,7 +148,7 @@ describe('Class diagram V2', () => {
|
||||
}
|
||||
`,
|
||||
],
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -175,7 +178,7 @@ describe('Class diagram V2', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -187,7 +190,7 @@ describe('Class diagram V2', () => {
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class01 : someMethod()*
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -199,7 +202,7 @@ describe('Class diagram V2', () => {
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class01 : someMethod()$
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -219,7 +222,7 @@ describe('Class diagram V2', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -240,7 +243,7 @@ describe('Class diagram V2', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -262,7 +265,7 @@ describe('Class diagram V2', () => {
|
||||
}
|
||||
link Class01 "google.com" "A Tooltip"
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -284,7 +287,7 @@ describe('Class diagram V2', () => {
|
||||
}
|
||||
callback Class01 "functionCall" "A Tooltip"
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -299,7 +302,7 @@ describe('Class diagram V2', () => {
|
||||
testArray() bool[]
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -315,7 +318,7 @@ describe('Class diagram V2', () => {
|
||||
testArray() bool[]
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -333,7 +336,7 @@ describe('Class diagram V2', () => {
|
||||
|
||||
cssClass "Class10" exClass2
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -349,7 +352,7 @@ describe('Class diagram V2', () => {
|
||||
testArray() bool[]
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -363,7 +366,7 @@ describe('Class diagram V2', () => {
|
||||
|
||||
cssClass "Class10, class20" exClass2
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -376,7 +379,7 @@ describe('Class diagram V2', () => {
|
||||
+String bar$
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -401,7 +404,7 @@ describe('Class diagram V2', () => {
|
||||
Student "1" --o "1" Bike : rides
|
||||
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -426,7 +429,7 @@ describe('Class diagram V2', () => {
|
||||
Student "1" --o "1" Bike : rides
|
||||
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -450,7 +453,7 @@ describe('Class diagram V2', () => {
|
||||
Student "1" --o "1" Bike : rides
|
||||
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -474,7 +477,7 @@ describe('Class diagram V2', () => {
|
||||
Student "1" --o "1" Bike : rides
|
||||
|
||||
`,
|
||||
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||
{logLevel : 1, flowchart: { "htmlLabels": false },}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||
|
||||
describe('Class diagram', () => {
|
||||
@@ -30,7 +31,7 @@ describe('Class diagram', () => {
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
@@ -1,9 +1,10 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Configuration and directives - nodes should be light blue', () => {
|
||||
it('No config - use default', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
it('No config - use default', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
A(Default) --> B[/Another/]
|
||||
A --> C[End]
|
||||
@@ -12,13 +13,13 @@ describe('Configuration and directives - nodes should be light blue', () => {
|
||||
C
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settigns from intitialize - nodes should be green', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settigns from intitialize - nodes should be green', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
A(Forest) --> B[/Another/]
|
||||
A --> C[End]
|
||||
@@ -26,13 +27,13 @@ graph TD
|
||||
B
|
||||
C
|
||||
end `,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
{theme:'forest'}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
|
||||
|
||||
%%{init: { 'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||
@@ -44,13 +45,13 @@ graph TD
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ theme: 'base', themeVariables: { primaryColor: '#ff0000' }, logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from directive - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
{theme:'base', themeVariables:{ primaryColor: '#ff0000'}, logLevel: 0}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from directive - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
@@ -60,14 +61,14 @@ graph TD
|
||||
C
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('Settings from directive overriding theme variable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
it('Settings from directive overriding theme variable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
@@ -77,13 +78,13 @@ graph TD
|
||||
C
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from initialize and directive - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
it('Settings from initialize and directive - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
@@ -93,13 +94,13 @@ graph TD
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
{theme:'forest'}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
@@ -109,13 +110,13 @@ graph TD
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ theme: 'base' }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Theme variable from initialize, theme from directive - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
{theme:'base'}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Theme variable from initialize, theme from directive - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'logLevel': 0, 'theme': 'base'} }%%
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
@@ -125,16 +126,16 @@ graph TD
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ themeVariables: { primaryColor: '#ff0000' } }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
describe('when rendering several diagrams', () => {
|
||||
it('diagrams should not taint later diagrams', () => {
|
||||
const url = 'http://localhost:9000/theme-directives.html';
|
||||
cy.visit(url);
|
||||
{themeVariables:{primaryColor: '#ff0000'}}
|
||||
);
|
||||
cy.get('svg');
|
||||
cy.matchImageSnapshot('conf-and-directives.spec-when-rendering-several-diagrams-diagram-1');
|
||||
});
|
||||
describe('when rendering several diagrams', () => {
|
||||
it('diagrams should not taint later diagrams', () => {
|
||||
const url = 'http://localhost:9000/theme-directives.html';
|
||||
cy.visit(url);
|
||||
cy.get('svg');
|
||||
cy.percySnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
|
@@ -1,12 +1,14 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('Flowchart', () => {
|
||||
|
||||
it('34: testing the label width in percy', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas]
|
||||
`,
|
||||
{ theme: 'forest', fontFamily: '"Noto Sans SC", sans-serif' }
|
||||
{ theme: 'forest' , fontFamily: '"Noto Sans SC", sans-serif' }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||
|
||||
describe('Entity Relationship Diagram', () => {
|
||||
@@ -8,7 +9,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -21,7 +22,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -33,7 +34,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
CUSTOMER ||--|{ ADDRESS : "invoiced at"
|
||||
CUSTOMER ||--|{ ADDRESS : "receives goods at"
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -46,7 +47,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
B ||--|{ C : likes
|
||||
C ||--|{ A : likes
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -64,7 +65,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
|
||||
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -72,18 +73,18 @@ describe('Entity Relationship Diagram', () => {
|
||||
it('should render multiple ER diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
[
|
||||
`
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
`
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
`
|
||||
],
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -96,7 +97,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
BOOK }|..|{ GENRE : " "
|
||||
AUTHOR }|..|{ GENRE : " "
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -110,15 +111,16 @@ describe('Entity Relationship Diagram', () => {
|
||||
`,
|
||||
{ er: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height', '465');
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(maxWidthValue).to.be.within(140 * 0.95, 140 * 1.05);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height', '465');
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(maxWidthValue).to.be.within(140 * .95, 140 * 1.05);
|
||||
});
|
||||
});
|
||||
|
||||
it('should render an ER when useMaxWidth is false', () => {
|
||||
@@ -130,13 +132,14 @@ describe('Entity Relationship Diagram', () => {
|
||||
`,
|
||||
{ er: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(width).to.be.within(140 * 0.95, 140 * 1.05);
|
||||
expect(svg).to.have.attr('height', '465');
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(width).to.be.within(140 * .95, 140 * 1.05);
|
||||
expect(svg).to.have.attr('height', '465');
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
|
||||
it('should render entities that have no relationships', () => {
|
||||
@@ -162,7 +165,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
AUTHOR }|..|{ BOOK : writes
|
||||
BOOK { float price }
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{ logLevel : 1 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -178,45 +181,7 @@ describe('Entity Relationship Diagram', () => {
|
||||
PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
|
||||
EMPLOYEE { bool officer_of_firm }
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render entities with keys', () => {
|
||||
renderGraph(
|
||||
`
|
||||
erDiagram
|
||||
AUTHOR_WITH_LONG_ENTITY_NAME {
|
||||
string name PK
|
||||
}
|
||||
AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
|
||||
BOOK {
|
||||
float price
|
||||
string author FK
|
||||
string title PK
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render entities with comments', () => {
|
||||
renderGraph(
|
||||
`
|
||||
erDiagram
|
||||
AUTHOR_WITH_LONG_ENTITY_NAME {
|
||||
string name "comment"
|
||||
}
|
||||
AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
|
||||
BOOK {
|
||||
string author
|
||||
string title "author comment"
|
||||
float price "price comment"
|
||||
}
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{ logLevel : 1 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -225,19 +190,11 @@ describe('Entity Relationship Diagram', () => {
|
||||
renderGraph(
|
||||
`
|
||||
erDiagram
|
||||
AUTHOR_WITH_LONG_ENTITY_NAME {
|
||||
string name PK "comment"
|
||||
}
|
||||
AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
|
||||
BOOK {
|
||||
string description
|
||||
float price "price comment"
|
||||
string title PK "title comment"
|
||||
string author FK
|
||||
}
|
||||
BOOK { string title PK "comment"}
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
{ logLevel : 1 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||
|
||||
describe('Flowchart v2', () => {
|
||||
@@ -28,7 +29,7 @@ describe('Flowchart v2', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('3: a link with correct arrowhead to a subgraph', () => {
|
||||
it('3: a link with correct arrowhead to a subgraph', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart TD
|
||||
P1
|
||||
@@ -68,7 +69,7 @@ describe('Flowchart v2', () => {
|
||||
`flowchart TD
|
||||
a["<strong>Haiya</strong>"]---->b
|
||||
`,
|
||||
{ htmlLabels: false, flowchart: { htmlLabels: false } }
|
||||
{htmlLabels: false, flowchart: {htmlLabels: false}}
|
||||
);
|
||||
});
|
||||
it('6: should render non-escaped with html labels', () => {
|
||||
@@ -76,7 +77,7 @@ describe('Flowchart v2', () => {
|
||||
`flowchart TD
|
||||
a["<strong>Haiya</strong>"]===>b
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('7: should render a flowchart when useMaxWidth is true (default)', () => {
|
||||
@@ -90,17 +91,18 @@ describe('Flowchart v2', () => {
|
||||
`,
|
||||
{ flowchart: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.be.within(290 * 0.95 - 1, 290 * 1.05);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(446 * .95, 446 * 1.05);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.be.within(290 * .95-1, 290 * 1.05);
|
||||
});
|
||||
});
|
||||
it('8: should render a flowchart when useMaxWidth is false', () => {
|
||||
renderGraph(
|
||||
@@ -113,14 +115,15 @@ describe('Flowchart v2', () => {
|
||||
`,
|
||||
{ flowchart: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||
expect(width).to.be.within(290 * 0.95 - 1, 290 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(height).to.be.within(446 * .95, 446 * 1.05);
|
||||
expect(width).to.be.within(290 * .95-1, 290 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
|
||||
it('V2 - 16: Render Stadium shape', () => {
|
||||
@@ -138,7 +141,7 @@ describe('Flowchart v2', () => {
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -153,7 +156,7 @@ describe('Flowchart v2', () => {
|
||||
b
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -168,7 +171,7 @@ describe('Flowchart v2', () => {
|
||||
b
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -189,7 +192,7 @@ describe('Flowchart v2', () => {
|
||||
B
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -219,7 +222,7 @@ describe('Flowchart v2', () => {
|
||||
routeur --> subnet1 & subnet2
|
||||
subnet1 & subnet2 --> nat --> internet
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -233,7 +236,7 @@ describe('Flowchart v2', () => {
|
||||
subcontainer-child--> subcontainer-sibling
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -255,10 +258,11 @@ end
|
||||
sub_one --> sub_two
|
||||
_one --> b
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('56: handle nested subgraphs with outgoing links 3', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart TB
|
||||
@@ -271,7 +275,7 @@ _one --> b
|
||||
end
|
||||
process_B-->|via_AWSBatch|container_Beta
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('57: handle nested subgraphs with outgoing links 4', () => {
|
||||
@@ -284,10 +288,11 @@ subgraph B
|
||||
b
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it('57: handle nested subgraphs with outgoing links 2', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart TB
|
||||
@@ -305,7 +310,7 @@ end
|
||||
three --> two
|
||||
two --> c2
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('57.x: handle nested subgraphs with outgoing links 5', () => {
|
||||
@@ -321,7 +326,7 @@ flowchart TB
|
||||
process_A-->|messages|process_C
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('58: handle styling with style expressions', () => {
|
||||
@@ -332,7 +337,7 @@ flowchart TB
|
||||
style id1 fill:#f9f,stroke:#333,stroke-width:4px
|
||||
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('59: handle styling of subgraphs and links', () => {
|
||||
@@ -354,7 +359,7 @@ flowchart TD
|
||||
class T TestSub
|
||||
linkStyle 0,1 color:orange, stroke: orange;
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('60: handle styling for all node shapes - v2', () => {
|
||||
@@ -368,7 +373,6 @@ flowchart TD
|
||||
I{{red text}} -->|default style| J[/blue text/]
|
||||
K[\\ red text\\] -->|default style| L[/blue text\\]
|
||||
M[\\ red text/] -->|default style| N[blue text];
|
||||
O(((red text))) -->|default style| P(((blue text)));
|
||||
linkStyle default color:Sienna;
|
||||
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||
style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||
@@ -384,10 +388,8 @@ flowchart TD
|
||||
style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||
style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||
style O stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||
style P stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose', logLevel:2}
|
||||
);
|
||||
});
|
||||
it('61: fontawesome icons in edge labels', () => {
|
||||
@@ -396,7 +398,7 @@ flowchart TD
|
||||
flowchart TD
|
||||
C -->|fa:fa-car Car| F[fa:fa-car Car]
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('62: should render styled subgraphs', () => {
|
||||
@@ -430,7 +432,7 @@ flowchart TD
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('63: title on subgraphs should be themable', () => {
|
||||
@@ -446,7 +448,7 @@ flowchart TD
|
||||
end
|
||||
A --> B
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('65: text-color from classes', () => {
|
||||
@@ -457,7 +459,7 @@ flowchart TD
|
||||
Lorem --> Ipsum --> Dolor
|
||||
class Lorem,Dolor dark
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('66: More nested subgraph cases (TB)', () => {
|
||||
@@ -475,7 +477,7 @@ flowchart TB
|
||||
two --> c2
|
||||
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('67: More nested subgraph cases (RL)', () => {
|
||||
@@ -493,7 +495,7 @@ flowchart RL
|
||||
two --> c2
|
||||
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('68: More nested subgraph cases (BT)', () => {
|
||||
@@ -511,7 +513,7 @@ flowchart BT
|
||||
two --> c2
|
||||
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('69: More nested subgraph cases (LR)', () => {
|
||||
@@ -529,7 +531,7 @@ flowchart LR
|
||||
two --> c2
|
||||
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('70: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
|
||||
@@ -545,7 +547,7 @@ flowchart TB
|
||||
S1 --> S2
|
||||
sub1 --> sub4
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('71: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
|
||||
@@ -561,7 +563,7 @@ flowchart RL
|
||||
S1 --> S2
|
||||
sub1 --> sub4
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('72: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
|
||||
@@ -577,7 +579,7 @@ flowchart BT
|
||||
S1 --> S2
|
||||
sub1 --> sub4
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('74: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
|
||||
@@ -593,10 +595,10 @@ flowchart RL
|
||||
S1 --> S2
|
||||
sub1 --> sub4
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
|
||||
it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
flowchart RL
|
||||
@@ -605,7 +607,7 @@ flowchart RL
|
||||
a1 -- l2 --> a2
|
||||
end
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -613,13 +615,13 @@ flowchart RL
|
||||
imgSnapshotTest(
|
||||
`flowchart TB
|
||||
a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
|
||||
--> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
|
||||
--> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
|
||||
it('2050: handling of different rendering direction in subgraphs', () => {
|
||||
it('2050: handling of different rendering direction in subgraphs', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
flowchart LR
|
||||
@@ -638,18 +640,7 @@ flowchart RL
|
||||
A --> TOP --> B
|
||||
B1 --> B2
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
);
|
||||
});
|
||||
|
||||
it('2388: handling default in the node name', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
flowchart LR
|
||||
default-index.js --> dot.template.js
|
||||
index.js --> module-utl.js
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||
|
||||
describe('Graph', () => {
|
||||
@@ -37,7 +38,7 @@ describe('Graph', () => {
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -52,7 +53,7 @@ describe('Graph', () => {
|
||||
C -->|Two| E[\\iPhone\\]
|
||||
C -->|Three| F[Car]
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -68,7 +69,7 @@ describe('Graph', () => {
|
||||
classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
|
||||
class 1A,1B,D,E processHead
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -97,7 +98,7 @@ describe('Graph', () => {
|
||||
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
|
||||
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -168,7 +169,7 @@ describe('Graph', () => {
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -177,7 +178,7 @@ describe('Graph', () => {
|
||||
`
|
||||
graph TB;subgraph "number as labels";1;end;
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -189,7 +190,7 @@ describe('Graph', () => {
|
||||
a1-->a2
|
||||
end
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -201,7 +202,7 @@ describe('Graph', () => {
|
||||
a1-->a2
|
||||
end
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -236,7 +237,7 @@ describe('Graph', () => {
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -338,7 +339,7 @@ describe('Graph', () => {
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
`,
|
||||
{ fontFamily: 'courier' }
|
||||
{ fontFamily: 'courier' }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -356,7 +357,7 @@ describe('Graph', () => {
|
||||
listUrl: false,
|
||||
listId: 'color styling',
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0,
|
||||
logLevel: 0
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -378,9 +379,8 @@ describe('Graph', () => {
|
||||
`,
|
||||
{
|
||||
listUrl: false,
|
||||
listId: 'color styling',
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0,
|
||||
listId: 'color styling', fontFamily: 'courier',
|
||||
logLevel: 0
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -395,7 +395,7 @@ describe('Graph', () => {
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -414,7 +414,7 @@ describe('Graph', () => {
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -431,7 +431,7 @@ describe('Graph', () => {
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 2 stroke:DarkGray,stroke-width:2px
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -440,7 +440,7 @@ describe('Graph', () => {
|
||||
`graph LR
|
||||
a --> b --> c
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -449,7 +449,7 @@ describe('Graph', () => {
|
||||
`graph LR
|
||||
a --> b & c--> d
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -459,7 +459,7 @@ describe('Graph', () => {
|
||||
A[ h ] -- hello --> B[" test "]:::exClass & C --> D;
|
||||
classDef exClass background:#bbb,border:1px solid red;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -481,7 +481,7 @@ describe('Graph', () => {
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -522,7 +522,7 @@ describe('Graph', () => {
|
||||
linkStyle 1 stroke:greenyellow,stroke-width:2px
|
||||
style C fill:greenyellow,stroke:green,stroke-width:4px
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -545,7 +545,7 @@ describe('Graph', () => {
|
||||
click F "javascript:alert('test')" "script test"
|
||||
`,
|
||||
{ securityLevel: 'loose', fontFamily: 'courier' }
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
it('26: Set text color of nodes and links according to styles when html labels are enabled', () => {
|
||||
@@ -584,7 +584,7 @@ describe('Graph', () => {
|
||||
click B "index.html#link-clicked" "link test"
|
||||
click D testClick "click test"
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -616,7 +616,7 @@ describe('Graph', () => {
|
||||
class A myClass1
|
||||
class D myClass2
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -640,7 +640,7 @@ describe('Graph', () => {
|
||||
classDef redBg fill:#622;
|
||||
classDef whiteTxt color: white;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -652,7 +652,7 @@ describe('Graph', () => {
|
||||
eat --> sleep
|
||||
work --> eat
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -671,7 +671,7 @@ describe('Graph', () => {
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -694,7 +694,7 @@ describe('Graph', () => {
|
||||
`graph TD
|
||||
A[Christmas]
|
||||
`,
|
||||
{}
|
||||
{ }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -712,7 +712,7 @@ describe('Graph', () => {
|
||||
C -----> E4
|
||||
C ======> E5
|
||||
`,
|
||||
{}
|
||||
{ }
|
||||
);
|
||||
});
|
||||
it('36: should render escaped without html labels', () => {
|
||||
@@ -720,7 +720,7 @@ describe('Graph', () => {
|
||||
`graph TD
|
||||
a["<strong>Haiya</strong>"]-->b
|
||||
`,
|
||||
{ htmlLabels: false, flowchart: { htmlLabels: false } }
|
||||
{htmlLabels: false, flowchart: {htmlLabels: false}}
|
||||
);
|
||||
});
|
||||
it('37: should render non-escaped with html labels', () => {
|
||||
@@ -728,7 +728,7 @@ describe('Graph', () => {
|
||||
`graph TD
|
||||
a["<strong>Haiya</strong>"]-->b
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('38: should render a flowchart when useMaxWidth is true (default)', () => {
|
||||
@@ -742,17 +742,18 @@ describe('Graph', () => {
|
||||
`,
|
||||
{ flowchart: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.be.within(300 * 0.95, 300 * 1.05);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(446 * .95, 446 * 1.05);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.be.within(300 * .95, 300 * 1.05);
|
||||
});
|
||||
});
|
||||
it('39: should render a flowchart when useMaxWidth is false', () => {
|
||||
renderGraph(
|
||||
@@ -765,14 +766,15 @@ describe('Graph', () => {
|
||||
`,
|
||||
{ flowchart: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||
expect(width).to.be.within(300 * 0.95, 300 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(height).to.be.within(446 * .95, 446 * 1.05);
|
||||
expect(width).to.be.within(300 * .95, 300 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
it('58: handle styling with style expressions', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -782,7 +784,7 @@ describe('Graph', () => {
|
||||
style id1 fill:#f9f,stroke:#333,stroke-width:4px
|
||||
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('60: handle styling for all node shapes', () => {
|
||||
@@ -806,7 +808,7 @@ describe('Graph', () => {
|
||||
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('61: fontawesome icons in edge labels', () => {
|
||||
@@ -815,7 +817,7 @@ describe('Graph', () => {
|
||||
graph TD
|
||||
C -->|fa:fa-car Car| F[fa:fa-car Car]
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('62: fontawesome icons in edge labels', () => {
|
||||
@@ -827,7 +829,7 @@ graph TD
|
||||
end
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('63: fontawesome icons in edge labels', () => {
|
||||
@@ -861,7 +863,7 @@ graph TD
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('64: fontawesome icons in edge labels', () => {
|
||||
@@ -877,7 +879,7 @@ graph TD
|
||||
end
|
||||
A --> B
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
it('65: text-color from classes', () => {
|
||||
@@ -888,7 +890,7 @@ graph TD
|
||||
Lorem --> Ipsum --> Dolor
|
||||
class Lorem,Dolor dark
|
||||
`,
|
||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -1,9 +1,10 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||
|
||||
describe('Gantt diagram', () => {
|
||||
beforeEach(() => {
|
||||
cy.clock(new Date('1010-10-10').getTime());
|
||||
});
|
||||
beforeEach(()=>{
|
||||
cy.clock((new Date('1010-10-10')).getTime())
|
||||
})
|
||||
it('should render a gantt chart', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -198,17 +199,18 @@ describe('Gantt diagram', () => {
|
||||
`,
|
||||
{ gantt: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.be.within(984 * 0.95, 984 * 1.05);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(484 * .95, 484 * 1.05);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.be.within(984 * .95, 984 * 1.05);
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a gantt diagram when useMaxWidth is false', () => {
|
||||
@@ -246,16 +248,17 @@ describe('Gantt diagram', () => {
|
||||
`,
|
||||
{ gantt: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
|
||||
expect(width).to.be.within(984 * 0.95, 984 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(height).to.be.within(484 * .95, 484 * 1.05);
|
||||
expect(width).to.be.within(984 * .95, 984 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
it('should render a gantt diagram with data labels at the top when topAxis is true', () => {
|
||||
it('should render a gantt diagram with data labels at the top when topAxis is true', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
|
@@ -1,105 +1,21 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Git Graph diagram', () => {
|
||||
it('1: should render a simple gitgraph with commit on main branch', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
commit id: "3"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('2: should render a simple gitgraph with commit on main branch with Id', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "One"
|
||||
commit id: "Two"
|
||||
commit id: "Three"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('3: should render a simple gitgraph with different commitTypes on main branch ', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "Normal Commit"
|
||||
commit id: "Reverse Commit" type: REVERSE
|
||||
commit id: "Hightlight Commit" type: HIGHLIGHT
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('4: should render a simple gitgraph with tags commitTypes on main branch ', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "Normal Commit with tag" tag: "v1.0.0"
|
||||
commit id: "Reverse Commit with tag" type: REVERSE tag: "RC_1"
|
||||
commit id: "Hightlight Commit" type: HIGHLIGHT tag: "8.8.4"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('5: should render a simple gitgraph with two branches', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('6: should render a simple gitgraph with two branches and merge commit', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id: "3"
|
||||
commit id: "4"
|
||||
checkout main
|
||||
merge develop
|
||||
commit id: "5"
|
||||
commit id: "6"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('7: should render a simple gitgraph with three branches and merge commit', () => {
|
||||
imgSnapshotTest(
|
||||
`gitGraph
|
||||
commit id: "1"
|
||||
commit id: "2"
|
||||
branch nice_feature
|
||||
checkout nice_feature
|
||||
commit id: "3"
|
||||
checkout main
|
||||
commit id: "4"
|
||||
checkout nice_feature
|
||||
branch very_nice_feature
|
||||
checkout very_nice_feature
|
||||
commit id: "5"
|
||||
checkout main
|
||||
commit id: "6"
|
||||
checkout nice_feature
|
||||
commit id: "7"
|
||||
checkout main
|
||||
merge nice_feature
|
||||
checkout very_nice_feature
|
||||
commit id: "8"
|
||||
checkout main
|
||||
commit id: "9"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
describe('Sequencediagram', () => {
|
||||
// it('should render a simple git graph', () => {
|
||||
// imgSnapshotTest(
|
||||
// `
|
||||
// gitGraph:
|
||||
// commit
|
||||
// branch newbranch
|
||||
// checkout newbranch
|
||||
// commit
|
||||
// commit
|
||||
// checkout master
|
||||
// commit
|
||||
// commit
|
||||
// merge newbranch`,
|
||||
// { logLevel: 0 }
|
||||
// );
|
||||
// });
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Sequencediagram', () => {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||
|
||||
describe('User journey diagram', () => {
|
||||
@@ -39,16 +40,17 @@ section Checkout from website
|
||||
`,
|
||||
{ journey: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.eq(565);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.eq(700);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.eq(565);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.eq(700);
|
||||
});
|
||||
});
|
||||
|
||||
it('should render a user journey diagram when useMaxWidth is false', () => {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||
|
||||
describe('Pie Chart', () => {
|
||||
@@ -46,16 +47,17 @@ describe('Pie Chart', () => {
|
||||
`,
|
||||
{ pie: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.eq(450);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.eq(984);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.eq(450);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
expect(maxWidthValue).to.eq(984);
|
||||
});
|
||||
});
|
||||
it('should render a pie diagram when useMaxWidth is false', () => {
|
||||
renderGraph(
|
||||
@@ -67,12 +69,13 @@ describe('Pie Chart', () => {
|
||||
`,
|
||||
{ pie: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.eq(450);
|
||||
expect(width).to.eq(984);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.eq(450);
|
||||
expect(width).to.eq(984);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||
|
||||
describe('Requirement diagram', () => {
|
||||
|
@@ -29,7 +29,7 @@ context('Sequence diagram', () => {
|
||||
Alice -->> John: Parallel message 2
|
||||
end
|
||||
`,
|
||||
{ sequence: { actorFontFamily: 'courier' } }
|
||||
{sequence:{actorFontFamily:'courier'}}
|
||||
);
|
||||
});
|
||||
it('should handle different line breaks', () => {
|
||||
@@ -71,7 +71,7 @@ context('Sequence diagram', () => {
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
})
|
||||
it('should render loops with a slight margin', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -147,7 +147,7 @@ context('Sequence diagram', () => {
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
{logLevel: 0}
|
||||
);
|
||||
});
|
||||
it('should wrap (inline) long actor descriptions', () => {
|
||||
@@ -158,7 +158,7 @@ context('Sequence diagram', () => {
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
{logLevel: 0}
|
||||
);
|
||||
});
|
||||
it('should wrap (directive) long actor descriptions', () => {
|
||||
@@ -527,17 +527,17 @@ context('Sequence diagram', () => {
|
||||
});
|
||||
it('should render with an init directive', () => {
|
||||
imgSnapshotTest(
|
||||
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
|
||||
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can!
|
||||
Note left of Alice: Bob thinks
|
||||
Bob->>Alice: Fine!`,
|
||||
{}
|
||||
);
|
||||
)
|
||||
});
|
||||
});
|
||||
context('directives', () => {
|
||||
it('should override config with directive settings', () => {
|
||||
it('should override config with directive settings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": true }}}%%
|
||||
@@ -546,13 +546,10 @@ context('Sequence diagram', () => {
|
||||
note left of Alice: config set to mirrorActors: false<br/>directive set to mirrorActors: true
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
|
||||
}
|
||||
{ logLevel:0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
it('should override config with directive settings 2', () => {
|
||||
it('should override config with directive settings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": false, "wrap": true }}}%%
|
||||
@@ -561,13 +558,13 @@ context('Sequence diagram', () => {
|
||||
note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
{ logLevel:0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
context('links', () => {
|
||||
it('should support actor links and properties EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||
//Be aware that the syntax for "properties" is likely to be changed.
|
||||
//Be aware that the syntax for "properties" is likely to be changed.
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": true, "forceMenus": true }}}%%
|
||||
@@ -588,7 +585,7 @@ context('Sequence diagram', () => {
|
||||
);
|
||||
});
|
||||
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||
//Be aware that the syntax for "properties" is likely to be changed.
|
||||
//Be aware that the syntax for "properties" is likely to be changed.
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": false, "forceMenus": true, "wrap": true }}}%%
|
||||
@@ -604,10 +601,7 @@ context('Sequence diagram', () => {
|
||||
a->>j: Hello John, how are you?
|
||||
j-->>a: Great!
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
|
||||
}
|
||||
{ logLevel: 0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -640,17 +634,18 @@ context('Sequence diagram', () => {
|
||||
`,
|
||||
{ sequence: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(920, 960);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(920, 960);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(maxWidthValue).to.be.within(820 * .95, 820 * 1.05);
|
||||
});
|
||||
});
|
||||
it('should render a sequence diagram when useMaxWidth is false', () => {
|
||||
renderGraph(
|
||||
@@ -680,14 +675,15 @@ context('Sequence diagram', () => {
|
||||
`,
|
||||
{ sequence: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.be.within(920, 960);
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(width).to.be.within(820 * 0.95, 820 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.be.within(920, 960);
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(width).to.be.within(820 * .95, 820 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
@@ -158,7 +159,7 @@ describe('State diagram', () => {
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a simple state diagrams 2', () => {
|
||||
it('v2 should render a simple state diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
@@ -350,7 +351,7 @@ describe('State diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
state "Long state name 2" as NotShooting {
|
||||
state "Long state name" as NotShooting {
|
||||
a-->b
|
||||
}
|
||||
`,
|
||||
@@ -359,18 +360,6 @@ stateDiagram-v2
|
||||
}
|
||||
);
|
||||
});
|
||||
it('v2 state label with names in it', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
Yswsii: Your state with spaces in it
|
||||
[*] --> Yswsii
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
it('v2 Simplest composite state', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -380,8 +369,7 @@ stateDiagram-v2
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier'
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -393,8 +381,7 @@ stateDiagram-v2
|
||||
a --> b: Stop
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier',
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -407,8 +394,7 @@ stateDiagram-v2
|
||||
note right of MyState : I am a rightie
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier',
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -428,8 +414,7 @@ stateDiagram-v2
|
||||
A --> C
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier',
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -448,8 +433,7 @@ stateDiagram-v2
|
||||
sub1 --> sub4
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier',
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -463,17 +447,18 @@ stateDiagram-v2
|
||||
`,
|
||||
{ state: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(177, 178);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(maxWidthValue).to.be.within(135 * 0.95, 135 * 1.05);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(177, 178);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(maxWidthValue).to.be.within(135 * .95, 135 * 1.05);
|
||||
});
|
||||
});
|
||||
it('v2 should render a state diagram when useMaxWidth is false', () => {
|
||||
renderGraph(
|
||||
@@ -485,13 +470,14 @@ stateDiagram-v2
|
||||
`,
|
||||
{ state: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.be.within(177, 178);
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(width).to.be.within(135 * 0.95, 135 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.be.within(177, 178);
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
expect(width).to.be.within(135 * .95, 135 * 1.05);
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
@@ -148,7 +149,7 @@ describe('State diagram', () => {
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple state diagrams 2', () => {
|
||||
it('should render a simple state diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
@@ -314,8 +315,7 @@ describe('State diagram', () => {
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier'
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -328,8 +328,7 @@ describe('State diagram', () => {
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier'
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -341,8 +340,7 @@ describe('State diagram', () => {
|
||||
a --> b: Stop
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
fontFamily: 'courier',
|
||||
logLevel: 0, fontFamily: 'courier'
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -355,19 +353,20 @@ describe('State diagram', () => {
|
||||
`,
|
||||
{ state: { useMaxWidth: true } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(176, 178);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
// Todo investigate difference
|
||||
// expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
|
||||
expect(maxWidthValue).to.be.within(130, 140);
|
||||
});
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
expect(svg).to.have.attr('width', '100%');
|
||||
expect(svg).to.have.attr('height');
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
expect(height).to.be.within(176,178);
|
||||
const style = svg.attr('style');
|
||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
// Todo investigate difference
|
||||
// expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
|
||||
expect(maxWidthValue).to.be.within(130, 140);
|
||||
});
|
||||
});
|
||||
it('should render a state diagram when useMaxWidth is false', () => {
|
||||
renderGraph(
|
||||
@@ -378,16 +377,17 @@ describe('State diagram', () => {
|
||||
`,
|
||||
{ state: { useMaxWidth: false } }
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.be.within(176, 178);
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
// Todo investigate difference
|
||||
// expect(width).to.be.within(112 * .95, 112 * 1.05);
|
||||
expect(width).to.be.within(130, 140);
|
||||
cy.get('svg')
|
||||
.should((svg) => {
|
||||
const height = parseFloat(svg.attr('height'));
|
||||
const width = parseFloat(svg.attr('width'));
|
||||
expect(height).to.be.within(176,178);
|
||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||
// Todo investigate difference
|
||||
// expect(width).to.be.within(112 * .95, 112 * 1.05);
|
||||
expect(width).to.be.within(130, 140);
|
||||
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
expect(svg).to.not.have.attr('style');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,36 +1,12 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('themeCSS balancing, it', () => {
|
||||
it('should not allow unbalanced CSS definitions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'themeCSS': '} * { background: red }' } }%%
|
||||
flowchart TD
|
||||
a --> b
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should not allow unbalanced CSS definitions 2', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'themeCSS': '\u007D * { background: red }' } }%%
|
||||
flowchart TD
|
||||
a2 --> b2
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Pie Chart', () => {
|
||||
// beforeEach(()=>{
|
||||
// cy.clock((new Date('2014-06-09')).getTime());
|
||||
// });
|
||||
// beforeEach(()=>{
|
||||
// cy.clock((new Date('2014-06-09')).getTime());
|
||||
// });
|
||||
|
||||
['default', 'forest', 'dark', 'neutral'].forEach((theme) => {
|
||||
['default', 'forest', 'dark', 'neutral'].forEach(theme=>{
|
||||
describe(theme, () => {
|
||||
it('should render a pie diagram', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -40,7 +16,7 @@ describe('Pie Chart', () => {
|
||||
"Ice-Hockey" : 80
|
||||
"Football" : 90
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -63,7 +39,7 @@ describe('Pie Chart', () => {
|
||||
G
|
||||
end
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -86,7 +62,7 @@ describe('Pie Chart', () => {
|
||||
G
|
||||
end
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -112,7 +88,7 @@ describe('Pie Chart', () => {
|
||||
|
||||
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
@@ -159,10 +135,10 @@ describe('Pie Chart', () => {
|
||||
classM ..|> classN : Realization
|
||||
classO .. classP : Link(Dashed)
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
it('should render a state diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -191,10 +167,10 @@ stateDiagram
|
||||
Active --> SomethingElse
|
||||
note right of SomethingElse : This is the note to the right.
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
it('should render a state diagram (v2)', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -223,10 +199,10 @@ stateDiagram-v2
|
||||
Active --> SomethingElse2
|
||||
note right of SomethingElse2 : This is the note to the right.
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
it('should render a er diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -241,10 +217,10 @@ erDiagram
|
||||
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
|
||||
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
it('should render a user journey diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -259,12 +235,12 @@ erDiagram
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
it('should render a gantt diagram', () => {
|
||||
cy.clock(new Date('2014-01-06').getTime());
|
||||
cy.clock((new Date('2014-01-06')).getTime());
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
@@ -295,10 +271,10 @@ erDiagram
|
||||
Add gantt diagram to demo page :20h
|
||||
Add another diagram to demo page :48h
|
||||
`,
|
||||
{ theme }
|
||||
{theme}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -30,29 +30,30 @@ if (location.href.match('test-html-escaping')) {
|
||||
code = code3;
|
||||
}
|
||||
|
||||
|
||||
mermaid.initialize({
|
||||
theme: 'default',
|
||||
// fontFamily: '"Lucida Console", Monaco, monospace',
|
||||
startOnLoad: false,
|
||||
securityLevel: 'loose',
|
||||
flowchart: {
|
||||
htmlLabels: true,
|
||||
htmlLabels: true
|
||||
},
|
||||
gantt: {
|
||||
axisFormatter: [
|
||||
[
|
||||
'%Y-%m-%d',
|
||||
(d) => {
|
||||
d => {
|
||||
return d.getDay() === 1;
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
});
|
||||
mermaid.render(
|
||||
'the-id-of-the-svg',
|
||||
code,
|
||||
(svg) => {
|
||||
svg => {
|
||||
console.log(svg);
|
||||
const elem = document.querySelector('#graph-to-be');
|
||||
elem.innerHTML = svg;
|
||||
|
@@ -115,14 +115,14 @@
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
theme: 'default',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'linear', htmlLabels: true },
|
||||
flowchart: { curve: 'linear', "htmlLabels": true },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
@@ -131,11 +131,9 @@
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// },
|
||||
curve: 'linear',
|
||||
securityLevel: 'loose',
|
||||
securityLevel: 'loose'
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
function callback(){alert('It worked');}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -130,39 +130,39 @@
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Flow';
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByFlowArg(argument) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-click-2';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Flow: ' + argument;
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click-2'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow: ' + argument
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByGantt(arg1, arg2, arg3) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-gant-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Gant';
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-gant-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Gant'
|
||||
if (arg1) div.innerText += ' ' + arg1;
|
||||
if (arg2) div.innerText += ' ' + arg2;
|
||||
if (arg3) div.innerText += ' ' + arg3;
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByClass(arg) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-class-click';
|
||||
div.style = 'padding: 20px; background: purple; color: white;';
|
||||
div.innerText = 'Clicked By Class' + (arg ? arg : '');
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-class-click'
|
||||
div.style = 'padding: 20px; background: purple; color: white;'
|
||||
div.innerText = 'Clicked By Class' + (arg?arg:'')
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
|
||||
</script>
|
||||
|
@@ -62,20 +62,20 @@
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Flow';
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByGantt(elemName) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-gant-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Gant';
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-gant-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Gant'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'strct', logLevel: 1 });
|
||||
</script>
|
||||
|
@@ -1,170 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<style>
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="display: flex">
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
Function-->URL
|
||||
click Function clickByFlow "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
1Function--->2URL
|
||||
click 1Function clickByFlow "Add a div"
|
||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
flowchart TB
|
||||
Function-->URL
|
||||
click Function clickByFlow "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>" _self
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
flowchart TB
|
||||
1Function--->2URL
|
||||
click 1Function clickByFlow "Add a div"
|
||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>" _self
|
||||
</div>
|
||||
|
||||
<div id="FirstLine" class="mermaid">
|
||||
classDiagram
|
||||
class ShapeLink
|
||||
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||
class ShapeCallback
|
||||
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
classDiagram-v2
|
||||
class ShapeLink2
|
||||
link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||
class ShapeCallback2
|
||||
callback ShapeCallback2 "clickByClass" "This is a tooltip for a callback"
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Clickable
|
||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
Calling a Callback with args :cl3, after cl1, 3d
|
||||
|
||||
click cl1 href "http://localhost:9000/webpackUsage.html"
|
||||
click cl2 call clickByGantt()
|
||||
click cl3 call clickByGantt("test1", test2, test3)
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
FunctionArg-->URL
|
||||
click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
flowchart TB
|
||||
FunctionArg-->URL
|
||||
click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
|
||||
<div id="FirstLine" class="mermaid">
|
||||
classDiagram
|
||||
class ShapeLink
|
||||
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||
class ShapeCallback
|
||||
click ShapeCallback call clickByClass(123) "This is a tooltip for a callback"
|
||||
</div>
|
||||
|
||||
<div id="FirstLine" class="mermaid">
|
||||
classDiagram-v2
|
||||
class ShapeLink2
|
||||
link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||
class ShapeCallback2
|
||||
click ShapeCallback2 call clickByClass(123) "This is a tooltip for a callback"
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Flow';
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
function clickByFlowArg(argument) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-click-2';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Flow: ' + argument;
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
function clickByGantt(arg1, arg2, arg3) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-gant-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Gant';
|
||||
if (arg1) div.innerText += ' ' + arg1;
|
||||
if (arg2) div.innerText += ' ' + arg2;
|
||||
if (arg3) div.innerText += ' ' + arg3;
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
function clickByClass(arg) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-class-click';
|
||||
div.style = 'padding: 20px; background: purple; color: white;';
|
||||
div.innerText = 'Clicked By Class' + (arg ? arg : '');
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'sandbox', logLevel: 1 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -64,23 +64,23 @@
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Flow';
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByGantt(arg1, arg2, arg3) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'created-by-gant-click';
|
||||
div.style = 'padding: 20px; background: green; color: white;';
|
||||
div.innerText = 'Clicked By Gant';
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-gant-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Gant'
|
||||
if (arg1) div.innerText += ' ' + arg1;
|
||||
if (arg2) div.innerText += ' ' + arg2;
|
||||
if (arg3) div.innerText += ' ' + arg3;
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'strict', logLevel: 1 });
|
||||
</script>
|
||||
|
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid2">
|
||||
%%{init: { 'themeCSS': '} * { background: lightblue }' } }%%
|
||||
flowchart TD
|
||||
a --> b
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
%%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
|
||||
flowchart LR
|
||||
subgraph A
|
||||
a --> b
|
||||
end
|
||||
subgraph B
|
||||
i -->f
|
||||
end
|
||||
A --> B
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function showFullFirstSquad(elemName) {
|
||||
console.log('show ' + elemName);
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 0 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -155,25 +155,23 @@ _one --> b
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
// theme: 'forest',
|
||||
// themeVariables:{primaryColor: '#ff0000'},
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'cardinal', htmlLabels: true },
|
||||
flowchart: { curve: 'cardinal', "htmlLabels": true },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
fontFamily: '"arial", sans-serif',
|
||||
curve: 'cardinal',
|
||||
securityLevel: 'strict',
|
||||
securityLevel: 'strict'
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
function callback(){alert('It worked');}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -107,25 +107,23 @@ Note over Bob,Alice: Looks back
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
// theme: 'forest',
|
||||
// themeVariables:{primaryColor: '#ff0000'},
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'cardinal', htmlLabels: false },
|
||||
flowchart: { curve: 'cardinal', "htmlLabels": false },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
fontFamily: '"arial", sans-serif',
|
||||
curve: 'cardinal',
|
||||
securityLevel: 'strict',
|
||||
securityLevel: 'strict'
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
function callback(){alert('It worked');}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,52 +1,52 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<!-- <meta charset="iso-8859-15"/> -->
|
||||
<script src="/e2e.js"></script>
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
/* font-family: 'Mansalva', cursive;*/
|
||||
/* font-family: 'Mansalva', cursive; */
|
||||
/* font-family: 'arial'; */
|
||||
/* font-family: "trebuchet ms", verdana, arial; */
|
||||
}
|
||||
/* div {
|
||||
font-family: 'arial';
|
||||
} */
|
||||
/* .mermaid-main-font {
|
||||
font-family: "trebuchet ms", verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
} */
|
||||
/* :root {
|
||||
--mermaid-font-family: '"trebuchet ms", verdana, arial';
|
||||
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
--mermaid-font-family: '"Lucida Console", Monaco, monospace';
|
||||
} */
|
||||
svg {
|
||||
border: 2px solid darkred;
|
||||
}
|
||||
.exClass2 > rect, .exClass {
|
||||
fill: greenyellow !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
// Notice startOnLoad=false
|
||||
// This prevents default handling in mermaid from render before the e2e logic is applied
|
||||
// mermaid.initialize({
|
||||
// startOnLoad: false,
|
||||
// useMaxWidth: true,
|
||||
// // "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
|
||||
// // fontFamily: '\"trebuchet ms\", verdana, arial;'
|
||||
// // fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
|
||||
// // fontFamily: '"Mansalva", cursive',
|
||||
// // fontFamily: '"Noto Sans SC", sans-serif'
|
||||
// fontFamily: '"Noto Sans SC", sans-serif'
|
||||
// });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<!-- <meta charset="iso-8859-15"/> -->
|
||||
<script src="/e2e.js"></script>
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
/* font-family: 'Mansalva', cursive;*/
|
||||
/* font-family: 'Mansalva', cursive; */
|
||||
/* font-family: 'arial'; */
|
||||
/* font-family: "trebuchet ms", verdana, arial; */
|
||||
}
|
||||
/* div {
|
||||
font-family: 'arial';
|
||||
} */
|
||||
/* .mermaid-main-font {
|
||||
font-family: "trebuchet ms", verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
} */
|
||||
/* :root {
|
||||
--mermaid-font-family: '"trebuchet ms", verdana, arial';
|
||||
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
--mermaid-font-family: '"Lucida Console", Monaco, monospace';
|
||||
} */
|
||||
svg {
|
||||
border: 2px solid darkred;
|
||||
}
|
||||
.exClass2 > rect, .exClass {
|
||||
fill: greenyellow !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
// Notice startOnLoad=false
|
||||
// This prevents default handling in mermaid from render before the e2e logic is applied
|
||||
// mermaid.initialize({
|
||||
// startOnLoad: false,
|
||||
// useMaxWidth: true,
|
||||
// // "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
|
||||
// // fontFamily: '\"trebuchet ms\", verdana, arial;'
|
||||
// // fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
|
||||
// // fontFamily: '"Mansalva", cursive',
|
||||
// // fontFamily: '"Noto Sans SC", sans-serif'
|
||||
// fontFamily: '"Noto Sans SC", sans-serif'
|
||||
// });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,46 +1,46 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2-->a3
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
a_a --> b_b:::apa --> c_c:::apa
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
|
||||
a_a --> c --> d_d --> c_c
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
click a_a "http://www.aftonbladet.se" "apa"
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
flowchart: { curve: 'linear' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2-->a3
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
a_a --> b_b:::apa --> c_c:::apa
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
|
||||
a_a --> c --> d_d --> c_c
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
click a_a "http://www.aftonbladet.se" "apa"
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
flowchart: { curve: 'linear' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,67 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
background: rgb(221, 208, 208);
|
||||
/*background:#333;*/
|
||||
font-family: 'Arial';
|
||||
}
|
||||
h1 { color: white;}
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
.customCss > rect, .customCss{
|
||||
fill:#FF0000 !important;
|
||||
stroke:#FFFF00 !important;
|
||||
stroke-width:4px !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||
|
||||
gitGraph
|
||||
class BankAccount{
|
||||
+String owner
|
||||
+BigDecimal balance
|
||||
+deposit(amount) bool
|
||||
+withdrawl(amount) int
|
||||
}
|
||||
cssClass "BankAccount" customCss
|
||||
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
theme: 'default',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'linear', htmlLabels: true },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// themeVariables: {
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// },
|
||||
curve: 'linear',
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,143 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
/* background: rgb(221, 208, 208); */
|
||||
background:#111;
|
||||
/* background:#333; */
|
||||
font-family: 'Arial';
|
||||
}
|
||||
/* h1 { color: white;} */
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
.customCss > rect, .customCss{
|
||||
fill:#FF0000 !important;
|
||||
stroke:#FFFF00 !important;
|
||||
stroke-width:4px !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||
%%{init: { "logLevel": "debug", "theme": "default" , "gitGraph" : {"showBranches":"false"},"themeVariables": {
|
||||
"gitBranchLabel0": "#ff0000",
|
||||
"gitBranchLabel1": "#00ff00",
|
||||
"gitBranchLabel2": "#0000ff",
|
||||
"git0": "#550055"
|
||||
} } }%%
|
||||
gitGraph
|
||||
commit
|
||||
branch develop
|
||||
commit tag:"v1.0.0"
|
||||
commit
|
||||
checkout main
|
||||
commit type: HIGHLIGHT
|
||||
commit
|
||||
merge develop
|
||||
commit
|
||||
branch featureA
|
||||
commit
|
||||
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||
gitGraph
|
||||
commit type:HIGHLIGHT
|
||||
branch hotfix
|
||||
checkout hotfix
|
||||
commit type:HIGHLIGHT
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id:"ash" tag:"abc" type:HIGHLIGHT
|
||||
branch featureB
|
||||
checkout featureB
|
||||
commit type:HIGHLIGHT
|
||||
checkout main
|
||||
checkout hotfix
|
||||
commit type:HIGHLIGHT
|
||||
checkout develop
|
||||
commit type:REVERSE
|
||||
checkout featureB
|
||||
commit type:HIGHLIGHT
|
||||
checkout main
|
||||
merge hotfix
|
||||
checkout featureB
|
||||
commit type:HIGHLIGHT
|
||||
checkout develop
|
||||
branch featureA
|
||||
commit type:HIGHLIGHT
|
||||
checkout develop
|
||||
checkout featureA
|
||||
commit
|
||||
checkout featureB
|
||||
commit
|
||||
checkout develop
|
||||
merge featureA
|
||||
branch release
|
||||
checkout release
|
||||
commit type:HIGHLIGHT
|
||||
checkout main
|
||||
commit
|
||||
checkout release
|
||||
merge main
|
||||
checkout develop
|
||||
merge release
|
||||
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||
gitGraph:
|
||||
commit
|
||||
commit
|
||||
branch newbranch
|
||||
commit
|
||||
merge main
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
//theme: 'dark',
|
||||
themeVariables: {
|
||||
commitLabelColor: '#9400D3',
|
||||
commitLabelBackground: '#FFFFFF',
|
||||
// darkMode: true,
|
||||
// background: '#222',
|
||||
// // textColor: 'white',
|
||||
// // primaryTextColor: '#f4f4f4',
|
||||
|
||||
// // // nodeBkg: '#ff0000',
|
||||
// // // mainBkg: '#0000ff',
|
||||
// // // tertiaryColor: '#ffffcc',
|
||||
},
|
||||
// theme: 'forest',
|
||||
// theme: 'neutral',
|
||||
// theme: 'dark',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 1,
|
||||
flowchart: { curve: 'linear', htmlLabels: true },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// themeVariables: {
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// },
|
||||
curve: 'linear',
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,139 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
/* background: rgb(221, 208, 208); */
|
||||
/* background:#111; */
|
||||
/* background:#333; */
|
||||
font-family: 'Arial';
|
||||
}
|
||||
/* h1 { color: white;} */
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
.customCss > rect, .customCss{
|
||||
fill:#FF0000 !important;
|
||||
stroke:#FFFF00 !important;
|
||||
stroke-width:4px !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||
gitGraph:
|
||||
commit "Ashish"
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit id:"1111"
|
||||
commit tag:"test"
|
||||
checkout main
|
||||
commit type: HIGHLIGHT
|
||||
commit
|
||||
merge newbranch
|
||||
commit
|
||||
branch b2
|
||||
commit
|
||||
|
||||
</div>
|
||||
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||
%%{init: { "gitGraph": { "showBranches": true, "mainBranchName": "APA" }}}%%
|
||||
gitGraph
|
||||
commit
|
||||
branch hotfix
|
||||
checkout hotfix
|
||||
commit
|
||||
branch develop
|
||||
checkout develop
|
||||
commit id:"An id" tag:"A tag"
|
||||
branch featureB
|
||||
checkout featureB
|
||||
commit type:HIGHLIGHT
|
||||
checkout APA
|
||||
checkout hotfix
|
||||
commit type:NORMAL
|
||||
checkout develop
|
||||
commit type:REVERSE
|
||||
checkout featureB
|
||||
commit
|
||||
checkout APA
|
||||
merge hotfix
|
||||
checkout featureB
|
||||
commit
|
||||
checkout develop
|
||||
branch featureA
|
||||
commit
|
||||
checkout develop
|
||||
merge hotfix
|
||||
checkout featureA
|
||||
commit
|
||||
checkout featureB
|
||||
commit
|
||||
checkout develop
|
||||
merge featureA
|
||||
branch release
|
||||
checkout release
|
||||
commit
|
||||
checkout APA
|
||||
commit
|
||||
checkout release
|
||||
merge APA
|
||||
checkout develop
|
||||
merge release
|
||||
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||
gitGraph:
|
||||
commit
|
||||
commit
|
||||
branch newbranch
|
||||
commit
|
||||
merge main
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
theme: 'default',
|
||||
themeVariables: {
|
||||
// primaryColor: '#9400D3',
|
||||
// darkMode: false,
|
||||
// background: '#222',
|
||||
// textColor: 'white',
|
||||
// primaryTextColor: '#f4f4f4',
|
||||
// nodeBkg: '#ff0000',
|
||||
// mainBkg: '#0000ff',
|
||||
// tertiaryColor: '#ffffcc',
|
||||
},
|
||||
// theme: 'forest',
|
||||
// theme: 'neutral',
|
||||
// theme: 'dark',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 1,
|
||||
flowchart: { curve: 'linear', htmlLabels: true },
|
||||
// gitGraph: { showCommitLabel: false },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// themeVariables: {
|
||||
// fontFamily: '"arial", sans-serif',
|
||||
// },
|
||||
curve: 'linear',
|
||||
securityLevel: 'loose',
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -29,7 +29,7 @@
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'linear', htmlLabels: false },
|
||||
flowchart: { curve: 'linear', "htmlLabels": false },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user