Compare commits

..

6 Commits

Author SHA1 Message Date
darshanr0107
7091792694 fix: build issues
Some optional description over here if you need to add more info

on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-21 14:15:50 +05:30
darshanr0107
efd94b705d fix: build issues
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-21 14:11:48 +05:30
darshanr0107
9ec989e633 Merge branch 'develop' of https://github.com/mermaid-js/mermaid into 6784-edge-label-color-mismatch 2025-08-21 12:06:04 +05:30
darshanr0107
227cef05b3 fix: the breaking argos
Some optional description over here if you need to add more info

on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-12 18:55:11 +05:30
darshanr0107
1d3681053b added changeset
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-06 12:34:41 +05:30
darshanr0107
93df13898f fix: ensure class def color is applied to edge label
on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
2025-08-06 12:21:34 +05:30
10 changed files with 4276 additions and 5734 deletions

View File

@@ -0,0 +1,5 @@
---
'mermaid': patch
---
fix: Ensure edge label color is applied when using classDef with edge IDs

View File

@@ -1,95 +0,0 @@
name: Applitools E2E (Develop Branch) - Fixed
on:
push:
branches:
- develop
- applitools_workflow
workflow_dispatch:
# Manual triggering only - to limit Applitools usage
inputs:
parent_branch:
required: true
type: string
default: master
description: 'Parent branch to use for PRs'
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: read
env:
# on PRs from forks, this secret will always be empty, for security reasons
USE_APPLI: ${{ secrets.APPLITOOLS_API_KEY && 'true' || '' }}
jobs:
applitools-e2e:
runs-on: ubuntu-latest
container:
image: cypress/browsers:node-22.18.0-chrome-139.0.7258.127-1-ff-141.0.3-edge-139.0.3405.86-1
options: --user root --shm-size=2gb
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check Applitools API Key
run: |
if [ -z "${{ secrets.APPLITOOLS_API_KEY }}" ]; then
echo "::error::APPLITOOLS_API_KEY secret is not set. Please add it to your repository secrets."
exit 1
else
echo "✅ Applitools API Key is present"
fi
- name: Setup Node.js and pnpm
run: |
# Install pnpm globally
npm install -g pnpm@10.4.1
# Verify installations
node --version
pnpm --version
- name: Setup Applitools Environment
run: |
# Set Applitools environment variables for proper CI integration
echo "APPLITOOLS_BATCH_ID=${{ github.run_id }}-${{ github.run_attempt }}" >> $GITHUB_ENV
echo "APPLITOOLS_BATCH_NAME=GitHub Actions - ${{ github.workflow }}" >> $GITHUB_ENV
echo "APPLITOOLS_SERVER_URL=https://eyes.applitools.com" >> $GITHUB_ENV
# Force disable local Eyes server
echo "APPLITOOLS_DISABLE_LOCAL_EYES_SERVER=true" >> $GITHUB_ENV
- name: Verify Cypress Installation
run: |
npx cypress verify
npx cypress info
- name: Run Cypress with Applitools (single spec)
uses: cypress-io/github-action@v6
with:
command: pnpm cypress
start: pnpm dev
wait-on: http://localhost:9000
wait-on-timeout: 180
browser: chrome
headless: true
env:
# Ensure these are visible to Cypress + Applitools
APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
APPLITOOLS_BATCH_ID: ${{ env.APPLITOOLS_BATCH_ID }}
APPLITOOLS_BATCH_NAME: ${{ env.APPLITOOLS_BATCH_NAME }}
APPLITOOLS_SERVER_URL: ${{ env.APPLITOOLS_SERVER_URL }}
APPLITOOLS_DISABLE_LOCAL_EYES_SERVER: true
USE_APPLI: true
# Force Applitools to use cloud service instead of local server
APPLITOOLS_DONT_CLOSE_BATCHES: false
APPLITOOLS_SAVE_DEBUG_SCREENSHOTS: false
# Disable any local server connections
APPLITOOLS_PROXY_URL: ''
# GitHub Actions CI environment
CI: true
# Disable Chrome sandbox for container
ELECTRON_EXTRA_LAUNCH_ARGS: '--disable-dev-shm-usage'

View File

@@ -1,38 +0,0 @@
export default {
// Explicitly set the server URL to use Applitools cloud service
serverUrl: 'https://eyes.applitools.com',
// API key from environment variable
apiKey: process.env.APPLITOOLS_API_KEY,
// Batch configuration
batch: {
name: 'Cypress Tests',
id: process.env.APPLITOOLS_BATCH_ID,
},
// Browser configuration for CI
browser: [{ name: 'chrome', width: 1440, height: 1024 }],
// Test concurrency (reduce for stability in CI)
testConcurrency: 1,
// Viewport size
viewportSize: { width: 1440, height: 1024 },
// Force full page screenshots
forceFullPageScreenshot: true,
// Don't fail tests on visual differences (optional)
exitcode: false,
// Additional settings for CI stability
matchTimeout: 2000,
// Disable local Eyes server
// cspell:ignore dont
dontCloseBatches: false,
// Save debug screenshots on failure
saveDebugScreenshots: process.env.CI ? false : true,
} as const;

View File

