3.9 KB154 lines
Blame
1/* eslint-disable @typescript-eslint/no-explicit-any */
2import { Buffer } from 'buffer';
3import type { MermaidConfig } from '../../packages/mermaid/src/config.type.js';
4
5interface CypressConfig {
6 listUrl?: boolean;
7 listId?: string;
8 name?: string;
9 screenshot?: boolean;
10}
11type CypressMermaidConfig = MermaidConfig & CypressConfig;
12
13interface CodeObject {
14 code: string | string[];
15 mermaid: CypressMermaidConfig;
16}
17
18export const utf8ToB64 = (str: string): string => {
19 return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
20};
21
22const batchId: string =
23 'mermaid-batch-' +
24 (Cypress.env('useAppli')
25 ? Date.now().toString()
26 : (Cypress.env('CYPRESS_COMMIT') ?? Date.now().toString()));
27
28export const mermaidUrl = (
29 graphStr: string | string[],
30 options: CypressMermaidConfig,
31 api: boolean
32): string => {
33 options.handDrawnSeed = 1;
34 const codeObject: CodeObject = {
35 code: graphStr,
36 mermaid: options,
37 };
38 const objStr: string = JSON.stringify(codeObject);
39 let url = `/e2e.html?graph=${utf8ToB64(objStr)}`;
40 if (api && typeof graphStr === 'string') {
41 url = `/xss.html?graph=${graphStr}`;
42 }
43
44 if (options.listUrl) {
45 cy.log(options.listId, ' ', url);
46 }
47
48 return url;
49};
50
51export const imgSnapshotTest = (
52 graphStr: string,
53 _options: CypressMermaidConfig = {},
54 api = false,
55 validation?: any
56): void => {
57 const options: CypressMermaidConfig = {
58 ..._options,
59 fontFamily: _options.fontFamily ?? 'courier',
60 // @ts-ignore TODO: Fix type of fontSize
61 fontSize: _options.fontSize ?? '16px',
62 sequence: {
63 ...(_options.sequence ?? {}),
64 actorFontFamily: 'courier',
65 noteFontFamily: _options.sequence?.noteFontFamily ?? 'courier',
66 messageFontFamily: 'courier',
67 },
68 };
69
70 const url: string = mermaidUrl(graphStr, options, api);
71 openURLAndVerifyRendering(url, options, validation);
72};
73
74export const urlSnapshotTest = (
75 url: string,
76 options: CypressMermaidConfig = {},
77 _api = false,
78 validation?: any
79): void => {
80 openURLAndVerifyRendering(url, options, validation);
81};
82
83export const renderGraph = (
84 graphStr: string | string[],
85 options: CypressMermaidConfig = {},
86 api = false
87): void => {
88 const url: string = mermaidUrl(graphStr, options, api);
89 openURLAndVerifyRendering(url, options);
90};
91
92export const openURLAndVerifyRendering = (
93 url: string,
94 { screenshot = true, ...options }: CypressMermaidConfig,
95 validation?: any
96): void => {
97 const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
98
99 cy.visit(url);
100 cy.window().should('have.property', 'rendered', true);
101
102 // Handle sandbox mode where SVG is inside an iframe
103 if (options.securityLevel === 'sandbox') {
104 cy.get('iframe').should('be.visible');
105 if (validation) {
106 cy.get('iframe').should(validation);
107 }
108 } else {
109 cy.get('svg').should('be.visible');
110 // cspell:ignore viewbox
111 cy.get('svg').should('not.have.attr', 'viewbox');
112
113 if (validation) {
114 cy.get('svg').should(validation);
115 }
116 }
117
118 if (screenshot) {
119 verifyScreenshot(name);
120 }
121};
122
123export const verifyScreenshot = (name: string): void => {
124 const useAppli: boolean = Cypress.env('useAppli');
125 const useArgos: boolean = Cypress.env('useArgos');
126
127 if (useAppli) {
128 cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`);
129 cy.eyesOpen({
130 appName: 'Mermaid',
131 testName: name,
132 batchName: Cypress.spec.name,
133 batchId: batchId + Cypress.spec.name,
134 });
135 cy.log(`Check eyes ${Cypress.spec.name}`);
136 cy.eyesCheckWindow('Click!');
137 cy.log(`Closing eyes ${Cypress.spec.name}`);
138 cy.eyesClose();
139 } else if (useArgos) {
140 cy.argosScreenshot(name, {
141 threshold: 0.01,
142 });
143 } else {
144 cy.matchImageSnapshot(name);
145 }
146};
147
148export const verifyNumber = (value: number, expected: number, deltaPercent = 10): void => {
149 expect(value).to.be.within(
150 expected * (1 - deltaPercent / 100),
151 expected * (1 + deltaPercent / 100)
152 );
153};
154