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 @@

Should correctly load a third-party diagram using registerDiagram

await mermaid.registerExternalDiagrams([mindmap]); await mermaid.initialize({ logLevel: 0 }); await mermaid.initThrowsErrorsAsync(); + if (window.Cypress) { + window.rendered = true; + } diff --git a/cypress/platform/ghsa1.html b/cypress/platform/ghsa1.html index 890a8e0dd2..59c316eb36 100644 --- a/cypress/platform/ghsa1.html +++ b/cypress/platform/ghsa1.html @@ -21,6 +21,9 @@

Background should be yellow!!!

const diagram = document.getElementById('diagram'); const svg = mermaid.render('diagram-svg', graph); diagram.innerHTML = svg; + if (window.Cypress) { + window.rendered = true; + } diff --git a/cypress/platform/ghsa2.html b/cypress/platform/ghsa2.html index 6d4dccca32..3ff69158bb 100644 --- a/cypress/platform/ghsa2.html +++ b/cypress/platform/ghsa2.html @@ -21,6 +21,9 @@

This element does not belong to the SVG but we can style it

const diagram = document.getElementById('diagram'); const svg = mermaid.render('diagram-svg', graph); diagram.innerHTML = svg; + if (window.Cypress) { + window.rendered = true; + } diff --git a/cypress/platform/ghsa3.html b/cypress/platform/ghsa3.html index 63dfa0d01e..79fa401316 100644 --- a/cypress/platform/ghsa3.html +++ b/cypress/platform/ghsa3.html @@ -94,6 +94,9 @@

PAGE SHOULD NOT BE RED

// document.querySelector('#diagram').innerHTML = diagram; mermaid.render('diagram', diagram, (res) => { document.querySelector('#res').innerHTML = res; + if (window.Cypress) { + window.rendered = true; + } }); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 5e1f4d76b3..afc12dbe93 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -63,6 +63,13 @@ c --> d
+flowchart-elk TB
+      a --> b
+      a --> c
+      b --> d
+      c --> d
+    
+
 %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
 flowchart TB
   %% I could not figure out how to use double quotes in labels in Mermaid
@@ -238,10 +245,9 @@