mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-24 16:34:09 +02:00
Compare commits
2529 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ce18ec2a8 | ||
|
|
831110029c | ||
|
|
89ce930de2 | ||
|
|
f69f770043 | ||
|
|
a97b2cc4da | ||
|
|
25b70d8058 | ||
|
|
bd106e4aec | ||
|
|
b7abaf1e47 | ||
|
|
4fea702347 | ||
|
|
e6cf1f2602 | ||
|
|
9a729257f2 | ||
|
|
492ecb1099 | ||
|
|
ab17af274d | ||
|
|
59e0a8e1b5 | ||
|
|
c232bee95f | ||
|
|
837eeb6d01 | ||
|
|
3426aa8b2a | ||
|
|
3526e35012 | ||
|
|
a018789026 | ||
|
|
d9e598aa7f | ||
|
|
27027d003b | ||
|
|
89eea0536d | ||
|
|
4679daafcf | ||
|
|
a0c6160e55 | ||
|
|
f887420818 | ||
|
|
31851b2e30 | ||
|
|
08702565f7 | ||
|
|
5d99ac7d8d | ||
|
|
d19be0b940 | ||
|
|
b7115b804c | ||
|
|
28bb07d415 | ||
|
|
c2db1d4d44 | ||
|
|
b6d3ac8e32 | ||
|
|
9e8c03cb49 | ||
|
|
5fff8403a8 | ||
|
|
86810e04bd | ||
|
|
ee3680eb6d | ||
|
|
984a5084b0 | ||
|
|
853d62c8d1 | ||
|
|
0550e4a899 | ||
|
|
dec6b6d8b5 | ||
|
|
0b1b3538bc | ||
|
|
31c29b4c02 | ||
|
|
17a23a1103 | ||
|
|
6b4107b231 | ||
|
|
0a50b835b1 | ||
|
|
89ed7d9b72 | ||
|
|
6e5180bd1c | ||
|
|
efcc3b7d37 | ||
|
|
8a08efdfbb | ||
|
|
a4f26f27bc | ||
|
|
226f90dbcb | ||
|
|
7ce383078d | ||
|
|
d84be0d792 | ||
|
|
4089ee8786 | ||
|
|
5487ac9542 | ||
|
|
f303909ad6 | ||
|
|
be412ba78c | ||
|
|
a1ae00070c | ||
|
|
bb299685cd | ||
|
|
9d1f32cc0a | ||
|
|
6318eee07e | ||
|
|
bc64fc7efb | ||
|
|
650bcef3d1 | ||
|
|
95df8fa128 | ||
|
|
bb62704433 | ||
|
|
09cc0d02f4 | ||
|
|
98f575e098 | ||
|
|
72d2045104 | ||
|
|
3feff08d42 | ||
|
|
fcbd8a5081 | ||
|
|
5b8a4a0b7a | ||
|
|
00f228b959 | ||
|
|
e68ec31a8f | ||
|
|
d6782bced8 | ||
|
|
2368ba4914 | ||
|
|
857f6c892c | ||
|
|
0db5f9fea7 | ||
|
|
1fe31dac7d | ||
|
|
ce675b011d | ||
|
|
775461407e | ||
|
|
6305455554 | ||
|
|
c964461cb5 | ||
|
|
42b2e582c5 | ||
|
|
12f58c967e | ||
|
|
d140a9df8f | ||
|
|
53a539e84b | ||
|
|
57671b2b78 | ||
|
|
4d103c14f7 | ||
|
|
6f4fb48fad | ||
|
|
92f036222e | ||
|
|
c29c8bd33c | ||
|
|
ec834363b4 | ||
|
|
d69c3b8856 | ||
|
|
0fb25ee749 | ||
|
|
d2d8c9bc8e | ||
|
|
829642a2cb | ||
|
|
a2e6180143 | ||
|
|
69ecb02375 | ||
|
|
2ae442accc | ||
|
|
caeeca7722 | ||
|
|
dac542682d | ||
|
|
ab3e076c91 | ||
|
|
d2b7a3ec28 | ||
|
|
c015d97957 | ||
|
|
4ec12ba9d5 | ||
|
|
2d4f31dff5 | ||
|
|
95a4f96da7 | ||
|
|
4f3130908f | ||
|
|
b874322f2f | ||
|
|
fdfb5d8270 | ||
|
|
1b7e690ec1 | ||
|
|
5cc7ba52bb | ||
|
|
66d4d9d5b8 | ||
|
|
8579442d77 | ||
|
|
d23ff27e1a | ||
|
|
932fabbd42 | ||
|
|
4d6792141d | ||
|
|
8930a80fdd | ||
|
|
b46db461a2 | ||
|
|
0be2084b18 | ||
|
|
5f43f44db0 | ||
|
|
3c996ee4a0 | ||
|
|
fa184320e9 | ||
|
|
780b3eb95a | ||
|
|
8b35745928 | ||
|
|
f8c01acd18 | ||
|
|
250c9beff9 | ||
|
|
24d18eb42a | ||
|
|
d144128bf0 | ||
|
|
2a87ec2dc2 | ||
|
|
d6a4047a52 | ||
|
|
d63b26efc2 | ||
|
|
1ba990be6e | ||
|
|
7b5e6e95c8 | ||
|
|
3a77f91ba4 | ||
|
|
84338524c5 | ||
|
|
e5966f97b3 | ||
|
|
4a0b074967 | ||
|
|
4d2d99f227 | ||
|
|
23d23251c7 | ||
|
|
4d477d7e96 | ||
|
|
bf378b76f4 | ||
|
|
0d7d5ddc5f | ||
|
|
ebe8b8d89f | ||
|
|
4a50995906 | ||
|
|
bb3597614a | ||
|
|
4620a7eeba | ||
|
|
96236187b5 | ||
|
|
d325f4b496 | ||
|
|
236fd6b231 | ||
|
|
9b32e0b222 | ||
|
|
2c1e8a2a73 | ||
|
|
aa0e84c3c3 | ||
|
|
7d876ea9f2 | ||
|
|
ea4a49d50e | ||
|
|
eb5b6966e5 | ||
|
|
00e716e064 | ||
|
|
cd885e952c | ||
|
|
e2cd2a72aa | ||
|
|
cd427ab8ba | ||
|
|
cefafba062 | ||
|
|
ddcaf1850f | ||
|
|
18ecf479b1 | ||
|
|
a06f6f9604 | ||
|
|
35de6d4cbc | ||
|
|
2bcd66e714 | ||
|
|
4c7ac3fdb6 | ||
|
|
cf3ded482f | ||
|
|
dcca4896f0 | ||
|
|
d267f84030 | ||
|
|
b2f93b49ba | ||
|
|
1c00608b27 | ||
|
|
e3c1354ce0 | ||
|
|
93a1961762 | ||
|
|
c04fdd250c | ||
|
|
626fbe6de8 | ||
|
|
b22422f4b8 | ||
|
|
b0b85e12a6 | ||
|
|
b500a312b6 | ||
|
|
cac354caa9 | ||
|
|
1c8c635e48 | ||
|
|
9c48703fb1 | ||
|
|
d040883286 | ||
|
|
b2c059d56b | ||
|
|
15b9a25aa4 | ||
|
|
e01855ca9c | ||
|
|
618ee6d95f | ||
|
|
8f82d86e7c | ||
|
|
b3525deeab | ||
|
|
7d81fd3c3c | ||
|
|
d48af035d8 | ||
|
|
ebba764c85 | ||
|
|
a5c4d0783d | ||
|
|
3772afb40c | ||
|
|
19343e890e | ||
|
|
5661b43168 | ||
|
|
aa666d1829 | ||
|
|
2758d64778 | ||
|
|
5d5808880f | ||
|
|
8ee3155f2a | ||
|
|
62cc720607 | ||
|
|
900d7e0974 | ||
|
|
7102c1205e | ||
|
|
ec05e2333a | ||
|
|
8540a2757e | ||
|
|
ce1a8d8f6a | ||
|
|
637ae09192 | ||
|
|
4f59e2d28b | ||
|
|
cb2294d6f2 | ||
|
|
95e6efc218 | ||
|
|
029042393c | ||
|
|
7ad509cc7a | ||
|
|
f6cd4547ab | ||
|
|
dd088bc603 | ||
|
|
c5d091d445 | ||
|
|
38ef061175 | ||
|
|
715d0aced3 | ||
|
|
55eebd9309 | ||
|
|
cce8821a83 | ||
|
|
d45765dab5 | ||
|
|
54a4aafd06 | ||
|
|
e4e8a00acc | ||
|
|
db8517a7f9 | ||
|
|
35d8f33542 | ||
|
|
75b79e1b23 | ||
|
|
66df007ea8 | ||
|
|
9da885b2f8 | ||
|
|
efa063d8d0 | ||
|
|
fcd4cc17d3 | ||
|
|
550cf9b102 | ||
|
|
69639bb61c | ||
|
|
4839e6a8b3 | ||
|
|
477c4f1c88 | ||
|
|
b62d0d974f | ||
|
|
5a433d9bf8 | ||
|
|
f91920ab90 | ||
|
|
83d3b31a1a | ||
|
|
97268b9876 | ||
|
|
b2fb9f421a | ||
|
|
6b0105cc3b | ||
|
|
0b2d0ce34f | ||
|
|
5c4ee44787 | ||
|
|
165a10ac37 | ||
|
|
b8f68325ef | ||
|
|
2f2eb67b5f | ||
|
|
5b1f574167 | ||
|
|
a990718b71 | ||
|
|
8670fe9a4f | ||
|
|
2a22c3396a | ||
|
|
20b139bf7f | ||
|
|
a838e52fea | ||
|
|
918cea5291 | ||
|
|
b7ecf3b9dd | ||
|
|
b90a5e2b0b | ||
|
|
1deef137a9 | ||
|
|
8baf553a49 | ||
|
|
d3afc8a245 | ||
|
|
cc4476031a | ||
|
|
3a2c8456d7 | ||
|
|
9cb1a566c1 | ||
|
|
d2707bbb6a | ||
|
|
88f30a26b2 | ||
|
|
61d16b682b | ||
|
|
1c3f94c9ec | ||
|
|
004e7e376d | ||
|
|
549011edf4 | ||
|
|
432267c811 | ||
|
|
0fcabfae05 | ||
|
|
9faa5acb21 | ||
|
|
9c511559ff | ||
|
|
f9a4c8eb0e | ||
|
|
5f27987ca2 | ||
|
|
866ee997d9 | ||
|
|
c82b1cee8e | ||
|
|
6ce1c80a47 | ||
|
|
0839fadbc2 | ||
|
|
96977e70b3 | ||
|
|
a448af2897 | ||
|
|
20aaf644fa | ||
|
|
0d91eee5e0 | ||
|
|
e01ad572a5 | ||
|
|
8bd830c991 | ||
|
|
85d33ecccd | ||
|
|
b6ba4b2fd8 | ||
|
|
37c6837dc1 | ||
|
|
08f2f9aef0 | ||
|
|
09461fd3df | ||
|
|
b8996ce50b | ||
|
|
857f6ecc81 | ||
|
|
f5963b8ea5 | ||
|
|
904849e156 | ||
|
|
b9513c80eb | ||
|
|
b3210ed2ef | ||
|
|
6dbed7964b | ||
|
|
ce6d8576ae | ||
|
|
291bec7e90 | ||
|
|
5997227997 | ||
|
|
c73b04111e | ||
|
|
05637b1eff | ||
|
|
48b6a32fe1 | ||
|
|
579e79575b | ||
|
|
296a64f465 | ||
|
|
3ad190855b | ||
|
|
206a35ebd9 | ||
|
|
8acab4bba6 | ||
|
|
abd3b18727 | ||
|
|
f07a777194 | ||
|
|
cd60a30aeb | ||
|
|
2e02f843ad | ||
|
|
fddc408cd9 | ||
|
|
d4f0c0808a | ||
|
|
dbdee1f7f8 | ||
|
|
bae74bcc95 | ||
|
|
bc31125bc6 | ||
|
|
d32fb0e4c0 | ||
|
|
0658a363cb | ||
|
|
186fb03048 | ||
|
|
8db827e429 | ||
|
|
46a7039ae9 | ||
|
|
8a8f792d4b | ||
|
|
c0c978bbdf | ||
|
|
ff75349d95 | ||
|
|
e88c710fd3 | ||
|
|
0fba1c06b4 | ||
|
|
69a9829041 | ||
|
|
d68c1958b5 | ||
|
|
2434a94aae | ||
|
|
b80ebb4fcb | ||
|
|
fd6e59174e | ||
|
|
54ef5b0bee | ||
|
|
b0c09a5b0f | ||
|
|
719de71de4 | ||
|
|
571816fc28 | ||
|
|
adcc25db8e | ||
|
|
7c97f68ee2 | ||
|
|
2dfc9a7973 | ||
|
|
c04aac4ae0 | ||
|
|
798a0ad783 | ||
|
|
935cc3b098 | ||
|
|
5ef2ad5536 | ||
|
|
0276a67417 | ||
|
|
46a3d10e8a | ||
|
|
d09dea7e5e | ||
|
|
55faa3cb1a | ||
|
|
d9a9eb56a7 | ||
|
|
5237729a6d | ||
|
|
a251848ba1 | ||
|
|
3383da514a | ||
|
|
3d7091a9e2 | ||
|
|
d1759228cc | ||
|
|
768536b9e2 | ||
|
|
8f0b19f427 | ||
|
|
972f6a0ea9 | ||
|
|
9c55dec6ba | ||
|
|
06715be05f | ||
|
|
8f8169b8e4 | ||
|
|
313aa11528 | ||
|
|
2ccd9feae7 | ||
|
|
fa3735b033 | ||
|
|
adfceaf20b | ||
|
|
8af36b742e | ||
|
|
a670b67844 | ||
|
|
e8fc810b8d | ||
|
|
b6648283c2 | ||
|
|
b29979bfd9 | ||
|
|
7e346a56ff | ||
|
|
719480cf76 | ||
|
|
92f1b9c079 | ||
|
|
c0831ecef6 | ||
|
|
d3ae43c4ba | ||
|
|
a4e01dd8e9 | ||
|
|
88e195408c | ||
|
|
f77ae2b045 | ||
|
|
655ff2675e | ||
|
|
37fae09ce4 | ||
|
|
711fb7d748 | ||
|
|
f8891beb0a | ||
|
|
61a401b119 | ||
|
|
5dd78c18da | ||
|
|
eb4ac5c103 | ||
|
|
af7f5d0aaf | ||
|
|
7275b215b8 | ||
|
|
6fa6503515 | ||
|
|
73ff972789 | ||
|
|
a51bfd6a04 | ||
|
|
b8cda6616f | ||
|
|
1aa5388aaf | ||
|
|
0dd79d4f80 | ||
|
|
68cd425950 | ||
|
|
ffa83547ca | ||
|
|
d48cd57198 | ||
|
|
ab26c172d7 | ||
|
|
1d32307a71 | ||
|
|
42d8bbfce2 | ||
|
|
9245b0bb8b | ||
|
|
fa6f453e88 | ||
|
|
f7295a7a79 | ||
|
|
4c00e90436 | ||
|
|
7d802a71c1 | ||
|
|
69a1bb99ac | ||
|
|
b055015250 | ||
|
|
e325bdb16b | ||
|
|
209ac97d15 | ||
|
|
e64cea499f | ||
|
|
c621c145e9 | ||
|
|
6ea84a36dc | ||
|
|
9914e9b1ab | ||
|
|
5dfaed91f1 | ||
|
|
d523818339 | ||
|
|
33e8ee6c0e | ||
|
|
a87d557354 | ||
|
|
024f7c3275 | ||
|
|
f2910da513 | ||
|
|
b5ed5db880 | ||
|
|
fa65e73bd0 | ||
|
|
f1ff7d02d1 | ||
|
|
21afb56089 | ||
|
|
034cdc9d02 | ||
|
|
2008d497bb | ||
|
|
b71a28106c | ||
|
|
eb5147b497 | ||
|
|
341c40b610 | ||
|
|
169800b209 | ||
|
|
bdacc5e3eb | ||
|
|
afaf213f11 | ||
|
|
e4116bf5b1 | ||
|
|
58c1d7dd62 | ||
|
|
56a4ca0406 | ||
|
|
3f991a4f1f | ||
|
|
056abc314c | ||
|
|
9870121f01 | ||
|
|
525e342f9b | ||
|
|
8b267ba947 | ||
|
|
843ccbc88b | ||
|
|
78fbe18aed | ||
|
|
dd83cd9f78 | ||
|
|
0f178b9f07 | ||
|
|
381ff20820 | ||
|
|
559d5ee5e6 | ||
|
|
ec0e476521 | ||
|
|
3f8ff1a66c | ||
|
|
7229b6aaf1 | ||
|
|
3ab447a766 | ||
|
|
0ed11dc98c | ||
|
|
52b1b23d47 | ||
|
|
030d383d30 | ||
|
|
b34f7bcdd5 | ||
|
|
6a3991bbaa | ||
|
|
5d2a9fe267 | ||
|
|
cd8620cc9d | ||
|
|
5399214ad8 | ||
|
|
896c7eca57 | ||
|
|
c29486f515 | ||
|
|
3fe1f5af60 | ||
|
|
1034e1a301 | ||
|
|
6379320b83 | ||
|
|
30de90e4f0 | ||
|
|
52a40112a2 | ||
|
|
7a679dea2d | ||
|
|
0eb86cb97f | ||
|
|
7fcb1ae9b3 | ||
|
|
6715498598 | ||
|
|
eaec4c9744 | ||
|
|
fa07abd014 | ||
|
|
30a02adfe3 | ||
|
|
ea6102e123 | ||
|
|
b5aaf0f990 | ||
|
|
ed6abb6d92 | ||
|
|
862330a576 | ||
|
|
fadda49b0e | ||
|
|
db5709a033 | ||
|
|
c447262764 | ||
|
|
79e6013342 | ||
|
|
2c00d4c116 | ||
|
|
b468065c6b | ||
|
|
67050e4d6d | ||
|
|
5437ab7057 | ||
|
|
2f73fd3a9d | ||
|
|
27b6845b78 | ||
|
|
1310619848 | ||
|
|
1d78267871 | ||
|
|
ed0947d761 | ||
|
|
6564bad85e | ||
|
|
6b9462f606 | ||
|
|
eef4ef54a1 | ||
|
|
9cc4f73cab | ||
|
|
d0d87497c5 | ||
|
|
09a97d339e | ||
|
|
db049f9c8e | ||
|
|
c1335955f4 | ||
|
|
3a65551746 | ||
|
|
62c6b9d886 | ||
|
|
a78ccb460d | ||
|
|
2f5c7ea2f1 | ||
|
|
ecede3126b | ||
|
|
8b55b83256 | ||
|
|
ee57e60ca6 | ||
|
|
890512ccbb | ||
|
|
3d22fa5d24 | ||
|
|
e0652539fb | ||
|
|
26ede9b015 | ||
|
|
2d01c5489b | ||
|
|
7cdf4c7476 | ||
|
|
5251dfaa97 | ||
|
|
d6ce739b8a | ||
|
|
b2be90e1a0 | ||
|
|
e6e94ad57e | ||
|
|
fc70fb7c1a | ||
|
|
e0c3b8e269 | ||
|
|
9861c081db | ||
|
|
916df3ff4f | ||
|
|
c0b65e9304 | ||
|
|
aa2596b457 | ||
|
|
359ea05680 | ||
|
|
c77e7af126 | ||
|
|
1a444071f1 | ||
|
|
5070d992dd | ||
|
|
bf21aa8cd6 | ||
|
|
529824e2b3 | ||
|
|
6e6ced2cee | ||
|
|
4fa4849fcd | ||
|
|
affab5f6d3 | ||
|
|
5fb8d34a07 | ||
|
|
ff75122095 | ||
|
|
4c92592aa1 | ||
|
|
0bbefdc48f | ||
|
|
09569301f1 | ||
|
|
84ad8aabec | ||
|
|
98c092637e | ||
|
|
1f86ec3d19 | ||
|
|
85217fffc3 | ||
|
|
9f9fb7d043 | ||
|
|
cea1441eeb | ||
|
|
85faec73f4 | ||
|
|
d1180a5c69 | ||
|
|
84941607df | ||
|
|
3dc7b68d08 | ||
|
|
af4930e3f3 | ||
|
|
0a4f16737a | ||
|
|
a4795975a7 | ||
|
|
0e10160d85 | ||
|
|
f7944e83eb | ||
|
|
a55777c62b | ||
|
|
ebd2cb6f25 | ||
|
|
d5a349fccc | ||
|
|
417428acea | ||
|
|
ac837a77e7 | ||
|
|
d208f58084 | ||
|
|
3eb44ccb80 | ||
|
|
6dcc538777 | ||
|
|
560951d597 | ||
|
|
75769c46de | ||
|
|
d3d0df59cb | ||
|
|
43f6ae7ba0 | ||
|
|
f86f027fb2 | ||
|
|
e3164d8d44 | ||
|
|
4720ede442 | ||
|
|
413bdce17c | ||
|
|
37136c9bef | ||
|
|
fb5970d4db | ||
|
|
2de9d491c3 | ||
|
|
f6b4794183 | ||
|
|
30909bd6fe | ||
|
|
2104c983e9 | ||
|
|
30faf7bfad | ||
|
|
785e5552ae | ||
|
|
a1cd398e4d | ||
|
|
edb06b12e9 | ||
|
|
1337ffe9e5 | ||
|
|
1238dc20da | ||
|
|
5157b2eff4 | ||
|
|
257ed8dc92 | ||
|
|
ea12f5b2ec | ||
|
|
34bd9b58e8 | ||
|
|
83754410f3 | ||
|
|
ae36704b66 | ||
|
|
70899ffb87 | ||
|
|
001865f1db | ||
|
|
2a3c68f2c6 | ||
|
|
769a7b1384 | ||
|
|
149abf98cf | ||
|
|
e104078b3f | ||
|
|
b7fa328d95 | ||
|
|
598dbeb185 | ||
|
|
7c249e9f7a | ||
|
|
1c7710d0ab | ||
|
|
a67e714abc | ||
|
|
932d08c276 | ||
|
|
2c90b6157c | ||
|
|
4b5b7381c2 | ||
|
|
f67639e0a2 | ||
|
|
66082029a9 | ||
|
|
f9e8b31633 | ||
|
|
257c57ccca | ||
|
|
7b488c8ec8 | ||
|
|
a46719eaba | ||
|
|
1bdf906617 | ||
|
|
97abb0e97f | ||
|
|
86f3153973 | ||
|
|
390726ac03 | ||
|
|
82b24d95d0 | ||
|
|
c7a2afa287 | ||
|
|
92d70dfcf4 | ||
|
|
cfcf72b8e0 | ||
|
|
36226a23ab | ||
|
|
fdba19043a | ||
|
|
c56ccb3aa4 | ||
|
|
f7a5cda7f4 | ||
|
|
7c346df471 | ||
|
|
99f5e9fc9f | ||
|
|
a942cb2711 | ||
|
|
aa39dcc34f | ||
|
|
0b3881751f | ||
|
|
31e656630d | ||
|
|
9cce3faba5 | ||
|
|
6dc71122b8 | ||
|
|
073c9445ea | ||
|
|
5dc7c62cd4 | ||
|
|
d3f8f03a7d | ||
|
|
7a90970177 | ||
|
|
b20f8668be | ||
|
|
d8d624870d | ||
|
|
1e6ed7be02 | ||
|
|
973369e7f1 | ||
|
|
0185d75b05 | ||
|
|
3e40bec98d | ||
|
|
f96ca5dd73 | ||
|
|
2240333df1 | ||
|
|
fdac4bf2c9 | ||
|
|
fab98633a4 | ||
|
|
11f3cbdb36 | ||
|
|
a3e7df0068 | ||
|
|
4e6b9ec947 | ||
|
|
de8bdb96bd | ||
|
|
ebafb9c316 | ||
|
|
f4ae9b41d6 | ||
|
|
27bf4b272b | ||
|
|
bb92715f02 | ||
|
|
0ffa15eb21 | ||
|
|
ae4a18c745 | ||
|
|
a9f14d9ffe | ||
|
|
ce84278f10 | ||
|
|
8955e0a6b1 | ||
|
|
9594c8d004 | ||
|
|
8a893e12f5 | ||
|
|
8f09514dd7 | ||
|
|
2bb4f1f875 | ||
|
|
050569b03b | ||
|
|
8b3ac57ce7 | ||
|
|
88447f87d6 | ||
|
|
d6296e9cf0 | ||
|
|
ab1a31cfb6 | ||
|
|
45918da48e | ||
|
|
cef6273dcf | ||
|
|
8c57df1945 | ||
|
|
6c927e8ec4 | ||
|
|
0e881faa87 | ||
|
|
6dbec06571 | ||
|
|
3306b01df9 | ||
|
|
598993e592 | ||
|
|
d03ef49a3c | ||
|
|
ea108b7733 | ||
|
|
60bbee9eaf | ||
|
|
1e316c75ea | ||
|
|
30c07c429c | ||
|
|
b69ad0a3d2 | ||
|
|
bad2c82669 | ||
|
|
12efdbef01 | ||
|
|
cf6476c1fc | ||
|
|
f48cb65284 | ||
|
|
62b8f78937 | ||
|
|
1b66b3c3fb | ||
|
|
2075e42c6d | ||
|
|
cda845f9a6 | ||
|
|
3edd06548c | ||
|
|
723976be58 | ||
|
|
91e1866d1a | ||
|
|
42178d5f7b | ||
|
|
cd94bb3f5b | ||
|
|
94cc7c8256 | ||
|
|
6ce2de6fb0 | ||
|
|
f7750e5f04 | ||
|
|
adab9819bd | ||
|
|
1304890441 | ||
|
|
a6dfaa0076 | ||
|
|
97563c1f2a | ||
|
|
68d0002d6b | ||
|
|
9734bfc4a0 | ||
|
|
646a76570f | ||
|
|
b8ef76f130 | ||
|
|
2fd7992b0e | ||
|
|
2beedb1676 | ||
|
|
cd7657d4d5 | ||
|
|
25e2c96ecd | ||
|
|
8085179499 | ||
|
|
0a922752de | ||
|
|
d58a286e3b | ||
|
|
8666f4efbf | ||
|
|
0c60ee5f1d | ||
|
|
d75f950ac4 | ||
|
|
f78d8b3e5e | ||
|
|
84f664de14 | ||
|
|
9eedd6c57a | ||
|
|
7866e761cc | ||
|
|
8af62c37bb | ||
|
|
74c109d6f1 | ||
|
|
c7e05df9c0 | ||
|
|
b558d67fcd | ||
|
|
f78d4b13eb | ||
|
|
120b89041b | ||
|
|
2d0aab223c | ||
|
|
6629061abd | ||
|
|
79b30153ba | ||
|
|
1b3971d6da | ||
|
|
0ad932acf6 | ||
|
|
d719f44e6f | ||
|
|
96e89f5ce5 | ||
|
|
f86bdd648a | ||
|
|
bce5cf9400 | ||
|
|
fe182a7407 | ||
|
|
94471c1a1a | ||
|
|
c714f3109a | ||
|
|
6cc95f2a4a | ||
|
|
3d31c9753a | ||
|
|
346a6721df | ||
|
|
d2a3f7de23 | ||
|
|
f47b83235a | ||
|
|
2d22c3519f | ||
|
|
a18543862f | ||
|
|
30dfbbbd68 | ||
|
|
4339fadd50 | ||
|
|
1ae074d05f | ||
|
|
84c9dd0dad | ||
|
|
3209986df1 | ||
|
|
87458657f8 | ||
|
|
67a6ed3fb4 | ||
|
|
f10e267b4c | ||
|
|
22987a5747 | ||
|
|
497fe6399f | ||
|
|
a5cc75c1f7 | ||
|
|
c8d4c798ee | ||
|
|
90c225e8b2 | ||
|
|
b789d44fd6 | ||
|
|
f26f4c30c8 | ||
|
|
00848fef21 | ||
|
|
0dfaa13f20 | ||
|
|
94decf01dc | ||
|
|
c269dc822c | ||
|
|
0f50e4d895 | ||
|
|
9a2cb1b6d1 | ||
|
|
31be8e7585 | ||
|
|
6d1e16a0a6 | ||
|
|
540dc17303 | ||
|
|
a8028768bc | ||
|
|
3872c16ed9 | ||
|
|
4e7ecb3f30 | ||
|
|
b9d90339ac | ||
|
|
5f841d98bc | ||
|
|
9bf5d7e6ba | ||
|
|
05bd2329c7 | ||
|
|
1a1de95ff5 | ||
|
|
7aaf09e92d | ||
|
|
2eb9ee1507 | ||
|
|
f2196b25f8 | ||
|
|
0f31471b2e | ||
|
|
4395a5f404 | ||
|
|
407996b00b | ||
|
|
2bf866052d | ||
|
|
10b002889c | ||
|
|
b50eea26ed | ||
|
|
8dae33e9ba | ||
|
|
ac742bf662 | ||
|
|
f368908660 | ||
|
|
76da6598c6 | ||
|
|
395bf25e1a | ||
|
|
3a3111ab91 | ||
|
|
ba8b49c703 | ||
|
|
fa1e69c1ec | ||
|
|
dbc1015d18 | ||
|
|
bb3df31c86 | ||
|
|
df9129364a | ||
|
|
38049c4bab | ||
|
|
9fafe50693 | ||
|
|
190dfe6706 | ||
|
|
835508a6b2 | ||
|
|
b20569a3fb | ||
|
|
feb1bb4fa3 | ||
|
|
fecb80665b | ||
|
|
23a6137624 | ||
|
|
a7e838e001 | ||
|
|
8f2b51c574 | ||
|
|
0b4d42eb27 | ||
|
|
2e108b7875 | ||
|
|
1d5228b4e3 | ||
|
|
f9251271fb | ||
|
|
7472a8ebc7 | ||
|
|
f2a6b6c6b6 | ||
|
|
438884b866 | ||
|
|
c583386175 | ||
|
|
749f16d875 | ||
|
|
82618f0184 | ||
|
|
cc1eb5dd98 | ||
|
|
d66727cb35 | ||
|
|
865aeaad12 | ||
|
|
0c05f998e9 | ||
|
|
4524f8413f | ||
|
|
903054e97a | ||
|
|
623056fe20 | ||
|
|
f2e75e730b | ||
|
|
5e8b8ab3e3 | ||
|
|
b1d21b0e3f | ||
|
|
184351c932 | ||
|
|
c0d0e80fe0 | ||
|
|
0646b43144 | ||
|
|
b477ffd08f | ||
|
|
ef63a0661b | ||
|
|
1293850a09 | ||
|
|
300d405621 | ||
|
|
f5d1a1753d | ||
|
|
bbdeec5a50 | ||
|
|
30b265a425 | ||
|
|
62e196e802 | ||
|
|
7cc7a8f47c | ||
|
|
b9859a1e57 | ||
|
|
9c6f50af41 | ||
|
|
45518580a4 | ||
|
|
f6d4686898 | ||
|
|
021bc5f011 | ||
|
|
55251e1024 | ||
|
|
693de2996a | ||
|
|
dabe7a3b55 | ||
|
|
be95b93a2d | ||
|
|
73ce47675c | ||
|
|
67d1368730 | ||
|
|
d923b4df53 | ||
|
|
ba3e0c4c35 | ||
|
|
9677aaa715 | ||
|
|
2e3b93b7f5 | ||
|
|
229f5b0c51 | ||
|
|
adac0bb388 | ||
|
|
745f3854d4 | ||
|
|
4a594ed115 | ||
|
|
dc14b2f9fe | ||
|
|
1f523ee843 | ||
|
|
0728533676 | ||
|
|
7019a1149d | ||
|
|
b4b2a5b5a6 | ||
|
|
1ec21662a9 | ||
|
|
560c487d15 | ||
|
|
edd7bc7197 | ||
|
|
98fbef7c24 | ||
|
|
8b191f038e | ||
|
|
eb206cb687 | ||
|
|
b974b3df3e | ||
|
|
15e412bd4e | ||
|
|
f1fc0df52a | ||
|
|
c05e3f8fe1 | ||
|
|
a0c2ffaac4 | ||
|
|
68a5f36f25 | ||
|
|
bb42f78bef | ||
|
|
562390dbb6 | ||
|
|
1b9d9fe12c | ||
|
|
fc5693067c | ||
|
|
177cd30854 | ||
|
|
2e5771b9e8 | ||
|
|
757bc94a23 | ||
|
|
7d48890f76 | ||
|
|
1514ef18ec | ||
|
|
a6cfb315f2 | ||
|
|
9ec76f7ecb | ||
|
|
03edd00014 | ||
|
|
0c724d1a88 | ||
|
|
bf8e7a3590 | ||
|
|
7cb46ffa18 | ||
|
|
d9293afd35 | ||
|
|
ea9a893c24 | ||
|
|
0619059047 | ||
|
|
f8c6fd9fac | ||
|
|
1136834d63 | ||
|
|
277915407e | ||
|
|
a2b2e4599d | ||
|
|
a9b1a6daaf | ||
|
|
ebf6fca040 | ||
|
|
f9273d3692 | ||
|
|
981bfc9b39 | ||
|
|
e70b32e14d | ||
|
|
9a928295fa | ||
|
|
22da3bdba7 | ||
|
|
89c8b3e3dd | ||
|
|
c60734cc5f | ||
|
|
1daa259c98 | ||
|
|
3c5da00230 | ||
|
|
98c30799a8 | ||
|
|
5b605bb6db | ||
|
|
a53518fd0e | ||
|
|
8014116bda | ||
|
|
466e725afd | ||
|
|
520a9b8b0d | ||
|
|
071fd8b569 | ||
|
|
64deea0d99 | ||
|
|
a8fd8053f4 | ||
|
|
000b880023 | ||
|
|
d42cb40ae3 | ||
|
|
5d24a2b7d9 | ||
|
|
b2f52baa99 | ||
|
|
081de6bed8 | ||
|
|
f47450846c | ||
|
|
2026be325f | ||
|
|
f6bc3cf998 | ||
|
|
5ec30ac35c | ||
|
|
e08ae8ed4a | ||
|
|
fc67edb44d | ||
|
|
3e042f63e6 | ||
|
|
aac78cef0a | ||
|
|
1c0b167c95 | ||
|
|
f435152c88 | ||
|
|
4da5df9c9b | ||
|
|
36589ad832 | ||
|
|
032d8781dc | ||
|
|
2ec7ef8acd | ||
|
|
d4b1eefe70 | ||
|
|
ddea5b57a5 | ||
|
|
49fed04bd2 | ||
|
|
9c36b2bef7 | ||
|
|
7d394896e4 | ||
|
|
5a0122cec5 | ||
|
|
bdb2afb1dc | ||
|
|
0fe1fb76d1 | ||
|
|
2a5b029ecc | ||
|
|
8aa030539b | ||
|
|
8ed7d12a08 | ||
|
|
469a726285 | ||
|
|
0103da13f0 | ||
|
|
c3ce525c6c | ||
|
|
939a96b314 | ||
|
|
b0c5c24d06 | ||
|
|
2b61d131dc | ||
|
|
e7db2a63b9 | ||
|
|
d5d78a1018 | ||
|
|
fc3c05692f | ||
|
|
1fdd037132 | ||
|
|
63b404be9f | ||
|
|
aaf031f501 | ||
|
|
a855f4bc67 | ||
|
|
85c8b2fdc3 | ||
|
|
b97e71e83e | ||
|
|
44a744752f | ||
|
|
02fec31c92 | ||
|
|
93f15a507b | ||
|
|
7cc2daa696 | ||
|
|
46aff7aabf | ||
|
|
65a4e664e5 | ||
|
|
62768cd617 | ||
|
|
f03efefac5 | ||
|
|
7f22d155f2 | ||
|
|
619b9f230f | ||
|
|
3e8b6dd1c1 | ||
|
|
0b8561711b | ||
|
|
5cb04828d2 | ||
|
|
2d100197c8 | ||
|
|
4debc2dffb | ||
|
|
b1bb2dce16 | ||
|
|
1940b63237 | ||
|
|
5ca629ec90 | ||
|
|
e7852ea54e | ||
|
|
40cf4dfee4 | ||
|
|
1a2c1252f0 | ||
|
|
95ee87f771 | ||
|
|
84697eb9b0 | ||
|
|
884f6b3571 | ||
|
|
aa9ecde7c8 | ||
|
|
1ead98b999 | ||
|
|
2a14039733 | ||
|
|
568962dadf | ||
|
|
7126d215b0 | ||
|
|
027342bba0 | ||
|
|
7b953ffefb | ||
|
|
d8e57d1c01 | ||
|
|
56f3f49f15 | ||
|
|
f8a45e4963 | ||
|
|
740a86609f | ||
|
|
d6b2bcf0d2 | ||
|
|
c3209e7738 | ||
|
|
3b55a19119 | ||
|
|
8ed7d22010 | ||
|
|
6542134e04 | ||
|
|
96ac13cdac | ||
|
|
d409006a44 | ||
|
|
ec418f98c0 | ||
|
|
2e7452f067 | ||
|
|
ddc31870bf | ||
|
|
77d6048005 | ||
|
|
8748e661e8 | ||
|
|
a50086ddec | ||
|
|
465fa571d2 | ||
|
|
d72ba16664 | ||
|
|
efd14f4c24 | ||
|
|
c472024921 | ||
|
|
35cd3918df | ||
|
|
a2a0851978 | ||
|
|
b329679d2d | ||
|
|
39657e6537 | ||
|
|
ee99d15df4 | ||
|
|
813b993819 | ||
|
|
f62189b381 | ||
|
|
dfa306c8c2 | ||
|
|
df7e90f4b5 | ||
|
|
55532c00b4 | ||
|
|
7ea18f5462 | ||
|
|
a16bbb8046 | ||
|
|
1d30241871 | ||
|
|
a0e5ec1d13 | ||
|
|
830620740a | ||
|
|
d34e8c4336 | ||
|
|
2370531e75 | ||
|
|
06f74a8c15 | ||
|
|
e0ad5eaf5e | ||
|
|
067f356010 | ||
|
|
555a38b819 | ||
|
|
88f2ede8fe | ||
|
|
9b2f61d778 | ||
|
|
0801047fe6 | ||
|
|
f8b8d03e15 | ||
|
|
f4270a0d75 | ||
|
|
0ab629e32d | ||
|
|
4259611726 | ||
|
|
24e2429fc0 | ||
|
|
ebf046ebc0 | ||
|
|
0155171c0d | ||
|
|
5a92b77560 | ||
|
|
0604b1a822 | ||
|
|
d54f3afe25 | ||
|
|
acc2392c3d | ||
|
|
3044c63773 | ||
|
|
f963238a75 | ||
|
|
46d41ba67a | ||
|
|
00921ce713 | ||
|
|
55073bd891 | ||
|
|
2b4ceda937 | ||
|
|
93ddc0b4f5 | ||
|
|
a74fc5aac7 | ||
|
|
e1032498e2 | ||
|
|
f43e07bc68 | ||
|
|
e61207ab41 | ||
|
|
0f87b1b5da | ||
|
|
6032e33290 | ||
|
|
037cba9a13 | ||
|
|
cb41569a5a | ||
|
|
6167f5d7b4 | ||
|
|
b50a453fe0 | ||
|
|
52d7f02dcb | ||
|
|
cce90a2bed | ||
|
|
973b6fc355 | ||
|
|
331c7d1a1a | ||
|
|
e35ee592ad | ||
|
|
2e646d722c | ||
|
|
fff29fcd69 | ||
|
|
4fd8bcd7c7 | ||
|
|
9fd97d89c0 | ||
|
|
0544f96980 | ||
|
|
4671a49fd8 | ||
|
|
e3cf8b7843 | ||
|
|
997257ff79 | ||
|
|
153da33311 | ||
|
|
93f613d6af | ||
|
|
608c0df0f7 | ||
|
|
4f568d5d19 | ||
|
|
331c952212 | ||
|
|
879da091d3 | ||
|
|
68410b9c58 | ||
|
|
7a3ecb339b | ||
|
|
144cba7f10 | ||
|
|
ee4571071d | ||
|
|
47a3ca44ba | ||
|
|
0e7ad3feeb | ||
|
|
bb6ba758db | ||
|
|
1ce4805bdc | ||
|
|
ecdb66f65a | ||
|
|
ae1880311e | ||
|
|
6652319283 | ||
|
|
855dec7fcd | ||
|
|
e57120fa61 | ||
|
|
f955eef31e | ||
|
|
6aaec3dc96 | ||
|
|
f59e5128d7 | ||
|
|
29fa2dfcfb | ||
|
|
6363cb0d80 | ||
|
|
17d9f4fb46 | ||
|
|
2c6329310a | ||
|
|
48089e869e | ||
|
|
5cb735eb8f | ||
|
|
d034e32703 | ||
|
|
a3b8c84e39 | ||
|
|
bf2376d504 | ||
|
|
aba8c0356a | ||
|
|
8870ba3b65 | ||
|
|
26e0283fc7 | ||
|
|
0c38e014d7 | ||
|
|
b89f79d901 | ||
|
|
56fbbef133 | ||
|
|
6ece2537ee | ||
|
|
f7b722f10f | ||
|
|
64544a6e7c | ||
|
|
1ef7a097a6 | ||
|
|
b70297dc7a | ||
|
|
732b3289f0 | ||
|
|
bc0caa5dd6 | ||
|
|
f835b34f57 | ||
|
|
3aa33bd720 | ||
|
|
87601fba1b | ||
|
|
adc900a03a | ||
|
|
de52808e9f | ||
|
|
31aebca134 | ||
|
|
9d09bdc1f3 | ||
|
|
a9c3019433 | ||
|
|
3f56830170 | ||
|
|
73b1953c09 | ||
|
|
4e0fc58f60 | ||
|
|
108f102360 | ||
|
|
be73811c53 | ||
|
|
f3fbc004f3 | ||
|
|
be71cf5689 | ||
|
|
bd53fce4a7 | ||
|
|
80c72c8f83 | ||
|
|
445daaeba2 | ||
|
|
851cff4bb8 | ||
|
|
245e25f4b7 | ||
|
|
69113a988f | ||
|
|
521bfc66f0 | ||
|
|
d473f3904a | ||
|
|
74d09b5468 | ||
|
|
b495772118 | ||
|
|
7c939860d6 | ||
|
|
310420fda1 | ||
|
|
a679d2a0ed | ||
|
|
3f60107885 | ||
|
|
3c2e8cb71c | ||
|
|
cff55e91b0 | ||
|
|
005390f54b | ||
|
|
82ce848d24 | ||
|
|
dfdae7f046 | ||
|
|
7a7bad2aa3 | ||
|
|
8f438744cf | ||
|
|
460ccd9b34 | ||
|
|
0638d0b2d7 | ||
|
|
4c239b7eef | ||
|
|
ac8ddd58f0 | ||
|
|
b49308f0f1 | ||
|
|
b435171aa2 | ||
|
|
8e342e1db7 | ||
|
|
1ade6cdfa5 | ||
|
|
561ee5c72e | ||
|
|
143566fbf6 | ||
|
|
5e0f2e8572 | ||
|
|
350732d8dd | ||
|
|
d8da24804f | ||
|
|
15f8856f92 | ||
|
|
4ae61ad35a | ||
|
|
c2c5cc45fa | ||
|
|
7404e436d2 | ||
|
|
cc1560d3e3 | ||
|
|
4812437519 | ||
|
|
53933d934d | ||
|
|
f108099623 | ||
|
|
7dd82a4a87 | ||
|
|
1a91b1bd42 | ||
|
|
439399b9f1 | ||
|
|
5e95d75f44 | ||
|
|
35deb4a512 | ||
|
|
19ac8e6e61 | ||
|
|
68a0506a40 | ||
|
|
0f9da18cbe | ||
|
|
acc4f31c3a | ||
|
|
2e4d1a7b44 | ||
|
|
ec7628924e | ||
|
|
4c849554da | ||
|
|
582a045457 | ||
|
|
4b2d98129e | ||
|
|
8ec99cb244 | ||
|
|
088dd8698e | ||
|
|
e9f4d2040b | ||
|
|
6d58836301 | ||
|
|
c81eaccfef | ||
|
|
b21100cc5d | ||
|
|
f6954c898d | ||
|
|
f1cea37814 | ||
|
|
911d97c0a3 | ||
|
|
4dc805d25a | ||
|
|
c691ef1899 | ||
|
|
04338335d0 | ||
|
|
4d9d315f10 | ||
|
|
eb3ddbcca7 | ||
|
|
13d11633ab | ||
|
|
c4572036b3 | ||
|
|
f0a8eaa5be | ||
|
|
93bf8d7414 | ||
|
|
2cbb2d7b6a | ||
|
|
ce23316008 | ||
|
|
c04dac65ac | ||
|
|
abba5a5d75 | ||
|
|
98b556cb1a | ||
|
|
488afd64d7 | ||
|
|
e2a7e60dad | ||
|
|
c17778ba47 | ||
|
|
753ba194fd | ||
|
|
f856782528 | ||
|
|
c9ff70b3cc | ||
|
|
6311abec2d | ||
|
|
1461d535d4 | ||
|
|
77d57b865d | ||
|
|
57a208d271 | ||
|
|
a26c9fca1e | ||
|
|
c679d18888 | ||
|
|
2a6372cabe | ||
|
|
22c710ed99 | ||
|
|
a14ff7820e | ||
|
|
a446b3c600 | ||
|
|
c8c4554299 | ||
|
|
6360ed52b2 | ||
|
|
9d8c867de8 | ||
|
|
571b8bbd88 | ||
|
|
b795950892 | ||
|
|
28c01f6476 | ||
|
|
117988d26d | ||
|
|
137770dc61 | ||
|
|
5d57237c3b | ||
|
|
9635ef5f16 | ||
|
|
bbec2c54ed | ||
|
|
c95b9ffc43 | ||
|
|
5336e98e18 | ||
|
|
1f4be42b3f | ||
|
|
6a1c88204a | ||
|
|
4f8e242dac | ||
|
|
89f616df88 | ||
|
|
0918b97e81 | ||
|
|
a8b7144d62 | ||
|
|
9bf97d9dcd | ||
|
|
343703c54f | ||
|
|
2ca8bcad5c | ||
|
|
9106c6ad52 | ||
|
|
2a4344ace3 | ||
|
|
a82c53dd2e | ||
|
|
1ac3611e6e | ||
|
|
c62f3c2898 | ||
|
|
b244118fd9 | ||
|
|
7164eaa8b1 | ||
|
|
a20aa472d6 | ||
|
|
1811153467 | ||
|
|
d003f9c6fd | ||
|
|
99844b4ca3 | ||
|
|
184fcab0b7 | ||
|
|
459e07834c | ||
|
|
c7e7f3b4c1 | ||
|
|
78a8ae3ba2 | ||
|
|
31527e8e87 | ||
|
|
c0008bf850 | ||
|
|
3b026ff0cc | ||
|
|
73b5ffa3ef | ||
|
|
55f0d0ab9f | ||
|
|
0cbd002667 | ||
|
|
5246f81dce | ||
|
|
56a9b8fa94 | ||
|
|
ab130900a1 | ||
|
|
d4b72ececc | ||
|
|
41b8ac32b3 | ||
|
|
7e0e4455b0 | ||
|
|
2127c00671 | ||
|
|
874fc741b5 | ||
|
|
605241f6e1 | ||
|
|
dac7b1c5b1 | ||
|
|
76cb1dc237 | ||
|
|
9440b09c66 | ||
|
|
6da0ceec9d | ||
|
|
bcb388ea9e | ||
|
|
288f1320a1 | ||
|
|
4aa461e317 | ||
|
|
54674158ca | ||
|
|
b02a884c16 | ||
|
|
91f0f21f45 | ||
|
|
44a0115b07 | ||
|
|
95bcd14c1d | ||
|
|
9e8c6aed4d | ||
|
|
f63b58edd9 | ||
|
|
ea47873db3 | ||
|
|
a608f98ca5 | ||
|
|
e84d0b9334 | ||
|
|
43b0a83b82 | ||
|
|
4f7e0941dc | ||
|
|
70a2e934f9 | ||
|
|
14801805ac | ||
|
|
54f2bb1daf | ||
|
|
75e380fe14 | ||
|
|
ec97d40242 | ||
|
|
7bb4f5591c | ||
|
|
4447366118 | ||
|
|
7140aa1015 | ||
|
|
16f9b2631e | ||
|
|
a6dee9ee0c | ||
|
|
89b4f84b0a | ||
|
|
09f4c21421 | ||
|
|
9fe10d087f | ||
|
|
12a95dfbc6 | ||
|
|
d9f82806ec | ||
|
|
455cd9c696 | ||
|
|
f695fa736d | ||
|
|
51f0a3f42a | ||
|
|
b7e953bc1a | ||
|
|
8b508bda9a | ||
|
|
b69e7fbe2c | ||
|
|
d5062ec5ae | ||
|
|
7143a8c806 | ||
|
|
b3d1c548e7 | ||
|
|
b28af56523 | ||
|
|
4a08d1d954 | ||
|
|
71d977908d | ||
|
|
cc0da7d8c6 | ||
|
|
b55d5c0e39 | ||
|
|
aafb65f888 | ||
|
|
12272dfb80 | ||
|
|
7e3848cc76 | ||
|
|
2ca50de41b | ||
|
|
9561fcea76 | ||
|
|
b9f45577a7 | ||
|
|
25dd806a18 | ||
|
|
6b23c71bb5 | ||
|
|
236332d8c7 | ||
|
|
de72d7ba13 | ||
|
|
ba6d73fc17 | ||
|
|
450d4b5a0a | ||
|
|
888b1fb021 | ||
|
|
958b032cea | ||
|
|
e9060a3ad9 | ||
|
|
78f43b6e13 | ||
|
|
bbaf7583e4 | ||
|
|
34cc115cdb | ||
|
|
93c6272fe2 | ||
|
|
25402c708e | ||
|
|
33cc635fcf | ||
|
|
129b3f9004 | ||
|
|
01344a991d | ||
|
|
060ac3bb4a | ||
|
|
95677e601a | ||
|
|
a97cc62d0a | ||
|
|
62260aa30b | ||
|
|
32457e83f0 | ||
|
|
2519486a02 | ||
|
|
bec3cc437d | ||
|
|
525a32f9f0 | ||
|
|
36f8f1902c | ||
|
|
bde7b1a828 | ||
|
|
9891b383e7 | ||
|
|
28bc87b873 | ||
|
|
9223173ef2 | ||
|
|
5e72416478 | ||
|
|
595e03c584 | ||
|
|
50a0c93cce | ||
|
|
e06cf70615 | ||
|
|
4c38b1a776 | ||
|
|
677c6d9f89 | ||
|
|
2743681392 | ||
|
|
aacf84f78a | ||
|
|
b95a9bb9b4 | ||
|
|
77541102af | ||
|
|
b337cf9f95 | ||
|
|
f914cb0248 | ||
|
|
c93828569b | ||
|
|
61993a032a | ||
|
|
b99c14b910 | ||
|
|
8aa0185cb8 | ||
|
|
2a1161bff4 | ||
|
|
067b495212 | ||
|
|
894369cc73 | ||
|
|
9a86accc62 | ||
|
|
77be268a70 | ||
|
|
1f051d7a9f | ||
|
|
652b6ae7d2 | ||
|
|
57a5b09328 | ||
|
|
9b806f2690 | ||
|
|
1b56a8b696 | ||
|
|
5a5d2c770c | ||
|
|
a5d06bde03 | ||
|
|
15103ac7fb | ||
|
|
439e735d4b | ||
|
|
7f5df308ad | ||
|
|
2f97baadc6 | ||
|
|
c2863156cd | ||
|
|
75762d64c6 | ||
|
|
8209cffcd0 | ||
|
|
70976460ff | ||
|
|
954155b090 | ||
|
|
5265bc20f1 | ||
|
|
af60a4d407 | ||
|
|
c9a6dc4fab | ||
|
|
9c647dc57a | ||
|
|
52e688df9b | ||
|
|
87f12c7d5a | ||
|
|
e9e9b13df0 | ||
|
|
7ee9c4fb30 | ||
|
|
e43fd0c48a | ||
|
|
27bed22fee | ||
|
|
aae69fa599 | ||
|
|
8abe138150 | ||
|
|
dccb23bb80 | ||
|
|
5e4bf0f019 | ||
|
|
f87c56af5c | ||
|
|
5565aab488 | ||
|
|
dbe6b9dacb | ||
|
|
dd866718b9 | ||
|
|
116c616561 | ||
|
|
084e3df8f7 | ||
|
|
36e421eb5f | ||
|
|
a5b01c3f6f | ||
|
|
f1836c281c | ||
|
|
292289d16d | ||
|
|
4e3bdf0925 | ||
|
|
b17475f013 | ||
|
|
ecea0f90d4 | ||
|
|
a4bf85b1b6 | ||
|
|
d215d31349 | ||
|
|
e4e24399d9 | ||
|
|
8f9d132ed6 | ||
|
|
e651511c35 | ||
|
|
2ecda17618 | ||
|
|
db03b5b102 | ||
|
|
9fd9a7bc10 | ||
|
|
eda9faf956 | ||
|
|
cf70678188 | ||
|
|
b23988c947 | ||
|
|
06f6e75d5a | ||
|
|
c9854b35e2 | ||
|
|
71e4ada39a | ||
|
|
d04d8c3a1d | ||
|
|
283faf7a2f | ||
|
|
0299ff0a79 | ||
|
|
4ee65822aa | ||
|
|
e7ca6c16ff | ||
|
|
771bf78576 | ||
|
|
b9fa2f4125 | ||
|
|
e5b22684cd | ||
|
|
43d37ab1cf | ||
|
|
1fc142a59f | ||
|
|
c4ad95760a | ||
|
|
f0ed170b04 | ||
|
|
38d4b5be1a | ||
|
|
5a7d770a58 | ||
|
|
c8f652aaa8 | ||
|
|
336793b2a1 | ||
|
|
c29ea2e679 | ||
|
|
3b6f05800d | ||
|
|
dda824856a | ||
|
|
474ab586f8 | ||
|
|
6bef35d8ef | ||
|
|
ad12660019 | ||
|
|
016da1d37d | ||
|
|
4e12f959fc | ||
|
|
1c06e9d683 | ||
|
|
01d7a33230 | ||
|
|
d92f5621aa | ||
|
|
8fdc61e227 | ||
|
|
9825b161ff | ||
|
|
108a50f3bb | ||
|
|
95b7e4f9ad | ||
|
|
a526386fbb | ||
|
|
3fb3453166 | ||
|
|
8dd0fe3c40 | ||
|
|
b1f0797a1f | ||
|
|
416e355495 | ||
|
|
62acc18e7d | ||
|
|
06d80032fe | ||
|
|
4e795c81f4 | ||
|
|
718ba719ca | ||
|
|
a5ed3ca446 | ||
|
|
3a93c50e38 | ||
|
|
654f673def | ||
|
|
1111382b53 | ||
|
|
1e605cdf0f | ||
|
|
2c27f422d9 | ||
|
|
f53a2f1b94 | ||
|
|
4fb40a6af7 | ||
|
|
6f6f5738fa | ||
|
|
40aacbf279 | ||
|
|
9ea3bfb7c7 | ||
|
|
dc2d52fc09 | ||
|
|
7dcebd51ab | ||
|
|
9ef5769f93 | ||
|
|
d12b197ec9 | ||
|
|
c5b55fa476 | ||
|
|
355fcced55 | ||
|
|
701fb1378e | ||
|
|
b120c34177 | ||
|
|
c23caf899f | ||
|
|
52c30e588c | ||
|
|
9da8f4d35b | ||
|
|
1b89189efa | ||
|
|
e53c5097f9 | ||
|
|
cb675300b1 | ||
|
|
c6a1f42c44 | ||
|
|
dbda90b15b | ||
|
|
29a04d9d83 | ||
|
|
0a6dc68d13 | ||
|
|
a1a85d08af | ||
|
|
601eec7da5 | ||
|
|
a54f3c8c7f | ||
|
|
17478491e9 | ||
|
|
245cf6d2e0 | ||
|
|
71af9741cc | ||
|
|
0503b64205 | ||
|
|
c9d4cac3ff | ||
|
|
a2932a0393 | ||
|
|
6917303e1b | ||
|
|
f685363574 | ||
|
|
03c19ccae9 | ||
|
|
7313b4b649 | ||
|
|
ff439369da | ||
|
|
24e470a099 | ||
|
|
8e72ddde32 | ||
|
|
07a7ea1f23 | ||
|
|
3c854d4af9 | ||
|
|
7f3f011104 | ||
|
|
a5cfae4b33 | ||
|
|
516649a508 | ||
|
|
abe23250c4 | ||
|
|
0f575907c7 | ||
|
|
835a3f6149 | ||
|
|
b93ef22687 | ||
|
|
bfd927d395 | ||
|
|
cb79302867 | ||
|
|
211d6f4005 | ||
|
|
ddee6d2b6a | ||
|
|
575c34467f | ||
|
|
dc8c27b1f9 | ||
|
|
4639ec87d2 | ||
|
|
50079670f9 | ||
|
|
ae12e65712 | ||
|
|
2f9be335cb | ||
|
|
9e59d927f2 | ||
|
|
ced3e5fec8 | ||
|
|
50eb523d8e | ||
|
|
d6baf1b32a | ||
|
|
60b8dfaa2d | ||
|
|
815f398ada | ||
|
|
56ed31ed6f | ||
|
|
3213fbff8b | ||
|
|
4bca9c63da | ||
|
|
01fe70a29a | ||
|
|
e43804d950 | ||
|
|
17206fc538 | ||
|
|
8cda6ede84 | ||
|
|
a6ec038189 | ||
|
|
ffaf6c14e4 | ||
|
|
3a6915c0b6 | ||
|
|
93a8c83a68 | ||
|
|
1302addcdd | ||
|
|
490cbd3f0d | ||
|
|
631355d788 | ||
|
|
ec1ab05ae6 | ||
|
|
f5f26f334f | ||
|
|
dba579b546 | ||
|
|
fa68b8bb35 | ||
|
|
ceb84ce020 | ||
|
|
68aa7fa3a4 | ||
|
|
70cd0655ed | ||
|
|
956ee06ea6 | ||
|
|
e15e34db93 | ||
|
|
3c23de9735 | ||
|
|
91da46dd63 | ||
|
|
4d280ff010 | ||
|
|
0297dd2664 | ||
|
|
56e328f31f | ||
|
|
ac2c1e019f | ||
|
|
56073fd522 | ||
|
|
07f6572816 | ||
|
|
8a018aa0f2 | ||
|
|
936d5821f9 | ||
|
|
04493035cd | ||
|
|
08064c4243 | ||
|
|
ed1c2cb596 | ||
|
|
212e0e624f | ||
|
|
e8af778962 | ||
|
|
26dba53d99 | ||
|
|
1c6a64caf2 | ||
|
|
f7a6241ac0 | ||
|
|
b6453383cf | ||
|
|
615c6cb388 | ||
|
|
31f890d55c | ||
|
|
567c09850c | ||
|
|
8d076efd71 | ||
|
|
062126c43d | ||
|
|
f9667cd80f | ||
|
|
65c2f58a66 | ||
|
|
030b945828 | ||
|
|
fd4240b774 | ||
|
|
8c0e022b44 | ||
|
|
da8e75f98a | ||
|
|
a1d2208bf3 | ||
|
|
b6b76eb137 | ||
|
|
19b16fe796 | ||
|
|
fec1553041 | ||
|
|
bc2f693c55 | ||
|
|
594ae20a6e | ||
|
|
14388f4bb1 | ||
|
|
369e6d1e61 | ||
|
|
789200d454 | ||
|
|
dcfab0f4dd | ||
|
|
9677ed9e2d | ||
|
|
a4ece6c1c5 | ||
|
|
e34396015f | ||
|
|
64e3310376 | ||
|
|
a955d8f890 | ||
|
|
bbc9532444 | ||
|
|
389afde138 | ||
|
|
fe5d9e486b | ||
|
|
6959e140af | ||
|
|
3a9306a9c2 | ||
|
|
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 | ||
|
|
dc2f9c304d | ||
|
|
462d5c3b12 | ||
|
|
39e90a20da | ||
|
|
b40014d709 | ||
|
|
2bdc229a9a | ||
|
|
61684830bf | ||
|
|
e93a0556e7 | ||
|
|
12668b78b9 | ||
|
|
8255088508 | ||
|
|
e66f7f012e | ||
|
|
3e38da2120 | ||
|
|
f2e7c82231 | ||
|
|
20e56d7dfa | ||
|
|
13225faa9e | ||
|
|
99cb752c71 | ||
|
|
5da4ced8c1 | ||
|
|
e363a21619 | ||
|
|
09efbaf621 | ||
|
|
31027047e3 | ||
|
|
629eb4ca90 | ||
|
|
c4e6e5eca4 | ||
|
|
ea72d41e6d | ||
|
|
c0f5b04472 | ||
|
|
532b32dab5 | ||
|
|
fb5c96731a | ||
|
|
3f8eb8cb6b | ||
|
|
89dc64ab66 | ||
|
|
6968cff2b6 | ||
|
|
c390e9e877 | ||
|
|
dee47ec978 | ||
|
|
fce2a16e42 | ||
|
|
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 | ||
|
|
1e400624e0 | ||
|
|
b190a0eaba | ||
|
|
afc779440a | ||
|
|
7f71717a9f | ||
|
|
b9931da241 | ||
|
|
eaf0d5e0a0 | ||
|
|
832206ef80 | ||
|
|
85d4f2843e | ||
|
|
0849aa3f03 | ||
|
|
4cdeb214a7 | ||
|
|
3c727bc46f | ||
|
|
955ccfae88 | ||
|
|
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 | ||
|
|
aac915b285 | ||
|
|
7208f045c1 | ||
|
|
f7a3c42da1 | ||
|
|
4d1c53eb1e | ||
|
|
7bcc9b19ac | ||
|
|
7cfc729679 | ||
|
|
ec3b68ad28 |
@@ -1 +1,2 @@
|
|||||||
**/*.spec.js
|
dist/**
|
||||||
|
.github/**
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
|
"jest/globals": true,
|
||||||
"node": true
|
"node": true
|
||||||
},
|
},
|
||||||
|
"parser": "@babel/eslint-parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
"experimentalObjectRestSpread": true,
|
"experimentalObjectRestSpread": true,
|
||||||
@@ -11,9 +13,16 @@
|
|||||||
},
|
},
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"extends": ["prettier", "eslint:recommended"],
|
"extends": ["eslint:recommended", "plugin:jsdoc/recommended", "plugin:prettier/recommended"],
|
||||||
"plugins": ["prettier"],
|
"plugins": ["jest", "jsdoc", "prettier"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"prettier/prettier": ["error"]
|
"no-prototype-builtins": 0,
|
||||||
|
"no-unused-vars": 0,
|
||||||
|
"jsdoc/check-indentation": 0,
|
||||||
|
"jsdoc/check-alignment": 0,
|
||||||
|
"jsdoc/check-line-alignment": 0,
|
||||||
|
"jsdoc/multiline-blocks": 0,
|
||||||
|
"jsdoc/newline-after-description": 0,
|
||||||
|
"jsdoc/tag-lines": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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']
|
||||||
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -23,6 +23,9 @@ A clear and concise description of what you expected to happen.
|
|||||||
**Screenshots**
|
**Screenshots**
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Code Sample**
|
||||||
|
If applicable, add the code sample or a link to the [live editor](https://mermaid-js.github.io/mermaid-live-editor).
|
||||||
|
|
||||||
**Desktop (please complete the following information):**
|
**Desktop (please complete the following information):**
|
||||||
- OS: [e.g. iOS]
|
- OS: [e.g. iOS]
|
||||||
- Browser [e.g. chrome, safari]
|
- Browser [e.g. chrome, safari]
|
||||||
|
|||||||
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: npm
|
||||||
|
open-pull-requests-limit: 10
|
||||||
|
directory: /
|
||||||
|
target-branch: develop
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
day: monday
|
||||||
|
time: "07:00"
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: /
|
||||||
|
target-branch: develop
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
day: monday
|
||||||
|
time: "07:00"
|
||||||
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!** 🎉
|
||||||
58
.github/workflows/build.yml
vendored
Normal file
58
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name: Build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [16.x]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
cache: yarn
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
|
- name: Install Yarn
|
||||||
|
run: npm i yarn --global
|
||||||
|
|
||||||
|
- name: Install Packages
|
||||||
|
run: |
|
||||||
|
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@v2
|
||||||
|
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
|
||||||
|
|
||||||
52
.github/workflows/e2e.yml
vendored
Normal file
52
.github/workflows/e2e.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
name: E2E
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [16.x]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2.3.4
|
||||||
|
|
||||||
|
- name: Setup Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
cache: yarn
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
|
||||||
|
- name: Install Yarn
|
||||||
|
run: npm i yarn --global
|
||||||
|
|
||||||
|
- name: Install Packages
|
||||||
|
run: |
|
||||||
|
yarn install --frozen-lockfile
|
||||||
|
env:
|
||||||
|
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||||
|
|
||||||
|
- name: Run Build
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
# - name: Run e2e Tests
|
||||||
|
# run: |
|
||||||
|
# yarn e2e
|
||||||
|
|
||||||
|
#- 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
|
||||||
4
.github/workflows/issue-triage.yml
vendored
4
.github/workflows/issue-triage.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
triage:
|
triage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: andymckay/labeler@1.0
|
- uses: andymckay/labeler@1.0.4
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
labels: "Status: Triage"
|
add-labels: "Status: Triage"
|
||||||
|
|||||||
13
.github/workflows/lock-closed-issue.yml
vendored
13
.github/workflows/lock-closed-issue.yml
vendored
@@ -1,13 +0,0 @@
|
|||||||
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-config-validator.yml
vendored
Normal file
13
.github/workflows/pr-labeler-config-validator.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
name: Validate PR Labeler Configuration
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pr-labeler:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v2.3.4
|
||||||
|
- name: Validate Configuration
|
||||||
|
uses: Yash-Singh1/pr-labeler-config-validator@releases/v0.0.3
|
||||||
|
with:
|
||||||
|
configuration-path: .github/pr-labeler.yml
|
||||||
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_target:
|
||||||
|
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
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
15
.github/workflows/release-preview-publish.yml
vendored
15
.github/workflows/release-preview-publish.yml
vendored
@@ -8,15 +8,12 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [10.x]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- name: Setup Node.js ${{ matrix.node-version }}
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: 16.x
|
||||||
- name: Install Yarn
|
- name: Install Yarn
|
||||||
run: npm i yarn --global
|
run: npm i yarn --global
|
||||||
|
|
||||||
@@ -24,11 +21,11 @@ jobs:
|
|||||||
run: npm i json --global
|
run: npm i json --global
|
||||||
|
|
||||||
- name: Install Packages
|
- name: Install Packages
|
||||||
run: yarn install
|
run: yarn install --frozen-lockfile
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
PREVIEW_VERSION=$(git rev-list --count --first-parent HEAD)
|
PREVIEW_VERSION=8
|
||||||
VERSION=$(echo ${{github.ref}} | tail -c +20)-preview.$PREVIEW_VERSION
|
VERSION=$(echo ${{github.ref}} | tail -c +20)-preview.$PREVIEW_VERSION
|
||||||
echo $VERSION
|
echo $VERSION
|
||||||
npm version --no-git-tag-version --allow-same-version $VERSION
|
npm version --no-git-tag-version --allow-same-version $VERSION
|
||||||
|
|||||||
44
.github/workflows/release-publish.yml
vendored
Normal file
44
.github/workflows/release-publish.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: Publish release
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2.3.4
|
||||||
|
- uses: fregante/setup-git-user@v1
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 16.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
.gitignore
vendored
13
.gitignore
vendored
@@ -12,3 +12,16 @@ yarn-error.log
|
|||||||
token
|
token
|
||||||
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
|
dist/classTest.html
|
||||||
|
|
||||||
|
dist/sequenceTest.html
|
||||||
|
|
||||||
|
.vscode/
|
||||||
|
cypress/platform/current.html
|
||||||
|
cypress/platform/experimental.html
|
||||||
|
local/
|
||||||
|
|
||||||
|
_site
|
||||||
|
Gemfile.lock
|
||||||
|
/.vs
|
||||||
|
|||||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
yarn dlx lint-staged
|
||||||
5
.lintstagedrc.json
Normal file
5
.lintstagedrc.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"*": [
|
||||||
|
"yarn lint:fix"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
version: 1
|
version: 2
|
||||||
snapshot:
|
snapshot:
|
||||||
widths: [1280]
|
widths:
|
||||||
|
- 1280
|
||||||
|
discovery:
|
||||||
|
disable-cache: true
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 100,
|
|
||||||
"singleQuote": true
|
|
||||||
}
|
|
||||||
8
.prettierrc.json
Normal file
8
.prettierrc.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"endOfLine": "auto",
|
||||||
|
"plugins": [
|
||||||
|
"prettier-plugin-jsdoc"
|
||||||
|
],
|
||||||
|
"printWidth": 100,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
12
.travis.yml
12
.travis.yml
@@ -1,12 +0,0 @@
|
|||||||
dist: trusty
|
|
||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- "10"
|
|
||||||
cache:
|
|
||||||
npm: false
|
|
||||||
script:
|
|
||||||
- yarn build
|
|
||||||
- yarn test --coverage
|
|
||||||
- yarn e2e
|
|
||||||
after_success:
|
|
||||||
- cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
|
|
||||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"typescript.format.enable": false,
|
|
||||||
"typescript.reportStyleChecksAsWarnings": false,
|
|
||||||
"typescript.validate.enable": false,
|
|
||||||
"javascript.validate.enable": false,
|
|
||||||
"editor.formatOnSave": false,
|
|
||||||
"editor.snippetSuggestions": "top"
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@ Here are a few things to know to get you started on the right path.
|
|||||||
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:
|
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
|
* 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
|
* Smaller low-risk changes like dependencies, documentation etc can be merged by active collaborators
|
||||||
* documentation (updates to the docs folder is also allowed via direct commits)
|
* documentation (updates to the docs folder is also allowed via direct commits)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
@@ -26,7 +26,35 @@ Another:
|
|||||||
|
|
||||||
## Committing documentation
|
## Committing documentation
|
||||||
|
|
||||||
Less strict here, it is ok to commit directly in the develop branch if you are a collaborator.
|
Less strict here, it is OK to commit directly in the `develop` branch if you are a collaborator.
|
||||||
|
|
||||||
|
The documentation is located in the `docs` directory and published using GitHub Pages.
|
||||||
|
The documentation site is powered by [Docsify](https://docsify.js.org), a simple documentation site generator.
|
||||||
|
|
||||||
|
The documentation is written in Markdown, for more information about Markdown [see the GitHub Markdown help page](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax).
|
||||||
|
|
||||||
|
If you want to preview the documentation site on your machine, you need to install `docsify-cli`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ npm i docsify-cli -g
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are more familiar with Yarn, you can use the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ yarn global add docsify-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
The above command will install `docsify-cli` globally.
|
||||||
|
If the installation is successful, the command `docsify` will be available in your `PATH`.
|
||||||
|
|
||||||
|
You can now run the following command to serve the documentation site:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ docsify serve docs
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the local HTTP server is listening, you can point your browser at http://localhost:3000.
|
||||||
|
|
||||||
## Branching
|
## Branching
|
||||||
|
|
||||||
@@ -57,7 +85,7 @@ The rendering tests are very straightforward to create. There is a function imgS
|
|||||||
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.
|
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:
|
This is what a rendering test looks like:
|
||||||
```
|
```javascript
|
||||||
it('should render forks and joins', () => {
|
it('should render forks and joins', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014 - 2018 Knut Sveidqvist
|
Copyright (c) 2014 - 2021 Knut Sveidqvist
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
88
README.md
88
README.md
@@ -1,17 +1,40 @@
|
|||||||
<!-- <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> -->
|
|
||||||
|
|
||||||
# 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)
|
# 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)
|
||||||
|
|
||||||
|
English | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
:trophy: **Mermaid was nominated and won the [JS Open Source Awards (2019)](https://osawards.com/javascript/2019) in the category "The most exciting use of technology"!!!**
|
||||||
|
|
||||||
|
**Thanks to all involved, people committing pull requests, people answering questions! 🙏**
|
||||||
|
|
||||||
|
<a href="https://mermaid-js.github.io/mermaid/landing/" alt="Link to landing page for the book The Official Guide To mermaid.js"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/img/book-banner-post-release.jpg"></a>
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
<!-- <Main description> -->
|
<!-- <Main description> -->
|
||||||
__Generate diagrams, charts, graphs or flows from markdown-like text via javascript.__
|
Mermaid is a Javascript based diagramming and charting tool that uses Markdown-inspired text definitions and a renderer to create and modify complex diagrams. The main purpose of Mermaid is to help documentation catch up with development.
|
||||||
See our [documentation](http://mermaid-js.github.io/mermaid/) and start simplifying yours. Play in 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).
|
|
||||||
|
> Doc-Rot is a Catch-22 that Mermaid helps to solve.
|
||||||
|
|
||||||
|
Diagramming and documentation costs precious developer time and gets outdated quickly.
|
||||||
|
But not having diagrams or docs ruins productivity and hurts organizational learning. <br/>
|
||||||
|
Mermaid addresses this problem by cutting the time, effort and tooling that is required to create modifiable diagrams and charts, for smarter and more reusable content.
|
||||||
|
The text definitions for Mermaid diagrams allows for it to be updated easily, it can also be made part of production scripts (and other pieces of code).
|
||||||
|
So less time needs to be spent on documenting, as a separate and laborious task. <br/>
|
||||||
|
Even non-programmers can create diagrams through the [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/).<br/>
|
||||||
|
[Tutorials](./docs/Tutorials.md) has video tutorials.
|
||||||
|
Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
|
||||||
|
|
||||||
|
For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/n00b-overview.md) and [Usage](./docs/usage.md).
|
||||||
|
|
||||||
|
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [Changelog](./docs/CHANGELOG.md)
|
||||||
|
|
||||||
<!-- </Main description> -->
|
<!-- </Main description> -->
|
||||||
|
|
||||||
:trophy: _"The most exciting use of technology"_ - [JS Open Source Awards (2019)](https://osawards.com/javascript/#nominees)
|
## Examples
|
||||||
|
|
||||||
|
__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>
|
<table>
|
||||||
<!-- <Flowchart> -->
|
<!-- <Flowchart> -->
|
||||||
<tr><td colspan=2 align="center">
|
<tr><td colspan=2 align="center">
|
||||||
@@ -27,7 +50,7 @@ C -->|One| D[Result 1]
|
|||||||
C -->|Two| E[Result 2]
|
C -->|Two| E[Result 2]
|
||||||
</pre></td>
|
</pre></td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="./img/gray-flow.png" />
|
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-flow.png" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </Flowchart> -->
|
<!-- </Flowchart> -->
|
||||||
@@ -49,7 +72,7 @@ John->>Bob: How about you?
|
|||||||
Bob-->>John: Jolly good!
|
Bob-->>John: Jolly good!
|
||||||
</pre></td>
|
</pre></td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="./img/gray-sequence.png" />
|
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-sequence.png" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </Sequence> -->
|
<!-- </Sequence> -->
|
||||||
@@ -70,7 +93,7 @@ Parallel 3 : des5, after des3, 1d
|
|||||||
Parallel 4 : des6, after des4, 1d
|
Parallel 4 : des6, after des4, 1d
|
||||||
</pre></td>
|
</pre></td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="./img/gray-gantt.png" />
|
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-gantt.png" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </Gantt> -->
|
<!-- </Gantt> -->
|
||||||
@@ -99,18 +122,18 @@ class Class10 {
|
|||||||
}
|
}
|
||||||
</pre></td>
|
</pre></td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="./img/gray-class.png" />
|
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-class.png" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </Class> -->
|
<!-- </Class> -->
|
||||||
<!-- <State> -->
|
<!-- <State> -->
|
||||||
<tr><td colspan=2 align="center">
|
<tr><td colspan=2 align="center">
|
||||||
<b>State</b><br />
|
<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>]
|
[<a href="http://mermaid-js.github.io/mermaid/#/stateDiagram">docs</a> - <a href="https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><pre>
|
<td><pre>
|
||||||
stateDiagram
|
stateDiagram-v2
|
||||||
[*] --> Still
|
[*] --> Still
|
||||||
Still --> [*]
|
Still --> [*]
|
||||||
Still --> Moving
|
Still --> Moving
|
||||||
@@ -119,7 +142,7 @@ Moving --> Crash
|
|||||||
Crash --> [*]
|
Crash --> [*]
|
||||||
</pre></td>
|
</pre></td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="./img/gray-state.png" />
|
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-state.png" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </State> -->
|
<!-- </State> -->
|
||||||
@@ -136,7 +159,7 @@ pie
|
|||||||
"Rats" : 15
|
"Rats" : 15
|
||||||
</pre></td>
|
</pre></td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="./img/gray-pie.png" />
|
<img src="https://raw.githubusercontent.com/mermaid-js/mermaid/master/img/gray-pie.png" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </Pie> -->
|
<!-- </Pie> -->
|
||||||
@@ -149,20 +172,45 @@ pie
|
|||||||
<td colspan="2" align="center"><i>Coming soon!</i></td>
|
<td colspan="2" align="center"><i>Coming soon!</i></td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- </Git> -->
|
<!-- </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>
|
</table>
|
||||||
|
|
||||||
## Related projects
|
## Related projects
|
||||||
|
|
||||||
- [Command Line Interface](https://github.com/mermaid-js/mermaid.cli)
|
- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli)
|
||||||
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
|
||||||
|
- [HTTP Server](https://github.com/TomWright/mermaid-server)
|
||||||
|
|
||||||
# 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)
|
## Contributors [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
|
Detailed information about how to contribute can be found in the [contribution guide](CONTRIBUTING.md)
|
||||||
|
|
||||||
# Appreciation
|
## Appreciation
|
||||||
A quick note from Knut Sveidqvist:
|
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!*
|
>*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.*
|
>*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.*
|
||||||
|
|||||||
220
README.zh-CN.md
Normal file
220
README.zh-CN.md
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
# 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)
|
||||||
|
|
||||||
|
[English](./README.md) | 简体中文
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
:trophy: **Mermaid 被提名并获得了 [JS Open Source Awards (2019)](https://osawards.com/javascript/2019) 的 "The most exciting use of technology" 奖项!!!**
|
||||||
|
|
||||||
|
**感谢所有参与进来提交 PR,解答疑问的人们! 🙏**
|
||||||
|
|
||||||
|
<a href="https://mermaid-js.github.io/mermaid/landing/" alt="Link to landing page for the book The Official Guide To mermaid.js"><img src="https://github.com/mermaid-js/mermaid/blob/master/docs/img/book-banner-pre-release.jpg"></a>
|
||||||
|
|
||||||
|
## 关于 Mermaid
|
||||||
|
|
||||||
|
<!-- <Main description> -->
|
||||||
|
Mermaid 是一个基于 Javascript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。Mermaid 诞生的主要目的是让文档的更新能够及时跟上开发进度。
|
||||||
|
|
||||||
|
> Mermaid 致力于解决 Doc-Rot 这个令人头疼的问题。
|
||||||
|
|
||||||
|
绘图和编写文档花费了开发者宝贵的开发时间,而且随着业务的变更,它很快就会过期。 但是如果缺少了图表或文档,对于生产力和团队新人的业务学习都会产生巨大的阻碍。 <br/>
|
||||||
|
Mermaid 通过减少创建可修改的图表所需要的时间、精力和工具来解决这一难题,从而提高了内容的智能化和可重用性。 作为一个基于文本的绘图工具, Mermaid 天生就易于维护和更新,它也可以作为生产脚本(或其他代码)的一部分,使得文档编写变得更加简单。 有了它之后,开发者可以从维护文档这个与开发割离且麻烦的任务中解放出来。 <br/>
|
||||||
|
即使是从未接触过编程的非专业人员也可以通过 [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/)来创建图表。<br/>
|
||||||
|
你可以访问 [教程](./docs/Tutorials.md) 来查看 Live Editor 的视频教程。
|
||||||
|
U也可以查看 [Mermaid 的集成和使用](./docs/integrations.md) 这个清单来检查你的文档工具是否已经集成了 Mermaid 支持。
|
||||||
|
|
||||||
|
如果想要查看关于 Mermaid 更详细的介绍及基础使用方式,可以查看 [入门指引](./docs/n00b-overview.md) and [用法](./docs/usage.md).
|
||||||
|
|
||||||
|
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [文档](https://mermaidjs.github.io) | 🙌 [贡献](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [更新日志](./docs/CHANGELOG.md)
|
||||||
|
|
||||||
|
<!-- </Main description> -->
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
|
||||||
|
__下面是一些使用 Mermaid 和类 Markdown 语法创建的图表示例。点击 [语法](https://mermaid-js.github.io/mermaid/#/n00b-syntaxReference) 查看详情__
|
||||||
|
<table>
|
||||||
|
<!-- <Flowchart> -->
|
||||||
|
<tr><td colspan=2 align="center">
|
||||||
|
<b>流程图</b></br>
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/flowchart">文档</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>时序图</b><br />
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/sequenceDiagram">文档</a> - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5BbGljZS0-PkpvaG46IEhlbGxvIEpvaG4sIGhvdyBhcmUgeW91P1xubG9vcCBIZWFsdGhjaGVja1xuICAgIEpvaG4tPj5Kb2huOiBGaWdodCBhZ2FpbnN0IGh5cG9jaG9uZHJpYVxuZW5kXG5Ob3RlIHJpZ2h0IG9mIEpvaG46IFJhdGlvbmFsIHRob3VnaHRzIVxuSm9obi0tPj5BbGljZTogR3JlYXQhXG5Kb2huLT4-Qm9iOiBIb3cgYWJvdXQgeW91P1xuQm9iLS0-PkpvaG46IEpvbGx5IGdvb2QhIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0">live editor</a>]
|
||||||
|
</td></tr>
|
||||||
|
<tr>
|
||||||
|
<td><pre>
|
||||||
|
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!
|
||||||
|
</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>甘特图</b><br />
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/gantt">文档</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>类图</b><br />
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/classDiagram">文档</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>状态图</b><br />
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/stateDiagram">文档</a> - <a href="https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBTdGlsbFxuICAgIFN0aWxsIC0tPiBbKl1cbiAgICBTdGlsbCAtLT4gTW92aW5nXG4gICAgTW92aW5nIC0tPiBTdGlsbFxuICAgIE1vdmluZyAtLT4gQ3Jhc2hcbiAgICBDcmFzaCAtLT4gWypdIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQiLCJ0aGVtZVZhcmlhYmxlcyI6eyJiYWNrZ3JvdW5kIjoid2hpdGUiLCJwcmltYXJ5Q29sb3IiOiIjRUNFQ0ZGIiwic2Vjb25kYXJ5Q29sb3IiOiIjZmZmZmRlIiwidGVydGlhcnlDb2xvciI6ImhzbCg4MCwgMTAwJSwgOTYuMjc0NTA5ODAzOSUpIiwicHJpbWFyeUJvcmRlckNvbG9yIjoiaHNsKDI0MCwgNjAlLCA4Ni4yNzQ1MDk4MDM5JSkiLCJzZWNvbmRhcnlCb3JkZXJDb2xvciI6ImhzbCg2MCwgNjAlLCA4My41Mjk0MTE3NjQ3JSkiLCJ0ZXJ0aWFyeUJvcmRlckNvbG9yIjoiaHNsKDgwLCA2MCUsIDg2LjI3NDUwOTgwMzklKSIsInByaW1hcnlUZXh0Q29sb3IiOiIjMTMxMzAwIiwic2Vjb25kYXJ5VGV4dENvbG9yIjoiIzAwMDAyMSIsInRlcnRpYXJ5VGV4dENvbG9yIjoicmdiKDkuNTAwMDAwMDAwMSwgOS41MDAwMDAwMDAxLCA5LjUwMDAwMDAwMDEpIiwibGluZUNvbG9yIjoiIzMzMzMzMyIsInRleHRDb2xvciI6IiMzMzMiLCJtYWluQmtnIjoiI0VDRUNGRiIsInNlY29uZEJrZyI6IiNmZmZmZGUiLCJib3JkZXIxIjoiIzkzNzBEQiIsImJvcmRlcjIiOiIjYWFhYTMzIiwiYXJyb3doZWFkQ29sb3IiOiIjMzMzMzMzIiwiZm9udEZhbWlseSI6IlwidHJlYnVjaGV0IG1zXCIsIHZlcmRhbmEsIGFyaWFsIiwiZm9udFNpemUiOiIxNnB4IiwibGFiZWxCYWNrZ3JvdW5kIjoiI2U4ZThlOCIsIm5vZGVCa2ciOiIjRUNFQ0ZGIiwibm9kZUJvcmRlciI6IiM5MzcwREIiLCJjbHVzdGVyQmtnIjoiI2ZmZmZkZSIsImNsdXN0ZXJCb3JkZXIiOiIjYWFhYTMzIiwiZGVmYXVsdExpbmtDb2xvciI6IiMzMzMzMzMiLCJ0aXRsZUNvbG9yIjoiIzMzMyIsImVkZ2VMYWJlbEJhY2tncm91bmQiOiIjZThlOGU4IiwiYWN0b3JCb3JkZXIiOiJoc2woMjU5LjYyNjE2ODIyNDMsIDU5Ljc3NjUzNjMxMjglLCA4Ny45MDE5NjA3ODQzJSkiLCJhY3RvckJrZyI6IiNFQ0VDRkYiLCJhY3RvclRleHRDb2xvciI6ImJsYWNrIiwiYWN0b3JMaW5lQ29sb3IiOiJncmV5Iiwic2lnbmFsQ29sb3IiOiIjMzMzIiwic2lnbmFsVGV4dENvbG9yIjoiIzMzMyIsImxhYmVsQm94QmtnQ29sb3IiOiIjRUNFQ0ZGIiwibGFiZWxCb3hCb3JkZXJDb2xvciI6ImhzbCgyNTkuNjI2MTY4MjI0MywgNTkuNzc2NTM2MzEyOCUsIDg3LjkwMTk2MDc4NDMlKSIsImxhYmVsVGV4dENvbG9yIjoiYmxhY2siLCJsb29wVGV4dENvbG9yIjoiYmxhY2siLCJub3RlQm9yZGVyQ29sb3IiOiIjYWFhYTMzIiwibm90ZUJrZ0NvbG9yIjoiI2ZmZjVhZCIsIm5vdGVUZXh0Q29sb3IiOiJibGFjayIsImFjdGl2YXRpb25Cb3JkZXJDb2xvciI6IiM2NjYiLCJhY3RpdmF0aW9uQmtnQ29sb3IiOiIjZjRmNGY0Iiwic2VxdWVuY2VOdW1iZXJDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yIjoicmdiYSgxMDIsIDEwMiwgMjU1LCAwLjQ5KSIsImFsdFNlY3Rpb25Ca2dDb2xvciI6IndoaXRlIiwic2VjdGlvbkJrZ0NvbG9yMiI6IiNmZmY0MDAiLCJ0YXNrQm9yZGVyQ29sb3IiOiIjNTM0ZmJjIiwidGFza0JrZ0NvbG9yIjoiIzhhOTBkZCIsInRhc2tUZXh0TGlnaHRDb2xvciI6IndoaXRlIiwidGFza1RleHRDb2xvciI6IndoaXRlIiwidGFza1RleHREYXJrQ29sb3IiOiJibGFjayIsInRhc2tUZXh0T3V0c2lkZUNvbG9yIjoiYmxhY2siLCJ0YXNrVGV4dENsaWNrYWJsZUNvbG9yIjoiIzAwMzE2MyIsImFjdGl2ZVRhc2tCb3JkZXJDb2xvciI6IiM1MzRmYmMiLCJhY3RpdmVUYXNrQmtnQ29sb3IiOiIjYmZjN2ZmIiwiZ3JpZENvbG9yIjoibGlnaHRncmV5IiwiZG9uZVRhc2tCa2dDb2xvciI6ImxpZ2h0Z3JleSIsImRvbmVUYXNrQm9yZGVyQ29sb3IiOiJncmV5IiwiY3JpdEJvcmRlckNvbG9yIjoiI2ZmODg4OCIsImNyaXRCa2dDb2xvciI6InJlZCIsInRvZGF5TGluZUNvbG9yIjoicmVkIiwibGFiZWxDb2xvciI6ImJsYWNrIiwiZXJyb3JCa2dDb2xvciI6IiM1NTIyMjIiLCJlcnJvclRleHRDb2xvciI6IiM1NTIyMjIiLCJjbGFzc1RleHQiOiIjMTMxMzAwIiwiZmlsbFR5cGUwIjoiI0VDRUNGRiIsImZpbGxUeXBlMSI6IiNmZmZmZGUiLCJmaWxsVHlwZTIiOiJoc2woMzA0LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTMiOiJoc2woMTI0LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkiLCJmaWxsVHlwZTQiOiJoc2woMTc2LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTUiOiJoc2woLTQsIDEwMCUsIDkzLjUyOTQxMTc2NDclKSIsImZpbGxUeXBlNiI6ImhzbCg4LCAxMDAlLCA5Ni4yNzQ1MDk4MDM5JSkiLCJmaWxsVHlwZTciOiJoc2woMTg4LCAxMDAlLCA5My41Mjk0MTE3NjQ3JSkifX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9">live editor</a>]
|
||||||
|
</td></tr>
|
||||||
|
<tr>
|
||||||
|
<td><pre>
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> 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>饼图</b><br />
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/pie">文档</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 />
|
||||||
|
[实验特性 - <a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ2l0R3JhcGg6XG5vcHRpb25zXG57XG4gICAgXCJub2RlU3BhY2luZ1wiOiAxNTAsXG4gICAgXCJub2RlUmFkaXVzXCI6IDEwXG59XG5lbmRcbmNvbW1pdFxuYnJhbmNoIG5ld2JyYW5jaFxuY2hlY2tvdXQgbmV3YnJhbmNoXG5jb21taXRcbmNvbW1pdFxuY2hlY2tvdXQgbWFzdGVyXG5jb21taXRcbmNvbW1pdFxubWVyZ2UgbmV3YnJhbmNoXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ">live editor</a>]
|
||||||
|
</td></tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" align="center"><i>敬请期待!</i></td>
|
||||||
|
</tr>
|
||||||
|
<!-- </Git> -->
|
||||||
|
<!-- <Journey> -->
|
||||||
|
<tr><td colspan=2 align="center">
|
||||||
|
<b>用户体验旅程图</b><br />
|
||||||
|
[<a href="http://mermaid-js.github.io/mermaid/#/user-journey">文档</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>
|
||||||
|
|
||||||
|
## 相关项目
|
||||||
|
|
||||||
|
- [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)
|
||||||
|
|
||||||
|
## 贡献者 [](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [](https://github.com/mermaid-js/mermaid/graphs/contributors) [](https://github.com/mermaid-js/mermaid/graphs/contributors)
|
||||||
|
|
||||||
|
Mermaid 是一个不断发展中的社区,并且还在接收新的贡献者。有很多不同的方式可以参与进来,而且我们还在寻找额外的帮助。如果你想知道如何开始贡献,请查看 [这个 issue](https://github.com/mermaid-js/mermaid/issues/866)。
|
||||||
|
|
||||||
|
关于如何贡献的详细信息可以在 [贡献指南](CONTRIBUTING.md) 中找到。
|
||||||
|
|
||||||
|
## 鸣谢
|
||||||
|
来自 Knut Sveidqvist:
|
||||||
|
>*特别感谢 [d3](http://d3js.org/) 和 [dagre-d3](https://github.com/cpettitt/dagre-d3) 这两个优秀的项目,它们提供了图形布局和绘图工具库! *
|
||||||
|
>*同样感谢 [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) 提供了时序图语法的使用。 感谢 Jessica Peter 提供了甘特图渲染的灵感。*
|
||||||
|
>*感谢 [Tyler Long](https://github.com/tylerlong) 从 2017年四月开始成为了项目的合作者。*
|
||||||
|
>
|
||||||
|
>*感谢越来越多的 [贡献者们](https://github.com/knsv/mermaid/graphs/contributors),没有你们,就没有这个项目的今天!*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Mermaid 是由 Knut Sveidqvist 创建,它为了更简单的文档编写而生。*
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
export const curveBasis = 'basis'
|
export const curveBasis = 'basis';
|
||||||
export const curveLinear = 'linear'
|
export const curveLinear = 'linear';
|
||||||
export const curveCardinal = 'cardinal'
|
export const curveCardinal = 'cardinal';
|
||||||
|
|||||||
69
__mocks__/d3.js
vendored
69
__mocks__/d3.js
vendored
@@ -1,11 +1,10 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
let NewD3 = function () {
|
let NewD3 = function () {
|
||||||
function returnThis() {
|
function returnThis() {
|
||||||
return this
|
return this;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
append: function () {
|
append: function () {
|
||||||
return NewD3()
|
return NewD3();
|
||||||
},
|
},
|
||||||
lower: returnThis,
|
lower: returnThis,
|
||||||
attr: returnThis,
|
attr: returnThis,
|
||||||
@@ -16,41 +15,47 @@ let NewD3 = function () {
|
|||||||
getBBox: function () {
|
getBBox: function () {
|
||||||
return {
|
return {
|
||||||
height: 10,
|
height: 10,
|
||||||
width: 20
|
width: 20,
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export const select = function () {
|
export const select = function () {
|
||||||
return new NewD3()
|
return new NewD3();
|
||||||
}
|
};
|
||||||
|
|
||||||
export const selectAll = function () {
|
export const selectAll = function () {
|
||||||
return new NewD3()
|
return new NewD3();
|
||||||
}
|
};
|
||||||
|
|
||||||
export const curveBasis = 'basis'
|
export const curveBasis = 'basis';
|
||||||
export const curveLinear = 'linear'
|
export const curveLinear = 'linear';
|
||||||
export const curveCardinal = 'cardinal'
|
export const curveCardinal = 'cardinal';
|
||||||
|
|
||||||
export const MockD3 = (name, parent) => {
|
export const MockD3 = (name, parent) => {
|
||||||
const children = []
|
const children = [];
|
||||||
const elem = {
|
const elem = {
|
||||||
get __children () { return children },
|
get __children() {
|
||||||
get __name () { return name },
|
return children;
|
||||||
get __parent () { return parent }
|
},
|
||||||
}
|
get __name() {
|
||||||
|
return name;
|
||||||
|
},
|
||||||
|
get __parent() {
|
||||||
|
return parent;
|
||||||
|
},
|
||||||
|
};
|
||||||
elem.append = (name) => {
|
elem.append = (name) => {
|
||||||
const mockElem = MockD3(name, elem)
|
const mockElem = MockD3(name, elem);
|
||||||
children.push(mockElem)
|
children.push(mockElem);
|
||||||
return mockElem
|
return mockElem;
|
||||||
}
|
};
|
||||||
elem.lower = jest.fn(() => elem)
|
elem.lower = jest.fn(() => elem);
|
||||||
elem.attr = jest.fn(() => elem)
|
elem.attr = jest.fn(() => elem);
|
||||||
elem.text = jest.fn(() => elem)
|
elem.text = jest.fn(() => elem);
|
||||||
elem.style = jest.fn(() => elem)
|
elem.style = jest.fn(() => elem);
|
||||||
return elem
|
return elem;
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ module.exports = {
|
|||||||
[
|
[
|
||||||
'@babel/preset-env',
|
'@babel/preset-env',
|
||||||
{
|
{
|
||||||
targets: {
|
targets: 'defaults, ie >= 11, current node',
|
||||||
node: 'current'
|
},
|
||||||
}
|
],
|
||||||
}
|
],
|
||||||
]
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
{ "video": false }
|
{
|
||||||
|
"video": false
|
||||||
|
}
|
||||||
10
cypress/.eslintrc.json
Normal file
10
cypress/.eslintrc.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"cypress/globals": true
|
||||||
|
},
|
||||||
|
"extends": ["plugin:cypress/recommended"],
|
||||||
|
"plugins": ["cypress"],
|
||||||
|
"rules":{
|
||||||
|
"cypress/no-unnecessary-waiting": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,15 +2,16 @@
|
|||||||
|
|
||||||
context('Actions', () => {
|
context('Actions', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/actions')
|
cy.visit('https://example.cypress.io/commands/actions');
|
||||||
})
|
});
|
||||||
|
|
||||||
// https://on.cypress.io/interacting-with-elements
|
// https://on.cypress.io/interacting-with-elements
|
||||||
|
|
||||||
it('.type() - type into a DOM element', () => {
|
it('.type() - type into a DOM element', () => {
|
||||||
// https://on.cypress.io/type
|
// https://on.cypress.io/type
|
||||||
cy.get('.action-email')
|
cy.get('.action-email')
|
||||||
.type('fake@email.com').should('have.value', 'fake@email.com')
|
.type('fake@email.com')
|
||||||
|
.should('have.value', 'fake@email.com')
|
||||||
|
|
||||||
// .type() with special character sequences
|
// .type() with special character sequences
|
||||||
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
|
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
|
||||||
@@ -24,48 +25,52 @@ context('Actions', () => {
|
|||||||
|
|
||||||
// Delay each keypress by 0.1 sec
|
// Delay each keypress by 0.1 sec
|
||||||
.type('slow.typing@email.com', { delay: 100 })
|
.type('slow.typing@email.com', { delay: 100 })
|
||||||
.should('have.value', 'slow.typing@email.com')
|
.should('have.value', 'slow.typing@email.com');
|
||||||
|
|
||||||
cy.get('.action-disabled')
|
cy.get('.action-disabled')
|
||||||
// Ignore error checking prior to type
|
// Ignore error checking prior to type
|
||||||
// like whether the input is visible or disabled
|
// like whether the input is visible or disabled
|
||||||
.type('disabled error checking', { force: true })
|
.type('disabled error checking', { force: true })
|
||||||
.should('have.value', 'disabled error checking')
|
.should('have.value', 'disabled error checking');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.focus() - focus on a DOM element', () => {
|
it('.focus() - focus on a DOM element', () => {
|
||||||
// https://on.cypress.io/focus
|
// https://on.cypress.io/focus
|
||||||
cy.get('.action-focus').focus()
|
cy.get('.action-focus')
|
||||||
|
.focus()
|
||||||
.should('have.class', 'focus')
|
.should('have.class', 'focus')
|
||||||
.prev().should('have.attr', 'style', 'color: orange;')
|
.prev()
|
||||||
})
|
.should('have.attr', 'style', 'color: orange;');
|
||||||
|
});
|
||||||
|
|
||||||
it('.blur() - blur off a DOM element', () => {
|
it('.blur() - blur off a DOM element', () => {
|
||||||
// https://on.cypress.io/blur
|
// https://on.cypress.io/blur
|
||||||
cy.get('.action-blur').type('About to blur').blur()
|
cy.get('.action-blur')
|
||||||
|
.type('About to blur')
|
||||||
|
.blur()
|
||||||
.should('have.class', 'error')
|
.should('have.class', 'error')
|
||||||
.prev().should('have.attr', 'style', 'color: red;')
|
.prev()
|
||||||
})
|
.should('have.attr', 'style', 'color: red;');
|
||||||
|
});
|
||||||
|
|
||||||
it('.clear() - clears an input or textarea element', () => {
|
it('.clear() - clears an input or textarea element', () => {
|
||||||
// https://on.cypress.io/clear
|
// https://on.cypress.io/clear
|
||||||
cy.get('.action-clear').type('Clear this text')
|
cy.get('.action-clear')
|
||||||
|
.type('Clear this text')
|
||||||
.should('have.value', 'Clear this text')
|
.should('have.value', 'Clear this text')
|
||||||
.clear()
|
.clear()
|
||||||
.should('have.value', '')
|
.should('have.value', '');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.submit() - submit a form', () => {
|
it('.submit() - submit a form', () => {
|
||||||
// https://on.cypress.io/submit
|
// https://on.cypress.io/submit
|
||||||
cy.get('.action-form')
|
cy.get('.action-form').find('[type="text"]').type('HALFOFF');
|
||||||
.find('[type="text"]').type('HALFOFF')
|
cy.get('.action-form').submit().next().should('contain', 'Your form has been submitted!');
|
||||||
cy.get('.action-form').submit()
|
});
|
||||||
.next().should('contain', 'Your form has been submitted!')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.click() - click on a DOM element', () => {
|
it('.click() - click on a DOM element', () => {
|
||||||
// https://on.cypress.io/click
|
// https://on.cypress.io/click
|
||||||
cy.get('.action-btn').click()
|
cy.get('.action-btn').click();
|
||||||
|
|
||||||
// You can click on 9 specific positions of an element:
|
// You can click on 9 specific positions of an element:
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
@@ -81,16 +86,16 @@ context('Actions', () => {
|
|||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
||||||
// clicking in the center of the element is the default
|
// clicking in the center of the element is the default
|
||||||
cy.get('#action-canvas').click()
|
cy.get('#action-canvas').click();
|
||||||
|
|
||||||
cy.get('#action-canvas').click('topLeft')
|
cy.get('#action-canvas').click('topLeft');
|
||||||
cy.get('#action-canvas').click('top')
|
cy.get('#action-canvas').click('top');
|
||||||
cy.get('#action-canvas').click('topRight')
|
cy.get('#action-canvas').click('topRight');
|
||||||
cy.get('#action-canvas').click('left')
|
cy.get('#action-canvas').click('left');
|
||||||
cy.get('#action-canvas').click('right')
|
cy.get('#action-canvas').click('right');
|
||||||
cy.get('#action-canvas').click('bottomLeft')
|
cy.get('#action-canvas').click('bottomLeft');
|
||||||
cy.get('#action-canvas').click('bottom')
|
cy.get('#action-canvas').click('bottom');
|
||||||
cy.get('#action-canvas').click('bottomRight')
|
cy.get('#action-canvas').click('bottomRight');
|
||||||
|
|
||||||
// .click() accepts an x and y coordinate
|
// .click() accepts an x and y coordinate
|
||||||
// that controls where the click occurs :)
|
// that controls where the click occurs :)
|
||||||
@@ -102,90 +107,83 @@ context('Actions', () => {
|
|||||||
.click(100, 185)
|
.click(100, 185)
|
||||||
.click(125, 190)
|
.click(125, 190)
|
||||||
.click(150, 185)
|
.click(150, 185)
|
||||||
.click(170, 165)
|
.click(170, 165);
|
||||||
|
|
||||||
// click multiple elements by passing multiple: true
|
// click multiple elements by passing multiple: true
|
||||||
cy.get('.action-labels>.label').click({ multiple: true })
|
cy.get('.action-labels>.label').click({ multiple: true });
|
||||||
|
|
||||||
// Ignore error checking prior to clicking
|
// Ignore error checking prior to clicking
|
||||||
cy.get('.action-opacity>.btn').click({ force: true })
|
cy.get('.action-opacity>.btn').click({ force: true });
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.dblclick() - double click on a DOM element', () => {
|
it('.dblclick() - double click on a DOM element', () => {
|
||||||
// https://on.cypress.io/dblclick
|
// https://on.cypress.io/dblclick
|
||||||
|
|
||||||
// Our app has a listener on 'dblclick' event in our 'scripts.js'
|
// Our app has a listener on 'dblclick' event in our 'scripts.js'
|
||||||
// that hides the div and shows an input on double click
|
// that hides the div and shows an input on double click
|
||||||
cy.get('.action-div').dblclick().should('not.be.visible')
|
cy.get('.action-div').dblclick().should('not.be.visible');
|
||||||
cy.get('.action-input-hidden').should('be.visible')
|
cy.get('.action-input-hidden').should('be.visible');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.check() - check a checkbox or radio element', () => {
|
it('.check() - check a checkbox or radio element', () => {
|
||||||
// https://on.cypress.io/check
|
// https://on.cypress.io/check
|
||||||
|
|
||||||
// By default, .check() will check all
|
// By default, .check() will check all
|
||||||
// matching checkbox or radio elements in succession, one after another
|
// matching checkbox or radio elements in succession, one after another
|
||||||
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
|
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]').check().should('be.checked');
|
||||||
.check().should('be.checked')
|
|
||||||
|
|
||||||
cy.get('.action-radios [type="radio"]').not('[disabled]')
|
cy.get('.action-radios [type="radio"]').not('[disabled]').check().should('be.checked');
|
||||||
.check().should('be.checked')
|
|
||||||
|
|
||||||
// .check() accepts a value argument
|
// .check() accepts a value argument
|
||||||
cy.get('.action-radios [type="radio"]')
|
cy.get('.action-radios [type="radio"]').check('radio1').should('be.checked');
|
||||||
.check('radio1').should('be.checked')
|
|
||||||
|
|
||||||
// .check() accepts an array of values
|
// .check() accepts an array of values
|
||||||
cy.get('.action-multiple-checkboxes [type="checkbox"]')
|
cy.get('.action-multiple-checkboxes [type="checkbox"]')
|
||||||
.check(['checkbox1', 'checkbox2']).should('be.checked')
|
.check(['checkbox1', 'checkbox2'])
|
||||||
|
.should('be.checked');
|
||||||
|
|
||||||
// Ignore error checking prior to checking
|
// Ignore error checking prior to checking
|
||||||
cy.get('.action-checkboxes [disabled]')
|
cy.get('.action-checkboxes [disabled]').check({ force: true }).should('be.checked');
|
||||||
.check({ force: true }).should('be.checked')
|
|
||||||
|
|
||||||
cy.get('.action-radios [type="radio"]')
|
cy.get('.action-radios [type="radio"]').check('radio3', { force: true }).should('be.checked');
|
||||||
.check('radio3', { force: true }).should('be.checked')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.uncheck() - uncheck a checkbox element', () => {
|
it('.uncheck() - uncheck a checkbox element', () => {
|
||||||
// https://on.cypress.io/uncheck
|
// https://on.cypress.io/uncheck
|
||||||
|
|
||||||
// By default, .uncheck() will uncheck all matching
|
// By default, .uncheck() will uncheck all matching
|
||||||
// checkbox elements in succession, one after another
|
// checkbox elements in succession, one after another
|
||||||
cy.get('.action-check [type="checkbox"]')
|
cy.get('.action-check [type="checkbox"]').not('[disabled]').uncheck().should('not.be.checked');
|
||||||
.not('[disabled]')
|
|
||||||
.uncheck().should('not.be.checked')
|
|
||||||
|
|
||||||
// .uncheck() accepts a value argument
|
// .uncheck() accepts a value argument
|
||||||
cy.get('.action-check [type="checkbox"]')
|
cy.get('.action-check [type="checkbox"]')
|
||||||
.check('checkbox1')
|
.check('checkbox1')
|
||||||
.uncheck('checkbox1').should('not.be.checked')
|
.uncheck('checkbox1')
|
||||||
|
.should('not.be.checked');
|
||||||
|
|
||||||
// .uncheck() accepts an array of values
|
// .uncheck() accepts an array of values
|
||||||
cy.get('.action-check [type="checkbox"]')
|
cy.get('.action-check [type="checkbox"]')
|
||||||
.check(['checkbox1', 'checkbox3'])
|
.check(['checkbox1', 'checkbox3'])
|
||||||
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
|
.uncheck(['checkbox1', 'checkbox3'])
|
||||||
|
.should('not.be.checked');
|
||||||
|
|
||||||
// Ignore error checking prior to unchecking
|
// Ignore error checking prior to unchecking
|
||||||
cy.get('.action-check [disabled]')
|
cy.get('.action-check [disabled]').uncheck({ force: true }).should('not.be.checked');
|
||||||
.uncheck({ force: true }).should('not.be.checked')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.select() - select an option in a <select> element', () => {
|
it('.select() - select an option in a <select> element', () => {
|
||||||
// https://on.cypress.io/select
|
// https://on.cypress.io/select
|
||||||
|
|
||||||
// Select option(s) with matching text content
|
// Select option(s) with matching text content
|
||||||
cy.get('.action-select').select('apples')
|
cy.get('.action-select').select('apples');
|
||||||
|
|
||||||
cy.get('.action-select-multiple')
|
cy.get('.action-select-multiple').select(['apples', 'oranges', 'bananas']);
|
||||||
.select(['apples', 'oranges', 'bananas'])
|
|
||||||
|
|
||||||
// Select option(s) with matching value
|
// Select option(s) with matching value
|
||||||
cy.get('.action-select').select('fr-bananas')
|
cy.get('.action-select').select('fr-bananas');
|
||||||
|
|
||||||
cy.get('.action-select-multiple')
|
cy.get('.action-select-multiple').select(['fr-apples', 'fr-oranges', 'fr-bananas']);
|
||||||
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.scrollIntoView() - scroll an element into view', () => {
|
it('.scrollIntoView() - scroll an element into view', () => {
|
||||||
// https://on.cypress.io/scrollintoview
|
// https://on.cypress.io/scrollintoview
|
||||||
@@ -194,27 +192,21 @@ context('Actions', () => {
|
|||||||
// because they're not within
|
// because they're not within
|
||||||
// the viewable area of their parent
|
// the viewable area of their parent
|
||||||
// (we need to scroll to see them)
|
// (we need to scroll to see them)
|
||||||
cy.get('#scroll-horizontal button')
|
cy.get('#scroll-horizontal button').should('not.be.visible');
|
||||||
.should('not.be.visible')
|
|
||||||
|
|
||||||
// scroll the button into view, as if the user had scrolled
|
// scroll the button into view, as if the user had scrolled
|
||||||
cy.get('#scroll-horizontal button').scrollIntoView()
|
cy.get('#scroll-horizontal button').scrollIntoView().should('be.visible');
|
||||||
.should('be.visible')
|
|
||||||
|
|
||||||
cy.get('#scroll-vertical button')
|
cy.get('#scroll-vertical button').should('not.be.visible');
|
||||||
.should('not.be.visible')
|
|
||||||
|
|
||||||
// Cypress handles the scroll direction needed
|
// Cypress handles the scroll direction needed
|
||||||
cy.get('#scroll-vertical button').scrollIntoView()
|
cy.get('#scroll-vertical button').scrollIntoView().should('be.visible');
|
||||||
.should('be.visible')
|
|
||||||
|
|
||||||
cy.get('#scroll-both button')
|
cy.get('#scroll-both button').should('not.be.visible');
|
||||||
.should('not.be.visible')
|
|
||||||
|
|
||||||
// Cypress knows to scroll to the right and down
|
// Cypress knows to scroll to the right and down
|
||||||
cy.get('#scroll-both button').scrollIntoView()
|
cy.get('#scroll-both button').scrollIntoView().should('be.visible');
|
||||||
.should('be.visible')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.trigger() - trigger an event on a DOM element', () => {
|
it('.trigger() - trigger an event on a DOM element', () => {
|
||||||
// https://on.cypress.io/trigger
|
// https://on.cypress.io/trigger
|
||||||
@@ -228,12 +220,12 @@ context('Actions', () => {
|
|||||||
cy.get('.trigger-input-range')
|
cy.get('.trigger-input-range')
|
||||||
.invoke('val', 25)
|
.invoke('val', 25)
|
||||||
.trigger('change')
|
.trigger('change')
|
||||||
.get('input[type=range]').siblings('p')
|
.get('input[type=range]')
|
||||||
.should('have.text', '25')
|
.siblings('p')
|
||||||
})
|
.should('have.text', '25');
|
||||||
|
});
|
||||||
|
|
||||||
it('cy.scrollTo() - scroll the window or element to a position', () => {
|
it('cy.scrollTo() - scroll the window or element to a position', () => {
|
||||||
|
|
||||||
// https://on.cypress.io/scrollTo
|
// https://on.cypress.io/scrollTo
|
||||||
|
|
||||||
// You can scroll to 9 specific positions of an element:
|
// You can scroll to 9 specific positions of an element:
|
||||||
@@ -251,22 +243,22 @@ context('Actions', () => {
|
|||||||
|
|
||||||
// if you chain .scrollTo() off of cy, we will
|
// if you chain .scrollTo() off of cy, we will
|
||||||
// scroll the entire window
|
// scroll the entire window
|
||||||
cy.scrollTo('bottom')
|
cy.scrollTo('bottom');
|
||||||
|
|
||||||
cy.get('#scrollable-horizontal').scrollTo('right')
|
cy.get('#scrollable-horizontal').scrollTo('right');
|
||||||
|
|
||||||
// or you can scroll to a specific coordinate:
|
// or you can scroll to a specific coordinate:
|
||||||
// (x axis, y axis) in pixels
|
// (x axis, y axis) in pixels
|
||||||
cy.get('#scrollable-vertical').scrollTo(250, 250)
|
cy.get('#scrollable-vertical').scrollTo(250, 250);
|
||||||
|
|
||||||
// or you can scroll to a specific percentage
|
// or you can scroll to a specific percentage
|
||||||
// of the (width, height) of the element
|
// of the (width, height) of the element
|
||||||
cy.get('#scrollable-both').scrollTo('75%', '25%')
|
cy.get('#scrollable-both').scrollTo('75%', '25%');
|
||||||
|
|
||||||
// control the easing of the scroll (default is 'swing')
|
// control the easing of the scroll (default is 'swing')
|
||||||
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
|
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' });
|
||||||
|
|
||||||
// control the duration of the scroll (in ms)
|
// control the duration of the scroll (in ms)
|
||||||
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
|
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 });
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
context('Aliasing', () => {
|
context('Aliasing', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/aliasing')
|
cy.visit('https://example.cypress.io/commands/aliasing');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.as() - alias a DOM element for later use', () => {
|
it('.as() - alias a DOM element for later use', () => {
|
||||||
// https://on.cypress.io/as
|
// https://on.cypress.io/as
|
||||||
@@ -12,31 +12,25 @@ context('Aliasing', () => {
|
|||||||
// We don't have to traverse to the element
|
// We don't have to traverse to the element
|
||||||
// later in our code, we reference it with @
|
// later in our code, we reference it with @
|
||||||
|
|
||||||
cy.get('.as-table').find('tbody>tr')
|
cy.get('.as-table').find('tbody>tr').first().find('td').first().find('button').as('firstBtn');
|
||||||
.first().find('td').first()
|
|
||||||
.find('button').as('firstBtn')
|
|
||||||
|
|
||||||
// when we reference the alias, we place an
|
// when we reference the alias, we place an
|
||||||
// @ in front of its name
|
// @ in front of its name
|
||||||
cy.get('@firstBtn').click()
|
cy.get('@firstBtn').click();
|
||||||
|
|
||||||
cy.get('@firstBtn')
|
cy.get('@firstBtn').should('have.class', 'btn-success').and('contain', 'Changed');
|
||||||
.should('have.class', 'btn-success')
|
});
|
||||||
.and('contain', 'Changed')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.as() - alias a route for later use', () => {
|
it('.as() - alias a route for later use', () => {
|
||||||
|
|
||||||
// Alias the route to wait for its response
|
// Alias the route to wait for its response
|
||||||
cy.server()
|
cy.server();
|
||||||
cy.route('GET', 'comments/*').as('getComment')
|
cy.route('GET', 'comments/*').as('getComment');
|
||||||
|
|
||||||
// we have code that gets a comment when
|
// we have code that gets a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.network-btn').click()
|
cy.get('.network-btn').click();
|
||||||
|
|
||||||
// https://on.cypress.io/wait
|
// https://on.cypress.io/wait
|
||||||
cy.wait('@getComment').its('status').should('eq', 200)
|
cy.wait('@getComment').its('status').should('eq', 200);
|
||||||
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
context('Assertions', () => {
|
context('Assertions', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/assertions')
|
cy.visit('https://example.cypress.io/commands/assertions');
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('Implicit Assertions', () => {
|
describe('Implicit Assertions', () => {
|
||||||
it('.should() - make an assertion about the current subject', () => {
|
it('.should() - make an assertion about the current subject', () => {
|
||||||
@@ -23,7 +23,7 @@ context('Assertions', () => {
|
|||||||
// first need to invoke jQuery method text()
|
// first need to invoke jQuery method text()
|
||||||
// and then match using regular expression
|
// and then match using regular expression
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.should('match', /column content/i)
|
.should('match', /column content/i);
|
||||||
|
|
||||||
// a better way to check element's text content against a regular expression
|
// a better way to check element's text content against a regular expression
|
||||||
// is to use "cy.contains"
|
// is to use "cy.contains"
|
||||||
@@ -32,33 +32,33 @@ context('Assertions', () => {
|
|||||||
.find('tbody tr:last')
|
.find('tbody tr:last')
|
||||||
// finds first <td> element with text content matching regular expression
|
// finds first <td> element with text content matching regular expression
|
||||||
.contains('td', /column content/i)
|
.contains('td', /column content/i)
|
||||||
.should('be.visible')
|
.should('be.visible');
|
||||||
|
|
||||||
// for more information about asserting element's text
|
// 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
|
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.and() - chain multiple assertions together', () => {
|
it('.and() - chain multiple assertions together', () => {
|
||||||
// https://on.cypress.io/and
|
// https://on.cypress.io/and
|
||||||
cy.get('.assertions-link')
|
cy.get('.assertions-link')
|
||||||
.should('have.class', 'active')
|
.should('have.class', 'active')
|
||||||
.and('have.attr', 'href')
|
.and('have.attr', 'href')
|
||||||
.and('include', 'cypress.io')
|
.and('include', 'cypress.io');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('Explicit Assertions', () => {
|
describe('Explicit Assertions', () => {
|
||||||
// https://on.cypress.io/assertions
|
// https://on.cypress.io/assertions
|
||||||
it('expect - make an assertion about a specified subject', () => {
|
it('expect - make an assertion about a specified subject', () => {
|
||||||
// We can use Chai's BDD style assertions
|
// We can use Chai's BDD style assertions
|
||||||
expect(true).to.be.true
|
expect(true).to.be.true;
|
||||||
const o = { foo: 'bar' }
|
const o = { foo: 'bar' };
|
||||||
|
|
||||||
expect(o).to.equal(o)
|
expect(o).to.equal(o);
|
||||||
expect(o).to.deep.equal({ foo: 'bar' })
|
expect(o).to.deep.equal({ foo: 'bar' });
|
||||||
// matching text using regular expression
|
// matching text using regular expression
|
||||||
expect('FooBar').to.match(/bar$/i)
|
expect('FooBar').to.match(/bar$/i);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('pass your own callback function to should()', () => {
|
it('pass your own callback function to should()', () => {
|
||||||
// Pass a function to should that can have any number
|
// Pass a function to should that can have any number
|
||||||
@@ -71,14 +71,14 @@ context('Assertions', () => {
|
|||||||
// https://on.cypress.io/$
|
// https://on.cypress.io/$
|
||||||
// return an array of texts from all of the p's
|
// return an array of texts from all of the p's
|
||||||
// @ts-ignore TS6133 unused variable
|
// @ts-ignore TS6133 unused variable
|
||||||
const texts = $p.map((i, el) => Cypress.$(el).text())
|
const texts = $p.map((i, el) => Cypress.$(el).text());
|
||||||
|
|
||||||
// jquery map returns jquery object
|
// jquery map returns jquery object
|
||||||
// and .get() convert this to simple array
|
// and .get() convert this to simple array
|
||||||
const paragraphs = texts.get()
|
const paragraphs = texts.get();
|
||||||
|
|
||||||
// array should have length of 3
|
// array should have length of 3
|
||||||
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
|
expect(paragraphs, 'has 3 paragraphs').to.have.length(3);
|
||||||
|
|
||||||
// use second argument to expect(...) to provide clear
|
// use second argument to expect(...) to provide clear
|
||||||
// message with each assertion
|
// message with each assertion
|
||||||
@@ -86,27 +86,27 @@ context('Assertions', () => {
|
|||||||
'Some text from first p',
|
'Some text from first p',
|
||||||
'More text from second p',
|
'More text from second p',
|
||||||
'And even more text from third p',
|
'And even more text from third p',
|
||||||
])
|
]);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('finds element by class name regex', () => {
|
it('finds element by class name regex', () => {
|
||||||
cy.get('.docs-header')
|
cy.get('.docs-header')
|
||||||
.find('div')
|
.find('div')
|
||||||
// .should(cb) callback function will be retried
|
// .should(cb) callback function will be retried
|
||||||
.should(($div) => {
|
.should(($div) => {
|
||||||
expect($div).to.have.length(1)
|
expect($div).to.have.length(1);
|
||||||
|
|
||||||
const className = $div[0].className
|
const className = $div[0].className;
|
||||||
|
|
||||||
expect(className).to.match(/heading-/)
|
expect(className).to.match(/heading-/);
|
||||||
})
|
})
|
||||||
// .then(cb) callback is not retried,
|
// .then(cb) callback is not retried,
|
||||||
// it either passes or fails
|
// it either passes or fails
|
||||||
.then(($div) => {
|
.then(($div) => {
|
||||||
expect($div, 'text content').to.have.text('Introduction')
|
expect($div, 'text content').to.have.text('Introduction');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('can throw any error', () => {
|
it('can throw any error', () => {
|
||||||
cy.get('.docs-header')
|
cy.get('.docs-header')
|
||||||
@@ -114,55 +114,56 @@ context('Assertions', () => {
|
|||||||
.should(($div) => {
|
.should(($div) => {
|
||||||
if ($div.length !== 1) {
|
if ($div.length !== 1) {
|
||||||
// you can throw your own errors
|
// you can throw your own errors
|
||||||
throw new Error('Did not find 1 element')
|
throw new Error('Did not find 1 element');
|
||||||
}
|
}
|
||||||
|
|
||||||
const className = $div[0].className
|
const className = $div[0].className;
|
||||||
|
|
||||||
if (!className.match(/heading-/)) {
|
if (!className.match(/heading-/)) {
|
||||||
throw new Error(`Could not find class "heading-" in ${className}`)
|
throw new Error(`Could not find class "heading-" in ${className}`);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('matches unknown text between two elements', () => {
|
it('matches unknown text between two elements', () => {
|
||||||
/**
|
/**
|
||||||
* Text from the first element.
|
* Text from the first element.
|
||||||
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
let text
|
let text;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalizes passed text,
|
* Normalizes passed text, useful before comparing text with spaces and different capitalization.
|
||||||
* useful before comparing text with spaces and different capitalization.
|
*
|
||||||
* @param {string} s Text to normalize
|
* @param {string} s Text to normalize
|
||||||
*/
|
*/
|
||||||
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
|
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase();
|
||||||
|
|
||||||
cy.get('.two-elements')
|
cy.get('.two-elements')
|
||||||
.find('.first')
|
.find('.first')
|
||||||
.then(($first) => {
|
.then(($first) => {
|
||||||
// save text from the first element
|
// save text from the first element
|
||||||
text = normalizeText($first.text())
|
text = normalizeText($first.text());
|
||||||
})
|
});
|
||||||
|
|
||||||
cy.get('.two-elements')
|
cy.get('.two-elements')
|
||||||
.find('.second')
|
.find('.second')
|
||||||
.should(($div) => {
|
.should(($div) => {
|
||||||
// we can massage text before comparing
|
// we can massage text before comparing
|
||||||
const secondText = normalizeText($div.text())
|
const secondText = normalizeText($div.text());
|
||||||
|
|
||||||
expect(secondText, 'second text').to.equal(text)
|
expect(secondText, 'second text').to.equal(text);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('assert - assert shape of an object', () => {
|
it('assert - assert shape of an object', () => {
|
||||||
const person = {
|
const person = {
|
||||||
name: 'Joe',
|
name: 'Joe',
|
||||||
age: 20,
|
age: 20,
|
||||||
}
|
};
|
||||||
|
|
||||||
assert.isObject(person, 'value is object')
|
assert.isObject(person, 'value is object');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,55 +2,54 @@
|
|||||||
|
|
||||||
context('Connectors', () => {
|
context('Connectors', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/connectors')
|
cy.visit('https://example.cypress.io/commands/connectors');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.each() - iterate over an array of elements', () => {
|
it('.each() - iterate over an array of elements', () => {
|
||||||
// https://on.cypress.io/each
|
// https://on.cypress.io/each
|
||||||
cy.get('.connectors-each-ul>li')
|
cy.get('.connectors-each-ul>li').each(($el, index, $list) => {
|
||||||
.each(($el, index, $list) => {
|
console.log($el, index, $list);
|
||||||
console.log($el, index, $list)
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.its() - get properties on the current subject', () => {
|
it('.its() - get properties on the current subject', () => {
|
||||||
// https://on.cypress.io/its
|
// https://on.cypress.io/its
|
||||||
cy.get('.connectors-its-ul>li')
|
cy.get('.connectors-its-ul>li')
|
||||||
// calls the 'length' property yielding that value
|
// calls the 'length' property yielding that value
|
||||||
.its('length')
|
.its('length')
|
||||||
.should('be.gt', 2)
|
.should('be.gt', 2);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.invoke() - invoke a function on the current subject', () => {
|
it('.invoke() - invoke a function on the current subject', () => {
|
||||||
// our div is hidden in our script.js
|
// our div is hidden in our script.js
|
||||||
// $('.connectors-div').hide()
|
// $('.connectors-div').hide()
|
||||||
|
|
||||||
// https://on.cypress.io/invoke
|
// https://on.cypress.io/invoke
|
||||||
cy.get('.connectors-div').should('be.hidden')
|
cy.get('.connectors-div')
|
||||||
|
.should('be.hidden')
|
||||||
// call the jquery method 'show' on the 'div.container'
|
// call the jquery method 'show' on the 'div.container'
|
||||||
.invoke('show')
|
.invoke('show')
|
||||||
.should('be.visible')
|
.should('be.visible');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.spread() - spread an array as individual args to callback function', () => {
|
it('.spread() - spread an array as individual args to callback function', () => {
|
||||||
// https://on.cypress.io/spread
|
// https://on.cypress.io/spread
|
||||||
const arr = ['foo', 'bar', 'baz']
|
const arr = ['foo', 'bar', 'baz'];
|
||||||
|
|
||||||
cy.wrap(arr).spread((foo, bar, baz) => {
|
cy.wrap(arr).spread((foo, bar, baz) => {
|
||||||
expect(foo).to.eq('foo')
|
expect(foo).to.eq('foo');
|
||||||
expect(bar).to.eq('bar')
|
expect(bar).to.eq('bar');
|
||||||
expect(baz).to.eq('baz')
|
expect(baz).to.eq('baz');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.then() - invoke a callback function with the current subject', () => {
|
it('.then() - invoke a callback function with the current subject', () => {
|
||||||
// https://on.cypress.io/then
|
// https://on.cypress.io/then
|
||||||
cy.get('.connectors-list > li')
|
cy.get('.connectors-list > li').then(($lis) => {
|
||||||
.then(($lis) => {
|
expect($lis, '3 items').to.have.length(3);
|
||||||
expect($lis, '3 items').to.have.length(3)
|
expect($lis.eq(0), 'first item').to.contain('Walk the dog');
|
||||||
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(1), 'second item').to.contain('Feed the cat')
|
expect($lis.eq(2), 'third item').to.contain('Write JavaScript');
|
||||||
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,77 +2,78 @@
|
|||||||
|
|
||||||
context('Cookies', () => {
|
context('Cookies', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Cypress.Cookies.debug(true)
|
Cypress.Cookies.debug(true);
|
||||||
|
|
||||||
cy.visit('https://example.cypress.io/commands/cookies')
|
cy.visit('https://example.cypress.io/commands/cookies');
|
||||||
|
|
||||||
// clear cookies again after visiting to remove
|
// clear cookies again after visiting to remove
|
||||||
// any 3rd party cookies picked up such as cloudflare
|
// any 3rd party cookies picked up such as cloudflare
|
||||||
cy.clearCookies()
|
cy.clearCookies();
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.getCookie() - get a browser cookie', () => {
|
it('cy.getCookie() - get a browser cookie', () => {
|
||||||
// https://on.cypress.io/getcookie
|
// https://on.cypress.io/getcookie
|
||||||
cy.get('#getCookie .set-a-cookie').click()
|
cy.get('#getCookie .set-a-cookie').click();
|
||||||
|
|
||||||
// cy.getCookie() yields a cookie object
|
// cy.getCookie() yields a cookie object
|
||||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
cy.getCookie('token').should('have.property', 'value', '123ABC');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.getCookies() - get browser cookies', () => {
|
it('cy.getCookies() - get browser cookies', () => {
|
||||||
// https://on.cypress.io/getcookies
|
// https://on.cypress.io/getcookies
|
||||||
cy.getCookies().should('be.empty')
|
cy.getCookies().should('be.empty');
|
||||||
|
|
||||||
cy.get('#getCookies .set-a-cookie').click()
|
cy.get('#getCookies .set-a-cookie').click();
|
||||||
|
|
||||||
// cy.getCookies() yields an array of cookies
|
// cy.getCookies() yields an array of cookies
|
||||||
cy.getCookies().should('have.length', 1).should((cookies) => {
|
cy.getCookies()
|
||||||
|
.should('have.length', 1)
|
||||||
|
.should((cookies) => {
|
||||||
// each cookie has these properties
|
// each cookie has these properties
|
||||||
expect(cookies[0]).to.have.property('name', 'token')
|
expect(cookies[0]).to.have.property('name', 'token');
|
||||||
expect(cookies[0]).to.have.property('value', '123ABC')
|
expect(cookies[0]).to.have.property('value', '123ABC');
|
||||||
expect(cookies[0]).to.have.property('httpOnly', false)
|
expect(cookies[0]).to.have.property('httpOnly', false);
|
||||||
expect(cookies[0]).to.have.property('secure', false)
|
expect(cookies[0]).to.have.property('secure', false);
|
||||||
expect(cookies[0]).to.have.property('domain')
|
expect(cookies[0]).to.have.property('domain');
|
||||||
expect(cookies[0]).to.have.property('path')
|
expect(cookies[0]).to.have.property('path');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.setCookie() - set a browser cookie', () => {
|
it('cy.setCookie() - set a browser cookie', () => {
|
||||||
// https://on.cypress.io/setcookie
|
// https://on.cypress.io/setcookie
|
||||||
cy.getCookies().should('be.empty')
|
cy.getCookies().should('be.empty');
|
||||||
|
|
||||||
cy.setCookie('foo', 'bar')
|
cy.setCookie('foo', 'bar');
|
||||||
|
|
||||||
// cy.getCookie() yields a cookie object
|
// cy.getCookie() yields a cookie object
|
||||||
cy.getCookie('foo').should('have.property', 'value', 'bar')
|
cy.getCookie('foo').should('have.property', 'value', 'bar');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.clearCookie() - clear a browser cookie', () => {
|
it('cy.clearCookie() - clear a browser cookie', () => {
|
||||||
// https://on.cypress.io/clearcookie
|
// https://on.cypress.io/clearcookie
|
||||||
cy.getCookie('token').should('be.null')
|
cy.getCookie('token').should('be.null');
|
||||||
|
|
||||||
cy.get('#clearCookie .set-a-cookie').click()
|
cy.get('#clearCookie .set-a-cookie').click();
|
||||||
|
|
||||||
cy.getCookie('token').should('have.property', 'value', '123ABC')
|
cy.getCookie('token').should('have.property', 'value', '123ABC');
|
||||||
|
|
||||||
// cy.clearCookies() yields null
|
// cy.clearCookies() yields null
|
||||||
cy.clearCookie('token').should('be.null')
|
cy.clearCookie('token').should('be.null');
|
||||||
|
|
||||||
cy.getCookie('token').should('be.null')
|
cy.getCookie('token').should('be.null');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.clearCookies() - clear browser cookies', () => {
|
it('cy.clearCookies() - clear browser cookies', () => {
|
||||||
// https://on.cypress.io/clearcookies
|
// https://on.cypress.io/clearcookies
|
||||||
cy.getCookies().should('be.empty')
|
cy.getCookies().should('be.empty');
|
||||||
|
|
||||||
cy.get('#clearCookies .set-a-cookie').click()
|
cy.get('#clearCookies .set-a-cookie').click();
|
||||||
|
|
||||||
cy.getCookies().should('have.length', 1)
|
cy.getCookies().should('have.length', 1);
|
||||||
|
|
||||||
// cy.clearCookies() yields null
|
// cy.clearCookies() yields null
|
||||||
cy.clearCookies()
|
cy.clearCookies();
|
||||||
|
|
||||||
cy.getCookies().should('be.empty')
|
cy.getCookies().should('be.empty');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,81 +2,85 @@
|
|||||||
|
|
||||||
context('Cypress.Commands', () => {
|
context('Cypress.Commands', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
// https://on.cypress.io/custom-commands
|
// https://on.cypress.io/custom-commands
|
||||||
|
|
||||||
it('.add() - create a custom command', () => {
|
it('.add() - create a custom command', () => {
|
||||||
Cypress.Commands.add('console', {
|
Cypress.Commands.add(
|
||||||
|
'console',
|
||||||
|
{
|
||||||
prevSubject: true,
|
prevSubject: true,
|
||||||
}, (subject, method) => {
|
},
|
||||||
|
(subject, method) => {
|
||||||
// the previous subject is automatically received
|
// the previous subject is automatically received
|
||||||
// and the commands arguments are shifted
|
// and the commands arguments are shifted
|
||||||
|
|
||||||
// allow us to change the console method used
|
// allow us to change the console method used
|
||||||
method = method || 'log'
|
method = method || 'log';
|
||||||
|
|
||||||
// log the subject to the console
|
// log the subject to the console
|
||||||
// @ts-ignore TS7017
|
// @ts-ignore TS7017
|
||||||
console[method]('The subject is', subject)
|
console[method]('The subject is', subject);
|
||||||
|
|
||||||
// whatever we return becomes the new subject
|
// whatever we return becomes the new subject
|
||||||
// we don't want to change the subject so
|
// we don't want to change the subject so
|
||||||
// we return whatever was passed in
|
// we return whatever was passed in
|
||||||
return subject
|
return subject;
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// @ts-ignore TS2339
|
// @ts-ignore TS2339
|
||||||
cy.get('button').console('info').then(($button) => {
|
cy.get('button')
|
||||||
|
.console('info')
|
||||||
|
.then(($button) => {
|
||||||
// subject is still $button
|
// subject is still $button
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
context('Cypress.Cookies', () => {
|
context('Cypress.Cookies', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
// https://on.cypress.io/cookies
|
// https://on.cypress.io/cookies
|
||||||
it('.debug() - enable or disable debugging', () => {
|
it('.debug() - enable or disable debugging', () => {
|
||||||
Cypress.Cookies.debug(true)
|
Cypress.Cookies.debug(true);
|
||||||
|
|
||||||
// Cypress will now log in the console when
|
// Cypress will now log in the console when
|
||||||
// cookies are set or cleared
|
// cookies are set or cleared
|
||||||
cy.setCookie('fakeCookie', '123ABC')
|
cy.setCookie('fakeCookie', '123ABC');
|
||||||
cy.clearCookie('fakeCookie')
|
cy.clearCookie('fakeCookie');
|
||||||
cy.setCookie('fakeCookie', '123ABC')
|
cy.setCookie('fakeCookie', '123ABC');
|
||||||
cy.clearCookie('fakeCookie')
|
cy.clearCookie('fakeCookie');
|
||||||
cy.setCookie('fakeCookie', '123ABC')
|
cy.setCookie('fakeCookie', '123ABC');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.preserveOnce() - preserve cookies by key', () => {
|
it('.preserveOnce() - preserve cookies by key', () => {
|
||||||
// normally cookies are reset after each test
|
// normally cookies are reset after each test
|
||||||
cy.getCookie('fakeCookie').should('not.be.ok')
|
cy.getCookie('fakeCookie').should('not.be.ok');
|
||||||
|
|
||||||
// preserving a cookie will not clear it when
|
// preserving a cookie will not clear it when
|
||||||
// the next test starts
|
// the next test starts
|
||||||
cy.setCookie('lastCookie', '789XYZ')
|
cy.setCookie('lastCookie', '789XYZ');
|
||||||
Cypress.Cookies.preserveOnce('lastCookie')
|
Cypress.Cookies.preserveOnce('lastCookie');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.defaults() - set defaults for all cookies', () => {
|
it('.defaults() - set defaults for all cookies', () => {
|
||||||
// now any cookie with the name 'session_id' will
|
// now any cookie with the name 'session_id' will
|
||||||
// not be cleared before each new test runs
|
// not be cleared before each new test runs
|
||||||
Cypress.Cookies.defaults({
|
Cypress.Cookies.defaults({
|
||||||
whitelist: 'session_id',
|
whitelist: 'session_id',
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
context('Cypress.Server', () => {
|
context('Cypress.Server', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
// Permanently override server options for
|
// Permanently override server options for
|
||||||
// all instances of cy.server()
|
// all instances of cy.server()
|
||||||
@@ -86,71 +90,71 @@ context('Cypress.Server', () => {
|
|||||||
Cypress.Server.defaults({
|
Cypress.Server.defaults({
|
||||||
delay: 0,
|
delay: 0,
|
||||||
force404: false,
|
force404: false,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.arch', () => {
|
context('Cypress.arch', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Get CPU architecture name of underlying OS', () => {
|
it('Get CPU architecture name of underlying OS', () => {
|
||||||
// https://on.cypress.io/arch
|
// https://on.cypress.io/arch
|
||||||
expect(Cypress.arch).to.exist
|
expect(Cypress.arch).to.exist;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.config()', () => {
|
context('Cypress.config()', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Get and set configuration options', () => {
|
it('Get and set configuration options', () => {
|
||||||
// https://on.cypress.io/config
|
// https://on.cypress.io/config
|
||||||
let myConfig = Cypress.config()
|
let myConfig = Cypress.config();
|
||||||
|
|
||||||
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
|
expect(myConfig).to.have.property('animationDistanceThreshold', 5);
|
||||||
expect(myConfig).to.have.property('baseUrl', null)
|
expect(myConfig).to.have.property('baseUrl', null);
|
||||||
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
|
expect(myConfig).to.have.property('defaultCommandTimeout', 4000);
|
||||||
expect(myConfig).to.have.property('requestTimeout', 5000)
|
expect(myConfig).to.have.property('requestTimeout', 5000);
|
||||||
expect(myConfig).to.have.property('responseTimeout', 30000)
|
expect(myConfig).to.have.property('responseTimeout', 30000);
|
||||||
expect(myConfig).to.have.property('viewportHeight', 660)
|
expect(myConfig).to.have.property('viewportHeight', 660);
|
||||||
expect(myConfig).to.have.property('viewportWidth', 1000)
|
expect(myConfig).to.have.property('viewportWidth', 1000);
|
||||||
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
|
expect(myConfig).to.have.property('pageLoadTimeout', 60000);
|
||||||
expect(myConfig).to.have.property('waitForAnimations', true)
|
expect(myConfig).to.have.property('waitForAnimations', true);
|
||||||
|
|
||||||
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
|
expect(Cypress.config('pageLoadTimeout')).to.eq(60000);
|
||||||
|
|
||||||
// this will change the config for the rest of your tests!
|
// this will change the config for the rest of your tests!
|
||||||
Cypress.config('pageLoadTimeout', 20000)
|
Cypress.config('pageLoadTimeout', 20000);
|
||||||
|
|
||||||
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
|
expect(Cypress.config('pageLoadTimeout')).to.eq(20000);
|
||||||
|
|
||||||
Cypress.config('pageLoadTimeout', 60000)
|
Cypress.config('pageLoadTimeout', 60000);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.dom', () => {
|
context('Cypress.dom', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
// https://on.cypress.io/dom
|
// https://on.cypress.io/dom
|
||||||
it('.isHidden() - determine if a DOM element is hidden', () => {
|
it('.isHidden() - determine if a DOM element is hidden', () => {
|
||||||
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
|
let hiddenP = Cypress.$('.dom-p p.hidden').get(0);
|
||||||
let visibleP = Cypress.$('.dom-p p.visible').get(0)
|
let visibleP = Cypress.$('.dom-p p.visible').get(0);
|
||||||
|
|
||||||
// our first paragraph has css class 'hidden'
|
// our first paragraph has css class 'hidden'
|
||||||
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
|
expect(Cypress.dom.isHidden(hiddenP)).to.be.true;
|
||||||
expect(Cypress.dom.isHidden(visibleP)).to.be.false
|
expect(Cypress.dom.isHidden(visibleP)).to.be.false;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.env()', () => {
|
context('Cypress.env()', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
// We can set environment variables for highly dynamic values
|
// We can set environment variables for highly dynamic values
|
||||||
|
|
||||||
@@ -161,62 +165,61 @@ context('Cypress.env()', () => {
|
|||||||
Cypress.env({
|
Cypress.env({
|
||||||
host: 'veronica.dev.local',
|
host: 'veronica.dev.local',
|
||||||
api_server: 'http://localhost:8888/v1/',
|
api_server: 'http://localhost:8888/v1/',
|
||||||
})
|
});
|
||||||
|
|
||||||
// get environment variable
|
// get environment variable
|
||||||
expect(Cypress.env('host')).to.eq('veronica.dev.local')
|
expect(Cypress.env('host')).to.eq('veronica.dev.local');
|
||||||
|
|
||||||
// set environment variable
|
// set environment variable
|
||||||
Cypress.env('api_server', 'http://localhost:8888/v2/')
|
Cypress.env('api_server', 'http://localhost:8888/v2/');
|
||||||
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
|
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/');
|
||||||
|
|
||||||
// get all environment variable
|
// get all environment variable
|
||||||
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
|
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local');
|
||||||
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
|
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.log', () => {
|
context('Cypress.log', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Control what is printed to the Command Log', () => {
|
it('Control what is printed to the Command Log', () => {
|
||||||
// https://on.cypress.io/cypress-log
|
// https://on.cypress.io/cypress-log
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
context('Cypress.platform', () => {
|
context('Cypress.platform', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Get underlying OS name', () => {
|
it('Get underlying OS name', () => {
|
||||||
// https://on.cypress.io/platform
|
// https://on.cypress.io/platform
|
||||||
expect(Cypress.platform).to.be.exist
|
expect(Cypress.platform).to.be.exist;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.version', () => {
|
context('Cypress.version', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Get current version of Cypress being run', () => {
|
it('Get current version of Cypress being run', () => {
|
||||||
// https://on.cypress.io/version
|
// https://on.cypress.io/version
|
||||||
expect(Cypress.version).to.be.exist
|
expect(Cypress.version).to.be.exist;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.spec', () => {
|
context('Cypress.spec', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/cypress-api')
|
cy.visit('https://example.cypress.io/cypress-api');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Get current spec information', () => {
|
it('Get current spec information', () => {
|
||||||
// https://on.cypress.io/spec
|
// https://on.cypress.io/spec
|
||||||
// wrap the object so we can inspect it easily by clicking in the command log
|
// 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'])
|
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute']);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -3,18 +3,18 @@
|
|||||||
/// JSON fixture file can be loaded directly using
|
/// JSON fixture file can be loaded directly using
|
||||||
// the built-in JavaScript bundler
|
// the built-in JavaScript bundler
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const requiredExample = require('../../fixtures/example')
|
const requiredExample = require('../../fixtures/example');
|
||||||
|
|
||||||
context('Files', () => {
|
context('Files', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/files')
|
cy.visit('https://example.cypress.io/commands/files');
|
||||||
})
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// load example.json fixture file and store
|
// load example.json fixture file and store
|
||||||
// in the test context object
|
// in the test context object
|
||||||
cy.fixture('example.json').as('example')
|
cy.fixture('example.json').as('example');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.fixture() - load a fixture', () => {
|
it('cy.fixture() - load a fixture', () => {
|
||||||
// https://on.cypress.io/fixture
|
// https://on.cypress.io/fixture
|
||||||
@@ -22,57 +22,58 @@ context('Files', () => {
|
|||||||
// Instead of writing a response inline you can
|
// Instead of writing a response inline you can
|
||||||
// use a fixture file's content.
|
// use a fixture file's content.
|
||||||
|
|
||||||
cy.server()
|
cy.server();
|
||||||
cy.fixture('example.json').as('comment')
|
cy.fixture('example.json').as('comment');
|
||||||
// when application makes an Ajax request matching "GET comments/*"
|
// when application makes an Ajax request matching "GET comments/*"
|
||||||
// Cypress will intercept it and reply with object
|
// Cypress will intercept it and reply with object
|
||||||
// from the "comment" alias
|
// from the "comment" alias
|
||||||
cy.route('GET', 'comments/*', '@comment').as('getComment')
|
cy.route('GET', 'comments/*', '@comment').as('getComment');
|
||||||
|
|
||||||
// we have code that gets a comment when
|
// we have code that gets a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.fixture-btn').click()
|
cy.get('.fixture-btn').click();
|
||||||
|
|
||||||
cy.wait('@getComment').its('responseBody')
|
cy.wait('@getComment')
|
||||||
|
.its('responseBody')
|
||||||
.should('have.property', 'name')
|
.should('have.property', 'name')
|
||||||
.and('include', 'Using fixtures to represent data')
|
.and('include', 'Using fixtures to represent data');
|
||||||
|
|
||||||
// you can also just write the fixture in the route
|
// you can also just write the fixture in the route
|
||||||
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
|
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment');
|
||||||
|
|
||||||
// we have code that gets a comment when
|
// we have code that gets a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.fixture-btn').click()
|
cy.get('.fixture-btn').click();
|
||||||
|
|
||||||
cy.wait('@getComment').its('responseBody')
|
cy.wait('@getComment')
|
||||||
|
.its('responseBody')
|
||||||
.should('have.property', 'name')
|
.should('have.property', 'name')
|
||||||
.and('include', 'Using fixtures to represent data')
|
.and('include', 'Using fixtures to represent data');
|
||||||
|
|
||||||
// or write fx to represent fixture
|
// or write fx to represent fixture
|
||||||
// by default it assumes it's .json
|
// by default it assumes it's .json
|
||||||
cy.route('GET', 'comments/*', 'fx:example').as('getComment')
|
cy.route('GET', 'comments/*', 'fx:example').as('getComment');
|
||||||
|
|
||||||
// we have code that gets a comment when
|
// we have code that gets a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.fixture-btn').click()
|
cy.get('.fixture-btn').click();
|
||||||
|
|
||||||
cy.wait('@getComment').its('responseBody')
|
cy.wait('@getComment')
|
||||||
|
.its('responseBody')
|
||||||
.should('have.property', 'name')
|
.should('have.property', 'name')
|
||||||
.and('include', 'Using fixtures to represent data')
|
.and('include', 'Using fixtures to represent data');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.fixture() or require - load a fixture', function () {
|
it('cy.fixture() or require - load a fixture', function () {
|
||||||
// we are inside the "function () { ... }"
|
// we are inside the "function () { ... }"
|
||||||
// callback and can use test context object "this"
|
// callback and can use test context object "this"
|
||||||
// "this.example" was loaded in "beforeEach" function callback
|
// "this.example" was loaded in "beforeEach" function callback
|
||||||
expect(this.example, 'fixture in the test context')
|
expect(this.example, 'fixture in the test context').to.deep.equal(requiredExample);
|
||||||
.to.deep.equal(requiredExample)
|
|
||||||
|
|
||||||
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
|
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
cy.wrap(this.example, 'fixture vs require')
|
cy.wrap(this.example, 'fixture vs require').should('deep.equal', requiredExample);
|
||||||
.should('deep.equal', requiredExample)
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('cy.readFile() - read a files contents', () => {
|
it('cy.readFile() - read a files contents', () => {
|
||||||
// https://on.cypress.io/readfile
|
// https://on.cypress.io/readfile
|
||||||
@@ -80,9 +81,9 @@ context('Files', () => {
|
|||||||
// You can read a file and yield its contents
|
// You can read a file and yield its contents
|
||||||
// The filePath is relative to your project's root.
|
// The filePath is relative to your project's root.
|
||||||
cy.readFile('cypress.json').then((json) => {
|
cy.readFile('cypress.json').then((json) => {
|
||||||
expect(json).to.be.an('object')
|
expect(json).to.be.an('object');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.writeFile() - write to a file', () => {
|
it('cy.writeFile() - write to a file', () => {
|
||||||
// https://on.cypress.io/writefile
|
// https://on.cypress.io/writefile
|
||||||
@@ -91,13 +92,12 @@ context('Files', () => {
|
|||||||
|
|
||||||
// Use a response from a request to automatically
|
// Use a response from a request to automatically
|
||||||
// generate a fixture file for use later
|
// generate a fixture file for use later
|
||||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
|
||||||
.then((response) => {
|
cy.writeFile('cypress/fixtures/users.json', response.body);
|
||||||
cy.writeFile('cypress/fixtures/users.json', response.body)
|
});
|
||||||
})
|
|
||||||
cy.fixture('users').should((users) => {
|
cy.fixture('users').should((users) => {
|
||||||
expect(users[0].name).to.exist
|
expect(users[0].name).to.exist;
|
||||||
})
|
});
|
||||||
|
|
||||||
// JavaScript arrays and objects are stringified
|
// JavaScript arrays and objects are stringified
|
||||||
// and formatted into text.
|
// and formatted into text.
|
||||||
@@ -105,10 +105,10 @@ context('Files', () => {
|
|||||||
id: 8739,
|
id: 8739,
|
||||||
name: 'Jane',
|
name: 'Jane',
|
||||||
email: 'jane@example.com',
|
email: 'jane@example.com',
|
||||||
})
|
});
|
||||||
|
|
||||||
cy.fixture('profile').should((profile) => {
|
cy.fixture('profile').should((profile) => {
|
||||||
expect(profile.name).to.eq('Jane')
|
expect(profile.name).to.eq('Jane');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,51 +2,57 @@
|
|||||||
|
|
||||||
context('Local Storage', () => {
|
context('Local Storage', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/local-storage')
|
cy.visit('https://example.cypress.io/commands/local-storage');
|
||||||
})
|
});
|
||||||
// Although local storage is automatically cleared
|
// Although local storage is automatically cleared
|
||||||
// in between tests to maintain a clean state
|
// in between tests to maintain a clean state
|
||||||
// sometimes we need to clear the local storage manually
|
// sometimes we need to clear the local storage manually
|
||||||
|
|
||||||
it('cy.clearLocalStorage() - clear all data in local storage', () => {
|
it('cy.clearLocalStorage() - clear all data in local storage', () => {
|
||||||
// https://on.cypress.io/clearlocalstorage
|
// https://on.cypress.io/clearlocalstorage
|
||||||
cy.get('.ls-btn').click().should(() => {
|
cy.get('.ls-btn')
|
||||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
.click()
|
||||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
.should(() => {
|
||||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
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
|
// clearLocalStorage() yields the localStorage object
|
||||||
cy.clearLocalStorage().should((ls) => {
|
cy.clearLocalStorage().should((ls) => {
|
||||||
expect(ls.getItem('prop1')).to.be.null
|
expect(ls.getItem('prop1')).to.be.null;
|
||||||
expect(ls.getItem('prop2')).to.be.null
|
expect(ls.getItem('prop2')).to.be.null;
|
||||||
expect(ls.getItem('prop3')).to.be.null
|
expect(ls.getItem('prop3')).to.be.null;
|
||||||
})
|
});
|
||||||
|
|
||||||
// Clear key matching string in Local Storage
|
// Clear key matching string in Local Storage
|
||||||
cy.get('.ls-btn').click().should(() => {
|
cy.get('.ls-btn')
|
||||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
.click()
|
||||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
.should(() => {
|
||||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
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) => {
|
cy.clearLocalStorage('prop1').should((ls) => {
|
||||||
expect(ls.getItem('prop1')).to.be.null
|
expect(ls.getItem('prop1')).to.be.null;
|
||||||
expect(ls.getItem('prop2')).to.eq('blue')
|
expect(ls.getItem('prop2')).to.eq('blue');
|
||||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
expect(ls.getItem('prop3')).to.eq('magenta');
|
||||||
})
|
});
|
||||||
|
|
||||||
// Clear keys matching regex in Local Storage
|
// Clear keys matching regex in Local Storage
|
||||||
cy.get('.ls-btn').click().should(() => {
|
cy.get('.ls-btn')
|
||||||
expect(localStorage.getItem('prop1')).to.eq('red')
|
.click()
|
||||||
expect(localStorage.getItem('prop2')).to.eq('blue')
|
.should(() => {
|
||||||
expect(localStorage.getItem('prop3')).to.eq('magenta')
|
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) => {
|
cy.clearLocalStorage(/prop1|2/).should((ls) => {
|
||||||
expect(ls.getItem('prop1')).to.be.null
|
expect(ls.getItem('prop1')).to.be.null;
|
||||||
expect(ls.getItem('prop2')).to.be.null
|
expect(ls.getItem('prop2')).to.be.null;
|
||||||
expect(ls.getItem('prop3')).to.eq('magenta')
|
expect(ls.getItem('prop3')).to.eq('magenta');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,31 +2,31 @@
|
|||||||
|
|
||||||
context('Location', () => {
|
context('Location', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/location')
|
cy.visit('https://example.cypress.io/commands/location');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.hash() - get the current URL hash', () => {
|
it('cy.hash() - get the current URL hash', () => {
|
||||||
// https://on.cypress.io/hash
|
// https://on.cypress.io/hash
|
||||||
cy.hash().should('be.empty')
|
cy.hash().should('be.empty');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.location() - get window.location', () => {
|
it('cy.location() - get window.location', () => {
|
||||||
// https://on.cypress.io/location
|
// https://on.cypress.io/location
|
||||||
cy.location().should((location) => {
|
cy.location().should((location) => {
|
||||||
expect(location.hash).to.be.empty
|
expect(location.hash).to.be.empty;
|
||||||
expect(location.href).to.eq('https://example.cypress.io/commands/location')
|
expect(location.href).to.eq('https://example.cypress.io/commands/location');
|
||||||
expect(location.host).to.eq('example.cypress.io')
|
expect(location.host).to.eq('example.cypress.io');
|
||||||
expect(location.hostname).to.eq('example.cypress.io')
|
expect(location.hostname).to.eq('example.cypress.io');
|
||||||
expect(location.origin).to.eq('https://example.cypress.io')
|
expect(location.origin).to.eq('https://example.cypress.io');
|
||||||
expect(location.pathname).to.eq('/commands/location')
|
expect(location.pathname).to.eq('/commands/location');
|
||||||
expect(location.port).to.eq('')
|
expect(location.port).to.eq('');
|
||||||
expect(location.protocol).to.eq('https:')
|
expect(location.protocol).to.eq('https:');
|
||||||
expect(location.search).to.be.empty
|
expect(location.search).to.be.empty;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.url() - get the current URL', () => {
|
it('cy.url() - get the current URL', () => {
|
||||||
// https://on.cypress.io/url
|
// https://on.cypress.io/url
|
||||||
cy.url().should('eq', 'https://example.cypress.io/commands/location')
|
cy.url().should('eq', 'https://example.cypress.io/commands/location');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
context('Misc', () => {
|
context('Misc', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/misc')
|
cy.visit('https://example.cypress.io/commands/misc');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.end() - end the command chain', () => {
|
it('.end() - end the command chain', () => {
|
||||||
// https://on.cypress.io/end
|
// https://on.cypress.io/end
|
||||||
@@ -12,12 +12,12 @@ context('Misc', () => {
|
|||||||
// and force Cypress to re-query from the root element
|
// and force Cypress to re-query from the root element
|
||||||
cy.get('.misc-table').within(() => {
|
cy.get('.misc-table').within(() => {
|
||||||
// ends the current chain and yields null
|
// ends the current chain and yields null
|
||||||
cy.contains('Cheryl').click().end()
|
cy.contains('Cheryl').click().end();
|
||||||
|
|
||||||
// queries the entire table again
|
// queries the entire table again
|
||||||
cy.contains('Charles').click()
|
cy.contains('Charles').click();
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.exec() - execute a system command', () => {
|
it('cy.exec() - execute a system command', () => {
|
||||||
// https://on.cypress.io/exec
|
// https://on.cypress.io/exec
|
||||||
@@ -25,40 +25,36 @@ context('Misc', () => {
|
|||||||
// execute a system command.
|
// execute a system command.
|
||||||
// so you can take actions necessary for
|
// so you can take actions necessary for
|
||||||
// your test outside the scope of Cypress.
|
// your test outside the scope of Cypress.
|
||||||
cy.exec('echo Jane Lane')
|
cy.exec('echo Jane Lane').its('stdout').should('contain', 'Jane Lane');
|
||||||
.its('stdout').should('contain', 'Jane Lane')
|
|
||||||
|
|
||||||
// we can use Cypress.platform string to
|
// we can use Cypress.platform string to
|
||||||
// select appropriate command
|
// select appropriate command
|
||||||
// https://on.cypress/io/platform
|
// https://on.cypress/io/platform
|
||||||
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
|
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`);
|
||||||
|
|
||||||
if (Cypress.platform === 'win32') {
|
if (Cypress.platform === 'win32') {
|
||||||
cy.exec('print cypress.json')
|
cy.exec('print cypress.json').its('stderr').should('be.empty');
|
||||||
.its('stderr').should('be.empty')
|
|
||||||
} else {
|
} else {
|
||||||
cy.exec('cat cypress.json')
|
cy.exec('cat cypress.json').its('stderr').should('be.empty');
|
||||||
.its('stderr').should('be.empty')
|
|
||||||
|
|
||||||
cy.exec('pwd')
|
cy.exec('pwd').its('code').should('eq', 0);
|
||||||
.its('code').should('eq', 0)
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.focused() - get the DOM element that has focus', () => {
|
it('cy.focused() - get the DOM element that has focus', () => {
|
||||||
// https://on.cypress.io/focused
|
// https://on.cypress.io/focused
|
||||||
cy.get('.misc-form').find('#name').click()
|
cy.get('.misc-form').find('#name').click();
|
||||||
cy.focused().should('have.id', 'name')
|
cy.focused().should('have.id', 'name');
|
||||||
|
|
||||||
cy.get('.misc-form').find('#description').click()
|
cy.get('.misc-form').find('#description').click();
|
||||||
cy.focused().should('have.id', 'description')
|
cy.focused().should('have.id', 'description');
|
||||||
})
|
});
|
||||||
|
|
||||||
context('Cypress.Screenshot', function () {
|
context('Cypress.Screenshot', function () {
|
||||||
it('cy.screenshot() - take a screenshot', () => {
|
it('cy.screenshot() - take a screenshot', () => {
|
||||||
// https://on.cypress.io/screenshot
|
// https://on.cypress.io/screenshot
|
||||||
cy.screenshot('my-image')
|
cy.screenshot('my-image');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
|
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
|
||||||
Cypress.Screenshot.defaults({
|
Cypress.Screenshot.defaults({
|
||||||
@@ -70,14 +66,12 @@ context('Misc', () => {
|
|||||||
screenshotOnRunFailure: true,
|
screenshotOnRunFailure: true,
|
||||||
beforeScreenshot() {},
|
beforeScreenshot() {},
|
||||||
afterScreenshot() {},
|
afterScreenshot() {},
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.wrap() - wrap an object', () => {
|
it('cy.wrap() - wrap an object', () => {
|
||||||
// https://on.cypress.io/wrap
|
// https://on.cypress.io/wrap
|
||||||
cy.wrap({ foo: 'bar' })
|
cy.wrap({ foo: 'bar' }).should('have.property', 'foo').and('include', 'bar');
|
||||||
.should('have.property', 'foo')
|
});
|
||||||
.and('include', 'bar')
|
});
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,38 +2,38 @@
|
|||||||
|
|
||||||
context('Navigation', () => {
|
context('Navigation', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io')
|
cy.visit('https://example.cypress.io');
|
||||||
cy.get('.navbar-nav').contains('Commands').click()
|
cy.get('.navbar-nav').contains('Commands').click();
|
||||||
cy.get('.dropdown-menu').contains('Navigation').click()
|
cy.get('.dropdown-menu').contains('Navigation').click();
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.go() - go back or forward in the browser\'s history', () => {
|
it("cy.go() - go back or forward in the browser's history", () => {
|
||||||
// https://on.cypress.io/go
|
// https://on.cypress.io/go
|
||||||
|
|
||||||
cy.location('pathname').should('include', 'navigation')
|
cy.location('pathname').should('include', 'navigation');
|
||||||
|
|
||||||
cy.go('back')
|
cy.go('back');
|
||||||
cy.location('pathname').should('not.include', 'navigation')
|
cy.location('pathname').should('not.include', 'navigation');
|
||||||
|
|
||||||
cy.go('forward')
|
cy.go('forward');
|
||||||
cy.location('pathname').should('include', 'navigation')
|
cy.location('pathname').should('include', 'navigation');
|
||||||
|
|
||||||
// clicking back
|
// clicking back
|
||||||
cy.go(-1)
|
cy.go(-1);
|
||||||
cy.location('pathname').should('not.include', 'navigation')
|
cy.location('pathname').should('not.include', 'navigation');
|
||||||
|
|
||||||
// clicking forward
|
// clicking forward
|
||||||
cy.go(1)
|
cy.go(1);
|
||||||
cy.location('pathname').should('include', 'navigation')
|
cy.location('pathname').should('include', 'navigation');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.reload() - reload the page', () => {
|
it('cy.reload() - reload the page', () => {
|
||||||
// https://on.cypress.io/reload
|
// https://on.cypress.io/reload
|
||||||
cy.reload()
|
cy.reload();
|
||||||
|
|
||||||
// reload the page without using the cache
|
// reload the page without using the cache
|
||||||
cy.reload(true)
|
cy.reload(true);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.visit() - visit a remote url', () => {
|
it('cy.visit() - visit a remote url', () => {
|
||||||
// https://on.cypress.io/visit
|
// https://on.cypress.io/visit
|
||||||
@@ -45,12 +45,12 @@ context('Navigation', () => {
|
|||||||
timeout: 50000, // increase total time for the visit to resolve
|
timeout: 50000, // increase total time for the visit to resolve
|
||||||
onBeforeLoad(contentWindow) {
|
onBeforeLoad(contentWindow) {
|
||||||
// contentWindow is the remote page's window object
|
// contentWindow is the remote page's window object
|
||||||
expect(typeof contentWindow === 'object').to.be.true
|
expect(typeof contentWindow === 'object').to.be.true;
|
||||||
},
|
},
|
||||||
onLoad(contentWindow) {
|
onLoad(contentWindow) {
|
||||||
// contentWindow is the remote page's window object
|
// contentWindow is the remote page's window object
|
||||||
expect(typeof contentWindow === 'object').to.be.true
|
expect(typeof contentWindow === 'object').to.be.true;
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
context('Network Requests', () => {
|
context('Network Requests', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/network-requests')
|
cy.visit('https://example.cypress.io/commands/network-requests');
|
||||||
})
|
});
|
||||||
|
|
||||||
// Manage AJAX / XHR requests in your app
|
// Manage AJAX / XHR requests in your app
|
||||||
|
|
||||||
@@ -13,59 +13,56 @@ context('Network Requests', () => {
|
|||||||
cy.server().should((server) => {
|
cy.server().should((server) => {
|
||||||
// the default options on server
|
// the default options on server
|
||||||
// you can override any of these options
|
// you can override any of these options
|
||||||
expect(server.delay).to.eq(0)
|
expect(server.delay).to.eq(0);
|
||||||
expect(server.method).to.eq('GET')
|
expect(server.method).to.eq('GET');
|
||||||
expect(server.status).to.eq(200)
|
expect(server.status).to.eq(200);
|
||||||
expect(server.headers).to.be.null
|
expect(server.headers).to.be.null;
|
||||||
expect(server.response).to.be.null
|
expect(server.response).to.be.null;
|
||||||
expect(server.onRequest).to.be.undefined
|
expect(server.onRequest).to.be.undefined;
|
||||||
expect(server.onResponse).to.be.undefined
|
expect(server.onResponse).to.be.undefined;
|
||||||
expect(server.onAbort).to.be.undefined
|
expect(server.onAbort).to.be.undefined;
|
||||||
|
|
||||||
// These options control the server behavior
|
// These options control the server behavior
|
||||||
// affecting all requests
|
// affecting all requests
|
||||||
|
|
||||||
// pass false to disable existing route stubs
|
// pass false to disable existing route stubs
|
||||||
expect(server.enable).to.be.true
|
expect(server.enable).to.be.true;
|
||||||
// forces requests that don't match your routes to 404
|
// forces requests that don't match your routes to 404
|
||||||
expect(server.force404).to.be.false
|
expect(server.force404).to.be.false;
|
||||||
// whitelists requests from ever being logged or stubbed
|
// whitelists requests from ever being logged or stubbed
|
||||||
expect(server.whitelist).to.be.a('function')
|
expect(server.whitelist).to.be.a('function');
|
||||||
})
|
});
|
||||||
|
|
||||||
cy.server({
|
cy.server({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
delay: 1000,
|
delay: 1000,
|
||||||
status: 422,
|
status: 422,
|
||||||
response: {},
|
response: {},
|
||||||
})
|
});
|
||||||
|
|
||||||
// any route commands will now inherit the above options
|
// any route commands will now inherit the above options
|
||||||
// from the server. anything we pass specifically
|
// from the server. anything we pass specifically
|
||||||
// to route will override the defaults though.
|
// to route will override the defaults though.
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.request() - make an XHR request', () => {
|
it('cy.request() - make an XHR request', () => {
|
||||||
// https://on.cypress.io/request
|
// https://on.cypress.io/request
|
||||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
cy.request('https://jsonplaceholder.cypress.io/comments').should((response) => {
|
||||||
.should((response) => {
|
expect(response.status).to.eq(200);
|
||||||
expect(response.status).to.eq(200)
|
expect(response.body).to.have.length(500);
|
||||||
expect(response.body).to.have.length(500)
|
expect(response).to.have.property('headers');
|
||||||
expect(response).to.have.property('headers')
|
expect(response).to.have.property('duration');
|
||||||
expect(response).to.have.property('duration')
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
it('cy.request() - verify response using BDD syntax', () => {
|
it('cy.request() - verify response using BDD syntax', () => {
|
||||||
cy.request('https://jsonplaceholder.cypress.io/comments')
|
cy.request('https://jsonplaceholder.cypress.io/comments').then((response) => {
|
||||||
.then((response) => {
|
|
||||||
// https://on.cypress.io/assertions
|
// https://on.cypress.io/assertions
|
||||||
expect(response).property('status').to.equal(200)
|
expect(response).property('status').to.equal(200);
|
||||||
expect(response).property('body').to.have.length(500)
|
expect(response).property('body').to.have.length(500);
|
||||||
expect(response).to.include.keys('headers', 'duration')
|
expect(response).to.include.keys('headers', 'duration');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.request() with query parameters', () => {
|
it('cy.request() with query parameters', () => {
|
||||||
// will execute request
|
// will execute request
|
||||||
@@ -84,35 +81,35 @@ context('Network Requests', () => {
|
|||||||
.should('contain', {
|
.should('contain', {
|
||||||
postId: 1,
|
postId: 1,
|
||||||
id: 3,
|
id: 3,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.request() - pass result to the second request', () => {
|
it('cy.request() - pass result to the second request', () => {
|
||||||
// first, let's find out the userId of the first user we have
|
// first, let's find out the userId of the first user we have
|
||||||
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
|
||||||
.its('body.0') // yields the first element of the returned list
|
.its('body.0') // yields the first element of the returned list
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
expect(user).property('id').to.be.a('number')
|
expect(user).property('id').to.be.a('number');
|
||||||
// make a new post on behalf of the user
|
// make a new post on behalf of the user
|
||||||
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
title: 'Cypress Test Runner',
|
title: 'Cypress Test Runner',
|
||||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
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
|
// note that the value here is the returned value of the 2nd request
|
||||||
// which is the new post object
|
// which is the new post object
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
expect(response).property('status').to.equal(201) // new entity created
|
expect(response).property('status').to.equal(201); // new entity created
|
||||||
expect(response).property('body').to.contain({
|
expect(response).property('body').to.contain({
|
||||||
id: 101, // there are already 100 posts, so new entity gets id 101
|
id: 101, // there are already 100 posts, so new entity gets id 101
|
||||||
title: 'Cypress Test Runner',
|
title: 'Cypress Test Runner',
|
||||||
})
|
});
|
||||||
// we don't know the user id here - since it was in above closure
|
// 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
|
// so in this test just confirm that the property is there
|
||||||
expect(response.body).property('userId').to.be.a('number')
|
expect(response.body).property('userId').to.be.a('number');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.request() - save response in the shared test context', () => {
|
it('cy.request() - save response in the shared test context', () => {
|
||||||
// https://on.cypress.io/variables-and-aliases
|
// https://on.cypress.io/variables-and-aliases
|
||||||
@@ -131,47 +128,48 @@ context('Network Requests', () => {
|
|||||||
title: 'Cypress Test Runner',
|
title: 'Cypress Test Runner',
|
||||||
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
|
||||||
})
|
})
|
||||||
.its('body').as('post') // save the new post from the response
|
.its('body')
|
||||||
|
.as('post'); // save the new post from the response
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
// When this callback runs, both "cy.request" API commands have finished
|
// When this callback runs, both "cy.request" API commands have finished
|
||||||
// and the test context has "user" and "post" objects set.
|
// and the test context has "user" and "post" objects set.
|
||||||
// Let's verify them.
|
// Let's verify them.
|
||||||
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
|
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.route() - route responses to matching requests', () => {
|
it('cy.route() - route responses to matching requests', () => {
|
||||||
// https://on.cypress.io/route
|
// https://on.cypress.io/route
|
||||||
|
|
||||||
let message = 'whoa, this comment does not exist'
|
let message = 'whoa, this comment does not exist';
|
||||||
|
|
||||||
cy.server()
|
cy.server();
|
||||||
|
|
||||||
// Listen to GET to comments/1
|
// Listen to GET to comments/1
|
||||||
cy.route('GET', 'comments/*').as('getComment')
|
cy.route('GET', 'comments/*').as('getComment');
|
||||||
|
|
||||||
// we have code that gets a comment when
|
// we have code that gets a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.network-btn').click()
|
cy.get('.network-btn').click();
|
||||||
|
|
||||||
// https://on.cypress.io/wait
|
// https://on.cypress.io/wait
|
||||||
cy.wait('@getComment').its('status').should('eq', 200)
|
cy.wait('@getComment').its('status').should('eq', 200);
|
||||||
|
|
||||||
// Listen to POST to comments
|
// Listen to POST to comments
|
||||||
cy.route('POST', '/comments').as('postComment')
|
cy.route('POST', '/comments').as('postComment');
|
||||||
|
|
||||||
// we have code that posts a comment when
|
// we have code that posts a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.network-post').click()
|
cy.get('.network-post').click();
|
||||||
cy.wait('@postComment')
|
cy.wait('@postComment');
|
||||||
|
|
||||||
// get the route
|
// get the route
|
||||||
cy.get('@postComment').should((xhr) => {
|
cy.get('@postComment').should((xhr) => {
|
||||||
expect(xhr.requestBody).to.include('email')
|
expect(xhr.requestBody).to.include('email');
|
||||||
expect(xhr.requestHeaders).to.have.property('Content-Type')
|
expect(xhr.requestHeaders).to.have.property('Content-Type');
|
||||||
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
|
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()');
|
||||||
})
|
});
|
||||||
|
|
||||||
// Stub a response to PUT comments/ ****
|
// Stub a response to PUT comments/ ****
|
||||||
cy.route({
|
cy.route({
|
||||||
@@ -180,15 +178,15 @@ context('Network Requests', () => {
|
|||||||
status: 404,
|
status: 404,
|
||||||
response: { error: message },
|
response: { error: message },
|
||||||
delay: 500,
|
delay: 500,
|
||||||
}).as('putComment')
|
}).as('putComment');
|
||||||
|
|
||||||
// we have code that puts a comment when
|
// we have code that puts a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.network-put').click()
|
cy.get('.network-put').click();
|
||||||
|
|
||||||
cy.wait('@putComment')
|
cy.wait('@putComment');
|
||||||
|
|
||||||
// our 404 statusCode logic in scripts.js executed
|
// our 404 statusCode logic in scripts.js executed
|
||||||
cy.get('.network-put-comment').should('contain', message)
|
cy.get('.network-put-comment').should('contain', message);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
context('Querying', () => {
|
context('Querying', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/querying')
|
cy.visit('https://example.cypress.io/commands/querying');
|
||||||
})
|
});
|
||||||
|
|
||||||
// The most commonly used query is 'cy.get()', you can
|
// The most commonly used query is 'cy.get()', you can
|
||||||
// think of this like the '$' in jQuery
|
// think of this like the '$' in jQuery
|
||||||
@@ -11,77 +11,65 @@ context('Querying', () => {
|
|||||||
it('cy.get() - query DOM elements', () => {
|
it('cy.get() - query DOM elements', () => {
|
||||||
// https://on.cypress.io/get
|
// https://on.cypress.io/get
|
||||||
|
|
||||||
cy.get('#query-btn').should('contain', 'Button')
|
cy.get('#query-btn').should('contain', 'Button');
|
||||||
|
|
||||||
cy.get('.query-btn').should('contain', 'Button')
|
cy.get('.query-btn').should('contain', 'Button');
|
||||||
|
|
||||||
cy.get('#querying .well>button:first').should('contain', 'Button')
|
cy.get('#querying .well>button:first').should('contain', 'Button');
|
||||||
// ↲
|
// ↲
|
||||||
// Use CSS selectors just like jQuery
|
// Use CSS selectors just like jQuery
|
||||||
|
|
||||||
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
|
cy.get('[data-test-id="test-example"]').should('have.class', 'example');
|
||||||
|
|
||||||
// 'cy.get()' yields jQuery object, you can get its attribute
|
// 'cy.get()' yields jQuery object, you can get its attribute
|
||||||
// by invoking `.attr()` method
|
// by invoking `.attr()` method
|
||||||
cy.get('[data-test-id="test-example"]')
|
cy.get('[data-test-id="test-example"]')
|
||||||
.invoke('attr', 'data-test-id')
|
.invoke('attr', 'data-test-id')
|
||||||
.should('equal', 'test-example')
|
.should('equal', 'test-example');
|
||||||
|
|
||||||
// or you can get element's CSS property
|
// or you can get element's CSS property
|
||||||
cy.get('[data-test-id="test-example"]')
|
cy.get('[data-test-id="test-example"]').invoke('css', 'position').should('equal', 'static');
|
||||||
.invoke('css', 'position')
|
|
||||||
.should('equal', 'static')
|
|
||||||
|
|
||||||
// or use assertions directly during 'cy.get()'
|
// or use assertions directly during 'cy.get()'
|
||||||
// https://on.cypress.io/assertions
|
// https://on.cypress.io/assertions
|
||||||
cy.get('[data-test-id="test-example"]')
|
cy.get('[data-test-id="test-example"]')
|
||||||
.should('have.attr', 'data-test-id', 'test-example')
|
.should('have.attr', 'data-test-id', 'test-example')
|
||||||
.and('have.css', 'position', 'static')
|
.and('have.css', 'position', 'static');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.contains() - query DOM elements with matching content', () => {
|
it('cy.contains() - query DOM elements with matching content', () => {
|
||||||
// https://on.cypress.io/contains
|
// https://on.cypress.io/contains
|
||||||
cy.get('.query-list')
|
cy.get('.query-list').contains('bananas').should('have.class', 'third');
|
||||||
.contains('bananas')
|
|
||||||
.should('have.class', 'third')
|
|
||||||
|
|
||||||
// we can pass a regexp to `.contains()`
|
// we can pass a regexp to `.contains()`
|
||||||
cy.get('.query-list')
|
cy.get('.query-list').contains(/^b\w+/).should('have.class', 'third');
|
||||||
.contains(/^b\w+/)
|
|
||||||
.should('have.class', 'third')
|
|
||||||
|
|
||||||
cy.get('.query-list')
|
cy.get('.query-list').contains('apples').should('have.class', 'first');
|
||||||
.contains('apples')
|
|
||||||
.should('have.class', 'first')
|
|
||||||
|
|
||||||
// passing a selector to contains will
|
// passing a selector to contains will
|
||||||
// yield the selector containing the text
|
// yield the selector containing the text
|
||||||
cy.get('#querying')
|
cy.get('#querying').contains('ul', 'oranges').should('have.class', 'query-list');
|
||||||
.contains('ul', 'oranges')
|
|
||||||
.should('have.class', 'query-list')
|
|
||||||
|
|
||||||
cy.get('.query-button')
|
cy.get('.query-button').contains('Save Form').should('have.class', 'btn');
|
||||||
.contains('Save Form')
|
});
|
||||||
.should('have.class', 'btn')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.within() - query DOM elements within a specific element', () => {
|
it('.within() - query DOM elements within a specific element', () => {
|
||||||
// https://on.cypress.io/within
|
// https://on.cypress.io/within
|
||||||
cy.get('.query-form').within(() => {
|
cy.get('.query-form').within(() => {
|
||||||
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
|
cy.get('input:first').should('have.attr', 'placeholder', 'Email');
|
||||||
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
|
cy.get('input:last').should('have.attr', 'placeholder', 'Password');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.root() - query the root DOM element', () => {
|
it('cy.root() - query the root DOM element', () => {
|
||||||
// https://on.cypress.io/root
|
// https://on.cypress.io/root
|
||||||
|
|
||||||
// By default, root is the document
|
// By default, root is the document
|
||||||
cy.root().should('match', 'html')
|
cy.root().should('match', 'html');
|
||||||
|
|
||||||
cy.get('.query-ul').within(() => {
|
cy.get('.query-ul').within(() => {
|
||||||
// In this within, the root is now the ul DOM element
|
// In this within, the root is now the ul DOM element
|
||||||
cy.root().should('have.class', 'query-ul')
|
cy.root().should('have.class', 'query-ul');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -3,93 +3,92 @@
|
|||||||
context('Spies, Stubs, and Clock', () => {
|
context('Spies, Stubs, and Clock', () => {
|
||||||
it('cy.spy() - wrap a method in a spy', () => {
|
it('cy.spy() - wrap a method in a spy', () => {
|
||||||
// https://on.cypress.io/spy
|
// https://on.cypress.io/spy
|
||||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
foo() {},
|
foo() {},
|
||||||
}
|
};
|
||||||
|
|
||||||
const spy = cy.spy(obj, 'foo').as('anyArgs')
|
const spy = cy.spy(obj, 'foo').as('anyArgs');
|
||||||
|
|
||||||
obj.foo()
|
obj.foo();
|
||||||
|
|
||||||
expect(spy).to.be.called
|
expect(spy).to.be.called;
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.spy() retries until assertions pass', () => {
|
it('cy.spy() retries until assertions pass', () => {
|
||||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
/**
|
/**
|
||||||
* Prints the argument passed
|
* Prints the argument passed
|
||||||
|
*
|
||||||
* @param x {any}
|
* @param x {any}
|
||||||
*/
|
*/
|
||||||
foo(x) {
|
foo(x) {
|
||||||
console.log('obj.foo called with', x)
|
console.log('obj.foo called with', x);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
cy.spy(obj, 'foo').as('foo')
|
cy.spy(obj, 'foo').as('foo');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
obj.foo('first')
|
obj.foo('first');
|
||||||
}, 500)
|
}, 500);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
obj.foo('second')
|
obj.foo('second');
|
||||||
}, 2500)
|
}, 2500);
|
||||||
|
|
||||||
cy.get('@foo').should('have.been.calledTwice')
|
cy.get('@foo').should('have.been.calledTwice');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.stub() - create a stub and/or replace a function with stub', () => {
|
it('cy.stub() - create a stub and/or replace a function with stub', () => {
|
||||||
// https://on.cypress.io/stub
|
// https://on.cypress.io/stub
|
||||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||||
|
|
||||||
const obj = {
|
const obj = {
|
||||||
/**
|
/**
|
||||||
* prints both arguments to the console
|
* Prints both arguments to the console
|
||||||
|
*
|
||||||
* @param a {string}
|
* @param a {string}
|
||||||
* @param b {string}
|
* @param b {string}
|
||||||
*/
|
*/
|
||||||
foo(a, b) {
|
foo(a, b) {
|
||||||
console.log('a', a, 'b', b)
|
console.log('a', a, 'b', b);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const stub = cy.stub(obj, 'foo').as('foo')
|
const stub = cy.stub(obj, 'foo').as('foo');
|
||||||
|
|
||||||
obj.foo('foo', 'bar')
|
obj.foo('foo', 'bar');
|
||||||
|
|
||||||
expect(stub).to.be.called
|
expect(stub).to.be.called;
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.clock() - control time in the browser', () => {
|
it('cy.clock() - control time in the browser', () => {
|
||||||
// https://on.cypress.io/clock
|
// https://on.cypress.io/clock
|
||||||
|
|
||||||
// create the date in UTC so its always the same
|
// create the date in UTC so its always the same
|
||||||
// no matter what local timezone the browser is running in
|
// no matter what local timezone the browser is running in
|
||||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
const now = new Date(Date.UTC(2017, 2, 14)).getTime();
|
||||||
|
|
||||||
cy.clock(now)
|
cy.clock(now);
|
||||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||||
cy.get('#clock-div').click()
|
cy.get('#clock-div').click().should('have.text', '1489449600');
|
||||||
.should('have.text', '1489449600')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('cy.tick() - move time in the browser', () => {
|
it('cy.tick() - move time in the browser', () => {
|
||||||
// https://on.cypress.io/tick
|
// https://on.cypress.io/tick
|
||||||
|
|
||||||
// create the date in UTC so its always the same
|
// create the date in UTC so its always the same
|
||||||
// no matter what local timezone the browser is running in
|
// no matter what local timezone the browser is running in
|
||||||
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
|
const now = new Date(Date.UTC(2017, 2, 14)).getTime();
|
||||||
|
|
||||||
cy.clock(now)
|
cy.clock(now);
|
||||||
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
|
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
|
||||||
cy.get('#tick-div').click()
|
cy.get('#tick-div').click().should('have.text', '1489449600');
|
||||||
.should('have.text', '1489449600')
|
cy.tick(10000); // 10 seconds passed
|
||||||
cy.tick(10000) // 10 seconds passed
|
cy.get('#tick-div').click().should('have.text', '1489449610');
|
||||||
cy.get('#tick-div').click()
|
});
|
||||||
.should('have.text', '1489449610')
|
});
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,120 +2,96 @@
|
|||||||
|
|
||||||
context('Traversal', () => {
|
context('Traversal', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/traversal')
|
cy.visit('https://example.cypress.io/commands/traversal');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('.children() - get child DOM elements', () => {
|
it('.children() - get child DOM elements', () => {
|
||||||
// https://on.cypress.io/children
|
// https://on.cypress.io/children
|
||||||
cy.get('.traversal-breadcrumb')
|
cy.get('.traversal-breadcrumb').children('.active').should('contain', 'Data');
|
||||||
.children('.active')
|
});
|
||||||
.should('contain', 'Data')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.closest() - get closest ancestor DOM element', () => {
|
it('.closest() - get closest ancestor DOM element', () => {
|
||||||
// https://on.cypress.io/closest
|
// https://on.cypress.io/closest
|
||||||
cy.get('.traversal-badge')
|
cy.get('.traversal-badge').closest('ul').should('have.class', 'list-group');
|
||||||
.closest('ul')
|
});
|
||||||
.should('have.class', 'list-group')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.eq() - get a DOM element at a specific index', () => {
|
it('.eq() - get a DOM element at a specific index', () => {
|
||||||
// https://on.cypress.io/eq
|
// https://on.cypress.io/eq
|
||||||
cy.get('.traversal-list>li')
|
cy.get('.traversal-list>li').eq(1).should('contain', 'siamese');
|
||||||
.eq(1).should('contain', 'siamese')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.filter() - get DOM elements that match the selector', () => {
|
it('.filter() - get DOM elements that match the selector', () => {
|
||||||
// https://on.cypress.io/filter
|
// https://on.cypress.io/filter
|
||||||
cy.get('.traversal-nav>li')
|
cy.get('.traversal-nav>li').filter('.active').should('contain', 'About');
|
||||||
.filter('.active').should('contain', 'About')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.find() - get descendant DOM elements of the selector', () => {
|
it('.find() - get descendant DOM elements of the selector', () => {
|
||||||
// https://on.cypress.io/find
|
// https://on.cypress.io/find
|
||||||
cy.get('.traversal-pagination')
|
cy.get('.traversal-pagination').find('li').find('a').should('have.length', 7);
|
||||||
.find('li').find('a')
|
});
|
||||||
.should('have.length', 7)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.first() - get first DOM element', () => {
|
it('.first() - get first DOM element', () => {
|
||||||
// https://on.cypress.io/first
|
// https://on.cypress.io/first
|
||||||
cy.get('.traversal-table td')
|
cy.get('.traversal-table td').first().should('contain', '1');
|
||||||
.first().should('contain', '1')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.last() - get last DOM element', () => {
|
it('.last() - get last DOM element', () => {
|
||||||
// https://on.cypress.io/last
|
// https://on.cypress.io/last
|
||||||
cy.get('.traversal-buttons .btn')
|
cy.get('.traversal-buttons .btn').last().should('contain', 'Submit');
|
||||||
.last().should('contain', 'Submit')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.next() - get next sibling DOM element', () => {
|
it('.next() - get next sibling DOM element', () => {
|
||||||
// https://on.cypress.io/next
|
// https://on.cypress.io/next
|
||||||
cy.get('.traversal-ul')
|
cy.get('.traversal-ul').contains('apples').next().should('contain', 'oranges');
|
||||||
.contains('apples').next().should('contain', 'oranges')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.nextAll() - get all next sibling DOM elements', () => {
|
it('.nextAll() - get all next sibling DOM elements', () => {
|
||||||
// https://on.cypress.io/nextall
|
// https://on.cypress.io/nextall
|
||||||
cy.get('.traversal-next-all')
|
cy.get('.traversal-next-all').contains('oranges').nextAll().should('have.length', 3);
|
||||||
.contains('oranges')
|
});
|
||||||
.nextAll().should('have.length', 3)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.nextUntil() - get next sibling DOM elements until next el', () => {
|
it('.nextUntil() - get next sibling DOM elements until next el', () => {
|
||||||
// https://on.cypress.io/nextuntil
|
// https://on.cypress.io/nextuntil
|
||||||
cy.get('#veggies')
|
cy.get('#veggies').nextUntil('#nuts').should('have.length', 3);
|
||||||
.nextUntil('#nuts').should('have.length', 3)
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.not() - remove DOM elements from set of DOM elements', () => {
|
it('.not() - remove DOM elements from set of DOM elements', () => {
|
||||||
// https://on.cypress.io/not
|
// https://on.cypress.io/not
|
||||||
cy.get('.traversal-disabled .btn')
|
cy.get('.traversal-disabled .btn').not('[disabled]').should('not.contain', 'Disabled');
|
||||||
.not('[disabled]').should('not.contain', 'Disabled')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.parent() - get parent DOM element from DOM elements', () => {
|
it('.parent() - get parent DOM element from DOM elements', () => {
|
||||||
// https://on.cypress.io/parent
|
// https://on.cypress.io/parent
|
||||||
cy.get('.traversal-mark')
|
cy.get('.traversal-mark').parent().should('contain', 'Morbi leo risus');
|
||||||
.parent().should('contain', 'Morbi leo risus')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.parents() - get parent DOM elements from DOM elements', () => {
|
it('.parents() - get parent DOM elements from DOM elements', () => {
|
||||||
// https://on.cypress.io/parents
|
// https://on.cypress.io/parents
|
||||||
cy.get('.traversal-cite')
|
cy.get('.traversal-cite').parents().should('match', 'blockquote');
|
||||||
.parents().should('match', 'blockquote')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
|
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
|
||||||
// https://on.cypress.io/parentsuntil
|
// https://on.cypress.io/parentsuntil
|
||||||
cy.get('.clothes-nav')
|
cy.get('.clothes-nav').find('.active').parentsUntil('.clothes-nav').should('have.length', 2);
|
||||||
.find('.active')
|
});
|
||||||
.parentsUntil('.clothes-nav')
|
|
||||||
.should('have.length', 2)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('.prev() - get previous sibling DOM element', () => {
|
it('.prev() - get previous sibling DOM element', () => {
|
||||||
// https://on.cypress.io/prev
|
// https://on.cypress.io/prev
|
||||||
cy.get('.birds').find('.active')
|
cy.get('.birds').find('.active').prev().should('contain', 'Lorikeets');
|
||||||
.prev().should('contain', 'Lorikeets')
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.prevAll() - get all previous sibling DOM elements', () => {
|
it('.prevAll() - get all previous sibling DOM elements', () => {
|
||||||
// https://on.cypress.io/prevAll
|
// https://on.cypress.io/prevAll
|
||||||
cy.get('.fruits-list').find('.third')
|
cy.get('.fruits-list').find('.third').prevAll().should('have.length', 2);
|
||||||
.prevAll().should('have.length', 2)
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
|
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
|
||||||
// https://on.cypress.io/prevUntil
|
// https://on.cypress.io/prevUntil
|
||||||
cy.get('.foods-list').find('#nuts')
|
cy.get('.foods-list').find('#nuts').prevUntil('#veggies').should('have.length', 3);
|
||||||
.prevUntil('#veggies').should('have.length', 3)
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it('.siblings() - get all sibling DOM elements', () => {
|
it('.siblings() - get all sibling DOM elements', () => {
|
||||||
// https://on.cypress.io/siblings
|
// https://on.cypress.io/siblings
|
||||||
cy.get('.traversal-pills .active')
|
cy.get('.traversal-pills .active').siblings().should('have.length', 2);
|
||||||
.siblings().should('have.length', 2)
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,123 +2,118 @@
|
|||||||
|
|
||||||
context('Utilities', () => {
|
context('Utilities', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/utilities')
|
cy.visit('https://example.cypress.io/utilities');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Cypress._ - call a lodash method', () => {
|
it('Cypress._ - call a lodash method', () => {
|
||||||
// https://on.cypress.io/_
|
// https://on.cypress.io/_
|
||||||
cy.request('https://jsonplaceholder.cypress.io/users')
|
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
|
||||||
.then((response) => {
|
let ids = Cypress._.chain(response.body).map('id').take(3).value();
|
||||||
let ids = Cypress._.chain(response.body).map('id').take(3).value()
|
|
||||||
|
|
||||||
expect(ids).to.deep.eq([1, 2, 3])
|
expect(ids).to.deep.eq([1, 2, 3]);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('Cypress.$ - call a jQuery method', () => {
|
it('Cypress.$ - call a jQuery method', () => {
|
||||||
// https://on.cypress.io/$
|
// https://on.cypress.io/$
|
||||||
let $li = Cypress.$('.utility-jquery li:first')
|
let $li = Cypress.$('.utility-jquery li:first');
|
||||||
|
|
||||||
cy.wrap($li)
|
cy.wrap($li).should('not.have.class', 'active').click().should('have.class', 'active');
|
||||||
.should('not.have.class', 'active')
|
});
|
||||||
.click()
|
|
||||||
.should('have.class', 'active')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
|
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
|
||||||
// https://on.cypress.io/blob
|
// https://on.cypress.io/blob
|
||||||
cy.get('.utility-blob').then(($div) =>
|
cy.get('.utility-blob').then(($div) =>
|
||||||
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
|
||||||
// get the dataUrl string for the javascript-logo
|
// get the dataUrl string for the javascript-logo
|
||||||
Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
|
Cypress.Blob.imgSrcToDataURL(
|
||||||
.then((dataUrl) => {
|
'https://example.cypress.io/assets/img/javascript-logo.png',
|
||||||
|
undefined,
|
||||||
|
'anonymous'
|
||||||
|
).then((dataUrl) => {
|
||||||
// create an <img> element and set its src to the dataUrl
|
// create an <img> element and set its src to the dataUrl
|
||||||
let img = Cypress.$('<img />', { src: dataUrl })
|
let img = Cypress.$('<img />', { src: dataUrl });
|
||||||
|
|
||||||
// need to explicitly return cy here since we are initially returning
|
// need to explicitly return cy here since we are initially returning
|
||||||
// the Cypress.Blob.imgSrcToDataURL promise to our test
|
// the Cypress.Blob.imgSrcToDataURL promise to our test
|
||||||
// append the image
|
// append the image
|
||||||
$div.append(img)
|
$div.append(img);
|
||||||
|
|
||||||
cy.get('.utility-blob img').click()
|
cy.get('.utility-blob img').click().should('have.attr', 'src', dataUrl);
|
||||||
.should('have.attr', 'src', dataUrl)
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('Cypress.minimatch - test out glob patterns against strings', () => {
|
it('Cypress.minimatch - test out glob patterns against strings', () => {
|
||||||
// https://on.cypress.io/minimatch
|
// https://on.cypress.io/minimatch
|
||||||
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
|
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
|
||||||
matchBase: true,
|
matchBase: true,
|
||||||
})
|
});
|
||||||
|
|
||||||
expect(matching, 'matching wildcard').to.be.true
|
expect(matching, 'matching wildcard').to.be.true;
|
||||||
|
|
||||||
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
|
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
|
||||||
matchBase: true,
|
matchBase: true,
|
||||||
})
|
});
|
||||||
expect(matching, 'comments').to.be.false
|
expect(matching, 'comments').to.be.false;
|
||||||
|
|
||||||
// ** matches against all downstream path segments
|
// ** matches against all downstream path segments
|
||||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
|
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
|
||||||
matchBase: true,
|
matchBase: true,
|
||||||
})
|
});
|
||||||
expect(matching, 'comments').to.be.true
|
expect(matching, 'comments').to.be.true;
|
||||||
|
|
||||||
// whereas * matches only the next path segment
|
// whereas * matches only the next path segment
|
||||||
|
|
||||||
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
|
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
|
||||||
matchBase: false,
|
matchBase: false,
|
||||||
})
|
});
|
||||||
expect(matching, 'comments').to.be.false
|
expect(matching, 'comments').to.be.false;
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
it('Cypress.moment() - format or parse dates using a moment method', () => {
|
it('Cypress.moment() - format or parse dates using a moment method', () => {
|
||||||
// https://on.cypress.io/moment
|
// https://on.cypress.io/moment
|
||||||
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
|
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A');
|
||||||
|
|
||||||
expect(time).to.be.a('string')
|
expect(time).to.be.a('string');
|
||||||
|
|
||||||
cy.get('.utility-moment').contains('3:38 PM')
|
cy.get('.utility-moment').contains('3:38 PM').should('have.class', 'badge');
|
||||||
.should('have.class', 'badge')
|
|
||||||
|
|
||||||
// the time in the element should be between 3pm and 5pm
|
// the time in the element should be between 3pm and 5pm
|
||||||
const start = Cypress.moment('3:00 PM', 'LT')
|
const start = Cypress.moment('3:00 PM', 'LT');
|
||||||
const end = Cypress.moment('5:00 PM', 'LT')
|
const end = Cypress.moment('5:00 PM', 'LT');
|
||||||
|
|
||||||
cy.get('.utility-moment .badge')
|
cy.get('.utility-moment .badge').should(($el) => {
|
||||||
.should(($el) => {
|
|
||||||
// parse American time like "3:38 PM"
|
// parse American time like "3:38 PM"
|
||||||
const m = Cypress.moment($el.text().trim(), 'LT')
|
const m = Cypress.moment($el.text().trim(), 'LT');
|
||||||
|
|
||||||
// display hours + minutes + AM|PM
|
// display hours + minutes + AM|PM
|
||||||
const f = 'h:mm A'
|
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
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
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', () => {
|
it('Cypress.Promise - instantiate a bluebird promise', () => {
|
||||||
// https://on.cypress.io/promise
|
// https://on.cypress.io/promise
|
||||||
let waited = false
|
let waited = false;
|
||||||
|
|
||||||
/**
|
/** @returns Bluebird<string> */
|
||||||
* @return Bluebird<string>
|
|
||||||
*/
|
|
||||||
function waitOneSecond() {
|
function waitOneSecond() {
|
||||||
// return a promise that resolves after 1 second
|
// return a promise that resolves after 1 second
|
||||||
// @ts-ignore TS2351 (new Cypress.Promise)
|
// @ts-ignore TS2351 (new Cypress.Promise)
|
||||||
return new Cypress.Promise((resolve, reject) => {
|
return new Cypress.Promise((resolve, reject) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// set waited to true
|
// set waited to true
|
||||||
waited = true
|
waited = true;
|
||||||
|
|
||||||
// resolve with 'foo' string
|
// resolve with 'foo' string
|
||||||
resolve('foo')
|
resolve('foo');
|
||||||
}, 1000)
|
}, 1000);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cy.then(() =>
|
cy.then(() =>
|
||||||
@@ -126,8 +121,9 @@ context('Utilities', () => {
|
|||||||
// is awaited until it resolves
|
// is awaited until it resolves
|
||||||
// @ts-ignore TS7006
|
// @ts-ignore TS7006
|
||||||
waitOneSecond().then((str) => {
|
waitOneSecond().then((str) => {
|
||||||
expect(str).to.eq('foo')
|
expect(str).to.eq('foo');
|
||||||
expect(waited).to.be.true
|
expect(waited).to.be.true;
|
||||||
}))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -2,22 +2,22 @@
|
|||||||
|
|
||||||
context('Viewport', () => {
|
context('Viewport', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/viewport')
|
cy.visit('https://example.cypress.io/commands/viewport');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.viewport() - set the viewport size and dimension', () => {
|
it('cy.viewport() - set the viewport size and dimension', () => {
|
||||||
// https://on.cypress.io/viewport
|
// https://on.cypress.io/viewport
|
||||||
|
|
||||||
cy.get('#navbar').should('be.visible')
|
cy.get('#navbar').should('be.visible');
|
||||||
cy.viewport(320, 480)
|
cy.viewport(320, 480);
|
||||||
|
|
||||||
// the navbar should have collapse since our screen is smaller
|
// the navbar should have collapse since our screen is smaller
|
||||||
cy.get('#navbar').should('not.be.visible')
|
cy.get('#navbar').should('not.be.visible');
|
||||||
cy.get('.navbar-toggle').should('be.visible').click()
|
cy.get('.navbar-toggle').should('be.visible').click();
|
||||||
cy.get('.nav').find('a').should('be.visible')
|
cy.get('.nav').find('a').should('be.visible');
|
||||||
|
|
||||||
// lets see what our app looks like on a super large screen
|
// lets see what our app looks like on a super large screen
|
||||||
cy.viewport(2999, 2999)
|
cy.viewport(2999, 2999);
|
||||||
|
|
||||||
// cy.viewport() accepts a set of preset sizes
|
// cy.viewport() accepts a set of preset sizes
|
||||||
// to easily set the screen to a device's width and height
|
// to easily set the screen to a device's width and height
|
||||||
@@ -25,35 +25,35 @@ context('Viewport', () => {
|
|||||||
// We added a cy.wait() between each viewport change so you can see
|
// We added a cy.wait() between each viewport change so you can see
|
||||||
// the change otherwise it is a little too fast to see :)
|
// the change otherwise it is a little too fast to see :)
|
||||||
|
|
||||||
cy.viewport('macbook-15')
|
cy.viewport('macbook-15');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('macbook-13')
|
cy.viewport('macbook-13');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('macbook-11')
|
cy.viewport('macbook-11');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('ipad-2')
|
cy.viewport('ipad-2');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('ipad-mini')
|
cy.viewport('ipad-mini');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('iphone-6+')
|
cy.viewport('iphone-6+');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('iphone-6')
|
cy.viewport('iphone-6');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('iphone-5')
|
cy.viewport('iphone-5');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('iphone-4')
|
cy.viewport('iphone-4');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('iphone-3')
|
cy.viewport('iphone-3');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
|
|
||||||
// cy.viewport() accepts an orientation for all presets
|
// cy.viewport() accepts an orientation for all presets
|
||||||
// the default orientation is 'portrait'
|
// the default orientation is 'portrait'
|
||||||
cy.viewport('ipad-2', 'portrait')
|
cy.viewport('ipad-2', 'portrait');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
cy.viewport('iphone-4', 'landscape')
|
cy.viewport('iphone-4', 'landscape');
|
||||||
cy.wait(200)
|
cy.wait(200);
|
||||||
|
|
||||||
// The viewport will be reset back to the default dimensions
|
// The viewport will be reset back to the default dimensions
|
||||||
// in between tests (the default can be set in cypress.json)
|
// in between tests (the default can be set in cypress.json)
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -2,33 +2,32 @@
|
|||||||
|
|
||||||
context('Waiting', () => {
|
context('Waiting', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/waiting')
|
cy.visit('https://example.cypress.io/commands/waiting');
|
||||||
})
|
});
|
||||||
// BE CAREFUL of adding unnecessary wait times.
|
// BE CAREFUL of adding unnecessary wait times.
|
||||||
// https://on.cypress.io/best-practices#Unnecessary-Waiting
|
// https://on.cypress.io/best-practices#Unnecessary-Waiting
|
||||||
|
|
||||||
// https://on.cypress.io/wait
|
// https://on.cypress.io/wait
|
||||||
it('cy.wait() - wait for a specific amount of time', () => {
|
it('cy.wait() - wait for a specific amount of time', () => {
|
||||||
cy.get('.wait-input1').type('Wait 1000ms after typing')
|
cy.get('.wait-input1').type('Wait 1000ms after typing');
|
||||||
cy.wait(1000)
|
cy.wait(1000);
|
||||||
cy.get('.wait-input2').type('Wait 1000ms after typing')
|
cy.get('.wait-input2').type('Wait 1000ms after typing');
|
||||||
cy.wait(1000)
|
cy.wait(1000);
|
||||||
cy.get('.wait-input3').type('Wait 1000ms after typing')
|
cy.get('.wait-input3').type('Wait 1000ms after typing');
|
||||||
cy.wait(1000)
|
cy.wait(1000);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.wait() - wait for a specific route', () => {
|
it('cy.wait() - wait for a specific route', () => {
|
||||||
cy.server()
|
cy.server();
|
||||||
|
|
||||||
// Listen to GET to comments/1
|
// Listen to GET to comments/1
|
||||||
cy.route('GET', 'comments/*').as('getComment')
|
cy.route('GET', 'comments/*').as('getComment');
|
||||||
|
|
||||||
// we have code that gets a comment when
|
// we have code that gets a comment when
|
||||||
// the button is clicked in scripts.js
|
// the button is clicked in scripts.js
|
||||||
cy.get('.network-btn').click()
|
cy.get('.network-btn').click();
|
||||||
|
|
||||||
// wait for GET comments/1
|
// wait for GET comments/1
|
||||||
cy.wait('@getComment').its('status').should('eq', 200)
|
cy.wait('@getComment').its('status').should('eq', 200);
|
||||||
})
|
});
|
||||||
|
});
|
||||||
})
|
|
||||||
|
|||||||
@@ -2,21 +2,21 @@
|
|||||||
|
|
||||||
context('Window', () => {
|
context('Window', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('https://example.cypress.io/commands/window')
|
cy.visit('https://example.cypress.io/commands/window');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.window() - get the global window object', () => {
|
it('cy.window() - get the global window object', () => {
|
||||||
// https://on.cypress.io/window
|
// https://on.cypress.io/window
|
||||||
cy.window().should('have.property', 'top')
|
cy.window().should('have.property', 'top');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.document() - get the document object', () => {
|
it('cy.document() - get the document object', () => {
|
||||||
// https://on.cypress.io/document
|
// https://on.cypress.io/document
|
||||||
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
|
cy.document().should('have.property', 'charset').and('eq', 'UTF-8');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('cy.title() - get the title', () => {
|
it('cy.title() - get the title', () => {
|
||||||
// https://on.cypress.io/title
|
// https://on.cypress.io/title
|
||||||
cy.title().should('include', 'Kitchen Sink')
|
cy.title().should('include', 'Kitchen Sink');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import { Base64 } from 'js-base64';
|
import { Base64 } from 'js-base64';
|
||||||
|
|
||||||
export const mermaidUrl = (graphStr, options, api) => {
|
export const mermaidUrl = (graphStr, options, api) => {
|
||||||
const obj = {
|
const obj = {
|
||||||
code: graphStr,
|
code: graphStr,
|
||||||
mermaid: options
|
mermaid: options,
|
||||||
};
|
};
|
||||||
const objStr = JSON.stringify(obj);
|
const objStr = JSON.stringify(obj);
|
||||||
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);
|
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);
|
||||||
@@ -19,10 +18,40 @@ export const mermaidUrl = (graphStr, options, api) => {
|
|||||||
return url;
|
return url;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const imgSnapshotTest = (graphStr, options, api) => {
|
export const imgSnapshotTest = (graphStr, _options, api) => {
|
||||||
|
cy.log(_options);
|
||||||
|
const options = Object.assign(_options);
|
||||||
|
if (!options.fontFamily) {
|
||||||
|
options.fontFamily = 'courier';
|
||||||
|
}
|
||||||
|
if (!options.sequence) {
|
||||||
|
options.sequence = {};
|
||||||
|
}
|
||||||
|
if (!options.sequence || (options.sequence && !options.sequence.actorFontFamily)) {
|
||||||
|
options.sequence.actorFontFamily = 'courier';
|
||||||
|
}
|
||||||
|
if (options.sequence && !options.sequence.noteFontFamily) {
|
||||||
|
options.sequence.noteFontFamily = 'courier';
|
||||||
|
}
|
||||||
|
options.sequence.actorFontFamily = 'courier';
|
||||||
|
options.sequence.noteFontFamily = 'courier';
|
||||||
|
options.sequence.messageFontFamily = 'courier';
|
||||||
|
if (options.sequence && !options.sequence.actorFontFamily) {
|
||||||
|
options.sequence.actorFontFamily = 'courier';
|
||||||
|
}
|
||||||
|
if (!options.fontSize) {
|
||||||
|
options.fontSize = '16px';
|
||||||
|
}
|
||||||
|
cy.log(options);
|
||||||
const url = mermaidUrl(graphStr, options, api);
|
const url = mermaidUrl(graphStr, options, api);
|
||||||
|
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
cy.percySnapshot();
|
cy.percySnapshot();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const renderGraph = (graphStr, options, api) => {
|
||||||
|
const url = mermaidUrl(graphStr, options, api);
|
||||||
|
|
||||||
|
cy.visit(url);
|
||||||
|
};
|
||||||
|
|||||||
117
cypress/integration/other/configuration.spec.js
Normal file
117
cypress/integration/other/configuration.spec.js
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import { renderGraph } from '../../helpers/util';
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
it('should not taint the initial configuration when using multiple directives', () => {
|
||||||
|
const url = 'http://localhost:9000/regression/issue-1874.html';
|
||||||
|
cy.viewport(1440, 1024);
|
||||||
|
cy.visit(url);
|
||||||
|
|
||||||
|
cy.get('svg');
|
||||||
|
cy.percySnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,47 +1,83 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
describe('Interaction', () => {
|
describe('Interaction', () => {
|
||||||
describe('Interaction - security level loose', () => {
|
describe('Interaction - security level loose', () => {
|
||||||
it('should handle a click on a node with a bound function', () => {
|
it('Graph: should handle a click on a node with a bound function', () => {
|
||||||
const url = 'http://localhost:9000/click_security_loose.html';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g#flowchart-Function-2').click();
|
||||||
.find('g#Function')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
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', () => {
|
it('Graph: should handle a click on a node with a bound function with args', () => {
|
||||||
const url = 'http://localhost:9000/click_security_loose.html';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g#flowchart-FunctionArg-18').click();
|
||||||
.find('g#s1Function')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
|
||||||
});
|
});
|
||||||
it('should handle a click on a node with a bound url', () => {
|
it('Flowchart: 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';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g[id="flowchart-FunctionArg-22"]').click();
|
||||||
.find('g#URL')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
|
||||||
|
});
|
||||||
|
it('Graph: 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('#flowchart-URL-3').click();
|
||||||
|
|
||||||
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
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', () => {
|
it('Graph: 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';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g[id="flowchart-2URL-7"]').click();
|
||||||
.find('g#s2URL')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Flowchart-v2: 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#flowchart-Function-10').click();
|
||||||
|
|
||||||
|
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||||
|
});
|
||||||
|
it('Flowchart-v2: 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="flowchart-1Function-14"]').click();
|
||||||
|
|
||||||
|
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
|
||||||
|
});
|
||||||
|
it('Flowchart-v2: 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('#flowchart-URL-11').click();
|
||||||
|
|
||||||
|
cy.location().should((location) => {
|
||||||
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('Flowchart-v2: 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="flowchart-2URL-15"]').click();
|
||||||
|
|
||||||
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -50,11 +86,9 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_loose.html';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('rect#cl1').click({ force: true });
|
||||||
.find('rect#cl1')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -62,33 +96,44 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_loose.html';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('text#cl1-text').click({ force: true });
|
||||||
.find('text#cl1-text')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should handle a click on a task with a bound function', () => {
|
it('should handle a click on a task with a bound function without args', () => {
|
||||||
const url = 'http://localhost:9000/click_security_loose.html';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('rect#cl2').click({ force: true });
|
||||||
.find('rect#cl2')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant');
|
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', () => {
|
it('should handle a click on a task with a bound function with args', () => {
|
||||||
const url = 'http://localhost:9000/click_security_loose.html';
|
const url = 'http://localhost:9000/click_security_loose.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('rect#cl3').click({ force: true });
|
||||||
.find('text#cl2-text')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant');
|
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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -97,31 +142,27 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g#flowchart-Function-2').click();
|
||||||
.find('g#Function')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
cy.get('.created-by-click').should('not.exist');
|
||||||
|
// 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', () => {
|
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';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g[id="flowchart-1Function-6"]').click();
|
||||||
.find('g#s1Function')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||||
|
cy.get('.created-by-click').should('not.exist');
|
||||||
});
|
});
|
||||||
it('should handle a click on a node with a bound url', () => {
|
it('should handle a click on a node with a bound url', () => {
|
||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g#flowchart-URL-3').click();
|
||||||
.find('g#URL')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -129,11 +170,9 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g[id="flowchart-2URL-7"]').click();
|
||||||
.find('g#s2URL')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -142,11 +181,9 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('rect#cl1').click({ force: true });
|
||||||
.find('rect#cl1')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -154,11 +191,9 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('text#cl1-text').click({ force: true });
|
||||||
.find('text#cl1-text')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -166,77 +201,67 @@ describe('Interaction', () => {
|
|||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('rect#cl2').click({ force: true });
|
||||||
.find('rect#cl2')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant');
|
// cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||||
|
cy.get('.created-by-gant-click').should('not.exist');
|
||||||
});
|
});
|
||||||
it('should handle a click on a task with a bound function', () => {
|
it('should handle a click on a task with a bound function', () => {
|
||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_strict.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('text#cl2-text').click({ force: true });
|
||||||
.find('text#cl2-text')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant');
|
// cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
|
||||||
|
cy.get('.created-by-gant-click').should('not.exist');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Interaction - security level other, missspelling', () => {
|
describe('Interaction - security level other, missspelling', () => {
|
||||||
it('should handle a click on a node with a bound function', () => {
|
it('should handle a click on a node with a bound function', () => {
|
||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_other.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g#flowchart-Function-2').click();
|
||||||
.find('g#Function')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
||||||
|
cy.get('.created-by-click').should('not.exist');
|
||||||
});
|
});
|
||||||
it('should handle a click on a node with a bound function where the node starts with a number', () => {
|
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';
|
const url = 'http://localhost:9000/click_security_other.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g[id="flowchart-1Function-6"]').click();
|
||||||
.find('g#s1Function')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
|
cy.get('.created-by-click').should('not.exist');
|
||||||
|
cy.get('.created-by-click').should('not.exist');
|
||||||
});
|
});
|
||||||
it('should handle a click on a node with a bound url', () => {
|
it('should handle a click on a node with a bound url', () => {
|
||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_other.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('g#flowchart-URL-3').click();
|
||||||
.find('g#URL')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.location().should(location => {
|
cy.location().should((location) => {
|
||||||
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a click on a task with a bound function', () => {
|
it('should handle a click on a task with a bound function', () => {
|
||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_other.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('rect#cl2').click({ force: true });
|
||||||
.find('rect#cl2')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant');
|
cy.get('.created-by-gant-click').should('not.exist');
|
||||||
});
|
});
|
||||||
it('should handle a click on a task with a bound function', () => {
|
it('should handle a click on a task with a bound function', () => {
|
||||||
const url = 'http://localhost:9000/click_security_strict.html';
|
const url = 'http://localhost:9000/click_security_other.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('text#cl2-text').click({ force: true });
|
||||||
.find('text#cl2-text')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant');
|
cy.get('.created-by-gant-click').should('not.exist');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
describe('Rerendering', () => {
|
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', () => {
|
it('should be able to render and rerender a graph via API', () => {
|
||||||
const url = 'http://localhost:9000/rerender.html';
|
const url = 'http://localhost:9000/rerender.html';
|
||||||
cy.viewport(1440, 1024);
|
cy.viewport(1440, 1024);
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('#graph #A').should('have.text', 'XMas');
|
cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
|
||||||
|
|
||||||
cy.get('body')
|
cy.get('body').find('#rerender').click({ force: true });
|
||||||
.find('#rerender')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
cy.get('#graph #A').should('have.text', 'Saturday');
|
cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
describe('Sequencediagram', () => {
|
describe('Sequencediagram', () => {
|
||||||
it('should render a simple sequence diagrams', () => {
|
it('should render a simple sequence diagrams', () => {
|
||||||
const url = 'http://localhost:9000/webpackUsage.html';
|
const url = 'http://localhost:9000/webpackUsage.html';
|
||||||
|
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('body')
|
cy.get('body').find('svg').should('have.length', 1);
|
||||||
.find('svg')
|
});
|
||||||
.should('have.length', 2);
|
it('should handle html escapings properly', () => {
|
||||||
|
const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
|
||||||
|
|
||||||
|
cy.visit(url);
|
||||||
|
cy.get('body').find('svg').should('have.length', 1);
|
||||||
|
|
||||||
|
cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,113 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import { mermaidUrl } from '../../helpers/util.js';
|
import { mermaidUrl } from '../../helpers/util.js';
|
||||||
|
|
||||||
/* eslint-disable */
|
|
||||||
describe('XSS', () => {
|
describe('XSS', () => {
|
||||||
it('should handle xss in tags', () => {
|
it('should handle xss in tags', () => {
|
||||||
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
|
const str =
|
||||||
|
'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
|
||||||
|
|
||||||
const url = mermaidUrl(str, {}, true);
|
const url = mermaidUrl(str, {}, true);
|
||||||
|
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.get('svg')
|
cy.wait(1000).then(() => {
|
||||||
cy.percySnapshot()
|
cy.get('.mermaid').should('exist');
|
||||||
|
});
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
})
|
it('should not allow tags in the css', () => {
|
||||||
})
|
const str =
|
||||||
|
'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
|
||||||
|
|
||||||
|
const url = mermaidUrl(
|
||||||
|
str,
|
||||||
|
{
|
||||||
|
theme: 'default',
|
||||||
|
flowchart: {
|
||||||
|
htmlMode: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.visit(url);
|
||||||
|
cy.wait(1000).then(() => {
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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.wait(1000);
|
||||||
|
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow changing the __proto__ attribute using config', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss2.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating htmlLabels into a false positive', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss4.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss5.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss6.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre wrapper', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss8.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss9.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss10.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss11.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss12.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss13.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
it('should not allow maniplulating antiscript to run javascript iframes in class diagrams', () => {
|
||||||
|
cy.visit('http://localhost:9000/xss14.html');
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#the-malware').should('not.exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
481
cypress/integration/rendering/classDiagram-v2.spec.js
Normal file
481
cypress/integration/rendering/classDiagram-v2.spec.js
Normal file
@@ -0,0 +1,481 @@
|
|||||||
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
describe('Class diagram V2', () => {
|
||||||
|
it('0: should render a simple class diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
|
||||||
|
classA -- classB : Inheritance
|
||||||
|
classA -- classC : link
|
||||||
|
classC -- classD : link
|
||||||
|
classB -- classD
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('1: should render a simple class diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
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, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('2: should render a simple class diagrams with cardinality', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a simple class diagram with different visibilities', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
Class01 <|-- AveryLongClass : Cool
|
||||||
|
<<interface>> Class01
|
||||||
|
Class01 : -privateMethod()
|
||||||
|
Class01 : +publicMethod()
|
||||||
|
Class01 : #protectedMethod()
|
||||||
|
Class01 : -int privateChimp
|
||||||
|
Class01 : +int publicGorilla
|
||||||
|
Class01 : #int protectedMarmoset
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render multiple class diagrams', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
[
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
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-v2
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('4: should render a simple class diagram with comments', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
%% 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()
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('5: should render a simple class diagram with abstract method', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
Class01 <|-- AveryLongClass : Cool
|
||||||
|
Class01 : someMethod()*
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('6: should render a simple class diagram with static method', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
Class01 <|-- AveryLongClass : Cool
|
||||||
|
Class01 : someMethod()$
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('7: should render a simple class diagram with Generic class', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class01~T~
|
||||||
|
Class01 : size()
|
||||||
|
Class01 : int chimp
|
||||||
|
Class01 : int gorilla
|
||||||
|
Class08 <--> C2: Cool label
|
||||||
|
class Class10~T~ {
|
||||||
|
<<service>>
|
||||||
|
int id
|
||||||
|
test()
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('8: should render a simple class diagram with Generic class and relations', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('9: should render a simple class diagram with clickable link', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
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"
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('10: should render a simple class diagram with clickable callback', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
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"
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('11: should render a simple class diagram with return type on method', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10~T~ {
|
||||||
|
int[] id
|
||||||
|
test(int[] ids) bool
|
||||||
|
testArray() bool[]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('12: should render a simple class diagram with generic types', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10~T~ {
|
||||||
|
int[] id
|
||||||
|
List~int~ ids
|
||||||
|
test(List~int~ ids) List~bool~
|
||||||
|
testArray() bool[]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('13: should render a simple class diagram with css classes applied', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10 {
|
||||||
|
int[] id
|
||||||
|
List~int~ ids
|
||||||
|
test(List~int~ ids) List~bool~
|
||||||
|
testArray() bool[]
|
||||||
|
}
|
||||||
|
|
||||||
|
cssClass "Class10" exClass2
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('14: should render a simple class diagram with css classes applied directly', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10:::exClass2 {
|
||||||
|
int[] id
|
||||||
|
List~int~ ids
|
||||||
|
test(List~int~ ids) List~bool~
|
||||||
|
testArray() bool[]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('15: should render a simple class diagram with css classes applied two multiple classes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Class10
|
||||||
|
class Class20
|
||||||
|
|
||||||
|
cssClass "Class10, class20" exClass2
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('16a: should render a simple class diagram with static field', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram-v2
|
||||||
|
class Foo {
|
||||||
|
+String bar$
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('16b: should handle the direction statemnent with TB', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
direction TB
|
||||||
|
class Student {
|
||||||
|
-idCard : IdCard
|
||||||
|
}
|
||||||
|
class IdCard{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
class Bike{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
Student "1" --o "1" IdCard : carries
|
||||||
|
Student "1" --o "1" Bike : rides
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('18: should handle the direction statemnent with LR', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
direction LR
|
||||||
|
class Student {
|
||||||
|
-idCard : IdCard
|
||||||
|
}
|
||||||
|
class IdCard{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
class Bike{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
Student "1" --o "1" IdCard : carries
|
||||||
|
Student "1" --o "1" Bike : rides
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('17a: should handle the direction statemnent with BT', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
direction BT
|
||||||
|
class Student {
|
||||||
|
-idCard : IdCard
|
||||||
|
}
|
||||||
|
class IdCard{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
class Bike{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
Student "1" --o "1" IdCard : carries
|
||||||
|
Student "1" --o "1" Bike : rides
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('17b: should handle the direction statemment with RL', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
direction RL
|
||||||
|
class Student {
|
||||||
|
-idCard : IdCard
|
||||||
|
}
|
||||||
|
class IdCard{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
class Bike{
|
||||||
|
-id : int
|
||||||
|
-name : string
|
||||||
|
}
|
||||||
|
Student "1" --o "1" IdCard : carries
|
||||||
|
Student "1" --o "1" Bike : rides
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
/* eslint-env jest */
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||||
import { imgSnapshotTest } from '../../helpers/util';
|
|
||||||
|
|
||||||
describe('Class diagram', () => {
|
describe('Class diagram', () => {
|
||||||
it('should render a simple class diagram', () => {
|
it('1: should render a simple class diagram', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
classDiagram
|
classDiagram
|
||||||
@@ -14,11 +13,16 @@ describe('Class diagram', () => {
|
|||||||
Class09 --> C2 : Where am i?
|
Class09 --> C2 : Where am i?
|
||||||
Class09 --* C3
|
Class09 --* C3
|
||||||
Class09 --|> Class07
|
Class09 --|> Class07
|
||||||
|
Class12 <|.. Class08
|
||||||
|
Class11 ..>Class12
|
||||||
Class07 : equals()
|
Class07 : equals()
|
||||||
Class07 : Object[] elementData
|
Class07 : Object[] elementData
|
||||||
Class01 : size()
|
Class01 : size()
|
||||||
Class01 : int chimp
|
Class01 : int chimp
|
||||||
Class01 : int gorilla
|
Class01 : int gorilla
|
||||||
|
Class01 : -int privateChimp
|
||||||
|
Class01 : +int publicGorilla
|
||||||
|
Class01 : #int protectedMarmoset
|
||||||
Class08 <--> C2: Cool label
|
Class08 <--> C2: Cool label
|
||||||
class Class10 {
|
class Class10 {
|
||||||
<<service>>
|
<<service>>
|
||||||
@@ -26,11 +30,12 @@ describe('Class diagram', () => {
|
|||||||
test()
|
test()
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
{}
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
it('should render a simple class diagrams with cardinality', () => {
|
|
||||||
|
it('2: should render a simple class diagrams with cardinality', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
classDiagram
|
classDiagram
|
||||||
@@ -58,4 +63,348 @@ describe('Class diagram', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('3: 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('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');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('13: should render a simple class diagram with css classes applied', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
class Class10 {
|
||||||
|
int[] id
|
||||||
|
List~int~ ids
|
||||||
|
test(List~int~ ids) List~bool~
|
||||||
|
testArray() bool[]
|
||||||
|
}
|
||||||
|
|
||||||
|
class Class10:::exClass2
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('14: should render a simple class diagram with css classes applied directly', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
class Class10:::exClass2 {
|
||||||
|
int[] id
|
||||||
|
List~int~ ids
|
||||||
|
test(List~int~ ids) List~bool~
|
||||||
|
testArray() bool[]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('15: should render a simple class diagram with css classes applied two multiple classes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
classDiagram
|
||||||
|
class Class10
|
||||||
|
class Class20
|
||||||
|
|
||||||
|
cssClass "Class10, Class20" exClass2
|
||||||
|
class Class20:::exClass2
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('16: 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('17: should render a class diagram when useMaxWidth is true (default)', () => {
|
||||||
|
// renderGraph(
|
||||||
|
// `
|
||||||
|
// classDiagram
|
||||||
|
// Class01 <|-- AveryLongClass : Cool
|
||||||
|
// Class01 : size()
|
||||||
|
// Class01 : int chimp
|
||||||
|
// Class01 : int gorilla
|
||||||
|
// Class01 : -int privateChimp
|
||||||
|
// Class01 : +int publicGorilla
|
||||||
|
// Class01 : #int protectedMarmoset
|
||||||
|
// `,
|
||||||
|
// { class: { useMaxWidth: true } }
|
||||||
|
// );
|
||||||
|
// cy.get('svg')
|
||||||
|
// .should((svg) => {
|
||||||
|
// expect(svg).to.have.attr('width', '100%');
|
||||||
|
// const height = parseFloat(svg.attr('height'));
|
||||||
|
// expect(height).to.be.within(332, 333);
|
||||||
|
// // expect(svg).to.have.attr('height', '218');
|
||||||
|
// const style = svg.attr('style');
|
||||||
|
// expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
// const maxWidthValue = parseInt(style.match(/[\d.]+/g).join(''));
|
||||||
|
// // use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
// expect(maxWidthValue).to.be.within(203, 204);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('18: should render a class diagram when useMaxWidth is false', () => {
|
||||||
|
// renderGraph(
|
||||||
|
// `
|
||||||
|
// classDiagram
|
||||||
|
// Class01 <|-- AveryLongClass : Cool
|
||||||
|
// Class01 : size()
|
||||||
|
// Class01 : int chimp
|
||||||
|
// Class01 : int gorilla
|
||||||
|
// Class01 : -int privateChimp
|
||||||
|
// Class01 : +int publicGorilla
|
||||||
|
// Class01 : #int protectedMarmoset
|
||||||
|
// `,
|
||||||
|
// { class: { useMaxWidth: false } }
|
||||||
|
// );
|
||||||
|
// cy.get('svg')
|
||||||
|
// .should((svg) => {
|
||||||
|
// const width = parseFloat(svg.attr('width'));
|
||||||
|
// // use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
// expect(width).to.be.within(100, 101);
|
||||||
|
// const height = parseFloat(svg.attr('height'));
|
||||||
|
// expect(height).to.be.within(332, 333);
|
||||||
|
// // expect(svg).to.have.attr('height', '332');
|
||||||
|
// // expect(svg).to.not.have.attr('style');
|
||||||
|
// });
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
|||||||
140
cypress/integration/rendering/conf-and-directives.spec.js
Normal file
140
cypress/integration/rendering/conf-and-directives.spec.js
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||||
|
|
||||||
|
describe('Configuration and directives - nodes should be light blue', () => {
|
||||||
|
it('No config - use default', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
graph TD
|
||||||
|
A(Default) --> B[/Another/]
|
||||||
|
A --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('Settigns from intitialize - nodes should be green', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
graph TD
|
||||||
|
A(Forest) --> B[/Another/]
|
||||||
|
A --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end `,
|
||||||
|
{ theme: 'forest' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
|
||||||
|
|
||||||
|
%%{init: { 'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||||
|
graph TD
|
||||||
|
A(Start) --> B[/Another/]
|
||||||
|
A[/Another/] --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ theme: 'base', themeVariables: { primaryColor: '#ff0000' }, logLevel: 0 }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('Settings from directive - nodes should be grey', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
|
||||||
|
graph TD
|
||||||
|
A(Start) --> B[/Another/]
|
||||||
|
A[/Another/] --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Settings from directive overriding theme variable - nodes should be red', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||||
|
graph TD
|
||||||
|
A(Start) --> B[/Another/]
|
||||||
|
A[/Another/] --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('Settings from initialize and directive - nodes should be grey', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
|
||||||
|
graph TD
|
||||||
|
A(Start) --> B[/Another/]
|
||||||
|
A[/Another/] --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ theme: 'forest' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||||
|
graph TD
|
||||||
|
A(Start) --> B[/Another/]
|
||||||
|
A[/Another/] --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ theme: 'base' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('Theme variable from initialize, theme from directive - nodes should be red', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': 'base'} }%%
|
||||||
|
graph TD
|
||||||
|
A(Start) --> B[/Another/]
|
||||||
|
A[/Another/] --> C[End]
|
||||||
|
subgraph section
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ themeVariables: { primaryColor: '#ff0000' } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
describe('when rendering several diagrams', () => {
|
||||||
|
it('diagrams should not taint later diagrams', () => {
|
||||||
|
const url = 'http://localhost:9000/theme-directives.html';
|
||||||
|
cy.visit(url);
|
||||||
|
cy.get('svg');
|
||||||
|
cy.percySnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import { imgSnapshotTest } from '../../helpers/util';
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
|
||||||
describe('State diagram', () => {
|
describe('State diagram', () => {
|
||||||
it('should render a flowchart full of circles', () => {
|
it('should render a state with states in it', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
stateDiagram
|
stateDiagram
|
||||||
State1: The state with a note
|
state PersonalizedCockpit {
|
||||||
note right of State1
|
Other
|
||||||
Important information! You\ncan write
|
state Parent {
|
||||||
notes with multiple lines...
|
C
|
||||||
Here is another line...
|
}
|
||||||
And another line...
|
}
|
||||||
end note
|
|
||||||
`,
|
`,
|
||||||
{}
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
12
cypress/integration/rendering/debug.spec.js
Normal file
12
cypress/integration/rendering/debug.spec.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
|
||||||
|
describe('Flowchart', () => {
|
||||||
|
it('34: testing the label width in percy', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph TD
|
||||||
|
A[Christmas]
|
||||||
|
`,
|
||||||
|
{ theme: 'forest', fontFamily: '"Noto Sans SC", sans-serif' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
196
cypress/integration/rendering/erDiagram.spec.js
Normal file
196
cypress/integration/rendering/erDiagram.spec.js
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
import { imgSnapshotTest, renderGraph } 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');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render an ER diagrams when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
CUSTOMER ||--o{ ORDER : places
|
||||||
|
ORDER ||--|{ LINE-ITEM : contains
|
||||||
|
`,
|
||||||
|
{ er: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height', '465');
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(maxWidthValue).to.be.within(140 * 0.95, 140 * 1.05);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render an ER when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
CUSTOMER ||--o{ ORDER : places
|
||||||
|
ORDER ||--|{ LINE-ITEM : contains
|
||||||
|
`,
|
||||||
|
{ er: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(width).to.be.within(140 * 0.95, 140 * 1.05);
|
||||||
|
expect(svg).to.have.attr('height', '465');
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render entities that have no relationships', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
DEAD_PARROT
|
||||||
|
HERMIT
|
||||||
|
RECLUSE
|
||||||
|
SOCIALITE }o--o{ SOCIALITE : "interacts with"
|
||||||
|
RECLUSE }o--o{ SOCIALITE : avoids
|
||||||
|
`,
|
||||||
|
{ er: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render entities with and without attributes', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
BOOK { string title }
|
||||||
|
AUTHOR }|..|{ BOOK : writes
|
||||||
|
BOOK { float price }
|
||||||
|
`,
|
||||||
|
{ logLevel: 1 }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render entities and attributes with big and small entity names', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
PRIVATE_FINANCIAL_INSTITUTION {
|
||||||
|
string name
|
||||||
|
int turnover
|
||||||
|
}
|
||||||
|
PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
|
||||||
|
EMPLOYEE { bool officer_of_firm }
|
||||||
|
`,
|
||||||
|
{ logLevel: 1 }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render entities with keys and comments', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
erDiagram
|
||||||
|
BOOK { string title PK "comment"}
|
||||||
|
`,
|
||||||
|
{ logLevel: 1 }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
});
|
||||||
641
cypress/integration/rendering/flowchart-v2.spec.js
Normal file
641
cypress/integration/rendering/flowchart-v2.spec.js
Normal file
@@ -0,0 +1,641 @@
|
|||||||
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||||
|
|
||||||
|
describe('Flowchart v2', () => {
|
||||||
|
it('1: should render a simple flowchart', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart 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]
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('2: should render a simple flowchart with diagramPadding set to 0', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart 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: { diagramPadding: 0 } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('3: a link with correct arrowhead to a subgraph', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
P1
|
||||||
|
P1 -->P1.5
|
||||||
|
subgraph P1.5
|
||||||
|
P2
|
||||||
|
P2.5(( A ))
|
||||||
|
P3
|
||||||
|
end
|
||||||
|
P2 --> P4
|
||||||
|
P3 --> P6
|
||||||
|
P1.5 --> P5
|
||||||
|
`,
|
||||||
|
{ flowchart: { diagramPadding: 0 } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('4: Length of edges', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
L1 --- L2
|
||||||
|
L2 --- C
|
||||||
|
M1 ---> C
|
||||||
|
R1 .-> R2
|
||||||
|
R2 <.-> C
|
||||||
|
C -->|Label 1| E1
|
||||||
|
C <-- Label 2 ---> E2
|
||||||
|
C ----> E3
|
||||||
|
C <-...-> E4
|
||||||
|
C ======> E5
|
||||||
|
`,
|
||||||
|
{ flowchart: { diagramPadding: 0 } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('5: should render escaped without html labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
a["<strong>Haiya</strong>"]---->b
|
||||||
|
`,
|
||||||
|
{ htmlLabels: false, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('6: should render non-escaped with html labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
a["<strong>Haiya</strong>"]===>b
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('7: should render a flowchart when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`flowchart 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: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
expect(maxWidthValue).to.be.within(290 * 0.95 - 1, 290 * 1.05);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('8: should render a flowchart when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`flowchart 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: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||||
|
expect(width).to.be.within(290 * 0.95 - 1, 290 * 1.05);
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('V2 - 16: Render Stadium shape', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
` flowchart 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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('50: handle nested subgraphs in reverse order', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart LR
|
||||||
|
a -->b
|
||||||
|
subgraph A
|
||||||
|
B
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
b
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('51: handle nested subgraphs in reverse order', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart LR
|
||||||
|
a -->b
|
||||||
|
subgraph A
|
||||||
|
B
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
b
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('52: handle nested subgraphs in several levels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TB
|
||||||
|
b-->B
|
||||||
|
a-->c
|
||||||
|
subgraph O
|
||||||
|
A
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
c
|
||||||
|
end
|
||||||
|
subgraph A
|
||||||
|
a
|
||||||
|
b
|
||||||
|
B
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('53: handle nested subgraphs with edges in and out', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TB
|
||||||
|
internet
|
||||||
|
nat
|
||||||
|
routeur
|
||||||
|
lb1
|
||||||
|
lb2
|
||||||
|
compute1
|
||||||
|
compute2
|
||||||
|
subgraph project
|
||||||
|
routeur
|
||||||
|
nat
|
||||||
|
subgraph subnet1
|
||||||
|
compute1
|
||||||
|
lb1
|
||||||
|
end
|
||||||
|
subgraph subnet2
|
||||||
|
compute2
|
||||||
|
lb2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
internet --> routeur
|
||||||
|
routeur --> subnet1 & subnet2
|
||||||
|
subnet1 & subnet2 --> nat --> internet
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('54: handle nested subgraphs with outgoing links', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
subgraph main
|
||||||
|
subgraph subcontainer
|
||||||
|
subcontainer-child
|
||||||
|
end
|
||||||
|
subcontainer-child--> subcontainer-sibling
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('55: handle nested subgraphs with outgoing links 2', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
|
||||||
|
subgraph one[One]
|
||||||
|
subgraph sub_one[Sub One]
|
||||||
|
_sub_one
|
||||||
|
end
|
||||||
|
subgraph sub_two[Sub Two]
|
||||||
|
_sub_two
|
||||||
|
end
|
||||||
|
_one
|
||||||
|
end
|
||||||
|
|
||||||
|
%% here, either the first or the second one
|
||||||
|
sub_one --> sub_two
|
||||||
|
_one --> b
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('56: handle nested subgraphs with outgoing links 3', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TB
|
||||||
|
subgraph container_Beta
|
||||||
|
process_C-->Process_D
|
||||||
|
end
|
||||||
|
subgraph container_Alpha
|
||||||
|
process_A-->process_B
|
||||||
|
process_A-->|messages|process_C
|
||||||
|
end
|
||||||
|
process_B-->|via_AWSBatch|container_Beta
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('57: handle nested subgraphs with outgoing links 4', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart LR
|
||||||
|
subgraph A
|
||||||
|
a -->b
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
b
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('57: handle nested subgraphs with outgoing links 2', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TB
|
||||||
|
c1-->a2
|
||||||
|
subgraph one
|
||||||
|
a1-->a2
|
||||||
|
end
|
||||||
|
subgraph two
|
||||||
|
b1-->b2
|
||||||
|
end
|
||||||
|
subgraph three
|
||||||
|
c1-->c2
|
||||||
|
end
|
||||||
|
one --> two
|
||||||
|
three --> two
|
||||||
|
two --> c2
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('57.x: handle nested subgraphs with outgoing links 5', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`%% this does not produce the desired result
|
||||||
|
flowchart TB
|
||||||
|
subgraph container_Beta
|
||||||
|
process_C-->Process_D
|
||||||
|
end
|
||||||
|
subgraph container_Alpha
|
||||||
|
process_A-->process_B
|
||||||
|
process_B-->|via_AWSBatch|container_Beta
|
||||||
|
process_A-->|messages|process_C
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('58: handle styling with style expressions', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart LR
|
||||||
|
id1(Start)-->id2(Stop)
|
||||||
|
style id1 fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
|
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('59: handle styling of subgraphs and links', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] ==> D
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
A[Christmas] ==> C
|
||||||
|
subgraph T ["Test"]
|
||||||
|
A
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
|
||||||
|
classDef Test fill:#F84E68,stroke:#333,color:white;
|
||||||
|
class A,T Test
|
||||||
|
classDef TestSub fill:green;
|
||||||
|
class T TestSub
|
||||||
|
linkStyle 0,1 color:orange, stroke: orange;
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('60: handle styling for all node shapes - v2', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart LR
|
||||||
|
A[red text] -->|default style| B(blue text)
|
||||||
|
C([red text]) -->|default style| D[[blue text]]
|
||||||
|
E[(red text)] -->|default style| F((blue text))
|
||||||
|
G>red text] -->|default style| H{blue text}
|
||||||
|
I{{red text}} -->|default style| J[/blue text/]
|
||||||
|
K[\\ red text\\] -->|default style| L[/blue text\\]
|
||||||
|
M[\\ red text/] -->|default style| N[blue text];
|
||||||
|
linkStyle default color:Sienna;
|
||||||
|
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style D stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style F stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style H stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style J stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('61: fontawesome icons in edge labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart TD
|
||||||
|
C -->|fa:fa-car Car| F[fa:fa-car Car]
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('62: should render styled subgraphs', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart 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,color:darkred
|
||||||
|
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('63: title on subgraphs should be themable', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
|
||||||
|
flowchart LR
|
||||||
|
subgraph A
|
||||||
|
a --> b
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
i -->f
|
||||||
|
end
|
||||||
|
A --> B
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('65: text-color from classes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart LR
|
||||||
|
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
|
||||||
|
Lorem --> Ipsum --> Dolor
|
||||||
|
class Lorem,Dolor dark
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('66: More nested subgraph cases (TB)', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart TB
|
||||||
|
subgraph two
|
||||||
|
b1
|
||||||
|
end
|
||||||
|
subgraph three
|
||||||
|
c2
|
||||||
|
end
|
||||||
|
|
||||||
|
three --> two
|
||||||
|
two --> c2
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('67: More nested subgraph cases (RL)', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart RL
|
||||||
|
subgraph two
|
||||||
|
b1
|
||||||
|
end
|
||||||
|
subgraph three
|
||||||
|
c2
|
||||||
|
end
|
||||||
|
|
||||||
|
three --> two
|
||||||
|
two --> c2
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('68: More nested subgraph cases (BT)', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart BT
|
||||||
|
subgraph two
|
||||||
|
b1
|
||||||
|
end
|
||||||
|
subgraph three
|
||||||
|
c2
|
||||||
|
end
|
||||||
|
|
||||||
|
three --> two
|
||||||
|
two --> c2
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('69: More nested subgraph cases (LR)', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart LR
|
||||||
|
subgraph two
|
||||||
|
b1
|
||||||
|
end
|
||||||
|
subgraph three
|
||||||
|
c2
|
||||||
|
end
|
||||||
|
|
||||||
|
three --> two
|
||||||
|
two --> c2
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('70: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart TB
|
||||||
|
subgraph S1
|
||||||
|
sub1 -->sub2
|
||||||
|
end
|
||||||
|
subgraph S2
|
||||||
|
sub4
|
||||||
|
end
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('71: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart RL
|
||||||
|
subgraph S1
|
||||||
|
sub1 -->sub2
|
||||||
|
end
|
||||||
|
subgraph S2
|
||||||
|
sub4
|
||||||
|
end
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('72: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart BT
|
||||||
|
subgraph S1
|
||||||
|
sub1 -->sub2
|
||||||
|
end
|
||||||
|
subgraph S2
|
||||||
|
sub4
|
||||||
|
end
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('74: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart RL
|
||||||
|
subgraph S1
|
||||||
|
sub1 -->sub2
|
||||||
|
end
|
||||||
|
subgraph S2
|
||||||
|
sub4
|
||||||
|
end
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart RL
|
||||||
|
subgraph one
|
||||||
|
a1 -- l1 --> a2
|
||||||
|
a1 -- l2 --> a2
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('76: handle unicode encoded character with HTML labels true', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TB
|
||||||
|
a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
|
||||||
|
--> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('2050: handling of different rendering direction in subgraphs', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart LR
|
||||||
|
|
||||||
|
subgraph TOP
|
||||||
|
direction TB
|
||||||
|
subgraph B1
|
||||||
|
direction RL
|
||||||
|
i1 -->f1
|
||||||
|
end
|
||||||
|
subgraph B2
|
||||||
|
direction BT
|
||||||
|
i2 -->f2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
A --> TOP --> B
|
||||||
|
B1 --> B2
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/* eslint-env jest */
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||||
import { imgSnapshotTest } from '../../helpers/util';
|
|
||||||
|
|
||||||
describe('Flowcart', () => {
|
describe('Graph', () => {
|
||||||
it('1: should render a simple flowchart no htmlLabels', () => {
|
it('1: should render a simple flowchart no htmlLabels', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`graph TD
|
`graph TD
|
||||||
@@ -11,9 +10,10 @@ describe('Flowcart', () => {
|
|||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[fa:fa-car Car]
|
C -->|Three| F[fa:fa-car Car]
|
||||||
`,
|
`,
|
||||||
{ flowchart: { htmlLabels: false } }
|
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('2: should render a simple flowchart with htmlLabels', () => {
|
it('2: should render a simple flowchart with htmlLabels', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`graph TD
|
`graph TD
|
||||||
@@ -23,9 +23,10 @@ describe('Flowcart', () => {
|
|||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[fa:fa-car Car]
|
C -->|Three| F[fa:fa-car Car]
|
||||||
`,
|
`,
|
||||||
{ flowchart: { htmlLabels: true } }
|
{ flowchart: { htmlLabels: true }, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('3: should render a simple flowchart with line breaks', () => {
|
it('3: should render a simple flowchart with line breaks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -36,7 +37,7 @@ describe('Flowcart', () => {
|
|||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[Car]
|
C -->|Three| F[Car]
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -51,11 +52,11 @@ describe('Flowcart', () => {
|
|||||||
C -->|Two| E[\\iPhone\\]
|
C -->|Two| E[\\iPhone\\]
|
||||||
C -->|Three| F[Car]
|
C -->|Three| F[Car]
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('4: should style nodes via a class.', () => {
|
it('5: should style nodes via a class.', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph TD
|
graph TD
|
||||||
@@ -67,11 +68,11 @@ describe('Flowcart', () => {
|
|||||||
classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
|
classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
|
||||||
class 1A,1B,D,E processHead
|
class 1A,1B,D,E processHead
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('5: should render a flowchart full of circles', () => {
|
it('6: should render a flowchart full of circles', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph LR
|
graph LR
|
||||||
@@ -96,10 +97,11 @@ describe('Flowcart', () => {
|
|||||||
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
|
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
|
||||||
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
|
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('6: should render a flowchart full of icons', () => {
|
|
||||||
|
it('7: should render a flowchart full of icons', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph TD
|
graph TD
|
||||||
@@ -166,19 +168,20 @@ describe('Flowcart', () => {
|
|||||||
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||||
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('7: should render labels with numbers at the start', () => {
|
it('8: should render labels with numbers at the start', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph TB;subgraph "number as labels";1;end;
|
graph TB;subgraph "number as labels";1;end;
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('8: should render subgraphs', () => {
|
|
||||||
|
it('9: should render subgraphs', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph TB
|
graph TB
|
||||||
@@ -186,11 +189,11 @@ describe('Flowcart', () => {
|
|||||||
a1-->a2
|
a1-->a2
|
||||||
end
|
end
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('9: should render subgraphs with a title startign with a digit', () => {
|
it('10: should render subgraphs with a title starting with a digit', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph TB
|
graph TB
|
||||||
@@ -198,11 +201,11 @@ describe('Flowcart', () => {
|
|||||||
a1-->a2
|
a1-->a2
|
||||||
end
|
end
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('10: should render styled subgraphs', () => {
|
it('11: should render styled subgraphs', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph TB
|
graph TB
|
||||||
@@ -230,14 +233,14 @@ describe('Flowcart', () => {
|
|||||||
B-->G
|
B-->G
|
||||||
G-->D
|
G-->D
|
||||||
|
|
||||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F
|
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
|
||||||
style bar fill:#999,stroke-width:10px,stroke:#0F0
|
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('11: should render a flowchart with ling sames and class definitoins', () => {
|
it('12: should render a flowchart with long names and class definitions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`graph LR
|
`graph LR
|
||||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||||
@@ -335,11 +338,11 @@ describe('Flowcart', () => {
|
|||||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||||
`,
|
`,
|
||||||
{}
|
{ fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('12: should render color of styled nodes', () => {
|
it('13: should render color of styled nodes', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
graph LR
|
graph LR
|
||||||
@@ -352,8 +355,540 @@ describe('Flowcart', () => {
|
|||||||
{
|
{
|
||||||
listUrl: false,
|
listUrl: false,
|
||||||
listId: 'color styling',
|
listId: 'color styling',
|
||||||
logLevel: 0
|
fontFamily: 'courier',
|
||||||
|
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',
|
||||||
|
fontFamily: 'courier',
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('18: Chaining of nodes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph LR
|
||||||
|
a --> b --> c
|
||||||
|
`,
|
||||||
|
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('19: Multiple nodes and chaining in one statement', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph LR
|
||||||
|
a --> b & c--> d
|
||||||
|
`,
|
||||||
|
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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' }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 (open in same tab)"]
|
||||||
|
B["link test (open in new tab)"]
|
||||||
|
C[anchor test]
|
||||||
|
D[mailto test]
|
||||||
|
E[other protocol test]
|
||||||
|
F[script test]
|
||||||
|
TITLE --> A & B & C & D & E & F
|
||||||
|
click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
|
||||||
|
click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
|
||||||
|
click C "#link-clicked"
|
||||||
|
click D "mailto:user@user.user" "mailto test"
|
||||||
|
click E "notes://do-your-thing/id" "other protocol test"
|
||||||
|
click F "javascript:alert('test')" "script test"
|
||||||
|
`,
|
||||||
|
{ securityLevel: 'loose', fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 }, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('33: should render a simple flowchart with diagramPadding set to 0', () => {
|
||||||
|
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: { diagramPadding: 0 } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('34: testing the label width in percy', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph TD
|
||||||
|
A[Christmas]
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('35: should honor minimum edge length as specified by the user', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph TD
|
||||||
|
L1 --- L2
|
||||||
|
L2 --- C
|
||||||
|
M1 ---> C
|
||||||
|
R1 .-> R2
|
||||||
|
R2 <.-> C
|
||||||
|
C -->|Label 1| E1
|
||||||
|
C -- Label 2 ---> E2
|
||||||
|
C ----> E3
|
||||||
|
C -----> E4
|
||||||
|
C ======> E5
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('36: should render escaped without html labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph TD
|
||||||
|
a["<strong>Haiya</strong>"]-->b
|
||||||
|
`,
|
||||||
|
{ htmlLabels: false, flowchart: { htmlLabels: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('37: should render non-escaped with html labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`graph TD
|
||||||
|
a["<strong>Haiya</strong>"]-->b
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('38: should render a flowchart when useMaxWidth is true (default)', () => {
|
||||||
|
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]
|
||||||
|
`,
|
||||||
|
{ flowchart: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
expect(maxWidthValue).to.be.within(300 * 0.95, 300 * 1.05);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('39: should render a flowchart when useMaxWidth is 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]
|
||||||
|
`,
|
||||||
|
{ flowchart: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||||
|
expect(width).to.be.within(300 * 0.95, 300 * 1.05);
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('58: handle styling with style expressions', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
graph LR
|
||||||
|
id1(Start)-->id2(Stop)
|
||||||
|
style id1 fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
|
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('60: handle styling for all node shapes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
graph LR
|
||||||
|
A[red text] -->|default style| B(blue text)
|
||||||
|
C([red text]) -->|default style| D[[blue text]]
|
||||||
|
E[(red text)] -->|default style| F((blue text))
|
||||||
|
G>red text] -->|default style| H{blue text}
|
||||||
|
I{{red text}} -->|default style| J[/blue text/]
|
||||||
|
linkStyle default color:Sienna;
|
||||||
|
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('61: fontawesome icons in edge labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
graph TD
|
||||||
|
C -->|fa:fa-car Car| F[fa:fa-car Car]
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('62: fontawesome icons in edge labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
graph TB
|
||||||
|
subgraph bar[Bar]
|
||||||
|
F
|
||||||
|
end
|
||||||
|
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('63: fontawesome icons in edge labels', () => {
|
||||||
|
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,color:darkred
|
||||||
|
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('64: fontawesome icons in edge labels', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
|
||||||
|
flowchart LR
|
||||||
|
subgraph A
|
||||||
|
a --> b
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
i -->f
|
||||||
|
end
|
||||||
|
A --> B
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('65: text-color from classes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
flowchart LR
|
||||||
|
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
|
||||||
|
Lorem --> Ipsum --> Dolor
|
||||||
|
class Lorem,Dolor dark
|
||||||
|
`,
|
||||||
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
/* eslint-env jest */
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
|
||||||
|
|
||||||
describe('Sequencediagram', () => {
|
describe('Gantt diagram', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.clock(new Date('1010-10-10').getTime());
|
||||||
|
});
|
||||||
it('should render a gantt chart', () => {
|
it('should render a gantt chart', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -38,4 +40,255 @@ describe('Sequencediagram', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a gantt diagram when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ gantt: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
expect(maxWidthValue).to.be.within(984 * 0.95, 984 * 1.05);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a gantt diagram when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ gantt: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
|
||||||
|
expect(width).to.be.within(984 * 0.95, 984 * 1.05);
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should render a gantt diagram with data labels at the top when topAxis is true', () => {
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ gantt: { topAxis: true } }
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||||
|
|
||||||
describe('Sequencediagram', () => {
|
describe('Sequencediagram', () => {
|
||||||
it('should render a simple git graph', () => {
|
// it('should render a simple git graph', () => {
|
||||||
imgSnapshotTest(
|
// imgSnapshotTest(
|
||||||
`
|
// `
|
||||||
gitGraph:
|
// gitGraph:
|
||||||
commit
|
// commit
|
||||||
branch newbranch
|
// branch newbranch
|
||||||
checkout newbranch
|
// checkout newbranch
|
||||||
commit
|
// commit
|
||||||
commit
|
// commit
|
||||||
checkout master
|
// checkout master
|
||||||
commit
|
// commit
|
||||||
commit
|
// commit
|
||||||
merge newbranch`,
|
// merge newbranch`,
|
||||||
{ logLevel: 0 }
|
// { logLevel: 0 }
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||||
|
|
||||||
describe('Sequencediagram', () => {
|
describe('Sequencediagram', () => {
|
||||||
|
|||||||
66
cypress/integration/rendering/journey.spec.js
Normal file
66
cypress/integration/rendering/journey.spec.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { imgSnapshotTest, renderGraph } 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
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a user journey diagram when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`journey
|
||||||
|
title E-Commerce
|
||||||
|
section Order from website
|
||||||
|
Add to cart: 5: Me
|
||||||
|
section Checkout from website
|
||||||
|
Add payment details: 5: Me
|
||||||
|
`,
|
||||||
|
{ journey: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.eq(565);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
expect(maxWidthValue).to.eq(700);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a user journey diagram when useMaxWidth is false', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`journey
|
||||||
|
title E-Commerce
|
||||||
|
section Order from website
|
||||||
|
Add to cart: 5: Me
|
||||||
|
section Checkout from website
|
||||||
|
Add payment details: 5: Me
|
||||||
|
`,
|
||||||
|
{ journey: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
/* eslint-env jest */
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||||
import { imgSnapshotTest } from '../../helpers/util.js';
|
|
||||||
|
|
||||||
describe('Pie Chart', () => {
|
describe('Pie Chart', () => {
|
||||||
it('should render a simple pie diagram', () => {
|
it('should render a simple pie diagram', () => {
|
||||||
@@ -37,4 +36,43 @@ describe('Pie Chart', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
it('should render a pie diagram when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
pie title Sports in Sweden
|
||||||
|
"Bandy" : 40
|
||||||
|
"Ice-Hockey" : 80
|
||||||
|
"Football" : 90
|
||||||
|
`,
|
||||||
|
{ pie: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.eq(450);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
expect(maxWidthValue).to.eq(984);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should render a pie diagram when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
pie title Sports in Sweden
|
||||||
|
"Bandy" : 40
|
||||||
|
"Ice-Hockey" : 80
|
||||||
|
"Football" : 90
|
||||||
|
`,
|
||||||
|
{ pie: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
expect(height).to.eq(450);
|
||||||
|
expect(width).to.eq(984);
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
49
cypress/integration/rendering/requirement.spec.js
Normal file
49
cypress/integration/rendering/requirement.spec.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
|
||||||
|
|
||||||
|
describe('Requirement diagram', () => {
|
||||||
|
it('sample', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/// <reference types="Cypress" />
|
/// <reference types="Cypress" />
|
||||||
|
|
||||||
import { imgSnapshotTest } from '../../helpers/util';
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||||
|
|
||||||
context('Aliasing', () => {
|
context('Sequence diagram', () => {
|
||||||
it('should render a simple sequence diagrams', () => {
|
it('should render a simple sequence diagram', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
@@ -28,10 +28,270 @@ context('Aliasing', () => {
|
|||||||
and
|
and
|
||||||
Alice -->> John: Parallel message 2
|
Alice -->> John: Parallel message 2
|
||||||
end
|
end
|
||||||
|
`,
|
||||||
|
{ sequence: { actorFontFamily: 'courier' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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 handle line breaks and wrap annotations', () => {
|
||||||
|
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?
|
||||||
|
Note right of John: John thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
|
||||||
|
Bob-->Alice: Checking with John...
|
||||||
|
Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
|
||||||
|
Bob-x John: Hey John -<br/>we're still waiting to know<br/>how you're doing
|
||||||
|
Note over John:nowrap: John's trying hard not to break his train of thought.
|
||||||
|
Bob-x John:wrap: John! Are you still debating about how you're doing? How long does it take??
|
||||||
|
Note over John: After a few more moments, John<br/>finally snaps out of it.
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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: 'times' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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 be possible to use actor symbols instead of boxes', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
sequenceDiagram
|
||||||
|
actor Alice
|
||||||
|
actor Bob
|
||||||
|
Alice->>Bob: Hi Bob
|
||||||
|
Bob->>Alice: Hi Alice
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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', () => {
|
context('background rects', () => {
|
||||||
it('should render a single and nested rects', () => {
|
it('should render a single and nested rects', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
@@ -64,6 +324,69 @@ context('Aliasing', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
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', () => {
|
it('should render rect around and inside loops', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -129,5 +452,242 @@ context('Aliasing', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
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 override 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 override 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' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
context('links', () => {
|
||||||
|
it('should support actor links and properties EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||||
|
//Be aware that the syntax for "properties" is likely to be changed.
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { "config": { "mirrorActors": true, "forceMenus": true }}}%%
|
||||||
|
sequenceDiagram
|
||||||
|
participant a as Alice
|
||||||
|
participant j as John
|
||||||
|
note right of a: Hello world!
|
||||||
|
properties a: {"class": "internal-service-actor", "type": "@clock"}
|
||||||
|
properties j: {"class": "external-service-actor", "type": "@computer"}
|
||||||
|
links a: {"Repo": "https://www.contoso.com/repo", "Swagger": "https://www.contoso.com/swagger"}
|
||||||
|
links j: {"Repo": "https://www.contoso.com/repo"}
|
||||||
|
links a: {"Dashboard": "https://www.contoso.com/dashboard", "On-Call": "https://www.contoso.com/oncall"}
|
||||||
|
link a: Contacts @ https://contacts.contoso.com/?contact=alice@contoso.com
|
||||||
|
a->>j: Hello John, how are you?
|
||||||
|
j-->>a: Great!
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||||
|
//Be aware that the syntax for "properties" is likely to be changed.
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { "config": { "mirrorActors": false, "forceMenus": true, "wrap": true }}}%%
|
||||||
|
sequenceDiagram
|
||||||
|
participant a as Alice
|
||||||
|
participant j as John
|
||||||
|
note right of a: Hello world!
|
||||||
|
properties a: {"class": "internal-service-actor", "type": "@clock"}
|
||||||
|
properties j: {"class": "external-service-actor", "type": "@computer"}
|
||||||
|
links a: {"Repo": "https://www.contoso.com/repo", "Swagger": "https://www.contoso.com/swagger"}
|
||||||
|
links j: {"Repo": "https://www.contoso.com/repo"}
|
||||||
|
links a: {"Dashboard": "https://www.contoso.com/dashboard", "On-Call": "https://www.contoso.com/oncall"}
|
||||||
|
a->>j: Hello John, how are you?
|
||||||
|
j-->>a: Great!
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
context('svg size', () => {
|
||||||
|
it('should render a sequence diagram when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ sequence: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.be.within(920, 960);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should render a sequence diagram when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ sequence: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
expect(height).to.be.within(920, 960);
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(width).to.be.within(820 * 0.95, 820 * 1.05);
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
497
cypress/integration/rendering/stateDiagram-v2.spec.js
Normal file
497
cypress/integration/rendering/stateDiagram-v2.spec.js
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||||
|
|
||||||
|
describe('State diagram', () => {
|
||||||
|
it('v2 should render a simple info', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
info
|
||||||
|
`,
|
||||||
|
{ logLevel: 1, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('v2 should render a simple state diagrams', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('v2 should render a single state with short descriptions', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
state "A long long name" as long1
|
||||||
|
state "A" as longlonglongid
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('v2 should render a transition descriptions 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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('v2 should render a simple state diagrams', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> State2
|
||||||
|
State1 --> State3
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('v2 should render composite 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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('v2 should render multiple composite 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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 should render forks in composite 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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
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 it should be possibel to use a choice', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> Off
|
||||||
|
Off --> On
|
||||||
|
state MyChoice [[choice]]
|
||||||
|
On --> MyChoice
|
||||||
|
MyChoice --> Washing
|
||||||
|
MyChoice --> Drying
|
||||||
|
Washing --> Finished
|
||||||
|
Finished --> [*]
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 width of compond state should grow with title if title is wider', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
state "Long state name 2" as NotShooting {
|
||||||
|
a-->b
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 state label with names in it', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
Yswsii: Your state with spaces in it
|
||||||
|
[*] --> Yswsii
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 Simplest composite state', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
state Parent {
|
||||||
|
C
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 should handle multiple arrows from one node to another', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
a --> b: Start
|
||||||
|
a --> b: Stop
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 should handle multiple notes added to one state', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
MyState
|
||||||
|
note left of MyState : I am a leftie
|
||||||
|
note right of MyState : I am a rightie
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 should handle different rendering directions in composite states', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
direction LR
|
||||||
|
state A {
|
||||||
|
direction BT
|
||||||
|
a --> b
|
||||||
|
}
|
||||||
|
state C {
|
||||||
|
direction RL
|
||||||
|
c --> d
|
||||||
|
}
|
||||||
|
A --> C
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 handle transition from one state in a composite state to a composite state', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
state S1 {
|
||||||
|
sub1 -->sub2
|
||||||
|
}
|
||||||
|
|
||||||
|
state S2 {
|
||||||
|
sub4
|
||||||
|
}
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('v2 should render a state diagram when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{ state: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.be.within(177, 178);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(maxWidthValue).to.be.within(135 * 0.95, 135 * 1.05);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('v2 should render a state diagram when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
stateDiagram-v2
|
||||||
|
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{ state: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
expect(height).to.be.within(177, 178);
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
expect(width).to.be.within(135 * 0.95, 135 * 1.05);
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
/* eslint-env jest */
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
|
||||||
import { imgSnapshotTest } from '../../helpers/util';
|
|
||||||
|
|
||||||
describe('State diagram', () => {
|
describe('State diagram', () => {
|
||||||
it('should render a simple state diagrams', () => {
|
it('should render a simple state diagrams', () => {
|
||||||
@@ -9,7 +8,7 @@ describe('State diagram', () => {
|
|||||||
[*] --> State1
|
[*] --> State1
|
||||||
State1 --> [*]
|
State1 --> [*]
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -21,7 +20,7 @@ describe('State diagram', () => {
|
|||||||
[*] --> S1
|
[*] --> S1
|
||||||
state "Some long name" as S1
|
state "Some long name" as S1
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -33,22 +32,22 @@ describe('State diagram', () => {
|
|||||||
[*] --> S1
|
[*] --> S1
|
||||||
state "Some long name" as S1: The description
|
state "Some long name" as S1: The description
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
it('should render a single state with short descr', () => {
|
it('should render a single state with short descriptions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
stateDiagram
|
stateDiagram
|
||||||
state "A long long name" as long1
|
state "A long long name" as long1
|
||||||
state "A" as longlonglongid
|
state "A" as longlonglongid
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
it('should render a transition descrions with new lines', () => {
|
it('should render a transition descriptions with new lines', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
stateDiagram
|
stateDiagram
|
||||||
@@ -58,7 +57,7 @@ describe('State diagram', () => {
|
|||||||
S1 --> S3: long line using <br>should work
|
S1 --> S3: long line using <br>should work
|
||||||
S1 --> S4: long line using \\nshould work
|
S1 --> S4: long line using \\nshould work
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -72,7 +71,7 @@ describe('State diagram', () => {
|
|||||||
notes.
|
notes.
|
||||||
end note
|
end note
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -86,7 +85,7 @@ describe('State diagram', () => {
|
|||||||
notes with . and in them.
|
notes with . and in them.
|
||||||
end note
|
end note
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -102,10 +101,38 @@ describe('State diagram', () => {
|
|||||||
State1 --> State2 : With +,-
|
State1 --> State2 : With +,-
|
||||||
note left of State2 : This is the note +,-<br/>
|
note left of State2 : This is the note +,-<br/>
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
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
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should render a states with descriptions including multi-line descriptions', () => {
|
it('should render a states with descriptions including multi-line descriptions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -117,7 +144,7 @@ describe('State diagram', () => {
|
|||||||
State1 --> State2
|
State1 --> State2
|
||||||
State2 --> [*]
|
State2 --> [*]
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -130,7 +157,7 @@ describe('State diagram', () => {
|
|||||||
State1 --> State3
|
State1 --> State3
|
||||||
State1 --> [*]
|
State1 --> [*]
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -146,7 +173,7 @@ describe('State diagram', () => {
|
|||||||
State2 --> State3 : Transition 5
|
State2 --> State3 : Transition 5
|
||||||
State1 --> [*]
|
State1 --> [*]
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -159,11 +186,11 @@ describe('State diagram', () => {
|
|||||||
XState2 : New line
|
XState2 : New line
|
||||||
XState1 --> XState2
|
XState1 --> XState2
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
it('should render composit states', () => {
|
it('should render composite states', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
stateDiagram
|
stateDiagram
|
||||||
@@ -178,7 +205,7 @@ describe('State diagram', () => {
|
|||||||
Configuring --> Idle : EvConfig EvConfig EvConfig EvConfig EvConfig
|
Configuring --> Idle : EvConfig EvConfig EvConfig EvConfig EvConfig
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
@@ -208,7 +235,7 @@ describe('State diagram', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should render forks in composit states', () => {
|
it('should render forks in composit states', () => {
|
||||||
@@ -230,7 +257,7 @@ describe('State diagram', () => {
|
|||||||
State4 --> [*]
|
State4 --> [*]
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should render forks and joins', () => {
|
it('should render forks and joins', () => {
|
||||||
@@ -248,11 +275,11 @@ describe('State diagram', () => {
|
|||||||
join_state --> State4
|
join_state --> State4
|
||||||
State4 --> [*]
|
State4 --> [*]
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
it('should render conurrency states', () => {
|
it('should render concurrency states', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
stateDiagram
|
stateDiagram
|
||||||
@@ -272,8 +299,95 @@ describe('State diagram', () => {
|
|||||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
{ logLevel: 0 }
|
{ logLevel: 0, fontFamily: 'courier' }
|
||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
it('should render a state with states in it', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
state PilotCockpit {
|
||||||
|
state Parent {
|
||||||
|
C
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('Simplest composite state', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
state Parent {
|
||||||
|
C
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should handle multiple arrows from one node to another', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
a --> b: Start
|
||||||
|
a --> b: Stop
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
logLevel: 0,
|
||||||
|
fontFamily: 'courier',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render a state diagram when useMaxWidth is true (default)', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{ state: { useMaxWidth: true } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
expect(svg).to.have.attr('width', '100%');
|
||||||
|
expect(svg).to.have.attr('height');
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
expect(height).to.be.within(176, 178);
|
||||||
|
const style = svg.attr('style');
|
||||||
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
// Todo investigate difference
|
||||||
|
// expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
|
||||||
|
expect(maxWidthValue).to.be.within(130, 140);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should render a state diagram when useMaxWidth is false', () => {
|
||||||
|
renderGraph(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
[*] --> State1
|
||||||
|
State1 --> [*]
|
||||||
|
`,
|
||||||
|
{ state: { useMaxWidth: false } }
|
||||||
|
);
|
||||||
|
cy.get('svg').should((svg) => {
|
||||||
|
const height = parseFloat(svg.attr('height'));
|
||||||
|
const width = parseFloat(svg.attr('width'));
|
||||||
|
expect(height).to.be.within(176, 178);
|
||||||
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
|
// Todo investigate difference
|
||||||
|
// expect(width).to.be.within(112 * .95, 112 * 1.05);
|
||||||
|
expect(width).to.be.within(130, 140);
|
||||||
|
|
||||||
|
expect(svg).to.not.have.attr('style');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
279
cypress/integration/rendering/theme.spec.js
Normal file
279
cypress/integration/rendering/theme.spec.js
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
import { imgSnapshotTest } from '../../helpers/util.js';
|
||||||
|
|
||||||
|
describe('Pie Chart', () => {
|
||||||
|
// beforeEach(()=>{
|
||||||
|
// cy.clock((new Date('2014-06-09')).getTime());
|
||||||
|
// });
|
||||||
|
|
||||||
|
['default', 'forest', 'dark', 'neutral'].forEach((theme) => {
|
||||||
|
describe(theme, () => {
|
||||||
|
it('should render a pie diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
pie title Sports in Sweden
|
||||||
|
"Bandy" : 40
|
||||||
|
"Ice-Hockey" : 80
|
||||||
|
"Football" : 90
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a flowchart diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0} }%%
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a new flowchart diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a sequence diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a class diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||||
|
classDiagram
|
||||||
|
Animal "*" <|-- "1" Duck
|
||||||
|
Animal "1" <|-- "10" Fish
|
||||||
|
Animal <|-- Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
classA <|-- classB
|
||||||
|
classC *-- classD
|
||||||
|
classE o-- classF
|
||||||
|
classG <-- classH
|
||||||
|
classI -- classJ
|
||||||
|
classK <.. classL
|
||||||
|
classM <|.. classN
|
||||||
|
classO .. classP
|
||||||
|
classA --|> classB : Inheritance
|
||||||
|
classC --* classD : Composition
|
||||||
|
classE --o classF : Aggregation
|
||||||
|
classG --> classH : Association
|
||||||
|
classI -- classJ : Link(Solid)
|
||||||
|
classK ..> classL : Dependency
|
||||||
|
classM ..|> classN : Realization
|
||||||
|
classO .. classP : Link(Dashed)
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a state diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a state diagram (v2)', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a 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"
|
||||||
|
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a user journey diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
%%{init: { 'logLevel': 0, 'theme': '${theme}'} }%%
|
||||||
|
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: 5: Me
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
it('should render a gantt diagram', () => {
|
||||||
|
cy.clock(new Date('2014-01-06').getTime());
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title :Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
{ theme }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,10 +1,61 @@
|
|||||||
import mermaid from '../../dist/mermaid.core'
|
import mermaid from '../../dist/mermaid.core';
|
||||||
|
|
||||||
|
let code = `flowchart LR
|
||||||
|
Power_Supply --> Transmitter_A
|
||||||
|
Power_Supply --> Transmitter_B
|
||||||
|
Transmitter_A --> D
|
||||||
|
Transmitter_B --> D`;
|
||||||
|
|
||||||
|
let code2 = `gantt
|
||||||
|
dateFormat YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality 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`;
|
||||||
|
|
||||||
|
const code3 = `flowchart TD
|
||||||
|
A(<img scr='https://iconscout.com/ms-icon-310x310.png' width='20' height='20' />)
|
||||||
|
B(<b>Bold text!</b>)`;
|
||||||
|
|
||||||
|
if (location.href.match('test-html-escaping')) {
|
||||||
|
code = code3;
|
||||||
|
}
|
||||||
|
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
theme: 'forest',
|
theme: 'default',
|
||||||
gantt: { axisFormatter: [
|
// fontFamily: '"Lucida Console", Monaco, monospace',
|
||||||
['%Y-%m-%d', (d) => {
|
startOnLoad: false,
|
||||||
return d.getDay() === 1
|
securityLevel: 'loose',
|
||||||
}]
|
flowchart: {
|
||||||
] }
|
htmlLabels: true,
|
||||||
})
|
},
|
||||||
|
gantt: {
|
||||||
|
axisFormatter: [
|
||||||
|
[
|
||||||
|
'%Y-%m-%d',
|
||||||
|
(d) => {
|
||||||
|
return d.getDay() === 1;
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
mermaid.render(
|
||||||
|
'the-id-of-the-svg',
|
||||||
|
code,
|
||||||
|
(svg) => {
|
||||||
|
console.log(svg);
|
||||||
|
const elem = document.querySelector('#graph-to-be');
|
||||||
|
elem.innerHTML = svg;
|
||||||
|
}
|
||||||
|
// ,document.querySelector('#tmp')
|
||||||
|
);
|
||||||
|
|||||||
139
cypress/platform/class.html
Normal file
139
cypress/platform/class.html
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
|
||||||
|
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: white;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.customCss > rect, .customCss{
|
||||||
|
fill:#FF0000 !important;
|
||||||
|
stroke:#FFFF00 !important;
|
||||||
|
stroke-width:4px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>info below</h1>
|
||||||
|
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||||
|
%%{init: {'theme': 'base', 'fontFamily': 'courier', 'themeVariables': { 'primaryColor': '#fff000'}}}%%
|
||||||
|
classDiagram
|
||||||
|
class BankAccount{
|
||||||
|
+String owner
|
||||||
|
+BigDecimal balance
|
||||||
|
+deposit(amount) bool
|
||||||
|
+withdrawl(amount) int
|
||||||
|
}
|
||||||
|
cssClass "BankAccount" customCss
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||||
|
%%{init: {'theme': 'base', 'fontFamily': 'courier', 'themeVariables': { 'primaryColor': '#fff000'}}}%%
|
||||||
|
classDiagram-v2
|
||||||
|
class BankAccount{
|
||||||
|
+String owner
|
||||||
|
+BigDecimal balance
|
||||||
|
+deposit(amount) bool
|
||||||
|
+withdrawl(amount) int
|
||||||
|
}
|
||||||
|
cssClass "BankAccount" customCss
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||||
|
%%{init: {'theme': 'base', 'fontFamily': 'courier', 'themeVariables': { 'primaryColor': '#fff000'}}}%%
|
||||||
|
classDiagram
|
||||||
|
class BankAccount{
|
||||||
|
+String owner
|
||||||
|
+BigDecimal balance
|
||||||
|
+deposit(amount) bool
|
||||||
|
+withdrawl(amount) int
|
||||||
|
}
|
||||||
|
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 "callback" "A Tooltip"
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||||
|
flowchart 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>
|
||||||
|
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||||
|
classDiagram-v2
|
||||||
|
|
||||||
|
classA -- classB : Inheritance
|
||||||
|
classA -- classC : link
|
||||||
|
classC -- classD : link
|
||||||
|
classB -- classD
|
||||||
|
classA --|> classB : Inheritance
|
||||||
|
classC --* classD : Composition
|
||||||
|
classE --o classF : Aggregation
|
||||||
|
classG --> classH : Association
|
||||||
|
classI -- classJ : Link(Solid)
|
||||||
|
classK ..> classL : Dependency
|
||||||
|
classM ..|> classN : Realization
|
||||||
|
classO .. classP : Link(Dashed)
|
||||||
|
classA : +attr1
|
||||||
|
classA : attr2
|
||||||
|
classA : method1()
|
||||||
|
<<interface>> classB
|
||||||
|
classB : method2() int
|
||||||
|
|
||||||
|
Customer "1" --> "*" Ticket
|
||||||
|
Student "1" --> "1..*" Course
|
||||||
|
Galaxy --> "many" Star : Contains
|
||||||
|
<<interface>> Customer
|
||||||
|
|
||||||
|
class Shape
|
||||||
|
callback Shape "callbackFunction" "This is a tooltip for a callback"
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'default',
|
||||||
|
// arrowMarkerAbsolute: true,
|
||||||
|
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||||
|
logLevel: 0,
|
||||||
|
flowchart: { curve: 'linear', "htmlLabels": true },
|
||||||
|
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
|
sequence: { actorMargin: 50, showSequenceNumbers: true },
|
||||||
|
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||||
|
// fontFamily: '"arial", sans-serif',
|
||||||
|
// themeVariables: {
|
||||||
|
// fontFamily: '"arial", sans-serif',
|
||||||
|
// },
|
||||||
|
curve: 'linear',
|
||||||
|
securityLevel: 'loose'
|
||||||
|
});
|
||||||
|
function callback(){alert('It worked');}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -5,8 +5,14 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<title>Mermaid Quick Test Page</title>
|
<title>Mermaid Quick Test Page</title>
|
||||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||||
|
<style>
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div style="display: flex">
|
||||||
<div id="FirstLine" class="mermaid">
|
<div id="FirstLine" class="mermaid">
|
||||||
graph TB
|
graph TB
|
||||||
Function-->URL
|
Function-->URL
|
||||||
@@ -15,9 +21,38 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="FirstLine" class="mermaid">
|
<div id="FirstLine" class="mermaid">
|
||||||
graph TB
|
graph TB
|
||||||
1Function-->2URL
|
1Function--->2URL
|
||||||
click 1Function clickByFlow "Add a div"
|
click 1Function clickByFlow "Add a div"
|
||||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||||
|
</div>
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
flowchart TB
|
||||||
|
Function-->URL
|
||||||
|
click Function clickByFlow "Add a div"
|
||||||
|
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>" _self
|
||||||
|
</div>
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
flowchart TB
|
||||||
|
1Function--->2URL
|
||||||
|
click 1Function clickByFlow "Add a div"
|
||||||
|
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>" _self
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
classDiagram
|
||||||
|
class ShapeLink
|
||||||
|
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||||
|
class ShapeCallback
|
||||||
|
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||||
|
</div>
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
classDiagram-v2
|
||||||
|
class ShapeLink2
|
||||||
|
link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||||
|
class ShapeCallback2
|
||||||
|
callback ShapeCallback2 "clickByClass" "This is a tooltip for a callback"
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
@@ -49,15 +84,48 @@
|
|||||||
section Clickable
|
section Clickable
|
||||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
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 (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 cl1 href "http://localhost:9000/webpackUsage.html"
|
||||||
click cl2 call clickByGantt("test", test, test)
|
click cl2 call clickByGantt()
|
||||||
|
click cl3 call clickByGantt("test1", test2, test3)
|
||||||
|
|
||||||
section Last section
|
section Last section
|
||||||
Describe gantt syntax :after doc1, 3d
|
Describe gantt syntax :after doc1, 3d
|
||||||
Add gantt diagram to demo page : 20h
|
Add gantt diagram to demo page : 20h
|
||||||
Add another diagram to demo page : 48h
|
Add another diagram to demo page : 48h
|
||||||
</div>
|
</div>
|
||||||
|
<div style="display: flex">
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
graph TB
|
||||||
|
FunctionArg-->URL
|
||||||
|
click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
|
||||||
|
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||||
|
</div>
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
flowchart TB
|
||||||
|
FunctionArg-->URL
|
||||||
|
click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
|
||||||
|
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
classDiagram
|
||||||
|
class ShapeLink
|
||||||
|
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||||
|
class ShapeCallback
|
||||||
|
click ShapeCallback call clickByClass(123) "This is a tooltip for a callback"
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
classDiagram-v2
|
||||||
|
class ShapeLink2
|
||||||
|
link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||||
|
class ShapeCallback2
|
||||||
|
click ShapeCallback2 call clickByClass(123) "This is a tooltip for a callback"
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="./mermaid.js"></script>
|
<script src="./mermaid.js"></script>
|
||||||
<script>
|
<script>
|
||||||
@@ -69,11 +137,30 @@
|
|||||||
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(div)
|
document.getElementsByTagName('body')[0].appendChild(div)
|
||||||
}
|
}
|
||||||
function clickByGantt(elemName) {
|
function clickByFlowArg(argument) {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.className = 'created-by-click-2'
|
||||||
|
div.style = 'padding: 20px; background: green; color: white;'
|
||||||
|
div.innerText = 'Clicked By Flow: ' + argument
|
||||||
|
|
||||||
|
document.getElementsByTagName('body')[0].appendChild(div)
|
||||||
|
}
|
||||||
|
function clickByGantt(arg1, arg2, arg3) {
|
||||||
const div = document.createElement('div')
|
const div = document.createElement('div')
|
||||||
div.className = 'created-by-gant-click'
|
div.className = 'created-by-gant-click'
|
||||||
div.style = 'padding: 20px; background: green; color: white;'
|
div.style = 'padding: 20px; background: green; color: white;'
|
||||||
div.innerText = 'Clicked By Gant'
|
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)
|
||||||
|
}
|
||||||
|
function clickByClass(arg) {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.className = 'created-by-class-click'
|
||||||
|
div.style = 'padding: 20px; background: purple; color: white;'
|
||||||
|
div.innerText = 'Clicked By Class' + (arg?arg:'')
|
||||||
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(div)
|
document.getElementsByTagName('body')[0].appendChild(div)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,11 @@
|
|||||||
section Clickable
|
section Clickable
|
||||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
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 (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 cl1 href "http://localhost:9000/webpackUsage.html"
|
||||||
click cl2 call clickByGantt("test", test, test)
|
click cl2 call clickByGantt()
|
||||||
|
click cl3 call clickByGantt("test1", test2, test3)
|
||||||
|
|
||||||
section Last section
|
section Last section
|
||||||
Describe gantt syntax :after doc1, 3d
|
Describe gantt syntax :after doc1, 3d
|
||||||
@@ -69,11 +71,14 @@
|
|||||||
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(div)
|
document.getElementsByTagName('body')[0].appendChild(div)
|
||||||
}
|
}
|
||||||
function clickByGantt(elemName) {
|
function clickByGantt(arg1, arg2, arg3) {
|
||||||
const div = document.createElement('div')
|
const div = document.createElement('div')
|
||||||
div.className = 'created-by-gant-click'
|
div.className = 'created-by-gant-click'
|
||||||
div.style = 'padding: 20px; background: green; color: white;'
|
div.style = 'padding: 20px; background: green; color: white;'
|
||||||
div.innerText = 'Clicked By Gant'
|
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)
|
document.getElementsByTagName('body')[0].appendChild(div)
|
||||||
}
|
}
|
||||||
|
|||||||
177
cypress/platform/current.html
Normal file
177
cypress/platform/current.html
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
<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="mermaid2" 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="mermaid2" 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="mermaid2" style="width: 50%; height: 40%;">
|
||||||
|
%% this does not produce the desired result
|
||||||
|
flowchart TB
|
||||||
|
subgraph container_Beta
|
||||||
|
process_C-->Process_D
|
||||||
|
end
|
||||||
|
subgraph container_Alpha
|
||||||
|
process_A-->process_B
|
||||||
|
process_B-->|via_AWSBatch|container_Beta
|
||||||
|
process_A-->|messages|process_C
|
||||||
|
end
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid" style="width: 50%; height: 40%;">
|
||||||
|
flowchart TB
|
||||||
|
a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
|
||||||
|
--> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 50%;">
|
||||||
|
flowchart TB
|
||||||
|
internet
|
||||||
|
nat
|
||||||
|
routeur
|
||||||
|
lb1
|
||||||
|
lb2
|
||||||
|
compute1
|
||||||
|
compute2
|
||||||
|
subgraph project
|
||||||
|
routeur
|
||||||
|
nat
|
||||||
|
subgraph subnet1
|
||||||
|
compute1
|
||||||
|
lb1
|
||||||
|
end
|
||||||
|
subgraph subnet2
|
||||||
|
compute2
|
||||||
|
lb2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
internet --> routeur
|
||||||
|
routeur --> subnet1 & subnet2
|
||||||
|
subnet1 & subnet2 --> nat --> internet
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 50%;">
|
||||||
|
flowchart TD
|
||||||
|
|
||||||
|
subgraph one[One]
|
||||||
|
subgraph sub_one[Sub One]
|
||||||
|
_sub_one
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph two[Two]
|
||||||
|
_two
|
||||||
|
end
|
||||||
|
|
||||||
|
sub_one --> two
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 50%;">
|
||||||
|
flowchart TD
|
||||||
|
|
||||||
|
subgraph one[One]
|
||||||
|
subgraph sub_one[Sub One]
|
||||||
|
_sub_one
|
||||||
|
end
|
||||||
|
subgraph sub_two[Sub Two]
|
||||||
|
_sub_two
|
||||||
|
end
|
||||||
|
_one
|
||||||
|
end
|
||||||
|
|
||||||
|
%% here, either the first or the second one
|
||||||
|
sub_one --> sub_two
|
||||||
|
_one --> b
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
// theme: 'forest',
|
||||||
|
// themeVariables:{primaryColor: '#ff0000'},
|
||||||
|
// arrowMarkerAbsolute: true,
|
||||||
|
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||||
|
logLevel: 0,
|
||||||
|
flowchart: { curve: 'cardinal', "htmlLabels": true },
|
||||||
|
// 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>
|
||||||
129
cypress/platform/current2.html
Normal file
129
cypress/platform/current2.html
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<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="mermaid2" 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="mermaid2" 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="mermaid2" style="width: 50%; height: 20%;">
|
||||||
|
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
|
||||||
|
flowchart LR
|
||||||
|
a -->b
|
||||||
|
subgraph A
|
||||||
|
B
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
b
|
||||||
|
end
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid" style="width: 50%; height: 20%;">
|
||||||
|
flowchart TB
|
||||||
|
subgraph A
|
||||||
|
b-->B
|
||||||
|
a-->c
|
||||||
|
end
|
||||||
|
subgraph B
|
||||||
|
c
|
||||||
|
end
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||||
|
sequenceDiagram
|
||||||
|
Alice->Bob: Hello Bob, how are you?
|
||||||
|
Note over Alice,Bob: Looks
|
||||||
|
Note over Bob,Alice: Looks back
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
// theme: 'forest',
|
||||||
|
// themeVariables:{primaryColor: '#ff0000'},
|
||||||
|
// 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>
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<!-- <meta charset="iso-8859-15"/> -->
|
||||||
<script src="/e2e.js"></script>
|
<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=Mansalva&display=swap" rel="stylesheet" /> -->
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
/* font-family: 'Mansalva', cursive;
|
/* font-family: 'Mansalva', cursive;*/
|
||||||
font-family: 'Mansalva', cursive; */
|
/* font-family: 'Mansalva', cursive; */
|
||||||
font-family: 'times';
|
/* font-family: 'arial'; */
|
||||||
|
/* font-family: "trebuchet ms", verdana, arial; */
|
||||||
}
|
}
|
||||||
|
/* div {
|
||||||
|
font-family: 'arial';
|
||||||
|
} */
|
||||||
/* .mermaid-main-font {
|
/* .mermaid-main-font {
|
||||||
font-family: "trebuchet ms", verdana, arial;
|
font-family: "trebuchet ms", verdana, arial;
|
||||||
font-family: var(--mermaid-font-family);
|
font-family: var(--mermaid-font-family);
|
||||||
@@ -20,6 +27,9 @@
|
|||||||
svg {
|
svg {
|
||||||
border: 2px solid darkred;
|
border: 2px solid darkred;
|
||||||
}
|
}
|
||||||
|
.exClass2 > rect, .exClass {
|
||||||
|
fill: greenyellow !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -27,14 +37,16 @@
|
|||||||
<script>
|
<script>
|
||||||
// Notice startOnLoad=false
|
// Notice startOnLoad=false
|
||||||
// This prevents default handling in mermaid from render before the e2e logic is applied
|
// This prevents default handling in mermaid from render before the e2e logic is applied
|
||||||
mermaid.initialize({
|
// mermaid.initialize({
|
||||||
startOnLoad: false,
|
// startOnLoad: false,
|
||||||
useMaxWidth: true,
|
// useMaxWidth: true,
|
||||||
// "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
|
// // "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
|
||||||
// fontFamily: '\"trebuchet ms\", verdana, arial;'
|
// // fontFamily: '\"trebuchet ms\", verdana, arial;'
|
||||||
// fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
|
// // fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
|
||||||
fontFamily: '"Mansalva", cursive'
|
// // fontFamily: '"Mansalva", cursive',
|
||||||
});
|
// // fontFamily: '"Noto Sans SC", sans-serif'
|
||||||
|
// fontFamily: '"Noto Sans SC", sans-serif'
|
||||||
|
// });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
6
cypress/platform/exploit.js
Normal file
6
cypress/platform/exploit.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const div = parent.document.createElement('div');
|
||||||
|
div.id = 'the-malware';
|
||||||
|
div.className = 'malware';
|
||||||
|
div.innerHTML = 'XSS Succeeded';
|
||||||
|
parent.document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
|
throw new Error('XSS Succeded');
|
||||||
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
122
cypress/platform/interaction.html
Normal file
122
cypress/platform/interaction.html
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<!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>
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="display: flex">
|
||||||
|
<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="mermaid2">
|
||||||
|
graph TB
|
||||||
|
1Function-->2URL
|
||||||
|
click 1Function clickByFlow "Add a div"
|
||||||
|
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="FirstLine" class="mermaid2">
|
||||||
|
classDiagram
|
||||||
|
class Test
|
||||||
|
class ShapeLink
|
||||||
|
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||||
|
class ShapeCallback
|
||||||
|
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||||
|
</div>
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
classDiagram-v2
|
||||||
|
class ShapeCallback
|
||||||
|
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||||
|
</div>
|
||||||
|
<div id="FirstLine" class="mermaid">
|
||||||
|
classDiagram-v2
|
||||||
|
class ShapeLink
|
||||||
|
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mermaid2">
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
function clickByClass() {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.className = 'created-by-class-click'
|
||||||
|
div.style = 'padding: 20px; background: purple; color: white;'
|
||||||
|
div.innerText = 'Clicked By Class'
|
||||||
|
|
||||||
|
document.getElementsByTagName('body')[0].appendChild(div)
|
||||||
|
}
|
||||||
|
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
69
cypress/platform/knsv.html
Normal file
69
cypress/platform/knsv.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<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';
|
||||||
|
/* font-size: 18px !important; */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2,.mermaid3 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.mermaid svg {
|
||||||
|
/* font-size: 18px !important; */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>info below</div>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
|
||||||
|
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> S1
|
||||||
|
state "Some long name" as S1
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
// theme: 'dark',
|
||||||
|
theme: 'forest',
|
||||||
|
arrowMarkerAbsolute: true,
|
||||||
|
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||||
|
logLevel: 2,
|
||||||
|
flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: false },
|
||||||
|
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
|
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
|
||||||
|
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||||
|
// fontFamily: '"times", sans-serif',
|
||||||
|
// fontFamily: 'courier',
|
||||||
|
state:{
|
||||||
|
nodeSpacing: 50,
|
||||||
|
rankSpacing: 50,
|
||||||
|
defaultRenderer: 'dagre-wrapper',
|
||||||
|
},
|
||||||
|
logLevel:0,
|
||||||
|
fontSize: 18,
|
||||||
|
curve: 'cardinal',
|
||||||
|
securityLevel: 'strict',
|
||||||
|
// themeVariables: {relationLabelColor: 'red'}
|
||||||
|
});
|
||||||
|
function callback(){alert('It worked');}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
93
cypress/platform/knsv2.html
Normal file
93
cypress/platform/knsv2.html
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<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';
|
||||||
|
/* font-size: 18px !important; */
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.mermaid svg {
|
||||||
|
/* font-size: 18px !important; */
|
||||||
|
}
|
||||||
|
.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>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>Security check</div>
|
||||||
|
<div class="flex">
|
||||||
|
<div id="diagram" class="mermaid"></div>
|
||||||
|
<div id="res" class=""></div>
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'forest',
|
||||||
|
arrowMarkerAbsolute: true,
|
||||||
|
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||||
|
logLevel: 0,
|
||||||
|
state: {
|
||||||
|
defaultRenderer: 'dagre-wrapper',
|
||||||
|
},
|
||||||
|
flowchart: {
|
||||||
|
// defaultRenderer: 'dagre-wrapper',
|
||||||
|
nodeSpacing: 10, curve: 'cardinal', htmlLabels: true
|
||||||
|
},
|
||||||
|
htmlLabels: false,
|
||||||
|
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
|
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
|
||||||
|
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||||
|
// fontFamily: '"times", sans-serif',
|
||||||
|
// fontFamily: 'courier',
|
||||||
|
fontSize: 18,
|
||||||
|
curve: 'basis',
|
||||||
|
securityLevel: 'strict',
|
||||||
|
startOnLoad: false
|
||||||
|
// themeVariables: {relationLabelColor: 'red'}
|
||||||
|
});
|
||||||
|
function callback(){alert('It worked');}
|
||||||
|
|
||||||
|
var diagram = "%%{init: {\"flowchart\": {\"htmlLabels\": \"false\"}} }%%\n";
|
||||||
|
diagram += "flowchart\n";
|
||||||
|
diagram += "A[\"<ifra";
|
||||||
|
diagram += "me srcdoc='<scrip";
|
||||||
|
diagram += "t src=http://localhost:9000/exploit.js>";
|
||||||
|
diagram += "</scr"
|
||||||
|
diagram += "ipt>'></iframe>\"]";
|
||||||
|
|
||||||
|
console.log(diagram);
|
||||||
|
// document.querySelector('#diagram').innerHTML = diagram;
|
||||||
|
mermaid.render('diagram', diagram, (res) => {
|
||||||
|
document.querySelector('#res').innerHTML = res;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
210
cypress/platform/knsv3.html
Normal file
210
cypress/platform/knsv3.html
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<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';
|
||||||
|
/* font-size: 18px !important; */
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.mermaid svg {
|
||||||
|
/* font-size: 18px !important; */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>info below</div>
|
||||||
|
<div class="flex">
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 400px;">
|
||||||
|
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 400px;">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] ==> D
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
A[Christmas] ==> C
|
||||||
|
subgraph T ["Test"]
|
||||||
|
A
|
||||||
|
B
|
||||||
|
C
|
||||||
|
end
|
||||||
|
|
||||||
|
classDef Test fill:#F84E68,stroke:#333,color:white;
|
||||||
|
class A,T Test
|
||||||
|
classDef TestSub fill:green;
|
||||||
|
class T TestSub
|
||||||
|
linkStyle 0,1 color:orange, stroke: orange;
|
||||||
|
</div>
|
||||||
|
<div class="mermaid" style="width: 100%; height: 20%;">
|
||||||
|
flowchart TB
|
||||||
|
subgraph S1
|
||||||
|
sub1 -->sub2
|
||||||
|
end
|
||||||
|
subgraph S2
|
||||||
|
sub4
|
||||||
|
end
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||||
|
flowchart TB
|
||||||
|
c1-->a2
|
||||||
|
subgraph one
|
||||||
|
a1-->a2
|
||||||
|
end
|
||||||
|
subgraph two
|
||||||
|
b1-->b2
|
||||||
|
end
|
||||||
|
subgraph three
|
||||||
|
c1-->c2
|
||||||
|
end
|
||||||
|
one --> two
|
||||||
|
three --> two
|
||||||
|
two --> c2
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||||
|
stateDiagram-v2
|
||||||
|
state S1 {
|
||||||
|
sub1 -->sub2
|
||||||
|
}
|
||||||
|
state S2 {
|
||||||
|
sub4
|
||||||
|
}
|
||||||
|
S1 --> S2
|
||||||
|
sub1 --> sub4
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 100%; height: 20%;">
|
||||||
|
requirementDiagram
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||||
|
flowchart LR
|
||||||
|
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
|
||||||
|
Lorem --> Ipsum --> Dolor
|
||||||
|
class Lorem,Dolor dark
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 20%;">
|
||||||
|
%%{init: {'theme': 'base' }}%%
|
||||||
|
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
|
||||||
|
flowchart TD
|
||||||
|
L1 --- L2
|
||||||
|
L2 --- C
|
||||||
|
M1 ---> C
|
||||||
|
R1 .-> R2
|
||||||
|
R2 <.-> C
|
||||||
|
C -->|Label 1| E1
|
||||||
|
C <-- Label 2 ---> E2
|
||||||
|
C ----> E3
|
||||||
|
C <-...-> E4
|
||||||
|
C ======> E5
|
||||||
|
</div>
|
||||||
|
<div class="mermaid2" style="width: 50%; height: 21%;">
|
||||||
|
flowchart LR
|
||||||
|
A[red text] -->|default style| B(blue text)
|
||||||
|
C([red text]) -->|default style| D[[blue text]]
|
||||||
|
E[(red text)] -->|default style| F((blue text))
|
||||||
|
G>red text] -->|default style| H{blue text}
|
||||||
|
I{{red text}} -->|default style| J[/blue text/]
|
||||||
|
K[
|
||||||
|
ed text] -->|default style| L[/blue text]
|
||||||
|
M[
|
||||||
|
ed text/] -->|default style| N[blue text]
|
||||||
|
linkStyle default color:Sienna;
|
||||||
|
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'neutral',
|
||||||
|
arrowMarkerAbsolute: true,
|
||||||
|
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
|
||||||
|
logLevel: 0,
|
||||||
|
flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true },
|
||||||
|
htmlLabels: true,
|
||||||
|
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
|
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
|
||||||
|
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||||
|
// fontFamily: '"times", sans-serif',
|
||||||
|
// fontFamily: 'courier',
|
||||||
|
fontSize: 18,
|
||||||
|
curve: 'cardinal',
|
||||||
|
securityLevel: 'loose',
|
||||||
|
// themeVariables: {relationLabelColor: 'red'}
|
||||||
|
});
|
||||||
|
function callback(){alert('It worked');}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31
cypress/platform/regression/issue-1874.html
Normal file
31
cypress/platform/regression/issue-1874.html
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="http://localhost:9000/mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'base',
|
||||||
|
themeVariables: {
|
||||||
|
},
|
||||||
|
startOnLoad: true,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Example</h1>
|
||||||
|
<div class="mermaid">
|
||||||
|
%%{init:{"theme":"base", "sequence": {"mirrorActors":false},"themeVariables": {"actorBkg":"red"}}}%%
|
||||||
|
sequenceDiagram
|
||||||
|
Bert->>+Ernie: Start looking for the cookie!
|
||||||
|
Ernie-->>-Bert: Found it!
|
||||||
|
Note left of Ernie: Cookies are good
|
||||||
|
</div>
|
||||||
|
<div class="mermaid">
|
||||||
|
%%{init:{"theme":"base", "themeVariables": {}}}%%
|
||||||
|
sequenceDiagram
|
||||||
|
Bert->>+Ernie: Start looking for the cookie!
|
||||||
|
Ernie-->>-Bert: Found it!
|
||||||
|
Note left of Ernie: Cookies are good
|
||||||
|
</div>
|
||||||
|
</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>
|
||||||
289
cypress/platform/showcase_base.html
Normal file
289
cypress/platform/showcase_base.html
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
<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: #f4f4f4;
|
||||||
|
font-family: 'Arial';
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.height {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.height2 {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 1300px;
|
||||||
|
}
|
||||||
|
.width {
|
||||||
|
width: 33%;
|
||||||
|
border: 1px solid blue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Showcases of diagrams</h1>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="mermaid width height">
|
||||||
|
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
|
||||||
|
classDiagram
|
||||||
|
Animal "1" <|-- Duck
|
||||||
|
Animal <|-- Fish
|
||||||
|
Animal <--o Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
|
||||||
|
SomethingElse --> [*]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
|
||||||
|
SomethingElse2 --> [*]
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
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: 5: Me
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</div>
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'base',
|
||||||
|
// themeVariables:
|
||||||
|
// 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>
|
||||||
284
cypress/platform/showcase_base_dark.html
Normal file
284
cypress/platform/showcase_base_dark.html
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
<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: #f4f4f4;
|
||||||
|
background: #222;
|
||||||
|
font-family: 'Arial';
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.height {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.height2 {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 1300px;
|
||||||
|
}
|
||||||
|
.width {
|
||||||
|
width: 33%;
|
||||||
|
border: 1px solid blue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Showcases of diagrams</h1>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="mermaid width height">
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
%%{init2: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
classDiagram
|
||||||
|
Animal "1" <|-- Duck
|
||||||
|
Animal <|-- Fish
|
||||||
|
Animal <--o Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
|
||||||
|
SomethingElse --> [*]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
|
||||||
|
SomethingElse2 --> [*]
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
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: 5: Me
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'base',
|
||||||
|
themeVariables: { primaryColor: '#9400D3', darkMode: true, background: '#222', textColor:'white', primaryTextColor: '#f4f4f4', nodeBkg: '#ff0000', mainBkg:'#0000ff', tertiaryColor:'#ffffcc' },
|
||||||
|
// 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>
|
||||||
280
cypress/platform/showcase_dark.html
Normal file
280
cypress/platform/showcase_dark.html
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<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';
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.height {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.height2 {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 1300px;
|
||||||
|
}
|
||||||
|
.width {
|
||||||
|
width: 33%;
|
||||||
|
border: 1px solid blue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Showcases of diagrams</h1>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="mermaid width height">
|
||||||
|
%%{init: {'theme': 'base', 'themeVariables':{'primaryColor': '#ff0000'}}%%
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
%%{init: {'theme':'dark'}}%%
|
||||||
|
|
||||||
|
classDiagram
|
||||||
|
Animal "1" <|-- Duck
|
||||||
|
Animal <|-- Fish
|
||||||
|
Animal <--o Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
SomethingElse --> [*]
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
SomethingElse2 --> [*]
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
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: 5: Me
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</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": true },
|
||||||
|
// 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>
|
||||||
275
cypress/platform/showcase_default.html
Normal file
275
cypress/platform/showcase_default.html
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
<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';
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.height {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.height2 {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 1300px;
|
||||||
|
}
|
||||||
|
.width {
|
||||||
|
width: 33%;
|
||||||
|
border: 1px solid blue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Showcases of diagrams</h1>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="mermaid width height">
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
classDiagram
|
||||||
|
Animal "1" <|-- Duck
|
||||||
|
Animal <|-- Fish
|
||||||
|
Animal <--o Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
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: 5: Me
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</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>
|
||||||
279
cypress/platform/showcase_forest.html
Normal file
279
cypress/platform/showcase_forest.html
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
<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';
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.height {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.height2 {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 1300px;
|
||||||
|
}
|
||||||
|
.width {
|
||||||
|
width: 33%;
|
||||||
|
border: 1px solid blue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Showcases of diagrams</h1>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="mermaid width height">
|
||||||
|
%%{init: {'theme': 'forest'}}%%
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
%%{init: {'theme':'forest'}}%%
|
||||||
|
|
||||||
|
classDiagram
|
||||||
|
Animal "1" <|-- Duck
|
||||||
|
Animal <|-- Fish
|
||||||
|
Animal <--o Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
SomethingElse --> [*]
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
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: 5: Me
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</div>
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'forest',
|
||||||
|
// 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>
|
||||||
278
cypress/platform/showcase_neutral.html
Normal file
278
cypress/platform/showcase_neutral.html
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
<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';
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
h1 { color: grey;}
|
||||||
|
.mermaid2 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.height {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
.height2 {
|
||||||
|
min-height: 600px;
|
||||||
|
height: 1300px;
|
||||||
|
}
|
||||||
|
.width {
|
||||||
|
width: 33%;
|
||||||
|
border: 1px solid blue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Showcases of diagrams</h1>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="mermaid width height">
|
||||||
|
%%{init: {'theme': 'neutral'}}%%
|
||||||
|
graph TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[/Another/]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
B --> G[Another]
|
||||||
|
C ==>|One| D[Laptop]
|
||||||
|
C x--x|Two| E[iPhone]
|
||||||
|
C o--o|Three| F[fa:fa-car Car]
|
||||||
|
subgraph section
|
||||||
|
C
|
||||||
|
D
|
||||||
|
E
|
||||||
|
F
|
||||||
|
G
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
par Action 1
|
||||||
|
Alice->>John: Hello John, how are you?
|
||||||
|
and Action 2
|
||||||
|
Alice->>Bob: Hello Bob, how are you?
|
||||||
|
end
|
||||||
|
Alice->>+John: Hello John, how are you?
|
||||||
|
Alice->>+John: John, can you hear me?
|
||||||
|
John-->>-Alice: Hi Alice, I can hear you!
|
||||||
|
Note right of John: John is perceptive
|
||||||
|
John-->>-Alice: I feel great!
|
||||||
|
loop Every minute
|
||||||
|
John-->Alice: Great!
|
||||||
|
end
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height" >
|
||||||
|
%%{init: {'theme':'neutral'}}%%
|
||||||
|
|
||||||
|
classDiagram
|
||||||
|
Animal "1" <|-- Duck
|
||||||
|
Animal <|-- Fish
|
||||||
|
Animal <--o Zebra
|
||||||
|
Animal : +int age
|
||||||
|
Animal : +String gender
|
||||||
|
Animal: +isMammal()
|
||||||
|
Animal: +mate()
|
||||||
|
class Duck{
|
||||||
|
+String beakColor
|
||||||
|
+swim()
|
||||||
|
+quack()
|
||||||
|
}
|
||||||
|
class Fish{
|
||||||
|
-int sizeInFeet
|
||||||
|
-canEat()
|
||||||
|
}
|
||||||
|
class Zebra{
|
||||||
|
+bool is_wild
|
||||||
|
+run()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
gantt
|
||||||
|
dateFormat :YYYY-MM-DD
|
||||||
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
excludes :excludes the named dates/days from being included in a charted task..
|
||||||
|
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>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse
|
||||||
|
note right of SomethingElse : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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
|
||||||
|
}
|
||||||
|
state SomethingElse {
|
||||||
|
A --> B
|
||||||
|
B --> A
|
||||||
|
}
|
||||||
|
|
||||||
|
Active --> SomethingElse2
|
||||||
|
note right of SomethingElse2 : This is the note to the right.
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height2">
|
||||||
|
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"
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
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: 5: Me
|
||||||
|
</div>
|
||||||
|
<div class="mermaid width height">
|
||||||
|
requirementDiagram
|
||||||
|
|
||||||
|
requirement test_req {
|
||||||
|
id: 1
|
||||||
|
text: the test text.
|
||||||
|
risk: high
|
||||||
|
verifymethod: test
|
||||||
|
}
|
||||||
|
|
||||||
|
functionalRequirement test_req2 {
|
||||||
|
id: 1.1
|
||||||
|
text: the second test text.
|
||||||
|
risk: low
|
||||||
|
verifymethod: inspection
|
||||||
|
}
|
||||||
|
|
||||||
|
performanceRequirement test_req3 {
|
||||||
|
id: 1.2
|
||||||
|
text: the third test text.
|
||||||
|
risk: medium
|
||||||
|
verifymethod: demonstration
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity {
|
||||||
|
type: simulation
|
||||||
|
}
|
||||||
|
|
||||||
|
element test_entity2 {
|
||||||
|
type: word doc
|
||||||
|
docRef: reqs/test_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test_entity - satisfies -> test_req2
|
||||||
|
test_req - traces -> test_req2
|
||||||
|
test_req - contains -> test_req3
|
||||||
|
test_req <- copies - test_entity2
|
||||||
|
</div>
|
||||||
|
<script src="./mermaid.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.parseError = function (err, hash) {
|
||||||
|
// console.error('Mermaid error: ', err);
|
||||||
|
};
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'neutral',
|
||||||
|
// 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>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user