mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-31 19:04:16 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			8.13.8
			...
			feature/Ad
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a69b7090cc | 
| @@ -1,5 +0,0 @@ | ||||
| { | ||||
|     "extends": [ | ||||
|         "@commitlint/config-conventional" | ||||
|     ] | ||||
| } | ||||
| @@ -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"] | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										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@v2.3.4 | ||||
|       - name: Validate Configuration | ||||
|         uses: Yash-Singh1/pr-labeler-config-validator@releases/v0.0.3 | ||||
|         with: | ||||
|           configuration-path: .github/pr-labeler.yml | ||||
							
								
								
									
										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@v2 | ||||
|       - run: npx browserslist@latest --update-db | ||||
|       - name: Commit changes | ||||
|         uses: EndBug/add-and-commit@v7 | ||||
|         with: | ||||
|           author_name: ${{ github.actor }} | ||||
|           author_email: ${{ github.actor }}@users.noreply.github.com | ||||
|           message: 'Update Browserslist' | ||||
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.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 | ||||
|   | ||||
| @@ -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,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', | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
| }); | ||||
| @@ -204,7 +204,7 @@ pie | ||||
| - [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. | ||||
|  | ||||
|   | ||||
| @@ -201,7 +201,7 @@ pie | ||||
| - [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)。 | ||||
|  | ||||
|   | ||||
| @@ -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,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); | ||||
|   | ||||
| @@ -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'); | ||||
|     }); | ||||
|   | ||||
| @@ -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,113 +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'); | ||||
|   }); | ||||
| }); | ||||
|   }) | ||||
|  | ||||
| }) | ||||
|   | ||||
| @@ -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.percySnapshot(); | ||||
|     }); | ||||
|     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,7 +181,7 @@ describe('Entity Relationship Diagram', () => { | ||||
|         PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs | ||||
|         EMPLOYEE { bool officer_of_firm } | ||||
|       `, | ||||
|       { logLevel: 1 } | ||||
|       { logLevel : 1 } | ||||
|     ); | ||||
|     cy.get('svg'); | ||||
|   }); | ||||
| @@ -189,8 +192,9 @@ describe('Entity Relationship Diagram', () => { | ||||
|     erDiagram | ||||
|         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', () => { | ||||
| @@ -384,7 +389,7 @@ flowchart TD | ||||
|       style M stroke:#ff0000,fill:#ffcccc,color:#ff0000; | ||||
|       style N 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', () => { | ||||
| @@ -393,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', () => { | ||||
| @@ -427,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', () => { | ||||
| @@ -443,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', () => { | ||||
| @@ -454,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)', () => { | ||||
| @@ -472,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)', () => { | ||||
| @@ -490,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)', () => { | ||||
| @@ -508,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)', () => { | ||||
| @@ -526,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', () => { | ||||
| @@ -542,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', () => { | ||||
| @@ -558,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', () => { | ||||
| @@ -574,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', () => { | ||||
| @@ -590,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 | ||||
| @@ -602,7 +607,7 @@ flowchart RL | ||||
|       a1 -- l2 --> a2 | ||||
|     end | ||||
|       `, | ||||
|       { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } | ||||
|       {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'} | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
| @@ -610,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 | ||||
| @@ -635,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,3 +1,4 @@ | ||||
| /* eslint-env jest */ | ||||
| import { imgSnapshotTest } from '../../helpers/util.js'; | ||||
|  | ||||
| describe('Sequencediagram', () => { | ||||
|   | ||||
| @@ -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', () => { | ||||
|       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', () => { | ||||
| @@ -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', () => { | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -90,31 +90,31 @@ | ||||
|   <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) | ||||
|   } | ||||
|   function clickByClass() { | ||||
|     const div = document.createElement('div'); | ||||
|     div.className = 'created-by-class-click'; | ||||
|     div.style = 'padding: 20px; background: purple; color: white;'; | ||||
|     div.innerText = 'Clicked By Class'; | ||||
|     const div = document.createElement('div') | ||||
|     div.className = 'created-by-class-click' | ||||
|     div.style = 'padding: 20px; background: purple; color: white;' | ||||
|     div.innerText = 'Clicked By Class' | ||||
|  | ||||
|     document.getElementsByTagName('body')[0].appendChild(div); | ||||
|     document.getElementsByTagName('body')[0].appendChild(div) | ||||
|   } | ||||
|   mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 }); | ||||
|   </script> | ||||
|   | ||||
| @@ -28,43 +28,142 @@ | ||||
|     <div>info below</div> | ||||
|     <div class="flex flex-wrap"> | ||||
|  | ||||
| <div class="mermaid" style="width: 100%; height: 20%;"> | ||||
| stateDiagram-v2 | ||||
|       [*] --> S1 | ||||
|       state "Some long name" as S1 | ||||
| <div class="mermaid2" style="width: 100%; height: 20%;"> | ||||
| classDiagram | ||||
|   direction TB | ||||
|   class Student { | ||||
|     -idCard : IdCard | ||||
|   } | ||||
|   class IdCard{ | ||||
|     -id : int | ||||
|     -name : string | ||||
|   } | ||||
|   class Bike{ | ||||
|     -id : int | ||||
|     -name : string | ||||
|   } | ||||
|   Student "1" --o "1" IdCard : carries | ||||
|   Student "1" --o "1" Bike : rides | ||||
|  | ||||
| </div> | ||||
| <div class="mermaid3" style="width: 100%; height: 20%;"> | ||||
| stateDiagram | ||||
|   state CompositeState { | ||||
|       YourState123456789012345123456789123456789012345123456789123456789012345123456789123456789012345123456789 --> MyState:a label | ||||
|     } | ||||
|  | ||||
| </div> | ||||
| <div class="mermaid" style="width: 100%; height: 20%;"> | ||||
| sequenceDiagram | ||||
|   %%{init: {'config': {'wrap': true }}}%% | ||||
|   actor Alice as Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be | ||||
|   actor Bob | ||||
|   participant John as John2 | ||||
|   participant Mandy | ||||
|   Alice->>Bob: Hi Bob | ||||
|   Bob->>Alice: Hi Alice | ||||
|   Alice->>John: Hi John | ||||
|   John->>Mandy: Hi Mandy | ||||
|   Mandy ->>Joan: Hi Joan | ||||
|  | ||||
| </div> | ||||
| <div class="mermaid" style="width: 100%; height: 20%;"> | ||||
| %%{int: { "apa":"b", "theme":"forest"}}%% | ||||
| sequenceDiagram | ||||
| Alice->>Bob: Hi Bob | ||||
| Bob->>Alice: Hi Alice | ||||
| </div> | ||||
| <div class="mermaid"> | ||||
| sequenceDiagram | ||||
|   autonumber | ||||
|   par Action 1 | ||||
|     Alice->>John: Hello John, how are you? | ||||
|   and Action 2 | ||||
|     Alice->>Bob: Hello Bob, how are you? | ||||
|   end | ||||
|   Alice->>+John: Hello John, how are you? | ||||
|   Alice->>+John: John, can you hear me? | ||||
|   John-->>-Alice: Hi Alice, I can hear you! | ||||
|   Note right of John: John is perceptive | ||||
|   John-->>-Alice: I feel great! | ||||
|       loop Every minute | ||||
|         John-->Alice: Great! | ||||
|     end | ||||
| </div> | ||||
| <div class="mermaid"> | ||||
| sequenceDiagram | ||||
|   %%{init: {'config': {'wrap': true }}}%% | ||||
|   actor Alice | ||||
|   actor Bob | ||||
|   Alice->>Bob: Hi Bob | ||||
|   Bob->>Alice: Hi Alice | ||||
| </div> | ||||
| <div class="mermaid" style="width: 100%; height: 20%;"> | ||||
|         %%{init: {'config': {'wrap': true }}}%% | ||||
|         sequenceDiagram | ||||
|         participant A as Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be | ||||
|         A->>Bob: Hola | ||||
|         Bob-->A: Pasten ! | ||||
|   </div> | ||||
| <div class="mermaid2" style="width: 100%; height: 20%;"> | ||||
| stateDiagram-v2 | ||||
| state CS { | ||||
| state ACS { | ||||
| YourState | ||||
| } | ||||
| } | ||||
|   </div> | ||||
| <div class="mermaid2" style="width: 100%; height: 20%;"> | ||||
|       stateDiagram-v2 | ||||
|         [*] --> Active | ||||
|  | ||||
|         state Active { | ||||
|             [*] --> NumLockOff | ||||
|             NumLockOff --> NumLockOn : EvNumLockPressed | ||||
|             NumLockOn --> NumLockOff : EvNumLockPressed | ||||
|             -- | ||||
|             [*] --> CapsLockOff | ||||
|             CapsLockOff --> CapsLockOn : EvCapsLockPressed | ||||
|             CapsLockOn --> CapsLockOff : EvCapsLockPressed | ||||
|         } | ||||
|         state SomethingElse { | ||||
|           A --> B | ||||
|           B --> A | ||||
|         } | ||||
|  | ||||
|         Active --> SomethingElse | ||||
|         note right of SomethingElse : This is the note to the right. | ||||
|  | ||||
|         SomethingElse --> [*]  </div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         // theme: 'dark', | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 2, | ||||
|         flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: false }, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         state: { | ||||
|         state:{ | ||||
|           nodeSpacing: 50, | ||||
|           rankSpacing: 50, | ||||
|           defaultRenderer: 'dagre-wrapper', | ||||
|         }, | ||||
|         logLevel: 0, | ||||
|         logLevel:0, | ||||
|         fontSize: 18, | ||||
|         curve: 'cardinal', | ||||
|         securityLevel: 'strict', | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function callback(){alert('It worked');} | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -46,8 +46,8 @@ | ||||
|   <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', | ||||
|         arrowMarkerAbsolute: true, | ||||
| @@ -58,39 +58,35 @@ | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|           nodeSpacing: 10, curve: 'cardinal', htmlLabels: true | ||||
|         }, | ||||
|         htmlLabels: false, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'strict', | ||||
|         startOnLoad: false, | ||||
|         startOnLoad: false | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function callback(){alert('It worked');} | ||||
|  | ||||
|       var diagram = '%%{init: {"flowchart": {"htmlLabels": "false"}} }%%\n'; | ||||
| diagram += 'flowchart\n'; | ||||
| diagram += 'A["<ifra'; | ||||
| diagram += "me srcdoc='<scrip"; | ||||
| diagram += 't src=http://localhost:9000/exploit.js>'; | ||||
| diagram += '</scr'; | ||||
| diagram += 'ipt>\'></iframe>"]'; | ||||
|       var diagram = "%%{init: {\"flowchart\": {\"htmlLabels\": \"false\"}} }%%\n"; | ||||
|   diagram += "flowchart\n"; | ||||
|   diagram += "A[\"<ifra"; | ||||
|   diagram += "me srcdoc='<scrip"; | ||||
|   diagram += "t src=http://localhost:9000/exploit.js>"; | ||||
|   diagram += "</scr" | ||||
|   diagram += "ipt>'></iframe>\"]"; | ||||
|  | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|   console.log(diagram); | ||||
|   // document.querySelector('#diagram').innerHTML = diagram; | ||||
|   mermaid.render('diagram', diagram, (res) => { | ||||
|     document.querySelector('#res').innerHTML = res; | ||||
|   }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -185,8 +185,8 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'neutral', | ||||
|         arrowMarkerAbsolute: true, | ||||
| @@ -195,7 +195,7 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff | ||||
|         flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
| @@ -204,9 +204,7 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff | ||||
|         securityLevel: 'loose', | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function callback(){alert('It worked');} | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -3,9 +3,10 @@ | ||||
|     <script src="http://localhost:9000/mermaid.js"></script> | ||||
|   <script> | ||||
|       mermaid.initialize({ | ||||
|         theme: 'base', | ||||
|         themeVariables: {}, | ||||
|         startOnLoad: true, | ||||
|        theme: 'base', | ||||
|        themeVariables: { | ||||
|       }, | ||||
|       startOnLoad: true, | ||||
|       }); | ||||
|   </script> | ||||
|  | ||||
|   | ||||
| @@ -11,16 +11,21 @@ | ||||
|         </div> | ||||
|  | ||||
|         <script src="./mermaid.js"></script> | ||||
|         <script>mermaid.init({ startOnLoad: false }); | ||||
|         <script> | ||||
|  | ||||
|          mermaid.init({ startOnLoad: false }); | ||||
|          mermaid.mermaidAPI.initialize(); | ||||
|  | ||||
|          try { | ||||
|            mermaid.mermaidAPI.render('graphDiv', `>`); | ||||
|          } catch (e) {} | ||||
|          try{ | ||||
|              mermaid.mermaidAPI.render("graphDiv", | ||||
|                                        `>`); | ||||
|          } catch(e){} | ||||
|  | ||||
|          mermaid.mermaidAPI.render('graphDiv', `graph LR\n a --> b`, (html) => { | ||||
|            document.getElementById('graph').innerHTML = html; | ||||
|          mermaid.mermaidAPI.render("graphDiv", | ||||
|                                    `graph LR\n a --> b`, html => { | ||||
|                                       document.getElementById('graph').innerHTML=html; | ||||
|          }); | ||||
|  | ||||
|         </script> | ||||
|  | ||||
|     </body> | ||||
|   | ||||
| @@ -11,18 +11,21 @@ | ||||
| </div> | ||||
|  | ||||
|   <script src="./mermaid.js"></script> | ||||
|   <script>mermaid.init({ startOnLoad: false }); | ||||
|   <script> | ||||
|  | ||||
|     mermaid.init({ startOnLoad: false }); | ||||
|     mermaid.mermaidAPI.initialize(); | ||||
|  | ||||
|     rerender('XMas'); | ||||
|  | ||||
|     function rerender(text) { | ||||
|       var graphText = `graph TD | ||||
|         A[${text}] -->|Get money| B(Go shopping)`; | ||||
|         A[${text}] -->|Get money| B(Go shopping)` | ||||
|       var graph = mermaid.mermaidAPI.render('id', graphText); | ||||
|       console.log('\x1b[35m%s\x1b[0m', '>> graph', graph); | ||||
|       document.getElementById('graph').innerHTML = graph; | ||||
|       console.log('\x1b[35m%s\x1b[0m', '>> graph', graph) | ||||
|       document.getElementById('graph').innerHTML=graph; | ||||
|     } | ||||
|  | ||||
|   </script> | ||||
|   <button id="rerender" onclick="rerender('Saturday')">Rerender</button> | ||||
|  | ||||
|   | ||||
							
								
								
									
										67
									
								
								cypress/platform/scratch/logicbeat/ashish.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								cypress/platform/scratch/logicbeat/ashish.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         width: 100%; | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2,.mermaid3 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>info below</div> | ||||
|     <div class="flex flex-wrap"> | ||||
|  | ||||
| <div class="mermaid" style="width: 100%; height: 20%;"> | ||||
|   flowchart LR | ||||
|     A(Ashu) --> B | ||||
|     C(^actor^) --> B | ||||
| </div> | ||||
|   <script src="/mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         // theme: 'dark', | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 2, | ||||
|         flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: false }, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         state:{ | ||||
|           nodeSpacing: 50, | ||||
|           rankSpacing: 50, | ||||
|           defaultRenderer: 'dagre-wrapper', | ||||
|         }, | ||||
|         logLevel:0, | ||||
|         fontSize: 18, | ||||
|         curve: 'cardinal', | ||||
|         securityLevel: 'strict', | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback(){alert('It worked');} | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
| @@ -267,25 +267,23 @@ requirementDiagram | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'base', | ||||
|         // themeVariables: | ||||
|         // 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> | ||||
|   | ||||
| @@ -262,24 +262,15 @@ requirementDiagram | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'base', | ||||
|         themeVariables: { | ||||
|     primaryColor: '#9400D3', | ||||
|     darkMode: true, | ||||
|     background: '#222', | ||||
|     textColor: 'white', | ||||
|     primaryTextColor: '#f4f4f4', | ||||
|     nodeBkg: '#ff0000', | ||||
|     mainBkg: '#0000ff', | ||||
|     tertiaryColor: '#ffffcc', | ||||
|   }, | ||||
|         themeVariables: { primaryColor: '#9400D3', darkMode: true, background: '#222', textColor:'white', primaryTextColor: '#f4f4f4', nodeBkg: '#ff0000', mainBkg:'#0000ff', tertiaryColor:'#ffffcc' }, | ||||
|         // 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 | ||||
| @@ -287,9 +278,7 @@ requirementDiagram | ||||
|         curve: 'cardinal', | ||||
|         // securityLevel: 'strict' | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function callback(){alert('It worked');} | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -259,24 +259,22 @@ requirementDiagram | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'dark', | ||||
|         // 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> | ||||
|   | ||||
| @@ -254,24 +254,22 @@ requirementDiagram | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         // theme: 'dark', | ||||
|         // 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> | ||||
|   | ||||
| @@ -258,24 +258,22 @@ requirementDiagram | ||||
|   <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', | ||||
|         // 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> | ||||
|   | ||||
| @@ -257,24 +257,22 @@ requirementDiagram | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'neutral', | ||||
|         // 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> | ||||
|   | ||||
| @@ -37,9 +37,9 @@ | ||||
|   <script src="./mermaid.js"></script> | ||||
|   <script> | ||||
|      function showFullFirstSquad(elemName) { | ||||
|        console.log('show ' + elemName); | ||||
|      } | ||||
|      mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 }); | ||||
|             console.log('show ' + elemName); | ||||
|         } | ||||
|         mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 }); | ||||
|   </script> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
| @@ -120,8 +120,8 @@ | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|           // console.error('Mermaid error: ', err); | ||||
|         }; | ||||
|       mermaid.initialize({ | ||||
|         // theme: 'dark', | ||||
|         // theme: 'dark', | ||||
| @@ -129,7 +129,7 @@ | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         // flowchart: { useMaxWidth: true }, | ||||
|         graph: { curve: 'cardinal', htmlLabels: false }, | ||||
|         graph: { curve: 'cardinal', "htmlLabels": false }, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorMargin: 50, showSequenceNumbers: true }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
| @@ -137,9 +137,7 @@ | ||||
|         curve: 'cardinal', | ||||
|         securityLevel: 'strict', | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function callback(){alert('It worked');} | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -29,9 +29,9 @@ | ||||
|   <script src="./mermaid.js"></script> | ||||
|   <script> | ||||
|      function showFullFirstSquad(elemName) { | ||||
|        console.log('show ' + elemName); | ||||
|      } | ||||
|      mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 }); | ||||
|             console.log('show ' + elemName); | ||||
|         } | ||||
|         mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 }); | ||||
|   </script> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
| @@ -2,10 +2,11 @@ import { Base64 } from 'js-base64'; | ||||
| import mermaid2 from '../../src/mermaid'; | ||||
|  | ||||
| /** | ||||
|  * ##contentLoaded Callback function that is called when page is loaded. This functions fetches | ||||
|  * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the page. | ||||
|  * ##contentLoaded | ||||
|  * Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and | ||||
|  * calls init for rendering the mermaid diagrams on the page. | ||||
|  */ | ||||
| const contentLoaded = function () { | ||||
| const contentLoaded = function() { | ||||
|   let pos = document.location.href.indexOf('?graph='); | ||||
|   if (pos > 0) { | ||||
|     pos = pos + 7; | ||||
| @@ -37,12 +38,8 @@ const contentLoaded = function () { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * @param current | ||||
|  * @param update | ||||
|  */ | ||||
| function merge(current, update) { | ||||
|   Object.keys(update).forEach(function (key) { | ||||
|   Object.keys(update).forEach(function(key) { | ||||
|     // if update[key] exist, and it's not a string or array, | ||||
|     // we go in one level deeper | ||||
|     if ( | ||||
| @@ -61,7 +58,7 @@ function merge(current, update) { | ||||
|   return current; | ||||
| } | ||||
|  | ||||
| const contentLoadedApi = function () { | ||||
| const contentLoadedApi = function() { | ||||
|   let pos = document.location.href.indexOf('?graph='); | ||||
|   if (pos > 0) { | ||||
|     pos = pos + 7; | ||||
| @@ -128,7 +125,7 @@ if (typeof document !== 'undefined') { | ||||
|    */ | ||||
|   window.addEventListener( | ||||
|     'load', | ||||
|     function () { | ||||
|     function() { | ||||
|       if (this.location.href.match('xss.html')) { | ||||
|         this.console.log('Using api'); | ||||
|         contentLoadedApi(); | ||||
|   | ||||
| @@ -23,11 +23,11 @@ | ||||
|       } | ||||
|     </style> | ||||
|     <script> | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|       function xssAttack(){ | ||||
|         const div = document.createElement('div') | ||||
|         div.id = 'the-malware' | ||||
|         div.className = 'malware' | ||||
|         div.innerHTML = 'XSS Succeeded' | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         // const el = document.querySelector('.mermaid'); | ||||
|         // el.parentNode.removeChild(el); | ||||
|   | ||||
| @@ -1,108 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|       .malware { | ||||
|         position: fixed; | ||||
|         bottom:0; | ||||
|         left:0; | ||||
|         right:0; | ||||
|         height: 150px; | ||||
|         background: red; | ||||
|         color: black; | ||||
|         display: flex; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         font-family: monospace; | ||||
|         font-size: 72px; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>Security check</div> | ||||
|     <div class="flex"> | ||||
|       <div id="diagram" class="mermaid"></div> | ||||
|       <div id="res" class=""></div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         state: { | ||||
|           defaultRenderer: 'dagre-d3', | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|         }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'antiscript', | ||||
|         startOnLoad: false, | ||||
|         secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         throw new Error('XSS Succeded'); | ||||
|       } | ||||
|  | ||||
|       var diagram = 'classDiagram\n'; | ||||
| diagram += 'class Square~<img/src'; | ||||
| diagram += "='1'/onerror=xssAttack()>~{\n"; | ||||
| diagram += 'id A\n'; | ||||
| diagram += '}'; | ||||
|  | ||||
| //   var diagram = "stateDiagram-v2\n"; | ||||
| //  diagram += "<img/src='1'/onerror" | ||||
| //  diagram += "=xssAttack()> --> B"; | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   console.log(res); | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @@ -1,106 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|       .malware { | ||||
|         position: fixed; | ||||
|         bottom:0; | ||||
|         left:0; | ||||
|         right:0; | ||||
|         height: 150px; | ||||
|         background: red; | ||||
|         color: black; | ||||
|         display: flex; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         font-family: monospace; | ||||
|         font-size: 72px; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>Security check</div> | ||||
|     <div class="flex"> | ||||
|       <div id="diagram" class="mermaid"></div> | ||||
|       <div id="res" class=""></div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         state: { | ||||
|           defaultRenderer: 'dagre-d3', | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|         }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'antiscript', | ||||
|         startOnLoad: false, | ||||
|         secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         throw new Error('XSS Succeded'); | ||||
|       } | ||||
|  | ||||
| var diagram = 'stateDiagram-v2\n'; | ||||
| diagram += 's2 : This is a state description<img/src'; | ||||
| diagram += "='1'/onerror=xssAttack()>"; | ||||
|  | ||||
| //   var diagram = "stateDiagram-v2\n"; | ||||
| //  diagram += "<img/src='1'/onerror" | ||||
| //  diagram += "=xssAttack()> --> B"; | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   console.log(res); | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @@ -1,106 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|       .malware { | ||||
|         position: fixed; | ||||
|         bottom:0; | ||||
|         left:0; | ||||
|         right:0; | ||||
|         height: 150px; | ||||
|         background: red; | ||||
|         color: black; | ||||
|         display: flex; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         font-family: monospace; | ||||
|         font-size: 72px; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>Security check</div> | ||||
|     <div class="flex"> | ||||
|       <div id="diagram" class="mermaid"></div> | ||||
|       <div id="res" class=""></div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         state: { | ||||
|           defaultRenderer: 'dagre-d3', | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|         }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'antiscript', | ||||
|         startOnLoad: false, | ||||
|         secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         throw new Error('XSS Succeded'); | ||||
|       } | ||||
|  | ||||
| var diagram = 'stateDiagram-v2\n'; | ||||
| diagram += 's2 : A<img/src'; | ||||
| diagram += "='1'/onerror=xssAttack()>"; | ||||
|  | ||||
| //   var diagram = "stateDiagram-v2\n"; | ||||
| //  diagram += "<img/src='1'/onerror" | ||||
| //  diagram += "=xssAttack()> --> B"; | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   console.log(res); | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @@ -1,106 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|       .malware { | ||||
|         position: fixed; | ||||
|         bottom:0; | ||||
|         left:0; | ||||
|         right:0; | ||||
|         height: 150px; | ||||
|         background: red; | ||||
|         color: black; | ||||
|         display: flex; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         font-family: monospace; | ||||
|         font-size: 72px; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>Security check</div> | ||||
|     <div class="flex"> | ||||
|       <div id="diagram" class="mermaid"></div> | ||||
|       <div id="res" class=""></div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         state: { | ||||
|           defaultRenderer: 'dagre-d3', | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|         }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'antiscript', | ||||
|         startOnLoad: false, | ||||
|         secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         throw new Error('XSS Succeded'); | ||||
|       } | ||||
|  | ||||
| var diagram = 'stateDiagram-v2\n'; | ||||
| diagram += 'if_state --> False: if n < 0<img/src'; | ||||
| diagram += "='1'/onerror=xssAttack()>"; | ||||
|  | ||||
| //   var diagram = "stateDiagram-v2\n"; | ||||
| //  diagram += "<img/src='1'/onerror" | ||||
| //  diagram += "=xssAttack()> --> B"; | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   console.log(res); | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @@ -1,108 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|       .malware { | ||||
|         position: fixed; | ||||
|         bottom:0; | ||||
|         left:0; | ||||
|         right:0; | ||||
|         height: 150px; | ||||
|         background: red; | ||||
|         color: black; | ||||
|         display: flex; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         font-family: monospace; | ||||
|         font-size: 72px; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>Security check</div> | ||||
|     <div class="flex"> | ||||
|       <div id="diagram" class="mermaid"></div> | ||||
|       <div id="res" class=""></div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         state: { | ||||
|           defaultRenderer: 'dagre-d3', | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|         }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'antiscript', | ||||
|         startOnLoad: false, | ||||
|         secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         throw new Error('XSS Succeded'); | ||||
|       } | ||||
|  | ||||
|       var diagram = 'classDiagram\n'; | ||||
| diagram += 'classA <-- classB : <ifr'; | ||||
| diagram += "ame/srcdoc='<scr"; | ||||
| diagram += 'ipt>parent.xssAttack(`XSS`)</'; | ||||
| diagram += "script>'>"; | ||||
|  | ||||
| //   var diagram = "stateDiagram-v2\n"; | ||||
| //  diagram += "<img/src='1'/onerror" | ||||
| //  diagram += "=xssAttack()> --> B"; | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   console.log(res); | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @@ -1,107 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" 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'; | ||||
|         /* font-size: 18px !important; */ | ||||
|         } | ||||
|       h1 { color: grey;} | ||||
|       .mermaid2 { | ||||
|         display: none; | ||||
|       } | ||||
|       .mermaid svg { | ||||
|         /* font-size: 18px !important; */ | ||||
|       } | ||||
|       .malware { | ||||
|         position: fixed; | ||||
|         bottom:0; | ||||
|         left:0; | ||||
|         right:0; | ||||
|         height: 150px; | ||||
|         background: red; | ||||
|         color: black; | ||||
|         display: flex; | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         font-family: monospace; | ||||
|         font-size: 72px; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div>Security check</div> | ||||
|     <div class="flex"> | ||||
|       <div id="diagram" class="mermaid"></div> | ||||
|       <div id="res" class=""></div> | ||||
|   <script src="./mermaid.js"></script> | ||||
|     <script> | ||||
|       mermaid.parseError = function (err, hash) { | ||||
|         // console.error('Mermaid error: ', err); | ||||
|       }; | ||||
|       mermaid.initialize({ | ||||
|         theme: 'forest', | ||||
|         arrowMarkerAbsolute: true, | ||||
|         // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', | ||||
|         logLevel: 0, | ||||
|         state: { | ||||
|           defaultRenderer: 'dagre-d3', | ||||
|         }, | ||||
|         flowchart: { | ||||
|           // defaultRenderer: 'dagre-wrapper', | ||||
|           nodeSpacing: 10, | ||||
|     curve: 'cardinal', | ||||
|     htmlLabels: true, | ||||
|         }, | ||||
|         htmlLabels: true, | ||||
|         // gantt: { axisFormat: '%m/%d/%Y' }, | ||||
|         sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, | ||||
|         // sequenceDiagram: { actorMargin: 300 } // deprecated | ||||
|         // fontFamily: '"times", sans-serif', | ||||
|         // fontFamily: 'courier', | ||||
|         fontSize: 18, | ||||
|         curve: 'basis', | ||||
|         securityLevel: 'strict', | ||||
|         startOnLoad: false, | ||||
|         secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'], | ||||
|         // themeVariables: {relationLabelColor: 'red'} | ||||
|       }); | ||||
|       function callback() { | ||||
|   alert('It worked'); | ||||
| } | ||||
|       function xssAttack() { | ||||
|         const div = document.createElement('div'); | ||||
|         div.id = 'the-malware'; | ||||
|         div.className = 'malware'; | ||||
|         div.innerHTML = 'XSS Succeeded'; | ||||
|         document.getElementsByTagName('body')[0].appendChild(div); | ||||
|         throw new Error('XSS Succeded'); | ||||
|       } | ||||
|  | ||||
|       var diagram = `sequenceDiagram | ||||
|     participant John | ||||
|     links John: {"XSS": "javas`; | ||||
| diagram += `cript:alert('AudioParam')"}`; | ||||
|  | ||||
| //   var diagram = "stateDiagram-v2\n"; | ||||
| //  diagram += "<img/src='1'/onerror" | ||||
| //  diagram += "=xssAttack()> --> B"; | ||||
| console.log(diagram); | ||||
| // document.querySelector('#diagram').innerHTML = diagram; | ||||
| mermaid.render('diagram', diagram, (res) => { | ||||
|   console.log(res); | ||||
|   document.querySelector('#res').innerHTML = res; | ||||
| }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user