diff --git a/.build/types.ts b/.build/types.ts index 419240782..9dec05a68 100644 --- a/.build/types.ts +++ b/.build/types.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { packageOptions } from './common.js'; import { execSync } from 'child_process'; @@ -5,11 +6,17 @@ const buildType = (packageName: string) => { console.log(`Building types for ${packageName}`); try { const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`); - out.length > 0 && console.log(out.toString()); + if (out.length > 0) { + console.log(out.toString()); + } } catch (e) { console.error(e); - e.stdout.length > 0 && console.error(e.stdout.toString()); - e.stderr.length > 0 && console.error(e.stderr.toString()); + if (e.stdout.length > 0) { + console.error(e.stdout.toString()); + } + if (e.stderr.length > 0) { + console.error(e.stderr.toString()); + } } }; diff --git a/.cspell/code-terms.txt b/.cspell/code-terms.txt index 2670a9521..cf47a86a8 100644 --- a/.cspell/code-terms.txt +++ b/.cspell/code-terms.txt @@ -13,6 +13,7 @@ bqstring BQUOTE bramp BRKT +brotli callbackargs callbackname classdef @@ -113,6 +114,7 @@ STYLECLASS STYLEOPTS subcomponent subcomponents +subconfig SUBROUTINEEND SUBROUTINESTART Subschemas @@ -127,6 +129,7 @@ titlevalue topbar TRAPEND TRAPSTART +treemap ts-nocheck tsdoc typeof diff --git a/.cspell/contributors.txt b/.cspell/contributors.txt index bd3ad9da2..b7f52f8d0 100644 --- a/.cspell/contributors.txt +++ b/.cspell/contributors.txt @@ -4,5 +4,6 @@ cpettitt Dong Cai Nikolay Rozhkov Peng Xiao +Per Brolin subhash-halder Vinod Sidharth diff --git a/.cspell/libraries.txt b/.cspell/libraries.txt index 83bea2d09..7eabb8b29 100644 --- a/.cspell/libraries.txt +++ b/.cspell/libraries.txt @@ -20,6 +20,7 @@ dagre-d3 Deepdwn Docsify Docsy +Doctave DokuWiki dompurify elkjs @@ -56,12 +57,14 @@ pyplot redmine rehype rscratch +shiki sparkline sphinxcontrib ssim stylis Swimm tsbuildinfo +tseslint Tuleap Typora unocss diff --git a/.cspell/misc-terms.txt b/.cspell/misc-terms.txt index 467e48891..0efd1dcc0 100644 --- a/.cspell/misc-terms.txt +++ b/.cspell/misc-terms.txt @@ -1 +1,4 @@ +BRANDES +handdrawn +KOEPF newbranch diff --git a/.esbuild/build.ts b/.esbuild/build.ts index 3c87f9d62..505c18405 100644 --- a/.esbuild/build.ts +++ b/.esbuild/build.ts @@ -2,7 +2,8 @@ import { build } from 'esbuild'; import { mkdir, writeFile } from 'node:fs/promises'; import { packageOptions } from '../.build/common.js'; import { generateLangium } from '../.build/generateLangium.js'; -import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js'; +import type { MermaidBuildOptions } from './util.js'; +import { defaultOptions, getBuildConfig } from './util.js'; const shouldVisualize = process.argv.includes('--visualize'); @@ -35,11 +36,11 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { if (shouldVisualize) { for (const { metafile } of results) { - if (!metafile) { + if (!metafile?.outputs) { continue; } const fileName = Object.keys(metafile.outputs) - .filter((file) => !file.includes('chunks') && file.endsWith('js'))[0] + .find((file) => !file.includes('chunks') && file.endsWith('js')) .replace('dist/', ''); // Upload metafile into https://esbuild.github.io/analyze/ await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile)); @@ -48,13 +49,14 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { }; const handler = (e) => { + // eslint-disable-next-line no-console console.error(e); process.exit(1); }; const main = async () => { await generateLangium(); - await mkdir('stats').catch(() => {}); + await mkdir('stats', { recursive: true }); const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; // it should build `parser` before `mermaid` because it's a dependency for (const pkg of packageNames) { diff --git a/.esbuild/jisonPlugin.ts b/.esbuild/jisonPlugin.ts index de801ea9f..007516f08 100644 --- a/.esbuild/jisonPlugin.ts +++ b/.esbuild/jisonPlugin.ts @@ -1,6 +1,6 @@ import { readFile } from 'node:fs/promises'; import { transformJison } from '../.build/jisonTransformer.js'; -import { Plugin } from 'esbuild'; +import type { Plugin } from 'esbuild'; export const jisonPlugin: Plugin = { name: 'jison', diff --git a/.esbuild/server.ts b/.esbuild/server.ts index 9102c7de8..ef61ebec2 100644 --- a/.esbuild/server.ts +++ b/.esbuild/server.ts @@ -1,11 +1,12 @@ -import express from 'express'; -import type { NextFunction, Request, Response } from 'express'; -import cors from 'cors'; -import { getBuildConfig, defaultOptions } from './util.js'; -import { context } from 'esbuild'; +/* eslint-disable no-console */ import chokidar from 'chokidar'; -import { generateLangium } from '../.build/generateLangium.js'; +import cors from 'cors'; +import { context } from 'esbuild'; +import type { Request, Response } from 'express'; +import express from 'express'; import { packageOptions } from '../.build/common.js'; +import { generateLangium } from '../.build/generateLangium.js'; +import { defaultOptions, getBuildConfig } from './util.js'; const configs = Object.values(packageOptions).map(({ packageName }) => getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName }) @@ -19,16 +20,28 @@ const mermaidIIFEConfig = getBuildConfig({ }); configs.push(mermaidIIFEConfig); -const contexts = await Promise.all(configs.map((config) => context(config))); +const contexts = await Promise.all( + configs.map(async (config) => ({ config, context: await context(config) })) +); +let rebuildCounter = 1; const rebuildAll = async () => { - console.time('Rebuild time'); - await Promise.all(contexts.map((ctx) => ctx.rebuild())).catch((e) => console.error(e)); - console.timeEnd('Rebuild time'); + const buildNumber = rebuildCounter++; + const timeLabel = `Rebuild ${buildNumber} Time (total)`; + console.time(timeLabel); + await Promise.all( + contexts.map(async ({ config, context }) => { + const buildVariant = `Rebuild ${buildNumber} Time (${Object.keys(config.entryPoints!)[0]} ${config.format})`; + console.time(buildVariant); + await context.rebuild(); + console.timeEnd(buildVariant); + }) + ).catch((e) => console.error(e)); + console.timeEnd(timeLabel); }; let clients: { id: number; response: Response }[] = []; -function eventsHandler(request: Request, response: Response, next: NextFunction) { +function eventsHandler(request: Request, response: Response) { const headers = { 'Content-Type': 'text/event-stream', Connection: 'keep-alive', @@ -45,19 +58,20 @@ function eventsHandler(request: Request, response: Response, next: NextFunction) }); } -let timeoutId: NodeJS.Timeout | undefined = undefined; +let timeoutID: NodeJS.Timeout | undefined = undefined; /** * Debounce file change events to avoid rebuilding multiple times. */ function handleFileChange() { - if (timeoutId !== undefined) { - clearTimeout(timeoutId); + if (timeoutID !== undefined) { + clearTimeout(timeoutID); } - timeoutId = setTimeout(async () => { + // eslint-disable-next-line @typescript-eslint/no-misused-promises + timeoutID = setTimeout(async () => { await rebuildAll(); sendEventsToAll(); - timeoutId = undefined; + timeoutID = undefined; }, 100); } @@ -74,15 +88,16 @@ async function createServer() { ignoreInitial: true, ignored: [/node_modules/, /dist/, /docs/, /coverage/], }) + // eslint-disable-next-line @typescript-eslint/no-misused-promises .on('all', async (event, path) => { // Ignore other events. if (!['add', 'change'].includes(event)) { return; } - if (/\.langium$/.test(path)) { + console.log(`${path} changed. Rebuilding...`); + if (path.endsWith('.langium')) { await generateLangium(); } - console.log(`${path} changed. Rebuilding...`); handleFileChange(); }); @@ -99,4 +114,4 @@ async function createServer() { }); } -createServer(); +void createServer(); diff --git a/.esbuild/util.ts b/.esbuild/util.ts index 5c21cbf45..6d424ab17 100644 --- a/.esbuild/util.ts +++ b/.esbuild/util.ts @@ -56,7 +56,7 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { const external: string[] = ['require', 'fs', 'path']; const { name, file, packageName } = packageOptions[entryName]; const outFileName = getFileName(name, options); - let output: BuildOptions = buildOptions({ + const output: BuildOptions = buildOptions({ absWorkingDir: resolve(__dirname, `../packages/${packageName}`), entryPoints: { [outFileName]: `src/${file}`, diff --git a/.eslintignore b/.eslintignore deleted file mode 120000 index 3e4e48b0b..000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -.gitignore \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index c9428c9f5..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,190 +0,0 @@ -module.exports = { - env: { - browser: true, - es6: true, - 'jest/globals': true, - node: true, - }, - root: true, - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaFeatures: { - experimentalObjectRestSpread: true, - jsx: true, - }, - tsconfigRootDir: __dirname, - sourceType: 'module', - ecmaVersion: 2022, - allowAutomaticSingleRunInference: true, - project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'], - parser: '@typescript-eslint/parser', - }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:json/recommended', - 'plugin:markdown/recommended-legacy', - 'plugin:@cspell/recommended', - 'prettier', - ], - plugins: [ - '@typescript-eslint', - 'no-only-tests', - 'html', - 'jest', - 'jsdoc', - 'json', - '@cspell', - 'lodash', - 'unicorn', - ], - ignorePatterns: [ - // this file is automatically generated by `pnpm run --filter mermaid types:build-config` - 'packages/mermaid/src/config.type.ts', - ], - rules: { - curly: 'error', - 'no-console': 'error', - 'no-prototype-builtins': 'off', - 'no-unused-vars': 'off', - 'cypress/no-async-tests': 'off', - '@typescript-eslint/consistent-type-imports': 'error', - '@typescript-eslint/no-explicit-any': 'warn', - '@typescript-eslint/no-floating-promises': 'error', - '@typescript-eslint/no-misused-promises': 'error', - '@typescript-eslint/no-unused-vars': 'warn', - '@typescript-eslint/consistent-type-definitions': 'error', - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-expect-error': 'allow-with-description', - 'ts-ignore': 'allow-with-description', - 'ts-nocheck': 'allow-with-description', - 'ts-check': 'allow-with-description', - minimumDescriptionLength: 10, - }, - ], - '@typescript-eslint/naming-convention': [ - 'error', - { - selector: 'typeLike', - format: ['PascalCase'], - custom: { - regex: '^I[A-Z]', - match: false, - }, - }, - ], - 'json/*': ['error', 'allowComments'], - '@cspell/spellchecker': [ - 'error', - { - checkIdentifiers: true, - checkStrings: true, - checkStringTemplates: true, - }, - ], - 'no-empty': [ - 'error', - { - allowEmptyCatch: true, - }, - ], - 'no-only-tests/no-only-tests': 'error', - 'lodash/import-scope': ['error', 'method'], - 'unicorn/better-regex': 'error', - 'unicorn/no-abusive-eslint-disable': 'error', - 'unicorn/no-array-push-push': 'error', - 'unicorn/no-for-loop': 'error', - 'unicorn/no-instanceof-array': 'error', - 'unicorn/no-typeof-undefined': 'error', - 'unicorn/no-unnecessary-await': 'error', - 'unicorn/no-unsafe-regex': 'warn', - 'unicorn/no-useless-promise-resolve-reject': 'error', - 'unicorn/prefer-array-find': 'error', - 'unicorn/prefer-array-flat-map': 'error', - 'unicorn/prefer-array-index-of': 'error', - 'unicorn/prefer-array-some': 'error', - 'unicorn/prefer-default-parameters': 'error', - 'unicorn/prefer-includes': 'error', - 'unicorn/prefer-negative-index': 'error', - 'unicorn/prefer-object-from-entries': 'error', - 'unicorn/prefer-string-starts-ends-with': 'error', - 'unicorn/prefer-string-trim-start-end': 'error', - 'unicorn/string-content': 'error', - 'unicorn/prefer-spread': 'error', - 'unicorn/no-lonely-if': 'error', - }, - overrides: [ - { - files: ['cypress/**', 'demos/**'], - rules: { - 'no-console': 'off', - }, - }, - { - files: ['*.{js,jsx,mjs,cjs}'], - extends: ['plugin:jsdoc/recommended'], - rules: { - 'jsdoc/check-indentation': 'off', - 'jsdoc/check-alignment': 'off', - 'jsdoc/check-line-alignment': 'off', - 'jsdoc/multiline-blocks': 'off', - 'jsdoc/newline-after-description': 'off', - 'jsdoc/tag-lines': 'off', - 'jsdoc/require-param-description': 'off', - 'jsdoc/require-param-type': 'off', - 'jsdoc/require-returns': 'off', - 'jsdoc/require-returns-description': 'off', - }, - }, - { - files: ['*.{ts,tsx}'], - plugins: ['tsdoc'], - rules: { - 'no-restricted-syntax': [ - 'error', - { - selector: 'TSEnumDeclaration', - message: - 'Prefer using TypeScript union types over TypeScript enum, since TypeScript enums have a bunch of issues, see https://dev.to/dvddpl/whats-the-problem-with-typescript-enums-2okj', - }, - ], - 'tsdoc/syntax': 'error', - }, - }, - { - files: ['*.spec.{ts,js}', 'cypress/**', 'demos/**', '**/docs/**'], - rules: { - 'jsdoc/require-jsdoc': 'off', - '@typescript-eslint/no-unused-vars': 'off', - }, - }, - { - files: ['*.spec.{ts,js}', 'tests/**', 'cypress/**/*.js'], - rules: { - '@cspell/spellchecker': [ - 'error', - { - checkIdentifiers: false, - checkStrings: false, - checkStringTemplates: false, - }, - ], - }, - }, - { - files: ['*.html', '*.md', '**/*.md/*'], - rules: { - 'no-var': 'error', - 'no-undef': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-floating-promises': 'off', - '@typescript-eslint/no-misused-promises': 'off', - }, - parserOptions: { - project: null, - }, - }, - ], -}; diff --git a/.github/lychee.toml b/.github/lychee.toml index c5a2f0e45..2e3b08c41 100644 --- a/.github/lychee.toml +++ b/.github/lychee.toml @@ -41,7 +41,10 @@ exclude = [ "https://bundlephobia.com", # Chrome webstore migration issue. Temporary -"https://chromewebstore.google.com" +"https://chromewebstore.google.com", + +# Drupal 403 +"https://(www.)?drupal.org" ] # Exclude all private IPs from checking. diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 87607bc2f..0ce778957 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -18,7 +18,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf54772bc..c6e96912e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 # uses version from "packageManager" field in package.json - name: Setup Node.js diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml index 1238fe371..5e5407a23 100644 --- a/.github/workflows/e2e-applitools.yml +++ b/.github/workflows/e2e-applitools.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 # uses version from "packageManager" field in package.json - name: Setup Node.js diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6477c9eb5..df487494d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,9 +1,3 @@ -# We use github cache to save snapshots between runs. -# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. -# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots. -# These are then downloaded before running the E2E, providing the reference snapshots. -# If there are any errors, the diff image is uploaded to artifacts, and the user is notified. - name: E2E on: @@ -38,7 +32,7 @@ jobs: options: --user 1001 steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -72,16 +66,6 @@ jobs: mkdir -p cypress/snapshots/stats/base mv stats cypress/snapshots/stats/base - - name: Cypress run - uses: cypress-io/github-action@v6 - id: cypress-snapshot-gen - if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} - with: - install: false - start: pnpm run dev - wait-on: 'http://localhost:9000' - browser: chrome - e2e: runs-on: ubuntu-latest container: @@ -95,7 +79,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 # uses version from "packageManager" field in package.json - name: Setup Node.js @@ -146,6 +130,10 @@ jobs: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true CYPRESS_COMMIT: ${{ github.sha }} + ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} + ARGOS_PARALLEL: ${{ secrets.CYPRESS_RECORD_KEY != '' }} + ARGOS_PARALLEL_TOTAL: 4 + ARGOS_PARALLEL_INDEX: ${{ matrix.containers }} - name: Upload Coverage to Codecov uses: codecov/codecov-action@v4 @@ -158,55 +146,3 @@ jobs: fail_ci_if_error: false verbose: true token: 6845cc80-77ee-4e17-85a1-026cd95e0766 - - # We upload the artifacts into numbered archives to prevent overwriting - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - if: ${{ always() }} - with: - name: snapshots-${{ matrix.containers }} - retention-days: 1 - path: ./cypress/snapshots - - combineArtifacts: - needs: e2e - runs-on: ubuntu-latest - if: ${{ always() }} - steps: - # Download all snapshot artifacts and merge them into a single folder - - name: Download All Artifacts - uses: actions/download-artifact@v4 - with: - path: snapshots - pattern: snapshots-* - merge-multiple: true - - # For successful push events, we save the snapshots cache - - name: Save snapshots cache - id: cache-upload - if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }} - uses: actions/cache/save@v4 - with: - path: ./snapshots - key: ${{ runner.os }}-snapshots-${{ github.event.after }} - - - name: Flatten images to a folder - if: ${{ needs.e2e.result == 'failure' }} - run: | - mkdir errors - cd snapshots - find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \; - - - name: Upload Error snapshots - if: ${{ needs.e2e.result == 'failure' }} - uses: actions/upload-artifact@v4 - id: upload-artifacts - with: - name: error-snapshots - retention-days: 10 - path: errors/ - - - name: Notify Users - if: ${{ needs.e2e.result == 'failure' }} - run: | - echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8f5995d71..ac34067f6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 # uses version from "packageManager" field in package.json - name: Setup Node.js diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index fb70a90ec..4ff5f4117 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -25,7 +25,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/release-preview-publish.yml b/.github/workflows/release-preview-publish.yml index c763430b0..91e3ac981 100644 --- a/.github/workflows/release-preview-publish.yml +++ b/.github/workflows/release-preview-publish.yml @@ -13,7 +13,7 @@ jobs: with: fetch-depth: 0 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index dce461cf5..4dcf709c0 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v4 - uses: fregante/setup-git-user@v2 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 # uses version from "packageManager" field in package.json - name: Setup Node.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a4bd264e0..a0b284a68 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 # uses version from "packageManager" field in package.json - name: Setup Node.js diff --git a/.github/workflows/update-browserlist.yml b/.github/workflows/update-browserlist.yml index 9aac3d7b3..f8f7696cd 100644 --- a/.github/workflows/update-browserlist.yml +++ b/.github/workflows/update-browserlist.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 - run: npx update-browserslist-db@latest - name: Commit changes uses: EndBug/add-and-commit@v9 diff --git a/.vite/build.ts b/.vite/build.ts index 7ce93a497..486d59452 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -1,4 +1,5 @@ -import { build, InlineConfig, type PluginOption } from 'vite'; +import type { InlineConfig } from 'vite'; +import { build, type PluginOption } from 'vite'; import { resolve } from 'path'; import { fileURLToPath } from 'url'; import jisonPlugin from './jisonPlugin.js'; @@ -46,9 +47,10 @@ interface BuildOptions { export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => { const external: (string | RegExp)[] = ['require', 'fs', 'path']; + // eslint-disable-next-line no-console console.log(entryName, packageOptions[entryName]); const { name, file, packageName } = packageOptions[entryName]; - let output: OutputOptions = [ + const output: OutputOptions = [ { name, format: 'esm', @@ -83,7 +85,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) plugins: [ jisonPlugin(), jsonSchemaPlugin(), // handles `.schema.yaml` files - // @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite typescript({ compilerOptions: { declaration: false } }), istanbul({ exclude: ['node_modules', 'test/', '__mocks__', 'generated'], @@ -121,10 +122,10 @@ await generateLangium(); if (watch) { await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' })); - build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' })); + void build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' })); if (!mermaidOnly) { - build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); - build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' })); + void build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); + void build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' })); } } else if (visualize) { await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' })); diff --git a/.vite/jsonSchemaPlugin.ts b/.vite/jsonSchemaPlugin.ts index 2e5b5cc0b..3614d5b45 100644 --- a/.vite/jsonSchemaPlugin.ts +++ b/.vite/jsonSchemaPlugin.ts @@ -1,4 +1,4 @@ -import { PluginOption } from 'vite'; +import type { PluginOption } from 'vite'; import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js'; /** diff --git a/.vite/server.ts b/.vite/server.ts index 99d16f6f2..078599dc1 100644 --- a/.vite/server.ts +++ b/.vite/server.ts @@ -23,8 +23,9 @@ async function createServer() { app.use(express.static('cypress/platform')); app.listen(9000, () => { + // eslint-disable-next-line no-console console.log(`Listening on http://localhost:9000`); }); } -createServer(); +void createServer(); diff --git a/README.md b/README.md index d368a4349..8d5eebfeb 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Try Live Editor previews of future releases: diff --git a/cypress.config.ts b/cypress.config.ts index 4182d92a8..3346b5549 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from 'cypress'; import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; import coverage from '@cypress/code-coverage/task'; import eyesPlugin from '@applitools/eyes-cypress'; +import { registerArgosTask } from '@argos-ci/cypress/task'; + export default eyesPlugin( defineConfig({ projectId: 'n2sma2', @@ -17,10 +19,17 @@ export default eyesPlugin( } return launchOptions; }); - addMatchImageSnapshotPlugin(on, config); // copy any needed variables from process.env to config.env config.env.useAppli = process.env.USE_APPLI ? true : false; + config.env.useArgos = !!process.env.CI; + if (config.env.useArgos) { + registerArgosTask(on, config, { + token: 'fc3a35cf5200db928d65b2047861582d9444032b', + }); + } else { + addMatchImageSnapshotPlugin(on, config); + } // do not forget to return the changed config object! return config; }, diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts index aed5d7973..3ffba697a 100644 --- a/cypress/helpers/util.ts +++ b/cypress/helpers/util.ts @@ -35,7 +35,7 @@ export const mermaidUrl = ( }; const objStr: string = JSON.stringify(codeObject); let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`; - if (api) { + if (api && typeof graphStr === 'string') { url = `http://localhost:9000/xss.html?graph=${graphStr}`; } @@ -54,16 +54,15 @@ export const imgSnapshotTest = ( ): void => { const options: CypressMermaidConfig = { ..._options, - fontFamily: _options.fontFamily || 'courier', + fontFamily: _options.fontFamily ?? 'courier', // @ts-ignore TODO: Fix type of fontSize - fontSize: _options.fontSize || '16px', + fontSize: _options.fontSize ?? '16px', sequence: { - ...(_options.sequence || {}), + ...(_options.sequence ?? {}), actorFontFamily: 'courier', - noteFontFamily: - _options.sequence && _options.sequence.noteFontFamily - ? _options.sequence.noteFontFamily - : 'courier', + noteFontFamily: _options.sequence?.noteFontFamily + ? _options.sequence.noteFontFamily + : 'courier', messageFontFamily: 'courier', }, }; @@ -95,18 +94,7 @@ export const openURLAndVerifyRendering = ( options: CypressMermaidConfig, validation?: any ): void => { - const useAppli: boolean = Cypress.env('useAppli'); - const name: string = (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 name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); cy.visit(url); cy.window().should('have.property', 'rendered', true); @@ -116,11 +104,27 @@ export const openURLAndVerifyRendering = ( cy.get('svg').should(validation); } + verifyScreenshot(name); +}; + +export const verifyScreenshot = (name: string): void => { + const useAppli: boolean = Cypress.env('useAppli'); + const useArgos: boolean = Cypress.env('useArgos'); + 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, + }); cy.log(`Check eyes ${Cypress.spec.name}`); cy.eyesCheckWindow('Click!'); cy.log(`Closing eyes ${Cypress.spec.name}`); cy.eyesClose(); + } else if (useArgos) { + cy.argosScreenshot(name); } else { cy.matchImageSnapshot(name); } diff --git a/cypress/integration/other/configuration.spec.js b/cypress/integration/other/configuration.spec.js index 544eab40f..ad6b21e29 100644 --- a/cypress/integration/other/configuration.spec.js +++ b/cypress/integration/other/configuration.spec.js @@ -1,4 +1,4 @@ -import { renderGraph } from '../../helpers/util.ts'; +import { renderGraph, verifyScreenshot } from '../../helpers/util.ts'; describe('Configuration', () => { describe('arrowMarkerAbsolute', () => { it('should handle default value false of arrowMarkerAbsolute', () => { @@ -119,8 +119,7 @@ describe('Configuration', () => { const url = 'http://localhost:9000/regression/issue-1874.html'; cy.visit(url); cy.window().should('have.property', 'rendered', true); - cy.get('svg').should('be.visible'); - cy.matchImageSnapshot( + verifyScreenshot( 'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives' ); }); @@ -145,7 +144,7 @@ describe('Configuration', () => { // none of the diagrams should be error diagrams expect($svg).to.not.contain('Syntax error'); }); - cy.matchImageSnapshot( + verifyScreenshot( 'configuration.spec-should-not-render-error-diagram-if-suppressErrorRendering-is-set' ); }); @@ -162,7 +161,7 @@ describe('Configuration', () => { // some of the diagrams should be error diagrams expect($svg).to.contain('Syntax error'); }); - cy.matchImageSnapshot( + verifyScreenshot( 'configuration.spec-should-render-error-diagram-if-suppressErrorRendering-is-not-set' ); }); diff --git a/cypress/integration/other/xss.spec.js b/cypress/integration/other/xss.spec.js index d041fa5f4..1e51d2f23 100644 --- a/cypress/integration/other/xss.spec.js +++ b/cypress/integration/other/xss.spec.js @@ -10,7 +10,6 @@ describe('XSS', () => { cy.wait(1000).then(() => { cy.get('.mermaid').should('exist'); }); - cy.get('svg'); }); it('should not allow tags in the css', () => { diff --git a/cypress/integration/rendering/c4.spec.js b/cypress/integration/rendering/c4.spec.js index 59af6504b..f699bd429 100644 --- a/cypress/integration/rendering/c4.spec.js +++ b/cypress/integration/rendering/c4.spec.js @@ -30,7 +30,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Container diagram', () => { imgSnapshotTest( @@ -50,7 +49,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Component diagram', () => { imgSnapshotTest( @@ -69,7 +67,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Dynamic diagram', () => { imgSnapshotTest( @@ -93,7 +90,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Deployment diagram', () => { imgSnapshotTest( @@ -117,6 +113,5 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); }); diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index cab3649df..a98a359ed 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -32,7 +32,6 @@ describe('Class diagram', () => { `, { logLevel: 1 } ); - cy.get('svg'); }); it('2: should render a simple class diagrams with cardinality', () => { @@ -61,7 +60,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('3: should render a simple class diagram with different visibilities', () => { @@ -79,7 +77,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('4: should render a simple class diagram with comments', () => { @@ -109,7 +106,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('5: should render a simple class diagram with abstract method', () => { @@ -121,7 +117,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('6: should render a simple class diagram with static method', () => { @@ -133,7 +128,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('7: should render a simple class diagram with Generic class', () => { @@ -153,7 +147,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('8: should render a simple class diagram with Generic class and relations', () => { @@ -174,7 +167,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('9: should render a simple class diagram with clickable link', () => { @@ -196,7 +188,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('10: should render a simple class diagram with clickable callback', () => { @@ -218,7 +209,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('11: should render a simple class diagram with return type on method', () => { @@ -233,7 +223,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('12: should render a simple class diagram with generic types', () => { @@ -249,7 +238,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('13: should render a simple class diagram with css classes applied', () => { @@ -267,7 +255,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('14: should render a simple class diagram with css classes applied directly', () => { @@ -283,7 +270,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('15: should render a simple class diagram with css classes applied to multiple classes', () => { @@ -298,7 +284,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('16: should render multiple class diagrams', () => { @@ -351,7 +336,6 @@ describe('Class diagram', () => { ], {} ); - cy.get('svg'); }); // it('17: should render a class diagram when useMaxWidth is true (default)', () => { @@ -421,7 +405,6 @@ describe('Class diagram', () => { `, { logLevel: 1 } ); - cy.get('svg'); }); it('should render class diagram with newlines in title', () => { @@ -439,7 +422,6 @@ describe('Class diagram', () => { +quack() } `); - cy.get('svg'); }); it('should render class diagram with many newlines in title', () => { diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index 578f5a398..1a2340906 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -218,7 +218,6 @@ describe('Entity Relationship Diagram', () => { `, { loglevel: 1 } ); - cy.get('svg'); }); it('should render entities with keys', () => { diff --git a/cypress/integration/rendering/quadrantChart.spec.js b/cypress/integration/rendering/quadrantChart.spec.js index 83a1455c6..4830db656 100644 --- a/cypress/integration/rendering/quadrantChart.spec.js +++ b/cypress/integration/rendering/quadrantChart.spec.js @@ -8,7 +8,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render a complete quadrant chart', () => { imgSnapshotTest( @@ -30,7 +29,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render without points', () => { imgSnapshotTest( @@ -46,7 +44,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should able to render y-axix on right side', () => { imgSnapshotTest( @@ -63,7 +60,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should able to render x-axix on bottom', () => { imgSnapshotTest( @@ -80,7 +76,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should able to render x-axix on bottom and y-axis on right', () => { imgSnapshotTest( @@ -97,7 +92,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render without title', () => { imgSnapshotTest( @@ -112,7 +106,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should use all the config', () => { imgSnapshotTest( @@ -135,7 +128,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should use all the theme variable', () => { imgSnapshotTest( @@ -158,7 +150,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render x-axis labels in the center, if x-axis has two labels', () => { imgSnapshotTest( @@ -180,7 +171,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render y-axis labels in the center, if y-axis has two labels', () => { imgSnapshotTest( @@ -202,7 +192,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render both axes labels on the left and bottom, if both axes have only one label', () => { imgSnapshotTest( @@ -224,7 +213,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('it should render data points with styles', () => { @@ -249,7 +237,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('it should render data points with styles + classes', () => { diff --git a/cypress/integration/rendering/requirement.spec.js b/cypress/integration/rendering/requirement.spec.js index f33ae7a0c..343441848 100644 --- a/cypress/integration/rendering/requirement.spec.js +++ b/cypress/integration/rendering/requirement.spec.js @@ -44,6 +44,5 @@ describe('Requirement diagram', () => { `, {} ); - cy.get('svg'); }); }); diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js index 1285a0832..f18e99abf 100644 --- a/cypress/integration/rendering/sequencediagram.spec.js +++ b/cypress/integration/rendering/sequencediagram.spec.js @@ -1,8 +1,6 @@ -/// - import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; -context('Sequence diagram', () => { +describe('Sequence diagram', () => { it('should render a sequence diagram with boxes', () => { renderGraph( ` @@ -68,6 +66,19 @@ context('Sequence diagram', () => { { sequence: { actorFontFamily: 'courier' } } ); }); + it('should render bidirectional arrows', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice<<->>John: Hello John, how are you? + Alice<<-->>John: Hi Alice, I can hear you! + John<<->>Alice: This also works the other way + John<<-->>Alice: Yes + Alice->John: Test + John->>Alice: Still works + ` + ); + }); it('should handle different line breaks', () => { imgSnapshotTest( ` @@ -231,7 +242,7 @@ context('Sequence diagram', () => { ` ); }); - context('font settings', () => { + describe('font settings', () => { it('should render different note fonts when configured', () => { imgSnapshotTest( ` @@ -328,7 +339,7 @@ context('Sequence diagram', () => { ); }); }); - context('auth width scaling', () => { + describe('auth width scaling', () => { it('should render long actor descriptions', () => { imgSnapshotTest( ` @@ -464,6 +475,18 @@ context('Sequence diagram', () => { {} ); }); + it('should render notes over actors and participant', () => { + imgSnapshotTest( + ` + sequenceDiagram + actor Alice + participant Charlie + note over Alice: some note + note over Charlie: other note + `, + {} + ); + }); it('should render long messages from an actor to the left to one to the right', () => { imgSnapshotTest( ` @@ -505,7 +528,7 @@ context('Sequence diagram', () => { ); }); }); - context('background rects', () => { + describe('background rects', () => { it('should render a single and nested rects', () => { imgSnapshotTest( ` @@ -785,7 +808,7 @@ context('Sequence diagram', () => { ); }); }); - context('directives', () => { + describe('directives', () => { it('should override config with directive settings', () => { imgSnapshotTest( ` @@ -817,7 +840,7 @@ context('Sequence diagram', () => { ); }); }); - context('links', () => { + describe('links', () => { it('should support actor links', () => { renderGraph( ` @@ -833,7 +856,7 @@ context('Sequence diagram', () => { ); cy.get('#actor0_popup').should((popupMenu) => { const style = popupMenu.attr('style'); - expect(style).to.undefined; + // expect(style).to.undefined; }); cy.get('#root-0').click(); cy.get('#actor0_popup').should((popupMenu) => { @@ -908,7 +931,7 @@ context('Sequence diagram', () => { ); }); }); - context('svg size', () => { + describe('svg size', () => { it('should render a sequence diagram when useMaxWidth is true (default)', () => { renderGraph( ` @@ -987,7 +1010,7 @@ context('Sequence diagram', () => { }); }); }); - context('render after error', () => { + describe('render after error', () => { it('should render diagram after fixing destroy participant error', () => { cy.on('uncaught:exception', (err) => { return false; diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 9a1a27abe..cb40aa8dc 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -8,7 +8,6 @@ describe('State diagram', () => { `, { logLevel: 1, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a simple state diagrams', () => { imgSnapshotTest( @@ -20,7 +19,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a long descriptions instead of id when available', () => { imgSnapshotTest( @@ -32,7 +30,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a long descriptions with additional descriptions', () => { imgSnapshotTest( @@ -44,7 +41,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a single state with short descriptions', () => { imgSnapshotTest( @@ -55,7 +51,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a transition descriptions with new lines', () => { imgSnapshotTest( @@ -69,7 +64,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with a note', () => { imgSnapshotTest( @@ -83,7 +77,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with on the left side when so specified', () => { imgSnapshotTest( @@ -97,7 +90,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with a note together with another state', () => { imgSnapshotTest( @@ -113,7 +105,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a note with multiple lines in it', () => { imgSnapshotTest( @@ -156,7 +147,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a simple state diagrams 2', () => { imgSnapshotTest( @@ -169,7 +159,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a simple state diagrams with labels', () => { imgSnapshotTest( @@ -185,7 +174,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render state descriptions', () => { imgSnapshotTest( @@ -198,7 +186,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render composite states', () => { imgSnapshotTest( @@ -217,7 +204,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render multiple composite states', () => { imgSnapshotTest( @@ -287,7 +273,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render concurrency states', () => { imgSnapshotTest( @@ -311,7 +296,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with states in it', () => { imgSnapshotTest( diff --git a/cypress/integration/rendering/stateDiagram.spec.js b/cypress/integration/rendering/stateDiagram.spec.js index 01e7a2b44..9be1f2322 100644 --- a/cypress/integration/rendering/stateDiagram.spec.js +++ b/cypress/integration/rendering/stateDiagram.spec.js @@ -10,7 +10,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a long descriptions instead of id when available', () => { imgSnapshotTest( @@ -22,7 +21,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a long descriptions with additional descriptions', () => { imgSnapshotTest( @@ -34,7 +32,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a single state with short descriptions', () => { imgSnapshotTest( @@ -45,7 +42,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a transition descriptions with new lines', () => { imgSnapshotTest( @@ -59,7 +55,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with a note', () => { imgSnapshotTest( @@ -73,7 +68,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with on the left side when so specified', () => { imgSnapshotTest( @@ -87,7 +81,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with a note together with another state', () => { imgSnapshotTest( @@ -103,7 +96,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a note with multiple lines in it', () => { imgSnapshotTest( @@ -146,7 +138,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a simple state diagrams 2', () => { imgSnapshotTest( @@ -159,7 +150,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a simple state diagrams with labels', () => { imgSnapshotTest( @@ -175,7 +165,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render state descriptions', () => { imgSnapshotTest( @@ -188,7 +177,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render composite states', () => { imgSnapshotTest( @@ -207,7 +195,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render multiple composit states', () => { imgSnapshotTest( @@ -277,7 +264,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render concurrency states', () => { imgSnapshotTest( @@ -301,7 +287,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with states in it', () => { imgSnapshotTest( diff --git a/cypress/integration/rendering/theme.spec.js b/cypress/integration/rendering/theme.spec.js index c84ad0c4b..1965f8c99 100644 --- a/cypress/integration/rendering/theme.spec.js +++ b/cypress/integration/rendering/theme.spec.js @@ -10,7 +10,6 @@ describe('themeCSS balancing, it', () => { `, {} ); - cy.get('svg'); }); it('should not allow unbalanced CSS definitions 2', () => { imgSnapshotTest( @@ -21,7 +20,6 @@ describe('themeCSS balancing, it', () => { `, {} ); - cy.get('svg'); }); }); @@ -45,7 +43,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a flowchart diagram', () => { imgSnapshotTest( @@ -70,7 +67,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a new flowchart diagram', () => { imgSnapshotTest( @@ -96,7 +92,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a sequence diagram', () => { imgSnapshotTest( @@ -125,7 +120,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a class diagram', () => { @@ -175,7 +169,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a state diagram', () => { imgSnapshotTest( @@ -210,7 +203,6 @@ stateDiagram `, { theme } ); - cy.get('svg'); }); it('should render a state diagram (v2)', () => { imgSnapshotTest( @@ -245,7 +237,6 @@ stateDiagram-v2 `, { theme } ); - cy.get('svg'); }); it('should render a er diagram', () => { imgSnapshotTest( @@ -266,7 +257,6 @@ erDiagram `, { theme } ); - cy.get('svg'); }); it('should render a user journey diagram', () => { imgSnapshotTest( @@ -287,7 +277,6 @@ erDiagram `, { theme } ); - cy.get('svg'); }); it('should render a gantt diagram', () => { cy.clock(new Date('2014-01-06').getTime()); @@ -326,7 +315,6 @@ erDiagram `, { theme } ); - cy.get('svg'); }); }); }); diff --git a/cypress/integration/rendering/xyChart.spec.js b/cypress/integration/rendering/xyChart.spec.js index 85d998c50..1245760e8 100644 --- a/cypress/integration/rendering/xyChart.spec.js +++ b/cypress/integration/rendering/xyChart.spec.js @@ -9,7 +9,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should render a complete chart', () => { imgSnapshotTest( @@ -35,7 +34,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('y-axis title not required', () => { imgSnapshotTest( @@ -48,7 +46,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should render a chart without y-axis with different range', () => { imgSnapshotTest( @@ -60,7 +57,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('x axis title not required', () => { imgSnapshotTest( @@ -72,7 +68,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Multiple plots can be rendered', () => { imgSnapshotTest( @@ -87,7 +82,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Decimals and negative numbers are supported', () => { imgSnapshotTest( @@ -98,7 +92,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render spark line with "plotReservedSpacePercent"', () => { imgSnapshotTest( @@ -116,7 +109,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render spark bar without displaying other property', () => { imgSnapshotTest( @@ -143,7 +135,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should use all the config from directive', () => { imgSnapshotTest( @@ -158,7 +149,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should use all the config from yaml', () => { imgSnapshotTest( @@ -199,7 +189,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis title false', () => { imgSnapshotTest( @@ -221,7 +210,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis label false', () => { imgSnapshotTest( @@ -243,7 +231,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis tick false', () => { imgSnapshotTest( @@ -265,7 +252,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis line false', () => { imgSnapshotTest( @@ -287,7 +273,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render all the theme color', () => { imgSnapshotTest( @@ -317,6 +302,17 @@ describe('XY Chart', () => { `, {} ); + }); + it('should use the correct distances between data points', () => { + imgSnapshotTest( + ` + xychart-beta + x-axis 0 --> 2 + line [0, 1, 0, 1] + bar [1, 0, 1, 0] + `, + {} + ); cy.get('svg'); }); }); diff --git a/cypress/platform/bundle-test.js b/cypress/platform/bundle-test.js index f5bf0ecd6..24ce8d753 100644 --- a/cypress/platform/bundle-test.js +++ b/cypress/platform/bundle-test.js @@ -27,7 +27,7 @@ const code3 = `flowchart TD A() B(Bold text!)`; -if (location.href.match('test-html-escaping')) { +if (/test-html-escaping/.exec(location.href)) { code = code3; } diff --git a/cypress/platform/viewer.js b/cypress/platform/viewer.js index 482a90646..c397f0e16 100644 --- a/cypress/platform/viewer.js +++ b/cypress/platform/viewer.js @@ -132,7 +132,7 @@ if (typeof document !== 'undefined') { window.addEventListener( 'load', function () { - if (this.location.href.match('xss.html')) { + if (/xss.html/.exec(this.location.href)) { this.console.log('Using api'); void contentLoadedApi().finally(markRendered); } else { diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index ef985866e..aa888465b 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -15,6 +15,7 @@ import '@cypress/code-coverage/support'; import '@applitools/eyes-cypress/commands'; +import '@argos-ci/cypress/support'; // Import commands.js using ES2015 syntax: import './commands'; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index baa9a7217..b01ce9bac 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es2020", "lib": ["es2020", "dom"], - "types": ["cypress", "node"], + "types": ["cypress", "node", "@argos-ci/cypress/dist/support.d.ts"], "allowImportingTsExtensions": true, "noEmit": true }, diff --git a/demos/sequence.html b/demos/sequence.html index abdc84f04..eca935ff5 100644 --- a/demos/sequence.html +++ b/demos/sequence.html @@ -238,6 +238,17 @@ Alice-xJohn: Hello John, how are you? John--xAlice: Great! + +
+ +
+    sequenceDiagram
+      participant Alice
+      participant Bob
+      Alice<<->>Bob: Hello!
+      Alice<<->>Bob: Wow, we said that at the same time!
+      Bob<<-->>Alice: Bidirectional Arrows are so cool
+