-English | [简体中文](./README.zh-CN.md)
+
+
+
+[![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid)
+[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml)
+[![npm minified gzipped bundle size](https://img.shields.io/bundlephobia/minzip/mermaid)](https://bundlephobia.com/package/mermaid)
+[![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master)
+[![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid)
+[![NPM Downloads](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid)
+[![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
+[![Twitter Follow](https://img.shields.io/badge/Social-mermaidjs__-blue?style=social&logo=twitter)](https://twitter.com/mermaidjs_)
@@ -27,14 +56,12 @@ Mermaid addresses this problem by enabling users to create easily modifiable dia
Mermaid allows even non-programmers to easily create detailed diagrams through the [Mermaid Live Editor](https://mermaid.live/).
[Tutorials](./docs/config/Tutorials.md) has video tutorials.
-Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/misc/integrations.md).
+Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/ecosystem/integrations.md).
-You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/misc/integrations.md).
+You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/ecosystem/integrations.md).
For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/community/n00b-overview.md), [Usage](./docs/config/usage.md) and [Tutorials](./docs/config/Tutorials.md).
-🌐 [CDN](https://www.jsdelivr.com/package/npm/mermaid) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [Changelog](./docs/CHANGELOG.md)
-
In our release process we rely heavily on visual regression tests using [applitools](https://applitools.com/). Applitools is a great service which has been easy to use and integrate with our tests.
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 415b4bf3e..2653ac72b 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,8 +1,37 @@
-# mermaid
+
Mermaid 甚至能让非程序员也能通过 [Mermaid Live Editor](https://mermaid.live/) 轻松创建详细的图表。
-你可以访问 [教程](./docs/config/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/misc/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
+你可以访问 [教程](./docs/config/Tutorials.md) 来查看 Live Editor 的视频教程,也可以查看 [Mermaid 的集成和使用](./docs/ecosystem/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/community/n00b-overview.md), [用法](./docs/config/usage.md) 和 [教程](./docs/config/Tutorials.md).
-🌐 [CDN](https://www.jsdelivr.com/package/npm/mermaid) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md)
-
## 示例
@@ -325,7 +352,7 @@ _很不幸的是,鱼与熊掌不可兼得,在这个场景下它意味着在
来自 Knut Sveidqvist:
-> _特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库! _ >_同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。_ >_感谢 [Tyler Long](https://github.com/tylerlong) 从 2017 年四月开始成为了项目的合作者。_
+> _特别感谢 [d3](https://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库!_ > _同样感谢 [js-sequence-diagram](https://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。_ > _感谢 [Tyler Long](https://github.com/tylerlong) 从 2017 年四月开始成为了项目的合作者。_
>
> _感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!_
diff --git a/V10-BreakingChanges.md b/V10-BreakingChanges.md
deleted file mode 100644
index bd9110d1a..000000000
--- a/V10-BreakingChanges.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# A collection of updates that change the behaviour
-
-## Lazy loading and asynchronisity
-
-- Invalid dates are rendered as syntax error instead of returning best guess or the current date
diff --git a/cSpell.json b/cSpell.json
index b3da99863..2bca06807 100644
--- a/cSpell.json
+++ b/cSpell.json
@@ -6,6 +6,7 @@
"adamiecki",
"alois",
"antiscript",
+ "appli",
"applitools",
"asciidoctor",
"ashish",
@@ -13,6 +14,7 @@
"bbox",
"bilkent",
"bisheng",
+ "blrs",
"braintree",
"brkt",
"brolin",
@@ -25,12 +27,14 @@
"cuzon",
"cytoscape",
"dagre",
+ "deepdwn",
"descr",
"docsify",
"docsy",
"doku",
"dompurify",
"edgechromium",
+ "elkjs",
"faber",
"flatmap",
"ftplugin",
@@ -39,6 +43,7 @@
"gitgraph",
"globby",
"graphlib",
+ "graphviz",
"grav",
"greywolf",
"inkdrop",
@@ -52,8 +57,10 @@
"knut",
"laganeckas",
"lintstagedrc",
+ "logmsg",
"lucida",
"matthieu",
+ "mdast",
"mdbook",
"mermerd",
"mindaugas",
@@ -70,6 +77,7 @@
"pnpm",
"podlite",
"quence",
+ "radious",
"ranksep",
"rect",
"rects",
@@ -79,17 +87,20 @@
"setupgraphviewbox",
"shiki",
"sidharth",
+ "sidharthv",
"sphinxcontrib",
"statediagram",
"stylis",
"substate",
"sveidqvist",
+ "swimm",
"techn",
"teststr",
"textlength",
"treemap",
"ts-nocheck",
"tuleap",
+ "ugge",
"unist",
"verdana",
"viewports",
diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js
index 5213f634a..533cca499 100644
--- a/cypress/helpers/util.js
+++ b/cypress/helpers/util.js
@@ -2,7 +2,7 @@ const utf8ToB64 = (str) => {
return window.btoa(unescape(encodeURIComponent(str)));
};
-const batchId = 'mermid-batch' + new Date().getTime();
+const batchId = 'mermaid-batch' + new Date().getTime();
export const mermaidUrl = (graphStr, options, api) => {
const obj = {
@@ -46,8 +46,22 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) =>
if (!options.fontSize) {
options.fontSize = '16px';
}
+ const url = mermaidUrl(graphStr, options, api);
+ openURLAndVerifyRendering(url, options, validation);
+};
+
+export const urlSnapshotTest = (url, _options, api = false, validation) => {
+ const options = Object.assign(_options);
+ openURLAndVerifyRendering(url, options, validation);
+};
+
+export const renderGraph = (graphStr, options, api) => {
+ const url = mermaidUrl(graphStr, options, api);
+ openURLAndVerifyRendering(url, options);
+};
+
+const openURLAndVerifyRendering = (url, options, validation = undefined) => {
const useAppli = Cypress.env('useAppli');
- cy.log('Hello ' + useAppli ? 'Appli' : 'image-snapshot');
const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
if (useAppli) {
@@ -60,82 +74,20 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) =>
});
}
- const url = mermaidUrl(graphStr, options, api);
-
cy.visit(url);
+ cy.window().should('have.property', 'rendered', true);
+ cy.get('svg').should('be.visible');
+
if (validation) {
cy.get('svg').should(validation);
}
- cy.get('svg');
- // Default name to test title
if (useAppli) {
cy.log('Check eyes' + Cypress.spec.name);
cy.eyesCheckWindow('Click!');
- cy.log('Closing eyes: ' + Cypress.spec.name);
+ cy.log('Closing eyes' + Cypress.spec.name);
cy.eyesClose();
} else {
cy.matchImageSnapshot(name);
}
};
-
-export const urlSnapshotTest = (url, _options, api = false, validation) => {
- cy.log(_options);
- const options = Object.assign(_options);
- if (!options.fontFamily) {
- options.fontFamily = 'courier';
- }
- if (!options.sequence) {
- options.sequence = {};
- }
- if (!options.sequence || (options.sequence && !options.sequence.actorFontFamily)) {
- options.sequence.actorFontFamily = 'courier';
- }
- if (options.sequence && !options.sequence.noteFontFamily) {
- options.sequence.noteFontFamily = 'courier';
- }
- options.sequence.actorFontFamily = 'courier';
- options.sequence.noteFontFamily = 'courier';
- options.sequence.messageFontFamily = 'courier';
- if (options.sequence && !options.sequence.actorFontFamily) {
- options.sequence.actorFontFamily = 'courier';
- }
- if (!options.fontSize) {
- options.fontSize = '16px';
- }
- const useAppli = Cypress.env('useAppli');
- cy.log('Hello ' + useAppli ? 'Appli' : 'image-snapshot');
- const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
-
- if (useAppli) {
- cy.log('Opening eyes 2' + Cypress.spec.name);
- cy.eyesOpen({
- appName: 'Mermaid',
- testName: name,
- batchName: Cypress.spec.name,
- batchId: batchId + Cypress.spec.name,
- });
- }
-
- cy.visit(url);
- if (validation) {
- cy.get('svg').should(validation);
- }
- cy.get('body');
- // Default name to test title
-
- if (useAppli) {
- cy.log('Check eyes 2' + Cypress.spec.name);
- cy.eyesCheckWindow('Click!');
- cy.log('Closing eyes 2' + Cypress.spec.name);
- cy.eyesClose();
- } else {
- cy.matchImageSnapshot(name);
- }
-};
-
-export const renderGraph = (graphStr, options, api) => {
- const url = mermaidUrl(graphStr, options, api);
-
- cy.visit(url);
-};
diff --git a/cypress/integration/other/external-diagrams.spec.js b/cypress/integration/other/external-diagrams.spec.js
index be69dfc98..c94235162 100644
--- a/cypress/integration/other/external-diagrams.spec.js
+++ b/cypress/integration/other/external-diagrams.spec.js
@@ -2,8 +2,8 @@ import { urlSnapshotTest } from '../../helpers/util';
describe('mermaid', () => {
describe('registerDiagram', () => {
- it('should work on @mermaid-js/mermaid-mindmap and mermaid-example-diagram', () => {
- const url = 'http://localhost:9000/external-diagrams-mindmap.html';
+ it('should work on @mermaid-js/mermaid-example-diagram', () => {
+ const url = 'http://localhost:9000/external-diagrams-example-diagram.html';
urlSnapshotTest(url, {}, false, false);
});
});
diff --git a/cypress/integration/rendering/c4.spec.js b/cypress/integration/rendering/c4.spec.js
new file mode 100644
index 000000000..0cf128ff6
--- /dev/null
+++ b/cypress/integration/rendering/c4.spec.js
@@ -0,0 +1,122 @@
+import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
+
+describe('C4 diagram', () => {
+ it('should render a simple C4Context diagram', () => {
+ imgSnapshotTest(
+ `
+ C4Context
+ accTitle: C4 context demo
+ accDescr: Many large C4 diagrams
+
+ title System Context diagram for Internet Banking System
+
+ Enterprise_Boundary(b0, "BankBoundary0") {
+ Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
+
+ System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
+
+ Enterprise_Boundary(b1, "BankBoundary") {
+ System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
+ }
+ }
+
+ BiRel(customerA, SystemAA, "Uses")
+ Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
+ Rel(SystemC, customerA, "Sends e-mails to")
+
+ UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red")
+ UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5")
+ UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20")
+ `,
+ {}
+ );
+ cy.get('svg');
+ });
+ it('should render a simple C4Container diagram', () => {
+ imgSnapshotTest(
+ `
+ C4Container
+ title Container diagram for Internet Banking System
+
+ System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system", $tags="v1.0")
+ Person(customer, Customer, "A customer of the bank, with personal bank accounts", $tags="v1.0")
+
+ Container_Boundary(c1, "Internet Banking") {
+ Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to customers via their web browser")
+ }
+
+ Rel(customer, spa, "Uses", "HTTPS")
+ Rel(email_system, customer, "Sends e-mails to")
+ `,
+ {}
+ );
+ cy.get('svg');
+ });
+ it('should render a simple C4Component diagram', () => {
+ imgSnapshotTest(
+ `
+ C4Component
+ title Component diagram for Internet Banking System - API Application
+
+ Container(spa, "Single Page Application", "javascript and angular", "Provides all the internet banking functionality to customers via their web browser.")
+
+ Container_Boundary(api, "API Application") {
+ Component(sign, "Sign In Controller", "MVC Rest Controller", "Allows users to sign in to the internet banking system")
+ }
+
+ Rel_Back(spa, sign, "Uses", "JSON/HTTPS")
+ UpdateRelStyle(spa, sign, $offsetY="-40")
+ `,
+ {}
+ );
+ cy.get('svg');
+ });
+ it('should render a simple C4Dynamic diagram', () => {
+ imgSnapshotTest(
+ `
+ C4Dynamic
+ title Dynamic diagram for Internet Banking System - API Application
+
+ ContainerDb(c4, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
+ Container(c1, "Single-Page Application", "JavaScript and Angular", "Provides all of the Internet banking functionality to customers via their web browser.")
+ Container_Boundary(b, "API Application") {
+ Component(c3, "Security Component", "Spring Bean", "Provides functionality Related to signing in, changing passwords, etc.")
+ Component(c2, "Sign In Controller", "Spring MVC Rest Controller", "Allows users to sign in to the Internet Banking System.")
+ }
+ Rel(c1, c2, "Submits credentials to", "JSON/HTTPS")
+ Rel(c2, c3, "Calls isAuthenticated() on")
+ Rel(c3, c4, "select * from users where username = ?", "JDBC")
+
+ UpdateRelStyle(c1, c2, $textColor="red", $offsetY="-40")
+ UpdateRelStyle(c2, c3, $textColor="red", $offsetX="-40", $offsetY="60")
+ UpdateRelStyle(c3, c4, $textColor="red", $offsetY="-40", $offsetX="10")
+ `,
+ {}
+ );
+ cy.get('svg');
+ });
+ it('should render a simple C4Deployment diagram', () => {
+ imgSnapshotTest(
+ `
+ C4Deployment
+ title Deployment Diagram for Internet Banking System - Live
+
+ Deployment_Node(mob, "Customer's mobile device", "Apple IOS or Android"){
+ Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.")
+ }
+
+ Deployment_Node(plc, "Big Bank plc", "Big Bank plc data center"){
+ Deployment_Node(dn, "bigbank-api*** x8", "Ubuntu 16.04 LTS"){
+ Deployment_Node(apache, "Apache Tomcat", "Apache Tomcat 8.x"){
+ Container(api, "API Application", "Java and Spring MVC", "Provides Internet Banking functionality via a JSON/HTTPS API.")
+ }
+ }
+ }
+
+ Rel(mobile, api, "Makes API calls to", "json/HTTPS")
+ `,
+ {}
+ );
+ cy.get('svg');
+ });
+});
diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js
index 8e8946170..df1fac0cd 100644
--- a/cypress/integration/rendering/erDiagram.spec.js
+++ b/cypress/integration/rendering/erDiagram.spec.js
@@ -182,6 +182,20 @@ describe('Entity Relationship Diagram', () => {
cy.get('svg');
});
+ it('should render entities with length in attributes type', () => {
+ renderGraph(
+ `
+ erDiagram
+ CLUSTER {
+ varchar(99) name
+ string(255) description
+ }
+ `,
+ { logLevel: 1 }
+ );
+ cy.get('svg');
+ });
+
it('should render entities and attributes with big and small entity names', () => {
renderGraph(
`
diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js
new file mode 100644
index 000000000..414037651
--- /dev/null
+++ b/cypress/integration/rendering/flowchart-elk.spec.js
@@ -0,0 +1,687 @@
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
+
+describe.skip('Flowchart ELK', () => {
+ it('1-elk: should render a simple flowchart', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ {}
+ );
+ imgSnapshotTest(
+ `flowchart TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { flowchart: { defaultRenderer: 'elk' } }
+ );
+ });
+
+ it('2-elk: should render a simple flowchart with diagramPadding set to 0', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ %% this is a comment
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { flowchart: { diagramPadding: 0 } }
+ );
+ });
+
+ it('3-elk: a link with correct arrowhead to a subgraph', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ P1
+ P1 -->P1.5
+ subgraph P1.5
+ P2
+ P2.5(( A ))
+ P3
+ end
+ P2 --> P4
+ P3 --> P6
+ P1.5 --> P5
+ `,
+ {}
+ );
+ });
+
+ it('4-elk: Length of edges', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ L1 --- L2
+ L2 --- C
+ M1 ---> C
+ R1 .-> R2
+ R2 <.-> C
+ C -->|Label 1| E1
+ C <-- Label 2 ---> E2
+ C ----> E3
+ C <-...-> E4
+ C ======> E5
+ `,
+ {}
+ );
+ });
+ it('5-elk: should render escaped without html labels', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ a["Haiya"]---->b
+ `,
+ { htmlLabels: false, flowchart: { htmlLabels: false } }
+ );
+ });
+ it('6-elk: should render non-escaped with html labels', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ a["Haiya"]===>b
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('7-elk: should render a flowchart when useMaxWidth is true (default)', () => {
+ renderGraph(
+ `flowchart-elk TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { 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(230 * 0.95, 230 * 1.05);
+ });
+ });
+ it('8-elk: should render a flowchart when useMaxWidth is false', () => {
+ renderGraph(
+ `flowchart-elk TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ B --> C{Let me think}
+ C -->|One| D[Laptop]
+ C -->|Two| E[iPhone]
+ C -->|Three| F[fa:fa-car Car]
+ `,
+ { 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(230 * 0.95, 230 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
+
+ it('V2 elk - 16: Render Stadium shape', () => {
+ imgSnapshotTest(
+ ` flowchart-elk TD
+ A([stadium shape test])
+ A -->|Get money| B([Go shopping])
+ B --> C([Let me think... Do I want something for work, something to spend every free second with, or something to get around?])
+ C -->|One| D([Laptop])
+ C -->|Two| E([iPhone])
+ C -->|Three| F([Car wroom wroom])
+ click A "index.html#link-clicked" "link test"
+ click B testClick "click test"
+ classDef someclass fill:#f96;
+ class A someclass;
+ class C someclass;
+ `,
+ { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
+ );
+ });
+
+ it('50-elk: handle nested subgraphs in reverse order', () => {
+ imgSnapshotTest(
+ `flowchart-elk LR
+ a -->b
+ subgraph A
+ B
+ end
+ subgraph B
+ b
+ end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('51-elk: handle nested subgraphs in reverse order', () => {
+ imgSnapshotTest(
+ `flowchart-elk LR
+ a -->b
+ subgraph A
+ B
+ end
+ subgraph B
+ b
+ end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('52-elk: handle nested subgraphs in several levels', () => {
+ imgSnapshotTest(
+ `flowchart-elk TB
+ b-->B
+ a-->c
+ subgraph O
+ A
+ end
+ subgraph B
+ c
+ end
+ subgraph A
+ a
+ b
+ B
+ end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('53-elk: handle nested subgraphs with edges in and out', () => {
+ imgSnapshotTest(
+ `flowchart-elk TB
+ internet
+ nat
+ routeur
+ lb1
+ lb2
+ compute1
+ compute2
+ subgraph project
+ routeur
+ nat
+ subgraph subnet1
+ compute1
+ lb1
+ end
+ subgraph subnet2
+ compute2
+ lb2
+ end
+ end
+ internet --> routeur
+ routeur --> subnet1 & subnet2
+ subnet1 & subnet2 --> nat --> internet
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('54-elk: handle nested subgraphs with outgoing links', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+ subgraph main
+ subgraph subcontainer
+ subcontainer-child
+ end
+ subcontainer-child--> subcontainer-sibling
+ end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('55-elk: handle nested subgraphs with outgoing links 2', () => {
+ imgSnapshotTest(
+ `flowchart-elk TD
+
+subgraph one[One]
+ subgraph sub_one[Sub One]
+ _sub_one
+ end
+ subgraph sub_two[Sub Two]
+ _sub_two
+ end
+ _one
+end
+
+%% here, either the first or the second one
+sub_one --> sub_two
+_one --> b
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('56-elk: handle nested subgraphs with outgoing links 3', () => {
+ imgSnapshotTest(
+ `flowchart-elk TB
+ subgraph container_Beta
+ process_C-->Process_D
+ end
+ subgraph container_Alpha
+ process_A-->process_B
+ process_A-->|messages|process_C
+ end
+ process_B-->|via_AWSBatch|container_Beta
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('57-elk: handle nested subgraphs with outgoing links 4', () => {
+ imgSnapshotTest(
+ `flowchart-elk LR
+subgraph A
+a -->b
+end
+subgraph B
+b
+end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('57-elk: handle nested subgraphs with outgoing links 2', () => {
+ imgSnapshotTest(
+ `flowchart-elk TB
+ c1-->a2
+ subgraph one
+ a1-->a2
+ end
+ subgraph two
+ b1-->b2
+ end
+ subgraph three
+ c1-->c2
+ end
+ one --> two
+ three --> two
+ two --> c2
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('57.x: handle nested subgraphs with outgoing links 5', () => {
+ imgSnapshotTest(
+ `%% this does not produce the desired result
+flowchart-elk TB
+ subgraph container_Beta
+ process_C-->Process_D
+ end
+ subgraph container_Alpha
+ process_A-->process_B
+ process_B-->|via_AWSBatch|container_Beta
+ process_A-->|messages|process_C
+ end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('58-elk: handle styling with style expressions', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk LR
+ id1(Start)-->id2(Stop)
+ 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' }
+ );
+ });
+ it('59-elk: handle styling of subgraphs and links', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk TD
+ A[Christmas] ==> D
+ A[Christmas] -->|Get money| B(Go shopping)
+ A[Christmas] ==> C
+ subgraph T ["Test"]
+ A
+ B
+ C
+ end
+
+ classDef Test fill:#F84E68,stroke:#333,color:white;
+ class A,T Test
+ classDef TestSub fill:green;
+ class T TestSub
+ linkStyle 0,1 color:orange, stroke: orange;
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('60-elk: handle styling for all node shapes - v2', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk LR
+ A[red text] -->|default style| B(blue text)
+ C([red text]) -->|default style| D[[blue text]]
+ E[(red text)] -->|default style| F((blue text))
+ G>red text] -->|default style| H{blue text}
+ I{{red text}} -->|default style| J[/blue text/]
+ K[\\ red text\\] -->|default style| L[/blue text\\]
+ M[\\ red text/] -->|default style| N[blue text];
+ O(((red text))) -->|default style| P(((blue text)));
+ linkStyle default color:Sienna;
+ style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style C stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style D stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style E stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style F stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style G stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style H stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style I stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style J stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style K stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ style O stroke:#ff0000,fill:#ffcccc,color:#ff0000;
+ style P stroke:#0000ff,fill:#ccccff,color:#0000ff;
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
+ );
+ });
+ it('61-elk: fontawesome icons in edge labels', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk TD
+ C -->|fa:fa-car Car| F[fa:fa-car Car]
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('62-elk: should render styled subgraphs', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk TB
+ A
+ B
+ subgraph foo[Foo SubGraph]
+ C
+ D
+ end
+ subgraph bar[Bar SubGraph]
+ E
+ F
+ end
+ G
+
+ A-->B
+ B-->C
+ C-->D
+ B-->D
+ D-->E
+ E-->A
+ E-->F
+ F-->D
+ F-->G
+ B-->G
+ G-->D
+
+ 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' }
+ );
+ });
+ it('63-elk: title on subgraphs should be themable', () => {
+ imgSnapshotTest(
+ `
+ %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
+ flowchart-elk LR
+ subgraph A
+ a --> b
+ end
+ subgraph B
+ i -->f
+ end
+ A --> B
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('65-elk: text-color from classes', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk LR
+ classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
+ Lorem --> Ipsum --> Dolor
+ class Lorem,Dolor dark
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('66-elk: More nested subgraph cases (TB)', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk TB
+ subgraph two
+ b1
+ end
+ subgraph three
+ c2
+ end
+
+ three --> two
+ two --> c2
+
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('67-elk: More nested subgraph cases (RL)', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk RL
+ subgraph two
+ b1
+ end
+ subgraph three
+ c2
+ end
+
+ three --> two
+ two --> c2
+
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('68-elk: More nested subgraph cases (BT)', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk BT
+ subgraph two
+ b1
+ end
+ subgraph three
+ c2
+ end
+
+ three --> two
+ two --> c2
+
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('69-elk: More nested subgraph cases (LR)', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk LR
+ subgraph two
+ b1
+ end
+ subgraph three
+ c2
+ end
+
+ three --> two
+ two --> c2
+
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('70-elk: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk TB
+ subgraph S1
+ sub1 -->sub2
+ end
+ subgraph S2
+ sub4
+ end
+ S1 --> S2
+ sub1 --> sub4
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('71-elk: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk RL
+ subgraph S1
+ sub1 -->sub2
+ end
+ subgraph S2
+ sub4
+ end
+ S1 --> S2
+ sub1 --> sub4
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('72-elk: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk BT
+ subgraph S1
+ sub1 -->sub2
+ end
+ subgraph S2
+ sub4
+ end
+ S1 --> S2
+ sub1 --> sub4
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('74-elk: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk RL
+ subgraph S1
+ sub1 -->sub2
+ end
+ subgraph S2
+ sub4
+ end
+ S1 --> S2
+ sub1 --> sub4
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('74-elk: Handle labels for multiple edges from and to the same couple of nodes', () => {
+ imgSnapshotTest(
+ `
+flowchart-elk RL
+ subgraph one
+ a1 -- l1 --> a2
+ a1 -- l2 --> a2
+ end
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('76-elk: handle unicode encoded character with HTML labels true', () => {
+ imgSnapshotTest(
+ `flowchart-elk 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;."}}
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('2050-elk: handling of different rendering direction in subgraphs', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk LR
+
+ subgraph TOP
+ direction TB
+ subgraph B1
+ direction RL
+ i1 -->f1
+ end
+ subgraph B2
+ direction BT
+ i2 -->f2
+ end
+ end
+ A --> TOP --> B
+ B1 --> B2
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+
+ it('2388-elk: handling default in the node name', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk LR
+ default-index.js --> dot.template.js
+ index.js --> module-utl.js
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('2824-elk: Clipping of edges', () => {
+ imgSnapshotTest(
+ `
+ flowchart-elk TD
+ A --> B
+ A --> C
+ B --> C
+ `,
+ { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
+ );
+ });
+ it('1433-elk: should render a titled flowchart with titleTopMargin set to 0', () => {
+ imgSnapshotTest(
+ `---
+title: Simple flowchart
+---
+flowchart-elk TD
+A --> B
+`,
+ { titleTopMargin: 0 }
+ );
+ });
+});
diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js
index 30ae4f0d2..abdb22265 100644
--- a/cypress/integration/rendering/flowchart-v2.spec.js
+++ b/cypress/integration/rendering/flowchart-v2.spec.js
@@ -670,6 +670,17 @@ title: Simple flowchart
---
flowchart TD
A --> B
+`,
+ { titleTopMargin: 0 }
+ );
+ });
+ it('3192: It should be possieble to render flowcharts with invisible edges', () => {
+ imgSnapshotTest(
+ `---
+title: Simple flowchart with invisible edges
+---
+flowchart TD
+A ~~~ B
`,
{ titleTopMargin: 0 }
);
diff --git a/cypress/integration/rendering/mindmap.spec.ts b/cypress/integration/rendering/mindmap.spec.ts
index 62c7e785b..4663f6225 100644
--- a/cypress/integration/rendering/mindmap.spec.ts
+++ b/cypress/integration/rendering/mindmap.spec.ts
@@ -1,4 +1,4 @@
-import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
+import { imgSnapshotTest } from '../../helpers/util.js';
/**
* Check whether the SVG Element has a Mindmap root
@@ -158,7 +158,6 @@ mindmap
undefined,
shouldHaveRoot
);
- cy.get('svg');
});
it('rounded rect shape', () => {
imgSnapshotTest(
@@ -172,7 +171,6 @@ mindmap
undefined,
shouldHaveRoot
);
- cy.get('svg');
});
it('circle shape', () => {
imgSnapshotTest(
@@ -186,7 +184,6 @@ mindmap
undefined,
shouldHaveRoot
);
- cy.get('svg');
});
it('default shape', () => {
imgSnapshotTest(
@@ -198,7 +195,6 @@ mindmap
undefined,
shouldHaveRoot
);
- cy.get('svg');
});
it('adding children', () => {
imgSnapshotTest(
@@ -212,7 +208,6 @@ mindmap
undefined,
shouldHaveRoot
);
- cy.get('svg');
});
it('adding grand children', () => {
imgSnapshotTest(
@@ -227,7 +222,6 @@ mindmap
undefined,
shouldHaveRoot
);
- cy.get('svg');
});
/* The end */
});
diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js
index b5ff92c8c..f8948240a 100644
--- a/cypress/integration/rendering/sequencediagram.spec.js
+++ b/cypress/integration/rendering/sequencediagram.spec.js
@@ -3,6 +3,42 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
context('Sequence diagram', () => {
+ it('should render a sequence diagram with boxes', () => {
+ renderGraph(
+ `
+ sequenceDiagram
+ box LightGrey Alice and Bob
+ participant Alice
+ participant Bob
+ end
+ participant John as John Second Line
+ Alice ->> Bob: Hello Bob, how are you?
+ Bob-->>John: How about you John?
+ Bob--x Alice: I am good thanks!
+ Bob-x John: I am good thanks!
+ Note right of John: Bob thinks a long long time, so long that the text does not fit on a row.
+ Bob-->Alice: Checking with John...
+ alt either this
+ Alice->>John: Yes
+ else or this
+ Alice->>John: No
+ else or this will happen
+ Alice->John: Maybe
+ end
+ par this happens in parallel
+ Alice -->> Bob: Parallel message 1
+ and
+ Alice -->> John: Parallel message 2
+ end
+ `,
+ { sequence: { useMaxWidth: false } }
+ );
+ cy.get('svg').should((svg) => {
+ const width = parseFloat(svg.attr('width'));
+ expect(width).to.be.within(830 * 0.95, 830 * 1.05);
+ expect(svg).to.not.have.attr('style');
+ });
+ });
it('should render a simple sequence diagram', () => {
imgSnapshotTest(
`
@@ -80,7 +116,11 @@ context('Sequence diagram', () => {
loop Loopy
Bob->>Alice: Pasten
end `,
- { wrap: true }
+ {
+ sequence: {
+ wrap: true,
+ },
+ }
);
});
context('font settings', () => {
diff --git a/cypress/integration/rendering/timeline.spec.ts b/cypress/integration/rendering/timeline.spec.ts
new file mode 100644
index 000000000..6fae82fb4
--- /dev/null
+++ b/cypress/integration/rendering/timeline.spec.ts
@@ -0,0 +1,164 @@
+import { imgSnapshotTest } from '../../helpers/util.js';
+
+describe('Timeline diagram', () => {
+ it('1: should render a simple timeline with no specific sections', () => {
+ imgSnapshotTest(
+ `timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ `,
+ {}
+ );
+ });
+ it('2: should render a timeline diagram with sections', () => {
+ imgSnapshotTest(
+ `timeline
+ title Timeline of Industrial Revolution
+ section 17th-20th century
+ Industry 1.0 : Machinery, Water power, Steam power
+ Industry 2.0 : Electricity, Internal combustion engine, Mass production
+ Industry 3.0 : Electronics, Computers, Automation
+ section 21st century
+ Industry 4.0 : Internet, Robotics, Internet of Things
+ Industry 5.0 : Artificial intelligence, Big data,3D printing
+ `,
+ {}
+ );
+ });
+ it('3: should render a complex timeline with sections, and long events text with ', () => {
+ imgSnapshotTest(
+ `timeline
+ title England's History Timeline
+ section Stone Age
+ 7600 BC : Britain's oldest known house was built in Orkney, Scotland
+ 6000 BC : Sea levels rise and Britain becomes an island. The people who live here are hunter-gatherers.
+ section Broze Age
+ 2300 BC : People arrive from Europe and settle in Britain. They bring farming and metalworking.
+ : New styles of pottery and ways of burying the dead appear.
+ 2200 BC : The last major building works are completed at Stonehenge. People now bury their dead in stone circles.
+ : The first metal objects are made in Britain.Some other nice things happen. it is a good time to be alive.
+ `,
+ {}
+ );
+ });
+ it('4: should render a simple timeline with directives and disableMultiColor:true ', () => {
+ imgSnapshotTest(
+ `%%{init: { 'logLevel': 'debug', 'theme': 'base', 'timeline': {'disableMulticolor': true}}}%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ `,
+ {}
+ );
+ });
+ it('5: should render a simple timeline with directive overriden colors', () => {
+ imgSnapshotTest(
+ ` %%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
+ 'cScale0': '#ff0000',
+ 'cScale1': '#00ff00',
+ 'cScale2': '#0000ff'
+ } } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008 : Instagram
+ 2010 : Pinterest
+ `,
+ {}
+ );
+ });
+ it('6: should render a simple timeline in base theme', () => {
+ imgSnapshotTest(
+ `%%{init: { 'logLevel': 'debug', 'theme': 'base' } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008 : Instagram
+ 2010 : Pinterest
+ `,
+ {}
+ );
+ });
+
+ it('7: should render a simple timeline in default theme', () => {
+ imgSnapshotTest(
+ `%%{init: { 'logLevel': 'debug', 'theme': 'default' } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008 : Instagram
+ 2010 : Pinterest
+ `,
+ {}
+ );
+ });
+
+ it('8: should render a simple timeline in dark theme', () => {
+ imgSnapshotTest(
+ `%%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008 : Instagram
+ 2010 : Pinterest
+ `,
+ {}
+ );
+ });
+
+ it('9: should render a simple timeline in neutral theme', () => {
+ imgSnapshotTest(
+ `%%{init: { 'logLevel': 'debug', 'theme': 'neutral' } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008 : Instagram
+ 2010 : Pinterest
+ `,
+ {}
+ );
+ });
+
+ it('10: should render a simple timeline in forest theme', () => {
+ imgSnapshotTest(
+ `%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008 : Instagram
+ 2010 : Pinterest
+ `,
+ {}
+ );
+ });
+});
diff --git a/cypress/platform/ashish2.html b/cypress/platform/ashish2.html
new file mode 100644
index 000000000..bcea4f4cc
--- /dev/null
+++ b/cypress/platform/ashish2.html
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+
+
+
Security check
+
+ timeline
+ title My day
+ section section with no tasks
+ section Go to work at the dog office
+ 1930 : first step : second step is a long step
+ : third step
+ 1940 : fourth step : fifth step
+ section Go home
+ 1950 : India got independent and already won war against Pakistan
+ 1960 : India fights poverty, looses war to China and gets nuclear weapons from USA and USSR
+ 1970 : Green Revolution comes to india
+ section Another section with no tasks
+ I am a big big big tasks
+ I am not so big tasks
+
+ timeline
+ title England's History Timeline
+ section Stone Age
+ 7600 BC : Britain's oldest known house was built in Orkney, Scotland
+ 6000 BC : Sea levels rise and Britain becomes an island. The people who live here are hunter-gatherers.
+ section Broze Age
+ 2300 BC : People arrive from Europe and settle in Britain. They bring farming and metalworking.
+ : New styles of pottery and ways of burying the dead appear.
+ 2200 BC : The last major building works are completed at Stonehenge. People now bury their dead in stone circles.
+ : The first metal objects are made in Britain.Some other nice things happen. it is a good time to be alive.
+
+
+
+ %%{'init': { 'logLevel': 'debug', 'theme': 'default', 'timeline': {'disableMulticolor':false} } }%%
+ timeline
+ title History of Social Media Platform
+ 2002 : LinkedIn
+ 2004 : Facebook : Google : Pixar
+ 2005 : Youtube
+ 2006 : Twitter
+ 2007 : Tumblr
+ 2008s : Instagram
+ 2010 : Pinterest
+