@@ -1,90 +1,42 @@
// cypress.config.ts
import { defineConfig } from 'cypress';
import eyesPlugin from '@applitools/eyes-cypress';
import { registerArgosTask } from '@argos-ci/cypress/task';
import coverage from '@cypress/code-coverage/task.js';
import { defineConfig } from 'cypress';
import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin.js';
import cypressSplit from 'cypress-split';
import eyesPlugin from '@applitools/eyes-cypress';
// --- Base Cypress config ---
const baseConfig = defineConfig({
projectId: 'n2sma2',
viewportWidth: 1440,
viewportHeight: 1024,
e2e: {
specPattern: 'cypress/integration/**/*.{js,ts}',
setupNodeEvents(on, config) {
// Code coverage
coverage(on, config);
export default eyesPlugin(
defineConfig({
projectId: 'n2sma2',
viewportWidth: 1440,
viewportHeight: 1024,
e2e: {
specPattern: 'cypress/integration/**/*.{js,ts}',
setupNodeEvents(on, config) {
coverage(on, config);
cypressSplit(on, config);
on('before:browser:launch', (browser, launchOptions) => {
if (browser.name === 'chrome' && browser.isHeadless) {
launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1');
}
return launchOptions;
});
// copy any needed variables from process.env to config.env
config.env.useAppli = process.env.USE_APPLI ? true : false;
config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
// Test splitting
cypressSplit(on, config);
// Browser tweaks for CI
on('before:browser:launch', (browser, launchOptions) => {
if (browser.name === 'chrome' && browser.isHeadless) {
launchOptions.args.push(
'--window-size=1440,1024',
'--force-device-scale-factor=1',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--disable-web-security'
);
if (config.env.useArgos) {
registerArgosTask(on, config, {
// Enable upload to Argos only when it runs on CI.
uploadToArgos: !!process.env.CI,
});
} else {
addMatchImageSnapshotPlugin(on, config);
}
return launchOptions;
});
// Env flags
config.env.useAppli = process.env.USE_APPLI === 'true';
config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
if (config.env.useArgos) {
registerArgosTask(on, config, { uploadToArgos: !!process.env.CI });
} else {
addMatchImageSnapshotPlugin(on, config);
}
return config;
},
},
video: false,
defaultCommandTimeout: 10000,
requestTimeout: 10000,
responseTimeout: 10000,
pageLoadTimeout: 30000,
});
// --- Conditional Applitools wrapper ---
function withApplitools(config: Cypress.ConfigOptions): Cypress.ConfigOptions {
const shouldLoadApplitools = !!process.env.APPLITOOLS_API_KEY && process.env.USE_APPLI === 'true';
if (shouldLoadApplitools) {
return eyesPlugin(config, {
serverUrl: 'https://eyes.applitools.com',
batch: {
name:
process.env.APPLITOOLS_BATCH_NAME ||
`GitHub Actions - ${process.env.GITHUB_WORKFLOW || 'Cypress Tests'}`,
id:
process.env.APPLITOOLS_BATCH_ID ||
`${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}`,
// do not forget to return the changed config object!
return config;
},
testConcurrency: 1,
browser: { name: 'chrome', width: 1440, height: 1024 },
viewportSize: { width: 1440, height: 1024 },
matchTimeout: 2000,
forceFullPageScreenshot: true,
// cspell:ignore dont
dontCloseBatches: false,
saveDebugScreenshots: false,
saveDiffs: false,
concurrency: 1,
});
}
return config;
}
// --- Export final config ---
export default withApplitools(baseConfig);
},
video: false,
})
);

View File

@@ -1186,4 +1186,17 @@ end
imgSnapshotTest(graph, { htmlLabels: false });
});
});
it('V2 - 17: should apply class def colour to edge label', () => {
imgSnapshotTest(
` graph LR
id1(Start) link@-- "Label" -->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px
class id2 myClass
classDef myClass fill:#bbf,stroke:#f66,stroke-width:2px,color:white,stroke-dasharray: 5 5
class link myClass
`
);
});
});

View File

@@ -31,7 +31,7 @@
"lint:fix": "eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts",
"lint:jison": "tsx ./scripts/jison/lint.mts",
"contributors": "tsx scripts/updateContributors.ts",
"cypress": "cypress run --spec ./cypress/integration/rendering/appli.spec.js",
"cypress": "cypress run",
"cypress:open": "cypress open",
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
"e2e:coverage": "start-server-and-test dev:coverage http://localhost:9000/ cypress",

View File

@@ -25,7 +25,7 @@ import {
import rough from 'roughjs';
import createLabel from './createLabel.js';
import { addEdgeMarkers } from './edgeMarker.ts';
import { isLabelStyle } from './shapes/handDrawnShapeStyles.js';
import { isLabelStyle, styles2String } from './shapes/handDrawnShapeStyles.js';
const edgeLabels = new Map();
const terminalLabels = new Map();
@@ -43,8 +43,10 @@ export const getLabelStyles = (styleArray) => {
export const insertEdgeLabel = async (elem, edge) => {
let useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels);
const { labelStyles } = styles2String(edge);
edge.labelStyle = labelStyles;
const labelElement = await createText(elem, edge.label, {
style: getLabelStyles(edge.labelStyle),
style: edge.labelStyle,
useHtmlLabels,
addSvgBackground: true,
isNode: false,

View File

@@ -20,7 +20,11 @@ export const compileStyles = (node: Node) => {
// the array is the styles of node from the classes it is using
// node.cssStyles is an array of styles directly set on the node
// concat the arrays and remove duplicates such that the values from node.cssStyles are used if there are duplicates
const stylesMap = styles2Map([...(node.cssCompiledStyles || []), ...(node.cssStyles || [])]);
const stylesMap = styles2Map([
...(node.cssCompiledStyles || []),
...(node.cssStyles || []),
...(node.labelStyle || []),
]);
return { stylesMap, stylesArray: [...stylesMap] };
};

9726
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,6 @@
"./demos/dev",
"./vite.config.ts",
"./vitest.workspace.js",
"eslint.config.js",
"./appli.config.ts"
"eslint.config.js"
]
}