diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..8f0f3b95d
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,58 @@
+name: Build
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [10.x, 12.x]
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Setup Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Install Yarn
+ run: npm i yarn --global
+
+ - name: Cache Node Modules
+ uses: actions/cache@v1
+ with:
+ path: .cache
+ key: ${{ runner.OS }}-build-${{ hashFiles('**/yarn.lock') }}
+
+ - name: Install Packages
+ run: |
+ yarn config set cache-folder $GITHUB_WORKSPACE/.cache/yarn
+ yarn install --frozen-lockfile
+ env:
+ CYPRESS_CACHE_FOLDER: ../../.cache/Cypress
+
+ - name: Run Build
+ run: yarn build
+
+ - name: Run Unit Tests
+ run: |
+ yarn test --coverage
+
+ - name: Upload Test Results
+ uses: coverallsapp/github-action@v1.0.1
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ parallel: true
+
+ - name: Run E2E Tests
+ run: yarn e2e
+ env:
+ PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
+ CYPRESS_CACHE_FOLDER: .cache/Cypress
+
+ - name: Post Upload Test Results
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ parallel-finished: true
diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js
index 143fc7ed7..a3f92defd 100644
--- a/cypress/helpers/util.js
+++ b/cypress/helpers/util.js
@@ -26,3 +26,9 @@ export const imgSnapshotTest = (graphStr, options, api) => {
cy.get('svg');
cy.percySnapshot();
};
+
+export const renderGraph = (graphStr, options, api) => {
+ const url = mermaidUrl(graphStr, options, api);
+
+ cy.visit(url);
+};
diff --git a/cypress/integration/other/configuration.spec.js b/cypress/integration/other/configuration.spec.js
new file mode 100644
index 000000000..c2f1533b2
--- /dev/null
+++ b/cypress/integration/other/configuration.spec.js
@@ -0,0 +1,100 @@
+import { renderGraph } from '../../helpers/util';
+/* eslint-env jest */
+describe('Configuration', () => {
+ describe('arrowMarkerAbsolute', () => {
+ it('should handle default value false of arrowMarkerAbsolute', () => {
+ renderGraph(
+ `graph 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]
+ `,
+ { }
+ );
+
+ // 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')
+ .should('exist')
+ .and('include', 'url(#');
+ });
+ it('should handle default value false of arrowMarkerAbsolute', () => {
+ renderGraph(
+ `graph 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]
+ `,
+ { }
+ );
+
+ // 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')
+ .should('exist')
+ .and('include', 'url(#');
+ });
+ it('should handle arrowMarkerAbsolute excplicitly set to false', () => {
+ renderGraph(
+ `graph 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]
+ `,
+ {
+ 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')
+ .should('exist')
+ .and('include', 'url(#');
+ });
+ it('should handle arrowMarkerAbsolute excplicitly set to "false" as false', () => {
+ renderGraph(
+ `graph 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]
+ `,
+ {
+ 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')
+ .should('exist')
+ .and('include', 'url(#');
+ });
+ it('should handle arrowMarkerAbsolute set to true', () => {
+ renderGraph(
+ `graph 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]
+ `,
+ {
+ arrowMarkerAbsolute: true
+ }
+ );
+
+ cy.get('.edgePath path').first().should('have.attr', 'marker-end')
+ .should('exist')
+ .and('include', 'url(http://localhost');
+ });
+ });
+});
diff --git a/cypress/integration/other/interaction.spec.js b/cypress/integration/other/interaction.spec.js
index cfd937e63..6d37af273 100644
--- a/cypress/integration/other/interaction.spec.js
+++ b/cypress/integration/other/interaction.spec.js
@@ -16,7 +16,7 @@ describe('Interaction', () => {
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
- .find('g#mermaid-dom-id-1Function')
+ .find('g[id="1Function"]')
.click();
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
@@ -38,7 +38,7 @@ describe('Interaction', () => {
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
- .find('g#mermaid-dom-id-2URL')
+ .find('g[id="2URL"]')
.click();
cy.location().should(location => {
@@ -108,7 +108,7 @@ describe('Interaction', () => {
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
- .find('g#mermaid-dom-id-1Function')
+ .find('g[id="1Function"]')
.click();
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
@@ -130,7 +130,7 @@ describe('Interaction', () => {
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
- .find('g#mermaid-dom-id-2URL')
+ .find('g[id="2URL"]')
.click();
cy.location().should(location => {
@@ -200,7 +200,7 @@ describe('Interaction', () => {
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
- .find('g#mermaid-dom-id-1Function')
+ .find('g[id="1Function"]')
.click();
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js
index d1f290436..0125a4373 100644
--- a/cypress/integration/rendering/classDiagram.spec.js
+++ b/cypress/integration/rendering/classDiagram.spec.js
@@ -19,6 +19,9 @@ describe('Class diagram', () => {
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
+ Class01 : -int privateChimp
+ Class01 : +int publicGorilla
+ Class01 : #int protectedMarmoset
Class08 <--> C2: Cool label
class Class10 {
<<service>>
@@ -58,4 +61,75 @@ describe('Class diagram', () => {
);
cy.get('svg');
});
+
+ it('should render a simple class diagram with different visibilities', () => {
+ imgSnapshotTest(
+ `
+ classDiagram
+ Class01 <|-- AveryLongClass : Cool
+ <<interface>> Class01
+ Class01 : -int privateMethod()
+ Class01 : +int publicMethod()
+ Class01 : #int protectedMethod()
+ Class01 : -int privateChimp
+ Class01 : +int publicGorilla
+ Class01 : #int protectedMarmoset
+ `,
+ {}
+ );
+ cy.get('svg');
+ });
+
+ it('should render multiple class diagrams', () => {
+ imgSnapshotTest(
+ [
+ `
+ classDiagram
+ Class01 "1" <|--|> "*" AveryLongClass : Cool
+ <<interface>> Class01
+ Class03 "1" *-- "*" Class04
+ Class05 "1" o-- "many" Class06
+ Class07 "1" .. "*" Class08
+ Class09 "1" --> "*" C2 : Where am i?
+ Class09 "*" --* "*" C3
+ Class09 "1" --|> "1" Class07
+ Class07 : equals()
+ Class07 : Object[] elementData
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class08 "1" <--> "*" C2: Cool label
+ class Class10 {
+ <<service>>
+ int id
+ test()
+ }
+ `,
+ `
+ classDiagram
+ Class01 "1" <|--|> "*" AveryLongClass : Cool
+ <<interface>> Class01
+ Class03 "1" *-- "*" Class04
+ Class05 "1" o-- "many" Class06
+ Class07 "1" .. "*" Class08
+ Class09 "1" --> "*" C2 : Where am i?
+ Class09 "*" --* "*" C3
+ Class09 "1" --|> "1" Class07
+ Class07 : equals()
+ Class07 : Object[] elementData
+ Class01 : size()
+ Class01 : int chimp
+ Class01 : int gorilla
+ Class08 "1" <--> "*" C2: Cool label
+ class Class10 {
+ <<service>>
+ int id
+ test()
+ }
+ `,
+ ],
+ {}
+ );
+ cy.get('svg');
+ });
});
diff --git a/cypress/platform/e2e.html b/cypress/platform/e2e.html
index 4384fd0ec..010b11cb2 100644
--- a/cypress/platform/e2e.html
+++ b/cypress/platform/e2e.html
@@ -4,9 +4,8 @@