mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-27 11:19:38 +02:00
Compare commits
1685 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d12b197ec9 | ||
![]() |
f685363574 | ||
![]() |
7313b4b649 | ||
![]() |
8e72ddde32 | ||
![]() |
07a7ea1f23 | ||
![]() |
a1d2208bf3 | ||
![]() |
b6b76eb137 | ||
![]() |
19b16fe796 | ||
![]() |
14388f4bb1 | ||
![]() |
369e6d1e61 | ||
![]() |
789200d454 | ||
![]() |
dcfab0f4dd | ||
![]() |
9677ed9e2d | ||
![]() |
a4ece6c1c5 | ||
![]() |
e34396015f | ||
![]() |
64e3310376 | ||
![]() |
cd23899e02 | ||
![]() |
5a9fa66b04 | ||
![]() |
1866244a2a | ||
![]() |
5d4583c77f | ||
![]() |
66ee81c55f | ||
![]() |
9a2321a669 | ||
![]() |
1878e39dfc | ||
![]() |
2b9960e05f | ||
![]() |
c2e34cd0f5 | ||
![]() |
78bb5e09e5 | ||
![]() |
e8c7ffa872 | ||
![]() |
557a3f0896 | ||
![]() |
b2af5390fb | ||
![]() |
eb6c901527 | ||
![]() |
d5a9cbe5a3 | ||
![]() |
0658581bcd | ||
![]() |
26c3f5a2cc | ||
![]() |
34a60d7661 | ||
![]() |
ea0cd80ea7 | ||
![]() |
11d35c8410 | ||
![]() |
38359e176f | ||
![]() |
e54d9cf629 | ||
![]() |
deccf8891d | ||
![]() |
e5ac551795 | ||
![]() |
7684f79e64 | ||
![]() |
9fdab327c8 | ||
![]() |
1908af6f54 | ||
![]() |
a677608f1d | ||
![]() |
93d462e028 | ||
![]() |
661553da68 | ||
![]() |
b4203992bf | ||
![]() |
686ee1e349 | ||
![]() |
9e8c9e897f | ||
![]() |
06ceb5e68d | ||
![]() |
e363a21619 | ||
![]() |
09efbaf621 | ||
![]() |
31027047e3 | ||
![]() |
629eb4ca90 | ||
![]() |
c4e6e5eca4 | ||
![]() |
ea72d41e6d | ||
![]() |
c0f5b04472 | ||
![]() |
532b32dab5 | ||
![]() |
fb5c96731a | ||
![]() |
3f8eb8cb6b | ||
![]() |
89dc64ab66 | ||
![]() |
6968cff2b6 | ||
![]() |
c390e9e877 | ||
![]() |
dee47ec978 | ||
![]() |
5242672efb | ||
![]() |
5c043dd908 | ||
![]() |
19ed03c44c | ||
![]() |
32b2ee8cab | ||
![]() |
7e9ab546eb | ||
![]() |
2af1f9a9d3 | ||
![]() |
b6d6d3c980 | ||
![]() |
c655cfaca8 | ||
![]() |
b3a465dbca | ||
![]() |
33d3bc53b4 | ||
![]() |
be9da3928b | ||
![]() |
a9fd557c4e | ||
![]() |
faac22f6ed | ||
![]() |
35a47093ab | ||
![]() |
01a2d90e38 | ||
![]() |
1cc2e74a03 | ||
![]() |
ca86ab71f2 | ||
![]() |
ee425d278c | ||
![]() |
1c3c2b6a74 | ||
![]() |
9952f7734a | ||
![]() |
2ffb2988bf | ||
![]() |
fda1d7c4c5 | ||
![]() |
19519ac74e | ||
![]() |
eb3f62fd90 | ||
![]() |
891b362e7d | ||
![]() |
cbb69bd3cb | ||
![]() |
200a3e5e8c | ||
![]() |
0fab2dc24f | ||
![]() |
a48654f195 | ||
![]() |
174b098724 | ||
![]() |
ecb4671e0d | ||
![]() |
6c6f6838ee | ||
![]() |
b4414758a7 | ||
![]() |
5b37536ce5 | ||
![]() |
3365fa174d | ||
![]() |
d42b95bab9 | ||
![]() |
6a3aaf360e | ||
![]() |
083d0c90e2 | ||
![]() |
fed142dad2 | ||
![]() |
fcd2126330 | ||
![]() |
e5cd0ced53 | ||
![]() |
06dad7865c | ||
![]() |
6915634729 | ||
![]() |
d3647e2e8a | ||
![]() |
217bd1f4bf | ||
![]() |
75fe500305 | ||
![]() |
afc779440a | ||
![]() |
7f71717a9f | ||
![]() |
0849aa3f03 | ||
![]() |
4cdeb214a7 | ||
![]() |
3c727bc46f | ||
![]() |
e13662dd2c | ||
![]() |
2840c98bb0 | ||
![]() |
7d9bf83f66 | ||
![]() |
d2c47bb153 | ||
![]() |
9da3402997 | ||
![]() |
e7784e3c34 | ||
![]() |
224d6dc93f | ||
![]() |
f95b5d05d7 | ||
![]() |
ee109c2279 | ||
![]() |
e515c7beb1 | ||
![]() |
5f56db6f6e | ||
![]() |
c00b204259 | ||
![]() |
280c89a78d | ||
![]() |
809ba2b392 | ||
![]() |
18254392ab | ||
![]() |
5646518352 | ||
![]() |
710b88efae | ||
![]() |
1118c3399c | ||
![]() |
98a7800fae | ||
![]() |
b3f9bbe50f | ||
![]() |
e37c7e58cf | ||
![]() |
feb9ffadec | ||
![]() |
a4d96b032e | ||
![]() |
038d70a40b | ||
![]() |
44d5009538 | ||
![]() |
8e1e7fb314 | ||
![]() |
dbbfbb2855 | ||
![]() |
24ed979faf | ||
![]() |
e64a65c41e | ||
![]() |
67c2fe8005 | ||
![]() |
d3d15b79fb | ||
![]() |
60586d8ce0 | ||
![]() |
c95257f32c | ||
![]() |
f0162557c5 | ||
![]() |
5f257119d6 | ||
![]() |
e6df4f24f4 | ||
![]() |
d4b733ff16 | ||
![]() |
3c72d28511 | ||
![]() |
e4b63a68fd | ||
![]() |
a251029546 | ||
![]() |
b5d457daa9 | ||
![]() |
603f2a2154 | ||
![]() |
4f40c96d19 | ||
![]() |
d7fc658bae | ||
![]() |
08dd2bd93d | ||
![]() |
10b8a33b55 | ||
![]() |
bd0210cdce | ||
![]() |
5677523800 | ||
![]() |
2150933368 | ||
![]() |
fd7dbaf0a7 | ||
![]() |
d145310447 | ||
![]() |
9d413680d9 | ||
![]() |
0e85c814e1 | ||
![]() |
3589bb9597 | ||
![]() |
10b06eda91 | ||
![]() |
145d337db9 | ||
![]() |
1d59ae24c6 | ||
![]() |
6309dd1350 | ||
![]() |
0ae001ed6d | ||
![]() |
bb8efadb98 | ||
![]() |
620c894929 | ||
![]() |
18d2a7fe4d | ||
![]() |
78e74cda28 | ||
![]() |
cc9c69c931 | ||
![]() |
6559cfd0e1 | ||
![]() |
28dcc781b4 | ||
![]() |
09f10d2d7e | ||
![]() |
8492503d4f | ||
![]() |
c48b9b34e9 | ||
![]() |
04b4da0c75 | ||
![]() |
276b171d93 | ||
![]() |
44675739a1 | ||
![]() |
6e13718cbd | ||
![]() |
2bb6922e7f | ||
![]() |
67e167427c | ||
![]() |
969a4e7ba5 | ||
![]() |
a5aa38ce3c | ||
![]() |
0495103635 | ||
![]() |
ae6b75b62a | ||
![]() |
9091d686ed | ||
![]() |
47b5d7a2df | ||
![]() |
6298a7a357 | ||
![]() |
45c63e2b82 | ||
![]() |
dba617a7fe | ||
![]() |
4a253a7760 | ||
![]() |
bd11663e0a | ||
![]() |
7c4bff567b | ||
![]() |
df2a5e97f8 | ||
![]() |
e9e5c75dec | ||
![]() |
21e4387a39 | ||
![]() |
67ef829e04 | ||
![]() |
8b2b9713ce | ||
![]() |
b7f998094f | ||
![]() |
c324200f70 | ||
![]() |
db3377e170 | ||
![]() |
85a8feec9d | ||
![]() |
22b0ddfb42 | ||
![]() |
1cc94f8353 | ||
![]() |
7d2a7d24a6 | ||
![]() |
73056f5620 | ||
![]() |
2c271acfe9 | ||
![]() |
b76e833ea5 | ||
![]() |
3bdb9f289f | ||
![]() |
97b8684e1a | ||
![]() |
8958b2aa1b | ||
![]() |
cf0fb69153 | ||
![]() |
8603cf89b0 | ||
![]() |
39ef0107ad | ||
![]() |
63d7b63f42 | ||
![]() |
4ea6c98f43 | ||
![]() |
39bdf261c6 | ||
![]() |
cb3e13e9e5 | ||
![]() |
7a7e8fe741 | ||
![]() |
4a9e691747 | ||
![]() |
4026c57834 | ||
![]() |
f1c05bc909 | ||
![]() |
18d3b3545d | ||
![]() |
a03d9fba10 | ||
![]() |
ef24020b14 | ||
![]() |
d16d969799 | ||
![]() |
232f1fda6d | ||
![]() |
c1fd7fdad0 | ||
![]() |
9470a4f1ed | ||
![]() |
9da027cf74 | ||
![]() |
45e9988700 | ||
![]() |
1f9b4703e8 | ||
![]() |
c21b61bbd2 | ||
![]() |
61249b0887 | ||
![]() |
0ac48a431a | ||
![]() |
7b15fefcaa | ||
![]() |
6d076284e8 | ||
![]() |
d7d248fd04 | ||
![]() |
a636aa592b | ||
![]() |
1fc6603f41 | ||
![]() |
d36a233cbf | ||
![]() |
2a11f42318 | ||
![]() |
e23383be41 | ||
![]() |
36a47febc2 | ||
![]() |
053a86c0d4 | ||
![]() |
3ded1b6c6e | ||
![]() |
28ea68fe7f | ||
![]() |
6203c27244 | ||
![]() |
57fb800c77 | ||
![]() |
9a3ec31191 | ||
![]() |
8ef3aee7e7 | ||
![]() |
a20e6086cc | ||
![]() |
66fa8a7595 | ||
![]() |
a8f9e3f0b0 | ||
![]() |
215905213b | ||
![]() |
f8865c1413 | ||
![]() |
67aed51742 | ||
![]() |
2be2b10e59 | ||
![]() |
ed5e194b8e | ||
![]() |
a6b4cb24b8 | ||
![]() |
4276fc0b0b | ||
![]() |
0d10957441 | ||
![]() |
368720538c | ||
![]() |
d068a460bd | ||
![]() |
346ff199c6 | ||
![]() |
480a4a9d38 | ||
![]() |
77cfd0e1a6 | ||
![]() |
950af2e753 | ||
![]() |
aa2845a730 | ||
![]() |
aedf066337 | ||
![]() |
b975cf3ed4 | ||
![]() |
f2af5ce7eb | ||
![]() |
fa612b731c | ||
![]() |
0933268e61 | ||
![]() |
3aa5fc0cc2 | ||
![]() |
397f57accb | ||
![]() |
e3b1944e31 | ||
![]() |
507582f40b | ||
![]() |
08e015a951 | ||
![]() |
ef17f4eacb | ||
![]() |
3d185dc622 | ||
![]() |
76b4b88e4b | ||
![]() |
fd37edc53f | ||
![]() |
5662c06a33 | ||
![]() |
0aede618ec | ||
![]() |
e52d4ce033 | ||
![]() |
b646672d3e | ||
![]() |
a1a7d44fd7 | ||
![]() |
25ea221a6a | ||
![]() |
38ee4f556e | ||
![]() |
862f20ef20 | ||
![]() |
5c902001b9 | ||
![]() |
5f6887b316 | ||
![]() |
45b96bd568 | ||
![]() |
197d006860 | ||
![]() |
49f8aac6a9 | ||
![]() |
22dd50a047 | ||
![]() |
81d9b5afd6 | ||
![]() |
59f3d2a11e | ||
![]() |
134a170a61 | ||
![]() |
681f006ae1 | ||
![]() |
36abfcc79b | ||
![]() |
249a14f84a | ||
![]() |
10fdc45dea | ||
![]() |
e8e7b419b5 | ||
![]() |
955fc58773 | ||
![]() |
2da3d83420 | ||
![]() |
c3f2e8dde1 | ||
![]() |
4e4c80b7fa | ||
![]() |
3e776c8c41 | ||
![]() |
7c82e4b6c1 | ||
![]() |
12d26d5a3d | ||
![]() |
d228769b1b | ||
![]() |
433f88b459 | ||
![]() |
704d56d193 | ||
![]() |
5f4da6e0bc | ||
![]() |
0ce89d53d7 | ||
![]() |
5bdffd7d20 | ||
![]() |
5996920249 | ||
![]() |
f0119085e4 | ||
![]() |
22e17172dd | ||
![]() |
6ec731e263 | ||
![]() |
7cd8b6f938 | ||
![]() |
a4a19845d4 | ||
![]() |
fffb0eafde | ||
![]() |
10f60e2807 | ||
![]() |
3db27e6017 | ||
![]() |
91b64798bb | ||
![]() |
8455db6fae | ||
![]() |
530648e937 | ||
![]() |
7f67435cb9 | ||
![]() |
d8eba411ec | ||
![]() |
dcfa903176 | ||
![]() |
fc70a8e145 | ||
![]() |
e4a2d7dfb7 | ||
![]() |
f081527731 | ||
![]() |
9f8a0234aa | ||
![]() |
857c860952 | ||
![]() |
cff68fc062 | ||
![]() |
365c741864 | ||
![]() |
366f9db8a8 | ||
![]() |
9d5303c59d | ||
![]() |
c527392e21 | ||
![]() |
933cc333cc | ||
![]() |
e72c3b2c86 | ||
![]() |
231c849451 | ||
![]() |
a5af248715 | ||
![]() |
8fede48e7b | ||
![]() |
d0492ec7bd | ||
![]() |
b5399202b6 | ||
![]() |
240077ffe8 | ||
![]() |
eee9a1661f | ||
![]() |
9199546dca | ||
![]() |
e0d97d44aa | ||
![]() |
5fbb69e7c5 | ||
![]() |
3a6aa8f820 | ||
![]() |
44ae5c86a7 | ||
![]() |
85f47e1693 | ||
![]() |
9a96f8b155 | ||
![]() |
391dc06013 | ||
![]() |
598b392878 | ||
![]() |
9e75993658 | ||
![]() |
159a3a3706 | ||
![]() |
cbdb2e6e6f | ||
![]() |
d409da2201 | ||
![]() |
c7aa67b07a | ||
![]() |
5b302ae2e6 | ||
![]() |
df2925e51c | ||
![]() |
02b19fed27 | ||
![]() |
17f06564a2 | ||
![]() |
6ddd394e33 | ||
![]() |
d3f78299e7 | ||
![]() |
3e76b2374c | ||
![]() |
a3b97f7c24 | ||
![]() |
4f50e36e5b | ||
![]() |
a0bbbe1404 | ||
![]() |
50f983871b | ||
![]() |
2d3b02df6a | ||
![]() |
4010c89899 | ||
![]() |
215e930da4 | ||
![]() |
5b74d75011 | ||
![]() |
9266eaef16 | ||
![]() |
963a0ce6ef | ||
![]() |
5f5e453fb3 | ||
![]() |
0cacd111df | ||
![]() |
d86a7ccf3e | ||
![]() |
35ea4d1a00 | ||
![]() |
10583610bd | ||
![]() |
55816a09fe | ||
![]() |
ad288be2ee | ||
![]() |
c9071ff724 | ||
![]() |
96b8dce982 | ||
![]() |
1e498eccb6 | ||
![]() |
da048cbc7b | ||
![]() |
7bd5529bb7 | ||
![]() |
1b64af143e | ||
![]() |
d2685f2544 | ||
![]() |
83c6aef078 | ||
![]() |
a9570f7298 | ||
![]() |
71e0a788d1 | ||
![]() |
e6910d3c52 | ||
![]() |
9a6e4ba77f | ||
![]() |
bab4649a1e | ||
![]() |
5a763230e5 | ||
![]() |
09e6804761 | ||
![]() |
a414aa27b6 | ||
![]() |
c598fd9ec4 | ||
![]() |
a8eeb7f76a | ||
![]() |
d28e3374c7 | ||
![]() |
c3e9ae0ca0 | ||
![]() |
71cfec91af | ||
![]() |
b085222253 | ||
![]() |
29b6e00071 | ||
![]() |
9aacc85a16 | ||
![]() |
aa32d454c9 | ||
![]() |
d3b69abd87 | ||
![]() |
df88300e6e | ||
![]() |
e90ed7a853 | ||
![]() |
fdaf13bdc4 | ||
![]() |
d96d40e0b0 | ||
![]() |
5dae0c14d9 | ||
![]() |
5cd54c4831 | ||
![]() |
4caa02474c | ||
![]() |
005defbb5c | ||
![]() |
061045016f | ||
![]() |
997353ab71 | ||
![]() |
1570ed4610 | ||
![]() |
25e2d78311 | ||
![]() |
1e2d014ac9 | ||
![]() |
a0b1d16e79 | ||
![]() |
6985391437 | ||
![]() |
e90f58a0a7 | ||
![]() |
0555fca5d8 | ||
![]() |
2a55e74e11 | ||
![]() |
94ace2348f | ||
![]() |
2b58a2a176 | ||
![]() |
7bc82365c6 | ||
![]() |
de11dc43ab | ||
![]() |
756927b6f8 | ||
![]() |
5693c69457 | ||
![]() |
cda41a1506 | ||
![]() |
890298457a | ||
![]() |
ccfc7351e7 | ||
![]() |
df6c5dd22e | ||
![]() |
60f23c838b | ||
![]() |
dcd807c49b | ||
![]() |
575b921a15 | ||
![]() |
67473f07b1 | ||
![]() |
3aa368b630 | ||
![]() |
4e044d66b4 | ||
![]() |
065a5d2a47 | ||
![]() |
5103da09c5 | ||
![]() |
33ea1d44fb | ||
![]() |
e62027b73c | ||
![]() |
26c43667aa | ||
![]() |
92fbc26852 | ||
![]() |
a4e488a1eb | ||
![]() |
0ee9c69ddf | ||
![]() |
dd5e6c18d5 | ||
![]() |
737e95c3f9 | ||
![]() |
4b064dc19f | ||
![]() |
f2e5c913d6 | ||
![]() |
8758bd57ca | ||
![]() |
73e31373a8 | ||
![]() |
990e620dc7 | ||
![]() |
9103e58314 | ||
![]() |
a26fe71171 | ||
![]() |
7a44e46d6d | ||
![]() |
b376e4da1f | ||
![]() |
f8481f8d4c | ||
![]() |
54f55cc021 | ||
![]() |
a7a4f38d58 | ||
![]() |
d67e49400f | ||
![]() |
6789f2c1e3 | ||
![]() |
e8a3ffcb41 | ||
![]() |
9607c743a0 | ||
![]() |
553b964ab8 | ||
![]() |
72ac408429 | ||
![]() |
8456905960 | ||
![]() |
13261c974a | ||
![]() |
eafabdce36 | ||
![]() |
d02a57744c | ||
![]() |
58374add90 | ||
![]() |
a52d501ba2 | ||
![]() |
702abbad6d | ||
![]() |
2d0edb5270 | ||
![]() |
7aab34b540 | ||
![]() |
d637a13f59 | ||
![]() |
17f99aeed8 | ||
![]() |
8729414da9 | ||
![]() |
cd8b7e5528 | ||
![]() |
6d74c5663f | ||
![]() |
5ccca5e329 | ||
![]() |
6c7b7b796e | ||
![]() |
4ee3cea6ce | ||
![]() |
1c07e550bb | ||
![]() |
50c71ebb01 | ||
![]() |
348d086c11 | ||
![]() |
89c1853977 | ||
![]() |
3acff54837 | ||
![]() |
c7466f7a1a | ||
![]() |
6420ad9f69 | ||
![]() |
b30823d5ac | ||
![]() |
864472d648 | ||
![]() |
36b02ec008 | ||
![]() |
aad080aa1b | ||
![]() |
7b7a6e10f8 | ||
![]() |
aeccf92375 | ||
![]() |
f90d271739 | ||
![]() |
9c2fde940d | ||
![]() |
2b57cc6be8 | ||
![]() |
b62819e3fb | ||
![]() |
3eb5f2c65b | ||
![]() |
41be7f951c | ||
![]() |
7812fdb6ed | ||
![]() |
4eeb2a0583 | ||
![]() |
3dd0c537ee | ||
![]() |
e0aa42f695 | ||
![]() |
5dddf2f757 | ||
![]() |
f8137ea7c1 | ||
![]() |
cf6f1a083e | ||
![]() |
f9cfeacc67 | ||
![]() |
98229a47b2 | ||
![]() |
530ace1507 | ||
![]() |
792c657ff2 | ||
![]() |
5aa07439a8 | ||
![]() |
bf2862f164 | ||
![]() |
d9ef227435 | ||
![]() |
324c845dc4 | ||
![]() |
5d0c44e84b | ||
![]() |
01a71c3dbb | ||
![]() |
b018f026e3 | ||
![]() |
0a38e3557d | ||
![]() |
6f450272b8 | ||
![]() |
7e01f9be6e | ||
![]() |
00d2a1fe9f | ||
![]() |
18d0d435c6 | ||
![]() |
f298c154e2 | ||
![]() |
822df37f8c | ||
![]() |
73cac95255 | ||
![]() |
a0e7789d50 | ||
![]() |
c825b37cc6 | ||
![]() |
2dd4aa31e5 | ||
![]() |
c95adfaf74 | ||
![]() |
9da8ea5967 | ||
![]() |
4d5ecc5518 | ||
![]() |
963a0fcd77 | ||
![]() |
fbd8dfa5be | ||
![]() |
c43f791b29 | ||
![]() |
39b873cd5f | ||
![]() |
ec90537181 | ||
![]() |
4709195a1d | ||
![]() |
0082c23a90 | ||
![]() |
c7b559f449 | ||
![]() |
d571c7e08e | ||
![]() |
b6f0b25f24 | ||
![]() |
5ea6bd5980 | ||
![]() |
ea29b67c5c | ||
![]() |
1f851bc04c | ||
![]() |
0921007d92 | ||
![]() |
4a2e0bfa00 | ||
![]() |
8ebc587fb5 | ||
![]() |
c7b46f4fba | ||
![]() |
4ad354a561 | ||
![]() |
587592449a | ||
![]() |
425b071a50 | ||
![]() |
4dd72e6793 | ||
![]() |
d2d4a24229 | ||
![]() |
4805394e61 | ||
![]() |
5cbd723f8d | ||
![]() |
28153656d7 | ||
![]() |
d2eaf16751 | ||
![]() |
e0d98b2e14 | ||
![]() |
c38f053294 | ||
![]() |
921d274579 | ||
![]() |
c9f95a1866 | ||
![]() |
99469f8404 | ||
![]() |
417d2c0336 | ||
![]() |
2a3de1a090 | ||
![]() |
d9318c5af3 | ||
![]() |
0e02cf5c86 | ||
![]() |
45277affe8 | ||
![]() |
c564a843fa | ||
![]() |
efa810da91 | ||
![]() |
c0e1c90497 | ||
![]() |
b1bfdec473 | ||
![]() |
244f423baf | ||
![]() |
8897b32cd3 | ||
![]() |
5493fadc9e | ||
![]() |
eade3d0a2d | ||
![]() |
36f9eca33e | ||
![]() |
4dd90e56b1 | ||
![]() |
5e7484a12d | ||
![]() |
fdbc44e41b | ||
![]() |
e0d16dcb22 | ||
![]() |
0a5ee0634f | ||
![]() |
fa1331ffd5 | ||
![]() |
57b5b9a7a6 | ||
![]() |
58fbfc3c38 | ||
![]() |
0af5e0b795 | ||
![]() |
d7771eb4b6 | ||
![]() |
fc0902c290 | ||
![]() |
75890f88fa | ||
![]() |
9a6b07e1e1 | ||
![]() |
ce02d1dc98 | ||
![]() |
7760e63b47 | ||
![]() |
a483f2466f | ||
![]() |
48c345a403 | ||
![]() |
82b79aa332 | ||
![]() |
ffbf9f265f | ||
![]() |
144f65c459 | ||
![]() |
18204586e1 | ||
![]() |
1f3c970e7a | ||
![]() |
1cfd93640c | ||
![]() |
553ea4971f | ||
![]() |
ac8b01a94c | ||
![]() |
b3934c9788 | ||
![]() |
37ae863443 | ||
![]() |
f57356006d | ||
![]() |
591a104c80 | ||
![]() |
38097c9095 | ||
![]() |
7f31e624ca | ||
![]() |
e6fbfcb1e8 | ||
![]() |
00687f21cd | ||
![]() |
96fc0d043e | ||
![]() |
190353785e | ||
![]() |
f54adb4a3e | ||
![]() |
f2a5d92398 | ||
![]() |
b14c768fa2 | ||
![]() |
851d2f2d91 | ||
![]() |
4e6aad5115 | ||
![]() |
7bd1408de0 | ||
![]() |
d63eb396e1 | ||
![]() |
465e99ab5d | ||
![]() |
33916cfbd3 | ||
![]() |
a1626927cc | ||
![]() |
75e2abe242 | ||
![]() |
2db8075e3f | ||
![]() |
413876644c | ||
![]() |
d5e9f2e23e | ||
![]() |
bc59d015e6 | ||
![]() |
2decf94ad0 | ||
![]() |
b52744ae18 | ||
![]() |
6cbbf0af2f | ||
![]() |
5d7ef149aa | ||
![]() |
7ce0974767 | ||
![]() |
7b12c7a07d | ||
![]() |
728e3fd2f0 | ||
![]() |
4eedeebd46 | ||
![]() |
85fb12155b | ||
![]() |
f99daa696e | ||
![]() |
b4f9dd46a9 | ||
![]() |
ffe16f89bb | ||
![]() |
7604d92d5c | ||
![]() |
3abd77a1e6 | ||
![]() |
d96b79a9ba | ||
![]() |
14bb888c21 | ||
![]() |
c8f59ea1a7 | ||
![]() |
233520b797 | ||
![]() |
061d31af33 | ||
![]() |
ec742d3180 | ||
![]() |
1bc62cfba4 | ||
![]() |
028d9a2667 | ||
![]() |
d53e00ffe0 | ||
![]() |
b90fcc1b71 | ||
![]() |
a4e7305d52 | ||
![]() |
a3378f8d03 | ||
![]() |
5716d163ec | ||
![]() |
42ef035241 | ||
![]() |
b6157195b3 | ||
![]() |
b8ee68034d | ||
![]() |
6598b1b10d | ||
![]() |
4ff4058244 | ||
![]() |
dddd5af830 | ||
![]() |
26fac9507e | ||
![]() |
1f1c9698ce | ||
![]() |
56f7459617 | ||
![]() |
86604b5de1 | ||
![]() |
0544dbe891 | ||
![]() |
6365cea0b2 | ||
![]() |
7fef13346e | ||
![]() |
81216e6ece | ||
![]() |
1d0b305332 | ||
![]() |
c10ccc011f | ||
![]() |
3fe7995060 | ||
![]() |
c441d04e8a | ||
![]() |
52d84a99ac | ||
![]() |
fcf20215a6 | ||
![]() |
aa2f9622f8 | ||
![]() |
1811318dea | ||
![]() |
5eb50cb2b6 | ||
![]() |
f6ef6ff7db | ||
![]() |
2f33a80e1e | ||
![]() |
363d49b655 | ||
![]() |
de8c6d5572 | ||
![]() |
9406bda93d | ||
![]() |
d17a447a5f | ||
![]() |
5b4e95484e | ||
![]() |
bebea41e19 | ||
![]() |
442474fc44 | ||
![]() |
0d9112a4c1 | ||
![]() |
d504e00e18 | ||
![]() |
74c8e7fad9 | ||
![]() |
4b781d3827 | ||
![]() |
9fbcc5c32d | ||
![]() |
c7ec8190fb | ||
![]() |
b73a6d84ee | ||
![]() |
2eaa7f1ab6 | ||
![]() |
608445e64f | ||
![]() |
1f4be77662 | ||
![]() |
0deae4abf9 | ||
![]() |
5b2f9351c7 | ||
![]() |
6fdf30357c | ||
![]() |
cf5d7478fc | ||
![]() |
9a0df5afb0 | ||
![]() |
813b2fcb38 | ||
![]() |
08cbc0f187 | ||
![]() |
d8251c8f79 | ||
![]() |
5ea70baa6f | ||
![]() |
d23ce9fb63 | ||
![]() |
ddf8016a0c | ||
![]() |
ab191abd5a | ||
![]() |
c2e5e94b37 | ||
![]() |
6a9b251be1 | ||
![]() |
6b5185abfb | ||
![]() |
2a41280076 | ||
![]() |
91d986970b | ||
![]() |
b4192bba7a | ||
![]() |
9fe0aa0604 | ||
![]() |
fc528749f8 | ||
![]() |
5c71a3c85b | ||
![]() |
94e768dd01 | ||
![]() |
0fb91d6bcc | ||
![]() |
02854881b4 | ||
![]() |
4254781391 | ||
![]() |
31f4f4096e | ||
![]() |
e95e016378 | ||
![]() |
c337c9128c | ||
![]() |
5a38562bfc | ||
![]() |
a3dd0e5f7d | ||
![]() |
fcd1e106a5 | ||
![]() |
346328156a | ||
![]() |
3239f99ea8 | ||
![]() |
93c32d3f29 | ||
![]() |
98449dac3f | ||
![]() |
32b60edda7 | ||
![]() |
823c95bd9c | ||
![]() |
e99d872f2b | ||
![]() |
de8f8b02dc | ||
![]() |
eec45dfff9 | ||
![]() |
cce86c8e96 | ||
![]() |
aabdc47c38 | ||
![]() |
cb07a729e5 | ||
![]() |
df10f7fbe7 | ||
![]() |
71c531240f | ||
![]() |
1e83207dac | ||
![]() |
3311fcdc8e | ||
![]() |
f368be925f | ||
![]() |
075c57ca06 | ||
![]() |
49fc80d506 | ||
![]() |
74fc2fcfa9 | ||
![]() |
7cc427e28d | ||
![]() |
87c571412c | ||
![]() |
ab093b2cde | ||
![]() |
bbc4ede768 | ||
![]() |
64c20dc528 | ||
![]() |
50ea9bda89 | ||
![]() |
2cf8c4e37a | ||
![]() |
fe4719f656 | ||
![]() |
1d43b7b316 | ||
![]() |
78e4fead49 | ||
![]() |
02d5143ff2 | ||
![]() |
d9c92b2c6d | ||
![]() |
27ac9bbaf3 | ||
![]() |
11cdd393f2 | ||
![]() |
1ca8578035 | ||
![]() |
2516718882 | ||
![]() |
5283314c4f | ||
![]() |
dcae8da0d1 | ||
![]() |
34f2a1a02f | ||
![]() |
ee5a68a23c | ||
![]() |
6c706ccd9f | ||
![]() |
94106f5825 | ||
![]() |
72ab2b8011 | ||
![]() |
8978ab5917 | ||
![]() |
94577316f9 | ||
![]() |
91650fb052 | ||
![]() |
e9aa037230 | ||
![]() |
871e6f691c | ||
![]() |
fe60836a89 | ||
![]() |
bea2e73b82 | ||
![]() |
481e55e8da | ||
![]() |
d26a67297a | ||
![]() |
753bd7e1d9 | ||
![]() |
b57492c1c6 | ||
![]() |
4ff5c3b455 | ||
![]() |
f62c47a757 | ||
![]() |
a85bb0d86f | ||
![]() |
5736d523dd | ||
![]() |
5004b5723d | ||
![]() |
ad2802d8e8 | ||
![]() |
3fedd452a5 | ||
![]() |
292bc3c4e5 | ||
![]() |
512ba8e733 | ||
![]() |
9a87ff684d | ||
![]() |
f79fc21bfc | ||
![]() |
ffddd58b6b | ||
![]() |
087e5eaa32 | ||
![]() |
cbd27831df | ||
![]() |
f6028b63b6 | ||
![]() |
a60e01db97 | ||
![]() |
68c2ea38c9 | ||
![]() |
3469cfca2f | ||
![]() |
afd189d24c | ||
![]() |
06cb09c267 | ||
![]() |
e461b57a48 | ||
![]() |
eca9d49575 | ||
![]() |
15a37a5062 | ||
![]() |
3f8f9eb92c | ||
![]() |
33de2bda9e | ||
![]() |
94d913fbab | ||
![]() |
beb1fcc176 | ||
![]() |
1e1a6e3a2d | ||
![]() |
6e7c21e439 | ||
![]() |
cfe9aaf639 | ||
![]() |
69e701befb | ||
![]() |
5174a085b7 | ||
![]() |
15fab69eca | ||
![]() |
20b103a0fb | ||
![]() |
8ebe7ee81a | ||
![]() |
1d747f664b | ||
![]() |
dbf5988c28 | ||
![]() |
31ab0e4b7d | ||
![]() |
35ea7083bb | ||
![]() |
bf90e8bf44 | ||
![]() |
b1305644f4 | ||
![]() |
34707a057b | ||
![]() |
f5e90252f1 | ||
![]() |
e75acf69aa | ||
![]() |
3ad3fc2622 | ||
![]() |
a59468d6c1 | ||
![]() |
86e63b1614 | ||
![]() |
3f8f9f6711 | ||
![]() |
d01f494277 | ||
![]() |
4db525c6a9 | ||
![]() |
8b5f8b0cb4 | ||
![]() |
d0c9b5e98f | ||
![]() |
e313625ccb | ||
![]() |
7dead548f3 | ||
![]() |
8db46ff762 | ||
![]() |
93f54a997a | ||
![]() |
1353491952 | ||
![]() |
00802ffe7a | ||
![]() |
78e556aaf7 | ||
![]() |
e34988d65a | ||
![]() |
07f5c7c89c | ||
![]() |
7319d8941a | ||
![]() |
3d7933135b | ||
![]() |
a778472461 | ||
![]() |
cbe2a7446d | ||
![]() |
8251dc5cd1 | ||
![]() |
5a4103a248 | ||
![]() |
d7996f5c1a | ||
![]() |
db4229f033 | ||
![]() |
e103664963 | ||
![]() |
fbf3936ddc | ||
![]() |
62d03f1976 | ||
![]() |
f3ea159c6b | ||
![]() |
3c99294a3a | ||
![]() |
7a2a8cffbb | ||
![]() |
6d90f87b2f | ||
![]() |
f506d24a82 | ||
![]() |
ddb0d23ca7 | ||
![]() |
763be9bb95 | ||
![]() |
77109144e7 | ||
![]() |
840e7bd985 | ||
![]() |
a6c12f4b25 | ||
![]() |
e8e9a4d07b | ||
![]() |
ba00182ce4 | ||
![]() |
2ad78ee3b8 | ||
![]() |
4995d59499 | ||
![]() |
d58ef7aa36 | ||
![]() |
dc59632fb3 | ||
![]() |
1542e15a1b | ||
![]() |
5b5be40dd5 | ||
![]() |
1ecf0f4c23 | ||
![]() |
fa7d1ac554 | ||
![]() |
48ce7a9b78 | ||
![]() |
09bf54f9af | ||
![]() |
43b9bcdb0b | ||
![]() |
a3017b8456 | ||
![]() |
aac915b285 | ||
![]() |
7208f045c1 | ||
![]() |
f7a3c42da1 | ||
![]() |
4d1c53eb1e | ||
![]() |
7bcc9b19ac | ||
![]() |
7cfc729679 | ||
![]() |
1f8480f0af | ||
![]() |
ec3b68ad28 | ||
![]() |
3674e27e0f | ||
![]() |
e4486420ce | ||
![]() |
fe64cc697b | ||
![]() |
97177dffd6 | ||
![]() |
061a02dddc | ||
![]() |
1f72c3e720 | ||
![]() |
8270469652 | ||
![]() |
5e6590a0f7 | ||
![]() |
06dfd13927 | ||
![]() |
486cc92f2e | ||
![]() |
e8d649b152 | ||
![]() |
e96bd14d21 | ||
![]() |
e4a2d2a290 | ||
![]() |
d8d5d0fa61 | ||
![]() |
e010a03dd5 | ||
![]() |
427aea73e7 | ||
![]() |
c4436b7a1e | ||
![]() |
d098051047 | ||
![]() |
034a7c424d | ||
![]() |
b113436055 | ||
![]() |
e550d974da | ||
![]() |
bc34ef4b66 | ||
![]() |
a5cc1e804b | ||
![]() |
aac51979cc | ||
![]() |
8f8638fb7c | ||
![]() |
d1c74070ab | ||
![]() |
ee01d09af5 | ||
![]() |
caaf4e3e40 | ||
![]() |
34037e58e5 | ||
![]() |
66152b42ae | ||
![]() |
76c8737485 | ||
![]() |
4a1eb55127 | ||
![]() |
c87637c6f4 | ||
![]() |
364b81a1b9 | ||
![]() |
d4c8cf66ef | ||
![]() |
08762bc066 | ||
![]() |
0add11a257 | ||
![]() |
ca5e60b38b | ||
![]() |
0e7876536d | ||
![]() |
be61a03a98 | ||
![]() |
50c707ba51 | ||
![]() |
2a2fd7a8b1 | ||
![]() |
ad126c838e | ||
![]() |
cafc18a78f | ||
![]() |
ffca12a8b0 | ||
![]() |
137f57ad9c | ||
![]() |
153b3322a6 | ||
![]() |
575535bdbd | ||
![]() |
61a3802494 | ||
![]() |
0157f665a3 | ||
![]() |
d366605d91 | ||
![]() |
fd5bcad5d6 | ||
![]() |
7adb80b35b | ||
![]() |
dc88e7a2c2 | ||
![]() |
dd68a7151f | ||
![]() |
bf2497ea3e | ||
![]() |
202c889246 | ||
![]() |
ec0e93bd6f | ||
![]() |
def9bef988 | ||
![]() |
c3db9032f3 | ||
![]() |
016dc17d94 | ||
![]() |
8e1672568a | ||
![]() |
42b8ac1235 | ||
![]() |
2348f9d785 | ||
![]() |
04f86ef130 | ||
![]() |
f436086aae | ||
![]() |
1b813d371d | ||
![]() |
8f49d96c3a | ||
![]() |
49f5b8d150 | ||
![]() |
f0bbb063dd | ||
![]() |
d95a9469ac | ||
![]() |
6e088d17fd | ||
![]() |
42aeafc907 | ||
![]() |
3073b6559c | ||
![]() |
af57da8e6b | ||
![]() |
56e9abfc92 | ||
![]() |
61b4c6d3ac | ||
![]() |
7e6b43236a | ||
![]() |
6a33ac05a3 | ||
![]() |
5f1246280c | ||
![]() |
ecef0c78d2 | ||
![]() |
0ce42e6185 | ||
![]() |
3709d9d5c8 | ||
![]() |
e65f916ba5 | ||
![]() |
f9c8ce1ac7 | ||
![]() |
b881e5c69c | ||
![]() |
51a89c80aa | ||
![]() |
97a5f408d2 | ||
![]() |
2f00d7d145 | ||
![]() |
d743838716 | ||
![]() |
069b4854f8 | ||
![]() |
f089c45115 | ||
![]() |
90fe015d68 | ||
![]() |
96c86fd4b2 | ||
![]() |
d921c36cd4 | ||
![]() |
4a552069cf | ||
![]() |
74c171b6d1 | ||
![]() |
1ae1313edd | ||
![]() |
5949d01821 | ||
![]() |
3cdb0ae4c8 | ||
![]() |
89b6ccf47d | ||
![]() |
047ce2949a | ||
![]() |
53bdfee057 | ||
![]() |
2da55993e0 | ||
![]() |
a258eda035 | ||
![]() |
7c125cf9d6 | ||
![]() |
2af76230f7 | ||
![]() |
bdb530f831 | ||
![]() |
7a7c09493c | ||
![]() |
f3d588eca5 | ||
![]() |
031c0b7b21 | ||
![]() |
ce017ecd40 | ||
![]() |
85e58faa78 | ||
![]() |
808ed11e91 | ||
![]() |
f8f52c4587 | ||
![]() |
54e6e2f66e | ||
![]() |
fe1e09f06b | ||
![]() |
cd646c0e42 | ||
![]() |
f180510fbb | ||
![]() |
687e74de9b | ||
![]() |
65f91dd051 | ||
![]() |
a8a4616cab | ||
![]() |
aaac86fd9d | ||
![]() |
35ddf9235f | ||
![]() |
554189908d | ||
![]() |
54dbbd154c | ||
![]() |
a9224015e0 | ||
![]() |
1cba50266e | ||
![]() |
341456cc25 | ||
![]() |
ae7852d9b9 | ||
![]() |
4ce523f33b | ||
![]() |
6b4a8325ae | ||
![]() |
6d3044bddd | ||
![]() |
0678f61ce9 | ||
![]() |
ebede9b910 | ||
![]() |
b12791d3e0 | ||
![]() |
ce0b0fa0c8 | ||
![]() |
dce09586cd | ||
![]() |
4f1186a610 | ||
![]() |
1cb52a602a | ||
![]() |
c482083d82 | ||
![]() |
d9dda88164 | ||
![]() |
c9fe948b90 | ||
![]() |
cc731fe3c4 | ||
![]() |
40b7262c19 | ||
![]() |
9da61ad562 | ||
![]() |
3b731282e3 | ||
![]() |
cfc14ade2a | ||
![]() |
d4306e61c2 | ||
![]() |
3afa6e2350 | ||
![]() |
8bbb0448dc | ||
![]() |
dcbcbf40a0 | ||
![]() |
9a0a5ca804 | ||
![]() |
20b2866631 | ||
![]() |
92eec664b1 | ||
![]() |
723fe84383 | ||
![]() |
3ca9347361 | ||
![]() |
704d36a7eb | ||
![]() |
612df99c34 | ||
![]() |
912e850db4 | ||
![]() |
96735dd543 | ||
![]() |
65cbfbdb40 | ||
![]() |
7865fd4f02 | ||
![]() |
801f001098 | ||
![]() |
7e92257c3c | ||
![]() |
7d4777a8bf | ||
![]() |
e7428afb3e | ||
![]() |
51b7c90dae | ||
![]() |
c9f84ccae5 | ||
![]() |
01fd54dd6f | ||
![]() |
e1446ce38a | ||
![]() |
1920e9f758 | ||
![]() |
550f91aa68 | ||
![]() |
57921e3f52 | ||
![]() |
b300a4decb | ||
![]() |
51e902cd36 | ||
![]() |
ea359c0037 | ||
![]() |
f9f8785aef | ||
![]() |
0abeaa4dc2 | ||
![]() |
18f35ac213 | ||
![]() |
9ca077b3dc | ||
![]() |
351dd3728e | ||
![]() |
054901cb79 | ||
![]() |
4f29f7c3a7 | ||
![]() |
f149f090a6 | ||
![]() |
d113364f82 | ||
![]() |
d499cce371 | ||
![]() |
5d7dbd701f | ||
![]() |
8345134d2a | ||
![]() |
55f9cba0f9 | ||
![]() |
94afcfb6f9 | ||
![]() |
682faa4f9d | ||
![]() |
3cffd1e3ed | ||
![]() |
0730f73f73 | ||
![]() |
dffe20b76c | ||
![]() |
e7161fcca6 | ||
![]() |
3bf873b99f | ||
![]() |
f49bae6622 | ||
![]() |
095233e6cf | ||
![]() |
490d42fce1 | ||
![]() |
11d2db08fa | ||
![]() |
13baa43081 | ||
![]() |
fad76ad534 | ||
![]() |
1c3ddcd120 | ||
![]() |
2ccdeec550 | ||
![]() |
3164f99b3b | ||
![]() |
1bceae12dd | ||
![]() |
b2c60135f5 | ||
![]() |
0dddf3c50c | ||
![]() |
b4badf6e7f | ||
![]() |
9c69afeddd | ||
![]() |
e8835429fd | ||
![]() |
029a84159e | ||
![]() |
ba01e3778a | ||
![]() |
6cfd4e6422 | ||
![]() |
bb372751f7 | ||
![]() |
3fdf2c7e32 | ||
![]() |
9f4ca63603 | ||
![]() |
4bdf772130 | ||
![]() |
6110640fc2 | ||
![]() |
6c243488fa | ||
![]() |
4f218435e3 | ||
![]() |
7ca13fd163 | ||
![]() |
2306534248 | ||
![]() |
2f0248e6d5 | ||
![]() |
3a8564de92 | ||
![]() |
1aa8b9b804 | ||
![]() |
921d5464a1 | ||
![]() |
9993b90a20 | ||
![]() |
6f054519e7 | ||
![]() |
51bf4a4c5c | ||
![]() |
046b83582d | ||
![]() |
be2e467583 | ||
![]() |
b1d137770c | ||
![]() |
40c7cab1da | ||
![]() |
f39e120952 | ||
![]() |
f30f607b0c | ||
![]() |
e40e1da292 | ||
![]() |
1783ef501d | ||
![]() |
b4ec22ecea | ||
![]() |
0200fef389 | ||
![]() |
d8397f146b | ||
![]() |
244be86207 | ||
![]() |
c26135780d | ||
![]() |
4411a26002 | ||
![]() |
21622f575b | ||
![]() |
23e6df04d4 | ||
![]() |
bf403dfc62 | ||
![]() |
c3f48b5a13 | ||
![]() |
e192454f54 | ||
![]() |
a55573be94 | ||
![]() |
0e548f63f9 | ||
![]() |
4d1a34661e | ||
![]() |
7e5802e799 | ||
![]() |
0e8164d805 | ||
![]() |
f9b30bdb43 | ||
![]() |
34de31195f | ||
![]() |
cf05a8d8fa | ||
![]() |
a2e3f3d900 | ||
![]() |
0890ba0fdd | ||
![]() |
d2f082b2e2 | ||
![]() |
e67b8c86d6 | ||
![]() |
e14922f15c | ||
![]() |
ad5669b523 | ||
![]() |
f2a6ba80b5 | ||
![]() |
b3dac15d57 | ||
![]() |
def4ca699a | ||
![]() |
f98fa82134 | ||
![]() |
ff44671ae5 | ||
![]() |
398d66bda9 | ||
![]() |
eb9ac1bbe5 | ||
![]() |
42fc23cff2 | ||
![]() |
78cae3dce7 | ||
![]() |
beed86ff37 | ||
![]() |
ec7324e12e | ||
![]() |
d097b673bb | ||
![]() |
7eea957a3b | ||
![]() |
4dda6b8a81 | ||
![]() |
5fd5a65283 | ||
![]() |
ca0513396d | ||
![]() |
9f87ab4941 | ||
![]() |
e37f5a6eb2 | ||
![]() |
ece40cdc54 | ||
![]() |
65561b22c5 | ||
![]() |
21aa8c5f15 | ||
![]() |
f4bafacc62 | ||
![]() |
2cb54293f8 | ||
![]() |
5610185050 | ||
![]() |
699bd61045 | ||
![]() |
27d0b934a1 | ||
![]() |
0f1b704385 | ||
![]() |
7d0c1d2594 | ||
![]() |
43cff9e1a3 | ||
![]() |
f5ddf869e4 | ||
![]() |
185db4c112 | ||
![]() |
07e3815b74 | ||
![]() |
187ddfd80c | ||
![]() |
d3f7923bc6 | ||
![]() |
e52db94c1a | ||
![]() |
e50959c1fe | ||
![]() |
bab75625cb | ||
![]() |
f0b039ad10 | ||
![]() |
5c8dc7ab07 | ||
![]() |
de2b5390cb | ||
![]() |
d89ceb2125 | ||
![]() |
c43d58d3c9 | ||
![]() |
c6efddee87 | ||
![]() |
f6377e6125 | ||
![]() |
357c47910a | ||
![]() |
4ae48f4284 | ||
![]() |
a48a306fe8 | ||
![]() |
a3c1928fc0 | ||
![]() |
34d3b85227 | ||
![]() |
06a91d8564 | ||
![]() |
e1f0367631 | ||
![]() |
dbcd4f635e | ||
![]() |
a3142aad69 | ||
![]() |
980749536b | ||
![]() |
5dbddfb6a1 | ||
![]() |
c4d2be7a0d | ||
![]() |
ef51f543a3 | ||
![]() |
4eda2aa36d | ||
![]() |
a35892da4f | ||
![]() |
23b567e11b | ||
![]() |
abdbf2cb8a | ||
![]() |
ca97ac11e1 | ||
![]() |
8f0a7f56e2 | ||
![]() |
0a61971d29 | ||
![]() |
7b335fb62e | ||
![]() |
a6f21c2b91 | ||
![]() |
e74378a8ac | ||
![]() |
ec67ee946a | ||
![]() |
c5e8a52205 | ||
![]() |
78dd0e6ddc | ||
![]() |
cfea52f570 | ||
![]() |
2d88982729 | ||
![]() |
148a3c4cf7 | ||
![]() |
533b55bb68 | ||
![]() |
5b85fe9293 | ||
![]() |
1ac126fb7a | ||
![]() |
b5e3323a93 | ||
![]() |
8f6d148481 | ||
![]() |
671a892b52 | ||
![]() |
5c25c5563a | ||
![]() |
8b05eeaa59 | ||
![]() |
1b001cf1e8 | ||
![]() |
855bad2f40 | ||
![]() |
b6d9407246 | ||
![]() |
957687ed39 | ||
![]() |
db86cfa7d9 | ||
![]() |
afa95172b6 | ||
![]() |
2e0843c226 | ||
![]() |
b312901705 | ||
![]() |
16028b51c7 | ||
![]() |
c8091c61c0 | ||
![]() |
5d9018aeec | ||
![]() |
cf686c445c | ||
![]() |
0478e4217b | ||
![]() |
f11d1a6fa1 | ||
![]() |
9dc6668e8a | ||
![]() |
527aea9264 | ||
![]() |
056f321ee6 | ||
![]() |
e679556975 | ||
![]() |
e9f4ac7425 | ||
![]() |
c6502fb03b | ||
![]() |
83b7163844 | ||
![]() |
c33533082c | ||
![]() |
5dd392127f | ||
![]() |
9c150eec4e | ||
![]() |
c25a3cf1c1 | ||
![]() |
b9ad9ba674 | ||
![]() |
92ac7d7c24 | ||
![]() |
8e27318eda | ||
![]() |
976d16b0db | ||
![]() |
1cee9828b0 | ||
![]() |
2c7f00bac1 | ||
![]() |
484b24d097 | ||
![]() |
e93cc85e9b | ||
![]() |
615381f8e7 | ||
![]() |
b01f7e1d54 | ||
![]() |
f29e1e2ee0 | ||
![]() |
ec4be237b5 | ||
![]() |
6249c90bc9 | ||
![]() |
69efac3634 | ||
![]() |
77b68ec12e | ||
![]() |
c818dbb5a0 | ||
![]() |
9753578903 | ||
![]() |
5abedab095 | ||
![]() |
31576f8f55 | ||
![]() |
31a2b2ca3c | ||
![]() |
27cc737fe1 | ||
![]() |
064700be36 | ||
![]() |
343277e387 | ||
![]() |
363b878a24 | ||
![]() |
69c7d31e69 | ||
![]() |
e5bd0e6dc7 | ||
![]() |
3b41ba9dd9 | ||
![]() |
17b4c98db1 | ||
![]() |
04d55f60ea | ||
![]() |
86f430f61b | ||
![]() |
c6511ed829 | ||
![]() |
047760ad4b | ||
![]() |
b7c4b66b61 | ||
![]() |
67bb5ffa73 | ||
![]() |
a671576578 | ||
![]() |
1ee4b964e2 | ||
![]() |
cb7d05bd53 | ||
![]() |
16f3338b3d | ||
![]() |
0a567a3ef9 | ||
![]() |
660e0f3d8b | ||
![]() |
ee766ec88e | ||
![]() |
63096a5c26 | ||
![]() |
b5b714861d | ||
![]() |
5c2d416a34 | ||
![]() |
0515375cfa | ||
![]() |
6d20ccccd0 | ||
![]() |
6dce255393 | ||
![]() |
402d4bdee1 | ||
![]() |
123fba5b07 | ||
![]() |
f506c795d6 | ||
![]() |
5fd803d479 | ||
![]() |
1241664d8d | ||
![]() |
3e6efb663b | ||
![]() |
cd907ff430 | ||
![]() |
724189e4ef | ||
![]() |
4bb0da0ce6 | ||
![]() |
666e587114 | ||
![]() |
3e9e5acdab | ||
![]() |
40d10ea741 | ||
![]() |
231aaedec8 | ||
![]() |
d86a4b15c1 | ||
![]() |
03abeacea4 | ||
![]() |
99169398b7 | ||
![]() |
24600355c8 | ||
![]() |
db2a21cea1 | ||
![]() |
95967151ae | ||
![]() |
f2137e4cdd | ||
![]() |
bba6bb6255 | ||
![]() |
7d7bc9782b | ||
![]() |
5667694652 | ||
![]() |
4cb0b9174b | ||
![]() |
7493031d11 | ||
![]() |
e64d2dcada | ||
![]() |
f057bd1e89 | ||
![]() |
1e7e719dbf | ||
![]() |
5b6e9747b7 | ||
![]() |
803c12877c | ||
![]() |
db5be3c28a | ||
![]() |
434a033411 | ||
![]() |
fd2ee3e109 | ||
![]() |
0816591cf9 | ||
![]() |
836d02d0b9 | ||
![]() |
b951d506d9 | ||
![]() |
ec5627a44c | ||
![]() |
333a13269c | ||
![]() |
e0a70bd352 | ||
![]() |
fe913ec10f | ||
![]() |
50899b845d | ||
![]() |
3e6396cc4b | ||
![]() |
a8d9b269ff | ||
![]() |
df7dc21893 | ||
![]() |
750c74eea7 | ||
![]() |
2f7da8b577 | ||
![]() |
5e52138861 | ||
![]() |
e2dba9e9b8 | ||
![]() |
c79fcf7ad5 | ||
![]() |
c6abc43ca5 | ||
![]() |
2c1913af23 | ||
![]() |
ed3d15501a | ||
![]() |
fef85cf259 | ||
![]() |
00be016979 | ||
![]() |
9290aa2b61 | ||
![]() |
977491ef8d | ||
![]() |
86fcbf9c5e | ||
![]() |
e081e4c9c6 | ||
![]() |
357e738983 | ||
![]() |
7242a98adb | ||
![]() |
6974892a11 | ||
![]() |
ee0cb8793f | ||
![]() |
0cfd3c7e02 | ||
![]() |
23693bd57e | ||
![]() |
d742211797 | ||
![]() |
9191663a1a | ||
![]() |
b3dd2a4282 | ||
![]() |
f51596eb61 | ||
![]() |
c1d252afe0 | ||
![]() |
c3f03e4497 | ||
![]() |
9e67de8a9f | ||
![]() |
6f09b14f44 | ||
![]() |
d78b33ca75 | ||
![]() |
fa9cf2b345 | ||
![]() |
b2c833b879 | ||
![]() |
96516d6dd5 | ||
![]() |
7071cd7381 | ||
![]() |
0a7b8840a4 | ||
![]() |
f272cff7f6 | ||
![]() |
6ede0f6166 | ||
![]() |
c44ff8a70f | ||
![]() |
d2eb507e7d | ||
![]() |
fa04e3de75 | ||
![]() |
63184d53c1 | ||
![]() |
1dfff7ac0e | ||
![]() |
6c84544521 | ||
![]() |
91651ca6ce | ||
![]() |
6fd790570a | ||
![]() |
b322a964ca | ||
![]() |
20b35cbe13 | ||
![]() |
d169641c99 | ||
![]() |
856591d253 | ||
![]() |
4587f5a73d | ||
![]() |
10057217cb | ||
![]() |
0c66e1b5b9 | ||
![]() |
4800460e07 | ||
![]() |
67ee649d99 | ||
![]() |
57b780a0d7 | ||
![]() |
19d9dd6954 | ||
![]() |
e298351caa | ||
![]() |
752a12bda4 | ||
![]() |
afeb3b53c9 | ||
![]() |
8ce658416b | ||
![]() |
6e846ac3e5 | ||
![]() |
ec298185a3 | ||
![]() |
58df72984f | ||
![]() |
5bfddcc444 | ||
![]() |
a99b31a61d | ||
![]() |
8a8b7bd48c | ||
![]() |
1d04c7e1fe | ||
![]() |
9f1c37ecb3 | ||
![]() |
8e8651a0e1 | ||
![]() |
a8e9f21035 | ||
![]() |
997cdfffb4 | ||
![]() |
5a9c57ec0f | ||
![]() |
418ac501aa | ||
![]() |
12b58a17e1 | ||
![]() |
7ca9df9357 | ||
![]() |
f912f8582d | ||
![]() |
a211b6d55d | ||
![]() |
c84c154603 | ||
![]() |
f903090e0f | ||
![]() |
901df242b7 | ||
![]() |
9dbb3767e2 | ||
![]() |
5565d36ef2 | ||
![]() |
48f8c3f85a | ||
![]() |
a3eef7298e | ||
![]() |
7d3578b31a | ||
![]() |
2914d4975b | ||
![]() |
2a0fcd99e4 | ||
![]() |
d7e0e4afc5 | ||
![]() |
de78bb5ffe | ||
![]() |
9ecee6b163 | ||
![]() |
e25e8af135 | ||
![]() |
4ab2fed8d2 | ||
![]() |
3e8fea6533 | ||
![]() |
a57b90809b | ||
![]() |
b097b8bb34 | ||
![]() |
349aeb5a26 | ||
![]() |
e8aebb00ee | ||
![]() |
6ece2838bd | ||
![]() |
bcd3aa7d61 | ||
![]() |
aca80726d7 | ||
![]() |
2fc5745c58 | ||
![]() |
ba2f2cb284 | ||
![]() |
ac2a4b54e7 | ||
![]() |
9326e91832 | ||
![]() |
06aa4a5c07 | ||
![]() |
80c7c9a86e | ||
![]() |
0fdddfe548 | ||
![]() |
42d66fd3d9 | ||
![]() |
ae8dde981b | ||
![]() |
228b832bed | ||
![]() |
8035572fac | ||
![]() |
7fcccb4ab2 | ||
![]() |
b80bad0a93 | ||
![]() |
f87c503d5e | ||
![]() |
568c0318be | ||
![]() |
5903b33016 | ||
![]() |
47bad33949 | ||
![]() |
fb79b133e9 | ||
![]() |
ad1763a8f2 | ||
![]() |
97e26686f4 | ||
![]() |
f476002691 | ||
![]() |
a4992963b3 | ||
![]() |
44ff608868 | ||
![]() |
f2ea725edb | ||
![]() |
40a87fa736 | ||
![]() |
a5627f97ff | ||
![]() |
8b1698b17d | ||
![]() |
f8da3c2e48 | ||
![]() |
03f9264394 | ||
![]() |
33da5bcee1 | ||
![]() |
01541a3dc1 | ||
![]() |
13ec3f6c0d | ||
![]() |
a949c2aaec | ||
![]() |
f4324d1de6 | ||
![]() |
f1d2808594 | ||
![]() |
52d0605066 | ||
![]() |
015b976c28 | ||
![]() |
b777c8de15 | ||
![]() |
93201b2ded | ||
![]() |
234d39cf96 | ||
![]() |
9913bf654b | ||
![]() |
2d560861df | ||
![]() |
24786c643b | ||
![]() |
3b4e48e32f | ||
![]() |
45b81a9db9 | ||
![]() |
500dea182f | ||
![]() |
274e9f3e42 | ||
![]() |
cf589f713d | ||
![]() |
07d881cd5e | ||
![]() |
0d0f793f81 | ||
![]() |
23dfe1e8a9 | ||
![]() |
a8e49a0d2d | ||
![]() |
594847ba04 | ||
![]() |
f3fcfb635b | ||
![]() |
011220180c | ||
![]() |
3e9215b27d | ||
![]() |
6ce2dfeaec | ||
![]() |
9176237361 | ||
![]() |
9b65abe76a | ||
![]() |
d6085fcdb9 | ||
![]() |
259d2a9b5c | ||
![]() |
f62736c749 | ||
![]() |
7ef1b28c83 | ||
![]() |
7df9dea72a | ||
![]() |
2a061fba07 | ||
![]() |
93aa575697 | ||
![]() |
8a20a71906 | ||
![]() |
37076d3d1f | ||
![]() |
acf11bdc6c | ||
![]() |
d222196fd1 | ||
![]() |
6f43082e38 | ||
![]() |
964bc4dc12 | ||
![]() |
ecf7870b3e | ||
![]() |
30fcab1c63 | ||
![]() |
edde501d54 | ||
![]() |
35c0e2cea2 | ||
![]() |
5cf061cb32 | ||
![]() |
5b6dfb01a6 | ||
![]() |
a0b589979d | ||
![]() |
0d0cdd0542 | ||
![]() |
297fa7a069 | ||
![]() |
2ed515091f | ||
![]() |
b093f9fd41 | ||
![]() |
fde6396f48 | ||
![]() |
11250290a2 | ||
![]() |
be33c41a40 | ||
![]() |
e20528ab0d | ||
![]() |
a40d89ba0d | ||
![]() |
c0c7c96f28 | ||
![]() |
003e5575b9 | ||
![]() |
d904574ea8 | ||
![]() |
cbb884edae | ||
![]() |
0a7829fcfe | ||
![]() |
7c970d6ff0 | ||
![]() |
048b39ae16 | ||
![]() |
bb9d5e38fa | ||
![]() |
bb365ca1b5 | ||
![]() |
53b97b3ffa | ||
![]() |
9c101eb8af | ||
![]() |
c251270633 | ||
![]() |
dfb1095908 | ||
![]() |
cf2b415cd3 | ||
![]() |
e9f3ad63c6 | ||
![]() |
6a9bd22904 | ||
![]() |
ebbf3bfa77 | ||
![]() |
661aaead35 | ||
![]() |
197671960d | ||
![]() |
e434ac9a1f | ||
![]() |
388ec2cd97 | ||
![]() |
1d7589abb9 | ||
![]() |
da47ba11f8 | ||
![]() |
eaa572aafe | ||
![]() |
d4ac9f8114 | ||
![]() |
4bc2f4d26d | ||
![]() |
7dd174642c | ||
![]() |
89f3de169c | ||
![]() |
bc04bb28fe | ||
![]() |
9df8d319c3 | ||
![]() |
3f55200737 | ||
![]() |
204b029973 | ||
![]() |
3fbe3a3078 | ||
![]() |
8848203d90 | ||
![]() |
8edd89c665 | ||
![]() |
c78d623e93 | ||
![]() |
b093fc8a55 | ||
![]() |
7e01b2b3fb | ||
![]() |
26eaaa8c79 | ||
![]() |
8cd0e3bb05 | ||
![]() |
e0f74690b0 | ||
![]() |
8db7d73dc0 | ||
![]() |
48ef5d74e8 | ||
![]() |
18117af067 | ||
![]() |
b418642359 | ||
![]() |
6a2f62a084 | ||
![]() |
1ec262becf | ||
![]() |
6cd5ffe637 | ||
![]() |
20b43d8ad1 | ||
![]() |
f16143de7c | ||
![]() |
daba43dcba | ||
![]() |
7c74107f36 | ||
![]() |
2e0bfaeb74 | ||
![]() |
d31e03d04e | ||
![]() |
8da5f26452 | ||
![]() |
d6e22d5f5e | ||
![]() |
c52f4d6307 | ||
![]() |
77f1a8ecac | ||
![]() |
a4348f1963 | ||
![]() |
fe0434cb16 | ||
![]() |
a6f992ce5b | ||
![]() |
04fc5e51fc | ||
![]() |
d430019b44 | ||
![]() |
72493b7a8b | ||
![]() |
0a828ee67f | ||
![]() |
385454f3f1 | ||
![]() |
f0ff4d087f | ||
![]() |
89081ea169 | ||
![]() |
e3d753da76 | ||
![]() |
1e89aa7d92 | ||
![]() |
f979d941b6 | ||
![]() |
b1dffc9eec | ||
![]() |
5424092189 | ||
![]() |
bfa8f75d3b | ||
![]() |
75d9e7bc59 | ||
![]() |
c5a7eeaa0f | ||
![]() |
4947c75ff7 | ||
![]() |
d07a7f505b | ||
![]() |
7ab5dac5c7 | ||
![]() |
4fc082b526 | ||
![]() |
2a0bc3b2e8 | ||
![]() |
a7d79baf00 | ||
![]() |
c9442653e9 | ||
![]() |
969faf91fe | ||
![]() |
8fe218676a | ||
![]() |
f6b518ed49 | ||
![]() |
c53c679c6b | ||
![]() |
2d91daf858 | ||
![]() |
a5b7145527 | ||
![]() |
ee912c2b29 | ||
![]() |
bdf9b33b10 | ||
![]() |
167368d508 | ||
![]() |
bb534225b3 | ||
![]() |
ab69dacc6d | ||
![]() |
8c2690e01f | ||
![]() |
57db10a4c0 | ||
![]() |
fc5c07027c | ||
![]() |
5da8c26cb6 | ||
![]() |
626fdfe345 | ||
![]() |
c071503f19 | ||
![]() |
873f7a591b | ||
![]() |
e0f5f10215 | ||
![]() |
11a949b78e | ||
![]() |
81007f841a | ||
![]() |
84f592c417 | ||
![]() |
1e3b61a188 | ||
![]() |
baeeedcc16 | ||
![]() |
70763fd13b | ||
![]() |
21c91a8408 | ||
![]() |
07af7123c9 | ||
![]() |
3fbb5f08b8 | ||
![]() |
973f5b2591 | ||
![]() |
64b5880444 | ||
![]() |
81132bf0ed | ||
![]() |
a9c23f205b | ||
![]() |
801d1e9eda | ||
![]() |
15977695cd | ||
![]() |
e0d578920a | ||
![]() |
b6c75c8d62 | ||
![]() |
e4cb1dcbfd | ||
![]() |
ceb8430f9b | ||
![]() |
2565b47637 | ||
![]() |
73eb98c4c3 | ||
![]() |
8c7e8b7a6c | ||
![]() |
894616bef9 | ||
![]() |
1cfd6b67b3 | ||
![]() |
5e4d8a1034 | ||
![]() |
00785daac9 | ||
![]() |
12bfc9570a |
2
.ackrc
2
.ackrc
@@ -1,2 +1,4 @@
|
||||
--ignore-dir=dist
|
||||
--ignore-file=match:/^yarn\.lock$/
|
||||
--ignore-file=match:/^yarn-error\.log$/
|
||||
--ignore-dir=coverage
|
||||
|
@@ -1,14 +0,0 @@
|
||||
engines:
|
||||
duplication:
|
||||
enabled: true
|
||||
config:
|
||||
languages:
|
||||
- javascript
|
||||
eslint:
|
||||
enabled: true
|
||||
ratings:
|
||||
paths:
|
||||
- "**.js"
|
||||
exclude_paths:
|
||||
- node_modules/
|
||||
- dist/
|
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
**/*.spec.js
|
19
.eslintrc.json
Normal file
19
.eslintrc.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": true
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": ["prettier", "eslint:recommended"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"prettier/prettier": ["error"]
|
||||
}
|
||||
}
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
*.js text eol=lf
|
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [knsv]
|
||||
#patreon: # Replace with a single Patreon username
|
||||
#open_collective: # Replace with a single Open Collective username
|
||||
#ko_fi: # Replace with a single Ko-fi username
|
||||
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
#liberapay: # Replace with a single Liberapay username
|
||||
#issuehunt: # Replace with a single IssueHunt username
|
||||
#otechie: # Replace with a single Otechie username
|
||||
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Bug / Error'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
15
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: Question
|
||||
about: Get some help from the community.
|
||||
title: ''
|
||||
labels: 'Help wanted!, Type: Other'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Help us help you!
|
||||
You want an answer. Here are some ways to get it quicker:
|
||||
* Use a clear and concise title.
|
||||
* Try to pose a clear and concise question.
|
||||
* Include as much, or as little, code as necessary.
|
||||
* Don't be shy to give us some screenshots, if it helps!
|
3
.github/pr-labeler.yml
vendored
Normal file
3
.github/pr-labeler.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
'Type: Bug / Error': 'bug/*'
|
||||
'Type: Enhancement': 'feature/*'
|
||||
'Type: Other': 'other/*'
|
13
.github/pull_request_template.md
vendored
Normal file
13
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
## :bookmark_tabs: Summary
|
||||
Brief description about the content of your PR.
|
||||
|
||||
Resolves #<your issue id here>
|
||||
|
||||
## :straight_ruler: Design Decisions
|
||||
Describe the way your implementation works or what design decisions you made if applicable.
|
||||
|
||||
### :clipboard: Tasks
|
||||
Make sure you
|
||||
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] :computer: have added unit/e2e tests (if appropriate)
|
||||
- [ ] :bookmark: targeted `develop` branch
|
25
.github/release-drafter.yml
vendored
Normal file
25
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name-template: '$NEXT_PATCH_VERSION'
|
||||
tag-template: '$NEXT_PATCH_VERSION'
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'Type: Enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
labels:
|
||||
- 'Type: Bug / Error'
|
||||
- title: '🧰 Maintenance'
|
||||
label: 'Type: Other'
|
||||
change-template: '- $TITLE (#$NUMBER) @$AUTHOR'
|
||||
sort-by: title
|
||||
sort-direction: ascending
|
||||
branches:
|
||||
- develop
|
||||
exclude-labels:
|
||||
- 'Skip changelog'
|
||||
no-changes-template: 'This release contains minor changes and bugfixes.'
|
||||
template: |
|
||||
# Release Notes
|
||||
|
||||
$CHANGES
|
||||
|
||||
🎉 **Thanks to all contributors helping with this release!** 🎉
|
19
.github/stale.yml
vendored
Normal file
19
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Retained
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Inactive
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
If you are still interested in this issue and it is still relevant you can comment to revive it.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been been automatically closed due to a lack of activity.
|
||||
This is done to maintain a clean list of issues that the community is interested in developing.
|
64
.github/workflows/build.yml
vendored
Normal file
64
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Cache Node Modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: .cache
|
||||
key: ${{ runner.OS }}-build-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn config set cache-folder $GITHUB_WORKSPACE/.cache/yarn
|
||||
yarn install --frozen-lockfile
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Build
|
||||
run: yarn build
|
||||
|
||||
- name: Upload Build as Artifact
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
|
||||
- name: Run Unit Tests
|
||||
run: |
|
||||
yarn test --coverage
|
||||
|
||||
#- name: Upload Test Results
|
||||
# uses: coverallsapp/github-action@v1.0.1
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# parallel: true
|
||||
|
||||
# - name: Run E2E Tests
|
||||
# run: yarn e2e
|
||||
# env:
|
||||
# PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
|
||||
# CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
#- name: Post Upload Test Results
|
||||
# uses: coverallsapp/github-action@master
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# parallel-finished: true
|
19
.github/workflows/checks
vendored
Normal file
19
.github/workflows/checks
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on: [push]
|
||||
|
||||
name: Static analysis
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: check tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: testomatio/check-tests@stable
|
||||
with:
|
||||
framework: cypress
|
||||
tests: "./cypress/integration/**/**.spec.js"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
has-tests-label: true
|
||||
|
14
.github/workflows/issue-triage.yml
vendored
Normal file
14
.github/workflows/issue-triage.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Apply triage label to new issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: andymckay/labeler@1.0
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
labels: "Status: Triage"
|
13
.github/workflows/lock-closed-issue.yml
vendored
Normal file
13
.github/workflows/lock-closed-issue.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Lock closed issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Dunning-Kruger/lock-issues@v1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
13
.github/workflows/pr-labeler.yml
vendored
Normal file
13
.github/workflows/pr-labeler.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Apply labels to PR
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
pr-labeler:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Label PR
|
||||
uses: TimonVS/pr-labeler-action@v3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
15
.github/workflows/release-draft.yml
vendored
Normal file
15
.github/workflows/release-draft.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Draft Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
draft-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Draft Release
|
||||
uses: toolmantim/release-drafter@v5.2.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
37
.github/workflows/release-preview-publish.yml
vendored
Normal file
37
.github/workflows/release-preview-publish.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Publish release preview package
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'release/**'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10.x
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Json
|
||||
run: npm i json --global
|
||||
|
||||
- name: Install Packages
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Publish
|
||||
run: |
|
||||
PREVIEW_VERSION=$(git rev-list --count --first-parent HEAD)
|
||||
VERSION=$(echo ${{github.ref}} | tail -c +20)-preview.$PREVIEW_VERSION
|
||||
echo $VERSION
|
||||
npm version --no-git-tag-version --allow-same-version $VERSION
|
||||
npm set //npm.pkg.github.com/:_authToken ${{ secrets.GITHUB_TOKEN }}
|
||||
npm set registry https://npm.pkg.github.com/mermaid-js
|
||||
json -I -f package.json -e 'this.name="@mermaid-js/mermaid"' # Package name needs to be set to a scoped one because GitHub registry requires this
|
||||
json -I -f package.json -e 'this.repository="git://github.com/mermaid-js/mermaid"' # Repo url needs to have a specific format too
|
||||
npm publish
|
||||
|
46
.github/workflows/release-publish.yml
vendored
Normal file
46
.github/workflows/release-publish.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Publish release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: fregante/setup-git-token@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10.x
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Json
|
||||
run: npm i json --global
|
||||
|
||||
- name: Install Packages
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Prepare release
|
||||
run: |
|
||||
VERSION=${GITHUB_REF:10}
|
||||
echo "Preparing release $VERSION"
|
||||
git checkout -t origin/release/$VERSION
|
||||
npm version --no-git-tag-version --allow-same-version $VERSION
|
||||
git add package.json
|
||||
git commit -m "Bump version $VERSION"
|
||||
git checkout -t origin/master
|
||||
git merge -m "Release $VERSION" --no-ff release/$VERSION
|
||||
git push --no-verify
|
||||
|
||||
- name: Publish
|
||||
run: |
|
||||
npm set //registry.npmjs.org/:_authToken $NPM_TOKEN
|
||||
npm publish
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
13
.github/workflows/unlock-reopened-issues.yml
vendored
Normal file
13
.github/workflows/unlock-reopened-issues.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Unlock reopened issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [reopened]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Dunning-Kruger/unlock-issues@v1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
28
.gitignore
vendored
28
.gitignore
vendored
@@ -1,15 +1,19 @@
|
||||
node_modules
|
||||
bower_components
|
||||
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
.DS_Store
|
||||
.idea
|
||||
coverage
|
||||
|
||||
test/tmp_*
|
||||
test/fixtures/samples/*.actual*
|
||||
node_modules/
|
||||
coverage/
|
||||
.idea/
|
||||
|
||||
dist/*.js
|
||||
dist/*.css
|
||||
yarn-error.log
|
||||
.npmrc
|
||||
token
|
||||
|
||||
package-lock.json
|
||||
|
||||
dist/classTest.html
|
||||
|
||||
dist/sequenceTest.html
|
||||
|
||||
.vscode/
|
||||
cypress/platform/current.html
|
||||
cypress/platform/experimental.html
|
3
.percy.yml
Normal file
3
.percy.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
version: 1
|
||||
snapshot:
|
||||
widths: [1280]
|
4
.prettierrc
Normal file
4
.prettierrc
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"singleQuote": true
|
||||
}
|
22
.tern-project
Normal file
22
.tern-project
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"ecmaVersion": 6,
|
||||
"libs": [
|
||||
"browser"
|
||||
],
|
||||
"loadEagerly": [
|
||||
"path/to/your/js/**/*.js"
|
||||
],
|
||||
"dontLoad": [
|
||||
"node_modules/**",
|
||||
"path/to/your/js/**/*.js"
|
||||
],
|
||||
"plugins": {
|
||||
"modules": {},
|
||||
"es_modules": {},
|
||||
"node": {},
|
||||
"doc_comment": {
|
||||
"fullDocs": true,
|
||||
"strong": true
|
||||
}
|
||||
}
|
||||
}
|
23
.travis.yml
23
.travis.yml
@@ -1,19 +1,12 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
addons:
|
||||
chrome: stable
|
||||
code_climate:
|
||||
repo_token: e87e6bf1c253e0555437ebd23235fdfe2749b889358e7c6d100e4ea5b4f2e091
|
||||
language: node_js
|
||||
node_js:
|
||||
- "8"
|
||||
before_install:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start &
|
||||
- sleep 3
|
||||
before_script:
|
||||
- yarn build
|
||||
- "10"
|
||||
cache:
|
||||
npm: false
|
||||
script:
|
||||
- yarn test
|
||||
after_script:
|
||||
- cat coverage/lcov.info | codeclimate
|
||||
- yarn build
|
||||
- yarn test --coverage
|
||||
- yarn e2e
|
||||
after_success:
|
||||
- cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
|
||||
|
807
CHANGELOG.md
807
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
124
CONTRIBUTING.md
124
CONTRIBUTING.md
@@ -1,88 +1,98 @@
|
||||
# How to contribute
|
||||
# Contributing
|
||||
|
||||
Great that you want to be involved in this project! Contributing is fun and contributions are GREAT! :)
|
||||
So you want to help? That's great!
|
||||
|
||||
This page is currently a starting point and is not so rigorous to start with.
|
||||

