diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 55e06f46d3..aff5852dbb 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -32,6 +32,7 @@ jobs:
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v4
+ id: cypress
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers
# Otherwise (e.g. if running from fork), we run on a single container only
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
@@ -44,3 +45,10 @@ jobs:
parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v3
+ if: ${{ failure() && steps.cypress.conclusion == 'failure' }}
+ with:
+ name: error-snapshots
+ path: cypress/snapshots/**/__diff_output__/*
diff --git a/.vite/build.ts b/.vite/build.ts
index 6c7e85827f..1261e375ba 100644
--- a/.vite/build.ts
+++ b/.vite/build.ts
@@ -41,11 +41,6 @@ const packageOptions = {
packageName: 'mermaid-mindmap',
file: 'detector.ts',
},
- 'mermaid-flowchart-v3': {
- name: 'mermaid-flowchart-v3',
- packageName: 'mermaid-flowchart-v3',
- file: 'detector.ts',
- },
// 'mermaid-example-diagram-detector': {
// name: 'mermaid-example-diagram-detector',
// packageName: 'mermaid-example-diagram',
@@ -125,7 +120,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
if (watch && config.build) {
config.build.watch = {
include: [
- 'packages/mermaid-flowchart-v3/src/**',
'packages/mermaid-mindmap/src/**',
'packages/mermaid/src/**',
// 'packages/mermaid-example-diagram/src/**',
@@ -154,7 +148,6 @@ const main = async () => {
if (watch) {
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
if (!mermaidOnly) {
- build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-flowchart-v3' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
// build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
}
diff --git a/cSpell.json b/cSpell.json
index c6660c4dcb..26550c527f 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",
@@ -54,8 +56,10 @@
"knut",
"laganeckas",
"lintstagedrc",
+ "logmsg",
"lucida",
"matthieu",
+ "mdast",
"mdbook",
"mermerd",
"mindaugas",
diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js
index 5213f634ab..533cca499c 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,69 +46,26 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) =>
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 ' + Cypress.spec.name + ' --- ' + name);
- cy.eyesOpen({
- appName: 'Mermaid',
- testName: name,
- batchName: Cypress.spec.name,
- batchId: batchId + Cypress.spec.name,
- });
- }
-
const url = mermaidUrl(graphStr, options, api);
-
- cy.visit(url);
- 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.eyesClose();
- } else {
- cy.matchImageSnapshot(name);
- }
+ openURLAndVerifyRendering(url, options, validation);
};
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';
- }
+ 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) {
- cy.log('Opening eyes 2' + Cypress.spec.name);
+ cy.log('Opening eyes ' + Cypress.spec.name + ' --- ' + name);
cy.eyesOpen({
appName: 'Mermaid',
testName: name,
@@ -118,24 +75,19 @@ export const urlSnapshotTest = (url, _options, api = false, validation) => {
}
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('body');
- // Default name to test title
if (useAppli) {
- cy.log('Check eyes 2' + Cypress.spec.name);
+ cy.log('Check eyes' + Cypress.spec.name);
cy.eyesCheckWindow('Click!');
- cy.log('Closing eyes 2' + Cypress.spec.name);
+ cy.log('Closing eyes' + 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/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js
new file mode 100644
index 0000000000..0d4ec42110
--- /dev/null
+++ b/cypress/integration/rendering/flowchart-elk.spec.js
@@ -0,0 +1,687 @@
+import { imgSnapshotTest, renderGraph } from '../../helpers/util';
+
+describe('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/mindmap.spec.ts b/cypress/integration/rendering/mindmap.spec.ts
index 62c7e785b6..4663f6225b 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/platform/external-diagrams-mindmap.html b/cypress/platform/external-diagrams-mindmap.html
index e5eded4ba0..e445a7627c 100644
--- a/cypress/platform/external-diagrams-mindmap.html
+++ b/cypress/platform/external-diagrams-mindmap.html
@@ -44,6 +44,9 @@