33.8 KB1048 lines
Blame
1import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
2
3describe('Flowchart HandDrawn', () => {
4 it('FHD1: should render a simple flowchart no htmlLabels', () => {
5 imgSnapshotTest(
6 `graph TD
7 A[Christmas] -->|Get money| B(Go shopping)
8 B --> C{Let me think}
9 C -->|One| D[Laptop]
10 C -->|Two| E[iPhone]
11 C -->|Three| F[fa:fa-car Car]
12 `,
13 {
14 look: 'handDrawn',
15 flowchart: { htmlLabels: false },
16 fontFamily: 'courier',
17 }
18 );
19 });
20
21 it('FHD2: should render a simple flowchart with htmlLabels', () => {
22 imgSnapshotTest(
23 `graph TD
24 A[Christmas] -->|Get money| B(Go shopping)
25 B --> C{Let me think}
26 C -->|One| D[Laptop]
27 C -->|Two| E[iPhone]
28 C -->|Three| F[fa:fa-car Car]
29 `,
30 {
31 look: 'handDrawn',
32 flowchart: { htmlLabels: true },
33 fontFamily: 'courier',
34 }
35 );
36 });
37
38 it('FHD3: should render a simple flowchart with line breaks', () => {
39 imgSnapshotTest(
40 `
41 graph TD
42 A[Christmas] -->|Get money| B(Go shopping)
43 B --> C{Let me thinksssss<br/>ssssssssssssssssssssss<br/>sssssssssssssssssssssssssss}
44 C -->|One| D[Laptop]
45 C -->|Two| E[iPhone]
46 C -->|Three| F[Car]
47 `,
48 { look: 'handDrawn', fontFamily: 'courier' }
49 );
50 });
51
52 it('FHD4: should render a simple flowchart with trapezoid and inverse trapezoid vertex options.', () => {
53 imgSnapshotTest(
54 `
55 graph TD
56 A[/Christmas\\]
57 A -->|Get money| B[\\Go shopping/]
58 B --> C{Let me thinksssss<br/>ssssssssssssssssssssss<br/>sssssssssssssssssssssssssss}
59 C -->|One| D[/Laptop/]
60 C -->|Two| E[\\iPhone\\]
61 C -->|Three| F[Car]
62 `,
63 { look: 'handDrawn', fontFamily: 'courier' }
64 );
65 });
66
67 it('FHD5: should style nodes via a class.', () => {
68 imgSnapshotTest(
69 `
70 graph TD
71 1A --> 1B
72 1B --> 1C
73 1C --> D
74 1C --> E
75
76 classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
77 class 1A,1B,D,E processHead
78 `,
79 { look: 'handDrawn', fontFamily: 'courier' }
80 );
81 });
82
83 it('FHD6: should render a flowchart full of circles', () => {
84 imgSnapshotTest(
85 `
86 graph LR
87 47(SAM.CommonFA.FMESummary)-->48(SAM.CommonFA.CommonFAFinanceBudget)
88 37(SAM.CommonFA.BudgetSubserviceLineVolume)-->48(SAM.CommonFA.CommonFAFinanceBudget)
89 35(SAM.CommonFA.PopulationFME)-->47(SAM.CommonFA.FMESummary)
90 41(SAM.CommonFA.MetricCost)-->47(SAM.CommonFA.FMESummary)
91 44(SAM.CommonFA.MetricOutliers)-->47(SAM.CommonFA.FMESummary)
92 46(SAM.CommonFA.MetricOpportunity)-->47(SAM.CommonFA.FMESummary)
93 40(SAM.CommonFA.OPVisits)-->47(SAM.CommonFA.FMESummary)
94 38(SAM.CommonFA.CommonFAFinanceRefund)-->47(SAM.CommonFA.FMESummary)
95 43(SAM.CommonFA.CommonFAFinancePicuDays)-->47(SAM.CommonFA.FMESummary)
96 42(SAM.CommonFA.CommonFAFinanceNurseryDays)-->47(SAM.CommonFA.FMESummary)
97 45(SAM.CommonFA.MetricPreOpportunity)-->46(SAM.CommonFA.MetricOpportunity)
98 35(SAM.CommonFA.PopulationFME)-->45(SAM.CommonFA.MetricPreOpportunity)
99 41(SAM.CommonFA.MetricCost)-->45(SAM.CommonFA.MetricPreOpportunity)
100 41(SAM.CommonFA.MetricCost)-->44(SAM.CommonFA.MetricOutliers)
101 39(SAM.CommonFA.ChargeDetails)-->43(SAM.CommonFA.CommonFAFinancePicuDays)
102 39(SAM.CommonFA.ChargeDetails)-->42(SAM.CommonFA.CommonFAFinanceNurseryDays)
103 39(SAM.CommonFA.ChargeDetails)-->41(SAM.CommonFA.MetricCost)
104 39(SAM.CommonFA.ChargeDetails)-->40(SAM.CommonFA.OPVisits)
105 35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
106 36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
107 `,
108 { look: 'handDrawn', fontFamily: 'courier' }
109 );
110 });
111
112 it('FHD7: should render a flowchart full of icons', () => {
113 imgSnapshotTest(
114 `
115 graph TD
116 9e122290_1ec3_e711_8c5a_005056ad0002("fa:fa-creative-commons My System | Test Environment")
117 82072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 1")
118 db052290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 2")
119 4e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 1")
120 30122290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 2")
121 5e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 1")
122 c1112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 2")
123 b7042290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[SupportDb]")
124 8f102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[DevelopmentDb]")
125 0e102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[TestDb]")
126 07132290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[SharedReportingDb]")
127 c7072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Business Logic Server")
128 ca122290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Report Server")
129 68102290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Dedicated Test Business Logic Server")
130 f4112290_1ec3_e711_8c5a_005056ad0002("fa:fa-database [DBServer\\SharedDbInstance]")
131 d6072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server DBServer")
132 71082290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\\:MSSQLSERVER")
133 c0102290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\\:SQLAgent")
134 9a072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\\:SQLBrowser")
135 1d0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost1")
136 200a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost2")
137 1c0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost3")
138 9e122290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
139 9e122290_1ec3_e711_8c5a_005056ad0002-->db052290_1ec3_e711_8c5a_005056ad0002
140 9e122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
141 9e122290_1ec3_e711_8c5a_005056ad0002-->30122290_1ec3_e711_8c5a_005056ad0002
142 9e122290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
143 9e122290_1ec3_e711_8c5a_005056ad0002-->c1112290_1ec3_e711_8c5a_005056ad0002
144 82072290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
145 82072290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
146 82072290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
147 82072290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
148 db052290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
149 db052290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
150 4e112290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
151 4e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
152 4e112290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
153 4e112290_1ec3_e711_8c5a_005056ad0002-->07132290_1ec3_e711_8c5a_005056ad0002
154 4e112290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
155 30122290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
156 30122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
157 5e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
158 5e112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
159 c1112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
160 c1112290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
161 b7042290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
162 8f102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
163 0e102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
164 07132290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
165 c7072290_1ec3_e711_8c5a_005056ad0002-->1d0a2290_1ec3_e711_8c5a_005056ad0002
166 ca122290_1ec3_e711_8c5a_005056ad0002-->200a2290_1ec3_e711_8c5a_005056ad0002
167 68102290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
168 f4112290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
169 f4112290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
170 f4112290_1ec3_e711_8c5a_005056ad0002-->c0102290_1ec3_e711_8c5a_005056ad0002
171 f4112290_1ec3_e711_8c5a_005056ad0002-->9a072290_1ec3_e711_8c5a_005056ad0002
172 d6072290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
173 71082290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
174 c0102290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
175 c0102290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
176 9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
177 9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
178 `,
179 { look: 'handDrawn', fontFamily: 'courier' }
180 );
181 });
182
183 it('FHD8: should render labels with numbers at the start', () => {
184 imgSnapshotTest(
185 `
186 graph TB;subgraph "number as labels";1;end;
187 `,
188 { look: 'handDrawn', fontFamily: 'courier' }
189 );
190 });
191
192 it('FHD9: should render subgraphs', () => {
193 imgSnapshotTest(
194 `
195 graph TB
196 subgraph One
197 a1-->a2
198 end
199 `,
200 { look: 'handDrawn', fontFamily: 'courier' }
201 );
202 });
203
204 it('FHD10: should render subgraphs with a title starting with a digit', () => {
205 imgSnapshotTest(
206 `
207 graph TB
208 subgraph 2Two
209 a1-->a2
210 end
211 `,
212 { look: 'handDrawn', fontFamily: 'courier' }
213 );
214 });
215
216 it('FHD11: should render styled subgraphs', () => {
217 imgSnapshotTest(
218 `
219 graph TB
220 A
221 B
222 subgraph foo[Foo SubGraph]
223 C
224 D
225 end
226 subgraph bar[Bar SubGraph]
227 E
228 F
229 end
230 G
231
232 A-->B
233 B-->C
234 C-->D
235 B-->D
236 D-->E
237 E-->A
238 E-->F
239 F-->D
240 F-->G
241 B-->G
242 G-->D
243
244 style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
245 style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
246 `,
247 { look: 'handDrawn', fontFamily: 'courier' }
248 );
249 });
250
251 it('FHD12: should render a flowchart with long names and class definitions', () => {
252 imgSnapshotTest(
253 `graph LR
254 sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
255
256 提交申请
257 熊大
258 "];
259 class sid-B3655226-6C29-4D00-B685-3D5C734DC7E1 node-executed;
260 sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A["
261 负责人审批
262 强子
263 "];
264 class sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A node-executed;
265 sid-E27C0367-E6D6-497F-9736-3CDC21FDE221["
266 DBA审批
267 强子
268 "];
269 class sid-E27C0367-E6D6-497F-9736-3CDC21FDE221 node-executed;
270 sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD["
271 SA审批
272 阿美
273 "];
274 class sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD node-executed;
275 sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7["
276 主管审批
277 光头强
278 "];
279 class sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7 node-executed;
280 sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89["
281 DBA确认
282 强子
283 "];
284 class sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89 node-executed;
285 sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937["
286 SA确认
287 阿美
288 "];
289 class sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937 node-executed;
290 sid-4FC27B48-A6F9-460A-A675-021F5854FE22["
291 结束
292 "];
293 class sid-4FC27B48-A6F9-460A-A675-021F5854FE22 node-executed;
294 sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E["
295 SA执行1
296 强子
297 "];
298 class sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E node-executed;
299 sid-6C2120F3-D940-4958-A067-0903DCE879C4["
300 SA执行2
301 强子
302 "];
303 class sid-6C2120F3-D940-4958-A067-0903DCE879C4 node-executed;
304 sid-9180E2A0-5C4B-435F-B42F-0D152470A338["
305 DBA执行1
306 强子
307 "];
308 class sid-9180E2A0-5C4B-435F-B42F-0D152470A338 node-executed;
309 sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD["
310 DBA执行3
311 强子
312 "];
313 class sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD node-executed;
314 sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756["
315 DBA执行2
316 强子
317 "];
318 class sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756 node-executed;
319 sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93["
320 DBA执行4
321 强子
322 "];
323 class sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93 node-executed;
324 sid-1897B30A-9C5C-4D5B-B80B-76A038785070["
325 负责人确认
326 梁静茹
327 "];
328 class sid-1897B30A-9C5C-4D5B-B80B-76A038785070 node-executed;
329 sid-B3655226-6C29-4D00-B685-3D5C734DC7E1-->sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7;
330 sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A-->sid-1897B30A-9C5C-4D5B-B80B-76A038785070;
331 sid-E27C0367-E6D6-497F-9736-3CDC21FDE221-->sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89;
332 sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD-->sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937;
333 sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
334 sid-9180E2A0-5C4B-435F-B42F-0D152470A338-->sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756;
335 sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD-->sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93;
336 sid-6C2120F3-D940-4958-A067-0903DCE879C4-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
337 sid-1897B30A-9C5C-4D5B-B80B-76A038785070-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
338 sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E;
339 sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-9180E2A0-5C4B-435F-B42F-0D152470A338;
340 sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD;
341 sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
342 sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
343 sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD;
344 sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-E27C0367-E6D6-497F-9736-3CDC21FDE221;
345 sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
346 sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
347 sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
348 `,
349 { look: 'handDrawn', fontFamily: 'courier' }
350 );
351 });
352
353 it('FHD13: should render color of styled nodes', () => {
354 imgSnapshotTest(
355 `
356 graph LR
357 foo-->bar
358
359 classDef foo fill:lightblue,color:green,stroke:#FF9E2C,font-weight:bold
360 style foo fill:#F99,stroke-width:2px,stroke:#F0F
361 style bar fill:#999,color: #00ff00, stroke-width:10px,stroke:#0F0
362 `,
363 {
364 look: 'handDrawn',
365 listUrl: false,
366 listId: 'color styling',
367 fontFamily: 'courier',
368 logLevel: 0,
369 }
370 );
371 });
372
373 it('FHD14: should render hexagons', () => {
374 imgSnapshotTest(
375 `
376 graph TD
377 A[Christmas] -->|Get money| B(Go shopping)
378 B --> C{{Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?}}
379 C -->|One| D[Laptop]
380 C -->|Two| E[iPhone]
381 C -->|Three| F[Car]
382 click A "index.html#link-clicked" "link test"
383 click B testClick "click test"
384 classDef someclass fill:#f96;
385 class A someclass;
386 class C someclass;
387 `,
388 {
389 look: 'handDrawn',
390 listUrl: false,
391 listId: 'color styling',
392 fontFamily: 'courier',
393 logLevel: 0,
394 }
395 );
396 });
397
398 it('FHD15: should render a simple flowchart with comments', () => {
399 imgSnapshotTest(
400 `graph TD
401 A[Christmas] -->|Get money| B(Go shopping)
402 B --> C{Let me think}
403 %% this is a comment
404 C -->|One| D[Laptop]
405 C -->|Two| E[iPhone]
406 C -->|Three| F[fa:fa-car Car]
407 `,
408 {
409 look: 'handDrawn',
410 flowchart: { htmlLabels: false },
411 fontFamily: 'courier',
412 }
413 );
414 });
415
416 it('FHD16: Render Stadium shape', () => {
417 imgSnapshotTest(
418 ` graph TD
419 A([stadium shape test])
420 A -->|Get money| B([Go shopping])
421 B --> C([Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?])
422 C -->|One| D([Laptop])
423 C -->|Two| E([iPhone])
424 C -->|Three| F([Car<br/>wroom wroom])
425 click A "index.html#link-clicked" "link test"
426 click B testClick "click test"
427 classDef someclass fill:#f96;
428 class A someclass;
429 class C someclass;
430 `,
431 {
432 look: 'handDrawn',
433 flowchart: { htmlLabels: false },
434 fontFamily: 'courier',
435 }
436 );
437 });
438
439 it('FHD17: Render multiline texts', () => {
440 imgSnapshotTest(
441 `graph LR
442 A1[Multi<br>Line] -->|Multi<br>Line| B1(Multi<br>Line)
443 C1[Multi<br/>Line] -->|Multi<br/>Line| D1(Multi<br/>Line)
444 E1[Multi<br />Line] -->|Multi<br />Line| F1(Multi<br />Line)
445 A2[Multi<br>Line] -->|Multi<br>Line| B2(Multi<br>Line)
446 C2[Multi<br/>Line] -->|Multi<br/>Line| D2(Multi<br/>Line)
447 E2[Multi<br />Line] -->|Multi<br />Line| F2(Multi<br />Line)
448 linkStyle 0 stroke:DarkGray,stroke-width:2px
449 linkStyle 1 stroke:DarkGray,stroke-width:2px
450 linkStyle 2 stroke:DarkGray,stroke-width:2px
451 `,
452 {
453 look: 'handDrawn',
454 flowchart: { htmlLabels: false },
455 fontFamily: 'courier',
456 }
457 );
458 });
459
460 it('FHD18: Chaining of nodes', () => {
461 imgSnapshotTest(
462 `graph LR
463 a --> b --> c
464 `,
465 {
466 look: 'handDrawn',
467 flowchart: { htmlLabels: false },
468 fontFamily: 'courier',
469 }
470 );
471 });
472
473 it('FHD19: Multiple nodes and chaining in one statement', () => {
474 imgSnapshotTest(
475 `graph LR
476 a --> b & c--> d
477 `,
478 {
479 look: 'handDrawn',
480 flowchart: { htmlLabels: false },
481 fontFamily: 'courier',
482 }
483 );
484 });
485
486 it('FHD20: Multiple nodes and chaining in one statement', () => {
487 imgSnapshotTest(
488 `graph TD
489 A[ h ] -- hello --> B[" test "]:::exClass & C --> D;
490 classDef exClass background:#bbb,border:1px solid red;
491 `,
492 {
493 look: 'handDrawn',
494 flowchart: { htmlLabels: false },
495 fontFamily: 'courier',
496 }
497 );
498 });
499
500 it('FDH21: Render cylindrical shape', () => {
501 imgSnapshotTest(
502 `graph LR
503 A[(cylindrical<br />shape<br />test)]
504 A -->|Get money| B1[(Go shopping 1)]
505 A -->|Get money| B2[(Go shopping 2)]
506 A -->|Get money| B3[(Go shopping 3)]
507 C[(Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?)]
508 B1 --> C
509 B2 --> C
510 B3 --> C
511 C -->|One| D[(Laptop)]
512 C -->|Two| E[(iPhone)]
513 C -->|Three| F[(Car)]
514 click A "index.html#link-clicked" "link test"
515 click B testClick "click test"
516 classDef someclass fill:#f96;
517 class A someclass;`,
518 {
519 look: 'handDrawn',
520 flowchart: { htmlLabels: false },
521 fontFamily: 'courier',
522 }
523 );
524 });
525
526 it('FDH22: Render a simple flowchart with nodeSpacing set to 100', () => {
527 imgSnapshotTest(
528 `graph TD
529 A[Christmas] -->|Get money| B(Go shopping)
530 B --> C{Let me think}
531 %% this is a comment
532 C -->|One| D[Laptop]
533 C -->|Two| E[iPhone]
534 C -->|Three| F[fa:fa-car Car]
535 `,
536 { look: 'handDrawn', flowchart: { nodeSpacing: 50 }, fontFamily: 'courier' }
537 );
538 });
539
540 it('FDH23: Render a simple flowchart with rankSpacing set to 100', () => {
541 imgSnapshotTest(
542 `graph TD
543 A[Christmas] -->|Get money| B(Go shopping)
544 B --> C{Let me think}
545 %% this is a comment
546 C -->|One| D[Laptop]
547 C -->|Two| E[iPhone]
548 C -->|Three| F[fa:fa-car Car]
549 `,
550 {
551 look: 'handDrawn',
552 flowchart: { rankSpacing: '100' },
553 fontFamily: 'courier',
554 }
555 );
556 });
557
558 it('FDH24: Keep node label text (if already defined) when a style is applied', () => {
559 imgSnapshotTest(
560 `graph LR
561 A(( )) -->|step 1| B(( ))
562 B(( )) -->|step 2| C(( ))
563 C(( )) -->|step 3| D(( ))
564 linkStyle 1 stroke:greenyellow,stroke-width:2px
565 style C fill:greenyellow,stroke:green,stroke-width:4px
566 `,
567 {
568 look: 'handDrawn',
569 flowchart: { htmlLabels: false },
570 fontFamily: 'courier',
571 }
572 );
573 });
574
575 it('FDH25: Handle link click events (link, anchor, mailto, other protocol, script)', () => {
576 imgSnapshotTest(
577 `graph TB
578 TITLE["Link Click Events<br>(click the nodes below)"]
579 A["link test (open in same tab)"]
580 B["link test (open in new tab)"]
581 C[anchor test]
582 D[mailto test]
583 E[other protocol test]
584 F[script test]
585 TITLE --> A & B & C & D & E & F
586 click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
587 click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
588 click C "#link-clicked"
589 click D "mailto:user@user.user" "mailto test"
590 click E "notes://do-your-thing/id" "other protocol test"
591 click F "javascript:alert('test')" "script test"
592 `,
593 { look: 'handDrawn', securityLevel: 'loose', fontFamily: 'courier' }
594 );
595 });
596
597 it('FDH26: Set text color of nodes and links according to styles when html labels are enabled', () => {
598 imgSnapshotTest(
599 `graph LR
600 A[red<br>text] -->|red<br>text| B(blue<br>text)
601 C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
602 E{{default<br />style}} -->|default<br />style| F([default<br />style])
603 linkStyle default color:Sienna;
604 linkStyle 0 color:red;
605 linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
606 style A color:red;
607 style B color:blue;
608 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
609 style D stroke:#0000ff,fill:#ccccff,color:#0000ff
610 click B "index.html#link-clicked" "link test"
611 click D testClick "click test"
612 `,
613 { look: 'handDrawn', flowchart: { htmlLabels: true } }
614 );
615 });
616
617 it('FDH27: Set text color of nodes and links according to styles when html labels are disabled', () => {
618 imgSnapshotTest(
619 `graph LR
620 A[red<br>text] -->|red<br>text| B(blue<br>text)
621 C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
622 E{{default<br />style}} -->|default<br />style| F([default<br />style])
623 linkStyle default color:Sienna;
624 linkStyle 0 color:red;
625 linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
626 style A color:red;
627 style B color:blue;
628 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
629 style D stroke:#0000ff,fill:#ccccff,color:#0000ff
630 click B "index.html#link-clicked" "link test"
631 click D testClick "click test"
632 `,
633 {
634 look: 'handDrawn',
635 flowchart: { htmlLabels: false },
636 fontFamily: 'courier',
637 }
638 );
639 });
640
641 it('FDH28: Apply default class to all nodes which do not have another class assigned (htmlLabels enabled)', () => {
642 imgSnapshotTest(
643 `graph TD
644 A[myClass1] --> B[default] & C[default]
645 B[default] & C[default] --> D[myClass2]
646 classDef default stroke-width:2px,fill:none,stroke:silver
647 classDef node color:red
648 classDef myClass1 color:#0000ff
649 classDef myClass2 stroke:#0000ff,fill:#ccccff
650 class A myClass1
651 class D myClass2
652 `,
653 { look: 'handDrawn', flowchart: { htmlLabels: true } }
654 );
655 });
656
657 it('FDH29: Apply default class to all nodes which do not have another class assigned (htmlLabels disabled)', () => {
658 imgSnapshotTest(
659 `graph TD
660 A[myClass1] --> B[default] & C[default]
661 B[default] & C[default] --> D[myClass2]
662 classDef default stroke-width:2px,fill:none,stroke:silver
663 classDef node color:red
664 classDef myClass1 color:#0000ff
665 classDef myClass2 stroke:#0000ff,fill:#ccccff
666 class A myClass1
667 class D myClass2
668 `,
669 {
670 look: 'handDrawn',
671 flowchart: { htmlLabels: false },
672 fontFamily: 'courier',
673 }
674 );
675 });
676
677 it('FDH30: Possibility to style text color of nodes and subgraphs as well as apply classes to subgraphs', () => {
678 imgSnapshotTest(
679 `graph LR
680 subgraph id1 [title is set]
681 A-->B
682 end
683 subgraph id2 [title]
684 E
685 end
686
687 B-->C
688
689 subgraph id3
690 C-->D
691 end
692 class id3,id2,A redBg;
693 class id3,A whiteTxt;
694 classDef redBg fill:#622;
695 classDef whiteTxt color: white;
696 `,
697 {
698 look: 'handDrawn',
699 flowchart: { htmlLabels: false },
700 fontFamily: 'courier',
701 }
702 );
703 });
704
705 it('FDH31: should not slice off edges that are to the left of the left-most vertex', () => {
706 imgSnapshotTest(
707 `graph TD
708 work --> sleep
709 sleep --> work
710 eat --> sleep
711 work --> eat
712 `,
713 {
714 look: 'handDrawn',
715 flowchart: { htmlLabels: false },
716 fontFamily: 'courier',
717 }
718 );
719 });
720
721 it('FDH32: Render Subroutine shape', () => {
722 imgSnapshotTest(
723 `graph LR
724 A[[subroutine shape test]]
725 A -->|Get money| B[[Go shopping]]
726 B --> C[[Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?]]
727 C -->|One| D[[Laptop]]
728 C -->|Two| E[[iPhone]]
729 C -->|Three| F[[Car<br/>wroom wroom]]
730 click A "index.html#link-clicked" "link test"
731 click B testClick "click test"
732 classDef someclass fill:#f96;
733 class A someclass;
734 class C someclass;
735 `,
736 {
737 look: 'handDrawn',
738 flowchart: { htmlLabels: false },
739 fontFamily: 'courier',
740 }
741 );
742 });
743
744 it('FDH33: should render a simple flowchart with diagramPadding set to 0', () => {
745 imgSnapshotTest(
746 `graph TD
747 A[Christmas] -->|Get money| B(Go shopping)
748 B --> C{Let me think}
749 %% this is a comment
750 C -->|One| D[Laptop]
751 C -->|Two| E[iPhone]
752 C -->|Three| F[fa:fa-car Car]
753 `,
754 { look: 'handDrawn', flowchart: { diagramPadding: 0 } }
755 );
756 });
757
758 it('FDH34: testing the label width in percy', () => {
759 imgSnapshotTest(
760 `graph TD
761 A[Christmas]
762 `,
763 { look: 'handDrawn', handDrawnSeed: 1 }
764 );
765 });
766
767 it('FDH35: should honor minimum edge length as specified by the user', () => {
768 imgSnapshotTest(
769 `graph TD
770 L1 --- L2
771 L2 --- C
772 M1 ---> C
773 R1 .-> R2
774 R2 <.-> C
775 C -->|Label 1| E1
776 C -- Label 2 ---> E2
777 C ----> E3
778 C -----> E4
779 C ======> E5
780 `,
781 { look: 'handDrawn', handDrawnSeed: 1 }
782 );
783 });
784 it('FDH36: should render escaped without html labels', () => {
785 imgSnapshotTest(
786 `graph TD
787 a["<strong>Haiya</strong>"]-->b
788 `,
789 { look: 'handDrawn', htmlLabels: false, flowchart: { htmlLabels: false } }
790 );
791 });
792 it('FDH37: should render non-escaped with html labels', () => {
793 imgSnapshotTest(
794 `graph TD
795 a["<strong>Haiya</strong>"]-->b
796 `,
797 {
798 look: 'handDrawn',
799 htmlLabels: true,
800 flowchart: { htmlLabels: true },
801 securityLevel: 'loose',
802 }
803 );
804 });
805 it('FDH38: should render a flowchart when useMaxWidth is true (default)', () => {
806 renderGraph(
807 `flowchart TD
808 A[Christmas] -->|Get money| B(Go shopping)
809 B --> C{Let me think}
810 C -->|One| D[Laptop]
811 C -->|Two| E[iPhone]
812 C -->|Three| F[fa:fa-car Car]
813 `,
814 { look: 'handDrawn', flowchart: { useMaxWidth: true } }
815 );
816 cy.get('svg').should((svg) => {
817 expect(svg).to.have.attr('width', '100%');
818 // expect(svg).to.have.attr('height');
819 // use within because the absolute value can be slightly different depending on the environment ±10%
820 // const height = parseFloat(svg.attr('height'));
821 // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
822 const style = svg.attr('style');
823 expect(style).to.match(/^max-width: [\d.]+px;$/);
824 const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
825 expect(maxWidthValue).to.be.within(446 * 0.9, 446 * 1.1);
826 });
827 });
828 it('FDH39: should render a flowchart when useMaxWidth is false', () => {
829 renderGraph(
830 `graph TD
831 A[Christmas] -->|Get money| B(Go shopping)
832 B --> C{Let me think}
833 C -->|One| D[Laptop]
834 C -->|Two| E[iPhone]
835 C -->|Three| F[fa:fa-car Car]
836 `,
837 { look: 'handDrawn', flowchart: { useMaxWidth: false } }
838 );
839 cy.get('svg').should((svg) => {
840 // const height = parseFloat(svg.attr('height'));
841 const width = parseFloat(svg.attr('width'));
842 // use within because the absolute value can be slightly different depending on the environment ±10%
843 // expect(height).to.be.within(446 * 0.95, 446 * 1.05);
844 expect(width).to.be.within(446 * 0.9, 446 * 1.1);
845 expect(svg).to.not.have.attr('style');
846 });
847 });
848 it('FDH40: handle styling with style expressions', () => {
849 imgSnapshotTest(
850 `
851 graph LR
852 id1(Start)-->id2(Stop)
853 style id1 fill:#f9f,stroke:#333,stroke-width:4px
854 style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
855 `,
856 {
857 look: 'handDrawn',
858 htmlLabels: true,
859 flowchart: { htmlLabels: true },
860 securityLevel: 'loose',
861 }
862 );
863 });
864 it('FDH41: handle styling for all node shapes', () => {
865 imgSnapshotTest(
866 `
867 graph LR
868 A[red text] -->|default style| B(blue text)
869 C([red text]) -->|default style| D[[blue text]]
870 E[(red text)] -->|default style| F((blue text))
871 G>red text] -->|default style| H{blue text}
872 I{{red text}} -->|default style| J[/blue text/]
873 linkStyle default color:Sienna;
874 style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
875 style B stroke:#0000ff,fill:#ccccff,color:#0000ff
876 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
877 style D stroke:#0000ff,fill:#ccccff,color:#0000ff
878 style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
879 style F stroke:#0000ff,fill:#ccccff,color:#0000ff
880 style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
881 style H stroke:#0000ff,fill:#ccccff,color:#0000ff
882 style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
883 style J stroke:#0000ff,fill:#ccccff,color:#0000ff
884 `,
885 {
886 look: 'handDrawn',
887 htmlLabels: true,
888 flowchart: { htmlLabels: true },
889 securityLevel: 'loose',
890 }
891 );
892 });
893 it('FDH42: fontawesome icons in edge labels', () => {
894 imgSnapshotTest(
895 `
896graph TD
897 C -->|fa:fa-car Car| F[fa:fa-car Car]
898 `,
899 {
900 look: 'handDrawn',
901 htmlLabels: true,
902 flowchart: { htmlLabels: true },
903 securityLevel: 'loose',
904 }
905 );
906 });
907 it('FDH43: fontawesome icons in edge labels', () => {
908 imgSnapshotTest(
909 `
910 graph TB
911 subgraph bar[Bar]
912 F
913 end
914 style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
915 `,
916 {
917 look: 'handDrawn',
918 htmlLabels: true,
919 flowchart: { htmlLabels: true },
920 securityLevel: 'loose',
921 }
922 );
923 });
924 it('FDH44: fontawesome icons in edge labels', () => {
925 imgSnapshotTest(
926 `
927 graph TB
928 A
929 B
930 subgraph foo[Foo SubGraph]
931 C
932 D
933 end
934 subgraph bar[Bar SubGraph]
935 E
936 F
937 end
938 G
939
940 A-->B
941 B-->C
942 C-->D
943 B-->D
944 D-->E
945 E-->A
946 E-->F
947 F-->D
948 F-->G
949 B-->G
950 G-->D
951
952 style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
953 style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
954 `,
955 {
956 look: 'handDrawn',
957 htmlLabels: true,
958 flowchart: { htmlLabels: true },
959 securityLevel: 'loose',
960 }
961 );
962 });
963 it('FDH45: fontawesome icons in edge labels', () => {
964 imgSnapshotTest(
965 `
966 %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
967 flowchart LR
968 subgraph A
969 a --> b
970 end
971 subgraph B
972 i -->f
973 end
974 A --> B
975 `,
976 {
977 look: 'handDrawn',
978 htmlLabels: true,
979 flowchart: { htmlLabels: true },
980 securityLevel: 'loose',
981 }
982 );
983 });
984 it('FDH46: text-color from classes', () => {
985 imgSnapshotTest(
986 `
987 flowchart LR
988 classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
989 Lorem --> Ipsum --> Dolor
990 class Lorem,Dolor dark
991 `,
992 {
993 look: 'handDrawn',
994 htmlLabels: true,
995 flowchart: { htmlLabels: true },
996 securityLevel: 'loose',
997 }
998 );
999 });
1000 it('FDH47: apply class called default on node called default', () => {
1001 imgSnapshotTest(
1002 `
1003 graph TD
1004 classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff
1005 hello --> default
1006 `,
1007 {
1008 look: 'handDrawn',
1009 htmlLabels: true,
1010 flowchart: { htmlLabels: true },
1011 securityLevel: 'loose',
1012 }
1013 );
1014 });
1015
1016 it('FDH48: should be able to style default node independently', () => {
1017 imgSnapshotTest(
1018 `
1019 flowchart TD
1020 classDef default fill:#a34
1021 hello --> default
1022
1023 style default stroke:#000,stroke-width:4px
1024 `,
1025 {
1026 look: 'handDrawn',
1027 flowchart: { htmlLabels: true },
1028 securityLevel: 'loose',
1029 }
1030 );
1031 });
1032
1033 it('FDH49: should add edge animation', () => {
1034 renderGraph(
1035 `
1036 flowchart TD
1037 A(["Start"]) L_A_B_0@--> B{"Decision"}
1038 B --> C["Option A"] & D["Option B"]
1039 style C stroke-width:4px,stroke-dasharray: 5
1040 L_A_B_0@{ animation: slow }
1041 L_B_D_0@{ animation: fast }`,
1042 { look: 'handDrawn', screenshot: false }
1043 );
1044 cy.get('path#L_A_B_0').should('have.class', 'edge-animation-slow');
1045 cy.get('path#L_B_D_0').should('have.class', 'edge-animation-fast');
1046 });
1047});
1048