|
||||
|
||||
Some important guidlines:
|
||||
Here are a few things to know to get you started on the right path.
|
||||
|
||||
* The work will be organized using the issues list
|
||||
* In the list there will be the bugs/enhancements etc we are working with in the project
|
||||
* There will be milestones outlineing the roadmap ahead
|
||||
* There will issues marked with help wanted
|
||||
## Committing code
|
||||
|
||||
The issue list and the items marked with **help wanted** is a good starting point if you want to do some work.
|
||||
We make all changes via pull requests. As we have many pull requests from developers new to mermaid, the current approach is to have *knsv, Knut Sveidqvist* as a main reviewer of changes and merging pull requests. More precisely like this:
|
||||
|
||||
* Large changes reviewed by knsv or other developer asked to review by knsv
|
||||
* Smaller low-risk changes like dependecies, documentation etc can be merged by active collaborators
|
||||
* documentation (updates to the docs folder is also allowed via direct commits)
|
||||
|
||||
## Guidelines for avoiding duplicate work
|
||||
To commit code, create a branch, let it start with the type like feature or bug followed by the issue number for reference and some describing text.
|
||||
|
||||
Contributing is great. It is not so fun when you are done with your issue and just before you're about to push your
|
||||
change you can't because someone else just pushed the same fix so you have wasted your time. The guidelines below are in
|
||||
place to prevent this:
|
||||
One example:
|
||||
|
||||
* Comment in the issue that you are working on it. You will then be added as an assignee (eventually).
|
||||
* When you pick an issue to work on.
|
||||
* Check that the issue not assigned
|
||||
* Also check the comments so that no one has started working on it before beeing officially assigned.
|
||||
`feature/945_state_diagrams`
|
||||
|
||||
Another:
|
||||
|
||||
## Submitting changes
|
||||
`bug/123_nasty_bug_branch`
|
||||
|
||||
Please send a GitHub Pull Request with a clear list of what you've done (read more about pull requests). When you send
|
||||
a pull request, we will love you forever if you include jasmine tests. We can always use more test coverage.
|
||||
## Committing documentation
|
||||
|
||||
Always write a clear log message for your commits. One-line messages are fine for small changes, but bigger changes should look like this:
|
||||
Less strict here, it is ok to commit directly in the develop branch if you are a collaborator.
|
||||
|
||||
$ git commit -m "A brief summary of the commit
|
||||
>
|
||||
> A paragraph describing what changed and its impact."
|
||||
Coding conventions
|
||||
Start reading our code and you'll get the hang of it. We optimize for readability:
|
||||
## Branching
|
||||
|
||||
This is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of
|
||||
like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as
|
||||
smooth as possible.
|
||||
Going forward we will use a git flow inspired approach to branching. So development is done in develop, to do the development in the develop.
|
||||
|
||||
So that we can consistently serve images from the CDN, always use image_path or image_tag when referring to images.
|
||||
Never prepend "/images/" when using image_path or image_tag.
|
||||
Also for the CDN, always use cwd-relative paths rather than root-relative paths in image URLs in any CSS. So instead of
|
||||
url('/images/blah.gif'), use url('../images/blah.gif').
|
||||
Once development is done we branch a release branch from develop for testing.
|
||||
|
||||
# Build instructions
|
||||
Once the release happens we merge the release branch to master and kill the release branch.
|
||||
|
||||
Fork, then:
|
||||
This means... **branch off your pull request from develop**
|
||||
|
||||
## Content of a pull request
|
||||
|
||||
A new feature has been born. Great! But without the steps below it might just ... fade away ...
|
||||
|
||||
### **Add unit tests for the parsing part**
|
||||
|
||||
This is important so that, if someone else does a change to the grammar that does not know about this great feature, gets notified early on when that change breaks the parser. Another important aspect is that without proper parsing tests refactoring is pretty much impossible.
|
||||
|
||||
### **Add e2e tests**
|
||||
|
||||
This tests the rendering and visual apearance of the diagram. This ensures that the rendering of that feature in the e2e will be reviewed in the release process going forward. Less chance that it breaks!
|
||||
|
||||
To start working with the e2e tests, run `yarn dev` to start the dev server, after that start cypress by running `cypress open` in the mermaid folder. (Make sure you have path to cypress in order, the binary is located in node_modules/.bin).
|
||||
|
||||
The rendering tests are very straightforward to create. There is a function imgSnapshotTest. This function takes a diagram in text form, the mermaid options and renders that diagram in cypress.
|
||||
|
||||
When running in ci it will take a snapshot of the rendered diagram and compare it with the snapshot from last build and flag for review it if it differs.
|
||||
|
||||
This is what a rendering test looks like:
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
it('should render forks and joins', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
fork_state --> State2
|
||||
fork_state --> State3
|
||||
|
||||
Then the dependencies will have been installed. You use gulp and yarn calls as build tools.
|
||||
state join_state <<join>>
|
||||
State2 --> join_state
|
||||
State3 --> join_state
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
```
|
||||
|
||||
The following targets are probably interesting:
|
||||
|
||||
* jison - compiles the jison grammars to parser files
|
||||
### **Add documentation for it**
|
||||
|
||||
for instance:
|
||||
```
|
||||
gulp jison
|
||||
```
|
||||
Finally, if it is not in the documentation, no one will know about it and then **no one will use it**. Wouldn't that be sad? With all the effort that was put into the feature?
|
||||
|
||||
To build:
|
||||
The docs are located in the docs folder and are ofc written in markdown. Just pick the right section and start typing. If you want to add to the structure as in adding a new section and new file you do that via the _navbar.md.
|
||||
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
The changes in master is reflected in http://mermaid-js.github.io/mermaid/ once released the updates are commited to https://mermaid-js.github.io/#/
|
||||
|
||||
To run the tests:
|
||||
## Last words
|
||||
|
||||
```
|
||||
yarn test
|
||||
```
|
||||
Don't get daunted if it is hard in the beginning. We have a great community with only encouraging words. So if you get stuck, ask for help and hints in the slack forum. If you want to show off something good, show it off there.
|
||||
|
||||
Make sure you have Chrome browser installed. We use Chrome headless for testing.
|
||||
[Join our slack community if you want closer contact!](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
|
||||
Manual test:
|
||||
|
||||
```
|
||||
open dist/demo/index.html
|
||||
```
|
||||

|
||||
|
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Knut Sveidqvist
|
||||
Copyright (c) 2014 - 2018 Knut Sveidqvist
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
435
README.md
435
README.md
@@ -1,238 +1,237 @@
|
||||
# mermaid
|
||||
<!-- <Remove this in the future> -->
|
||||
| :mega: :mega: :mega: |
|
||||
| :----: |
|
||||
| * If you're upgrading from a version __< v8.2.0__, there are [non-backward-compatible changes](http://mermaid-js.github.io/mermaid/#/usage?id=to-enable-click-event-and-tags-in-nodes) related to security issues. Default behaviour of the library might have changed for your implementation.|
|
||||
<!-- </Remove this in the future> -->
|
||||
|
||||
[](https://travis-ci.org/knsv/mermaid)
|
||||
[](https://codeclimate.com/github/knsv/mermaid)
|
||||
[](https://gitter.im/knsv/mermaid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# mermaid [](https://travis-ci.org/mermaid-js/mermaid) [](https://www.npmjs.com/package/mermaid) [](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [](https://percy.io/Mermaid/mermaid)
|
||||
|
||||

|
||||
<!-- <Main description> -->
|
||||
__mermaid is a Javascript based diagramming and charting tool. It generates diagrams flowcharts and more, using markdown-inspired text for ease and speed.__
|
||||
|
||||
Generation of diagrams and flowcharts from text in a similar manner as markdown.
|
||||
Check out the list of [Integrations and Usages of Mermaid](https://github.com/mermaid-js/mermaid/blob/develop/docs/integrations.md)
|
||||
|
||||
Ever wanted to simplify documentation and avoid heavy tools like Visio when explaining your code?
|
||||
For more information and help in getting started, please view our [documentation](http://mermaid-js.github.io/mermaid/) and start simplifying yours. Alternatively, you can also play with our [live editor](https://mermaidjs.github.io/mermaid-live-editor/).
|
||||
<!-- </Main description> -->
|
||||
|
||||
This is why mermaid was born, a simple markdown-like script language for generating charts from text via javascript.
|
||||
:trophy: **Mermaid was nominated and won the [JS Open Source Awards (2019)](https://osawards.com/javascript/#nominees) in the category "The most exciting use of technology"!!! Thanks to all involved, people committing pull requests, people answering questions and special thanks to Tyler Long who is helping me maintain the project.**
|
||||
|
||||
The code below would render the following image
|
||||
## New diagram
|
||||
|
||||
This version comes with a new diagram type, user journey diagrams.
|
||||
|
||||
## New diagrams in 8.4
|
||||
|
||||
With version 8.4 class diagrams have got some new features, bug fixes and documentation. Another new feature in 8.4 is the new diagram type, state diagrams.
|
||||
|
||||

|
||||
|
||||
## Special note regarding version 8.2
|
||||
|
||||
In version 8.2 a security improvement was introduced. A securityLevel configuration was introduced which sets the level of trust to be used on the parsed diagrams.
|
||||
|
||||
- **true**: (default) tags in text are encoded, click functionality is disabled
|
||||
- false: tags in text are allowed, click functionality is enabled
|
||||
|
||||
Closed issues:
|
||||
|
||||
⚠️ **Note** : This changes the default behaviour of mermaid so that after upgrade to 8.2, if the securityLevel is not configured, tags in flowcharts are encoded as tags and clicking is prohibited.
|
||||
|
||||
If your application is taking resposibility for the diagram source security you can set the securityLevel accordingly. By doing this clicks and tags are again allowed.
|
||||
|
||||
```javascript
|
||||
mermaidAPI.initialize({
|
||||
securityLevel: 'loose'
|
||||
});
|
||||
```
|
||||
|
||||
For more information and help in getting started, please view our [documentation](http://mermaid-js.github.io/mermaid/) and start simplifying yours. Play with our [live editor](https://mermaidjs.github.io/mermaid-live-editor/) or jump straight to the [installation and usage](http://mermaid-js.github.io/mermaid/#/usage).
|
||||
<!-- </Main description> -->
|
||||
|
||||
__The following are some examples of the diagrams, charts and graphs that can be made using mermaid and the Markdown-inspired text specific to it. Click here jump into the [text syntax](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference).__
|
||||
<table>
|
||||
<tr><th>Code</th><th>Rendered diagram</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
<code>
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
</code>
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<p align="center">
|
||||
<img src='./img/flow.png' alt='Flowchart'>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
<code>
|
||||
<!-- <Flowchart> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Flow</b></br>
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/flowchart">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0hhcmRdIC0tPnxUZXh0fCBCKFJvdW5kKVxuICAgIEIgLS0-IEN7RGVjaXNpb259XG4gICAgQyAtLT58T25lfCBEW1Jlc3VsdCAxXVxuICAgIEMgLS0-fFR3b3wgRVtSZXN1bHQgMl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
graph TD
|
||||
A[Hard] -->|Text| B(Round)
|
||||
B --> C{Decision}
|
||||
C -->|One| D[Result 1]
|
||||
C -->|Two| E[Result 2]
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-flow.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Flowchart> -->
|
||||
<!-- <Sequence> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Sequence</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/sequenceDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts <br/>prevail...
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
</code>
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<img src='./img/sequence.png' alt='Sequence Diagram'>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
<code>
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram to mermaid
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
</code>
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<img src='./img/gantt.png' alt='Gantt Diagram'>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
<code>
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class03 *-- Class04
|
||||
Class05 o-- Class06
|
||||
Class07 .. Class08
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
</code>
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<img src='./img/class.png' alt='Class Diagram'>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
<code>
|
||||
gitGraph :
|
||||
options
|
||||
{
|
||||
"key": "value",
|
||||
"nodeWidth": 150,
|
||||
"nodeSpacing" : 150
|
||||
}
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
commit
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit
|
||||
commit
|
||||
checkout master
|
||||
commit
|
||||
commit
|
||||
merge newbranch
|
||||
</code>
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<img src='./img/git.png' alt='Git Graph'>
|
||||
</td>
|
||||
</tr>
|
||||
Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-sequence.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Sequence> -->
|
||||
<!-- <Gantt> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Gantt</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/gantt">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2FudHRcbnNlY3Rpb24gU2VjdGlvblxuQ29tcGxldGVkIDpkb25lLCAgICBkZXMxLCAyMDE0LTAxLTA2LDIwMTQtMDEtMDhcbkFjdGl2ZSAgICAgICAgOmFjdGl2ZSwgIGRlczIsIDIwMTQtMDEtMDcsIDNkXG5QYXJhbGxlbCAxICAgOiAgICAgICAgIGRlczMsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAyICAgOiAgICAgICAgIGRlczQsIGFmdGVyIGRlczEsIDFkXG5QYXJhbGxlbCAzICAgOiAgICAgICAgIGRlczUsIGFmdGVyIGRlczMsIDFkXG5QYXJhbGxlbCA0ICAgOiAgICAgICAgIGRlczYsIGFmdGVyIGRlczQsIDFkIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
gantt
|
||||
section Section
|
||||
Completed :done, des1, 2014-01-06,2014-01-08
|
||||
Active :active, des2, 2014-01-07, 3d
|
||||
Parallel 1 : des3, after des1, 1d
|
||||
Parallel 2 : des4, after des1, 1d
|
||||
Parallel 3 : des5, after des3, 1d
|
||||
Parallel 4 : des6, after des4, 1d
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-gantt.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Gantt> -->
|
||||
<!-- <Class> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Class</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/classDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG5DbGFzczAxIDx8LS0gQXZlcnlMb25nQ2xhc3MgOiBDb29sXG48PGludGVyZmFjZT4-IENsYXNzMDFcbkNsYXNzMDkgLS0-IEMyIDogV2hlcmUgYW0gaT9cbkNsYXNzMDkgLS0qIEMzXG5DbGFzczA5IC0tfD4gQ2xhc3MwN1xuQ2xhc3MwNyA6IGVxdWFscygpXG5DbGFzczA3IDogT2JqZWN0W10gZWxlbWVudERhdGFcbkNsYXNzMDEgOiBzaXplKClcbkNsYXNzMDEgOiBpbnQgY2hpbXBcbkNsYXNzMDEgOiBpbnQgZ29yaWxsYVxuY2xhc3MgQ2xhc3MxMCB7XG4gID4-c2VydmljZT4-XG4gIGludCBpZFxuICBzaXplKClcbn0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-class.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Class> -->
|
||||
<!-- <State> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>State</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
stateDiagram
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-state.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </State> -->
|
||||
<!-- <Pie> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Pie</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/pie">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoicGllXG5cIkRvZ3NcIiA6IDQyLjk2XG5cIkNhdHNcIiA6IDUwLjA1XG5cIlJhdHNcIiA6IDEwLjAxIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td><pre>
|
||||
pie
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-pie.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Pie> -->
|
||||
<!-- <Git> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>Git</b><br />
|
||||
[experimental - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td colspan="2" align="center"><i>Coming soon!</i></td>
|
||||
</tr>
|
||||
<!-- </Git> -->
|
||||
<!-- <Journey> -->
|
||||
<tr><td colspan=2 align="center">
|
||||
<b>User Journey</b><br />
|
||||
[<a href="http://mermaid-js.github.io/mermaid/#/user-journey">docs</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<pre>
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
</pre></td>
|
||||
<td align="center">
|
||||
<img alt="User Journey Diagram" src="img/gray-user-journey.png" />
|
||||
</td>
|
||||
</tr>
|
||||
<!-- </Journey> -->
|
||||
|
||||
</table>
|
||||
|
||||
## Related projects
|
||||
|
||||
## Installation
|
||||
- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli)
|
||||
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
||||
- [HTTP Server](https://github.com/TomWright/mermaid-server)
|
||||
|
||||
### CDN
|
||||
# Contributors [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Help+wanted%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||
|
||||
```
|
||||
https://unpkg.com/mermaid@<version>/dist/
|
||||
```
|
||||
Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
|
||||
|
||||
Replace `<version>` with expected version number.
|
||||
Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
|
||||
|
||||
Example: https://unpkg.com/mermaid@7.0.4/dist/
|
||||
# Appreciation
|
||||
A quick note from Knut Sveidqvist:
|
||||
>*Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!*
|
||||
>*Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.*
|
||||
>*Thank you to [Tyler Long](https://github.com/tylerlong) who has been a collaborator since April 2017.*
|
||||
>
|
||||
>*Thank you to the ever-growing list of [contributors](https://github.com/knsv/mermaid/graphs/contributors) that brought the project this far!*
|
||||
|
||||
### Node.js
|
||||
|
||||
```
|
||||
yarn add mermaid
|
||||
```
|
||||
|
||||
|
||||
## Further reading
|
||||
|
||||
* [Usage](https://mermaidjs.github.io/usage.html)
|
||||
* [Flowchart syntax](https://mermaidjs.github.io/flowchart.html)
|
||||
* [Sequence diagram syntax](https://mermaidjs.github.io/sequenceDiagram.html)
|
||||
* [Mermaid CLI](https://mermaidjs.github.io/mermaidCLI.html)
|
||||
* [Demos](https://mermaidjs.github.io/demos.html)
|
||||
|
||||
|
||||
# Request for assistance
|
||||
|
||||
Things are piling up and I have hard time keeping up. To remedy this
|
||||
it would be great if we could form a core team of developers to cooperate
|
||||
with the future development mermaid.
|
||||
|
||||
As part of this team you would get write access to the repository and would
|
||||
represent the project when answering questions and issues.
|
||||
|
||||
Together we could continue the work with things like:
|
||||
* port the code to es6
|
||||
* adding more typers of diagrams like mindmaps, ert digrams etc
|
||||
* improving existing diagrams
|
||||
|
||||
Don't hesitate to contact me if you want to get involved.
|
||||
|
||||
|
||||
# For contributors
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure you have Chrome browser installed, this project uses Chrome headless to running tests.
|
||||
|
||||
yarn install
|
||||
|
||||
|
||||
## Build
|
||||
|
||||
yarn build
|
||||
|
||||
If you want real time incremental build:
|
||||
|
||||
yarn watch
|
||||
|
||||
|
||||
## Lint
|
||||
|
||||
yarn lint
|
||||
|
||||
We use [JavaScript Standard Style](https://github.com/feross/standard).
|
||||
We recommend you installing [editor plugins](https://github.com/feross/standard#are-there-text-editor-plugins) so you can get real time lint result.
|
||||
|
||||
|
||||
## Test
|
||||
|
||||
yarn test
|
||||
|
||||
Manual test in browser:
|
||||
|
||||
open dist/demo/index.html
|
||||
|
||||
Manual test in Node.js:
|
||||
|
||||
node dist/demo/index.js
|
||||
|
||||
|
||||
## Release
|
||||
|
||||
Update version number in `package.json`.
|
||||
|
||||
npm publish
|
||||
|
||||
Command above generates files into the `dist` folder and publishes them to npmjs.org.
|
||||
|
||||
|
||||
# Credits
|
||||
|
||||
Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!
|
||||
|
||||
Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.
|
||||
---
|
||||
|
||||
*Mermaid was created by Knut Sveidqvist for easier documentation.*
|
||||
|
||||
*[Tyler Long](https://github.com/tylerlong) has became a collaborator since April 2017.*
|
||||
|
||||
Here is the full list of the projects [contributors](https://github.com/knsv/mermaid/graphs/contributors).
|
||||
|
3
__mocks__/MERMAID.js
Normal file
3
__mocks__/MERMAID.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export const curveBasis = 'basis'
|
||||
export const curveLinear = 'linear'
|
||||
export const curveCardinal = 'cardinal'
|
56
__mocks__/d3.js
vendored
Normal file
56
__mocks__/d3.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/* eslint-env jest */
|
||||
let NewD3 = function () {
|
||||
function returnThis () {
|
||||
return this
|
||||
}
|
||||
return {
|
||||
append: function () {
|
||||
return NewD3()
|
||||
},
|
||||
lower: returnThis,
|
||||
attr: returnThis,
|
||||
style: returnThis,
|
||||
text: returnThis,
|
||||
0: {
|
||||
0: {
|
||||
getBBox: function () {
|
||||
return {
|
||||
height: 10,
|
||||
width: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const select = function () {
|
||||
return new NewD3()
|
||||
}
|
||||
|
||||
export const selectAll = function () {
|
||||
return new NewD3()
|
||||
}
|
||||
|
||||
export const curveBasis = 'basis'
|
||||
export const curveLinear = 'linear'
|
||||
export const curveCardinal = 'cardinal'
|
||||
|
||||
export const MockD3 = (name, parent) => {
|
||||
const children = []
|
||||
const elem = {
|
||||
get __children () { return children },
|
||||
get __name () { return name },
|
||||
get __parent () { return parent }
|
||||
}
|
||||
elem.append = (name) => {
|
||||
const mockElem = MockD3(name, elem)
|
||||
children.push(mockElem)
|
||||
return mockElem
|
||||
}
|
||||
elem.lower = jest.fn(() => elem)
|
||||
elem.attr = jest.fn(() => elem)
|
||||
elem.text = jest.fn(() => elem)
|
||||
elem.style = jest.fn(() => elem)
|
||||
return elem
|
||||
}
|
10
babel.config.js
Normal file
10
babel.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: "defaults, ie >= 11, current node"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var chalk = require('chalk')
|
||||
var cli = require('../lib/cli.js')
|
||||
var lib = require('../lib')
|
||||
|
||||
cli.parse(process.argv.slice(2), function (err, message, options) {
|
||||
if (err) {
|
||||
console.error(
|
||||
chalk.bold.red('\nYou had errors in your syntax. Use --help for further information.')
|
||||
)
|
||||
err.forEach(function (e) {
|
||||
console.error(e.message)
|
||||
})
|
||||
|
||||
return
|
||||
} else if (message) {
|
||||
console.log(message)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
lib.process(options.files, options, process.exit)
|
||||
})
|
38
bower.json
38
bower.json
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"authors": [
|
||||
"knsv <knut@sveido.com>",
|
||||
"Tyler Long (https://github.com/tylerlong)"
|
||||
],
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.slim.js",
|
||||
"keywords": [
|
||||
"diagram",
|
||||
"markdown",
|
||||
"flowchart",
|
||||
"sequence diagram",
|
||||
"gantt",
|
||||
"class diagram",
|
||||
"git graph"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"*",
|
||||
"!dist/",
|
||||
"!dist/*",
|
||||
"!LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"chalk": "^2.1.0",
|
||||
"d3": "3.5.17",
|
||||
"dagre": "^0.7.4",
|
||||
"dagre-d3-renderer": "^0.1.6",
|
||||
"he": "^1.1.1",
|
||||
"lodash": "^4.17.4",
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"moment": "^2.18.1",
|
||||
"semver": "^5.4.1",
|
||||
"which": "^1.3.0"
|
||||
}
|
||||
}
|
1
cypress.json
Normal file
1
cypress.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "video": false }
|
272
cypress/examples/actions.spec.js
Normal file
272
cypress/examples/actions.spec.js
Normal file
@@ -0,0 +1,272 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Actions', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/actions')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/interacting-with-elements
|
||||
|
||||
it('.type() - type into a DOM element', () => {
|
||||
// https://on.cypress.io/type
|
||||
cy.get('.action-email')
|
||||
.type('fake@email.com').should('have.value', 'fake@email.com')
|
||||
|
||||
// .type() with special character sequences
|
||||
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
|
||||
.type('{del}{selectall}{backspace}')
|
||||
|
||||
// .type() with key modifiers
|
||||
.type('{alt}{option}') //these are equivalent
|
||||
.type('{ctrl}{control}') //these are equivalent
|
||||
.type('{meta}{command}{cmd}') //these are equivalent
|
||||
.type('{shift}')
|
||||
|
||||
// Delay each keypress by 0.1 sec
|
||||
.type('slow.typing@email.com', { delay: 100 })
|
||||
.should('have.value', 'slow.typing@email.com')
|
||||
|
||||
cy.get('.action-disabled')
|
||||
// Ignore error checking prior to type
|
||||
// like whether the input is visible or disabled
|
||||
.type('disabled error checking', { force: true })
|
||||
.should('have.value', 'disabled error checking')
|
||||
})
|
||||
|
||||
it('.focus() - focus on a DOM element', () => {
|
||||
// https://on.cypress.io/focus
|
||||
cy.get('.action-focus').focus()
|
||||
.should('have.class', 'focus')
|
||||
.prev().should('have.attr', 'style', 'color: orange;')
|
||||
})
|
||||
|
||||
it('.blur() - blur off a DOM element', () => {
|
||||
// https://on.cypress.io/blur
|
||||
cy.get('.action-blur').type('About to blur').blur()
|
||||
.should('have.class', 'error')
|
||||
.prev().should('have.attr', 'style', 'color: red;')
|
||||
})
|
||||
|
||||
it('.clear() - clears an input or textarea element', () => {
|
||||
// https://on.cypress.io/clear
|
||||
cy.get('.action-clear').type('Clear this text')
|
||||
.should('have.value', 'Clear this text')
|
||||
.clear()
|
||||
.should('have.value', '')
|
||||
})
|
||||
|
||||
it('.submit() - submit a form', () => {
|
||||
// https://on.cypress.io/submit
|
||||
cy.get('.action-form')
|
||||
.find('[type="text"]').type('HALFOFF')
|
||||
cy.get('.action-form').submit()
|
||||
.next().should('contain', 'Your form has been submitted!')
|
||||
})
|
||||
|
||||
it('.click() - click on a DOM element', () => {
|
||||
// https://on.cypress.io/click
|
||||
cy.get('.action-btn').click()
|
||||
|
||||
// You can click on 9 specific positions of an element:
|
||||
// -----------------------------------
|
||||
// | topLeft top topRight |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | left center right |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | bottomLeft bottom bottomRight |
|
||||
// -----------------------------------
|
||||
|
||||
// clicking in the center of the element is the default
|
||||
cy.get('#action-canvas').click()
|
||||
|
||||
cy.get('#action-canvas').click('topLeft')
|
||||
cy.get('#action-canvas').click('top')
|
||||
cy.get('#action-canvas').click('topRight')
|
||||
cy.get('#action-canvas').click('left')
|
||||
cy.get('#action-canvas').click('right')
|
||||
cy.get('#action-canvas').click('bottomLeft')
|
||||
cy.get('#action-canvas').click('bottom')
|
||||
cy.get('#action-canvas').click('bottomRight')
|
||||
|
||||
// .click() accepts an x and y coordinate
|
||||
// that controls where the click occurs :)
|
||||
|
||||
cy.get('#action-canvas')
|
||||
.click(80, 75) // click 80px on x coord and 75px on y coord
|
||||
.click(170, 75)
|
||||
.click(80, 165)
|
||||
.click(100, 185)
|
||||
.click(125, 190)
|
||||
.click(150, 185)
|
||||
.click(170, 165)
|
||||
|
||||
// click multiple elements by passing multiple: true
|
||||
cy.get('.action-labels>.label').click({ multiple: true })
|
||||
|
||||
// Ignore error checking prior to clicking
|
||||
cy.get('.action-opacity>.btn').click({ force: true })
|
||||
})
|
||||
|
||||
it('.dblclick() - double click on a DOM element', () => {
|
||||
// https://on.cypress.io/dblclick
|
||||
|
||||
// Our app has a listener on 'dblclick' event in our 'scripts.js'
|
||||
// that hides the div and shows an input on double click
|
||||
cy.get('.action-div').dblclick().should('not.be.visible')
|
||||
cy.get('.action-input-hidden').should('be.visible')
|
||||
})
|
||||
|
||||
it('.check() - check a checkbox or radio element', () => {
|
||||
// https://on.cypress.io/check
|
||||
|
||||
// By default, .check() will check all
|
||||
// matching checkbox or radio elements in succession, one after another
|
||||
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
|
||||
.check().should('be.checked')
|
||||
|
||||
cy.get('.action-radios [type="radio"]').not('[disabled]')
|
||||
.check().should('be.checked')
|
||||
|
||||
// .check() accepts a value argument
|
||||
cy.get('.action-radios [type="radio"]')
|
||||
.check('radio1').should('be.checked')
|
||||
|
||||
// .check() accepts an array of values
|
||||
cy.get('.action-multiple-checkboxes [type="checkbox"]')
|
||||
.check(['checkbox1', 'checkbox2']).should('be.checked')
|
||||
|
||||
// Ignore error checking prior to checking
|
||||
cy.get('.action-checkboxes [disabled]')
|
||||
.check({ force: true }).should('be.checked')
|
||||
|
||||
cy.get('.action-radios [type="radio"]')
|
||||
.check('radio3', { force: true }).should('be.checked')
|
||||
})
|
||||
|
||||
it('.uncheck() - uncheck a checkbox element', () => {
|
||||
// https://on.cypress.io/uncheck
|
||||
|
||||
// By default, .uncheck() will uncheck all matching
|
||||
// checkbox elements in succession, one after another
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.not('[disabled]')
|
||||
.uncheck().should('not.be.checked')
|
||||
|
||||
// .uncheck() accepts a value argument
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.check('checkbox1')
|
||||
.uncheck('checkbox1').should('not.be.checked')
|
||||
|
||||
// .uncheck() accepts an array of values
|
||||
cy.get('.action-check [type="checkbox"]')
|
||||
.check(['checkbox1', 'checkbox3'])
|
||||
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
|
||||
|
||||
// Ignore error checking prior to unchecking
|
||||
cy.get('.action-check [disabled]')
|
||||
.uncheck({ force: true }).should('not.be.checked')
|
||||
})
|
||||
|
||||
it('.select() - select an option in a <select> element', () => {
|
||||
// https://on.cypress.io/select
|
||||
|
||||
// Select option(s) with matching text content
|
||||
cy.get('.action-select').select('apples')
|
||||
|
||||
cy.get('.action-select-multiple')
|
||||
.select(['apples', 'oranges', 'bananas'])
|
||||
|
||||
// Select option(s) with matching value
|
||||
cy.get('.action-select').select('fr-bananas')
|
||||
|
||||
cy.get('.action-select-multiple')
|
||||
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
|
||||
})
|
||||
|
||||
it('.scrollIntoView() - scroll an element into view', () => {
|
||||
// https://on.cypress.io/scrollintoview
|
||||
|
||||
// normally all of these buttons are hidden,
|
||||
// because they're not within
|
||||
// the viewable area of their parent
|
||||
// (we need to scroll to see them)
|
||||
cy.get('#scroll-horizontal button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// scroll the button into view, as if the user had scrolled
|
||||
cy.get('#scroll-horizontal button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
|
||||
cy.get('#scroll-vertical button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// Cypress handles the scroll direction needed
|
||||
cy.get('#scroll-vertical button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
|
||||
cy.get('#scroll-both button')
|
||||
.should('not.be.visible')
|
||||
|
||||
// Cypress knows to scroll to the right and down
|
||||
cy.get('#scroll-both button').scrollIntoView()
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('.trigger() - trigger an event on a DOM element', () => {
|
||||
// https://on.cypress.io/trigger
|
||||
|
||||
// To interact with a range input (slider)
|
||||
// we need to set its value & trigger the
|
||||
// event to signal it changed
|
||||
|
||||
// Here, we invoke jQuery's val() method to set
|
||||
// the value and trigger the 'change' event
|
||||
cy.get('.trigger-input-range')
|
||||
.invoke('val', 25)
|
||||
.trigger('change')
|
||||
.get('input[type=range]').siblings('p')
|
||||
.should('have.text', '25')
|
||||
})
|
||||
|
||||
it('cy.scrollTo() - scroll the window or element to a position', () => {
|
||||
|
||||
// https://on.cypress.io/scrollTo
|
||||
|
||||
// You can scroll to 9 specific positions of an element:
|
||||
// -----------------------------------
|
||||
// | topLeft top topRight |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | left center right |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | bottomLeft bottom bottomRight |
|
||||
// -----------------------------------
|
||||
|
||||
// if you chain .scrollTo() off of cy, we will
|
||||
// scroll the entire window
|
||||
cy.scrollTo('bottom')
|
||||
|
||||
cy.get('#scrollable-horizontal').scrollTo('right')
|
||||
|
||||
// or you can scroll to a specific coordinate:
|
||||
// (x axis, y axis) in pixels
|
||||
cy.get('#scrollable-vertical').scrollTo(250, 250)
|
||||
|
||||
// or you can scroll to a specific percentage
|
||||
// of the (width, height) of the element
|
||||
cy.get('#scrollable-both').scrollTo('75%', '25%')
|
||||
|
||||
// control the easing of the scroll (default is 'swing')
|
||||
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
|
||||
|
||||
// control the duration of the scroll (in ms)
|
||||
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
|
||||
})
|
||||
})
|
42
cypress/examples/aliasing.spec.js
Normal file
42
cypress/examples/aliasing.spec.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Aliasing', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/aliasing')
|
||||
})
|
||||
|
||||
it('.as() - alias a DOM element for later use', () => {
|
||||
// https://on.cypress.io/as
|
||||
|
||||
// Alias a DOM element for use later
|
||||
// We don't have to traverse to the element
|
||||
// later in our code, we reference it with @
|
||||
|
||||
cy.get('.as-table').find('tbody>tr')
|
||||
.first().find('td').first()
|
||||
.find('button').as('firstBtn')
|
||||
|
||||
// when we reference the alias, we place an
|
||||
// @ in front of its name
|
||||
cy.get('@firstBtn').click()
|
||||
|
||||
cy.get('@firstBtn')
|
||||
.should('have.class', 'btn-success')
|
||||
.and('contain', 'Changed')
|
||||
})
|
||||
|
||||
it('.as() - alias a route for later use', () => {
|
||||
|
||||
// Alias the route to wait for its response
|
||||
cy.server()
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
|
||||
})
|
||||
})
|
168
cypress/examples/assertions.spec.js
Normal file
168
cypress/examples/assertions.spec.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Assertions', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/assertions')
|
||||
})
|
||||
|
||||
describe('Implicit Assertions', () => {
|
||||
it('.should() - make an assertion about the current subject', () => {
|
||||
// https://on.cypress.io/should
|
||||
cy.get('.assertion-table')
|
||||
.find('tbody tr:last')
|
||||
.should('have.class', 'success')
|
||||
.find('td')
|
||||
.first()
|
||||
// checking the text of the <td> element in various ways
|
||||
.should('have.text', 'Column content')
|
||||
.should('contain', 'Column content')
|
||||
.should('have.html', 'Column content')
|
||||
// chai-jquery uses "is()" to check if element matches selector
|
||||
.should('match', 'td')
|
||||
// to match text content against a regular expression
|
||||
// first need to invoke jQuery method text()
|
||||
// and then match using regular expression
|
||||
.invoke('text')
|
||||
.should('match', /column content/i)
|
||||
|
||||
// a better way to check element's text content against a regular expression
|
||||
// is to use "cy.contains"
|
||||
// https://on.cypress.io/contains
|
||||
cy.get('.assertion-table')
|
||||
.find('tbody tr:last')
|
||||
// finds first <td> element with text content matching regular expression
|
||||
.contains('td', /column content/i)
|
||||
.should('be.visible')
|
||||
|
||||
// for more information about asserting element's text
|
||||
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
|
||||
})
|
||||
|
||||
it('.and() - chain multiple assertions together', () => {
|
||||
// https://on.cypress.io/and
|
||||
cy.get('.assertions-link')
|
||||
.should('have.class', 'active')
|
||||
.and('have.attr', 'href')
|
||||
.and('include', 'cypress.io')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Explicit Assertions', () => {
|
||||
// https://on.cypress.io/assertions
|
||||
it('expect - make an assertion about a specified subject', () => {
|
||||
// We can use Chai's BDD style assertions
|
||||
expect(true).to.be.true
|
||||
const o = { foo: 'bar' }
|
||||
|
||||
expect(o).to.equal(o)
|
||||
expect(o).to.deep.equal({ foo: 'bar' })
|
||||
// matching text using regular expression
|
||||
expect('FooBar').to.match(/bar$/i)
|
||||
})
|
||||
|
||||
it('pass your own callback function to should()', () => {
|
||||
// Pass a function to should that can have any number
|
||||
// of explicit assertions within it.
|
||||
// The ".should(cb)" function will be retried
|
||||
// automatically until it passes all your explicit assertions or times out.
|
||||
cy.get('.assertions-p')
|
||||
.find('p')
|
||||
.should(($p) => {
|
||||
// https://on.cypress.io/$
|
||||
// return an array of texts from all of the p's
|
||||
// @ts-ignore TS6133 unused variable
|
||||
const texts = $p.map((i, el) => Cypress.$(el).text())
|
||||
|
||||
// jquery map returns jquery object
|
||||
// and .get() convert this to simple array
|
||||
const paragraphs = texts.get()
|
||||
|
||||
// array should have length of 3
|
||||
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
|
||||
|
||||
// use second argument to expect(...) to provide clear
|
||||
// message with each assertion
|
||||
expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([
|
||||
'Some text from first p',
|
||||
'More text from second p',
|
||||
'And even more text from third p',
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
it('finds element by class name regex', () => {
|
||||
cy.get('.docs-header')
|
||||
.find('div')
|
||||
// .should(cb) callback function will be retried
|
||||
.should(($div) => {
|
||||
expect($div).to.have.length(1)
|
||||
|
||||
const className = $div[0].className
|
||||
|
||||
expect(className).to.match(/heading-/)
|
||||
})
|
||||
// .then(cb) callback is not retried,
|
||||
// it either passes or fails
|
||||
.then(($div) => {
|
||||
expect($div, 'text content').to.have.text('Introduction')
|
||||
})
|
||||
})
|
||||
|
||||
it('can throw any error', () => {
|
||||
cy.get('.docs-header')
|
||||
.find('div')
|
||||
.should(($div) => {
|
||||
if ($div.length !== 1) {
|
||||
// you can throw your own errors
|
||||
throw new Error('Did not find 1 element')
|
||||
}
|
||||
|
||||
const className = $div[0].className
|
||||
|
||||
if (!className.match(/heading-/)) {
|
||||
throw new Error(`Could not find class "heading-" in ${className}`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('matches unknown text between two elements', () => {
|
||||
/**
|
||||
* Text from the first element.
|
||||
* @type {string}
|
||||
*/
|
||||
let text
|
||||
|
||||
/**
|
||||
* Normalizes passed text,
|
||||
* useful before comparing text with spaces and different capitalization.
|
||||
* @param {string} s Text to normalize
|
||||
*/
|
||||
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
|
||||
|
||||
cy.get('.two-elements')
|
||||
.find('.first')
|
||||
.then(($first) => {
|
||||
// save text from the first element
|
||||
text = normalizeText($first.text())
|
||||
})
|
||||
|
||||
cy.get('.two-elements')
|
||||
.find('.second')
|
||||
.should(($div) => {
|
||||
// we can massage text before comparing
|
||||
const secondText = normalizeText($div.text())
|
||||
|
||||
expect(secondText, 'second text').to.equal(text)
|
||||
})
|
||||
})
|
||||
|
||||
it('assert - assert shape of an object', () => {
|
||||
const person = {
|
||||
name: 'Joe',
|
||||
age: 20,
|
||||
}
|
||||
|
||||
assert.isObject(person, 'value is object')
|
||||
})
|
||||
})
|
||||
})
|
56
cypress/examples/connectors.spec.js
Normal file
56
cypress/examples/connectors.spec.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Connectors', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/connectors')
|
||||
})
|
||||
|
||||
it('.each() - iterate over an array of elements', () => {
|
||||
// https://on.cypress.io/each
|
||||
cy.get('.connectors-each-ul>li')
|
||||
.each(($el, index, $list) => {
|
||||
console.log($el, index, $list)
|
||||
})
|
||||
})
|
||||
|
||||
it('.its() - get properties on the current subject', () => {
|
||||
// https://on.cypress.io/its
|
||||
cy.get('.connectors-its-ul>li')
|
||||
// calls the 'length' property yielding that value
|
||||
.its('length')
|
||||
.should('be.gt', 2)
|
||||
})
|
||||
|
||||
it('.invoke() - invoke a function on the current subject', () => {
|
||||
// our div is hidden in our script.js
|
||||
// $('.connectors-div').hide()
|
||||
|
||||
// https://on.cypress.io/invoke
|
||||
cy.get('.connectors-div').should('be.hidden')
|
||||
// call the jquery method 'show' on the 'div.container'
|
||||
.invoke('show')
|
||||
.should('be.visible')
|
||||
})
|
||||
|
||||
it('.spread() - spread an array as individual args to callback function', () => {
|
||||
// https://on.cypress.io/spread
|
||||
const arr = ['foo', 'bar', 'baz']
|
||||
|
||||
cy.wrap(arr).spread((foo, bar, baz) => {
|
||||
expect(foo).to.eq('foo')
|
||||
expect(bar).to.eq('bar')
|
||||
expect(baz).to.eq('baz')
|
||||
})
|
||||
})
|
||||
|
||||
it('.then() - invoke a callback function with the current subject', () => {
|
||||
// https://on.cypress.io/then
|
||||
cy.get('.connectors-list > li')
|
||||
.then(($lis) => {
|
||||
expect($lis, '3 items').to.have.length(3)
|
||||
expect($lis.eq(0), 'first item').to.contain('Walk the dog')
|
||||
expect($lis.eq(1), 'second item').to.contain('Feed the cat')
|
||||
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
|
||||
})
|
||||
})
|
||||
})
|
78
cypress/examples/cookies.spec.js
Normal file
78
cypress/examples/cookies.spec.js
Normal file
@@ -0,0 +1,78 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Cookies', () => {
|
||||
beforeEach(() => {
|
||||
Cypress.Cookies.debug(true)
|
||||
|
||||
cy.visit('https://example.cypress.io/commands/cookies')
|
||||
|
||||
// clear cookies again after visiting to remove
|
||||
// any 3rd party cookies picked up such as cloudflare
|
||||
cy.clearCookies()
|
||||
})
|
||||
|
||||
it('cy.getCookie() - get a browser cookie', () => {
|
||||
// https://on.cypress.io/getcookie
|
||||
cy.get('#getCookie .set-a-cookie').click()
|
||||
|
||||
// cy.getCookie() yields a cookie object
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
||||
})
|
||||
|
||||
it('cy.getCookies() - get browser cookies', () => {
|
||||
// https://on.cypress.io/getcookies
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.get('#getCookies .set-a-cookie').click()
|
||||
|
||||
// cy.getCookies() yields an array of cookies
|
||||
cy.getCookies().should('have.length', 1).should((cookies) => {
|
||||
|
||||
// each cookie has these properties
|
||||
expect(cookies[0]).to.have.property('name', 'token')
|
||||
expect(cookies[0]).to.have.property('value', '123ABC')
|
||||
expect(cookies[0]).to.have.property('httpOnly', false)
|
||||
expect(cookies[0]).to.have.property('secure', false)
|
||||
expect(cookies[0]).to.have.property('domain')
|
||||
expect(cookies[0]).to.have.property('path')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.setCookie() - set a browser cookie', () => {
|
||||
// https://on.cypress.io/setcookie
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.setCookie('foo', 'bar')
|
||||
|
||||
// cy.getCookie() yields a cookie object
|
||||
cy.getCookie('foo').should('have.property', 'value', 'bar')
|
||||
})
|
||||
|
||||
it('cy.clearCookie() - clear a browser cookie', () => {
|
||||
// https://on.cypress.io/clearcookie
|
||||
cy.getCookie('token').should('be.null')
|
||||
|
||||
cy.get('#clearCookie .set-a-cookie').click()
|
||||
|
||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
||||
|
||||
// cy.clearCookies() yields null
|
||||
cy.clearCookie('token').should('be.null')
|
||||
|
||||
cy.getCookie('token').should('be.null')
|
||||
})
|
||||
|
||||
it('cy.clearCookies() - clear browser cookies', () => {
|
||||
// https://on.cypress.io/clearcookies
|
||||
cy.getCookies().should('be.empty')
|
||||
|
||||
cy.get('#clearCookies .set-a-cookie').click()
|
||||
|
||||
cy.getCookies().should('have.length', 1)
|
||||
|
||||
// cy.clearCookies() yields null
|
||||
cy.clearCookies()
|
||||
|
||||
cy.getCookies().should('be.empty')
|
||||
})
|
||||
})
|
222
cypress/examples/cypress_api.spec.js
Normal file
222
cypress/examples/cypress_api.spec.js
Normal file
@@ -0,0 +1,222 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Cypress.Commands', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/custom-commands
|
||||
|
||||
it('.add() - create a custom command', () => {
|
||||
Cypress.Commands.add('console', {
|
||||
prevSubject: true,
|
||||
}, (subject, method) => {
|
||||
// the previous subject is automatically received
|
||||
// and the commands arguments are shifted
|
||||
|
||||
// allow us to change the console method used
|
||||
method = method || 'log'
|
||||
|
||||
// log the subject to the console
|
||||
// @ts-ignore TS7017
|
||||
console[method]('The subject is', subject)
|
||||
|
||||
// whatever we return becomes the new subject
|
||||
// we don't want to change the subject so
|
||||
// we return whatever was passed in
|
||||
return subject
|
||||
})
|
||||
|
||||
// @ts-ignore TS2339
|
||||
cy.get('button').console('info').then(($button) => {
|
||||
// subject is still $button
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.Cookies', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/cookies
|
||||
it('.debug() - enable or disable debugging', () => {
|
||||
Cypress.Cookies.debug(true)
|
||||
|
||||
// Cypress will now log in the console when
|
||||
// cookies are set or cleared
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
cy.clearCookie('fakeCookie')
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
cy.clearCookie('fakeCookie')
|
||||
cy.setCookie('fakeCookie', '123ABC')
|
||||
})
|
||||
|
||||
it('.preserveOnce() - preserve cookies by key', () => {
|
||||
// normally cookies are reset after each test
|
||||
cy.getCookie('fakeCookie').should('not.be.ok')
|
||||
|
||||
// preserving a cookie will not clear it when
|
||||
// the next test starts
|
||||
cy.setCookie('lastCookie', '789XYZ')
|
||||
Cypress.Cookies.preserveOnce('lastCookie')
|
||||
})
|
||||
|
||||
it('.defaults() - set defaults for all cookies', () => {
|
||||
// now any cookie with the name 'session_id' will
|
||||
// not be cleared before each new test runs
|
||||
Cypress.Cookies.defaults({
|
||||
whitelist: 'session_id',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.Server', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// Permanently override server options for
|
||||
// all instances of cy.server()
|
||||
|
||||
// https://on.cypress.io/cypress-server
|
||||
it('.defaults() - change default config of server', () => {
|
||||
Cypress.Server.defaults({
|
||||
delay: 0,
|
||||
force404: false,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.arch', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get CPU architecture name of underlying OS', () => {
|
||||
// https://on.cypress.io/arch
|
||||
expect(Cypress.arch).to.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.config()', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get and set configuration options', () => {
|
||||
// https://on.cypress.io/config
|
||||
let myConfig = Cypress.config()
|
||||
|
||||
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
|
||||
expect(myConfig).to.have.property('baseUrl', null)
|
||||
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
|
||||
expect(myConfig).to.have.property('requestTimeout', 5000)
|
||||
expect(myConfig).to.have.property('responseTimeout', 30000)
|
||||
expect(myConfig).to.have.property('viewportHeight', 660)
|
||||
expect(myConfig).to.have.property('viewportWidth', 1000)
|
||||
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
|
||||
expect(myConfig).to.have.property('waitForAnimations', true)
|
||||
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
|
||||
|
||||
// this will change the config for the rest of your tests!
|
||||
Cypress.config('pageLoadTimeout', 20000)
|
||||
|
||||
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
|
||||
|
||||
Cypress.config('pageLoadTimeout', 60000)
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.dom', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// https://on.cypress.io/dom
|
||||
it('.isHidden() - determine if a DOM element is hidden', () => {
|
||||
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
|
||||
let visibleP = Cypress.$('.dom-p p.visible').get(0)
|
||||
|
||||
// our first paragraph has css class 'hidden'
|
||||
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
|
||||
expect(Cypress.dom.isHidden(visibleP)).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.env()', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
// We can set environment variables for highly dynamic values
|
||||
|
||||
// https://on.cypress.io/environment-variables
|
||||
it('Get environment variables', () => {
|
||||
// https://on.cypress.io/env
|
||||
// set multiple environment variables
|
||||
Cypress.env({
|
||||
host: 'veronica.dev.local',
|
||||
api_server: 'http://localhost:8888/v1/',
|
||||
})
|
||||
|
||||
// get environment variable
|
||||
expect(Cypress.env('host')).to.eq('veronica.dev.local')
|
||||
|
||||
// set environment variable
|
||||
Cypress.env('api_server', 'http://localhost:8888/v2/')
|
||||
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
|
||||
|
||||
// get all environment variable
|
||||
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
|
||||
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.log', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Control what is printed to the Command Log', () => {
|
||||
// https://on.cypress.io/cypress-log
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
context('Cypress.platform', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get underlying OS name', () => {
|
||||
// https://on.cypress.io/platform
|
||||
expect(Cypress.platform).to.be.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.version', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get current version of Cypress being run', () => {
|
||||
// https://on.cypress.io/version
|
||||
expect(Cypress.version).to.be.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('Cypress.spec', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/cypress-api')
|
||||
})
|
||||
|
||||
it('Get current spec information', () => {
|
||||
// https://on.cypress.io/spec
|
||||
// wrap the object so we can inspect it easily by clicking in the command log
|
||||
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute'])
|
||||
})
|
||||
})
|
114
cypress/examples/files.spec.js
Normal file
114
cypress/examples/files.spec.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
/// JSON fixture file can be loaded directly using
|
||||
// the built-in JavaScript bundler
|
||||
// @ts-ignore
|
||||
const requiredExample = require('../../fixtures/example')
|
||||
|
||||
context('Files', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/files')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
// load example.json fixture file and store
|
||||
// in the test context object
|
||||
cy.fixture('example.json').as('example')
|
||||
})
|
||||
|
||||
it('cy.fixture() - load a fixture', () => {
|
||||
// https://on.cypress.io/fixture
|
||||
|
||||
// Instead of writing a response inline you can
|
||||
// use a fixture file's content.
|
||||
|
||||
cy.server()
|
||||
cy.fixture('example.json').as('comment')
|
||||
// when application makes an Ajax request matching "GET comments/*"
|
||||
// Cypress will intercept it and reply with object
|
||||
// from the "comment" alias
|
||||
cy.route('GET', 'comments/*', '@comment').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
|
||||
// you can also just write the fixture in the route
|
||||
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
|
||||
// or write fx to represent fixture
|
||||
// by default it assumes it's .json
|
||||
cy.route('GET', 'comments/*', 'fx:example').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.fixture-btn').click()
|
||||
|
||||
cy.wait('@getComment').its('responseBody')
|
||||
.should('have.property', 'name')
|
||||
.and('include', 'Using fixtures to represent data')
|
||||
})
|
||||
|
||||
it('cy.fixture() or require - load a fixture', function () {
|
||||
// we are inside the "function () { ... }"
|
||||
// callback and can use test context object "this"
|
||||
// "this.example" was loaded in "beforeEach" function callback
|
||||
expect(this.example, 'fixture in the test context')
|
||||
.to.deep.equal(requiredExample)
|
||||
|
||||
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
|
||||
// @ts-ignore
|
||||
cy.wrap(this.example, 'fixture vs require')
|
||||
.should('deep.equal', requiredExample)
|
||||
})
|
||||
|
||||
it('cy.readFile() - read a files contents', () => {
|
||||
// https://on.cypress.io/readfile
|
||||
|
||||
// You can read a file and yield its contents
|
||||
// The filePath is relative to your project's root.
|
||||
cy.readFile('cypress.json').then((json) => {
|
||||
expect(json).to.be.an('object')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.writeFile() - write to a file', () => {
|
||||
// https://on.cypress.io/writefile
|
||||
|
||||
// You can write to a file
|
||||
|
||||
// Use a response from a request to automatically
|
||||
// generate a fixture file for use later
|
||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
||||
.then((response) => {
|
||||
cy.writeFile('cypress/fixtures/users.json', response.body)
|
||||
})
|
||||
cy.fixture('users').should((users) => {
|
||||
expect(users[0].name).to.exist
|
||||
})
|
||||
|
||||
// JavaScript arrays and objects are stringified
|
||||
// and formatted into text.
|
||||
cy.writeFile('cypress/fixtures/profile.json', {
|
||||
id: 8739,
|
||||
name: 'Jane',
|
||||
email: 'jane@example.com',
|
||||
})
|
||||
|
||||
cy.fixture('profile').should((profile) => {
|
||||
expect(profile.name).to.eq('Jane')
|
||||
})
|
||||
})
|
||||
})
|
52
cypress/examples/local_storage.spec.js
Normal file
52
cypress/examples/local_storage.spec.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Local Storage', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/local-storage')
|
||||
})
|
||||
// Although local storage is automatically cleared
|
||||
// in between tests to maintain a clean state
|
||||
// sometimes we need to clear the local storage manually
|
||||
|
||||
it('cy.clearLocalStorage() - clear all data in local storage', () => {
|
||||
// https://on.cypress.io/clearlocalstorage
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
// clearLocalStorage() yields the localStorage object
|
||||
cy.clearLocalStorage().should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.be.null
|
||||
expect(ls.getItem('prop3')).to.be.null
|
||||
})
|
||||
|
||||
// Clear key matching string in Local Storage
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
cy.clearLocalStorage('prop1').should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.eq('blue')
|
||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
// Clear keys matching regex in Local Storage
|
||||
cy.get('.ls-btn').click().should(() => {
|
||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
|
||||
cy.clearLocalStorage(/prop1|2/).should((ls) => {
|
||||
expect(ls.getItem('prop1')).to.be.null
|
||||
expect(ls.getItem('prop2')).to.be.null
|
||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
||||
})
|
||||
})
|
||||
})
|
32
cypress/examples/location.spec.js
Normal file
32
cypress/examples/location.spec.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Location', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/location')
|
||||
})
|
||||
|
||||
it('cy.hash() - get the current URL hash', () => {
|
||||
// https://on.cypress.io/hash
|
||||
cy.hash().should('be.empty')
|
||||
})
|
||||
|
||||
it('cy.location() - get window.location', () => {
|
||||
// https://on.cypress.io/location
|
||||
cy.location().should((location) => {
|
||||
expect(location.hash).to.be.empty
|
||||
expect(location.href).to.eq('https://example.cypress.io/commands/location')
|
||||
expect(location.host).to.eq('example.cypress.io')
|
||||
expect(location.hostname).to.eq('example.cypress.io')
|
||||
expect(location.origin).to.eq('https://example.cypress.io')
|
||||
expect(location.pathname).to.eq('/commands/location')
|
||||
expect(location.port).to.eq('')
|
||||
expect(location.protocol).to.eq('https:')
|
||||
expect(location.search).to.be.empty
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.url() - get the current URL', () => {
|
||||
// https://on.cypress.io/url
|
||||
cy.url().should('eq', 'https://example.cypress.io/commands/location')
|
||||
})
|
||||
})
|
83
cypress/examples/misc.spec.js
Normal file
83
cypress/examples/misc.spec.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Misc', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/misc')
|
||||
})
|
||||
|
||||
it('.end() - end the command chain', () => {
|
||||
// https://on.cypress.io/end
|
||||
|
||||
// cy.end is useful when you want to end a chain of commands
|
||||
// and force Cypress to re-query from the root element
|
||||
cy.get('.misc-table').within(() => {
|
||||
// ends the current chain and yields null
|
||||
cy.contains('Cheryl').click().end()
|
||||
|
||||
// queries the entire table again
|
||||
cy.contains('Charles').click()
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.exec() - execute a system command', () => {
|
||||
// https://on.cypress.io/exec
|
||||
|
||||
// execute a system command.
|
||||
// so you can take actions necessary for
|
||||
// your test outside the scope of Cypress.
|
||||
cy.exec('echo Jane Lane')
|
||||
.its('stdout').should('contain', 'Jane Lane')
|
||||
|
||||
// we can use Cypress.platform string to
|
||||
// select appropriate command
|
||||
// https://on.cypress/io/platform
|
||||
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
|
||||
|
||||
if (Cypress.platform === 'win32') {
|
||||
cy.exec('print cypress.json')
|
||||
.its('stderr').should('be.empty')
|
||||
} else {
|
||||
cy.exec('cat cypress.json')
|
||||
.its('stderr').should('be.empty')
|
||||
|
||||
cy.exec('pwd')
|
||||
.its('code').should('eq', 0)
|
||||
}
|
||||
})
|
||||
|
||||
it('cy.focused() - get the DOM element that has focus', () => {
|
||||
// https://on.cypress.io/focused
|
||||
cy.get('.misc-form').find('#name').click()
|
||||
cy.focused().should('have.id', 'name')
|
||||
|
||||
cy.get('.misc-form').find('#description').click()
|
||||
cy.focused().should('have.id', 'description')
|
||||
})
|
||||
|
||||
context('Cypress.Screenshot', function () {
|
||||
it('cy.screenshot() - take a screenshot', () => {
|
||||
// https://on.cypress.io/screenshot
|
||||
cy.screenshot('my-image')
|
||||
})
|
||||
|
||||
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
|
||||
Cypress.Screenshot.defaults({
|
||||
blackout: ['.foo'],
|
||||
capture: 'viewport',
|
||||
clip: { x: 0, y: 0, width: 200, height: 200 },
|
||||
scale: false,
|
||||
disableTimersAndAnimations: true,
|
||||
screenshotOnRunFailure: true,
|
||||
beforeScreenshot () { },
|
||||
afterScreenshot () { },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.wrap() - wrap an object', () => {
|
||||
// https://on.cypress.io/wrap
|
||||
cy.wrap({ foo: 'bar' })
|
||||
.should('have.property', 'foo')
|
||||
.and('include', 'bar')
|
||||
})
|
||||
})
|
56
cypress/examples/navigation.spec.js
Normal file
56
cypress/examples/navigation.spec.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Navigation', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io')
|
||||
cy.get('.navbar-nav').contains('Commands').click()
|
||||
cy.get('.dropdown-menu').contains('Navigation').click()
|
||||
})
|
||||
|
||||
it('cy.go() - go back or forward in the browser\'s history', () => {
|
||||
// https://on.cypress.io/go
|
||||
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
|
||||
cy.go('back')
|
||||
cy.location('pathname').should('not.include', 'navigation')
|
||||
|
||||
cy.go('forward')
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
|
||||
// clicking back
|
||||
cy.go(-1)
|
||||
cy.location('pathname').should('not.include', 'navigation')
|
||||
|
||||
// clicking forward
|
||||
cy.go(1)
|
||||
cy.location('pathname').should('include', 'navigation')
|
||||
})
|
||||
|
||||
it('cy.reload() - reload the page', () => {
|
||||
// https://on.cypress.io/reload
|
||||
cy.reload()
|
||||
|
||||
// reload the page without using the cache
|
||||
cy.reload(true)
|
||||
})
|
||||
|
||||
it('cy.visit() - visit a remote url', () => {
|
||||
// https://on.cypress.io/visit
|
||||
|
||||
// Visit any sub-domain of your current domain
|
||||
|
||||
// Pass options to the visit
|
||||
cy.visit('https://example.cypress.io/commands/navigation', {
|
||||
timeout: 50000, // increase total time for the visit to resolve
|
||||
onBeforeLoad (contentWindow) {
|
||||
// contentWindow is the remote page's window object
|
||||
expect(typeof contentWindow === 'object').to.be.true
|
||||
},
|
||||
onLoad (contentWindow) {
|
||||
// contentWindow is the remote page's window object
|
||||
expect(typeof contentWindow === 'object').to.be.true
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
194
cypress/examples/network_requests.spec.js
Normal file
194
cypress/examples/network_requests.spec.js
Normal file
@@ -0,0 +1,194 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Network Requests', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/network-requests')
|
||||
})
|
||||
|
||||
// Manage AJAX / XHR requests in your app
|
||||
|
||||
it('cy.server() - control behavior of network requests and responses', () => {
|
||||
// https://on.cypress.io/server
|
||||
|
||||
cy.server().should((server) => {
|
||||
// the default options on server
|
||||
// you can override any of these options
|
||||
expect(server.delay).to.eq(0)
|
||||
expect(server.method).to.eq('GET')
|
||||
expect(server.status).to.eq(200)
|
||||
expect(server.headers).to.be.null
|
||||
expect(server.response).to.be.null
|
||||
expect(server.onRequest).to.be.undefined
|
||||
expect(server.onResponse).to.be.undefined
|
||||
expect(server.onAbort).to.be.undefined
|
||||
|
||||
// These options control the server behavior
|
||||
// affecting all requests
|
||||
|
||||
// pass false to disable existing route stubs
|
||||
expect(server.enable).to.be.true
|
||||
// forces requests that don't match your routes to 404
|
||||
expect(server.force404).to.be.false
|
||||
// whitelists requests from ever being logged or stubbed
|
||||
expect(server.whitelist).to.be.a('function')
|
||||
})
|
||||
|
||||
cy.server({
|
||||
method: 'POST',
|
||||
delay: 1000,
|
||||
status: 422,
|
||||
response: {},
|
||||
})
|
||||
|
||||
// any route commands will now inherit the above options
|
||||
// from the server. anything we pass specifically
|
||||
// to route will override the defaults though.
|
||||
})
|
||||
|
||||
it('cy.request() - make an XHR request', () => {
|
||||
// https://on.cypress.io/request
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
||||
.should((response) => {
|
||||
expect(response.status).to.eq(200)
|
||||
expect(response.body).to.have.length(500)
|
||||
expect(response).to.have.property('headers')
|
||||
expect(response).to.have.property('duration')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('cy.request() - verify response using BDD syntax', () => {
|
||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
||||
.then((response) => {
|
||||
// https://on.cypress.io/assertions
|
||||
expect(response).property('status').to.equal(200)
|
||||
expect(response).property('body').to.have.length(500)
|
||||
expect(response).to.include.keys('headers', 'duration')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() with query parameters', () => {
|
||||
// will execute request
|
||||
// https://jsonplaceholder.cypress.io/comments?postId=1&id=3
|
||||
cy.request({
|
||||
url: 'https://jsonplaceholder.cypress.io/comments',
|
||||
qs: {
|
||||
postId: 1,
|
||||
id: 3,
|
||||
},
|
||||
})
|
||||
.its('body')
|
||||
.should('be.an', 'array')
|
||||
.and('have.length', 1)
|
||||
.its('0') // yields first element of the array
|
||||
.should('contain', {
|
||||
postId: 1,
|
||||
id: 3,
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() - pass result to the second request', () => {
|
||||
// first, let's find out the userId of the first user we have
|
||||
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
||||
.its('body.0') // yields the first element of the returned list
|
||||
.then((user) => {
|
||||
expect(user).property('id').to.be.a('number')
|
||||
// make a new post on behalf of the user
|
||||
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
||||
userId: user.id,
|
||||
title: 'Cypress Test Runner',
|
||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||
})
|
||||
})
|
||||
// note that the value here is the returned value of the 2nd request
|
||||
// which is the new post object
|
||||
.then((response) => {
|
||||
expect(response).property('status').to.equal(201) // new entity created
|
||||
expect(response).property('body').to.contain({
|
||||
id: 101, // there are already 100 posts, so new entity gets id 101
|
||||
title: 'Cypress Test Runner',
|
||||
})
|
||||
// we don't know the user id here - since it was in above closure
|
||||
// so in this test just confirm that the property is there
|
||||
expect(response.body).property('userId').to.be.a('number')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.request() - save response in the shared test context', () => {
|
||||
// https://on.cypress.io/variables-and-aliases
|
||||
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
||||
.its('body.0') // yields the first element of the returned list
|
||||
.as('user') // saves the object in the test context
|
||||
.then(function () {
|
||||
// NOTE 👀
|
||||
// By the time this callback runs the "as('user')" command
|
||||
// has saved the user object in the test context.
|
||||
// To access the test context we need to use
|
||||
// the "function () { ... }" callback form,
|
||||
// otherwise "this" points at a wrong or undefined object!
|
||||
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
||||
userId: this.user.id,
|
||||
title: 'Cypress Test Runner',
|
||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||
})
|
||||
.its('body').as('post') // save the new post from the response
|
||||
})
|
||||
.then(function () {
|
||||
// When this callback runs, both "cy.request" API commands have finished
|
||||
// and the test context has "user" and "post" objects set.
|
||||
// Let's verify them.
|
||||
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.route() - route responses to matching requests', () => {
|
||||
// https://on.cypress.io/route
|
||||
|
||||
let message = 'whoa, this comment does not exist'
|
||||
|
||||
cy.server()
|
||||
|
||||
// Listen to GET to comments/1
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
|
||||
// Listen to POST to comments
|
||||
cy.route('POST', '/comments').as('postComment')
|
||||
|
||||
// we have code that posts a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-post').click()
|
||||
cy.wait('@postComment')
|
||||
|
||||
// get the route
|
||||
cy.get('@postComment').should((xhr) => {
|
||||
expect(xhr.requestBody).to.include('email')
|
||||
expect(xhr.requestHeaders).to.have.property('Content-Type')
|
||||
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
|
||||
})
|
||||
|
||||
// Stub a response to PUT comments/ ****
|
||||
cy.route({
|
||||
method: 'PUT',
|
||||
url: 'comments/*',
|
||||
status: 404,
|
||||
response: { error: message },
|
||||
delay: 500,
|
||||
}).as('putComment')
|
||||
|
||||
// we have code that puts a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-put').click()
|
||||
|
||||
cy.wait('@putComment')
|
||||
|
||||
// our 404 statusCode logic in scripts.js executed
|
||||
cy.get('.network-put-comment').should('contain', message)
|
||||
})
|
||||
})
|
87
cypress/examples/querying.spec.js
Normal file
87
cypress/examples/querying.spec.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Querying', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/querying')
|
||||
})
|
||||
|
||||
// The most commonly used query is 'cy.get()', you can
|
||||
// think of this like the '$' in jQuery
|
||||
|
||||
it('cy.get() - query DOM elements', () => {
|
||||
// https://on.cypress.io/get
|
||||
|
||||
cy.get('#query-btn').should('contain', 'Button')
|
||||
|
||||
cy.get('.query-btn').should('contain', 'Button')
|
||||
|
||||
cy.get('#querying .well>button:first').should('contain', 'Button')
|
||||
// ↲
|
||||
// Use CSS selectors just like jQuery
|
||||
|
||||
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
|
||||
|
||||
// 'cy.get()' yields jQuery object, you can get its attribute
|
||||
// by invoking `.attr()` method
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.invoke('attr', 'data-test-id')
|
||||
.should('equal', 'test-example')
|
||||
|
||||
// or you can get element's CSS property
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.invoke('css', 'position')
|
||||
.should('equal', 'static')
|
||||
|
||||
// or use assertions directly during 'cy.get()'
|
||||
// https://on.cypress.io/assertions
|
||||
cy.get('[data-test-id="test-example"]')
|
||||
.should('have.attr', 'data-test-id', 'test-example')
|
||||
.and('have.css', 'position', 'static')
|
||||
})
|
||||
|
||||
it('cy.contains() - query DOM elements with matching content', () => {
|
||||
// https://on.cypress.io/contains
|
||||
cy.get('.query-list')
|
||||
.contains('bananas')
|
||||
.should('have.class', 'third')
|
||||
|
||||
// we can pass a regexp to `.contains()`
|
||||
cy.get('.query-list')
|
||||
.contains(/^b\w+/)
|
||||
.should('have.class', 'third')
|
||||
|
||||
cy.get('.query-list')
|
||||
.contains('apples')
|
||||
.should('have.class', 'first')
|
||||
|
||||
// passing a selector to contains will
|
||||
// yield the selector containing the text
|
||||
cy.get('#querying')
|
||||
.contains('ul', 'oranges')
|
||||
.should('have.class', 'query-list')
|
||||
|
||||
cy.get('.query-button')
|
||||
.contains('Save Form')
|
||||
.should('have.class', 'btn')
|
||||
})
|
||||
|
||||
it('.within() - query DOM elements within a specific element', () => {
|
||||
// https://on.cypress.io/within
|
||||
cy.get('.query-form').within(() => {
|
||||
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
|
||||
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
|
||||
})
|
||||
})
|
||||
|
||||
it('cy.root() - query the root DOM element', () => {
|
||||
// https://on.cypress.io/root
|
||||
|
||||
// By default, root is the document
|
||||
cy.root().should('match', 'html')
|
||||
|
||||
cy.get('.query-ul').within(() => {
|
||||
// In this within, the root is now the ul DOM element
|
||||
cy.root().should('have.class', 'query-ul')
|
||||
})
|
||||
})
|
||||
})
|
95
cypress/examples/spies_stubs_clocks.spec.js
Normal file
95
cypress/examples/spies_stubs_clocks.spec.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Spies, Stubs, and Clock', () => {
|
||||
it('cy.spy() - wrap a method in a spy', () => {
|
||||
// https://on.cypress.io/spy
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
foo () {},
|
||||
}
|
||||
|
||||
const spy = cy.spy(obj, 'foo').as('anyArgs')
|
||||
|
||||
obj.foo()
|
||||
|
||||
expect(spy).to.be.called
|
||||
})
|
||||
|
||||
it('cy.spy() retries until assertions pass', () => {
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
/**
|
||||
* Prints the argument passed
|
||||
* @param x {any}
|
||||
*/
|
||||
foo (x) {
|
||||
console.log('obj.foo called with', x)
|
||||
},
|
||||
}
|
||||
|
||||
cy.spy(obj, 'foo').as('foo')
|
||||
|
||||
setTimeout(() => {
|
||||
obj.foo('first')
|
||||
}, 500)
|
||||
|
||||
setTimeout(() => {
|
||||
obj.foo('second')
|
||||
}, 2500)
|
||||
|
||||
cy.get('@foo').should('have.been.calledTwice')
|
||||
})
|
||||
|
||||
it('cy.stub() - create a stub and/or replace a function with stub', () => {
|
||||
// https://on.cypress.io/stub
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
|
||||
const obj = {
|
||||
/**
|
||||
* prints both arguments to the console
|
||||
* @param a {string}
|
||||
* @param b {string}
|
||||
*/
|
||||
foo (a, b) {
|
||||
console.log('a', a, 'b', b)
|
||||
},
|
||||
}
|
||||
|
||||
const stub = cy.stub(obj, 'foo').as('foo')
|
||||
|
||||
obj.foo('foo', 'bar')
|
||||
|
||||
expect(stub).to.be.called
|
||||
})
|
||||
|
||||
it('cy.clock() - control time in the browser', () => {
|
||||
// https://on.cypress.io/clock
|
||||
|
||||
// create the date in UTC so its always the same
|
||||
// no matter what local timezone the browser is running in
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
||||
|
||||
cy.clock(now)
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
cy.get('#clock-div').click()
|
||||
.should('have.text', '1489449600')
|
||||
})
|
||||
|
||||
it('cy.tick() - move time in the browser', () => {
|
||||
// https://on.cypress.io/tick
|
||||
|
||||
// create the date in UTC so its always the same
|
||||
// no matter what local timezone the browser is running in
|
||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
||||
|
||||
cy.clock(now)
|
||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
||||
cy.get('#tick-div').click()
|
||||
.should('have.text', '1489449600')
|
||||
cy.tick(10000) // 10 seconds passed
|
||||
cy.get('#tick-div').click()
|
||||
.should('have.text', '1489449610')
|
||||
})
|
||||
})
|
121
cypress/examples/traversal.spec.js
Normal file
121
cypress/examples/traversal.spec.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Traversal', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/traversal')
|
||||
})
|
||||
|
||||
it('.children() - get child DOM elements', () => {
|
||||
// https://on.cypress.io/children
|
||||
cy.get('.traversal-breadcrumb')
|
||||
.children('.active')
|
||||
.should('contain', 'Data')
|
||||
})
|
||||
|
||||
it('.closest() - get closest ancestor DOM element', () => {
|
||||
// https://on.cypress.io/closest
|
||||
cy.get('.traversal-badge')
|
||||
.closest('ul')
|
||||
.should('have.class', 'list-group')
|
||||
})
|
||||
|
||||
it('.eq() - get a DOM element at a specific index', () => {
|
||||
// https://on.cypress.io/eq
|
||||
cy.get('.traversal-list>li')
|
||||
.eq(1).should('contain', 'siamese')
|
||||
})
|
||||
|
||||
it('.filter() - get DOM elements that match the selector', () => {
|
||||
// https://on.cypress.io/filter
|
||||
cy.get('.traversal-nav>li')
|
||||
.filter('.active').should('contain', 'About')
|
||||
})
|
||||
|
||||
it('.find() - get descendant DOM elements of the selector', () => {
|
||||
// https://on.cypress.io/find
|
||||
cy.get('.traversal-pagination')
|
||||
.find('li').find('a')
|
||||
.should('have.length', 7)
|
||||
})
|
||||
|
||||
it('.first() - get first DOM element', () => {
|
||||
// https://on.cypress.io/first
|
||||
cy.get('.traversal-table td')
|
||||
.first().should('contain', '1')
|
||||
})
|
||||
|
||||
it('.last() - get last DOM element', () => {
|
||||
// https://on.cypress.io/last
|
||||
cy.get('.traversal-buttons .btn')
|
||||
.last().should('contain', 'Submit')
|
||||
})
|
||||
|
||||
it('.next() - get next sibling DOM element', () => {
|
||||
// https://on.cypress.io/next
|
||||
cy.get('.traversal-ul')
|
||||
.contains('apples').next().should('contain', 'oranges')
|
||||
})
|
||||
|
||||
it('.nextAll() - get all next sibling DOM elements', () => {
|
||||
// https://on.cypress.io/nextall
|
||||
cy.get('.traversal-next-all')
|
||||
.contains('oranges')
|
||||
.nextAll().should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.nextUntil() - get next sibling DOM elements until next el', () => {
|
||||
// https://on.cypress.io/nextuntil
|
||||
cy.get('#veggies')
|
||||
.nextUntil('#nuts').should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.not() - remove DOM elements from set of DOM elements', () => {
|
||||
// https://on.cypress.io/not
|
||||
cy.get('.traversal-disabled .btn')
|
||||
.not('[disabled]').should('not.contain', 'Disabled')
|
||||
})
|
||||
|
||||
it('.parent() - get parent DOM element from DOM elements', () => {
|
||||
// https://on.cypress.io/parent
|
||||
cy.get('.traversal-mark')
|
||||
.parent().should('contain', 'Morbi leo risus')
|
||||
})
|
||||
|
||||
it('.parents() - get parent DOM elements from DOM elements', () => {
|
||||
// https://on.cypress.io/parents
|
||||
cy.get('.traversal-cite')
|
||||
.parents().should('match', 'blockquote')
|
||||
})
|
||||
|
||||
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
|
||||
// https://on.cypress.io/parentsuntil
|
||||
cy.get('.clothes-nav')
|
||||
.find('.active')
|
||||
.parentsUntil('.clothes-nav')
|
||||
.should('have.length', 2)
|
||||
})
|
||||
|
||||
it('.prev() - get previous sibling DOM element', () => {
|
||||
// https://on.cypress.io/prev
|
||||
cy.get('.birds').find('.active')
|
||||
.prev().should('contain', 'Lorikeets')
|
||||
})
|
||||
|
||||
it('.prevAll() - get all previous sibling DOM elements', () => {
|
||||
// https://on.cypress.io/prevAll
|
||||
cy.get('.fruits-list').find('.third')
|
||||
.prevAll().should('have.length', 2)
|
||||
})
|
||||
|
||||
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
|
||||
// https://on.cypress.io/prevUntil
|
||||
cy.get('.foods-list').find('#nuts')
|
||||
.prevUntil('#veggies').should('have.length', 3)
|
||||
})
|
||||
|
||||
it('.siblings() - get all sibling DOM elements', () => {
|
||||
// https://on.cypress.io/siblings
|
||||
cy.get('.traversal-pills .active')
|
||||
.siblings().should('have.length', 2)
|
||||
})
|
||||
})
|
133
cypress/examples/utilities.spec.js
Normal file
133
cypress/examples/utilities.spec.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Utilities', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/utilities')
|
||||
})
|
||||
|
||||
it('Cypress._ - call a lodash method', () => {
|
||||
// https://on.cypress.io/_
|
||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
||||
.then((response) => {
|
||||
let ids = Cypress._.chain(response.body).map('id').take(3).value()
|
||||
|
||||
expect(ids).to.deep.eq([1, 2, 3])
|
||||
})
|
||||
})
|
||||
|
||||
it('Cypress.$ - call a jQuery method', () => {
|
||||
// https://on.cypress.io/$
|
||||
let $li = Cypress.$('.utility-jquery li:first')
|
||||
|
||||
cy.wrap($li)
|
||||
.should('not.have.class', 'active')
|
||||
.click()
|
||||
.should('have.class', 'active')
|
||||
})
|
||||
|
||||
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
|
||||
// https://on.cypress.io/blob
|
||||
cy.get('.utility-blob').then(($div) =>
|
||||
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
||||
// get the dataUrl string for the javascript-logo
|
||||
Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
|
||||
.then((dataUrl) => {
|
||||
// create an <img> element and set its src to the dataUrl
|
||||
let img = Cypress.$('<img />', { src: dataUrl })
|
||||
|
||||
// need to explicitly return cy here since we are initially returning
|
||||
// the Cypress.Blob.imgSrcToDataURL promise to our test
|
||||
// append the image
|
||||
$div.append(img)
|
||||
|
||||
cy.get('.utility-blob img').click()
|
||||
.should('have.attr', 'src', dataUrl)
|
||||
}))
|
||||
})
|
||||
|
||||
it('Cypress.minimatch - test out glob patterns against strings', () => {
|
||||
// https://on.cypress.io/minimatch
|
||||
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
|
||||
matchBase: true,
|
||||
})
|
||||
|
||||
expect(matching, 'matching wildcard').to.be.true
|
||||
|
||||
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
|
||||
matchBase: true,
|
||||
})
|
||||
expect(matching, 'comments').to.be.false
|
||||
|
||||
// ** matches against all downstream path segments
|
||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
|
||||
matchBase: true,
|
||||
})
|
||||
expect(matching, 'comments').to.be.true
|
||||
|
||||
// whereas * matches only the next path segment
|
||||
|
||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
|
||||
matchBase: false,
|
||||
})
|
||||
expect(matching, 'comments').to.be.false
|
||||
})
|
||||
|
||||
|
||||
it('Cypress.moment() - format or parse dates using a moment method', () => {
|
||||
// https://on.cypress.io/moment
|
||||
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
|
||||
|
||||
expect(time).to.be.a('string')
|
||||
|
||||
cy.get('.utility-moment').contains('3:38 PM')
|
||||
.should('have.class', 'badge')
|
||||
|
||||
// the time in the element should be between 3pm and 5pm
|
||||
const start = Cypress.moment('3:00 PM', 'LT')
|
||||
const end = Cypress.moment('5:00 PM', 'LT')
|
||||
|
||||
cy.get('.utility-moment .badge')
|
||||
.should(($el) => {
|
||||
// parse American time like "3:38 PM"
|
||||
const m = Cypress.moment($el.text().trim(), 'LT')
|
||||
|
||||
// display hours + minutes + AM|PM
|
||||
const f = 'h:mm A'
|
||||
|
||||
expect(m.isBetween(start, end),
|
||||
`${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('Cypress.Promise - instantiate a bluebird promise', () => {
|
||||
// https://on.cypress.io/promise
|
||||
let waited = false
|
||||
|
||||
/**
|
||||
* @return Bluebird<string>
|
||||
*/
|
||||
function waitOneSecond () {
|
||||
// return a promise that resolves after 1 second
|
||||
// @ts-ignore TS2351 (new Cypress.Promise)
|
||||
return new Cypress.Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// set waited to true
|
||||
waited = true
|
||||
|
||||
// resolve with 'foo' string
|
||||
resolve('foo')
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
cy.then(() =>
|
||||
// return a promise to cy.then() that
|
||||
// is awaited until it resolves
|
||||
// @ts-ignore TS7006
|
||||
waitOneSecond().then((str) => {
|
||||
expect(str).to.eq('foo')
|
||||
expect(waited).to.be.true
|
||||
}))
|
||||
})
|
||||
})
|
59
cypress/examples/viewport.spec.js
Normal file
59
cypress/examples/viewport.spec.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Viewport', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/viewport')
|
||||
})
|
||||
|
||||
it('cy.viewport() - set the viewport size and dimension', () => {
|
||||
// https://on.cypress.io/viewport
|
||||
|
||||
cy.get('#navbar').should('be.visible')
|
||||
cy.viewport(320, 480)
|
||||
|
||||
// the navbar should have collapse since our screen is smaller
|
||||
cy.get('#navbar').should('not.be.visible')
|
||||
cy.get('.navbar-toggle').should('be.visible').click()
|
||||
cy.get('.nav').find('a').should('be.visible')
|
||||
|
||||
// lets see what our app looks like on a super large screen
|
||||
cy.viewport(2999, 2999)
|
||||
|
||||
// cy.viewport() accepts a set of preset sizes
|
||||
// to easily set the screen to a device's width and height
|
||||
|
||||
// We added a cy.wait() between each viewport change so you can see
|
||||
// the change otherwise it is a little too fast to see :)
|
||||
|
||||
cy.viewport('macbook-15')
|
||||
cy.wait(200)
|
||||
cy.viewport('macbook-13')
|
||||
cy.wait(200)
|
||||
cy.viewport('macbook-11')
|
||||
cy.wait(200)
|
||||
cy.viewport('ipad-2')
|
||||
cy.wait(200)
|
||||
cy.viewport('ipad-mini')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-6+')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-6')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-5')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-4')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-3')
|
||||
cy.wait(200)
|
||||
|
||||
// cy.viewport() accepts an orientation for all presets
|
||||
// the default orientation is 'portrait'
|
||||
cy.viewport('ipad-2', 'portrait')
|
||||
cy.wait(200)
|
||||
cy.viewport('iphone-4', 'landscape')
|
||||
cy.wait(200)
|
||||
|
||||
// The viewport will be reset back to the default dimensions
|
||||
// in between tests (the default can be set in cypress.json)
|
||||
})
|
||||
})
|
34
cypress/examples/waiting.spec.js
Normal file
34
cypress/examples/waiting.spec.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Waiting', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/waiting')
|
||||
})
|
||||
// BE CAREFUL of adding unnecessary wait times.
|
||||
// https://on.cypress.io/best-practices#Unnecessary-Waiting
|
||||
|
||||
// https://on.cypress.io/wait
|
||||
it('cy.wait() - wait for a specific amount of time', () => {
|
||||
cy.get('.wait-input1').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
cy.get('.wait-input2').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
cy.get('.wait-input3').type('Wait 1000ms after typing')
|
||||
cy.wait(1000)
|
||||
})
|
||||
|
||||
it('cy.wait() - wait for a specific route', () => {
|
||||
cy.server()
|
||||
|
||||
// Listen to GET to comments/1
|
||||
cy.route('GET', 'comments/*').as('getComment')
|
||||
|
||||
// we have code that gets a comment when
|
||||
// the button is clicked in scripts.js
|
||||
cy.get('.network-btn').click()
|
||||
|
||||
// wait for GET comments/1
|
||||
cy.wait('@getComment').its('status').should('eq', 200)
|
||||
})
|
||||
|
||||
})
|
22
cypress/examples/window.spec.js
Normal file
22
cypress/examples/window.spec.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Window', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('https://example.cypress.io/commands/window')
|
||||
})
|
||||
|
||||
it('cy.window() - get the global window object', () => {
|
||||
// https://on.cypress.io/window
|
||||
cy.window().should('have.property', 'top')
|
||||
})
|
||||
|
||||
it('cy.document() - get the document object', () => {
|
||||
// https://on.cypress.io/document
|
||||
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
|
||||
})
|
||||
|
||||
it('cy.title() - get the title', () => {
|
||||
// https://on.cypress.io/title
|
||||
cy.title().should('include', 'Kitchen Sink')
|
||||
})
|
||||
})
|
5
cypress/fixtures/example.json
Normal file
5
cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
34
cypress/helpers/util.js
Normal file
34
cypress/helpers/util.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/* eslint-env jest */
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
export const mermaidUrl = (graphStr, options, api) => {
|
||||
const obj = {
|
||||
code: graphStr,
|
||||
mermaid: options
|
||||
};
|
||||
const objStr = JSON.stringify(obj);
|
||||
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);
|
||||
if (api) {
|
||||
url = 'http://localhost:9000/xss.html?graph=' + graphStr;
|
||||
}
|
||||
|
||||
if (options.listUrl) {
|
||||
cy.log(options.listId, ' ', url);
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
export const imgSnapshotTest = (graphStr, options, api) => {
|
||||
const url = mermaidUrl(graphStr, options, api);
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('svg');
|
||||
cy.percySnapshot();
|
||||
};
|
||||
|
||||
export const renderGraph = (graphStr, options, api) => {
|
||||
const url = mermaidUrl(graphStr, options, api);
|
||||
|
||||
cy.visit(url);
|
||||
};
|
100
cypress/integration/other/configuration.spec.js
Normal file
100
cypress/integration/other/configuration.spec.js
Normal file
@@ -0,0 +1,100 @@
|
||||
import { renderGraph } from '../../helpers/util';
|
||||
/* eslint-env jest */
|
||||
describe('Configuration', () => {
|
||||
describe('arrowMarkerAbsolute', () => {
|
||||
it('should handle default value false of arrowMarkerAbsolute', () => {
|
||||
renderGraph(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ }
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
it('should handle default value false of arrowMarkerAbsolute', () => {
|
||||
renderGraph(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ }
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
it('should handle arrowMarkerAbsolute excplicitly set to false', () => {
|
||||
renderGraph(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{
|
||||
arrowMarkerAbsolute: false
|
||||
}
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
it('should handle arrowMarkerAbsolute excplicitly set to "false" as false', () => {
|
||||
renderGraph(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{
|
||||
arrowMarkerAbsolute: "false"
|
||||
}
|
||||
);
|
||||
|
||||
// Check the marker-end property to make sure it is properly set to
|
||||
// start with #
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(#');
|
||||
});
|
||||
it('should handle arrowMarkerAbsolute set to true', () => {
|
||||
renderGraph(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{
|
||||
arrowMarkerAbsolute: true
|
||||
}
|
||||
);
|
||||
|
||||
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
|
||||
.should('exist')
|
||||
.and('include', 'url(http://localhost');
|
||||
});
|
||||
});
|
||||
});
|
264
cypress/integration/other/interaction.spec.js
Normal file
264
cypress/integration/other/interaction.spec.js
Normal file
@@ -0,0 +1,264 @@
|
||||
/* eslint-env jest */
|
||||
describe('Interaction', () => {
|
||||
describe('Interaction - security level loose', () => {
|
||||
it('should handle a click on a node with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#Function')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||
});
|
||||
it('should handle a click on a node with a bound function where the node starts with a number', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g[id="1Function"]')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||
});
|
||||
it('should handle a click on a node with a bound url', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#URL')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
it('should handle a click on a node with a bound url where the node starts with a number', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g[id="2URL"]')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a click on a task with a bound URL clicking on the rect', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('rect#cl1')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
it('should handle a click on a task with a bound URL clicking on the text', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('text#cl1-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
it('should handle a click on a task with a bound function without args', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('rect#cl2')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
it('should handle a click on a task with a bound function with args', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('rect#cl3')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
|
||||
});
|
||||
|
||||
it('should handle a click on a task with a bound function without args', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('text#cl2-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
it('should handle a click on a task with a bound function with args ', () => {
|
||||
const url = 'http://localhost:9000/click_security_loose.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('text#cl3-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Interaction - security level tight', () => {
|
||||
it('should handle a click on a node without a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#Function')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
});
|
||||
it('should handle a click on a node with a bound function where the node starts with a number', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g[id="1Function"]')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
});
|
||||
it('should handle a click on a node with a bound url', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#URL')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
it('should handle a click on a node with a bound url where the node starts with a number', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g[id="2URL"]')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a click on a task with a bound URL clicking on the rect', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('rect#cl1')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
it('should handle a click on a task with a bound URL clicking on the text', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('text#cl1-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
it('should handle a click on a task with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('rect#cl2')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
it('should handle a click on a task with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('text#cl2-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Interaction - security level other, missspelling', () => {
|
||||
it('should handle a click on a node with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#Function')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
});
|
||||
it('should handle a click on a node with a bound function where the node starts with a number', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g[id="1Function"]')
|
||||
.click();
|
||||
|
||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||
});
|
||||
it('should handle a click on a node with a bound url', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('g#URL')
|
||||
.click();
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a click on a task with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('rect#cl2')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
it('should handle a click on a task with a bound function', () => {
|
||||
const url = 'http://localhost:9000/click_security_strict.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('text#cl2-text')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||
});
|
||||
});
|
||||
});
|
22
cypress/integration/other/rerender.spec.js
Normal file
22
cypress/integration/other/rerender.spec.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/* eslint-env jest */
|
||||
describe('Rerendering', () => {
|
||||
it('should be able to render after an error has occured', () => {
|
||||
const url = 'http://localhost:9000/render-after-error.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('#graphDiv').should('exist');
|
||||
});
|
||||
|
||||
it('should be able to render and rerender a graph via API', () => {
|
||||
const url = 'http://localhost:9000/rerender.html';
|
||||
cy.viewport(1440, 1024);
|
||||
cy.visit(url);
|
||||
cy.get('#graph #A').should('have.text', 'XMas');
|
||||
|
||||
cy.get('body')
|
||||
.find('#rerender')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get('#graph #A').should('have.text', 'Saturday');
|
||||
});
|
||||
});
|
11
cypress/integration/other/webpackUsage.spec.js
Normal file
11
cypress/integration/other/webpackUsage.spec.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/* eslint-env jest */
|
||||
describe('Sequencediagram', () => {
|
||||
it('should render a simple sequence diagrams', () => {
|
||||
const url = 'http://localhost:9000/webpackUsage.html';
|
||||
|
||||
cy.visit(url);
|
||||
cy.get('body')
|
||||
.find('svg')
|
||||
.should('have.length', 2);
|
||||
});
|
||||
});
|
35
cypress/integration/other/xss.spec.js
Normal file
35
cypress/integration/other/xss.spec.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/* eslint-env jest */
|
||||
import { mermaidUrl } from '../../helpers/util.js';
|
||||
|
||||
/* eslint-disable */
|
||||
describe('XSS', () => {
|
||||
it('should handle xss in tags', () => {
|
||||
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
|
||||
|
||||
const url = mermaidUrl(str,{}, true);
|
||||
|
||||
cy.visit(url);
|
||||
cy.wait(1000).then(()=>{
|
||||
cy.get('.mermaid').should('exist');
|
||||
});
|
||||
cy.get('svg')
|
||||
// cy.percySnapshot()
|
||||
|
||||
})
|
||||
it('should handle xss in tags in non-html mode', () => {
|
||||
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
|
||||
|
||||
const url = mermaidUrl(str,{
|
||||
"theme": "default",
|
||||
"flowchart": {
|
||||
"htmlMode": false
|
||||
}
|
||||
}, true);
|
||||
|
||||
cy.visit(url);
|
||||
// cy.get('svg')
|
||||
// cy.percySnapshot()
|
||||
cy.get('.malware').should('not.exist');
|
||||
|
||||
})
|
||||
})
|
308
cypress/integration/rendering/classDiagram.spec.js
Normal file
308
cypress/integration/rendering/classDiagram.spec.js
Normal file
@@ -0,0 +1,308 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('Class diagram', () => {
|
||||
it('1: should render a simple class diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 *-- Class04
|
||||
Class05 o-- Class06
|
||||
Class07 .. Class08
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class12 <|.. Class08
|
||||
Class11 ..>Class12
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class01 : -int privateChimp
|
||||
Class01 : +int publicGorilla
|
||||
Class01 : #int protectedMarmoset
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('2: should render a simple class diagrams with cardinality', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01 "1" <|--|> "*" AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 "1" *-- "*" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07 "1" .. "*" Class08
|
||||
Class09 "1" --> "*" C2 : Where am i?
|
||||
Class09 "*" --* "*" C3
|
||||
Class09 "1" --|> "1" Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 "1" <--> "*" C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render a simple class diagram with different visibilities', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class01 : -privateMethod()
|
||||
Class01 : +publicMethod()
|
||||
Class01 : #protectedMethod()
|
||||
Class01 : -int privateChimp
|
||||
Class01 : +int publicGorilla
|
||||
Class01 : #int protectedMarmoset
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render multiple class diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
[
|
||||
`
|
||||
classDiagram
|
||||
Class01 "1" <|--|> "*" AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 "1" *-- "*" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07 "1" .. "*" Class08
|
||||
Class09 "1" --> "*" C2 : Where am i?
|
||||
Class09 "*" --* "*" C3
|
||||
Class09 "1" --|> "1" Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 "1" <--> "*" C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
`
|
||||
classDiagram
|
||||
Class01 "1" <|--|> "*" AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 "1" *-- "*" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07 "1" .. "*" Class08
|
||||
Class09 "1" --> "*" C2 : Where am i?
|
||||
Class09 "*" --* "*" C3
|
||||
Class09 "1" --|> "1" Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 "1" <--> "*" C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
],
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('4: should render a simple class diagram with comments', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
%% this is a comment
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 *-- Class04
|
||||
Class05 o-- Class06
|
||||
Class07 .. Class08
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('5: should render a simple class diagram with abstract method', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class01 : someMethod()*
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('6: should render a simple class diagram with static method', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class01 : someMethod()$
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('7: should render a simple class diagram with Generic class', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
class Class01~T~
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10~T~ {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('8: should render a simple class diagram with Generic class and relations', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01~T~ <|-- AveryLongClass : Cool
|
||||
Class03~T~ *-- Class04~T~
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10~T~ {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('9: should render a simple class diagram with clickable link', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01~T~ <|-- AveryLongClass : Cool
|
||||
Class03~T~ *-- Class04~T~
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10~T~ {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
link class01 "google.com" "A Tooltip"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('10: should render a simple class diagram with clickable callback', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
Class01~T~ <|-- AveryLongClass : Cool
|
||||
Class03~T~ *-- Class04~T~
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10~T~ {
|
||||
<<service>>
|
||||
int id
|
||||
test()
|
||||
}
|
||||
callback class01 "functionCall" "A Tooltip"
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('11: should render a simple class diagram with return type on method', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
class Class10~T~ {
|
||||
int[] id
|
||||
test(int[] ids) bool
|
||||
testArray() bool[]
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('12: should render a simple class diagram with generic types', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
classDiagram
|
||||
class Class10~T~ {
|
||||
int[] id
|
||||
List~int~ ids
|
||||
test(List~int~ ids) List~bool~
|
||||
testArray() bool[]
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
21
cypress/integration/rendering/current.spec.js
Normal file
21
cypress/integration/rendering/current.spec.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
it('should render a state with states in it', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state PersonalizedCockpit {
|
||||
Other
|
||||
state Parent {
|
||||
C
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
104
cypress/integration/rendering/erDiagram.spec.js
Normal file
104
cypress/integration/rendering/erDiagram.spec.js
Normal file
@@ -0,0 +1,104 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('Entity Relationship Diagram', () => {
|
||||
it('should render a simple ER diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render an ER diagram with a recursive relationship', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||..o{ CUSTOMER : refers
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render an ER diagram with multiple relationships between the same two entities', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||--|{ ADDRESS : "invoiced at"
|
||||
CUSTOMER ||--|{ ADDRESS : "receives goods at"
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render a cyclical ER diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
erDiagram
|
||||
A ||--|{ B : likes
|
||||
B ||--|{ C : likes
|
||||
C ||--|{ A : likes
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render a not-so-simple ER diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
CUSTOMER ||--o{ INVOICE : "liable for"
|
||||
DELIVERY-ADDRESS ||--o{ ORDER : receives
|
||||
INVOICE ||--|{ ORDER : covers
|
||||
ORDER ||--|{ ORDER-ITEM : includes
|
||||
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
|
||||
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render multiple ER diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
[
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`,
|
||||
`
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
`
|
||||
],
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('should render an ER diagram with blank or empty labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
erDiagram
|
||||
BOOK }|..|{ AUTHOR : ""
|
||||
BOOK }|..|{ GENRE : " "
|
||||
AUTHOR }|..|{ GENRE : " "
|
||||
`,
|
||||
{logLevel : 1}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
674
cypress/integration/rendering/flowchart.spec.js
Normal file
674
cypress/integration/rendering/flowchart.spec.js
Normal file
@@ -0,0 +1,674 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('Flowchart', () => {
|
||||
it('1: should render a simple flowchart no htmlLabels', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('2: should render a simple flowchart with htmlLabels', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { htmlLabels: true } }
|
||||
);
|
||||
});
|
||||
|
||||
it('3: should render a simple flowchart with line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssss<br/>ssssssssssssssssssssss<br/>sssssssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('4: should render a simple flowchart with trapezoid and inverse trapezoid vertex options.', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
A[/Christmas\\]
|
||||
A -->|Get money| B[\\Go shopping/]
|
||||
B --> C{Let me thinksssss<br/>ssssssssssssssssssssss<br/>sssssssssssssssssssssssssss}
|
||||
C -->|One| D[/Laptop/]
|
||||
C -->|Two| E[\\iPhone\\]
|
||||
C -->|Three| F[Car]
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('5: should style nodes via a class.', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
1A --> 1B
|
||||
1B --> 1C
|
||||
1C --> D
|
||||
1C --> E
|
||||
|
||||
classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
|
||||
class 1A,1B,D,E processHead
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('6: should render a flowchart full of circles', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph LR
|
||||
47(SAM.CommonFA.FMESummary)-->48(SAM.CommonFA.CommonFAFinanceBudget)
|
||||
37(SAM.CommonFA.BudgetSubserviceLineVolume)-->48(SAM.CommonFA.CommonFAFinanceBudget)
|
||||
35(SAM.CommonFA.PopulationFME)-->47(SAM.CommonFA.FMESummary)
|
||||
41(SAM.CommonFA.MetricCost)-->47(SAM.CommonFA.FMESummary)
|
||||
44(SAM.CommonFA.MetricOutliers)-->47(SAM.CommonFA.FMESummary)
|
||||
46(SAM.CommonFA.MetricOpportunity)-->47(SAM.CommonFA.FMESummary)
|
||||
40(SAM.CommonFA.OPVisits)-->47(SAM.CommonFA.FMESummary)
|
||||
38(SAM.CommonFA.CommonFAFinanceRefund)-->47(SAM.CommonFA.FMESummary)
|
||||
43(SAM.CommonFA.CommonFAFinancePicuDays)-->47(SAM.CommonFA.FMESummary)
|
||||
42(SAM.CommonFA.CommonFAFinanceNurseryDays)-->47(SAM.CommonFA.FMESummary)
|
||||
45(SAM.CommonFA.MetricPreOpportunity)-->46(SAM.CommonFA.MetricOpportunity)
|
||||
35(SAM.CommonFA.PopulationFME)-->45(SAM.CommonFA.MetricPreOpportunity)
|
||||
41(SAM.CommonFA.MetricCost)-->45(SAM.CommonFA.MetricPreOpportunity)
|
||||
41(SAM.CommonFA.MetricCost)-->44(SAM.CommonFA.MetricOutliers)
|
||||
39(SAM.CommonFA.ChargeDetails)-->43(SAM.CommonFA.CommonFAFinancePicuDays)
|
||||
39(SAM.CommonFA.ChargeDetails)-->42(SAM.CommonFA.CommonFAFinanceNurseryDays)
|
||||
39(SAM.CommonFA.ChargeDetails)-->41(SAM.CommonFA.MetricCost)
|
||||
39(SAM.CommonFA.ChargeDetails)-->40(SAM.CommonFA.OPVisits)
|
||||
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
|
||||
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('7: should render a flowchart full of icons', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002("fa:fa-creative-commons My System | Test Environment")
|
||||
82072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 1")
|
||||
db052290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 2")
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 1")
|
||||
30122290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 2")
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 1")
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 2")
|
||||
b7042290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[SupportDb]")
|
||||
8f102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[DevelopmentDb]")
|
||||
0e102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[TestDb]")
|
||||
07132290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\\SharedDbInstance].[SharedReportingDb]")
|
||||
c7072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Business Logic Server")
|
||||
ca122290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Report Server")
|
||||
68102290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Dedicated Test Business Logic Server")
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002("fa:fa-database [DBServer\\SharedDbInstance]")
|
||||
d6072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server DBServer")
|
||||
71082290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\\:MSSQLSERVER")
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\\:SQLAgent")
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\\:SQLBrowser")
|
||||
1d0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost1")
|
||||
200a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost2")
|
||||
1c0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost3")
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->db052290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->30122290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->c1112290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
|
||||
db052290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
|
||||
db052290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->07132290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
|
||||
30122290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
|
||||
30122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
|
||||
b7042290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
8f102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
0e102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
07132290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
c7072290_1ec3_e711_8c5a_005056ad0002-->1d0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
ca122290_1ec3_e711_8c5a_005056ad0002-->200a2290_1ec3_e711_8c5a_005056ad0002
|
||||
68102290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->c0102290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->9a072290_1ec3_e711_8c5a_005056ad0002
|
||||
d6072290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
71082290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('8: should render labels with numbers at the start', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB;subgraph "number as labels";1;end;
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('9: should render subgraphs', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('10: should render subgraphs with a title starting with a digit', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
subgraph 2Two
|
||||
a1-->a2
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('11: should render styled subgraphs', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TB
|
||||
A
|
||||
B
|
||||
subgraph foo[Foo SubGraph]
|
||||
C
|
||||
D
|
||||
end
|
||||
subgraph bar[Bar SubGraph]
|
||||
E
|
||||
F
|
||||
end
|
||||
G
|
||||
|
||||
A-->B
|
||||
B-->C
|
||||
C-->D
|
||||
B-->D
|
||||
D-->E
|
||||
E-->A
|
||||
E-->F
|
||||
F-->D
|
||||
F-->G
|
||||
B-->G
|
||||
G-->D
|
||||
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('12: should render a flowchart with long names and class definitions', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||
|
||||
提交申请
|
||||
熊大
|
||||
"];
|
||||
class sid-B3655226-6C29-4D00-B685-3D5C734DC7E1 node-executed;
|
||||
sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A["
|
||||
负责人审批
|
||||
强子
|
||||
"];
|
||||
class sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A node-executed;
|
||||
sid-E27C0367-E6D6-497F-9736-3CDC21FDE221["
|
||||
DBA审批
|
||||
强子
|
||||
"];
|
||||
class sid-E27C0367-E6D6-497F-9736-3CDC21FDE221 node-executed;
|
||||
sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD["
|
||||
SA审批
|
||||
阿美
|
||||
"];
|
||||
class sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD node-executed;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7["
|
||||
主管审批
|
||||
光头强
|
||||
"];
|
||||
class sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7 node-executed;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89["
|
||||
DBA确认
|
||||
强子
|
||||
"];
|
||||
class sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89 node-executed;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937["
|
||||
SA确认
|
||||
阿美
|
||||
"];
|
||||
class sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937 node-executed;
|
||||
sid-4FC27B48-A6F9-460A-A675-021F5854FE22["
|
||||
结束
|
||||
"];
|
||||
class sid-4FC27B48-A6F9-460A-A675-021F5854FE22 node-executed;
|
||||
sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E["
|
||||
SA执行1
|
||||
强子
|
||||
"];
|
||||
class sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E node-executed;
|
||||
sid-6C2120F3-D940-4958-A067-0903DCE879C4["
|
||||
SA执行2
|
||||
强子
|
||||
"];
|
||||
class sid-6C2120F3-D940-4958-A067-0903DCE879C4 node-executed;
|
||||
sid-9180E2A0-5C4B-435F-B42F-0D152470A338["
|
||||
DBA执行1
|
||||
强子
|
||||
"];
|
||||
class sid-9180E2A0-5C4B-435F-B42F-0D152470A338 node-executed;
|
||||
sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD["
|
||||
DBA执行3
|
||||
强子
|
||||
"];
|
||||
class sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD node-executed;
|
||||
sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756["
|
||||
DBA执行2
|
||||
强子
|
||||
"];
|
||||
class sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756 node-executed;
|
||||
sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93["
|
||||
DBA执行4
|
||||
强子
|
||||
"];
|
||||
class sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93 node-executed;
|
||||
sid-1897B30A-9C5C-4D5B-B80B-76A038785070["
|
||||
负责人确认
|
||||
梁静茹
|
||||
"];
|
||||
class sid-1897B30A-9C5C-4D5B-B80B-76A038785070 node-executed;
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1-->sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7;
|
||||
sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A-->sid-1897B30A-9C5C-4D5B-B80B-76A038785070;
|
||||
sid-E27C0367-E6D6-497F-9736-3CDC21FDE221-->sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89;
|
||||
sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD-->sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937;
|
||||
sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
|
||||
sid-9180E2A0-5C4B-435F-B42F-0D152470A338-->sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756;
|
||||
sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD-->sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93;
|
||||
sid-6C2120F3-D940-4958-A067-0903DCE879C4-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-1897B30A-9C5C-4D5B-B80B-76A038785070-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-9180E2A0-5C4B-435F-B42F-0D152470A338;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD;
|
||||
sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-E27C0367-E6D6-497F-9736-3CDC21FDE221;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('13: should render color of styled nodes', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph LR
|
||||
foo-->bar
|
||||
|
||||
classDef foo fill:lightblue,color:green,stroke:#FF9E2C,font-weight:bold
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F
|
||||
style bar fill:#999,color: #00ff00, stroke-width:10px,stroke:#0F0
|
||||
`,
|
||||
{
|
||||
listUrl: false,
|
||||
listId: 'color styling',
|
||||
logLevel: 0
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('14: should render hexagons', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
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?}}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
`,
|
||||
{
|
||||
listUrl: false,
|
||||
listId: 'color styling',
|
||||
logLevel: 0
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('15: should render a simple flowchart with comments', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('16: Render Stadium shape', () => {
|
||||
imgSnapshotTest(
|
||||
` graph TD
|
||||
A([stadium shape test])
|
||||
A -->|Get money| B([Go shopping])
|
||||
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?])
|
||||
C -->|One| D([Laptop])
|
||||
C -->|Two| E([iPhone])
|
||||
C -->|Three| F([Car<br/>wroom wroom])
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('17: Render multiline texts', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
A1[Multi<br>Line] -->|Multi<br>Line| B1(Multi<br>Line)
|
||||
C1[Multi<br/>Line] -->|Multi<br/>Line| D1(Multi<br/>Line)
|
||||
E1[Multi<br />Line] -->|Multi<br />Line| F1(Multi<br />Line)
|
||||
A2[Multi<br>Line] -->|Multi<br>Line| B2(Multi<br>Line)
|
||||
C2[Multi<br/>Line] -->|Multi<br/>Line| D2(Multi<br/>Line)
|
||||
E2[Multi<br />Line] -->|Multi<br />Line| F2(Multi<br />Line)
|
||||
linkStyle 0 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 2 stroke:DarkGray,stroke-width:2px
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('18: Chaining of nodes', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
a --> b --> c
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('19: Multiple nodes and chaining in one statement', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
a --> b & c--> d
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('20: Multiple nodes and chaining in one statement', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[ h ] -- hello --> B[" test "]:::exClass & C --> D;
|
||||
classDef exClass background:#bbb,border:1px solid red;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('21: Render cylindrical shape', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
A[(cylindrical<br />shape<br />test)]
|
||||
A -->|Get money| B1[(Go shopping 1)]
|
||||
A -->|Get money| B2[(Go shopping 2)]
|
||||
A -->|Get money| B3[(Go shopping 3)]
|
||||
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?)]
|
||||
B1 --> C
|
||||
B2 --> C
|
||||
B3 --> C
|
||||
C -->|One| D[(Laptop)]
|
||||
C -->|Two| E[(iPhone)]
|
||||
C -->|Three| F[(Car)]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('22: Render a simple flowchart with nodeSpacing set to 100', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { nodeSpacing: 50 } }
|
||||
);
|
||||
});
|
||||
|
||||
it('23: Render a simple flowchart with rankSpacing set to 100', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
%% this is a comment
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
`,
|
||||
{ flowchart: { rankSpacing: '100' } }
|
||||
);
|
||||
});
|
||||
|
||||
it('24: Keep node label text (if already defined) when a style is applied', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
A(( )) -->|step 1| B(( ))
|
||||
B(( )) -->|step 2| C(( ))
|
||||
C(( )) -->|step 3| D(( ))
|
||||
linkStyle 1 stroke:greenyellow,stroke-width:2px
|
||||
style C fill:greenyellow,stroke:green,stroke-width:4px
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('25: Handle link click events (link, anchor, mailto, other protocol, script)', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TB
|
||||
TITLE["Link Click Events<br>(click the nodes below)"]
|
||||
A[link test]
|
||||
B[anchor test]
|
||||
C[mailto test]
|
||||
D[other protocol test]
|
||||
E[script test]
|
||||
TITLE --> A & B & C & D & E
|
||||
click A "https://mermaid-js.github.io/mermaid/#/" "link test"
|
||||
click B "#link-clicked" "anchor test"
|
||||
click C "mailto:user@user.user" "mailto test"
|
||||
click D "notes://do-your-thing/id" "other protocol test"
|
||||
click E "javascript:alert('test')" "script test"
|
||||
`,
|
||||
{ securityLevel: 'loose' }
|
||||
);
|
||||
});
|
||||
|
||||
it('26: Set text color of nodes and links according to styles when html labels are enabled', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
A[red<br>text] -->|red<br>text| B(blue<br>text)
|
||||
C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
|
||||
E{{default<br />style}} -->|default<br />style| F([default<br />style])
|
||||
linkStyle default color:Sienna;
|
||||
linkStyle 0 color:red;
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
|
||||
style A color:red;
|
||||
style B color:blue;
|
||||
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||
click B "index.html#link-clicked" "link test"
|
||||
click D testClick "click test"
|
||||
`,
|
||||
{ flowchart: { htmlLabels: true } }
|
||||
);
|
||||
});
|
||||
|
||||
it('27: Set text color of nodes and links according to styles when html labels are disabled', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
A[red<br>text] -->|red<br>text| B(blue<br>text)
|
||||
C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
|
||||
E{{default<br />style}} -->|default<br />style| F([default<br />style])
|
||||
linkStyle default color:Sienna;
|
||||
linkStyle 0 color:red;
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
|
||||
style A color:red;
|
||||
style B color:blue;
|
||||
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||
click B "index.html#link-clicked" "link test"
|
||||
click D testClick "click test"
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('28: Apply default class to all nodes which do not have another class assigned (htmlLabels enabled)', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[myClass1] --> B[default] & C[default]
|
||||
B[default] & C[default] --> D[myClass2]
|
||||
classDef default stroke-width:2px,fill:none,stroke:silver
|
||||
classDef node color:red
|
||||
classDef myClass1 color:#0000ff
|
||||
classDef myClass2 stroke:#0000ff,fill:#ccccff
|
||||
class A myClass1
|
||||
class D myClass2
|
||||
`,
|
||||
{ flowchart: { htmlLabels: true } }
|
||||
);
|
||||
});
|
||||
|
||||
it('29: Apply default class to all nodes which do not have another class assigned (htmlLabels disabled)', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
A[myClass1] --> B[default] & C[default]
|
||||
B[default] & C[default] --> D[myClass2]
|
||||
classDef default stroke-width:2px,fill:none,stroke:silver
|
||||
classDef node color:red
|
||||
classDef myClass1 color:#0000ff
|
||||
classDef myClass2 stroke:#0000ff,fill:#ccccff
|
||||
class A myClass1
|
||||
class D myClass2
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('30: Possibility to style text color of nodes and subgraphs as well as apply classes to subgraphs', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
subgraph id1 [title is set]
|
||||
A-->B
|
||||
end
|
||||
subgraph id2 [title]
|
||||
E
|
||||
end
|
||||
|
||||
B-->C
|
||||
|
||||
subgraph id3
|
||||
C-->D
|
||||
end
|
||||
class id3,id2,A redBg;
|
||||
class id3,A whiteTxt;
|
||||
classDef redBg fill:#622;
|
||||
classDef whiteTxt color: white;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('31: should not slice off edges that are to the left of the left-most vertex', () => {
|
||||
imgSnapshotTest(
|
||||
`graph TD
|
||||
work --> sleep
|
||||
sleep --> work
|
||||
eat --> sleep
|
||||
work --> eat
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
|
||||
it('32: Render Subroutine shape', () => {
|
||||
imgSnapshotTest(
|
||||
`graph LR
|
||||
A[[subroutine shape test]]
|
||||
A -->|Get money| B[[Go shopping]]
|
||||
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?]]
|
||||
C -->|One| D[[Laptop]]
|
||||
C -->|Two| E[[iPhone]]
|
||||
C -->|Three| F[[Car<br/>wroom wroom]]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
`,
|
||||
{ flowchart: { htmlLabels: false } }
|
||||
);
|
||||
});
|
||||
});
|
163
cypress/integration/rendering/gantt.spec.js
Normal file
163
cypress/integration/rendering/gantt.spec.js
Normal file
@@ -0,0 +1,163 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Gantt diagram', () => {
|
||||
it('should render a gantt chart', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('Handle multiline section titles with different line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title GANTT diagram with multiline section titles
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section<br>multiline
|
||||
Completed task : done, des1, 2014-01-06,2014-01-08
|
||||
Active task : active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks<br/>multiline
|
||||
Completed task in the critical line : crit, done, 2014-01-06, 24h
|
||||
Implement parser and jison : crit, done, after des1, 2d
|
||||
Create tests for parser : crit, active, 3d
|
||||
Future task in critical line : crit, 5d
|
||||
Create tests for renderer : 2d
|
||||
Add to mermaid : 1d
|
||||
|
||||
section Documentation<br />multiline
|
||||
Describe gantt syntax : active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page : after a1, 20h
|
||||
Add another diagram to demo page : doc1, after a1, 48h
|
||||
|
||||
section Last section<br />multiline
|
||||
Describe gantt syntax : after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('Multiple dependencies syntax', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
apple :a, 2017-07-20, 1w
|
||||
banana :crit, b, 2017-07-23, 1d
|
||||
cherry :active, c, after b a, 1d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render a gantt chart for issue #1060', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
excludes weekdays 2017-01-10
|
||||
title Projects Timeline
|
||||
|
||||
section asdf
|
||||
specs :done, :ps, 2019-05-10, 50d
|
||||
Plasma :pc, 2019-06-20, 60d
|
||||
Rollup :or, 2019-08-20, 50d
|
||||
|
||||
section CEL
|
||||
|
||||
plasma-chamber :done, :pc, 2019-05-20, 60d
|
||||
Plasma Implementation (Rust) :por, 2019-06-20, 120d
|
||||
Predicates (Atomic Swap) :pred, 2019-07-20, 60d
|
||||
|
||||
section DEX
|
||||
|
||||
History zkSNARK :hs, 2019-08-10, 40d
|
||||
Exit :vs, after hs, 60d
|
||||
PredicateSpec :ps, 2019-09-1, 20d
|
||||
PlasmaIntegration :pi, after ps,40d
|
||||
|
||||
|
||||
section Events
|
||||
|
||||
ETHBoston :done, :eb, 2019-09-08, 3d
|
||||
DevCon :active, :dc, 2019-10-08, 3d
|
||||
|
||||
section Plasma Calls & updates
|
||||
OVM :ovm, 2019-07-12, 120d
|
||||
Plasma call 26 :pc26, 2019-08-21, 1d
|
||||
Plasma call 27 :pc27, 2019-09-03, 1d
|
||||
Plasma call 28 :pc28, 2019-09-17, 1d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('should hide today marker', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title Hide today marker (vertical line should not be visible)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
todayMarker off
|
||||
section Section1
|
||||
Today: 1, -1h
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('should style today marker', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title Style today marker (vertical line should be 5px wide and half-transparent blue)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||
section Section1
|
||||
Today: 1, -1h
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
21
cypress/integration/rendering/gitGraph.spec.js
Normal file
21
cypress/integration/rendering/gitGraph.spec.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Sequencediagram', () => {
|
||||
// it('should render a simple git graph', () => {
|
||||
// imgSnapshotTest(
|
||||
// `
|
||||
// gitGraph:
|
||||
// commit
|
||||
// branch newbranch
|
||||
// checkout newbranch
|
||||
// commit
|
||||
// commit
|
||||
// checkout master
|
||||
// commit
|
||||
// commit
|
||||
// merge newbranch`,
|
||||
// { logLevel: 0 }
|
||||
// );
|
||||
// });
|
||||
});
|
14
cypress/integration/rendering/info.spec.js
Normal file
14
cypress/integration/rendering/info.spec.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Sequencediagram', () => {
|
||||
it('should render a simple info diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
info
|
||||
showInfo
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
31
cypress/integration/rendering/journey.spec.js
Normal file
31
cypress/integration/rendering/journey.spec.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('User journey diagram', () => {
|
||||
it('Simple test', () => {
|
||||
imgSnapshotTest(
|
||||
`journey
|
||||
title Adding journey diagram functionality to mermaid
|
||||
section Order from website
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a user journey chart', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
40
cypress/integration/rendering/pie.spec.js
Normal file
40
cypress/integration/rendering/pie.spec.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||
|
||||
describe('Pie Chart', () => {
|
||||
it('should render a simple pie diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
pie title Sports in Sweden
|
||||
"Bandy" : 40
|
||||
"Ice-Hockey" : 80
|
||||
"Football" : 90
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple pie diagram with long labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
pie title NETFLIX
|
||||
"Time spent looking for movie" : 90
|
||||
"Time spent watching it" : 10
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple pie diagram with capital letters for labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
pie title What Voldemort doesn't have?
|
||||
"FRIENDS" : 2
|
||||
"FAMILY" : 3
|
||||
"NOSE" : 45
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
});
|
533
cypress/integration/rendering/sequencediagram.spec.js
Normal file
533
cypress/integration/rendering/sequencediagram.spec.js
Normal file
@@ -0,0 +1,533 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
context('Sequence diagram', () => {
|
||||
it('should render a simple sequence diagram', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
participant John as John<br/>Second Line
|
||||
Alice ->> Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?
|
||||
Bob--x Alice: I am good thanks!
|
||||
Bob-x John: I am good thanks!
|
||||
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
|
||||
Bob-->Alice: Checking with John...
|
||||
alt either this
|
||||
Alice->>John: Yes
|
||||
else or this
|
||||
Alice->>John: No
|
||||
else or this will happen
|
||||
Alice->John: Maybe
|
||||
end
|
||||
par this happens in parallel
|
||||
Alice -->> Bob: Parallel message 1
|
||||
and
|
||||
Alice -->> John: Parallel message 2
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should handle different line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant 1 as multiline<br>using #lt;br#gt;
|
||||
participant 2 as multiline<br/>using #lt;br/#gt;
|
||||
participant 3 as multiline<br />using #lt;br /#gt;
|
||||
participant 4 as multiline<br \t/>using #lt;br \t/#gt;
|
||||
1->>2: multiline<br>using #lt;br#gt;
|
||||
note right of 2: multiline<br>using #lt;br#gt;
|
||||
2->>3: multiline<br/>using #lt;br/#gt;
|
||||
note right of 3: multiline<br/>using #lt;br/#gt;
|
||||
3->>4: multiline<br />using #lt;br /#gt;
|
||||
note right of 4: multiline<br />using #lt;br /#gt;
|
||||
4->>1: multiline<br />using #lt;br /#gt;
|
||||
note right of 1: multiline<br \t/>using #lt;br \t/#gt;
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render loops with a slight margin', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
loop Loopy
|
||||
Bob->>Alice: Pasten
|
||||
end `,
|
||||
{}
|
||||
);
|
||||
});
|
||||
context('font settings', () => {
|
||||
it('should render different note fonts when configured', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: I should have bigger fonts
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ sequence: { noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
it('should render different message fonts when configured', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ sequence: { messageFontSize: 18, messageFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
it('should render different actor fonts when configured', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ sequence: { actorFontSize: 18, actorFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
it('should render notes aligned to the left when configured', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: I am left aligned
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ sequence: { noteAlign: 'left' } }
|
||||
);
|
||||
});
|
||||
it('should render notes aligned to the right when configured', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: I am right aligned
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ sequence: { noteAlign: 'right' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
context('auth width scaling', () => {
|
||||
it('should render long actor descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant A as Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{logLevel: 0}
|
||||
);
|
||||
});
|
||||
it('should wrap (inline) long actor descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant A as wrap:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{logLevel: 0}
|
||||
);
|
||||
});
|
||||
it('should wrap (directive) long actor descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: {'config': {'wrap': true }}}%%
|
||||
sequenceDiagram
|
||||
participant A as Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes left of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note left of Alice: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes wrapped (inline) left of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note left of Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes right of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note right of Alice: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes wrapped (inline) right of actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note right of Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes over actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note over Alice: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long notes wrapped (inline) over actor', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hola
|
||||
Note over Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages from an actor to the left to one to the right', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages wrapped (inline) from an actor to the left to one to the right', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob:wrap:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages from an actor to the right to one to the left', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
Bob->>Alice: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render long messages wrapped (inline) from an actor to the right to one to the left', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
Bob->>Alice:wrap: Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
||||
context('background rects', () => {
|
||||
it('should render a single and nested rects', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant A
|
||||
participant B
|
||||
participant C
|
||||
participant D
|
||||
participant E
|
||||
participant G
|
||||
|
||||
A ->>+ B: Task 1
|
||||
rect rgb(178, 102, 255)
|
||||
B ->>+ C: Task 2
|
||||
C -->>- B: Return
|
||||
end
|
||||
|
||||
A ->> D: Task 3
|
||||
rect rgb(0, 128, 255)
|
||||
D ->>+ E: Task 4
|
||||
rect rgb(0, 204, 0)
|
||||
E ->>+ G: Task 5
|
||||
G -->>- E: Return
|
||||
end
|
||||
E ->> E: Task 6
|
||||
end
|
||||
D -->> A: Complete
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render a single and nested opt with long test overflowing', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
participant A
|
||||
participant B
|
||||
participant C
|
||||
participant D
|
||||
participant E
|
||||
participant G
|
||||
|
||||
A ->>+ B: Task 1
|
||||
opt this is an opt with a long title that will overflow
|
||||
B ->>+ C: Task 2
|
||||
C -->>- B: Return
|
||||
end
|
||||
|
||||
A ->> D: Task 3
|
||||
opt this is another opt with a long title that will overflow
|
||||
D ->>+ E: Task 4
|
||||
opt this is a nested opt with a long title that will overflow
|
||||
E ->>+ G: Task 5
|
||||
G -->>- E: Return
|
||||
end
|
||||
E ->> E: Task 6
|
||||
end
|
||||
D -->> A: Complete
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render a single and nested opt with long test wrapping', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'config': { 'wrap': true } } }%%
|
||||
sequenceDiagram
|
||||
participant A
|
||||
participant B
|
||||
participant C
|
||||
participant D
|
||||
participant E
|
||||
participant G
|
||||
|
||||
A ->>+ B: Task 1
|
||||
opt this is an opt with a long title that will overflow
|
||||
B ->>+ C: Task 2
|
||||
C -->>- B: Return
|
||||
end
|
||||
|
||||
A ->> D: Task 3
|
||||
opt this is another opt with a long title that will overflow
|
||||
D ->>+ E: Task 4
|
||||
opt this is a nested opt with a long title that will overflow
|
||||
E ->>+ G: Task 5
|
||||
G -->>- E: Return
|
||||
end
|
||||
E ->> E: Task 6
|
||||
end
|
||||
D -->> A: Complete
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render rect around and inside loops', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
A ->> B: 1
|
||||
rect rgb(204, 0, 102)
|
||||
loop check C
|
||||
C ->> C: Every 10 seconds
|
||||
end
|
||||
end
|
||||
A ->> B: 2
|
||||
loop check D
|
||||
C ->> D: 3
|
||||
rect rgb(153, 153, 255)
|
||||
D -->> D: 5
|
||||
D --> C: 4
|
||||
end
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render rect around and inside alts', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
A ->> B: 1
|
||||
rect rgb(204, 0, 102)
|
||||
alt yes
|
||||
C ->> C: 1
|
||||
else no
|
||||
rect rgb(0, 204, 204)
|
||||
C ->> C: 0
|
||||
end
|
||||
end
|
||||
end
|
||||
B ->> A: Return
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render rect around and inside opts', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
A ->> B: 1
|
||||
rect rgb(204, 0, 102)
|
||||
opt maybe
|
||||
C -->> D: Do something
|
||||
rect rgb(0, 204, 204)
|
||||
C ->> C: 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
opt possibly
|
||||
rect rgb(0, 204, 204)
|
||||
C ->> C: 0
|
||||
end
|
||||
end
|
||||
B ->> A: Return
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render autonumber when configured with such', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
`,
|
||||
{ sequence: { actorMargin: 50, showSequenceNumbers: true } }
|
||||
);
|
||||
});
|
||||
it('should render autonumber when autonumber keyword is used', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render autonumber with different line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
Alice->>John: Hello John,<br>how are you?
|
||||
Alice->>John: John,<br/>can you hear me?
|
||||
John-->>Alice: Hi Alice,<br />I can hear you!
|
||||
John-->>Alice: I feel great!
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render dark theme from init directive and configure font size 24 font', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: {'theme': 'dark', 'config': {'fontSize': 24}}}%%
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
Alice->>John: John, can you hear me?
|
||||
John-->>Alice: Hi Alice, I can hear you!
|
||||
John-->>Alice: I feel great!
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render with wrapping enabled', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { 'config': { 'wrap': true }}}%%
|
||||
sequenceDiagram
|
||||
participant A as Alice, the talkative one
|
||||
A->>John: Hello John, how are you today? I'm feeling quite verbose today.
|
||||
A->>John: John, can you hear me? If you are not available, we can talk later.
|
||||
John-->>A: Hi Alice, I can hear you! I was finishing up an important meeting.
|
||||
John-->>A: I feel great! I was not ignoring you. I am sorry you had to wait for a response.
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should render with an init directive', () => {
|
||||
imgSnapshotTest(
|
||||
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can!
|
||||
Note left of Alice: Bob thinks
|
||||
Bob->>Alice: Fine!`,
|
||||
{}
|
||||
)
|
||||
});
|
||||
});
|
||||
context('directives', () => {
|
||||
it('should overide config with directive settings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: config set to mirrorActors: false<br/>directive set to mirrorActors: true
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ logLevel:0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
it('should overide config with directive settings', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
%%{init: { "config": { "mirrorActors": false, "wrap": true }}}%%
|
||||
sequenceDiagram
|
||||
Alice->>Bob: I'm short
|
||||
note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
|
||||
Bob->>Alice: Short as well
|
||||
`,
|
||||
{ logLevel:0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
358
cypress/integration/rendering/stateDiagram-v2.spec.js
Normal file
358
cypress/integration/rendering/stateDiagram-v2.spec.js
Normal file
@@ -0,0 +1,358 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
it('v2 should render a simple info', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
info
|
||||
`,
|
||||
{ logLevel: 1 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a simple state diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
|
||||
[*] --> State1
|
||||
State1 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a long descriptions instead of id when available', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
|
||||
[*] --> S1
|
||||
state "Some long name" as S1
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a long descriptions with additional descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
|
||||
[*] --> S1
|
||||
state "Some long name" as S1: The description
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a single state with short descr', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
state "A long long name" as long1
|
||||
state "A" as longlonglongid
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a transition descrions with new lines', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
|
||||
[*] --> S1
|
||||
S1 --> S2: long line using<br/>should work
|
||||
S1 --> S3: long line using <br>should work
|
||||
S1 --> S4: long line using \\nshould work
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a state with a note', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You can write
|
||||
notes.
|
||||
end note
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a state with on the left side when so specified', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
State1: The state with a note with minus - and plus + in it
|
||||
note left of State1
|
||||
Important information! You can write
|
||||
notes with . and in them.
|
||||
end note
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a state with a note together with another state', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
State1: The state with a note +,-
|
||||
note right of State1
|
||||
Important information! You can write +,-
|
||||
notes.
|
||||
end note
|
||||
State1 --> State2 : With +,-
|
||||
note left of State2 : This is the note +,-<br/>
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a note with multiple lines in it', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You\ncan write
|
||||
notes with multiple lines...
|
||||
Here is another line...
|
||||
And another line...
|
||||
end note
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('v2 should handle multiline notes with different line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
State1
|
||||
note right of State1
|
||||
Line1<br>Line2<br/>Line3<br />Line4<br />Line5
|
||||
end note
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('v2 should render a states with descriptions including multi-line descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
State1: This a a single line description
|
||||
State2: This a a multi line description
|
||||
State2: here comes the multi part
|
||||
[*] --> State1
|
||||
State1 --> State2
|
||||
State2 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a simple state diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
[*] --> State1
|
||||
State1 --> State2
|
||||
State1 --> State3
|
||||
State1 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a simple state diagrams with labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
[*] --> State1
|
||||
State1 --> State2 : Transition 1
|
||||
State1 --> State3 : Transition 2
|
||||
State1 --> State4 : Transition 3
|
||||
State1 --> State5 : Transition 4
|
||||
State2 --> State3 : Transition 5
|
||||
State1 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render state descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
state "Long state description" as XState1
|
||||
state "Another Long state description" as XState2
|
||||
XState2 : New line
|
||||
XState1 --> XState2
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render composit states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
[*] --> NotShooting: Pacifist
|
||||
NotShooting --> A
|
||||
NotShooting --> B
|
||||
NotShooting --> C
|
||||
|
||||
state NotShooting {
|
||||
[*] --> Idle: Yet another long long öong öong öong label
|
||||
Idle --> Configuring : EvConfig
|
||||
Configuring --> Idle : EvConfig EvConfig EvConfig EvConfig EvConfig
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render multiple composit states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
[*]-->TV
|
||||
|
||||
state TV {
|
||||
[*] --> Off: Off to start with
|
||||
On --> Off : Turn off
|
||||
Off --> On : Turn on
|
||||
}
|
||||
|
||||
TV--> Console
|
||||
|
||||
state Console {
|
||||
[*] --> Off2: Off to start with
|
||||
On2--> Off2 : Turn off
|
||||
Off2 --> On2 : Turn on
|
||||
On2-->Playing
|
||||
|
||||
state Playing {
|
||||
Alive --> Dead
|
||||
Dead-->Alive
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
});
|
||||
it('v2 should render forks in composit states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
[*]-->TV
|
||||
|
||||
state TV {
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
fork_state --> State2
|
||||
fork_state --> State3
|
||||
|
||||
state join_state <<join>>
|
||||
State2 --> join_state
|
||||
State3 --> join_state
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
});
|
||||
it('v2 should render forks and joins', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
fork_state --> State2
|
||||
fork_state --> State3
|
||||
|
||||
state join_state <<join>>
|
||||
State2 --> join_state
|
||||
State3 --> join_state
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render concurrency states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
|
||||
state Active {
|
||||
[*] --> NumLockOff
|
||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
||||
--
|
||||
[*] --> CapsLockOff
|
||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
||||
--
|
||||
[*] --> ScrollLockOff
|
||||
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
|
||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('v2 should render a state with states in it', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
state PilotCockpit {
|
||||
state Parent {
|
||||
C
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
it('v2 Simplest composit state', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
state Parent {
|
||||
C
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
it('v2 should handle multiple arrows from one node to another', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram-v2
|
||||
a --> b: Start
|
||||
a --> b: Stop
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
348
cypress/integration/rendering/stateDiagram.spec.js
Normal file
348
cypress/integration/rendering/stateDiagram.spec.js
Normal file
@@ -0,0 +1,348 @@
|
||||
/* eslint-env jest */
|
||||
import { imgSnapshotTest } from '../../helpers/util';
|
||||
|
||||
describe('State diagram', () => {
|
||||
it('should render a simple state diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*] --> State1
|
||||
State1 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a long descriptions instead of id when available', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
|
||||
[*] --> S1
|
||||
state "Some long name" as S1
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a long descriptions with additional descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
|
||||
[*] --> S1
|
||||
state "Some long name" as S1: The description
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a single state with short descr', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state "A long long name" as long1
|
||||
state "A" as longlonglongid
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a transition descrions with new lines', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
|
||||
[*] --> S1
|
||||
S1 --> S2: long line using<br/>should work
|
||||
S1 --> S3: long line using <br>should work
|
||||
S1 --> S4: long line using \\nshould work
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state with a note', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You can write
|
||||
notes.
|
||||
end note
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state with on the left side when so specified', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1: The state with a note with minus - and plus + in it
|
||||
note left of State1
|
||||
Important information! You can write
|
||||
notes with . and in them.
|
||||
end note
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state with a note together with another state', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1: The state with a note +,-
|
||||
note right of State1
|
||||
Important information! You can write +,-
|
||||
notes.
|
||||
end note
|
||||
State1 --> State2 : With +,-
|
||||
note left of State2 : This is the note +,-<br/>
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a note with multiple lines in it', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You\ncan write
|
||||
notes with multiple lines...
|
||||
Here is another line...
|
||||
And another line...
|
||||
end note
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('should handle multiline notes with different line breaks', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1
|
||||
note right of State1
|
||||
Line1<br>Line2<br/>Line3<br />Line4<br />Line5
|
||||
end note
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a states with descriptions including multi-line descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
State1: This a a single line description
|
||||
State2: This a a multi line description
|
||||
State2: here comes the multi part
|
||||
[*] --> State1
|
||||
State1 --> State2
|
||||
State2 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple state diagrams', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*] --> State1
|
||||
State1 --> State2
|
||||
State1 --> State3
|
||||
State1 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a simple state diagrams with labels', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*] --> State1
|
||||
State1 --> State2 : Transition 1
|
||||
State1 --> State3 : Transition 2
|
||||
State1 --> State4 : Transition 3
|
||||
State1 --> State5 : Transition 4
|
||||
State2 --> State3 : Transition 5
|
||||
State1 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render state descriptions', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state "Long state description" as XState1
|
||||
state "Another Long state description" as XState2
|
||||
XState2 : New line
|
||||
XState1 --> XState2
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render composit states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*] --> NotShooting: Pacifist
|
||||
NotShooting --> A
|
||||
NotShooting --> B
|
||||
NotShooting --> C
|
||||
|
||||
state NotShooting {
|
||||
[*] --> Idle: Yet another long long öong öong öong label
|
||||
Idle --> Configuring : EvConfig
|
||||
Configuring --> Idle : EvConfig EvConfig EvConfig EvConfig EvConfig
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render multiple composit states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*]-->TV
|
||||
|
||||
state TV {
|
||||
[*] --> Off: Off to start with
|
||||
On --> Off : Turn off
|
||||
Off --> On : Turn on
|
||||
}
|
||||
|
||||
TV--> Console
|
||||
|
||||
state Console {
|
||||
[*] --> Off2: Off to start with
|
||||
On2--> Off2 : Turn off
|
||||
Off2 --> On2 : Turn on
|
||||
On2-->Playing
|
||||
|
||||
state Playing {
|
||||
Alive --> Dead
|
||||
Dead-->Alive
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
});
|
||||
it('should render forks in composit states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*]-->TV
|
||||
|
||||
state TV {
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
fork_state --> State2
|
||||
fork_state --> State3
|
||||
|
||||
state join_state <<join>>
|
||||
State2 --> join_state
|
||||
State3 --> join_state
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
});
|
||||
it('should render forks and joins', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state fork_state <<fork>>
|
||||
[*] --> fork_state
|
||||
fork_state --> State2
|
||||
fork_state --> State3
|
||||
|
||||
state join_state <<join>>
|
||||
State2 --> join_state
|
||||
State3 --> join_state
|
||||
join_state --> State4
|
||||
State4 --> [*]
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render conurrency states', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
[*] --> Active
|
||||
|
||||
state Active {
|
||||
[*] --> NumLockOff
|
||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
||||
--
|
||||
[*] --> CapsLockOff
|
||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
||||
--
|
||||
[*] --> ScrollLockOff
|
||||
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
|
||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
||||
}
|
||||
`,
|
||||
{ logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('should render a state with states in it', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state PilotCockpit {
|
||||
state Parent {
|
||||
C
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
it('Simplest composit state', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
state Parent {
|
||||
C
|
||||
}
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should handle multiple arrows from one node to another', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
stateDiagram
|
||||
a --> b: Start
|
||||
a --> b: Stop
|
||||
`,
|
||||
{
|
||||
logLevel: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
10
cypress/platform/bundle-test.js
Normal file
10
cypress/platform/bundle-test.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import mermaid from '../../dist/mermaid.core'
|
||||
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
gantt: { axisFormatter: [
|
||||
['%Y-%m-%d', (d) => {
|
||||
return d.getDay() === 1
|
||||
}]
|
||||
] }
|
||||
})
|
88
cypress/platform/click_security_loose.html
Normal file
88
cypress/platform/click_security_loose.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
</head>
|
||||
<body>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
Function-->URL
|
||||
click Function clickByFlow "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
1Function-->2URL
|
||||
click 1Function clickByFlow "Add a div"
|
||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Clickable
|
||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
Calling a Callback with args :cl3, after cl1, 3d
|
||||
|
||||
click cl1 href "http://localhost:9000/webpackUsage.html"
|
||||
click cl2 call clickByGantt()
|
||||
click cl3 call clickByGantt("test1", test2, test3)
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByGantt(arg1, arg2, arg3) {
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-gant-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Gant'
|
||||
if (arg1) div.innerText += ' ' + arg1;
|
||||
if (arg2) div.innerText += ' ' + arg2;
|
||||
if (arg3) div.innerText += ' ' + arg3;
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
83
cypress/platform/click_security_other.html
Normal file
83
cypress/platform/click_security_other.html
Normal file
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
</head>
|
||||
<body>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
Function-->URL
|
||||
click Function clickByFlow "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
1Function-->2URL
|
||||
click 1Function clickByFlow "Add a div"
|
||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Clickable
|
||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
|
||||
click cl1 href "http://localhost:9000/webpackUsage.html"
|
||||
click cl2 call clickByGantt("test", test, test)
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByGantt(elemName) {
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-gant-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Gant'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'strct', logLevel: 1 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
88
cypress/platform/click_security_strict.html
Normal file
88
cypress/platform/click_security_strict.html
Normal file
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
</head>
|
||||
<body>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
Function-->URL
|
||||
click Function clickByFlow "Add a div"
|
||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
<div id="FirstLine" class="mermaid">
|
||||
graph TB
|
||||
1Function-->2URL
|
||||
click 1Function clickByFlow "Add a div"
|
||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Clickable
|
||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
Calling a Callback with args :cl3, after cl1, 3d
|
||||
|
||||
click cl1 href "http://localhost:9000/webpackUsage.html"
|
||||
click cl2 call clickByGantt()
|
||||
click cl3 call clickByGantt("test1", test2, test3)
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function clickByFlow(elemName) {
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Flow'
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
function clickByGantt(arg1, arg2, arg3) {
|
||||
const div = document.createElement('div')
|
||||
div.className = 'created-by-gant-click'
|
||||
div.style = 'padding: 20px; background: green; color: white;'
|
||||
div.innerText = 'Clicked By Gant'
|
||||
if (arg1) div.innerText += ' ' + arg1;
|
||||
if (arg2) div.innerText += ' ' + arg2;
|
||||
if (arg3) div.innerText += ' ' + arg3;
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(div)
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'strict', logLevel: 1 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
106
cypress/platform/current.html
Normal file
106
cypress/platform/current.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
/* background: rgb(221, 208, 208); */
|
||||
/* background:#333; */
|
||||
font-family: 'Arial';
|
||||
}
|
||||
h1 { color: grey;}
|
||||
.mermaid2 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="flex">
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
flowchart BT
|
||||
subgraph two
|
||||
b1
|
||||
end
|
||||
subgraph three
|
||||
c1-->c2
|
||||
end
|
||||
c1 --apa apa apa--> b1
|
||||
two --> c2
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 200px;">
|
||||
sequenceDiagram
|
||||
Alice->>Bob:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
|
||||
Bob->>Alice: I'm short though
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 200px;">
|
||||
%%{init: {'securityLevel': 'loose'}}%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
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?}}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B callback "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 200px;">
|
||||
|
||||
flowchart BT
|
||||
subgraph a
|
||||
b1 -- ok --> b2
|
||||
end
|
||||
a -- sert --> c
|
||||
c --> d
|
||||
b1 --> d
|
||||
a --asd123 --> d
|
||||
</div>
|
||||
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||
stateDiagram-v2
|
||||
state A {
|
||||
B1 --> B2: ok
|
||||
}
|
||||
A --> C: sert
|
||||
C --> D
|
||||
B1 --> D
|
||||
A --> D: asd123
|
||||
</div>
|
||||
</div>
|
||||
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||
|
||||
classDiagram
|
||||
Customer "1" --> "*" Ticket
|
||||
Student "1" --> "1..*" Course
|
||||
Galaxy --> "many" Star : Contains
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.parseError = function (err, hash) {
|
||||
// console.error('Mermaid error: ', err);
|
||||
};
|
||||
mermaid.initialize({
|
||||
// theme: 'dark',
|
||||
// arrowMarkerAbsolute: true,
|
||||
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||
logLevel: 0,
|
||||
flowchart: { curve: 'cardinal', "htmlLabels": false },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
fontFamily: '"arial", sans-serif',
|
||||
curve: 'cardinal',
|
||||
securityLevel: 'strict'
|
||||
});
|
||||
function callback(){alert('It worked');}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
41
cypress/platform/e2e.html
Normal file
41
cypress/platform/e2e.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="/e2e.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
/* font-family: 'Mansalva', cursive;*/
|
||||
font-family: 'Mansalva', cursive;
|
||||
}
|
||||
/* .mermaid-main-font {
|
||||
font-family: "trebuchet ms", verdana, arial;
|
||||
font-family: var(--mermaid-font-family);
|
||||
} */
|
||||
/* :root {
|
||||
--mermaid-font-family: '"trebuchet ms", verdana, arial';
|
||||
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
|
||||
--mermaid-font-family: '"Lucida Console", Monaco, monospace';
|
||||
} */
|
||||
svg {
|
||||
border: 2px solid darkred;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
// Notice startOnLoad=false
|
||||
// This prevents default handling in mermaid from render before the e2e logic is applied
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
useMaxWidth: true,
|
||||
// "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
|
||||
// fontFamily: '\"trebuchet ms\", verdana, arial;'
|
||||
// fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
|
||||
// fontFamily: '"Mansalva", cursive',
|
||||
fontFamily: '"Noto Sans SC", sans-serif'
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
46
cypress/platform/flow.html
Normal file
46
cypress/platform/flow.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2-->a3
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
a_a --> b_b:::apa --> c_c:::apa
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
|
||||
a_a --> c --> d_d --> c_c
|
||||
classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
|
||||
class a_a apa;
|
||||
click a_a "http://www.aftonbladet.se" "apa"
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
flowchart: { curve: 'linear' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
39
cypress/platform/huge.html
Normal file
39
cypress/platform/huge.html
Normal file
File diff suppressed because one or more lines are too long
26
cypress/platform/info.html
Normal file
26
cypress/platform/info.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>info below</h1>
|
||||
<div class="mermaid">info</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
flowchart: { curve: 'linear' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
32
cypress/platform/render-after-error.html
Normal file
32
cypress/platform/render-after-error.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
</head>
|
||||
<body>
|
||||
<div id="graph">
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
|
||||
mermaid.init({ startOnLoad: false });
|
||||
mermaid.mermaidAPI.initialize();
|
||||
|
||||
try{
|
||||
mermaid.mermaidAPI.render("graphDiv",
|
||||
`>`);
|
||||
} catch(e){}
|
||||
|
||||
mermaid.mermaidAPI.render("graphDiv",
|
||||
`graph LR\n a --> b`, html => {
|
||||
document.getElementById('graph').innerHTML=html;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
33
cypress/platform/rerender.html
Normal file
33
cypress/platform/rerender.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
</head>
|
||||
<body>
|
||||
<div id="graph">
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
|
||||
mermaid.init({ startOnLoad: false });
|
||||
mermaid.mermaidAPI.initialize();
|
||||
|
||||
rerender('XMas');
|
||||
|
||||
function rerender(text) {
|
||||
var graphText = `graph TD
|
||||
A[${text}] -->|Get money| B(Go shopping)`
|
||||
var graph = mermaid.mermaidAPI.render('id', graphText);
|
||||
console.log('\x1b[35m%s\x1b[0m', '>> graph', graph)
|
||||
document.getElementById('graph').innerHTML=graph;
|
||||
}
|
||||
|
||||
</script>
|
||||
<button id="rerender" onclick="rerender('Saturday')">Rerender</button>
|
||||
|
||||
</body>
|
||||
</html>
|
45
cypress/platform/subgraph.html
Normal file
45
cypress/platform/subgraph.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
subgraph 1test["id starting with number"]
|
||||
A
|
||||
end
|
||||
style 1test fill:#F99,stroke-width:2px,stroke:#F0F
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A.a[Christmas]:::someclass -->|Get money| B(Go shopping):::someclass
|
||||
subgraph test["id starting with number"]
|
||||
A.a
|
||||
end
|
||||
style test fill:#F99,stroke-width:2px,stroke:#F0F
|
||||
classDef someclass fill:#f96;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
9e122290-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
style 9e122290 fill:#F99,stroke-width:2px,stroke:#F0F
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function showFullFirstSquad(elemName) {
|
||||
console.log('show ' + elemName);
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
41
cypress/platform/user-journey.html
Normal file
41
cypress/platform/user-journey.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>User Journey</h1>
|
||||
<div class="mermaid">
|
||||
journey
|
||||
title Go shopping
|
||||
|
||||
section Get to the shops
|
||||
Get car keys:5: Dad
|
||||
Get into car:5: Dad, Mum, Child 1, Child 2
|
||||
Really drive to supermarket:3: Dad
|
||||
|
||||
section Do shopping
|
||||
Do actual shop:3: Mum
|
||||
Get in the way:2: Dad, Child 1, Child 2
|
||||
Pay: 2: Dad
|
||||
|
||||
section Go home
|
||||
Lose keys:3: Dad
|
||||
Get cross:1: Dad, Child 1
|
||||
Find keys:4: Mum
|
||||
Get into car:4: Dad, Mum, Child 1, Child 2
|
||||
Drive home:3: Dad
|
||||
</div>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
logLevel: 3,
|
||||
journey: { taskMargin: 30 },
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
37
cypress/platform/vertices.html
Normal file
37
cypress/platform/vertices.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
info
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
subgraph one
|
||||
1
|
||||
end
|
||||
</div>
|
||||
<!-- <div class="mermaid">
|
||||
graph TD
|
||||
A --> B --> C
|
||||
</div> -->
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
function showFullFirstSquad(elemName) {
|
||||
console.log('show ' + elemName);
|
||||
}
|
||||
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
111
cypress/platform/viewer.js
Normal file
111
cypress/platform/viewer.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import { Base64 } from 'js-base64';
|
||||
import mermaid2 from '../../src/mermaid';
|
||||
|
||||
/**
|
||||
* ##contentLoaded
|
||||
* Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
|
||||
* calls init for rendering the mermaid diagrams on the page.
|
||||
*/
|
||||
const contentLoaded = function() {
|
||||
let pos = document.location.href.indexOf('?graph=');
|
||||
if (pos > 0) {
|
||||
pos = pos + 7;
|
||||
const graphBase64 = document.location.href.substr(pos);
|
||||
const graphObj = JSON.parse(Base64.decode(graphBase64));
|
||||
// const graph = 'hello'
|
||||
console.log(graphObj);
|
||||
if (Array.isArray(graphObj.code)) {
|
||||
const numCodes = graphObj.code.length;
|
||||
for (let i = 0; i < numCodes; i++) {
|
||||
const div = document.createElement('div');
|
||||
div.id = 'block' + i;
|
||||
div.className = 'mermaid';
|
||||
div.innerHTML = graphObj.code[i];
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
} else {
|
||||
const div = document.createElement('div');
|
||||
div.id = 'block';
|
||||
div.className = 'mermaid';
|
||||
div.innerHTML = graphObj.code;
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
global.mermaid.initialize(graphObj.mermaid);
|
||||
global.mermaid.init();
|
||||
}
|
||||
};
|
||||
const contentLoadedApi = function() {
|
||||
let pos = document.location.href.indexOf('?graph=');
|
||||
if (pos > 0) {
|
||||
pos = pos + 7;
|
||||
const graphBase64 = document.location.href.substr(pos);
|
||||
const graphObj = JSON.parse(Base64.decode(graphBase64));
|
||||
// const graph = 'hello'
|
||||
if (Array.isArray(graphObj.code)) {
|
||||
const numCodes = graphObj.code.length;
|
||||
const divs = [];
|
||||
let div;
|
||||
for (let i = 0; i < numCodes; i++) {
|
||||
div = document.createElement('div');
|
||||
div.id = 'block' + i;
|
||||
div.className = 'mermaid';
|
||||
// div.innerHTML = graphObj.code
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
divs[i] = div;
|
||||
}
|
||||
|
||||
mermaid2.initialize(graphObj.mermaid);
|
||||
|
||||
for (let i = 0; i < numCodes; i++) {
|
||||
mermaid2.render(
|
||||
'newid' + i,
|
||||
graphObj.code[i],
|
||||
(svgCode, bindFunctions) => {
|
||||
div.innerHTML = svgCode;
|
||||
|
||||
bindFunctions(div);
|
||||
},
|
||||
divs[i]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const div = document.createElement('div');
|
||||
div.id = 'block';
|
||||
div.className = 'mermaid';
|
||||
// div.innerHTML = graphObj.code
|
||||
console.warn('graphObj.mermaid', graphObj.mermaid);
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
mermaid2.initialize(graphObj.mermaid);
|
||||
|
||||
mermaid2.render(
|
||||
'newid',
|
||||
graphObj.code,
|
||||
(svgCode, bindFunctions) => {
|
||||
div.innerHTML = svgCode;
|
||||
|
||||
if (bindFunctions) bindFunctions(div);
|
||||
},
|
||||
div
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
/*!
|
||||
* Wait for document loaded before starting the execution
|
||||
*/
|
||||
window.addEventListener(
|
||||
'load',
|
||||
function() {
|
||||
if (this.location.href.match('xss.html')) {
|
||||
this.console.log('Using api');
|
||||
contentLoadedApi();
|
||||
} else {
|
||||
this.console.log('Not using api');
|
||||
contentLoaded();
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
23
cypress/platform/webpackUsage.html
Normal file
23
cypress/platform/webpackUsage.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A-->B
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
</div>
|
||||
<script src="./bundle-test.js" charset="utf-8"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
47
cypress/platform/xss.html
Normal file
47
cypress/platform/xss.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="/e2e.js"></script>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
.malware {
|
||||
position: fixed;
|
||||
bottom:0;
|
||||
left:0;
|
||||
right:0;
|
||||
height: 150px;
|
||||
background: red;
|
||||
color: black;
|
||||
display: flex;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: monospace;
|
||||
font-size: 72px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function xssAttack(){
|
||||
const div = document.createElement('div')
|
||||
div.id = 'the-malware'
|
||||
div.className = 'malware'
|
||||
div.innerHTML = 'XSS Succeeded'
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
// const el = document.querySelector('.mermaid');
|
||||
// el.parentNode.removeChild(el);
|
||||
throw new Error('XSS Succeded');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
useMaxWidth: true,
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
BIN
cypress/platform/xss.png
Normal file
BIN
cypress/platform/xss.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
25
cypress/plugins/index.js
Normal file
25
cypress/plugins/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
// module.exports = (on, config) => {
|
||||
// // `on` is used to hook into various events Cypress emits
|
||||
// // `config` is the resolved Cypress config
|
||||
// }
|
||||
|
||||
let percyHealthCheck = require("@percy/cypress/task");
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
on("task", percyHealthCheck);
|
||||
};
|
27
cypress/support/commands.js
Normal file
27
cypress/support/commands.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
import '@percy/cypress'
|
20
cypress/support/index.js
Normal file
20
cypress/support/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
106
dist/demo/index.html
vendored
106
dist/demo/index.html
vendored
@@ -1,106 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<link rel="stylesheet" href="../mermaid.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
loop every day
|
||||
Alice->>John: Hello John, how are you?
|
||||
John-->>Alice: Great!
|
||||
end
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram to mermaid
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
gitGraph:
|
||||
options
|
||||
{
|
||||
"nodeSpacing": 150,
|
||||
"nodeRadius": 10
|
||||
}
|
||||
end
|
||||
commit
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit
|
||||
commit
|
||||
checkout master
|
||||
commit
|
||||
commit
|
||||
merge newbranch
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class03 *-- Class04
|
||||
Class05 o-- Class06
|
||||
Class07 .. Class08
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
</div>
|
||||
<script src="../mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({startOnLoad: true});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
9
dist/demo/index.js
vendored
9
dist/demo/index.js
vendored
@@ -1,9 +0,0 @@
|
||||
const api = require('../mermaidAPI.js')
|
||||
|
||||
const r = api.parse(`sequenceDiagram
|
||||
loop every day
|
||||
Alice->>John: Hello John, how are you?
|
||||
John-->>Alice: Great!
|
||||
end`)
|
||||
|
||||
console.log(r)
|
721
dist/index.html
vendored
Normal file
721
dist/index.html
vendored
Normal file
@@ -0,0 +1,721 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<style>
|
||||
div.mermaid {
|
||||
/* font-family: 'trebuchet ms', verdana, arial; */
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mermaid">
|
||||
info
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title Exclusive end dates (Manual date should end on 3d)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
section Section1
|
||||
2 Days: 1, 2019-01-01,2d
|
||||
Manual Date: 2, 2019-01-01,2019-01-03
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title Inclusive end dates (Manual date should end on 4th)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
inclusiveEndDates
|
||||
section Section1
|
||||
2 Days: 1, 2019-01-01,2d
|
||||
Manual Date: 2, 2019-01-01,2019-01-03
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title Hide today marker (vertical line should not be visible)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
todayMarker off
|
||||
section Section1
|
||||
Today: 1, -1h
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title Style today marker (vertical line should be 5px wide and half-transparent blue)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||
section Section1
|
||||
Today: 1, -1h
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||
|
||||
提交申请
|
||||
熊大
|
||||
"];
|
||||
class sid-B3655226-6C29-4D00-B685-3D5C734DC7E1 node-executed;
|
||||
sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A["
|
||||
负责人审批
|
||||
强子
|
||||
"];
|
||||
class sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A node-executed;
|
||||
sid-E27C0367-E6D6-497F-9736-3CDC21FDE221["
|
||||
DBA审批
|
||||
强子
|
||||
"];
|
||||
class sid-E27C0367-E6D6-497F-9736-3CDC21FDE221 node-executed;
|
||||
sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD["
|
||||
SA审批
|
||||
阿美
|
||||
"];
|
||||
class sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD node-executed;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7["
|
||||
主管审批
|
||||
光头强
|
||||
"];
|
||||
class sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7 node-executed;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89["
|
||||
DBA确认
|
||||
强子
|
||||
"];
|
||||
class sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89 node-executed;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937["
|
||||
SA确认
|
||||
阿美
|
||||
"];
|
||||
class sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937 node-executed;
|
||||
sid-4FC27B48-A6F9-460A-A675-021F5854FE22["
|
||||
结束
|
||||
"];
|
||||
class sid-4FC27B48-A6F9-460A-A675-021F5854FE22 node-executed;
|
||||
sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E["
|
||||
SA执行1
|
||||
强子
|
||||
"];
|
||||
class sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E node-executed;
|
||||
sid-6C2120F3-D940-4958-A067-0903DCE879C4["
|
||||
SA执行2
|
||||
强子
|
||||
"];
|
||||
class sid-6C2120F3-D940-4958-A067-0903DCE879C4 node-executed;
|
||||
sid-9180E2A0-5C4B-435F-B42F-0D152470A338["
|
||||
DBA执行1
|
||||
强子
|
||||
"];
|
||||
class sid-9180E2A0-5C4B-435F-B42F-0D152470A338 node-executed;
|
||||
sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD["
|
||||
DBA执行3
|
||||
强子
|
||||
"];
|
||||
class sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD node-executed;
|
||||
sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756["
|
||||
DBA执行2
|
||||
强子
|
||||
"];
|
||||
class sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756 node-executed;
|
||||
sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93["
|
||||
DBA执行4
|
||||
强子
|
||||
"];
|
||||
class sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93 node-executed;
|
||||
sid-1897B30A-9C5C-4D5B-B80B-76A038785070["
|
||||
负责人确认
|
||||
梁静茹
|
||||
"];
|
||||
class sid-1897B30A-9C5C-4D5B-B80B-76A038785070 node-executed;
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1-->sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7;
|
||||
sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A-->sid-1897B30A-9C5C-4D5B-B80B-76A038785070;
|
||||
sid-E27C0367-E6D6-497F-9736-3CDC21FDE221-->sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89;
|
||||
sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD-->sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937;
|
||||
sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
|
||||
sid-9180E2A0-5C4B-435F-B42F-0D152470A338-->sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756;
|
||||
sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD-->sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93;
|
||||
sid-6C2120F3-D940-4958-A067-0903DCE879C4-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-1897B30A-9C5C-4D5B-B80B-76A038785070-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-9180E2A0-5C4B-435F-B42F-0D152470A338;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD;
|
||||
sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-E27C0367-E6D6-497F-9736-3CDC21FDE221;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssssx<br/>sssssssssssssssssssuuu<br />tttsssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A[/Christmas\]
|
||||
A -->|Get money| B[\Go shopping/]
|
||||
B --> C{Let me thinksssss<br/>ssssssssssssssssssssss<br/>sssssssssssssssssssssssssss}
|
||||
C -->|One| D[/Laptop/]
|
||||
C -->|Two| E[\iPhone\]
|
||||
C -->|Three| F[Car]
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
47(SAM.CommonFA.FMESummary)-->48(SAM.CommonFA.CommonFAFinanceBudget)
|
||||
37(SAM.CommonFA.BudgetSubserviceLineVolume)-->48(SAM.CommonFA.CommonFAFinanceBudget)
|
||||
35(SAM.CommonFA.PopulationFME)-->47(SAM.CommonFA.FMESummary)
|
||||
41(SAM.CommonFA.MetricCost)-->47(SAM.CommonFA.FMESummary)
|
||||
44(SAM.CommonFA.MetricOutliers)-->47(SAM.CommonFA.FMESummary)
|
||||
46(SAM.CommonFA.MetricOpportunity)-->47(SAM.CommonFA.FMESummary)
|
||||
40(SAM.CommonFA.OPVisits)-->47(SAM.CommonFA.FMESummary)
|
||||
38(SAM.CommonFA.CommonFAFinanceRefund)-->47(SAM.CommonFA.FMESummary)
|
||||
43(SAM.CommonFA.CommonFAFinancePicuDays)-->47(SAM.CommonFA.FMESummary)
|
||||
42(SAM.CommonFA.CommonFAFinanceNurseryDays)-->47(SAM.CommonFA.FMESummary)
|
||||
45(SAM.CommonFA.MetricPreOpportunity)-->46(SAM.CommonFA.MetricOpportunity)
|
||||
35(SAM.CommonFA.PopulationFME)-->45(SAM.CommonFA.MetricPreOpportunity)
|
||||
41(SAM.CommonFA.MetricCost)-->45(SAM.CommonFA.MetricPreOpportunity)
|
||||
41(SAM.CommonFA.MetricCost)-->44(SAM.CommonFA.MetricOutliers)
|
||||
39(SAM.CommonFA.ChargeDetails)-->43(SAM.CommonFA.CommonFAFinancePicuDays)
|
||||
39(SAM.CommonFA.ChargeDetails)-->42(SAM.CommonFA.CommonFAFinanceNurseryDays)
|
||||
39(SAM.CommonFA.ChargeDetails)-->41(SAM.CommonFA.MetricCost)
|
||||
39(SAM.CommonFA.ChargeDetails)-->40(SAM.CommonFA.OPVisits)
|
||||
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
|
||||
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002("fa:fa-creative-commons My System | Test Environment")
|
||||
82072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 1")
|
||||
db052290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 2")
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 1")
|
||||
30122290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 2")
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 1")
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 2")
|
||||
b7042290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[SupportDb]")
|
||||
8f102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[DevelopmentDb]")
|
||||
0e102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[TestDb]")
|
||||
07132290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[SharedReportingDb]")
|
||||
c7072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Business Logic Server")
|
||||
ca122290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Report Server")
|
||||
68102290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Dedicated Test Business Logic Server")
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002("fa:fa-database [DBServer\SharedDbInstance]")
|
||||
d6072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server DBServer")
|
||||
71082290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\:MSSQLSERVER")
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\:SQLAgent")
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\:SQLBrowser")
|
||||
1d0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost1")
|
||||
200a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost2")
|
||||
1c0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost3")
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->db052290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->30122290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->c1112290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
|
||||
db052290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
|
||||
db052290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->07132290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
|
||||
30122290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
|
||||
30122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
|
||||
b7042290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
8f102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
0e102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
07132290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
c7072290_1ec3_e711_8c5a_005056ad0002-->1d0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
ca122290_1ec3_e711_8c5a_005056ad0002-->200a2290_1ec3_e711_8c5a_005056ad0002
|
||||
68102290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->c0102290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->9a072290_1ec3_e711_8c5a_005056ad0002
|
||||
d6072290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
71082290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
A
|
||||
B
|
||||
subgraph foo[Foo SubGraph]
|
||||
C
|
||||
D
|
||||
end
|
||||
subgraph bar[Bar SubGraph]
|
||||
E
|
||||
F
|
||||
end
|
||||
G
|
||||
|
||||
A-->B
|
||||
B-->C
|
||||
C-->D
|
||||
B-->D
|
||||
D-->E
|
||||
E-->A
|
||||
E-->F
|
||||
F-->D
|
||||
F-->G
|
||||
B-->G
|
||||
G-->D
|
||||
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
456ac9b0d15a8b7f1e71073221059886[1051 AAA fa:fa-check]
|
||||
f7f580e11d00a75814d2ded41fe8e8fe[1141 BBB fa:fa-check]
|
||||
81dc9bdb52d04dc20036dbd8313ed055[1234 CCC fa:fa-check]
|
||||
456ac9b0d15a8b7f1e71073221059886 -->|Node| f7f580e11d00a75814d2ded41fe8e8fe
|
||||
f7f580e11d00a75814d2ded41fe8e8fe -->|Node| 81dc9bdb52d04dc20036dbd8313ed055
|
||||
click 456ac9b0d15a8b7f1e71073221059886 "/admin/user/view?id=1051" "AAA
|
||||
6000"
|
||||
click f7f580e11d00a75814d2ded41fe8e8fe "/admin/user/view?id=1141" "BBB
|
||||
600"
|
||||
click 81dc9bdb52d04dc20036dbd8313ed055 "/admin/user/view?id=1234" "CCC
|
||||
3000"
|
||||
style 456ac9b0d15a8b7f1e71073221059886 fill:#f9f,stroke:#333,stroke-width:4px
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
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?}}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A([stadium shape test])
|
||||
A -->|Get money| B([Go shopping])
|
||||
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?])
|
||||
C -->|One| D([Laptop])
|
||||
C -->|Two| E([iPhone])
|
||||
C -->|Three| F([Car<br/>wroom wroom])
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A[[subroutine shape test]]
|
||||
A -->|Get money| B[[Go shopping]]
|
||||
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?]]
|
||||
C -->|One| D[[Laptop]]
|
||||
C -->|Two| E[[iPhone]]
|
||||
C -->|Three| F[[Car<br/>wroom wroom]]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A[(cylindrical<br />shape<br />test)]
|
||||
A -->|Get money| B1[(Go shopping 1)]
|
||||
A -->|Get money| B2[(Go shopping 2)]
|
||||
A -->|Get money| B3[(Go shopping 3)]
|
||||
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?)]
|
||||
B1 --> C
|
||||
B2 --> C
|
||||
B3 --> C
|
||||
C -->|One| D[(Laptop)]
|
||||
C -->|Two| E[(iPhone)]
|
||||
C -->|Three| F[(Car)]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A1[Multi<br>Line] -->|Multi<br>Line| B1(Multi<br>Line)
|
||||
C1[Multi<br/>Line] -->|Multi<br/>Line| D1(Multi<br/>Line)
|
||||
E1[Multi<br />Line] -->|Multi<br />Line| F1(Multi<br />Line)
|
||||
A2[Multi<br>Line] -->|Multi<br>Line| B2(Multi<br>Line)
|
||||
C2[Multi<br/>Line] -->|Multi<br/>Line| D2(Multi<br/>Line)
|
||||
E2[Multi<br />Line] -->|Multi<br />Line| F2(Multi<br />Line)
|
||||
linkStyle 0 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 2 stroke:DarkGray,stroke-width:2px
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A(( )) -->|step 1| B(( ))
|
||||
B(( )) -->|step 2| C(( ))
|
||||
C(( )) -->|step 3| D(( ))
|
||||
linkStyle 1 stroke:greenyellow,stroke-width:2px
|
||||
style C fill:greenyellow,stroke:green,stroke-width:4px
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TB
|
||||
TITLE["Link Click Events<br>(click the nodes below)"]
|
||||
A[link test]
|
||||
B[anchor test]
|
||||
C[mailto test]
|
||||
D[other protocol test]
|
||||
E[script test]
|
||||
TITLE --> A & B & C & D & E
|
||||
click A "https://mermaid-js.github.io/mermaid/#/" "link test"
|
||||
click B "#link-clicked" "anchor test"
|
||||
click C "mailto:user@user.user" "mailto test"
|
||||
click D "notes://do-your-thing/id" "other protocol test"
|
||||
click E "javascript:alert('test')" "script test"
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="mermaid">
|
||||
graph LR
|
||||
A[red<br>text] -->|red<br>text| B(blue<br>text)
|
||||
C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
|
||||
E{{default<br />style}} -->|default<br />style| F([default<br />style])
|
||||
linkStyle default color:Sienna;
|
||||
linkStyle 0 color:red;
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
|
||||
style A color:red;
|
||||
style B color:blue;
|
||||
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||
click B "index.html#link-clicked" "link test"
|
||||
click D testClick "click test"
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
graph TD
|
||||
A[myClass1] --> B[default] & C[default]
|
||||
B[default] & C[default] --> D[myClass2]
|
||||
classDef default stroke-width:2px,fill:none,stroke:silver
|
||||
classDef node color:red
|
||||
classDef myClass1 color:#0000ff
|
||||
classDef myClass2 stroke:#0000ff,fill:#ccccff
|
||||
class A myClass1
|
||||
class D myClass2
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
participant John as John<br/>Second Line
|
||||
rect rgb(200, 220, 100)
|
||||
rect rgb(200, 255, 200)
|
||||
Alice ->> Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?
|
||||
end
|
||||
Bob--x Alice: I am good thanks!
|
||||
Bob-x John: I am good thanks!
|
||||
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
|
||||
Bob-->Alice: Checking with John...
|
||||
end
|
||||
alt either this
|
||||
Alice->>John: Yes
|
||||
else or this
|
||||
Alice->>John: No
|
||||
else or this will happen
|
||||
Alice->John: Maybe
|
||||
end
|
||||
par this happens in parallel
|
||||
Alice -->> Bob: Parallel message 1
|
||||
and
|
||||
Alice -->> John: Parallel message 2
|
||||
end
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
participant 1 as multiline<br>using #lt;br#gt;
|
||||
participant 2 as multiline<br/>using #lt;br/#gt;
|
||||
participant 3 as multiline<br />using #lt;br /#gt;
|
||||
participant 4 as multiline<br />using #lt;br /#gt;
|
||||
1->>2: multiline<br>using #lt;br#gt;
|
||||
note right of 2: multiline<br>using #lt;br#gt;
|
||||
2->>3: multiline<br/>using #lt;br/#gt;
|
||||
note right of 3: multiline<br/>using #lt;br/#gt;
|
||||
3->>4: multiline<br />using #lt;br /#gt;
|
||||
note right of 4: multiline<br />using #lt;br /#gt;
|
||||
4->>1: multiline<br />using #lt;br /#gt;
|
||||
note right of 1: multiline<br />using #lt;br /#gt;
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
Alice->>John: Hello John,<br>how are you?
|
||||
Alice->>John: John,<br/>can you hear me?
|
||||
John-->>Alice: Hi Alice,<br />I can hear you!
|
||||
John-->>Alice: I feel great!
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Clickable
|
||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
|
||||
click cl1 href "https://mermaidjs.github.io/"
|
||||
click cl2 call ganttTestClick("test", test, test)
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title GANTT diagram with multiline section titles
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section<br>multiline
|
||||
Completed task : done, des1, 2014-01-06,2014-01-08
|
||||
Active task : active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks<br/>multiline
|
||||
Completed task in the critical line : crit, done, 2014-01-06, 24h
|
||||
Implement parser and jison : crit, done, after des1, 2d
|
||||
Create tests for parser : crit, active, 3d
|
||||
Future task in critical line : crit, 5d
|
||||
Create tests for renderer : 2d
|
||||
Add to mermaid : 1d
|
||||
|
||||
section Documentation<br />multiline
|
||||
Describe gantt syntax : active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page : after a1, 20h
|
||||
Add another diagram to demo page : doc1, after a1, 48h
|
||||
|
||||
section Last section<br />multiline
|
||||
Describe gantt syntax : after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
gitGraph:
|
||||
options
|
||||
{
|
||||
"nodeSpacing": 150,
|
||||
"nodeRadius": 10
|
||||
}
|
||||
end
|
||||
commit
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit
|
||||
commit
|
||||
checkout master
|
||||
commit
|
||||
commit
|
||||
merge newbranch
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="mermaid">
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03 "0" *-- "0..n" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07 .. Class08
|
||||
Class09 "many" --> "1" C2 : Where am i?
|
||||
Class09 "0" --* "1..n" C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : #size()
|
||||
Class01 : -int chimp
|
||||
Class01 : +int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
classDiagram
|
||||
class Class01~T~
|
||||
Class01 : #size()
|
||||
Class01 : -int chimp
|
||||
Class01 : +int gorilla
|
||||
class Class10~T~ {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
classDiagram
|
||||
Class01~T~ <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03~T~ "0" *-- "0..n" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07~T~ .. Class08
|
||||
Class09 "many" --> "1" C2 : Where am i?
|
||||
Class09 "0" --* "1..n" C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : #size()
|
||||
Class01 : -int chimp
|
||||
Class01 : +int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="mermaid">
|
||||
stateDiagram
|
||||
State1
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="mermaid">
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
state First {
|
||||
[*] --> second
|
||||
second --> [*]
|
||||
}
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You can write
|
||||
notes.
|
||||
end note
|
||||
State1 --> State2
|
||||
note left of State2 : This is the note to the left.
|
||||
</div>
|
||||
<div class="mermaid">
|
||||
stateDiagram
|
||||
State1
|
||||
note right of State1
|
||||
Line1<br>Line2<br/>Line3<br />Line4<br />Line5
|
||||
end note
|
||||
</div>
|
||||
|
||||
<h1 id="link-clicked">Anchor for "link-clicked" test</h1>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
flowchart: { curve: 'basis' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
function ganttTestClick(a, b, c){
|
||||
console.log("a:", a)
|
||||
console.log("b:", b)
|
||||
console.log("c:", c)
|
||||
}
|
||||
function testClick(nodeId) {
|
||||
console.log("clicked", nodeId)
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor
|
||||
document.querySelector('body').style.backgroundColor = 'yellow'
|
||||
setTimeout(function() {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor
|
||||
}, 100)
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
const testLineEndings = (test, input) => {
|
||||
try {
|
||||
mermaid.render(test, input, () => {});
|
||||
} catch (err) {
|
||||
console.error("Error in %s:\n\n%s", test, err);
|
||||
}
|
||||
};
|
||||
|
||||
testLineEndings("CR", "graph LR\rsubgraph CR\rA --> B\rend");
|
||||
testLineEndings("LF", "graph LR\nsubgraph LF\nA --> B\nend");
|
||||
testLineEndings("CRLF", "graph LR\r\nsubgraph CRLF\r\nA --> B\r\nend");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user