Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6af2944841 | ||
|
|
d19947c814 | ||
|
|
361bae4289 | ||
|
|
aae9cc7ee9 | ||
|
|
60c3d5edb1 | ||
|
|
bb12395d80 | ||
|
|
dea819670b | ||
|
|
7553782dcc | ||
|
|
daf5b1fca8 | ||
|
|
83878d8c3a | ||
|
|
83178bf58b | ||
|
|
03cf175e26 | ||
|
|
04c9f2e950 | ||
|
|
3f952ba966 | ||
|
|
b7ad03fb64 | ||
|
|
39c7abc757 | ||
|
|
aa0af7e776 | ||
|
|
33cfff5ebb | ||
|
|
7efe886ef4 | ||
|
|
caa236dff1 | ||
|
|
2b5b28c8dc | ||
|
|
481a6d0505 | ||
|
|
5103989eef | ||
|
|
266bf9911d | ||
|
|
8ab6ab5a3a | ||
|
|
d747c2b96f | ||
|
|
002ab3f783 | ||
|
|
a5f3848c16 | ||
|
|
601c7a2a96 | ||
|
|
8fcc10d52f | ||
|
|
65881829c5 | ||
|
|
99f946f33a | ||
|
|
8051bf7a63 | ||
|
|
9863d82e97 | ||
|
|
a56fef71fb | ||
|
|
db24520d75 | ||
|
|
ca23b4e4d4 | ||
|
|
9e9952eb53 | ||
|
|
90d63e19dd | ||
|
|
fe91a737d5 | ||
|
|
419f5c9968 | ||
|
|
809e361760 | ||
|
|
f5cc10c7df | ||
|
|
c225388951 | ||
|
|
6d50e32d27 | ||
|
|
6711223ad1 | ||
|
|
4e04972a09 | ||
|
|
a22b53a356 | ||
|
|
5e5aefd745 | ||
|
|
54eca19513 | ||
|
|
41bfbcc9d9 | ||
|
|
be1e821973 | ||
|
|
e38c70d39a | ||
|
|
796f97342b | ||
|
|
02fe5e1c77 | ||
|
|
c9bfb0ca1f | ||
|
|
ad321f0169 | ||
|
|
be81478d02 | ||
|
|
03372a9e92 | ||
|
|
7ec6092d6f | ||
|
|
354500f018 | ||
|
|
7458284c30 | ||
|
|
f8156f45ab | ||
|
|
ce13000dcb | ||
|
|
1664fa7ac7 | ||
|
|
1806136418 | ||
|
|
281140c19f | ||
|
|
0763dfbaa3 | ||
|
|
b4a59fdb7e | ||
|
|
7759001feb | ||
|
|
1b3ac0ff11 | ||
|
|
d43f21a4cc | ||
|
|
2d946cb9d9 | ||
|
|
8da314393b | ||
|
|
e9a11fbbca | ||
|
|
0af837321c | ||
|
|
0b92440cbc | ||
|
|
24e6aca4f8 | ||
|
|
5cb0d9f455 | ||
|
|
f6fddedeae | ||
|
|
6851ef187b | ||
|
|
133019e4e5 | ||
|
|
59c4ce4c70 | ||
|
|
727a2b6cf6 | ||
|
|
1d36f49586 | ||
|
|
7480f6ab2a | ||
|
|
2207dcc248 | ||
|
|
139db488cc | ||
|
|
059e208b53 | ||
|
|
7d8e8f5b53 | ||
|
|
0a15a7651f | ||
|
|
d03a5b3fec | ||
|
|
a9d0a674f4 | ||
|
|
2152366635 | ||
|
|
ad31359fdd | ||
|
|
610e844f8e | ||
|
|
bfd93347a4 | ||
|
|
eb6395844b | ||
|
|
0286c9e705 | ||
|
|
e7a6ba07ce | ||
|
|
3144e84bd3 | ||
|
|
5f9d1daf0f | ||
|
|
9d844f8e67 | ||
|
|
303748a980 | ||
|
|
89b55047e9 | ||
|
|
0bc3f485a9 | ||
|
|
514c9555e0 | ||
|
|
94ed933a4b | ||
|
|
2cd9ed554d | ||
|
|
a881f59e9c | ||
|
|
c700ecd5f7 | ||
|
|
7bd9939acd | ||
|
|
884463917b | ||
|
|
55cc382f4b | ||
|
|
da3a3cbf7f | ||
|
|
fb02712eaf | ||
|
|
5fd7b97802 | ||
|
|
d529670ebf | ||
|
|
9cf2f879b2 | ||
|
|
e372fe335f | ||
|
|
bf0a5c2b40 | ||
|
|
db3b51fbb0 | ||
|
|
7fca01690c | ||
|
|
6ebb19bcd0 | ||
|
|
47eb39b7a5 | ||
|
|
66b9070fb2 | ||
|
|
ee2f3acb04 | ||
|
|
5aeba4fbdf | ||
|
|
c9d5e52b26 | ||
|
|
1cc3cf90fb | ||
|
|
efbcbd4691 | ||
|
|
4015922833 | ||
|
|
b74e94e4f8 | ||
|
|
0097090d64 | ||
|
|
c8ebf124b5 | ||
|
|
905fab93bd | ||
|
|
868eaefbec | ||
|
|
a15853c374 | ||
|
|
17d1a7af4c | ||
|
|
f1caf21a48 | ||
|
|
15d9d98e98 | ||
|
|
af16c671cc | ||
|
|
d0f8995829 | ||
|
|
cd3fd7ba4b | ||
|
|
3d274eb8a2 | ||
|
|
dd582da97d | ||
|
|
11ace4d8b6 | ||
|
|
dc21097da1 | ||
|
|
8bdeda36d3 | ||
|
|
323f2455b2 | ||
|
|
a0b16eca7b | ||
|
|
2f4d4e4008 | ||
|
|
ee44e6f990 | ||
|
|
09d2b01029 | ||
|
|
abf3812439 | ||
|
|
67df81d4fd | ||
|
|
0a01ff53a3 | ||
|
|
53fcc9562d | ||
|
|
d8b719a728 | ||
|
|
06aa74a5f7 | ||
|
|
92354ed015 | ||
|
|
c83e3d5c22 | ||
|
|
594471d12c | ||
|
|
fdecf37ec0 | ||
|
|
0cfafd1d45 | ||
|
|
9891dea2e5 | ||
|
|
a07a4e24eb | ||
|
|
4f86ed1913 | ||
|
|
482ae93e0f | ||
|
|
5ed4a68cb1 | ||
|
|
b784b5de26 | ||
|
|
ca03f0f709 | ||
|
|
9ccaa12ac9 | ||
|
|
594d61503d | ||
|
|
e11f7ec67f | ||
|
|
f2f6104e7c | ||
|
|
53bd0136a5 | ||
|
|
6fbc73c259 | ||
|
|
67c5d77730 | ||
|
|
a1d17002fc | ||
|
|
f236d29053 | ||
|
|
752aff86e6 | ||
|
|
109f1a900f | ||
|
|
7c6a7293f7 | ||
|
|
8a9c9ffe56 | ||
|
|
2678017cde | ||
|
|
a8b1ce9593 | ||
|
|
39f8779394 | ||
|
|
67a9d5fe90 | ||
|
|
b4efd29492 | ||
|
|
abcb97d564 | ||
|
|
fc3af550de | ||
|
|
bcb42fc81d | ||
|
|
4b05314e3b | ||
|
|
712dcbcde8 | ||
|
|
e0f5c18b61 | ||
|
|
b4cd851b0d | ||
|
|
e2738f48e0 | ||
|
|
3e569f461d | ||
|
|
d5975ce4ce | ||
|
|
4622afab09 | ||
|
|
9888f5168d | ||
|
|
c866aabab8 | ||
|
|
e45c87ca43 | ||
|
|
68111db2f5 | ||
|
|
78a17e4171 | ||
|
|
54ed00f701 | ||
|
|
abb9b195ef | ||
|
|
bc0694c9a2 | ||
|
|
31e1bafeb9 | ||
|
|
7f922d1b58 | ||
|
|
4521549eb2 | ||
|
|
63aa1c1631 | ||
|
|
64fb8abf5a | ||
|
|
1790088cd0 | ||
|
|
b39fc1c4d3 | ||
|
|
28b0a845f8 | ||
|
|
77300ee065 | ||
|
|
2f703c3ad4 | ||
|
|
768bab4a48 | ||
|
|
740b7213c9 | ||
|
|
cb3720fdb1 | ||
|
|
773ace12b5 | ||
|
|
58a553afb2 | ||
|
|
2bf35c08af | ||
|
|
3739560564 | ||
|
|
26ba60cd64 | ||
|
|
9922f4557c | ||
|
|
0fb897a6b4 | ||
|
|
ba3212014a | ||
|
|
ac5971b56f | ||
|
|
46a567e464 | ||
|
|
2f394bb429 | ||
|
|
0600e60ee8 | ||
|
|
b6f87077d8 | ||
|
|
26c547e1d9 | ||
|
|
37f04a01dd | ||
|
|
3a449716cd | ||
|
|
e6d4870b8e | ||
|
|
cfe7bde356 | ||
|
|
3ef80b042a | ||
|
|
4ee343a34e | ||
|
|
c98a11b0dd | ||
|
|
6b3e3f2ac8 | ||
|
|
76d661f0bc | ||
|
|
303c6745e1 | ||
|
|
68e4ef032b | ||
|
|
9c3f9c7560 | ||
|
|
b086acfc24 | ||
|
|
2485580b6c | ||
|
|
d5770a9265 | ||
|
|
413b9cd866 | ||
|
|
a7dd33bbed | ||
|
|
e92abd6e95 | ||
|
|
6ea48bf8b6 | ||
|
|
e197764af3 | ||
|
|
cad546df90 | ||
|
|
ca13cfebb9 | ||
|
|
5c903c4eed | ||
|
|
72ac5eb86d | ||
|
|
258b0625d4 | ||
|
|
3bad415dd6 | ||
|
|
ae2ac64cf5 | ||
|
|
a82d3033bf | ||
|
|
b6e0c33f8e | ||
|
|
59e17efac6 | ||
|
|
8fcc80ad7b | ||
|
|
ededef0757 | ||
|
|
6cc340184f | ||
|
|
ee19257234 | ||
|
|
03295fff6b | ||
|
|
793a6f2a97 | ||
|
|
c2d81a82a2 | ||
|
|
603e86d87b | ||
|
|
8211a8d8e6 | ||
|
|
0ea6ccd6f2 | ||
|
|
43e6f12b6a | ||
|
|
2c741eac92 | ||
|
|
dc6ef05bb2 | ||
|
|
f8775c3c6b | ||
|
|
aebb2311c9 | ||
|
|
01e4fe78eb | ||
|
|
9a73384d61 | ||
|
|
fbf391628f | ||
|
|
78fbfaa07c | ||
|
|
79263e3dd1 | ||
|
|
117540d768 | ||
|
|
eed5f8166b | ||
|
|
96d6575959 | ||
|
|
4555d67463 | ||
|
|
de96156a18 | ||
|
|
cc188e092f | ||
|
|
afedea47c2 | ||
|
|
5c2206bbe6 | ||
|
|
70a17c87f0 | ||
|
|
6dd0f5870d | ||
|
|
1058baff54 | ||
|
|
d568f2ac6b | ||
|
|
b38de3a31d | ||
|
|
17c3038bcc | ||
|
|
13264dc2b8 | ||
|
|
8c3a762ab9 | ||
|
|
b4f841ff0d | ||
|
|
7d6a0d55a1 | ||
|
|
a577262c80 | ||
|
|
b6cd4a22f2 | ||
|
|
b8ea4df736 | ||
|
|
7b2fb60c98 | ||
|
|
a86011369b | ||
|
|
b1f21f3f0d | ||
|
|
3c067b63e9 | ||
|
|
d634045115 | ||
|
|
c7cf667693 | ||
|
|
59d265e29f | ||
|
|
9e250296ba | ||
|
|
1807838179 | ||
|
|
18aea74e4d | ||
|
|
e5008d4b7b | ||
|
|
925f20e8b8 | ||
|
|
d523848ae8 | ||
|
|
417b3370d2 | ||
|
|
80ffb33439 | ||
|
|
5bb2e96c52 | ||
|
|
ba8ae49ed8 | ||
|
|
6b882d8fb0 | ||
|
|
35bbbcd42c | ||
|
|
175e309412 | ||
|
|
eba7c6e156 | ||
|
|
14565ca0c4 | ||
|
|
82f916abae | ||
|
|
ee27a3613f | ||
|
|
7246fb9385 | ||
|
|
f34c597fa1 | ||
|
|
766c34a0c0 | ||
|
|
13431c6092 | ||
|
|
5e0a5c5b93 | ||
|
|
eab8a4b428 | ||
|
|
e91adb64a7 | ||
|
|
a425a85c35 | ||
|
|
db9c0a5b79 | ||
|
|
3c6867d3d5 | ||
|
|
e66066ec84 | ||
|
|
8419a5326f | ||
|
|
5e21f0e9b4 | ||
|
|
9b81e6f9a2 | ||
|
|
b895d17065 | ||
|
|
5345e59e30 | ||
|
|
c36d9f7aae | ||
|
|
5a4c0c9019 | ||
|
|
75011312f4 | ||
|
|
606f9aad1a | ||
|
|
7e6102dca3 | ||
|
|
47f0f58f5d | ||
|
|
3dac672ba3 | ||
|
|
8ef383ac9f | ||
|
|
744c022711 | ||
|
|
3f53069e3b | ||
|
|
9d00b0196b | ||
|
|
352e7d5c76 | ||
|
|
6ea600aaf2 | ||
|
|
18e8dc4e98 | ||
|
|
bf289d98dd | ||
|
|
22046c5d42 | ||
|
|
9cff37008d | ||
|
|
c631b60c26 | ||
|
|
aed37a7882 | ||
|
|
c23baf54c5 | ||
|
|
3dc2c001fc | ||
|
|
d0b55b8152 | ||
|
|
ef8300b94d | ||
|
|
66ef35e83f | ||
|
|
4992b35f10 | ||
|
|
1ff576d583 | ||
|
|
816971184a | ||
|
|
7dd7a0f4fb | ||
|
|
f10cd880f1 | ||
|
|
317103654c | ||
|
|
b1d0784f81 | ||
|
|
57a78b25b4 | ||
|
|
1abf6850d1 | ||
|
|
b20c94aa2f | ||
|
|
8ec08545f7 | ||
|
|
965b264db4 | ||
|
|
ac8187d800 | ||
|
|
fea209f199 | ||
|
|
04fad73b74 | ||
|
|
4b78e9f4a5 | ||
|
|
65e6b007ca | ||
|
|
ee35ce9540 | ||
|
|
7639042010 | ||
|
|
61a6c3c24f | ||
|
|
6598bcb28d | ||
|
|
537ccdeb5d | ||
|
|
05b6e51f88 | ||
|
|
7d3f375c1a | ||
|
|
1452bdd9be | ||
|
|
ca3de11171 | ||
|
|
cd997f6d5b | ||
|
|
54a54a5b00 | ||
|
|
c2f4df8afb | ||
|
|
4e4334a424 | ||
|
|
615a8db2d1 | ||
|
|
3ba071ac00 | ||
|
|
1dcc6bd29e | ||
|
|
386c634a3f | ||
|
|
f25bfb6252 | ||
|
|
1bb162bbd3 | ||
|
|
7e37d927ec | ||
|
|
9a488b0bc3 | ||
|
|
f2ca470d3f | ||
|
|
2ab9b7086c | ||
|
|
7b76ff01af | ||
|
|
8e4e2e4948 | ||
|
|
634e82d24e | ||
|
|
5544723938 | ||
|
|
72144d7734 | ||
|
|
8af1f62bd6 | ||
|
|
10c24e9bd7 | ||
|
|
38b0b502c3 | ||
|
|
563f9977b0 | ||
|
|
b78d329faa | ||
|
|
a777500389 | ||
|
|
c57c9d695f | ||
|
|
d866ce27db | ||
|
|
edb1c05d27 | ||
|
|
3d9e8c2571 | ||
|
|
843145e436 | ||
|
|
8a4fededb3 | ||
|
|
5325af1973 | ||
|
|
ed1238795c | ||
|
|
410a5fc740 | ||
|
|
b72d51c9ac | ||
|
|
1979f74084 | ||
|
|
76f1481557 | ||
|
|
af274ee955 | ||
|
|
e8e63fb4ef | ||
|
|
95a25b8f32 | ||
|
|
ba8194f6f9 | ||
|
|
40a6980846 | ||
|
|
44cd320c20 | ||
|
|
4e1eed3858 | ||
|
|
8173a7d564 | ||
|
|
4dd5e215b0 | ||
|
|
775cbff377 | ||
|
|
d58e9032a1 | ||
|
|
6c38e8f881 | ||
|
|
a67e38fa84 | ||
|
|
c23212f924 | ||
|
|
605356e400 | ||
|
|
2ad5fe410a | ||
|
|
f729048742 | ||
|
|
d27c5b28e2 | ||
|
|
570e7ddfa9 | ||
|
|
831c1c4209 | ||
|
|
eb23dc48d6 | ||
|
|
70372c52f9 | ||
|
|
e9f045a32a | ||
|
|
8954aba225 | ||
|
|
208af5c2ba | ||
|
|
36612b526e | ||
|
|
ca330f78ab | ||
|
|
4803c5181e | ||
|
|
3d2184ea4e | ||
|
|
9be1962510 | ||
|
|
23704d3171 | ||
|
|
b214a14669 | ||
|
|
a8f28f596b | ||
|
|
f93426c6ac | ||
|
|
0905b5b2b9 | ||
|
|
692d02cb5f | ||
|
|
58be278dd9 | ||
|
|
1ee43ef218 | ||
|
|
63af6a8bff | ||
|
|
fc4bf72202 | ||
|
|
085cf72470 | ||
|
|
e770f59643 | ||
|
|
4394a28fb8 | ||
|
|
51bdfb4ead | ||
|
|
e12308b801 | ||
|
|
18b1ba3a58 | ||
|
|
3fd50e096a | ||
|
|
51643e043e | ||
|
|
41ad8f9214 | ||
|
|
b94dec07fe | ||
|
|
4219fcdc97 | ||
|
|
e00e41651c | ||
|
|
5236d4a386 | ||
|
|
525adddfbf | ||
|
|
01cfcf68af | ||
|
|
da68860c7c | ||
|
|
c7da2e3759 | ||
|
|
473aeaa902 | ||
|
|
58c919b6f9 | ||
|
|
fda0db88bf | ||
|
|
07cdfb7421 | ||
|
|
a2d8a61ae9 | ||
|
|
6bed3b43a2 | ||
|
|
61f60feb39 | ||
|
|
c02439d325 | ||
|
|
88cb2f4b21 | ||
|
|
bdeb251c25 | ||
|
|
0a04cf2d69 | ||
|
|
45334d0c04 | ||
|
|
df6735fa76 | ||
|
|
8ac4afe087 | ||
|
|
9c4a47fa8f | ||
|
|
5d365d695b | ||
|
|
5ac40b6339 | ||
|
|
181b4096af | ||
|
|
e888279fe5 | ||
|
|
80d70d1532 | ||
|
|
2eb4ef60a4 | ||
|
|
3de3035185 | ||
|
|
2cc86d7b78 | ||
|
|
71f443e840 | ||
|
|
4abed70e49 | ||
|
|
8491bfddae | ||
|
|
ce83b210dd | ||
|
|
1ec8a224a8 | ||
|
|
df92e366b6 | ||
|
|
8c5c76f1f0 | ||
|
|
6e36163712 | ||
|
|
6af5c1a932 | ||
|
|
d23be82cc3 | ||
|
|
acc79c5a32 | ||
|
|
ffe82fa6c9 | ||
|
|
f75c524bde | ||
|
|
50c62955eb | ||
|
|
503ecca40a | ||
|
|
5267886606 | ||
|
|
cbe9c40be5 | ||
|
|
bd7ed55e73 | ||
|
|
adbc0cff51 | ||
|
|
5bb46a9e0d | ||
|
|
aad60b5dbd | ||
|
|
d10f2db7cd | ||
|
|
7c8369b22a | ||
|
|
d6fe21d835 | ||
|
|
67581e228e | ||
|
|
10bdc7cb5b | ||
|
|
04234ed81e | ||
|
|
c07ed1bbe0 | ||
|
|
9f277d2106 | ||
|
|
4813586eee | ||
|
|
f2a94d01d1 | ||
|
|
8e3da5badd | ||
|
|
9489e1f000 | ||
|
|
d303ac1833 | ||
|
|
fccc44cafc | ||
|
|
d6130c3eef | ||
|
|
d82385e5b9 | ||
|
|
71365b32f5 | ||
|
|
172c1b8324 | ||
|
|
729247898b | ||
|
|
408370b0d7 | ||
|
|
22ae2248f3 | ||
|
|
b0e49963a7 | ||
|
|
562fd1c5aa | ||
|
|
32198eff6e | ||
|
|
ebf4599020 | ||
|
|
17dd46c50e | ||
|
|
b161e24a74 | ||
|
|
608779cc9f | ||
|
|
ccc8b968c3 | ||
|
|
ebf4aecc33 | ||
|
|
3f6bf5a9ec | ||
|
|
2a54fcebdb | ||
|
|
8a6d7decc3 | ||
|
|
0f8d7ee427 | ||
|
|
fc21c2ccf2 | ||
|
|
8394f5dd8f | ||
|
|
bc87dca6f0 | ||
|
|
5f936d0e66 | ||
|
|
06d19f52f5 | ||
|
|
e8cd72ee7d | ||
|
|
b4f79c547e | ||
|
|
4216a9dfac | ||
|
|
ddd1ca8254 | ||
|
|
700a4cd81d | ||
|
|
07af430261 | ||
|
|
440628895f | ||
|
|
88974877d1 | ||
|
|
27d54fefe3 | ||
|
|
a4026377c1 | ||
|
|
71af4d80b3 | ||
|
|
4801b5fdaf | ||
|
|
4239c79325 | ||
|
|
315a519d38 | ||
|
|
fccf514c95 | ||
|
|
206a1fd066 | ||
|
|
2c55b6b986 | ||
|
|
414cbafa3d | ||
|
|
2ef2ea9739 | ||
|
|
bca43b417b | ||
|
|
935e077586 | ||
|
|
1b4686def4 | ||
|
|
9e335df094 | ||
|
|
fa8a124029 | ||
|
|
aa8df4c537 | ||
|
|
4350468ce2 | ||
|
|
a2f5a6054b | ||
|
|
e5b6d53ab6 | ||
|
|
dcfd901c67 | ||
|
|
40643309d7 | ||
|
|
b02fd18f9b | ||
|
|
a27f164a85 | ||
|
|
4ef1cf8e38 | ||
|
|
41b731f521 | ||
|
|
7bfa9caeeb | ||
|
|
46339148ec | ||
|
|
c6eb9d2115 | ||
|
|
8047b20afd | ||
|
|
749d971976 | ||
|
|
b417db357b | ||
|
|
7a82c93962 | ||
|
|
c63f127bff | ||
|
|
6981b1fda8 | ||
|
|
37a73243d4 | ||
|
|
3c72df1408 | ||
|
|
8c6cb5da9a | ||
|
|
e6c792fc9a | ||
|
|
801e6985f5 | ||
|
|
25698e9c61 | ||
|
|
7f9b836d41 | ||
|
|
2434fe4867 | ||
|
|
4e9f2ec71b | ||
|
|
65b476d360 | ||
|
|
648fbc8a5a | ||
|
|
7224558d5a | ||
|
|
41a0fa689c | ||
|
|
72ea56b413 | ||
|
|
d2ca900a7d | ||
|
|
53b0e43a0e | ||
|
|
3dd6951125 | ||
|
|
7eb4522484 | ||
|
|
64c8299890 | ||
|
|
2a9bd4d4a0 | ||
|
|
73208c49ac | ||
|
|
7a323266ea | ||
|
|
c5bf18c27c | ||
|
|
fd20a3e646 | ||
|
|
11c8570258 | ||
|
|
bf6c00202e | ||
|
|
f13c2b9cdb | ||
|
|
5b9591f514 | ||
|
|
a5eef411da | ||
|
|
8d870e5d20 | ||
|
|
dc4fa92b46 | ||
|
|
19630f1669 | ||
|
|
462d5b4ec1 | ||
|
|
7c25415a44 | ||
|
|
95d708e49a | ||
|
|
901dc1db89 | ||
|
|
a88768cddd | ||
|
|
2d5b711598 | ||
|
|
bb666f78e7 | ||
|
|
f0a4ac26de | ||
|
|
e4c98cc171 | ||
|
|
5e0fe8f6d2 | ||
|
|
92b5db01e9 | ||
|
|
45addc1ed9 | ||
|
|
954c3dc186 | ||
|
|
503bf6ad3d | ||
|
|
35777a9109 | ||
|
|
2616186cbc | ||
|
|
0e3bf20819 | ||
|
|
d7991757c7 | ||
|
|
6522b64521 | ||
|
|
a4cbd64af6 | ||
|
|
bc91a27c4c | ||
|
|
e58a7a62d7 | ||
|
|
54dfa885b8 | ||
|
|
5a64bdee10 | ||
|
|
8f8fb20721 | ||
|
|
994dee91d1 | ||
|
|
43faa70fbe | ||
|
|
00ee82e4bc | ||
|
|
f5eb81bf97 | ||
|
|
7fce3729b4 | ||
|
|
a29bc5d8b8 | ||
|
|
ef3fa55039 | ||
|
|
116924e210 | ||
|
|
d90819e9e6 | ||
|
|
d7da3699a8 | ||
|
|
ed54d749c0 | ||
|
|
d77aff784f | ||
|
|
640d772374 | ||
|
|
5e5278abbd | ||
|
|
bc0214335c | ||
|
|
7f2c4f0e77 | ||
|
|
172428306e | ||
|
|
888c4ba40d | ||
|
|
4a202e3c0f | ||
|
|
d79f2be4b7 | ||
|
|
61e3a5dc01 | ||
|
|
498105f35e | ||
|
|
402dac7735 | ||
|
|
4693ad38ee | ||
|
|
0e53be33ab | ||
|
|
366b71b53e | ||
|
|
c8239e870e | ||
|
|
87ec455304 | ||
|
|
760627c0d1 | ||
|
|
aa7675615d | ||
|
|
1bf7262ecf | ||
|
|
77a0bfaede | ||
|
|
3c853a868d | ||
|
|
0a29201e69 | ||
|
|
48eec8b891 | ||
|
|
9bfd6feeaa | ||
|
|
7e3516f87d | ||
|
|
cd9d5699bc | ||
|
|
96316c5116 | ||
|
|
739c77abba | ||
|
|
276a0554e4 | ||
|
|
5e275af84d | ||
|
|
6605552ca3 | ||
|
|
4be5b7a929 | ||
|
|
df9032bd8e | ||
|
|
f884390b60 | ||
|
|
274444d5a2 | ||
|
|
0a9583b6aa | ||
|
|
a85cf583ed | ||
|
|
b421c2dbe7 | ||
|
|
45aed98551 | ||
|
|
a0150cc7e4 | ||
|
|
c4175b7677 | ||
|
|
5902263f6d | ||
|
|
73a8d91470 | ||
|
|
51b78a323d | ||
|
|
52e5503457 | ||
|
|
cbdf33f830 | ||
|
|
727f42e3d4 | ||
|
|
1382389645 | ||
|
|
00fe64c25e | ||
|
|
86f8ffad15 | ||
|
|
5baf30f70b | ||
|
|
a95637bf24 | ||
|
|
35fd4bf568 | ||
|
|
f778f54c81 | ||
|
|
9dfb1167ec | ||
|
|
1b7c71b454 | ||
|
|
a10a4fefd8 | ||
|
|
0e15f35b7e | ||
|
|
a1a52ae508 | ||
|
|
3051a22948 | ||
|
|
df52f38112 | ||
|
|
b6312a1883 | ||
|
|
fd08a3f723 | ||
|
|
50ef8289a0 | ||
|
|
ed9ec13b66 | ||
|
|
b82eb7263b | ||
|
|
a7eca8af25 | ||
|
|
796558e258 | ||
|
|
8ac373e3ee | ||
|
|
a615712771 | ||
|
|
ea2651acb7 | ||
|
|
7b85a318bf | ||
|
|
0eb4b13087 | ||
|
|
ad3c46d13a | ||
|
|
b9aae080a8 | ||
|
|
b6ddd9b40f | ||
|
|
083e3b0c68 | ||
|
|
c2bc724628 | ||
|
|
db8d65becc | ||
|
|
6610125f6c | ||
|
|
7c31928729 | ||
|
|
db483ecf72 | ||
|
|
c2270ab04c | ||
|
|
bffabe6b89 | ||
|
|
fa760371be | ||
|
|
cd8735b545 | ||
|
|
27a76d2198 | ||
|
|
fe3a5668ee | ||
|
|
bf42da3746 | ||
|
|
0306844531 | ||
|
|
4b0c88a2ea | ||
|
|
ea9a0799d4 | ||
|
|
350014abaa | ||
|
|
7dbb778ce9 | ||
|
|
d24997bec3 | ||
|
|
2825512b1e | ||
|
|
4388a94ad7 | ||
|
|
f60c6cc81c | ||
|
|
d626680e28 | ||
|
|
f0ac30b758 | ||
|
|
ca269abffc | ||
|
|
1ee8a8fabf | ||
|
|
070f79695f | ||
|
|
6d8127ab18 | ||
|
|
bf9575c198 | ||
|
|
b2b39a5fd7 | ||
|
|
a68f7e500a | ||
|
|
a060de5a41 | ||
|
|
9a0bc4907d | ||
|
|
6e1c7db16f | ||
|
|
4f6879cbf0 | ||
|
|
af994d45ac | ||
|
|
7d2915d131 | ||
|
|
b0c88099a0 | ||
|
|
14dc08ecc1 | ||
|
|
badccd2348 | ||
|
|
131d26292c | ||
|
|
1b24e46150 | ||
|
|
33972d4cee | ||
|
|
bf23980b5f | ||
|
|
004b4d0d35 | ||
|
|
899ce192b8 | ||
|
|
7d44ba12d5 | ||
|
|
8cd3436764 | ||
|
|
56822e5e11 | ||
|
|
7fdf0b92b3 | ||
|
|
5261c7ce38 | ||
|
|
d97b7b94e0 | ||
|
|
adce26b50d | ||
|
|
8fbfd85905 | ||
|
|
054a9d4a5b | ||
|
|
8ad947a2d4 | ||
|
|
9b9ed45962 | ||
|
|
c38d31ad6e | ||
|
|
76c542e03e | ||
|
|
a295afc1fb | ||
|
|
6fd71b52ca | ||
|
|
3cba0dc491 | ||
|
|
f5b7964cd8 | ||
|
|
19a94f1f33 | ||
|
|
e5e2c6cb29 | ||
|
|
ddbdba0759 | ||
|
|
69210353ec | ||
|
|
a5e40401a0 | ||
|
|
1774625364 | ||
|
|
d21c491541 | ||
|
|
44d48475d5 | ||
|
|
16ebdc6ef4 | ||
|
|
162358118e | ||
|
|
fa14c1a8f2 | ||
|
|
356a4f57f2 | ||
|
|
de9c7ad839 | ||
|
|
646f0614eb | ||
|
|
6c1758134b | ||
|
|
46be215a48 | ||
|
|
7fa615de05 | ||
|
|
7bed2afa4d | ||
|
|
11a1aceb89 | ||
|
|
8b79f57666 | ||
|
|
9c9814b017 | ||
|
|
bdd9ae7b66 | ||
|
|
9c98fe6dcb | ||
|
|
826d9111f2 | ||
|
|
f6cbb50992 | ||
|
|
a986ca1a5d | ||
|
|
ac6c432ad6 | ||
|
|
e726184417 | ||
|
|
40feb0acab | ||
|
|
31064b9735 | ||
|
|
a4c8f21692 | ||
|
|
07f384f8fa | ||
|
|
e75f3f4b4d |
No files matched your search
@@ -0,0 +1,154 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Continuous Integration expired token tests
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26
|
||||
JAVA_VERSION: 25
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 8 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
# Docker Hub image
|
||||
image: postgres
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: skillsPassword
|
||||
POSTGRES_DB: skills
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps tcp port 5432 on service container to the host
|
||||
- 5432:5432
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
# - name: build skill-service
|
||||
# run: ./.github/workflows/scripts/getSkillsService.sh
|
||||
# - name: download skill-service
|
||||
# run: |
|
||||
# mkdir skills-service
|
||||
# cd skills-service
|
||||
# curl -s https://api.github.com/repos/NationalSecurityAgency/skills-service/releases/latest | grep browser_download_url | cut -d '"' -f 4 | wget -qi -
|
||||
# ls ./
|
||||
# cd ..
|
||||
|
||||
- name: Checkout specific branch fo skills-service
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: NationalSecurityAgency/skills-service
|
||||
path: skills-service
|
||||
|
||||
- name: build skill-service
|
||||
run: |
|
||||
cd skills-service
|
||||
mvn --batch-mode clean install -DskipTests
|
||||
cp ./service/target/skills-service-*.jar ./
|
||||
ls ./
|
||||
cd ..
|
||||
|
||||
- name: setup npm links
|
||||
run: ./.github/workflows/scripts/setupNpmLinks.sh
|
||||
|
||||
- name: build integration test apps
|
||||
run: |
|
||||
cd ./skills-client-integration
|
||||
mvn --batch-mode clean install
|
||||
cd ../
|
||||
|
||||
- name: start services for cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm install
|
||||
npm run cyServices:start:skills-service:ci:expired-token
|
||||
npm run cyServices:start:integration-apps
|
||||
cd ../../
|
||||
|
||||
- name: Run Cypress tests
|
||||
uses: cypress-io/github-action@v5
|
||||
with:
|
||||
working-directory: skills-client-integration/skills-int-e2e-test
|
||||
record: true
|
||||
parallel: false
|
||||
group: 'skills-client expired token tests'
|
||||
tag: "${{ github.workflow }}"
|
||||
spec: cypress/e2e/timeout.specs.js
|
||||
env: 'timeout=true'
|
||||
browser: chrome
|
||||
env:
|
||||
# pass the Dashboard record key as an environment variable
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
# pass GitHub token to allow accurately detecting a build vs a re-run build
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# - name: Run Cypress tests
|
||||
# run: |
|
||||
# cd skills-client-integration/skills-int-e2e-test
|
||||
# npm run cy:run:timeout
|
||||
# cd ../../
|
||||
|
||||
- name: upload result artifacts
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: result artifacts
|
||||
path: |
|
||||
./skills-service/*.jar
|
||||
./skills-client-integration/skills-int-service/target/*.jar
|
||||
./skills-client-integration/skills-int-e2e-test/target/logs/*.out
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/logs
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/**/__diff_output__/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/__diff_output__/*.png
|
||||
@@ -0,0 +1,185 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Continuous Integration with OAuth
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26
|
||||
JAVA_VERSION: 25
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- .github/workflows/skills-service-backward-compat.yml
|
||||
- .github/workflows/client-libs-backward-compat.yml
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- .github/workflows/skills-service-backward-compat.yml
|
||||
- .github/workflows/client-libs-backward-compat.yml
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
# Docker Hub image
|
||||
image: postgres
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: skillsPassword
|
||||
POSTGRES_DB: skills
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps tcp port 5432 on service container to the host
|
||||
- 5432:5432
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
# - name: download skill-service
|
||||
# run: |
|
||||
# mkdir skills-service
|
||||
# cd skills-service
|
||||
# curl -s https://api.github.com/repos/NationalSecurityAgency/skills-service/releases/latest | grep browser_download_url | cut -d '"' -f 4 | wget -qi -
|
||||
# ls ./
|
||||
# cd ..
|
||||
|
||||
- name: Checkout specific branch fo skills-service
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: NationalSecurityAgency/skills-service
|
||||
path: skills-service
|
||||
|
||||
- name: build skill-service
|
||||
run: |
|
||||
cd skills-service
|
||||
mvn --batch-mode clean install -DskipTests
|
||||
cp ./service/target/skills-service-*.jar ./
|
||||
ls ./
|
||||
cd ..
|
||||
|
||||
- name: setup npm links
|
||||
run: ./.github/workflows/scripts/setupNpmLinks.sh
|
||||
|
||||
- name: build integration test apps
|
||||
run: |
|
||||
cd ./skills-client-integration
|
||||
mvn --batch-mode clean install
|
||||
cd ../
|
||||
|
||||
- name: run hyrda oauth service
|
||||
run: ./.github/workflows/scripts/runHydra.sh
|
||||
|
||||
- name: Check running containers
|
||||
run: docker ps -a
|
||||
|
||||
- name: Caputre Hydra Oauth Service logs
|
||||
run: |
|
||||
mkdir -p ./skills-client-integration/skills-int-e2e-test/target/logs
|
||||
docker logs hydra > ./skills-client-integration/skills-int-e2e-test/target/logs/hydra.out &
|
||||
docker container logs -f hydra_consent > ./skills-client-integration/skills-int-e2e-test/target/logs/hydra_consent.out &
|
||||
docker container logs -f hydra_postgres > ./skills-client-integration/skills-int-e2e-test/target/logs/hydra_postgres.out &
|
||||
|
||||
- name: Register hydra client
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test/hydra
|
||||
docker compose -f quickstart.yml exec -T hydra \
|
||||
hydra clients create \
|
||||
--endpoint http://localhost:4445/ \
|
||||
--id skilltree-test \
|
||||
--secret client-secret \
|
||||
--grant-types authorization_code,refresh_token \
|
||||
--response-types code \
|
||||
--scope openid \
|
||||
--callbacks http://localhost:8080/login/oauth2/code/hydra
|
||||
|
||||
- name: start services for OAuth cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm install
|
||||
npm run cyServices:start:skills-service:ci:oauth
|
||||
npm run cyServices:start:integration-apps:oauth
|
||||
cd ../../
|
||||
|
||||
# - name: Run Cypress tests using OAuth
|
||||
# uses: cypress-io/github-action@v2
|
||||
# with:
|
||||
# working-directory: skills-client-integration/skills-int-e2e-test
|
||||
# record: true
|
||||
# parallel: false
|
||||
# group: 'skills-client oauth tests'
|
||||
# tag: "${{ github.workflow }}"
|
||||
# env: 'authMode=oauth'
|
||||
# env:
|
||||
# # pass the Dashboard record key as an environment variable
|
||||
# CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
# # pass GitHub token to allow accurately detecting a build vs a re-run build
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm run cy:run:oauth
|
||||
cd ../../
|
||||
|
||||
- name: upload result artifacts
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: result artifacts
|
||||
path: |
|
||||
./skills-service/*.jar
|
||||
./skills-client-integration/skills-int-service/target/*.jar
|
||||
./skills-client-integration/skills-int-e2e-test/target/logs/*.out
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/logs
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/**/__diff_output__/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/__diff_output__/*.png
|
||||
@@ -0,0 +1,132 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Continuous Integration
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26
|
||||
JAVA_VERSION: 25
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- .github/workflows/skills-service-backward-compat.yml
|
||||
- .github/workflows/client-libs-backward-compat.yml
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- .github/workflows/skills-service-backward-compat.yml
|
||||
- .github/workflows/client-libs-backward-compat.yml
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
# Docker Hub image
|
||||
image: postgres
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: skillsPassword
|
||||
POSTGRES_DB: skills
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps tcp port 5432 on service container to the host
|
||||
- 5432:5432
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
|
||||
- name: Checkout specific branch fo skills-service
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: NationalSecurityAgency/skills-service
|
||||
path: skills-service
|
||||
|
||||
- name: build skill-service
|
||||
run: |
|
||||
cd skills-service
|
||||
mvn --batch-mode clean install -DskipTests
|
||||
cp ./service/target/skills-service-*.jar ./
|
||||
ls ./
|
||||
cd ..
|
||||
|
||||
- name: setup npm links
|
||||
run: ./.github/workflows/scripts/setupNpmLinks.sh
|
||||
|
||||
- name: build integration test apps
|
||||
env:
|
||||
MAVEN_OPTS: -Xmx2048m
|
||||
run: |
|
||||
cd ./skills-client-integration
|
||||
mvn --batch-mode clean install
|
||||
cd ../
|
||||
|
||||
- name: start services for cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm install
|
||||
npm run cyServices:start:skills-service:ci
|
||||
npm run cyServices:start:integration-apps
|
||||
cd ../../
|
||||
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm run cy:run
|
||||
cd ../../
|
||||
|
||||
- name: upload result artifacts
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: result artifacts
|
||||
path: |
|
||||
./skills-service/*.jar
|
||||
./skills-client-integration/skills-int-service/target/*.jar
|
||||
./skills-client-integration/skills-int-e2e-test/target/logs/*.out
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/logs
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/**/__diff_output__/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/__diff_output__/*.png
|
||||
@@ -0,0 +1,202 @@
|
||||
name: Client Libs Backward Compatibility
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26
|
||||
JAVA_VERSION: 25
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- .github/workflows/skills-service-backward-compat.yml
|
||||
- .github/workflows/client-libs-backward-compat.yml
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- .github/workflows/skills-service-backward-compat.yml
|
||||
- .github/workflows/client-libs-backward-compat.yml
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
get_skills_service_versions:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
services: ${{ steps.generate-matrix.outputs.services }}
|
||||
versions: ${{ steps.generate-matrix.outputs.versions }}
|
||||
steps:
|
||||
- name: Generate Matrix
|
||||
id: generate-matrix
|
||||
run: |
|
||||
TO_EXCLUDE='["3.1.0","3.0.3","3.0.2","3.0.1","3.0.0"]'
|
||||
RESPONSE=$(curl -s -X GET 'https://api.github.com/repos/NationalSecurityAgency/skills-service/releases')
|
||||
ALL_TAG_NAMES=$(echo "$RESPONSE" | jq -c '[.[] | .tag_name]')
|
||||
echo "ALL_TAG_NAMES=$ALL_TAG_NAMES"
|
||||
FILTERED_TAG_NAMES=$(jq --argjson to_exclude "$TO_EXCLUDE" '. - $to_exclude' <<< "$ALL_TAG_NAMES")
|
||||
echo "FILTERED_TAG_NAMES=$FILTERED_TAG_NAMES"
|
||||
TOP_TAGS=$(jq -c '.[0:5]' <<< "$FILTERED_TAG_NAMES")
|
||||
echo "TOP_TAGS=$TOP_TAGS"
|
||||
echo ::set-output name=versions::${TOP_TAGS}
|
||||
|
||||
build_skills_client_int:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: setup npm links
|
||||
run: ./.github/workflows/scripts/setupNpmLinks.sh
|
||||
|
||||
- name: build integration test apps
|
||||
env:
|
||||
MAVEN_OPTS: -Xmx2048m
|
||||
run: |
|
||||
cd ./skills-client-integration
|
||||
mvn --batch-mode clean install
|
||||
cd ../
|
||||
|
||||
- name: upload service jar
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: service jar
|
||||
path: ./skills-client-integration/skills-int-service/target/skills-int-service-*.jar
|
||||
|
||||
run_backward_compatibility_tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
# Docker Hub image
|
||||
image: postgres
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: skillsPassword
|
||||
POSTGRES_DB: skills
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps tcp port 5432 on service container to the host
|
||||
- 5432:5432
|
||||
|
||||
needs:
|
||||
- get_skills_service_versions
|
||||
- build_skills_client_int
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ${{ fromJSON(needs.get_skills_service_versions.outputs.versions) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: download skill-service:${{ matrix.version }}
|
||||
run: |
|
||||
mkdir skills-service
|
||||
cd skills-service
|
||||
wget https://github.com/NationalSecurityAgency/skills-service/releases/download/${{ matrix.version }}/skills-service-${{ matrix.version }}.jar
|
||||
ls ./
|
||||
cd ..
|
||||
|
||||
- name: download integration test apps
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: service jar
|
||||
path: ./skills-client-integration/skills-int-service/target/
|
||||
|
||||
- name: start services for cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm install
|
||||
npm run cyServices:start:skills-service:ci
|
||||
npm run cyServices:start:integration-apps
|
||||
cd ../../
|
||||
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npx cypress run --env skills-service.minVersion=${{ matrix.version }}
|
||||
cd ../../
|
||||
|
||||
- name: upload result artifacts
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: result artifacts for ${{ matrix.version }}
|
||||
path: |
|
||||
./skills-service/*.jar
|
||||
./skills-client-integration/skills-int-service/target/*.jar
|
||||
./skills-client-integration/skills-int-e2e-test/target/logs/*.out
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/logs
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/**/__diff_output__/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/__diff_output__/*.png
|
||||
@@ -0,0 +1,66 @@
|
||||
# Copyright 2025 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "------- START: Build skills-service jar -------"
|
||||
# exit if a command returns non-zero exit code
|
||||
set -e
|
||||
#set -o pipefail
|
||||
|
||||
BRANCH_NAME=$(git branch | grep \*)
|
||||
myGitBranch=${BRANCH_NAME:2}
|
||||
echo "My Git Branch: [${myGitBranch}]"
|
||||
|
||||
if [[ "$myGitBranch" == *"HEAD detached at pull"* ]]; then
|
||||
echo 'We are on a pull-request branch'
|
||||
pullNumber=$(echo "$myGitBranch" | gawk -F'/' '{print $2}' | cat)
|
||||
echo "Looking for branch associated with PR#${pullNumber}"
|
||||
myGitBranch=$(curl -s https://api.github.com/repos/NationalSecurityAgency/skills-client/pulls/"${pullNumber}" | jq -r '.head.ref')
|
||||
echo "Found new Git Branch: [${myGitBranch}]"
|
||||
|
||||
echo "Checkout skill-service code and build it."
|
||||
git clone https://github.com/NationalSecurityAgency/skills-service.git
|
||||
cd ./skills-service/
|
||||
|
||||
echo "Default branch to consider [${myGitBranch}]"
|
||||
matchingBranch=`git branch -a | grep "remotes/origin/${myGitBranch}" | gawk -F'remotes/origin/' '{print $2}' | cat`
|
||||
echo "Matching branch to consider [${matchingBranch}]"
|
||||
if [[ "$myGitBranch" == *\.X ]] || [[ "$myGitBranch" == "master" ]] || [[ -z "$matchingBranch" ]]
|
||||
then
|
||||
echo 'Did not find a matching branch. Downloading latest skills-service release'
|
||||
mkdir skills-service
|
||||
cd skills-service
|
||||
curl -s https://api.github.com/repos/NationalSecurityAgency/skills-service/releases/latest | grep browser_download_url | cut -d '"' -f 4 | wget -qi -
|
||||
ls ./
|
||||
cd ..
|
||||
else
|
||||
switchToBranch=$matchingBranch
|
||||
echo "Found matching branch [${switchToBranch}]"
|
||||
|
||||
echo "Checking out [${switchToBranch}]"
|
||||
git checkout ${switchToBranch} --
|
||||
|
||||
echo "git status:"
|
||||
git status
|
||||
|
||||
export MAVEN_OPTS="-Xmx2048m"
|
||||
mvn --batch-mode package -DskipTests
|
||||
jar=$(ls ./service/target/*.jar)
|
||||
mv $jar ./
|
||||
|
||||
cd ../
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "------- DONE: Build skills-service jar -------"
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2020 SkillTree
|
||||
# Copyright 2025 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -21,12 +21,13 @@ cd skills-client-integration/skills-int-e2e-test
|
||||
npm install
|
||||
|
||||
# start services and wait
|
||||
npm run backend:start:ci &
|
||||
npm run integration:start &
|
||||
npm run backend:waitToStart
|
||||
npm run integration:waitToStart
|
||||
npm run cyServices:start:skills-service:ci
|
||||
npm run cyServices:start:integration-apps
|
||||
|
||||
# run tests
|
||||
npm run cy:run
|
||||
|
||||
npm run cyServices:kill
|
||||
cd ../../
|
||||
echo "------- DONE: Run Cypress Tests -------"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
# exit if a command returns non-zero exit code
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
DB=${DB:-postgres}
|
||||
TRACING=${TRACING:-false}
|
||||
PROMETHEUS=${PROMETHEUS:-false}
|
||||
echo "PWD: "
|
||||
echo $(pwd)
|
||||
cd ./skills-client-integration/skills-int-e2e-test/hydra
|
||||
DC="docker compose -f quickstart.yml"
|
||||
if [[ $DB == "mysql" ]]; then
|
||||
DC+=" -f quickstart-mysql.yml"
|
||||
fi
|
||||
if [[ $DB == "postgres" ]]; then
|
||||
DC+=" -f quickstart-postgres.yml"
|
||||
fi
|
||||
if [[ $TRACING == true ]]; then
|
||||
DC+=" -f quickstart-tracing.yml"
|
||||
fi
|
||||
if [[ $PROMETHEUS == true ]]; then
|
||||
DC+=" -f quickstart-prometheus.yml"
|
||||
fi
|
||||
DC+=" up --build -d"
|
||||
|
||||
$DC
|
||||
|
||||
declare -r HOST="localhost:4445/clients"
|
||||
|
||||
wait-for-url() {
|
||||
echo "Waiting for hydra service $1 ..."
|
||||
timeout -s TERM 45 bash -c \
|
||||
'while [[ "$(curl -X GET -s -o /dev/null -w ''%{http_code}'' ${0})" != "200" ]];\
|
||||
do echo "Waiting for ${0}" && sleep 2;\
|
||||
done' ${1}
|
||||
echo "OK!"
|
||||
}
|
||||
wait-for-url http://${HOST}
|
||||
@@ -0,0 +1,47 @@
|
||||
# Copyright 2025 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#!/usr/bin/env bash
|
||||
# exit if a command returns non-zero exit code
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
echo "------- START: Setup npm links -------"
|
||||
cd skills-client-js
|
||||
echo "------- skills-client-js: npm link -------"
|
||||
npm link
|
||||
cd ../skills-client-integration/skills-int-client-js/
|
||||
echo "------- skills-int-client-js: npm link @skilltree/skills-client-js -------"
|
||||
npm link @skilltree/skills-client-js
|
||||
|
||||
cd ../../skills-client-js
|
||||
echo "------- skills-client-js: npm install -------"
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
echo "------- skills-int-client-js: npm install -------"
|
||||
cd ../skills-client-integration/skills-int-client-js/
|
||||
npm install
|
||||
|
||||
echo "------- validate npm links -------"
|
||||
if ! npm ls --link --global | grep "skills-client-js"; then
|
||||
echo "Error: skills-client-js is not properly linked"
|
||||
exit 1
|
||||
else
|
||||
echo "Verified: skills-client-js is properly linked"
|
||||
fi
|
||||
|
||||
echo "------- skills-int-client-js: npm run build -------"
|
||||
npm run build
|
||||
|
||||
echo "------- DONE: Setup npm links -------"
|
||||
@@ -0,0 +1,244 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Skills-service Backward Compatibility
|
||||
|
||||
env:
|
||||
NODE_VERSION: 26
|
||||
JAVA_VERSION: 25
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
schedule:
|
||||
- cron: '0 6 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
|
||||
build-skills-service:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: |
|
||||
11
|
||||
${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: Checkout specific branch fo skills-service
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: NationalSecurityAgency/skills-service
|
||||
path: skills-service
|
||||
|
||||
- name: build skill-service
|
||||
run: |
|
||||
cd skills-service
|
||||
mvn --batch-mode clean install -DskipTests
|
||||
cd ..
|
||||
|
||||
- name: upload service jar
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: service jar
|
||||
path: ./skills-service/service/target/skills-service-*.jar
|
||||
|
||||
test-skill-service-backward-compat:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-skills-service]
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
skillsJsVersion: [ '3.1.1', '3.2.0', '3.3.0', '3.3.1', '3.4.0', '3.4.1', '3.5.0']
|
||||
|
||||
services:
|
||||
postgres:
|
||||
# Docker Hub image
|
||||
image: postgres
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: skillsPassword
|
||||
POSTGRES_DB: skills
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
# Maps tcp port 5432 on service container to the host
|
||||
- 5432:5432
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: |
|
||||
11
|
||||
${{ env.JAVA_VERSION }}
|
||||
|
||||
- name: Print Versions
|
||||
run: |
|
||||
mvn --version
|
||||
java -version
|
||||
npm -version
|
||||
node --version
|
||||
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
# - name: build skill-service
|
||||
# run: ./.github/workflows/scripts/getSkillsService.sh
|
||||
# - name: download skill-service
|
||||
# run: |
|
||||
# mkdir skills-service
|
||||
# cd skills-service
|
||||
# curl -s https://api.github.com/repos/NationalSecurityAgency/skills-service/releases/latest | grep browser_download_url | cut -d '"' -f 4 | wget -qi -
|
||||
# ls ./
|
||||
# cd ..
|
||||
|
||||
# - name: Checkout specific branch fo skills-service
|
||||
# uses: actions/checkout@v6
|
||||
# with:
|
||||
# repository: NationalSecurityAgency/skills-service
|
||||
# path: skills-service
|
||||
#
|
||||
# - name: build skill-service
|
||||
# run: |
|
||||
# cd skills-service
|
||||
# mvn --batch-mode clean install -DskipTests
|
||||
# cp ./service/target/skills-service-*.jar ./
|
||||
# ls ./
|
||||
# cd ..
|
||||
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: service jar
|
||||
path: ./skills-service/
|
||||
|
||||
- name: build integration test apps
|
||||
env:
|
||||
MAVEN_OPTS: -Xmx2048m
|
||||
run: |
|
||||
cd ./skills-client-integration/skills-int-client-js
|
||||
npm install @skilltree/skills-client-js@${{ matrix.skillsJsVersion }} --save-exact
|
||||
cd ..
|
||||
mvn --batch-mode clean install
|
||||
cd ../
|
||||
|
||||
- name: start services for cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm install
|
||||
ls ../
|
||||
echo "------"
|
||||
ls ../../
|
||||
echo "------"
|
||||
ls ../../skills-service/
|
||||
echo "------"
|
||||
npm run cyServices:start:skills-service:ci
|
||||
npm run cyServices:start:integration-apps
|
||||
cd ../../
|
||||
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: |
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
npm run cy:run
|
||||
cd ../../
|
||||
|
||||
- name: upload result artifacts
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: result artifacts for [${{ matrix.skillsJsVersion }}] version
|
||||
path: |
|
||||
./skills-service/*.jar
|
||||
./skills-client-integration/skills-int-service/target/*.jar
|
||||
./skills-client-integration/skills-int-e2e-test/target/logs/*.out
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/logs
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/videos
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/screenshots
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/**/__diff_output__/*.png
|
||||
./skills-client-integration/skills-int-e2e-test/cypress/snapshots/**/__diff_output__/*.png
|
||||
|
||||
|
||||
# - name: run backwards compat tests
|
||||
# run: |
|
||||
# cd skills-client-integration/skills-int-e2e-test
|
||||
# mvn --batch-mode clean package
|
||||
# export NO_COLOR=1
|
||||
# java -jar target/skills-int-e2e-test-*.jar
|
||||
# cd ../../
|
||||
#
|
||||
# - name: upload result artifacts
|
||||
# if: ${{ always() }}
|
||||
# uses: actions/upload-artifact@v7
|
||||
# with:
|
||||
# name: result artifacts
|
||||
# path: |
|
||||
# ./skills-client-integration/skills-int-e2e-test/target/logs/*
|
||||
# ./skills-client-integration/skills-int-e2e-test/target/skills-client/skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
# ./skills-client-integration/skills-int-e2e-test/target/skills-client/skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
# ./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
# ./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
# /home/runner/.npm/_logs/*
|
||||
@@ -6,3 +6,13 @@
|
||||
|
||||
.history
|
||||
/target/
|
||||
/skills-client-integration/skills-int-e2e-test/logs/
|
||||
/skills-client-integration/skills-int-e2e-test/cypress/videos/
|
||||
/skills-client-integration/skills-int-e2e-test/nohup.out
|
||||
/skills-client-vue/package-lock.json
|
||||
/skills-client-react/package-lock.json
|
||||
/skills-client-js/package-lock.json
|
||||
/skills-client-ng/package-lock.json
|
||||
/skills-client-ng/dist/
|
||||
/skills-client-ng/projects/skilltree/skills-client-ng/src/version.js
|
||||
/skills-client-integration/skills-int-e2e-test/cypress/downloads/*
|
||||
@@ -1,82 +0,0 @@
|
||||
stages:
|
||||
- build
|
||||
- testCypress
|
||||
- pushToNexus
|
||||
- deploy
|
||||
|
||||
build:
|
||||
image: maven:3.6.0-jdk-11
|
||||
stage: build
|
||||
before_script:
|
||||
- ./skills-client-integration/ci/setupNode.sh
|
||||
- ./skills-client-integration/ci/setupRepos.sh
|
||||
script:
|
||||
- ./skills-client-integration/ci/getSkillsService.sh
|
||||
- ./skills-client-integration/ci/setupNpmLinks.sh
|
||||
- cd ./skills-client-integration
|
||||
- mvn --batch-mode clean install
|
||||
- cd ../
|
||||
artifacts:
|
||||
paths:
|
||||
- ./skills-client-integration/skills-int-service/target/*.jar
|
||||
- ./skills-client-integration/skills-int-service/target/*.log
|
||||
- ./skills-client-integration/skills-int-e2e-test/target/*.jar
|
||||
- ./skills-client-integration/skills-int-e2e-test/target/*.log
|
||||
- ./skills-client-integration/target/*.log
|
||||
- ./skills-service/*.jar
|
||||
|
||||
testCypress:
|
||||
image: olehsrh/cypress:1
|
||||
stage: testCypress
|
||||
before_script:
|
||||
- ./skills-client-integration/ci/setupRepos.sh
|
||||
script:
|
||||
- ./skills-client-integration/ci/runCypressTests.sh
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- ./skills-client-integration/skills-int-e2e-test/cypress/videos/*.mp4
|
||||
- ./skills-client-integration/skills-int-e2e-test/cypress/screenshots/**/*.png
|
||||
expire_in: 1 day
|
||||
|
||||
pushToNexus:
|
||||
image: maven:3.6.0-jdk-11
|
||||
stage: pushToNexus
|
||||
before_script:
|
||||
- ./skills-client-integration/ci/setupRepos.sh
|
||||
script:
|
||||
- cd skills-client-integration/skills-int-service
|
||||
- jar=$(ls ./target/skills-int-service-*.jar)
|
||||
- echo $jar
|
||||
- mvn --batch-mode deploy:deploy-file -DpomFile=./pom.xml -Dfile=${jar} -Durl=http://${NEXUS_SERVER}/repository/maven-snapshots/ -DrepositoryId=nexus-snapshots
|
||||
artifacts:
|
||||
paths:
|
||||
- skills-client-integration/skills-int-service/target/skills-int-service-*.jar
|
||||
only:
|
||||
refs:
|
||||
- branches
|
||||
variables:
|
||||
- $BRANCH_TO_DEPLOY_SKILLS_CLIENT == $CI_COMMIT_REF_NAME
|
||||
|
||||
deploy:
|
||||
image: alpine:latest
|
||||
stage: deploy
|
||||
before_script:
|
||||
- apk --update --no-cache add sshpass openssh git
|
||||
script:
|
||||
- git clone https://${GITLAB_DEPLOY_USERNAME}:${GITLAB_DEPLOY_PASSWORD}@gitlab.evoforge.org/skills/skills-deploy.git
|
||||
- TIMESTAMP=`date +%s`
|
||||
- TMP_DIR="skills-int-service_${TIMESTAMP}"
|
||||
- DEST_PATH="/home/${CI_USERNAME}/$TMP_DIR"
|
||||
- sshpass -p $CI_PASSWORD ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no $CI_USERNAME@$CI_IP "rm -rf /home/${CI_USERNAME}/skills-int-service_* && mkdir -p ${DEST_PATH}"
|
||||
- cp skills-client-integration/skills-int-service/target/skills-int-service-*.jar skills-int-service.jar
|
||||
- sshpass -p $CI_PASSWORD scp -r skills-deploy ${CI_USERNAME}@${CI_IP}:${DEST_PATH}
|
||||
- sshpass -p $CI_PASSWORD scp -r skills-int-service.jar ${CI_USERNAME}@${CI_IP}:${DEST_PATH}/skills-deploy/skills-client-integration/
|
||||
- sshpass -p $CI_PASSWORD ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no $CI_USERNAME@$CI_IP "cd ${DEST_PATH}/skills-deploy/skills-client-integration && ./runDeploy.sh"
|
||||
only:
|
||||
refs:
|
||||
- branches
|
||||
variables:
|
||||
- $BRANCH_TO_DEPLOY_SKILLS_CLIENT == $CI_COMMIT_REF_NAME
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
## Legal
|
||||
|
||||
Consistent with Section D.6. of the GitHub Terms of Service as of 2019, and Section 5. of the Apache License, Version 2.0, the project maintainer for this project accepts contributions using the inbound=outbound model.
|
||||
When you submit a pull request to this repository (inbound), you are agreeing to license your contribution under the same terms as specified in [LICENSE] (outbound).
|
||||
|
||||
This is an open source project.
|
||||
Contributions you make to this public U.S. Government ("USG") repository are completely voluntary.
|
||||
When you submit an issue, bug report, question, enhancement, pull request, etc., you are offering your contribution without expectation of payment, you expressly waive any future pay claims against the USG related to your contribution, and you acknowledge that this does not create an obligation on the part of the USG of any kind.
|
||||
Furthermore, your contributing to this project does not create an employer-employee relationship between the United States ("U.S.") Government and the contributor.
|
||||
|
||||
[LICENSE]: LICENSE.txt
|
||||
@@ -0,0 +1,13 @@
|
||||
# Disclaimer of Warranty
|
||||
|
||||
This Work is provided "AS IS."
|
||||
Any express or implied warranties, including but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
In no event shall the United States Government be liable for any direct, indirect, incidental, special, exemplary or consequential damages (including, but not limited to, procurement of substitute goods or services, loss of use, data or profits, or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this Work, even if advised of the possibility of such damage.
|
||||
|
||||
The User of this Work agrees to hold harmless and indemnify the United States Government, its agents and employees from every claim or liability (whether in tort or in contract), including attorney's fees, court costs, and expenses, arising in direct consequence of Recipient's use of the item, including, but not limited to, claims or liabilities made for injury to or death of personnel of User or third parties, damage to or destruction of property of User or third parties, and infringement or other violations of intellectual property or technical data rights.
|
||||
|
||||
# Disclaimer of Endorsement
|
||||
|
||||
Nothing in this Work is intended to constitute an endorsement, explicit or implied, by the United States Government of any particular manufacturer's product or service.
|
||||
|
||||
Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, or otherwise, in this Work does not constitute an endorsement, recommendation, or favoring by the United States Government and shall not be used for advertising or product endorsement purposes.
|
||||
@@ -0,0 +1,19 @@
|
||||
## Licensing Intent
|
||||
|
||||
The intent is that this software and documentation ("Project") should be treated
|
||||
as if it is licensed under the license associated with the Project ("License")
|
||||
in the LICENSE file. However, because we are part of the United States (U.S.)
|
||||
Federal Government, it is not that simple.
|
||||
|
||||
The portions of this Project written by U.S. Federal Government employees within
|
||||
the scope of their federal employment are ineligible for copyright protection in
|
||||
the U.S.; this is generally understood to mean that these portions of the
|
||||
Project are placed in the public domain.
|
||||
|
||||
In countries where copyright protection is available (which does not include the
|
||||
U.S.), contributions made by U.S. Federal Government employees are released
|
||||
under the License. Merged contributions from private contributors are released
|
||||
under the License.
|
||||
|
||||
The SkillTree software is released under the Apache License, Version 2.0
|
||||
("Apache 2.0").
|
||||
@@ -0,0 +1,31 @@
|
||||
# SkillTree Client Libraries
|
||||
<p>
|
||||
<img src="https://img.shields.io/npm/d18m/%40skilltree%2Fskills-client-js" alt="npm downloads">
|
||||
<img src="https://img.shields.io/npm/dw/%40skilltree%2Fskills-client-js" alt="npm weekly downloads">
|
||||
<img src="https://img.shields.io/npm/l/%40skilltree%2Fskills-client-js" alt="License">
|
||||
<img src="https://img.shields.io/npm/v/%40skilltree%2Fskills-client-js" alt="Latest Version">
|
||||
<img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/%40skilltree%2Fskills-client-js">
|
||||
</p>
|
||||
|
||||
SkillTree is an innovative approach to implementing application training. SkillTree's ``skills-client-js`` project facilitates rapid integration with the SkillTree service.
|
||||
|
||||
To learn about the SkillTree platform please visit our [Official Documentation](https://skilltreeplatform.dev/).
|
||||
These pages provide in-depth guidance on the installation, usage and contribution.
|
||||
|
||||
## Workflow Status
|
||||
|
||||
[](https://github.com/NationalSecurityAgency/skills-client/actions/workflows/build-and-test.yml)
|
||||
|
||||
[](https://github.com/NationalSecurityAgency/skills-client/actions/workflows/build-and-test-oauth.yml)
|
||||
|
||||
[](https://github.com/NationalSecurityAgency/skills-client/actions/workflows/build-and-test-expired-token.yml)
|
||||
|
||||
[](https://github.com/NationalSecurityAgency/skills-client/actions/workflows/skills-service-backward-compat.yml)
|
||||
|
||||
[](https://github.com/NationalSecurityAgency/skills-client/actions/workflows/client-libs-backwards-compat.yml)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# skills-client
|
||||
|
||||
@@ -7,6 +7,7 @@ target
|
||||
skills-example-service/src/main/resources/public/native
|
||||
skills-example-service/src/main/resources/public/vuejs
|
||||
skills-example-service/src/main/resources/public/react
|
||||
skills-example-service/src/main/resources/public/angular
|
||||
|
||||
.DS_Store
|
||||
node_modules
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
# Copyright 2020 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "------- START: Build skills-service jar -------"
|
||||
# exit if a command returns non-zero exit code
|
||||
set -e
|
||||
#set -o pipefail
|
||||
|
||||
apt-get install -y gawk
|
||||
|
||||
myGitBranch=${CI_COMMIT_REF_NAME}
|
||||
echo "My Git Branch: [${myGitBranch}]"
|
||||
|
||||
echo "Checkout skill-service code and build it."
|
||||
git clone https://${DEPLOY_TOKEN_SKILLS_SERVICE}:${DEPLOY_TOKEN_SKILLS_SERVICE_PASS}@gitlab.evoforge.org/skills/skills-service.git
|
||||
cd ./skills-service/
|
||||
|
||||
switchToBranch=$BRANCH_TO_DEPLOY_SKILLS_SERVICE
|
||||
echo "Default branch to consider [${switchToBranch}]"
|
||||
matchingBranch=`git branch -a | grep "remotes/origin/${myGitBranch}" | gawk -F'remotes/origin/' '{print $2}' | cat`
|
||||
echo "Matching branch to consider [${matchingBranch}]"
|
||||
if [[ "$myGitBranch" == *\.X ]] || [[ "$myGitBranch" == "master" ]] || [[ -z "$matchingBranch" ]]
|
||||
then
|
||||
echo "Building skill-service from configured [${switchToBranch}] branch"
|
||||
else
|
||||
switchToBranch=$matchingBranch
|
||||
echo "Found matching branch [${switchToBranch}]"
|
||||
fi
|
||||
|
||||
if [[ -z "$switchToBranch" ]]
|
||||
then
|
||||
exit -1
|
||||
fi
|
||||
|
||||
echo "Checking out [${switchToBranch}]"
|
||||
git checkout ${switchToBranch} --
|
||||
|
||||
echo "git status:"
|
||||
git status
|
||||
|
||||
mvn --batch-mode package -DskipTests
|
||||
jar=$(ls ./backend/target/*.jar)
|
||||
mv $jar ./
|
||||
|
||||
cd ../
|
||||
echo "------- DONE: Build skills-service jar -------"
|
||||
@@ -1,24 +0,0 @@
|
||||
# Copyright 2020 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "------- START: Setup Node -------"
|
||||
cat /etc/os-release
|
||||
apt-get update
|
||||
apt-get install -y build-essential
|
||||
curl -sL https://deb.nodesource.com/setup_12.x | bash -
|
||||
apt-get install -y nodejs
|
||||
node -v
|
||||
npm -v
|
||||
echo "------- DONE: Setup Node -------"
|
||||
@@ -1,27 +0,0 @@
|
||||
# Copyright 2020 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#!/usr/bin/env bash
|
||||
# exit if a command returns non-zero exit code
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
echo "------- START: Setup npm links -------"
|
||||
cd skills-client-integration/skills-int-e2e-test
|
||||
mvn --batch-mode clean package
|
||||
ls -la target/skills-int-e2e-test-*.jar
|
||||
du -sh target/*
|
||||
java --version
|
||||
java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.SetupNpmLinks org.springframework.boot.loader.PropertiesLauncher
|
||||
cd ../../
|
||||
echo "------- DONE: Setup npm links -------"
|
||||
@@ -1,24 +0,0 @@
|
||||
# Copyright 2020 SkillTree
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#!/usr/bin/env bash
|
||||
# exit if a command returns non-zero exit code
|
||||
set -e
|
||||
set -o pipefail
|
||||
echo "------- START: Setup Repos -------"
|
||||
echo "@skills:registry=http://$NEXUS_SERVER/repository/skills-registry/" > ~/.npmrc
|
||||
cat ~/.npmrc
|
||||
mkdir -p ~/.m2
|
||||
cat ./skills-client-integration/skills-int-e2e-test/serverConfigs/settings.xml | sed s/NEXUS_SERVER/$NEXUS_SERVER/ | sed s/NEXUS_PASS/$NEXUS_PASS/ > ~/.m2/settings.xml
|
||||
cat ~/.m2/settings.xml
|
||||
echo "------- DONE: Setup Repos -------"
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright 2020 SkillTree
|
||||
Copyright 2025 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"ignore": [ ".git", "coverage", ".*/**", ".*", "*.iml", "babel.config.js",
|
||||
"rollup.config.js", "app/assets/**", "target/**", "pom.xml",
|
||||
"build/**", "**/robots.txt", "**.svg", "vue.config.js",
|
||||
"cypress/videos/**", "**/*.jar", "**.xml", "src/license/*.properties"
|
||||
"cypress/videos/**", "**/*.jar", "**.xml", "src/license/*.properties",
|
||||
"nohup.out", "logs/*", "**.patch", "**.yml", "cypress/downloads/**", "**.config.js"
|
||||
],
|
||||
"license": "../license-add/LICENSE-HEADER.txt",
|
||||
"licenseFormats": {
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.6.RELEASE</version>
|
||||
<version>3.5.16</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>skills</groupId>
|
||||
<artifactId>skills-client-integration</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<version>3.6.3-SNAPSHOT</version>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
@@ -25,34 +25,16 @@
|
||||
|
||||
<modules>
|
||||
<module>skills-int-client-js</module>
|
||||
<module>skills-int-client-vue</module>
|
||||
<module>skills-int-client-react</module>
|
||||
<module>skills-int-service</module>
|
||||
<module>skills-int-e2e-test</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<!--suppress UnresolvedMavenProperty -->
|
||||
<nexusServer>${nexus.url}</nexusServer>
|
||||
<node.version>v11.6.0</node.version>
|
||||
<frontend-maven-plugin.version>1.10.3</frontend-maven-plugin.version>
|
||||
|
||||
<!-- TODO: Temporary override spring boot versions, remove once spring boot upgrades these versions -->
|
||||
<commons-lang3.version>3.19.0</commons-lang3.version>
|
||||
</properties>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>nexus-releases</id>
|
||||
<name>Release Repository</name>
|
||||
<uniqueVersion>false</uniqueVersion>
|
||||
<url>
|
||||
${nexusServer}/repository/maven-releases/
|
||||
</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>nexus-snapshots</id>
|
||||
<name>Snapshot Repository</name>
|
||||
<uniqueVersion>true</uniqueVersion>
|
||||
<url>
|
||||
${nexusServer}/repository/maven-snapshots/
|
||||
</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
</project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright 2020 SkillTree
|
||||
Copyright 2025 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,26 +17,34 @@ limitations under the License.
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Skills Examples - Native Javascript</title>
|
||||
<title>Skill Client Test</title>
|
||||
<link rel="icon" type="image/x-icon" href="./skilltree.ico">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="./assets/app.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./assets/js/bootstrap/dist/css/bootstrap.css">
|
||||
|
||||
<script type="text/javascript" src="./assets/js/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/axios/dist/axios.min.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/js-beautify/js/lib/beautify.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/bootstrap/dist/js/bootstrap.bundle.js"></script>
|
||||
|
||||
<script type="text/javascript" src="assets/js/@skills/skills-client-js/dist/skills-client-js.umd.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/@skilltree/skills-client-js/dist/skills-client-js.umd.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const isSummaryOnly = params.get('isSummaryOnly') ? JSON.parse(params.get('isSummaryOnly')) : false;
|
||||
|
||||
let clientDisplay = null;
|
||||
|
||||
const options = {
|
||||
autoScrollStrategy: 'top-of-page',
|
||||
isSummaryOnly,
|
||||
};
|
||||
|
||||
const internalBackButtonParam = 'internalBackButton'
|
||||
if (params.get(internalBackButtonParam)) {
|
||||
options.internalBackButton = JSON.parse(params.get(internalBackButtonParam))
|
||||
}
|
||||
|
||||
const themes = {
|
||||
default: {
|
||||
name: 'Bright (default)',
|
||||
@@ -85,6 +93,16 @@ limitations under the License.
|
||||
window.location.search = params;
|
||||
};
|
||||
|
||||
const navigate = () => {
|
||||
clientDisplay.navigate('/subjects/subj0');
|
||||
}
|
||||
|
||||
const setInternalBackButton = () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.set('internalBackButton', !options.internalBackButton);
|
||||
window.location.search = params;
|
||||
}
|
||||
|
||||
const getTheme = () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
let themeName = params.get('themeName') ? params.get('themeName') : 'Bright (default)';
|
||||
@@ -98,6 +116,9 @@ limitations under the License.
|
||||
return version;
|
||||
};
|
||||
|
||||
const handleRouteChanged = (newPath) => {
|
||||
document.querySelector('#skillsDisplayPath').innerHTML = `Skills Display Path: [${newPath}]`;
|
||||
};
|
||||
axios.get("/api/config")
|
||||
.then((result) => {
|
||||
SkillsClient.SkillsConfiguration.configure(result.data);
|
||||
@@ -116,10 +137,11 @@ limitations under the License.
|
||||
defaultThemeElement.classList.add('active');
|
||||
}
|
||||
|
||||
const clientDisplay = new SkillsClient.SkillsDisplayJS({
|
||||
clientDisplay = new SkillsClient.SkillsDisplayJS({
|
||||
options,
|
||||
version: getVersion(),
|
||||
theme: theme.theme,
|
||||
handleRouteChanged: handleRouteChanged,
|
||||
});
|
||||
clientDisplay.attachTo(document.querySelector('#skills-client-display'));
|
||||
};
|
||||
@@ -137,53 +159,62 @@ limitations under the License.
|
||||
|
||||
<div id="app">
|
||||
<div>
|
||||
<div>
|
||||
<nav class="navbar navbar-dark bg-info">
|
||||
<a href="#" class="navbar-brand">Native Javascript Integration Examples</a>
|
||||
|
||||
<ul class="navbar-nav flex-row mr-auto">
|
||||
<li class="nav-item pr-3">
|
||||
<a class="nav-link" href="index.html">Report Skill Events</a>
|
||||
</li>
|
||||
<li class="nav-item active pr-3">
|
||||
<a class="nav-link" href="javascript:void(0)">User Display</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;">
|
||||
<div class="container-fluid">
|
||||
<a href="#" class="navbar-brand">Client Test</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" aria-current="page" href="index.html" data-cy="reportSkillsLink">Report Skill Events</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="javascript:void(0)" data-cy="userDisplayLink">User Display</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="container">
|
||||
<div class="">
|
||||
<div class="form-row align-items-center">
|
||||
<div class="d-inline dropdown">
|
||||
<button class="btn btn-outline-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Change Theme
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<a class="dropdown-item" href="javascript:void(0)" id="default-theme-dropdown-item" onclick="applyTheme(themes.default)">Bright (Default)</a>
|
||||
<a class="dropdown-item" href="javascript:void(0)" id="darkblue-theme-dropdown-item" onclick="applyTheme(themes.darkBlue)">Dark Blue</a>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="d-inline custom-control custom-checkbox mx-2">
|
||||
<input type="checkbox" class="custom-control-input" id="displayTypeControl" onclick="setDisplayType()" checked>
|
||||
<label class="custom-control-label" for="displayTypeControl">Summary Only</label>
|
||||
</div>
|
||||
<div class="d-inline custom-control custom-checkbox mx-2">
|
||||
<input type="checkbox" class="custom-control-input" id="internalBackButtonControl" onclick="setInternalBackButton()" checked>
|
||||
<label class="custom-control-label" for="internalBackButtonControl">Internal Back Button</label>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" type="button" data-cy="navigateButton" onclick="navigate()">
|
||||
Navigate
|
||||
</button>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<span id="skillsDisplayPath" data-cy="skillsDisplayPath"></span>
|
||||
</div>
|
||||
<div
|
||||
style="min-height: 860px">
|
||||
<div id="skills-client-display" />
|
||||
<div id="skills-client-display"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="text-muted bg-light py-5">
|
||||
<div class="container">
|
||||
<p>Native Javascript Examples Guide</p>
|
||||
<p></p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -192,4 +223,5 @@ limitations under the License.
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementById("displayTypeControl").checked = isSummaryOnly;
|
||||
document.getElementById("internalBackButtonControl").checked = params.get(internalBackButtonParam) ? JSON.parse(params.get(internalBackButtonParam)) : false
|
||||
</script>
|
||||
@@ -0,0 +1,66 @@
|
||||
<!--
|
||||
Copyright 2025 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Skill Client Test</title>
|
||||
<link rel="icon" type="image/x-icon" href="./skilltree.ico">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="./assets/app.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./assets/js/bootstrap/dist/css/bootstrap.css">
|
||||
|
||||
<script type="text/javascript" src="./assets/js/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/axios/dist/axios.min.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/bootstrap/dist/js/bootstrap.bundle.js"></script>
|
||||
|
||||
<script type="text/javascript" src="assets/js/@skilltree/skills-client-js/dist/skills-client-js.umd.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
axios.get("/api/config")
|
||||
.then((result) => {
|
||||
SkillsClient.SkillsConfiguration.configure(result.data);
|
||||
});
|
||||
|
||||
SkillsClient.SkillsConfiguration.afterConfigure().then(() => {
|
||||
const initializeSkillsDisplay = () => {
|
||||
const clientDisplay = new SkillsClient.SkillsDisplayJS();
|
||||
clientDisplay.attachTo(document.querySelector('#skills-client-display'));
|
||||
};
|
||||
if (document.readyState === "complete"
|
||||
|| document.readyState === "loaded"
|
||||
|| document.readyState === "interactive") {
|
||||
initializeSkillsDisplay();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", initializeSkillsDisplay);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="app">
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="container">
|
||||
<div style="min-height: 860px">
|
||||
<div id="skills-client-display"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!--
|
||||
Copyright 2025 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Skill Client Test</title>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="./skilltree.ico">
|
||||
<link rel="stylesheet" type="text/css" href="./assets/app.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./assets/js/bootstrap/dist/css/bootstrap.css">
|
||||
|
||||
<script type="text/javascript" src="./assets/js/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/axios/dist/axios.min.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/bootstrap/dist/js/bootstrap.bundle.js"></script>
|
||||
|
||||
<script type="module">
|
||||
import { SkillsReporter, SkillsConfiguration, SkillsLevelJS, SkillsDisplayJS, Logger } from './assets/js/@skilltree/skills-client-js/dist/skills-client-js.esm.min.js'
|
||||
|
||||
axios.get("/api/config")
|
||||
.then((result) => {
|
||||
SkillsConfiguration.configure({...result.data, enabled: false});
|
||||
});
|
||||
|
||||
document.querySelector('#reportSkillBtn').addEventListener('click', () => {
|
||||
SkillsReporter.reportSkill('someId')
|
||||
});
|
||||
|
||||
SkillsConfiguration.afterConfigure().then(() => {
|
||||
const initializeSkillsDisplay = () => {
|
||||
const clientDisplay = new SkillsDisplayJS();
|
||||
clientDisplay.attachTo(document.querySelector('#skills-client-display'));
|
||||
};
|
||||
if (document.readyState === "complete"
|
||||
|| document.readyState === "loaded"
|
||||
|| document.readyState === "interactive") {
|
||||
initializeSkillsDisplay();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", initializeSkillsDisplay);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="app">
|
||||
<button
|
||||
id="reportSkillBtn"
|
||||
data-cy="reportSkillButton"
|
||||
class="btn btn-outline-primary">
|
||||
Report Skill
|
||||
</button>
|
||||
|
||||
<div data-cy="levelComponentRes">Level: [<span id="skillLevel"/>]</div>
|
||||
<div data-cy="skillsDisplayRes">Skills Display: [<div id="skills-client-display"></div>]</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright 2020 SkillTree
|
||||
Copyright 2025 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,39 +17,60 @@ limitations under the License.
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Skills Examples - Native Javascript</title>
|
||||
<title>Skill Client Test</title>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="./skilltree.ico">
|
||||
<link rel="stylesheet" type="text/css" href="./assets/app.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="./assets/js/bootstrap/dist/css/bootstrap.css">
|
||||
|
||||
<script type="text/javascript" src="./assets/js/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/axios/dist/axios.min.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/js-beautify/js/lib/beautify.js"></script>
|
||||
<script type="text/javascript" src="./assets/js/bootstrap/dist/js/bootstrap.bundle.js"></script>
|
||||
|
||||
<script type="module">
|
||||
import { SkillsReporter, SkillsConfiguration } from './assets/js/@skills/skills-client-js/dist/skills-client-js.esm.min.js'
|
||||
import { SkillsReporter, SkillsConfiguration, SkillsLevelJS, Logger } from './assets/js/@skilltree/skills-client-js/dist/skills-client-js.esm.min.js'
|
||||
|
||||
axios.get("/api/config")
|
||||
.then((result) => {
|
||||
SkillsConfiguration.configure(result.data);
|
||||
});
|
||||
SkillsConfiguration.afterConfigure()
|
||||
.then(() => {
|
||||
SkillsReporter.addSuccessHandler((result) => {
|
||||
document.querySelector('#global-event-result-container-js').innerHTML = JSON.stringify(result, null, 2);
|
||||
});
|
||||
|
||||
SkillsReporter.addSuccessHandler((result) => {
|
||||
document.querySelector('#global-event-result-container-js').innerHTML = JSON.stringify(result, null, 2);
|
||||
});
|
||||
SkillsReporter.addErrorHandler((result) => {
|
||||
document.querySelector('#global-event-result-container-js').innerHTML = JSON.stringify(result, null, 2);
|
||||
});
|
||||
|
||||
const reportSkill = (skillId) => {
|
||||
SkillsReporter.reportSkill(skillId)
|
||||
.then((response) => {
|
||||
document.querySelector('#report-result-container').innerHTML = JSON.stringify(response, null, 2);
|
||||
});
|
||||
};
|
||||
document.querySelector('#exampleDirectiveClickEvent').addEventListener('click', () => { reportSkill('IronMan'); });
|
||||
const reportSkill = (skillId) => {
|
||||
SkillsReporter.reportSkill(skillId)
|
||||
.then((response) => {
|
||||
document.querySelector('#report-result-container').innerHTML = JSON.stringify(response, null, 2);
|
||||
}).catch((err) => {
|
||||
document.querySelector('#report-result-container').innerHTML = JSON.stringify(err, null, 2);
|
||||
});
|
||||
};
|
||||
|
||||
const toggleAllEvents = () => {
|
||||
const notifyIfSkillNotApplied = document.querySelector('#all-events-check').checked
|
||||
SkillsReporter.configure( { notifyIfSkillNotApplied });
|
||||
}
|
||||
document.querySelector('#all-events-check').addEventListener('click', toggleAllEvents);
|
||||
document.querySelector('#exampleDirectiveClickEvent').addEventListener('click', () => {
|
||||
var skillId = document.getElementById('skillId').value;
|
||||
reportSkill(skillId);
|
||||
});
|
||||
|
||||
const toggleAllEvents = () => {
|
||||
const notifyIfSkillNotApplied = document.querySelector('#all-events-check').checked
|
||||
SkillsReporter.configure({notifyIfSkillNotApplied});
|
||||
}
|
||||
document.querySelector('#all-events-check').addEventListener('click', toggleAllEvents);
|
||||
toggleAllEvents();
|
||||
|
||||
if (window.Cypress) {
|
||||
window.skillsLogger = Logger;
|
||||
}
|
||||
const skillLevel = new SkillsLevelJS();
|
||||
skillLevel.attachTo('#skillLevel')
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
@@ -58,17 +79,26 @@ limitations under the License.
|
||||
<div id="app">
|
||||
<div>
|
||||
<div>
|
||||
<nav class="navbar navbar-dark bg-info">
|
||||
<a href="#" class="navbar-brand">Native Javascript Integration Examples</a>
|
||||
|
||||
<ul class="navbar-nav flex-row mr-auto">
|
||||
<li class="nav-item active pr-3">
|
||||
<a class="nav-link" href="javascript:void(0)">Report Skill Events</a>
|
||||
</li>
|
||||
<li class="nav-item pr-3">
|
||||
<a class="nav-link" href="clientDisplay.html">User Display</a>
|
||||
</li>
|
||||
</ul>
|
||||
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;">
|
||||
<div class="container-fluid">
|
||||
<a href="#" class="navbar-brand">Client Test</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="javascript:void(0)" data-cy="reportSkillsLink">Report Skill Events</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="clientDisplay.html" data-cy="userDisplayLink">User Display</a>
|
||||
</li>
|
||||
</ul>
|
||||
<button type="button" class="btn btn-primary">
|
||||
<span id="skillLevel"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -77,13 +107,13 @@ limitations under the License.
|
||||
<h2>Report Skills Examples</h2>
|
||||
<div class="text-primary">Global Event Result:</div>
|
||||
<div>
|
||||
Include Skills Not Applied: <input type="checkbox" id="all-events-check">
|
||||
Include Skills Not Applied: <input type="checkbox" id="all-events-check" checked>
|
||||
</div>
|
||||
<div id="globalEventResultDiv" class="border rounded p-3 mb-5 bg-light">
|
||||
<pre id="global-event-result-container-js" data-cy="globalEventResult"></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="text-info"><strong>Skills Directive - Click Event</strong></h5>
|
||||
<h5 class="text-info"><strong>Report Any Skill</strong></h5>
|
||||
<div class="card card-body bg-light">
|
||||
<pre class="m-0 sample-code">
|
||||
<code class="javascript">SkillsReporter.reportSkill(this.skill)
|
||||
@@ -93,11 +123,18 @@ limitations under the License.
|
||||
|
||||
</div>
|
||||
<div class="card card-body mt-3">
|
||||
<div class="text-primary">Skill Id:</div>
|
||||
<div class="code-example">
|
||||
<input class="form-control" id="skillId" type="text" value="IronMan" />
|
||||
</div>
|
||||
<div>
|
||||
<div id="exampleDirectiveClickEvent">
|
||||
<button
|
||||
class="btn btn-outline-primary">
|
||||
Report Skill
|
||||
</button>
|
||||
<button
|
||||
data-cy="exampleDirectiveClickEventButton"
|
||||
class="btn btn-outline-primary">
|
||||
Report Skill
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="text-primary">Result:</div>
|
||||
@@ -111,13 +148,6 @@ limitations under the License.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="text-muted bg-light py-5">
|
||||
<div class="container">
|
||||
<p>Native Javascript Examples Guide</p>
|
||||
<p></p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 117 KiB |
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
{
|
||||
"name": "skills-int-client-js",
|
||||
"version": "2.0.0",
|
||||
"version": "3.6.3",
|
||||
"license": "Apache-2.0",
|
||||
"description": "SkillTree Client Lib Integration Tests - Native JS",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"postinstall": "node copyDeps.js",
|
||||
"serve": "npx live-server --no-browser --port=8092 --open=app --cors --proxy=/api:http://localhost:8090/api --proxy=/native:http://localhost:8092/app --proxy=/assets:http://localhost:8092/app/assets",
|
||||
"serve": "npm install && npx live-server --no-browser --port=8092 --open=app --cors --proxy=/api:http://localhost:8090/api --proxy=/native:http://localhost:8092/app --proxy=/assets:http://localhost:8092/app/assets",
|
||||
"test": "npm run test",
|
||||
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;Apache-2.0' --summary",
|
||||
"licenseHeaderCheck": "license-check-and-add check -f '../license-add/license-add-config.json'",
|
||||
"licenseHeaderAdd": "license-check-and-add add -f ../license-add/license-add-config.json",
|
||||
"licenseCheck": "npm run licenseHeaderCheck && npm run licenseDepCheck",
|
||||
"build": "npm run licenseCheck && echo nothingelsetodo"
|
||||
"build": "npm install && npm run licenseCheck && echo nothingelsetodo"
|
||||
},
|
||||
"author": "SkillTree Team",
|
||||
"dependencies": {
|
||||
"@skills/skills-client-js": "2.0.0",
|
||||
"axios": "^0.19.0",
|
||||
"bootstrap": "4.3.1",
|
||||
"jquery": "^3.4.1",
|
||||
"js-beautify": "1.10.2"
|
||||
"@skilltree/skills-client-js": "3.6.3",
|
||||
"axios": "1.17.0",
|
||||
"bootstrap": "5.3.8",
|
||||
"jquery": "4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"fs-extra": "^8.1.0",
|
||||
"license-check-and-add": "^3.0.4",
|
||||
"license-checker": "^25.0.1",
|
||||
"live-server": "1.2.1"
|
||||
"fs-extra": "11.3.5",
|
||||
"license-check-and-add": "4.0.5",
|
||||
"license-checker": "25.0.1",
|
||||
"live-server": "1.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>skills</groupId>
|
||||
<artifactId>skills-client-integration</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<version>3.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>skills-int-client-js</artifactId>
|
||||
|
||||
@@ -19,55 +19,26 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<configuration>
|
||||
<installDirectory>target</installDirectory>
|
||||
</configuration>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<id>exec-npm-install</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<nodeVersion>${node.version}</nodeVersion>
|
||||
<executable>npm</executable>
|
||||
<arguments>
|
||||
<argument>run</argument>
|
||||
<argument>build</argument>
|
||||
</arguments>
|
||||
<workingDirectory>${basedir}</workingDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<arguments>--unsafe-perm install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm run build</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run build</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<!--TODO: uncomment when we have at least 1 unit test-->
|
||||
<!--<execution>-->
|
||||
<!--<id>npm run test</id>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>npm</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--<phase>test</phase>-->
|
||||
<!--<configuration>-->
|
||||
<!--<arguments>run unit</arguments>-->
|
||||
<!--</configuration>-->
|
||||
<!--</execution>-->
|
||||
</executions>
|
||||
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
BROWSER=none
|
||||
@@ -1,23 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1 +0,0 @@
|
||||
package-lock=false
|
||||
@@ -1,83 +0,0 @@
|
||||
<!---
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.<br />
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br />
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.<br />
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.<br />
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.<br />
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"name": "skills-int-client-react",
|
||||
"version": "2.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "SkillTree Client Lib Integration Tests - React",
|
||||
"homepage": "/react/",
|
||||
"dependencies": {
|
||||
"@skills/skills-client-react": "2.0.0",
|
||||
"axios": "0.19.0",
|
||||
"bootstrap": "4.3.1",
|
||||
"core-js": "3.2.1",
|
||||
"highlightjs": "9.12.0",
|
||||
"js-beautify": "1.10.2",
|
||||
"react": "16.11.0",
|
||||
"react-bootstrap": "1.0.0-beta.14",
|
||||
"react-dom": "16.11.0",
|
||||
"react-highlight": "0.12.0",
|
||||
"react-router": "5.1.2",
|
||||
"react-router-dom": "5.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "PORT=8083 react-scripts start",
|
||||
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-3;BSD-2-Clause;Apache-2.0' --summary",
|
||||
"licenseHeaderCheck": "license-check-and-add check -f '../license-add/license-add-config.json'",
|
||||
"licenseHeaderAdd": "license-check-and-add add -f ../license-add/license-add-config.json",
|
||||
"licenseCheck": "npm run licenseHeaderCheck && npm run licenseDepCheck ",
|
||||
"build": "npm run licenseCheck && react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"license-check-and-add": "^3.0.4",
|
||||
"license-checker": "^25.0.1",
|
||||
"react-scripts": "3.2.0"
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>skills</groupId>
|
||||
<artifactId>skills-client-integration</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>skills-int-client-react</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<configuration>
|
||||
<installDirectory>target</installDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<nodeVersion>${node.version}</nodeVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm run build</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run build</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<!--TODO: uncomment when we have at least 1 unit test-->
|
||||
<!--<execution>-->
|
||||
<!--<id>npm run test</id>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>npm</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--<phase>test</phase>-->
|
||||
<!--<configuration>-->
|
||||
<!--<arguments>run unit</arguments>-->
|
||||
<!--</configuration>-->
|
||||
<!--</execution>-->
|
||||
</executions>
|
||||
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,60 +0,0 @@
|
||||
<!--
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
|
||||
<link rel="stylesheet" href="~highlight.js/styles/darcula.css">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import Navigation from "./skillsDisplay/Navigation";
|
||||
import './App.css';
|
||||
import {
|
||||
HashRouter as Router,
|
||||
Switch,
|
||||
Route,
|
||||
} from "react-router-dom";
|
||||
import ShowSkills from "./skillsDisplay/ShowSkills";
|
||||
import ReportSkill from "./skillsDisplay/ReportSkill";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Router>
|
||||
<div className="App">
|
||||
<Navigation projectId="movies"/>
|
||||
</div>
|
||||
<Switch>
|
||||
<Route exact path="/showSkills">
|
||||
<ShowSkills/>
|
||||
</Route>
|
||||
<Route exact path="/">
|
||||
<ReportSkill/>
|
||||
</Route>
|
||||
{/*<Route exact path="/reportSkillEvent">
|
||||
</Route>*/}
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import axios from 'axios';
|
||||
import './index.css';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import App from './App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import { SkillsConfiguration } from '@skills/skills-client-react';
|
||||
|
||||
axios.get("/api/config")
|
||||
.then((result) => {
|
||||
SkillsConfiguration.configure(result.data);
|
||||
})
|
||||
.then(() => {
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
});
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 170.96 159.93"><defs><style>.cls-1{fill:#09d3ac;}</style></defs><path class="cls-1" d="M141.35,73.27c0-6.89-8.11-13-20.58-16.73,3-12.67,1.69-22.75-4.28-26.16a9.55,9.55,0,0,0-4.79-1.2c-5.57,0-12.61,3.89-19.72,10.62-7.11-6.68-14.13-10.55-19.69-10.55a9.46,9.46,0,0,0-4.86,1.22c-5.94,3.42-7.17,13.44-4.21,26.05-12.41,3.71-20.48,9.77-20.5,16.63s8.12,13,20.59,16.72c-3,12.68-1.7,22.75,4.28,26.16a9.41,9.41,0,0,0,4.78,1.2c5.58,0,12.62-3.89,19.73-10.62,7.1,6.68,14.12,10.55,19.69,10.55a9.59,9.59,0,0,0,4.86-1.22c5.94-3.42,7.16-13.44,4.21-26C133.27,86.18,141.34,80.12,141.35,73.27ZM96.56,42.06c8.19-7.33,13.31-8.12,15.13-8.12h0a4.71,4.71,0,0,1,2.42.58c2.86,1.63,4,7.38,3.09,15a56.73,56.73,0,0,1-1,5.79,97.7,97.7,0,0,0-12.58-2.07,98.47,98.47,0,0,0-8.24-10.08C95.75,42.79,96.15,42.42,96.56,42.06ZM71.77,78.94c.78,1.5,1.61,3,2.47,4.51S76,86.49,77,88c-2.71-.39-5.34-.88-7.84-1.46C69.86,84,70.75,81.5,71.77,78.94ZM69,59.9c2.53-.59,5.18-1.08,7.93-1.46-1,1.48-1.86,3-2.76,4.59s-1.69,3-2.46,4.52Q70.18,63.65,69,59.9Zm5.21,13.34q1.86-3.93,4.09-7.86c1.5-2.62,3.11-5.17,4.77-7.61,2.91-.22,5.91-.34,9-.33s6,.12,8.89.35c1.66,2.42,3.25,5,4.75,7.55s2.88,5.22,4.12,7.83c-1.23,2.62-2.6,5.25-4.08,7.85s-3.11,5.18-4.77,7.62c-2.91.23-5.91.34-9,.34s-6-.13-8.89-.36c-1.66-2.42-3.26-4.94-4.76-7.55S75.5,75.85,74.25,73.24Zm32.86-14.77c2.72.38,5.35.87,7.84,1.45-.74,2.47-1.62,5-2.64,7.55-.79-1.5-1.61-3-2.48-4.51S108,59.93,107.11,58.47Zm2.76,24.92q1.29-2.27,2.46-4.53c1,2.6,2,5.16,2.7,7.66-2.52.59-5.17,1.07-7.92,1.45Q108.52,85.75,109.87,83.39ZM92,46.56c1.8,1.92,3.57,4,5.3,6.23-1.71-.07-3.46-.12-5.23-.12s-3.58,0-5.33.12C88.45,50.57,90.2,48.48,92,46.56Zm-22.18-12A4.82,4.82,0,0,1,72.29,34a13.11,13.11,0,0,1,5.19,1.31,39.07,39.07,0,0,1,10,6.78l1.17,1.07a98.49,98.49,0,0,0-8.16,10,98.88,98.88,0,0,0-12.65,2.06c-.44-1.94-.8-3.84-1-5.67C65.8,42,67,36.24,69.81,34.6ZM64.53,85.26a58.75,58.75,0,0,1-5.54-2c-7.1-3-11.5-6.85-11.5-10.14S51.91,66,59,63.05a57.63,57.63,0,0,1,5.44-1.94A97.93,97.93,0,0,0,69,73.25,98.72,98.72,0,0,0,64.53,85.26Zm23,19.1c-8.19,7.33-13.31,8.11-15.14,8.11a4.69,4.69,0,0,1-2.42-.58c-2.86-1.63-4-7.38-3.09-15a56.07,56.07,0,0,1,1-5.78,99.51,99.51,0,0,0,12.58,2.06,97.17,97.17,0,0,0,8.24,10.08Zm4.57-4.51c-1.8-1.92-3.57-4-5.31-6.23,1.72.08,3.47.12,5.24.12s3.58,0,5.33-.11C95.63,95.85,93.87,97.93,92.09,99.85Zm22.18,12a4.82,4.82,0,0,1-2.48.59c-1.82,0-7-.8-15.16-8.1l-1.17-1.07a98.44,98.44,0,0,0,8.15-10,97,97,0,0,0,12.66-2.06c.44,1.94.79,3.84,1,5.67C118.27,104.42,117.12,110.18,114.27,111.81Zm10.8-28.44c-1.71.7-3.52,1.35-5.44,1.93a98.54,98.54,0,0,0-4.57-12.14,98.1,98.1,0,0,0,4.49-12,58.75,58.75,0,0,1,5.54,2c7.09,3,11.5,6.85,11.49,10.14S132.17,80.42,125.07,83.37ZM92,82.39a9.18,9.18,0,1,0-9.17-9.19A9.17,9.17,0,0,0,92,82.39ZM31,17.88V128.53H153.07V17.88ZM148.3,123.77H35.78V22.65H148.3Zm-85-33.9c-3,12.68-1.7,22.75,4.28,26.16a9.41,9.41,0,0,0,4.78,1.2c5.58,0,12.62-3.89,19.73-10.62,7.1,6.68,14.12,10.55,19.69,10.55a9.59,9.59,0,0,0,4.86-1.22c5.94-3.42,7.16-13.44,4.21-26,12.41-3.72,20.48-9.78,20.49-16.63s-8.11-13-20.58-16.73c3-12.67,1.69-22.75-4.28-26.16a9.55,9.55,0,0,0-4.79-1.2c-5.57,0-12.61,3.89-19.72,10.62-7.11-6.68-14.13-10.55-19.69-10.55a9.46,9.46,0,0,0-4.86,1.22c-5.94,3.42-7.17,13.44-4.21,26.05-12.41,3.71-20.48,9.77-20.5,16.63S50.84,86.13,63.31,89.87Zm24.21,14.49c-8.19,7.33-13.31,8.11-15.14,8.11a4.69,4.69,0,0,1-2.42-.58c-2.86-1.63-4-7.38-3.09-15a56.07,56.07,0,0,1,1-5.78,99.51,99.51,0,0,0,12.58,2.06,97.17,97.17,0,0,0,8.24,10.08Zm24.79-36.89c-.79-1.5-1.61-3-2.48-4.51s-1.8-3-2.72-4.49c2.72.38,5.35.87,7.84,1.45C114.21,62.39,113.33,64.92,112.31,67.47Zm2.72,19c-2.52.59-5.17,1.07-7.92,1.45q1.41-2.22,2.76-4.58t2.46-4.53C113.37,81.46,114.28,84,115,86.52Zm-5.21-13.35c-1.23,2.62-2.6,5.25-4.08,7.85s-3.11,5.18-4.77,7.62c-2.91.23-5.91.34-9,.34s-6-.13-8.89-.36c-1.66-2.42-3.26-4.94-4.76-7.55s-2.87-5.22-4.12-7.83q1.86-3.93,4.09-7.86c1.5-2.62,3.11-5.17,4.77-7.61,2.91-.22,5.91-.34,9-.33s6,.12,8.89.35c1.66,2.42,3.25,5,4.75,7.55S108.58,70.56,109.82,73.17ZM77,88c-2.71-.39-5.34-.88-7.84-1.46.74-2.46,1.63-5,2.65-7.55.78,1.5,1.61,3,2.47,4.51S76,86.49,77,88ZM74.21,63c-.87,1.5-1.69,3-2.46,4.52Q70.18,63.65,69,59.9c2.53-.59,5.18-1.08,7.93-1.46C76,59.92,75.11,61.45,74.21,63ZM92.09,99.85c-1.8-1.92-3.57-4-5.31-6.23,1.72.08,3.47.12,5.24.12s3.58,0,5.33-.11C95.63,95.85,93.87,97.93,92.09,99.85Zm22.18,12a4.82,4.82,0,0,1-2.48.59c-1.82,0-7-.8-15.16-8.1l-1.17-1.07a98.44,98.44,0,0,0,8.15-10,97,97,0,0,0,12.66-2.06c.44,1.94.79,3.84,1,5.67C118.27,104.42,117.12,110.18,114.27,111.81Zm5.28-50.66a58.75,58.75,0,0,1,5.54,2c7.09,3,11.5,6.85,11.49,10.14s-4.41,7.16-11.51,10.11c-1.71.7-3.52,1.35-5.44,1.93a98.54,98.54,0,0,0-4.57-12.14A98.1,98.1,0,0,0,119.55,61.15Zm-23-19.09c8.19-7.33,13.31-8.12,15.13-8.12h0a4.71,4.71,0,0,1,2.42.58c2.86,1.63,4,7.38,3.09,15a56.73,56.73,0,0,1-1,5.79,97.7,97.7,0,0,0-12.58-2.07,98.47,98.47,0,0,0-8.24-10.08C95.75,42.79,96.15,42.42,96.56,42.06ZM92,46.56c1.8,1.92,3.57,4,5.3,6.23-1.71-.07-3.46-.12-5.23-.12s-3.58,0-5.33.12C88.45,50.57,90.2,48.48,92,46.56Line truncated
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// This optional code is used to register a service worker.
|
||||
// register() is not called by default.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on subsequent visits to a page, after all the
|
||||
// existing tabs open on the page have been closed, since previously cached
|
||||
// resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model and instructions on how to
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from "react";
|
||||
import Navbar from 'react-bootstrap/Navbar';
|
||||
import Nav from "react-bootstrap/Nav";
|
||||
import Button from "react-bootstrap/Button"
|
||||
import { SkillsLevel } from '@skills/skills-client-react';
|
||||
|
||||
import {
|
||||
NavLink
|
||||
} from "react-router-dom";
|
||||
|
||||
const Navigation = () => {
|
||||
|
||||
const tmpStyle = {
|
||||
position:'fixed',
|
||||
zIndex:1100,
|
||||
right:0,
|
||||
left:0,
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={tmpStyle}>
|
||||
<Navbar bg="info" variant="dark">
|
||||
<Navbar.Brand>React Integration Examples</Navbar.Brand>
|
||||
<Navbar.Toggle target="nav-collapse"></Navbar.Toggle>
|
||||
<Navbar.Collapse id="nav-collapse" is-nav="true">
|
||||
<Nav>
|
||||
<NavLink activeClassName="router-link-active" className="nav-link" to="/">Report Skill Events</NavLink>
|
||||
<NavLink activeClassName="router-link-active" className="nav-link" to="/showSkills">User Display</NavLink>
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
<Button variant="primary">
|
||||
<SkillsLevel />
|
||||
</Button>
|
||||
</Navbar>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navigation;
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { SkillsReporter } from '@skills/skills-client-react';
|
||||
import axios from 'axios';
|
||||
|
||||
const beautify = require('js-beautify').js;
|
||||
let selectedSkillId = '';
|
||||
|
||||
const ReportSkill = () => {
|
||||
const reportSkill = (skillId, resultContainer) => {
|
||||
SkillsReporter.reportSkill(skillId)
|
||||
.then((response) => {
|
||||
document.querySelector(resultContainer).innerHTML = JSON.stringify(response, null, 2);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
const sampleCode = () => {
|
||||
return beautify(`SkillsReporter.reportSkill(this.skill)
|
||||
.then((res) => {
|
||||
this.reportResult = res;
|
||||
});`, {indent_size: 2, indent_level: 1, end_with_newline: false})
|
||||
};
|
||||
|
||||
const handleInputChange = (inputValue) => {
|
||||
selectedSkillId = inputValue.target.value;
|
||||
};
|
||||
|
||||
const [selectData, setSelectData] = React.useState([]);
|
||||
|
||||
React.useEffect(()=>{
|
||||
axios.get("/api/skills")
|
||||
.then((result) => {
|
||||
setSelectData(result.data);
|
||||
if (result.data && result.data.length > 0) {
|
||||
selectedSkillId = result.data[0];
|
||||
}
|
||||
});
|
||||
SkillsReporter.addSuccessHandler((result) => {
|
||||
document.querySelector('#global-event-result-container').innerHTML = JSON.stringify(result, null, 2);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const style = {
|
||||
paddingTop: '55px'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container-fluid" style={style}>
|
||||
<div className="container">
|
||||
<h2>Report Skills Examples</h2>
|
||||
<div className="text-primary">Global Event Result:</div>
|
||||
<div id="globalEventResultDiv" className="border rounded p-3 mb-5 bg-light">
|
||||
<pre id="global-event-result-container" data-cy="globalEventResult"></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-info"><strong>Report Any Skill</strong></h5>
|
||||
<div className="card card-body bg-light">
|
||||
<pre className="m-0 sample-code">
|
||||
<code className="javascript">{sampleCode()}</code></pre>
|
||||
|
||||
</div>
|
||||
<div className="card card-body mt-3">
|
||||
<div id="exampleDirectiveClickEvent">
|
||||
<div className="float-left mr-3">
|
||||
<select onChange={(event) => handleInputChange(event)} className="custom-select custom-select-m mb-3">
|
||||
{selectData.map((skill)=>{
|
||||
return <option key={skill} value={skill}>{skill}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
<div className="float-left">
|
||||
<button
|
||||
className="btn btn-outline-primary"
|
||||
onClick={() => reportSkill(selectedSkillId, '#report-result-container')}>
|
||||
Report Skill
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div className="text-primary">Result:</div>
|
||||
<div className="border rounded p-3 bg-light">
|
||||
<pre id="report-result-container"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="mt-5"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export default ReportSkill;
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import Highlight from 'react-highlight';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const beautify = require('js-beautify').js;
|
||||
const beautifyHtml = require('js-beautify').html;
|
||||
|
||||
const SampleCode = ({options, selectedTheme}) => {
|
||||
|
||||
const sampleCode = () => {
|
||||
const tags = beautifyHtml(`
|
||||
<div id="myApp">
|
||||
<SkillsDisplay options="${JSON.stringify(options)}" theme={selectedThemeObj.theme} />
|
||||
</div>
|
||||
`,{indent_size: 4, indent_level: 2, end_with_newline: false, "html.format.contentUnformatted": "", "html.format.unformatted": ""});
|
||||
|
||||
const js = beautify(`
|
||||
import { SkillsDisplay } from '@skills/skills-client-react';
|
||||
const selectedThemeObj = ${JSON.stringify(selectedTheme)};
|
||||
const MyComponent = () => {
|
||||
return (
|
||||
placeholder
|
||||
)
|
||||
};`, {indent_size: 2, indent_level: 1, end_with_newline: false});
|
||||
|
||||
const replacedText = js.replace('placeholder', tags);
|
||||
return replacedText;
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="sample-code" className="row">
|
||||
<div className="col-12">
|
||||
<div className="mb-5 mt-5 card bg-light">
|
||||
<h5 className=" card-header text-info">
|
||||
<strong>Sample Code</strong>
|
||||
</h5>
|
||||
<div className="card-body py-0">
|
||||
<Highlight className="javascript">
|
||||
<pre><code className="javascript p-0 m-0">{sampleCode()}</code></pre>
|
||||
</Highlight>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
SampleCode.propTypes = {
|
||||
options: PropTypes.object.isRequired,
|
||||
selectedTheme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default React.memo(SampleCode);
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import SkillsDisplayThemeFactory from './ThemeFactory.js';
|
||||
import SampleCode from './SampleCode';
|
||||
import { SkillsDisplay } from '@skills/skills-client-react';
|
||||
import DropdownButton from "react-bootstrap/DropdownButton";
|
||||
import Dropdown from 'react-bootstrap/Dropdown';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
const getThemes = () => {
|
||||
return Object.values(SkillsDisplayThemeFactory);
|
||||
};
|
||||
|
||||
const findTheme = (name) => {
|
||||
return getThemes().find((item) => item.name === name);
|
||||
};
|
||||
|
||||
const scrollToRef = (ref) => window.scrollTo(0, ref.current.offsetTop);
|
||||
|
||||
function usePrevious(value){
|
||||
const ref = React.useRef();
|
||||
React.useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
}
|
||||
|
||||
const ShowSkill = () => {
|
||||
const history = useHistory();
|
||||
|
||||
const getUrlParam = (name) => {
|
||||
const urlSearchParams = new URLSearchParams(history.location.search);
|
||||
return urlSearchParams.get(name);
|
||||
};
|
||||
|
||||
const [selectedTheme, saveSelectedTheme] = React.useState(() => {
|
||||
const urlTheme = getUrlParam("themeName");
|
||||
if(urlTheme) {
|
||||
return findTheme(urlTheme);
|
||||
}
|
||||
return getThemes()[0];
|
||||
});
|
||||
|
||||
const [isSummaryOnly, setIsSummaryOnly] = React.useState(() => {
|
||||
const urlSummaryOnly = getUrlParam('isSummaryOnly');
|
||||
if ( urlSummaryOnly ) {
|
||||
return JSON.parse(urlSummaryOnly)
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const [skillsVersion] = React.useState(() => {
|
||||
const skillsVersion = getUrlParam("skillsVersion");
|
||||
if(skillsVersion) {
|
||||
return skillsVersion;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
const [options, setOptions] = React.useState({ isSummaryOnly: isSummaryOnly, autoScrollStrategy: 'top-offset', scrollTopOffset: 110 });
|
||||
|
||||
const previousIsSummaryOnly = usePrevious(isSummaryOnly);
|
||||
const previousSelectedTheme = usePrevious(selectedTheme);
|
||||
const previousSkillsVersion = usePrevious(skillsVersion);
|
||||
|
||||
React.useEffect(() => {
|
||||
const saveUrlParam = (paramsObj) => {
|
||||
let params = '?';
|
||||
Object.keys(paramsObj).forEach((key) =>{
|
||||
params+=`${key}=${paramsObj[key]}&`;
|
||||
});
|
||||
params = params.replace(/&$/,'');
|
||||
history.push({pathname:history.location.pathname, search: params});
|
||||
};
|
||||
|
||||
if (isSummaryOnly !== previousIsSummaryOnly || selectedTheme !== previousSelectedTheme) {
|
||||
saveUrlParam({'isSummaryOnly': isSummaryOnly, 'themeName': selectedTheme.name, 'skillsVersion': skillsVersion});
|
||||
}
|
||||
|
||||
}, [isSummaryOnly, selectedTheme, skillsVersion, previousIsSummaryOnly, previousSelectedTheme, previousSkillsVersion, history]);
|
||||
|
||||
const sampleCodeRef = React.createRef();
|
||||
const executeScroll = () => scrollToRef(sampleCodeRef);
|
||||
|
||||
const style = {
|
||||
paddingTop: '55px'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container" style={style}>
|
||||
<div className="d-flex align-items-center">
|
||||
<DropdownButton
|
||||
id="dropdown-1"
|
||||
className="mb-3"
|
||||
title="Theme"
|
||||
variant="Primary">
|
||||
|
||||
{ getThemes().map ( (theme) => {
|
||||
return <Dropdown.Item
|
||||
onClick={() => saveSelectedTheme(theme)}
|
||||
key={theme.name}
|
||||
eventKey={theme.name} {... (selectedTheme.name === theme.name ? {disabled:true} : "")}>
|
||||
{theme.name}
|
||||
</Dropdown.Item>
|
||||
})}
|
||||
|
||||
</DropdownButton>
|
||||
<Button variant={isSummaryOnly ? 'primary' : 'outline-primary'}
|
||||
onClick={() => { setIsSummaryOnly(!isSummaryOnly);
|
||||
setOptions({isSummaryOnly:!isSummaryOnly,autoScrollStrategy: 'top-offset', scrollTopOffset: 110}) }}>Summary Only</Button>
|
||||
<Button variant="link" onClick={executeScroll}>Show Source</Button>
|
||||
</div>
|
||||
|
||||
<div className="border rounded">
|
||||
<SkillsDisplay options={options} theme={selectedTheme.theme} version={skillsVersion}/>
|
||||
</div>
|
||||
|
||||
<div ref={sampleCodeRef}>
|
||||
<SampleCode options={options} selectedTheme={selectedTheme}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShowSkill;
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export default {
|
||||
default: {
|
||||
name: 'Bright (default)',
|
||||
theme: {
|
||||
backgroundColor: '#f7f7f7',
|
||||
},
|
||||
},
|
||||
darkBlue: {
|
||||
name: 'Dark Blue',
|
||||
theme: {
|
||||
backgroundColor: '#626d7d',
|
||||
pageTitleTextColor: 'white',
|
||||
textSecondaryColor: 'white',
|
||||
textPrimaryColor: 'white',
|
||||
stars: {
|
||||
unearnedColor: '#787886',
|
||||
earnedColor: 'gold',
|
||||
},
|
||||
progressIndicators: {
|
||||
beforeTodayColor: '#3e4d44',
|
||||
earnedTodayColor: '#667da4',
|
||||
completeColor: '#59ad52',
|
||||
incompleteColor: '#cdcdcd',
|
||||
},
|
||||
charts: {
|
||||
axisLabelColor: 'white',
|
||||
},
|
||||
tiles: {
|
||||
backgroundColor:'#152E4d',
|
||||
watermarkIconColor: '#a6c5f7',
|
||||
},
|
||||
graphLegendBorderColor: '1px solid grey',
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
> 0.2%
|
||||
not dead
|
||||
ff >= 50
|
||||
chrome >= 70
|
||||
safari >= 9
|
||||
opera >= 60
|
||||
edge >= 16
|
||||
not ie <= 8
|
||||
@@ -1 +0,0 @@
|
||||
package-lock=false
|
||||
@@ -1,45 +0,0 @@
|
||||
<!---
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
# skills-example-client-vue
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Run your tests
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@vue/app', { useBuiltIns: 'entry' }],
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"name": "skills-int-client-vue",
|
||||
"version": "2.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "SkillTree Client Lib Integration Tests - Vue",
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-3-Clause;Apache-2.0' --summary",
|
||||
"licenseHeaderCheck": "license-check-and-add check -f '../license-add/license-add-config.json'",
|
||||
"licenseHeaderAdd": "license-check-and-add add -f ../license-add/license-add-config.json",
|
||||
"licenseCheck": "npm run licenseHeaderCheck && npm run licenseDepCheck ",
|
||||
"build": "npm run licenseCheck && vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@skills/skills-client-vue": "2.0.0",
|
||||
"axios": "0.19.0",
|
||||
"bootstrap": "4.3.1",
|
||||
"bootstrap-vue": "2.0.2",
|
||||
"core-js": "^3.2.1",
|
||||
"highlightjs": "9.12.0",
|
||||
"js-beautify": "1.10.2",
|
||||
"vue": "2.6.10",
|
||||
"vue-highlightjs": "1.3.3",
|
||||
"vue-multiselect": "2.1.6",
|
||||
"vue-router": "3.1.3",
|
||||
"vue-scrollto": "2.17.1",
|
||||
"vuex": "3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "3.11.0",
|
||||
"@vue/cli-plugin-eslint": "3.11.0",
|
||||
"@vue/cli-service": "3.11.0",
|
||||
"babel-eslint": "10.0.3",
|
||||
"eslint": "6.5.1",
|
||||
"eslint-plugin-vue": "5.2.3",
|
||||
"license-check-and-add": "3.0.4",
|
||||
"license-checker": "25.0.1",
|
||||
"sass": "1.23.0",
|
||||
"sass-loader": "8.0.0",
|
||||
"vue-template-compiler": "2.6.10"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"rules": {},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>skills</groupId>
|
||||
<artifactId>skills-client-integration</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>skills-int-client-vue</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<configuration>
|
||||
<installDirectory>target</installDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<nodeVersion>${node.version}</nodeVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm run build</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run build</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<!--TODO: uncomment when we have at least 1 unit test-->
|
||||
<!--<execution>-->
|
||||
<!--<id>npm run test</id>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>npm</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--<phase>test</phase>-->
|
||||
<!--<configuration>-->
|
||||
<!--<arguments>run unit</arguments>-->
|
||||
<!--</configuration>-->
|
||||
<!--</execution>-->
|
||||
</executions>
|
||||
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -1,32 +0,0 @@
|
||||
<!--
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>skills.ico">
|
||||
<title>Skills Examples - Vue.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but skills-example-client-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 117 KiB |
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div id="app">
|
||||
<div>
|
||||
<customizable-header></customizable-header>
|
||||
<navigation/>
|
||||
|
||||
<b-container fluid class="mt-3">
|
||||
<router-view/>
|
||||
</b-container>
|
||||
|
||||
<skills-footer/>
|
||||
|
||||
<customizable-footer></customizable-footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Navigation from "./components/Navigation";
|
||||
import SkillsFooter from "./components/SkillsFooter";
|
||||
import CustomizableHeader from "./components/CustomizableHeader"
|
||||
import CustomizableFooter from "./components/CustomizableFooter"
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
SkillsFooter,
|
||||
Navigation,
|
||||
CustomizableHeader,
|
||||
CustomizableFooter,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import "~bootstrap/dist/css/bootstrap.css";
|
||||
@import "~bootstrap-vue/dist/bootstrap-vue.css";
|
||||
@import "~vue-multiselect/dist/vue-multiselect.min.css";
|
||||
@import "~highlight.js/styles/github.css";
|
||||
|
||||
#app {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.btn.disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
|
Before Width: | Height: | Size: 6.7 KiB |
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
|
||||
<code-example-layout :title="title" :sample-code="sampleCode">
|
||||
<div slot="code">
|
||||
<component :is="this.componentName" v-on:reporter-error="onReporterError" v-on:reporter-response="onReporterResponse"></component>
|
||||
</div>
|
||||
<span slot="res">{{reportResult}}</span>
|
||||
</code-example-layout>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import CodeExampleLayout from "./CodeExampleLayout";
|
||||
|
||||
export default {
|
||||
name: "CodeExample",
|
||||
components: {CodeExampleLayout},
|
||||
props: {
|
||||
title: String,
|
||||
sampleCode: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reportResult: null,
|
||||
componentName: '',
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.componentName = this.title.replace( /\s/g, '');
|
||||
Vue.component(this.componentName, {
|
||||
template: `<div class="code-example">${this.sampleCode}</div>`,
|
||||
methods: {
|
||||
onReporterResponse(response) {
|
||||
this.$emit('reporter-response', response);
|
||||
},
|
||||
|
||||
onReporterError(error) {
|
||||
this.$emit('reporter-error', error);
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onReporterResponse(response) {
|
||||
this.reportResult = response.detail;
|
||||
},
|
||||
onReporterError(response) {
|
||||
this.reportResult = response.detail;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" >
|
||||
@import "../../node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
.code-example button {
|
||||
@extend .btn;
|
||||
@extend .btn-outline-primary;
|
||||
}
|
||||
|
||||
.code-example input {
|
||||
@extend .form-control;
|
||||
}
|
||||
</style>
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div>
|
||||
<h5 class="text-info"><strong>{{ title }}</strong></h5>
|
||||
<div class="card card-body bg-light">
|
||||
<pre v-highlightjs="sampleCode"><code :class="codeType"></code></pre>
|
||||
</div>
|
||||
<div class="card card-body mt-3" :id="title.replace(/ /gi,'').replace(/-/g,'')">
|
||||
<div id="exampleDirectiveClickEvent">
|
||||
<slot name="code"/>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="text-primary">Result:</div>
|
||||
<div class="border rounded p-3 bg-light">
|
||||
<pre><slot name="res"/></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "CodeExampleLayout",
|
||||
props: {
|
||||
title: String,
|
||||
sampleCode: String,
|
||||
codeType: {
|
||||
type: String,
|
||||
default: 'html',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<!-- This footer will appear at the top of every page, update this component to customize for your app -->
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomizableFooter',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<!-- This header will appear on the top of every page, update this component to customize for your app -->
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomizableHeader',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div>
|
||||
<b-navbar type="dark" variant="info">
|
||||
<b-navbar-brand href="#">Vue.js Integration Examples</b-navbar-brand>
|
||||
|
||||
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
|
||||
|
||||
<b-collapse id="nav-collapse" is-nav>
|
||||
<b-navbar-nav>
|
||||
<b-nav-item href="#" to="/">Report Skill Events</b-nav-item>
|
||||
<b-nav-item href="#" to="/showSkills">User Display</b-nav-item>
|
||||
</b-navbar-nav>
|
||||
</b-collapse>
|
||||
<button
|
||||
@click="$router.push('/showSkills')"
|
||||
class="btn btn-primary"><skills-level /></button>
|
||||
</b-navbar>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { SkillsLevel } from '@skills/skills-client-vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SkillsLevel,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
token: '',
|
||||
version: 0,
|
||||
projectId: 'movies',
|
||||
serviceUrl: 'http://localhost:8080',
|
||||
authenticationUrl: 'http://localhost:8090/api/users/user1/token',
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div>
|
||||
<code-example-layout :title="title" :sample-code="sampleCode" code-type="javascript">
|
||||
<div slot="code">
|
||||
<multiselect v-model="skill" :options="available" placeholder="Select a skill id" :taggable="true" @tag="addTag"/>
|
||||
|
||||
<button
|
||||
:disabled="!hasSelectedSkill"
|
||||
:title="buttonTitle"
|
||||
:class="!hasSelectedSkill ? 'disabled' : ''"
|
||||
class="btn btn-outline-primary mt-2"
|
||||
type="button"
|
||||
@click="reportSkill">Report Skill</button>
|
||||
</div>
|
||||
<span slot="res">{{reportResult}}</span>
|
||||
</code-example-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import { SkillsReporter } from '@skills/skills-client-vue';
|
||||
import CodeExampleLayout from "./CodeExampleLayout";
|
||||
|
||||
const beautify = require('js-beautify').js;
|
||||
|
||||
export default {
|
||||
name: "ReportAnySkill",
|
||||
components: {CodeExampleLayout},
|
||||
data() {
|
||||
return {
|
||||
title: 'Pure JS - Report Any Skill',
|
||||
reportResult: '',
|
||||
sampleCode: beautify(
|
||||
`SkillsReporter.reportSkill(this.skill)
|
||||
.then((res) => {
|
||||
this.reportResult = res;
|
||||
});`, { indent_size: 2, indent_level: 1, end_with_newline: false }),
|
||||
skill: '',
|
||||
available: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasSelectedSkill() {
|
||||
return this.skill && this.skill !== '';
|
||||
},
|
||||
|
||||
buttonTitle() {
|
||||
return this.hasSelectedSkill ? '' : 'Select a Skill to report from the dropdown';
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
axios.get("/api/skills")
|
||||
.then((result) => {
|
||||
this.available = result.data;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
reportSkill() {
|
||||
SkillsReporter.reportSkill(this.skill)
|
||||
.then((res) => {
|
||||
this.reportResult = res;
|
||||
})
|
||||
.catch((res) => {
|
||||
this.reportResult = res;
|
||||
});
|
||||
},
|
||||
addTag(newTag) {
|
||||
this.available.push(newTag);
|
||||
this.skill = newTag;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div class="container">
|
||||
<h2>Report Skills Examples</h2>
|
||||
<div class="text-primary">Global Event Result:</div>
|
||||
<div id="globalEventResultDiv" class="border rounded p-3 bg-light">
|
||||
<pre data-cy="globalEventResult">{{ globalEventResult }}</pre>
|
||||
</div>
|
||||
<code-example
|
||||
v-for="example in examples"
|
||||
v-bind:key="example.title"
|
||||
class="mt-5"
|
||||
:title="example.title"
|
||||
:sample-code="example.code"
|
||||
/>
|
||||
|
||||
<report-any-skill class="mt-5"/>
|
||||
|
||||
<div class="mt-5"></div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CodeExample from "./CodeExample";
|
||||
import ReportAnySkill from "./ReportAnySkill";
|
||||
import {SkillsReporter} from "@skills/skills-client-vue";
|
||||
|
||||
export default {
|
||||
name: "ReportSkills",
|
||||
components: {ReportAnySkill, CodeExample},
|
||||
data() {
|
||||
return {
|
||||
examples: [
|
||||
{
|
||||
title: 'Skills Directive - Click Event',
|
||||
code: '<button \n v-skills="\'IronMan\'" \n @skills-report-success="onReporterResponse">\n Report Skill\n</button>',
|
||||
},
|
||||
{
|
||||
title: 'Skills Directive - Input Event',
|
||||
code: '<input \n type="text" \n v-skills:input="\'Thor\'" \n @skills-report-success="onReporterResponse"/>',
|
||||
},
|
||||
{
|
||||
title: 'Skills Directive - Error with Button',
|
||||
code: '<button \n v-skills="\'DoesNotExist\'" \n @skills-report-success="onReporterResponse" \n @skills-report-error="onReporterError">\n Report Skill\n</button>',
|
||||
},
|
||||
{
|
||||
title: 'Skills Directive - Error with Input',
|
||||
code: '<input \n type="text" \n v-skills:input="\'DoesNotExist\'" \n @skills-report-success="onReporterResponse" \n @skills-report-error="onReporterError"/>',
|
||||
},
|
||||
],
|
||||
globalEventResult: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
SkillsReporter.addSuccessHandler(this.update);
|
||||
},
|
||||
methods: {
|
||||
update(result) {
|
||||
this.globalEventResult = result;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<footer class="text-muted bg-light py-5">
|
||||
<div class="container">
|
||||
<p class="float-right">
|
||||
<a href="#">Back to top</a>
|
||||
</p>
|
||||
<p>Vue.js Examples Guide</p>
|
||||
<p></p>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SkillsFooter",
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 SkillTree
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="d-flex align-items-center">
|
||||
<b-dropdown
|
||||
id="dropdown-1"
|
||||
class="mb-3"
|
||||
text="Change Theme"
|
||||
variant="outline-primary">
|
||||
<b-dropdown-item
|
||||
v-for="themeItem in themes"
|
||||
@click="setIsThemeUrlParam(themeItem)"
|
||||
:key="themeItem.name"
|
||||
:active="selectedTheme.name === themeItem.name">
|
||||
{{ themeItem.name }}
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
<b-form-checkbox class="d-inline-block ml-3 border-right pr-2"
|
||||
v-model="displayOptions.isSummaryOnly"
|
||||
switch>
|
||||
Summary Only
|
||||
</b-form-checkbox>
|
||||
|
||||
<b-link
|
||||
class="ml-2"
|
||||
href="javascript:void"
|
||||
v-scroll-to="'#sample-code'"
|
||||
@click="showSampleCode = true">Show Source</b-link>
|
||||
</div>
|
||||
<div class="border rounded">
|
||||
<skills-display
|
||||
v-if="selectedTheme"
|
||||
:options="displayOptions"
|
||||
:version="version"
|
||||
:theme="selectedTheme.theme"/>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedTheme && showSampleCode"
|
||||
id="sample-code"
|
||||
class="row">
|
||||
<div class="col-12">
|
||||
<div class="mb-5 mt-5 card bg-light">
|
||||
<h5 class=" card-header text-info">
|
||||
<strong>Sample Code</strong>
|
||||
</h5>
|
||||
<div class="card-body py-0">
|
||||
<!-- // keep <template> and <script> tags separate, as one requires html highlighting and other javascript-->
|
||||
<pre v-highlightjs class="m-0 p-0">
|
||||
<code class="html m-0 p-0">
|
||||
<template>
|
||||
<skills-level /> <!-- You can display the user's current Level using the SkillsLevel component -->
|
||||
<skills-display :theme="selectedTheme" {{ this.displayOptions.isSummaryOnly ? ':options="displayOptions"' : '' }}/>
|
||||
</template>
|
||||
|
||||
<script></code></pre><pre v-highlightjs class="m-0 p-0">
|
||||
<code class="javascript p-0 m-0">{{ sampleCode }}
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { SkillsDisplay } from '@skills/skills-client-vue';
|
||||
import SkillsDisplayThemeFactory from './ThemeFactory.js';
|
||||
|
||||
import Vue from 'vue';
|
||||
import VueScrollTo from 'vue-scrollto';
|
||||
|
||||
const beautify = require('js-beautify').js;
|
||||
|
||||
Vue.use(VueScrollTo, {
|
||||
container: "body",
|
||||
duration: 1000,
|
||||
easing: "ease",
|
||||
offset: 0,
|
||||
force: true,
|
||||
cancelable: true,
|
||||
onStart: false,
|
||||
onDone: false,
|
||||
onCancel: false,
|
||||
x: false,
|
||||
y: true,
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SkillsDisplay,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
token: '',
|
||||
version: this.$route.query.skillsVersion ? JSON.parse(this.$route.query.skillsVersion) : 1000,
|
||||
displayOptions: {
|
||||
autoScrollStrategy: 'top-of-page',
|
||||
isSummaryOnly: this.$route.query.isSummaryOnly ? JSON.parse(this.$route.query.isSummaryOnly) : false,
|
||||
},
|
||||
showSampleCode: false,
|
||||
themes: this.getThemes(),
|
||||
selectedTheme: this.$route.query.themeName ? this.findTheme(this.$route.query.themeName) : this.getThemes()[0],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sampleCode() {
|
||||
return beautify(`import { SkillsDisplay, SkillsLevel } from '@skills/skills-client-vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SkillsDisplay,
|
||||
},
|
||||
data() {
|
||||
return { ${this.displayOptions.isSummaryOnly ? '\ndisplayOptions: { isSummaryOnly: true, },' : ''}
|
||||
selectedTheme: ${JSON.stringify(this.selectedTheme)}
|
||||
};
|
||||
},
|
||||
};`, {indent_size: 2, indent_level: 1, end_with_newline: false});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'displayOptions.isSummaryOnly'() {
|
||||
this.setIsSummaryOnlyUrlParam();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getThemes() {
|
||||
return Object.values(SkillsDisplayThemeFactory);
|
||||
},
|
||||
|
||||
refreshPage() {
|
||||
setTimeout(() => {
|
||||
document.location.reload();
|
||||
}, 250);
|
||||
},
|
||||
|
||||
setIsThemeUrlParam(theme) {
|
||||
this.$router.push({query: {themeName: theme.name, isSummaryOnly: this.displayOptions.isSummaryOnly}});
|
||||
this.refreshPage();
|
||||
},
|
||||
|
||||
setIsSummaryOnlyUrlParam() {
|
||||
this.$router.push({
|
||||
query: {
|
||||
themeName: this.selectedTheme.name,
|
||||
isSummaryOnly: this.displayOptions.isSummaryOnly
|
||||
}
|
||||
});
|
||||
this.refreshPage();
|
||||
},
|
||||
|
||||
findTheme(name) {
|
||||
return this.getThemes().find((item) => item.name === name);
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export default {
|
||||
default: {
|
||||
name: 'Bright (default)',
|
||||
theme: {
|
||||
backgroundColor: '#f7f7f7',
|
||||
},
|
||||
},
|
||||
darkBlue: {
|
||||
name: 'Dark Blue',
|
||||
theme: {
|
||||
backgroundColor: '#626d7d',
|
||||
pageTitleTextColor: 'white',
|
||||
textSecondaryColor: 'white',
|
||||
textPrimaryColor: 'white',
|
||||
stars: {
|
||||
unearnedColor: '#787886',
|
||||
earnedColor: 'gold',
|
||||
},
|
||||
progressIndicators: {
|
||||
beforeTodayColor: '#3e4d44',
|
||||
earnedTodayColor: '#667da4',
|
||||
completeColor: '#59ad52',
|
||||
incompleteColor: '#cdcdcd',
|
||||
},
|
||||
charts: {
|
||||
axisLabelColor: 'white',
|
||||
},
|
||||
tiles: {
|
||||
backgroundColor:'#152E4d',
|
||||
watermarkIconColor: '#a6c5f7',
|
||||
},
|
||||
graphLegendBorderColor: '1px solid grey',
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
import BootstrapVue from 'bootstrap-vue';
|
||||
import Multiselect from 'vue-multiselect';
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import axios from 'axios';
|
||||
import { SkillsDirective, SkillsConfiguration } from '@skills/skills-client-vue';
|
||||
import VueHighlightJS from 'vue-highlightjs'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.component('multiselect', Multiselect);
|
||||
|
||||
Vue.use(BootstrapVue);
|
||||
Vue.use(SkillsDirective);
|
||||
Vue.use(VueHighlightJS)
|
||||
|
||||
axios.get("/api/config")
|
||||
.then((result) => {
|
||||
SkillsConfiguration.configure(result.data);
|
||||
})
|
||||
.then(() => {
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
router,
|
||||
}).$mount('#app');
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
import Router from 'vue-router';
|
||||
import ReportSkills from './components/ReportSkills';
|
||||
import ShowSkills from './components/skillsDisplay/ShowSkills';
|
||||
|
||||
Vue.use(Router);
|
||||
|
||||
const router = new Router({
|
||||
base: 'vuejs',
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'ReportSkills',
|
||||
component: ReportSkills,
|
||||
},
|
||||
{
|
||||
path: '/showSkills',
|
||||
name: 'ShowSkills',
|
||||
component: ShowSkills,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -1,91 +0,0 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const resolve = dir => path.join(__dirname, dir);
|
||||
|
||||
const getTarget = () => {
|
||||
let target = 'http://localhost:8090';
|
||||
const proxySslKeyLocation = process.env.WEBPACK_DEV_SERVER_PROXY_TABLE_SSL_KEY_PATH;
|
||||
const proxyCertKeyLocation = process.env.WEBPACK_DEV_SERVER_PROXY_TABLE_SSL_CERT_PATH;
|
||||
if (fs.existsSync(proxySslKeyLocation) && fs.existsSync(proxyCertKeyLocation)) {
|
||||
target = {
|
||||
host: 'localhost',
|
||||
port: 9443,
|
||||
key: fs.readFileSync(proxySslKeyLocation),
|
||||
cert: fs.readFileSync(proxyCertKeyLocation),
|
||||
protocol: 'https:'
|
||||
};
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
const proxyConf = {
|
||||
target: getTarget(),
|
||||
secure: false,
|
||||
changeOrigin: true,
|
||||
logLevel: 'debug',
|
||||
};
|
||||
|
||||
// absolute paths to all symlinked modules inside `nodeModulesPath`
|
||||
// adapted from https://github.com/webpack/webpack/issues/811#issuecomment-405199263
|
||||
const findLinkedModules = (nodeModulesPath) => {
|
||||
const modules = []
|
||||
|
||||
fs.readdirSync(nodeModulesPath).forEach(dirname => {
|
||||
const modulePath = path.resolve(nodeModulesPath, dirname)
|
||||
const stat = fs.lstatSync(modulePath)
|
||||
|
||||
if (dirname.startsWith('.')) {
|
||||
// not a module or scope, ignore
|
||||
} else if (dirname.startsWith('@')) {
|
||||
// scoped modules
|
||||
modules.push(...findLinkedModules(modulePath))
|
||||
} else if (stat.isSymbolicLink()) {
|
||||
const realPath = fs.realpathSync(modulePath)
|
||||
const realModulePath = path.resolve(realPath, 'node_modules')
|
||||
|
||||
modules.push(realModulePath)
|
||||
}
|
||||
})
|
||||
|
||||
return modules
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
devServer: {
|
||||
host: 'localhost',
|
||||
port: 8091,
|
||||
overlay: true,
|
||||
proxy: {
|
||||
'/api': proxyConf,
|
||||
},
|
||||
},
|
||||
configureWebpack: {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@$': resolve('src'),
|
||||
},
|
||||
// work with npm link
|
||||
// see https://github.com/webpack/webpack/issues/985
|
||||
// see https://github.com/vuejs-templates/webpack/pull/688
|
||||
symlinks: false,
|
||||
modules: [
|
||||
// provide absolute path to the main node_modules,
|
||||
// to avoid webpack searching around and getting confused
|
||||
// see https://webpack.js.org/configuration/resolve/#resolve-modules
|
||||
path.resolve('node_modules'),
|
||||
// include linked node_modules as fallback, in case the deps haven't
|
||||
// yet propagated to the main node_modules
|
||||
...findLinkedModules(path.resolve('node_modules')),
|
||||
],
|
||||
},
|
||||
devtool: 'source-map',
|
||||
},
|
||||
publicPath: '/vuejs/',
|
||||
outputDir: undefined,
|
||||
assetsDir: 'static',
|
||||
runtimeCompiler: true,
|
||||
productionSourceMap: undefined,
|
||||
parallel: undefined,
|
||||
css: undefined,
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
const { defineConfig } = require('cypress')
|
||||
|
||||
module.exports = defineConfig({
|
||||
chromeWebSecurity: false,
|
||||
defaultCommandTimeout: 10000,
|
||||
projectId: '3yas4t',
|
||||
video: true,
|
||||
retries: {
|
||||
runMode: 2,
|
||||
openMode: 0,
|
||||
},
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents(on, config) {
|
||||
return require('./cypress/plugins/index.js')(on, config)
|
||||
},
|
||||
baseUrl: 'http://localhost:8090',
|
||||
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
|
||||
},
|
||||
})
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"baseUrl": "http://localhost:8090",
|
||||
"chromeWebSecurity": false,
|
||||
"defaultCommandTimeout": 10000
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var semver = require('semver');
|
||||
|
||||
export default {
|
||||
versionLaterThan (lib, minVersion){
|
||||
const versionToCompare = Cypress.env(lib);
|
||||
return this.laterThanMinVersion(minVersion, versionToCompare);
|
||||
},
|
||||
skillsClientJSVersionLaterThan(minVersion) {
|
||||
const versionToCompare = Cypress.env('skills-client-js-version')
|
||||
return this.laterThanMinVersion(minVersion, versionToCompare);
|
||||
},
|
||||
skillsServiceVersionLaterThan(minVersion) {
|
||||
const versionToCompare = Cypress.env('skills-service.minVersion');
|
||||
return this.laterThanMinVersion(minVersion, versionToCompare);
|
||||
},
|
||||
laterThanMinVersion(minVersion, currentVersion) {
|
||||
if (!currentVersion) {
|
||||
return true;
|
||||
}
|
||||
const shouldSkip = semver.lt(currentVersion, minVersion);
|
||||
return !shouldSkip;
|
||||
},
|
||||
laterThan_3_1_0() {
|
||||
return this.skillsServiceVersionLaterThan('3.1.0');
|
||||
},
|
||||
laterThan_1_4_0() {
|
||||
return this.skillsServiceVersionLaterThan('1.4.0');
|
||||
},
|
||||
laterThan_1_11_1() {
|
||||
return this.skillsServiceVersionLaterThan('1.11.1');
|
||||
},
|
||||
noThemeBackground() {
|
||||
return 'rgb(255, 255, 255)';
|
||||
},
|
||||
rankDetailsTitle() {
|
||||
return this.laterThan_1_11_1() ? 'My Rank' : 'Rank Overview'
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
import selectors from "../support/selectors";
|
||||
|
||||
context("Configuration Disabled Tests", () => {
|
||||
|
||||
it('export user transcript', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.6.0'))
|
||||
cy.createDefaultTinyProject('proj1')
|
||||
|
||||
// visit client display
|
||||
cy.intercept('**/public/status', cy.spy().as('getStatus'))
|
||||
cy.intercept('POST', '**/api/projects/proj1/skillsClientVersion', cy.spy().as('reportClientVersion'))
|
||||
cy.intercept('**/api/projects/proj1/level', cy.spy().as('getLevel'))
|
||||
cy.intercept('**/skills-websocket/info**', cy.spy().as('initWebsockets'))
|
||||
|
||||
cy.intercept('POST', '** /api/projects/proj1/skills/someId', cy.spy().as('reportSkillId'))
|
||||
cy.intercept('/api/projects/proj1/summary', cy.spy().as('getProjSummary'))
|
||||
|
||||
cy.visit('/native/disabledConfig.html');
|
||||
cy.wait(5000)
|
||||
cy.get('@getStatus').should('not.have.been.called');
|
||||
cy.get('@reportClientVersion').should('not.have.been.called');
|
||||
cy.get('@getLevel').should('not.have.been.called');
|
||||
cy.get('@initWebsockets').should('not.have.been.called');
|
||||
cy.get('[data-cy="levelComponentRes"]').contains('Level: []')
|
||||
|
||||
cy.get('[data-cy="skillsDisplayRes"] #skills-client-display').should('be.empty')
|
||||
cy.get('@getProjSummary').should('not.have.been.called');
|
||||
|
||||
cy.get('[data-cy="reportSkillButton"]').click()
|
||||
cy.wait(3000)
|
||||
cy.get('@reportSkillId').should('not.have.been.called');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
import selectors from "../support/selectors";
|
||||
|
||||
const homePage = '/native/index.html'
|
||||
|
||||
context("Global Events Tests", () => {
|
||||
|
||||
it("global event show correct results", () => {
|
||||
cy.createDefaultProject();
|
||||
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
cy.clickSubmit();
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
});
|
||||
it("global event show correct results (skills reported directly to backend endpoint)", () => {
|
||||
cy.createDefaultProject();
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
cy.reportSkillForUser("IronMan", Cypress.env('proxyUser'));
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').should('be.visible')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
});
|
||||
|
||||
it('global event does not update when skill reported for a different project', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.createDefaultTinyProject('proj2')
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'), 'proj2')
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
it('global event is not reported when skill is not applied (skill reported directly to backend endpoint)', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
|
||||
|
||||
cy.get('[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
it('global event is not reported when skill is not applied', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
cy.get('[type="checkbox"]').uncheck()
|
||||
cy.clickSubmit()
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
|
||||
it('global event is reported even when skill is not applied when notifyIfSkillNotApplied=true ', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
|
||||
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
cy.get('[type="checkbox"]').check()
|
||||
cy.clickSubmit()
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 0')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": false')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"explanation": "This skill reached its maximum points"')
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
import selectors from "../support/selectors";
|
||||
|
||||
const homePage = '/native/index.html'
|
||||
|
||||
context("Skills Display Tests", () => {
|
||||
|
||||
it("skill display", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.intercept(Cypress.env('tokenUrl'))
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: Cypress.env('proxyUser'),
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visitSkillsDisplay();
|
||||
|
||||
cy.wrapIframe().contains('My Level')
|
||||
cy.wrapIframe().contains('50 Points earned Today')
|
||||
cy.wrapIframe().contains('Subject 0')
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrapIframe().find('[data-cy="skillsTitle"]')
|
||||
.should('have.css', 'background-color').and('equal', Utils.noThemeBackground());
|
||||
});
|
||||
|
||||
it("skill display - default options", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.intercept(Cypress.env('tokenUrl'))
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: Cypress.env('proxyUser'),
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visit("/native/clientDisplayDefaultOptions.html");
|
||||
|
||||
|
||||
cy.wrapIframe().contains('My Level')
|
||||
cy.wrapIframe().contains('50 Points earned Today')
|
||||
cy.wrapIframe().contains('Subject 0')
|
||||
cy.wrapIframe().find(selectors.firstSubjectTileBtn)
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrapIframe().find('[data-cy="skillsTitle"]')
|
||||
.should('have.css', 'background-color').and('equal', Utils.noThemeBackground());
|
||||
});
|
||||
|
||||
it("skill display - summary only", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.intercept(Cypress.env('tokenUrl'))
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: Cypress.env('proxyUser'),
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visitSkillsDisplay("?isSummaryOnly=true");
|
||||
|
||||
|
||||
cy.wrapIframe().contains('My Level')
|
||||
cy.wrapIframe().contains('50 Points earned Today')
|
||||
cy.wrapIframe().find('[data-cy="subjectTile-subj0"] [data-cy="subjectTileBtn"]').should('not.exist')
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrapIframe().find('[data-cy="skillsTitle"]')
|
||||
.should('have.css', 'background-color').and('equal', Utils.noThemeBackground());
|
||||
});
|
||||
|
||||
it("skill display - theme", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.intercept(Cypress.env('tokenUrl'))
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: Cypress.env('proxyUser'),
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visitSkillsDisplay("?themeName=Dark Blue");
|
||||
cy.wait("@getToken");
|
||||
|
||||
cy.wrapIframe().contains('My Level')
|
||||
cy.wrapIframe().contains('50 Points earned Today')
|
||||
cy.wrapIframe().contains('Subject 0')
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrapIframe().find('[data-cy="skillsTitle"]')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(21, 46, 77)');
|
||||
});
|
||||
|
||||
it("skill display - summary only - theme", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.intercept(Cypress.env('tokenUrl'))
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: Cypress.env('proxyUser'),
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visit(
|
||||
"/native/clientDisplay.html?themeName=Dark Blue&isSummaryOnly=true"
|
||||
);
|
||||
|
||||
cy.wrapIframe().contains('My Level')
|
||||
cy.wrapIframe().contains('50 Points earned Today')
|
||||
cy.wrapIframe().find('[data-cy="subjectTile-subj0"] [data-cy="subjectTileBtn"]').should('not.exist')
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrapIframe().find('[data-cy="skillsTitle"]')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(21, 46, 77)');
|
||||
});
|
||||
|
||||
it('client display should display an error if skills service is down', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.2.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.intercept('/public/status',
|
||||
{
|
||||
statusCode: 503, // server is down
|
||||
body: {}
|
||||
}).as('getStatus')
|
||||
cy.visitSkillsDisplay();
|
||||
cy.wait('@getStatus')
|
||||
|
||||
cy.contains("Could NOT reach Skilltree Service");
|
||||
});
|
||||
|
||||
it("only display skills up-to the provided version", () => {
|
||||
const totalPointsSelector = '[data-cy="totalPoints"]'
|
||||
cy.createDefaultTinyProject();
|
||||
cy.intercept(Cypress.env('tokenUrl'))
|
||||
.as("getToken");
|
||||
cy.backendAddSkill("skillv1", 1);
|
||||
cy.backendAddSkill("skillv2", 2);
|
||||
cy.visitSkillsDisplay();
|
||||
cy.wait("@getToken");
|
||||
cy.wait('@getToken')
|
||||
const validateTotalPoints = (expectedPoints) => {
|
||||
if (Utils.skillsServiceVersionLaterThan('3.0.0')){
|
||||
cy.wrapIframe().find(totalPointsSelector).should('have.text', `${expectedPoints}`);
|
||||
} else {
|
||||
cy.wrapIframe().find('.user-skills-overview').contains(`Earn up to ${expectedPoints} points`)
|
||||
}
|
||||
}
|
||||
validateTotalPoints(200)
|
||||
|
||||
cy.visitSkillsDisplay("?skillsVersion=1");
|
||||
cy.wait('@getToken')
|
||||
validateTotalPoints(150)
|
||||
|
||||
cy.visitSkillsDisplay("?skillsVersion=0");
|
||||
cy.wait('@getToken')
|
||||
validateTotalPoints(100)
|
||||
});
|
||||
|
||||
it('skillsClientVersion is reported correctly', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.intercept('POST', '/api/projects/proj1/skillsClientVersion', (req) => {
|
||||
expect(req.body).to.have.property('skillsClientVersion').and.to.contain('@skilltree/skills-client-js-')
|
||||
req.reply((res) => {
|
||||
expect(res.statusCode).to.eq(200)
|
||||
expect(res.body).to.have.property('success').to.eq(true)
|
||||
})
|
||||
}).as('reportClientVersion')
|
||||
|
||||
cy.visit('/native/index.html')
|
||||
cy.wait('@reportClientVersion')
|
||||
})
|
||||
|
||||
it('level component should be reactive', () => {
|
||||
cy.createDefaultProject()
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
|
||||
cy.visitHomePage(homePage);
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.clickSubmit();
|
||||
cy.contains('Level 1')
|
||||
})
|
||||
|
||||
it('level component should load initial level', () => {
|
||||
cy.createDefaultProject()
|
||||
|
||||
// this will increment levels for [email protected] but Level and display components display data for the proxyUser
|
||||
// validate that level is still 0
|
||||
cy.reportSkillForUser('subj1_skill0', '[email protected]')
|
||||
cy.visitHomePage(homePage);
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('subj1_skill0', Cypress.env('proxyUser'))
|
||||
// cy.visitHomePage(homePage);
|
||||
cy.contains('Level 1')
|
||||
})
|
||||
|
||||
});
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
import selectors from "../support/selectors";
|
||||
|
||||
context("Navigation Tests", () => {
|
||||
|
||||
it('internal back button when when returning from an external page', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.intercept(Cypress.env('tokenUrl')).as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
const url = Utils.skillsClientJSVersionLaterThan('3.3.0') ? '?internalBackButton=true' : ''
|
||||
cy.visitSkillsDisplay(url);
|
||||
|
||||
// cy.clientDisplay(true)
|
||||
cy.wrapIframe().find(selectors.myRankButton)
|
||||
cy.wrapIframe().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
// navigate to Rank Overview that contains the back button
|
||||
cy.wrapIframe().find(selectors.myRankButton).click();
|
||||
cy.wrapIframe().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
cy.wrapIframe().find(selectors.titleSection).find(selectors.backButton).should('exist')
|
||||
|
||||
// now visit the "Report Skills" (external) page
|
||||
cy.get('[data-cy=reportSkillsLink]').click()
|
||||
cy.contains('Report Skills Examples');
|
||||
|
||||
// switch back to the the client display
|
||||
cy.get('[data-cy=userDisplayLink]').click()
|
||||
});
|
||||
|
||||
it('internal back button when when returning from an external page - multiple layers deep', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
const url = Utils.skillsClientJSVersionLaterThan('3.3.0') ? '?internalBackButton=true' : ''
|
||||
cy.visitSkillsDisplay(url);
|
||||
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
cy.clientDisplay().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
// to subject page
|
||||
cy.cdClickSubj();
|
||||
|
||||
// navigate to Rank Overview that contains the back button
|
||||
cy.clientDisplay().find(selectors.myRankButton).click();
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
cy.clientDisplay().find(selectors.backButton).should('exist');
|
||||
|
||||
// click the back button and verify that we are still in the
|
||||
// client display (Subject page)
|
||||
cy.cdBack('Subject 0');
|
||||
|
||||
// then back one more time and we should be back on the client display home page
|
||||
cy.cdBack('User Skills');
|
||||
});
|
||||
|
||||
it('browser back button works correctly when internal back button is not present', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
cy.visit("/native/clientDisplay.html?internalBackButton=false");
|
||||
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
cy.clientDisplay().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
// to subject page
|
||||
cy.cdClickSubj();
|
||||
cy.clientDisplay().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
// navigate to Rank Overview and that it does NOT contains the internal back button
|
||||
cy.clientDisplay().find(selectors.myRankButton).click()
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
cy.clientDisplay().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
// click the browser back button and verify that we are still in the
|
||||
// client display (Subject page)
|
||||
cy.wait(1000);
|
||||
cy.go('back') // browser back button
|
||||
cy.wait(1000);
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('Subject 0');
|
||||
|
||||
// then back one more time and we should be back on the client display home page
|
||||
cy.wait(1000);
|
||||
cy.go('back') // browser back button
|
||||
cy.wait(1000);
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
});
|
||||
|
||||
if (Utils.skillsServiceVersionLaterThan('3.1.1')) {
|
||||
it('browser back and forward operations', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
|
||||
// visit client display
|
||||
cy.visit("/native/clientDisplay.html");
|
||||
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
// to subject page
|
||||
cy.cdClickSubj();
|
||||
|
||||
// to skill
|
||||
cy.wrapIframe().find(selectors.buildSkillLinkSelector('Thor')).click()
|
||||
cy.wrapIframe().find(selectors.titleSection).contains('Skill Overview')
|
||||
cy.wrapIframe().find(selectors.buildSkillTitleSelector('Thor'))
|
||||
|
||||
// // click next
|
||||
cy.wrapIframe().find(selectors.nextSkillButton).click()
|
||||
cy.wrapIframe().find(selectors.buildSkillTitleSelector('IronMan'))
|
||||
|
||||
cy.go('back')
|
||||
cy.wrapIframe().find(selectors.buildSkillTitleSelector('Thor'))
|
||||
|
||||
cy.go('back')
|
||||
cy.wrapIframe().find(selectors.titleSection).contains('Subject 0')
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
cy.go('back')
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
cy.go('forward')
|
||||
cy.wrapIframe().find(selectors.titleSection).contains('Subject 0')
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
// cy.go('forward')
|
||||
// cy.wrapIframe().find(selectors.titleSection).contains('Skill Overview')
|
||||
// cy.wrapIframe().find(selectors.buildSkillTitleSelector('Thor'))
|
||||
//
|
||||
// cy.go('back')
|
||||
// cy.wrapIframe().find(selectors.titleSection).contains('Subject 0')
|
||||
// cy.clientDisplay().find(selectors.myRankButton)
|
||||
//
|
||||
// cy.wrapIframe().find(selectors.myRankButton).click();
|
||||
// cy.wrapIframe().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
//
|
||||
// cy.go('back')
|
||||
// cy.wrapIframe().find(selectors.titleSection).contains('Subject 0')
|
||||
// cy.clientDisplay().find(selectors.myRankButton)
|
||||
//
|
||||
// cy.go('back')
|
||||
// cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
// cy.clientDisplay().find(selectors.myRankButton)
|
||||
});
|
||||
}
|
||||
it('breadcrumb-based navigation', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
|
||||
// visit client display
|
||||
cy.visit("/native/clientDisplay.html?skillsClientDisplayPath=%2Fsubjects%2Fsubj0%2Frank");
|
||||
cy.wrapIframe().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
|
||||
cy.wrapIframe().find(selectors.buildBreadcrumbLinkSelector('subj0')).click()
|
||||
cy.wrapIframe().find(selectors.titleSection).contains('Subject 0')
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
cy.wrapIframe().find(selectors.buildBreadcrumbLinkSelector('Overview')).click()
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
});
|
||||
|
||||
it('deep link and reload', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// navigate to Rank Overview via direct link
|
||||
cy.visitSkillsDisplay('?skillsClientDisplayPath=%2Frank#/showSkills');
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
|
||||
// reload and confirm we are still on Rank Overview page
|
||||
cy.reload();
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
});
|
||||
|
||||
it('back button after reload', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
cy.visit("/native/clientDisplay.html?internalBackButton=false");
|
||||
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
cy.clientDisplay().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
// to subject page
|
||||
cy.cdClickSubj();
|
||||
|
||||
// navigate to Rank Overview and that it does NOT contain the internal back button
|
||||
cy.clientDisplay().find(selectors.myRankButton).click();
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
cy.clientDisplay().find(selectors.titleSection).find(selectors.backButton).should('not.exist')
|
||||
|
||||
cy.reload();
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
cy.clientDisplay().contains(Utils.rankDetailsTitle());
|
||||
|
||||
// click the browser back button and verify that we are still in the
|
||||
// client display (Subject page)
|
||||
cy.wait(1000);
|
||||
cy.go('back') // browser back button
|
||||
cy.wait(1000);
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('Subject 0');
|
||||
|
||||
// then back one more time and we should be back on the client display home page
|
||||
cy.wait(1000);
|
||||
cy.go('back') // browser back button
|
||||
cy.wait(1000);
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
});
|
||||
|
||||
it('route change is passed to the client app', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.0'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
cy.visitSkillsDisplay('?internalBackButton=true');
|
||||
|
||||
// to subject page
|
||||
cy.cdClickSubj();
|
||||
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0]');
|
||||
|
||||
// navigate to Rank Overview and that it does NOT contains the internal back button
|
||||
cy.clientDisplay().find(selectors.myRankButton).click();
|
||||
cy.clientDisplay().find(selectors.titleSection).contains(Utils.rankDetailsTitle());
|
||||
|
||||
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0/rank]');
|
||||
});
|
||||
|
||||
if (Utils.skillsServiceVersionLaterThan('3.1.1')) {
|
||||
it('navigate skills-display programmatically', () => {
|
||||
cy.onlyOn(Utils.skillsClientJSVersionLaterThan('3.3.1'))
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
cy.visitSkillsDisplay('?internalBackButton=true');
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
// to subject page
|
||||
cy.get('[data-cy=navigateButton]').click();
|
||||
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0]');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const homePage = '/native/index.html'
|
||||
|
||||
context("Token timeout JS Tests", () => {
|
||||
|
||||
if (Cypress.env('timeout') === true || Cypress.env('timeout') === 'true') {
|
||||
it("report skill with expired token, retry checker will resend with new token", () => {
|
||||
cy.createDefaultProject();
|
||||
cy.intercept(Cypress.env('tokenUrl')).as("getToken");
|
||||
cy.visitHomePage(homePage);
|
||||
|
||||
cy.wait("@getToken");
|
||||
cy.wait(71000) // wait 71 seconds to ensure the token has expired
|
||||
cy.get('[data-cy="exampleDirectiveClickEventButton"]').click();
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').should('be.empty');
|
||||
|
||||
cy.wait("@getToken", { timeout: 60000 }); // wait ~ another 50 seconds to all for the RetryChecker to resubmit
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
});
|
||||
|
||||
it('skill display - navigate after token expires', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
|
||||
|
||||
// visit client display
|
||||
cy.visit("/native/clientDisplay.html");
|
||||
|
||||
cy.clientDisplay().contains('User Skills');
|
||||
|
||||
// to subject page
|
||||
cy.wait(10000) // wait 10 seconds to ensure the token has expired
|
||||
cy.cdClickSubj();
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
it('timeout var not set, not tests to run', () => {
|
||||
cy.log(`timeout env var is not true [${Cypress.env('timeout')}], skipping test.`)
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
import selectors from "../support/selectors";
|
||||
|
||||
|
||||
context("Transcript Export Tests", () => {
|
||||
|
||||
const clean = (text) => {
|
||||
return text.replace(/\n/g, '')
|
||||
}
|
||||
|
||||
let userName
|
||||
beforeEach(() => {
|
||||
userName = Cypress.env('oauthMode') ? 'foo bar (foo)' : 'user1'
|
||||
const getFileName = (projName) => {
|
||||
return `./cypress/downloads/${projName} - ${userName} - Transcript.pdf`
|
||||
}
|
||||
Cypress.Commands.add("readTranscript", (pathToPdf) => {
|
||||
cy.log(`Reading transcript [${pathToPdf}]`)
|
||||
cy.readFile(pathToPdf, { timeout: 10000 }).then(() => {
|
||||
// file exists and was successfully read
|
||||
cy.log(`Transcript [${pathToPdf}] Found!`)
|
||||
})
|
||||
return cy.task('readPdf', pathToPdf)
|
||||
});
|
||||
Cypress.Commands.add("readTranscriptForProj", (projName) => {
|
||||
const pathToPdf = getFileName(projName)
|
||||
return cy.readTranscript(pathToPdf)
|
||||
});
|
||||
})
|
||||
if (Utils.skillsServiceVersionLaterThan('3.1.0')) {
|
||||
const expectedHeaderAndFooter = 'For All Dragons enjoyment'
|
||||
const expectedHeaderAndFooterCommunityProtected = 'For Divine Dragon enjoyment'
|
||||
|
||||
it('export user transcript', () => {
|
||||
const projName = 'Export1'
|
||||
cy.createDefaultTinyProject('proj1', projName)
|
||||
|
||||
// visit client display
|
||||
cy.visitSkillsDisplay();
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
cy.wrapIframe().find('[data-cy="downloadTranscriptBtn"]').click()
|
||||
|
||||
cy.readTranscriptForProj(projName).then((doc) => {
|
||||
expect(doc.numpages).to.equal(2)
|
||||
expect(clean(doc.text)).to.include('SkillTree Transcript')
|
||||
expect(clean(doc.text)).to.include(projName)
|
||||
expect(clean(doc.text)).to.include('Level: 0 / 5 ')
|
||||
expect(clean(doc.text)).to.include('Points: 0 / 100 ')
|
||||
expect(clean(doc.text)).to.include('Skills: 0 / 2 ')
|
||||
expect(clean(doc.text)).to.include(userName)
|
||||
expect(clean(doc.text)).to.not.include('Badges')
|
||||
|
||||
// should be a title on the 2nd page
|
||||
expect(clean(doc.text)).to.include('Subject: Subject 0'.toUpperCase())
|
||||
|
||||
expect(clean(doc.text)).to.not.include(expectedHeaderAndFooter)
|
||||
expect(clean(doc.text)).to.not.include(expectedHeaderAndFooterCommunityProtected)
|
||||
expect(clean(doc.text)).to.not.include('null')
|
||||
})
|
||||
});
|
||||
|
||||
it('export user transcript - community header', () => {
|
||||
cy.intercept('GET', '/public/config', (req) => {
|
||||
req.reply((res) => {
|
||||
const conf = res.body;
|
||||
conf.exportHeaderAndFooter = 'For {{community.project.descriptor}} enjoyment';
|
||||
res.send(conf);
|
||||
});
|
||||
}).as('getPublicConfig');
|
||||
const projName = 'Export2'
|
||||
cy.createDefaultTinyProject('proj1', projName)
|
||||
|
||||
// visit client display
|
||||
cy.visitSkillsDisplay();
|
||||
cy.wait('@getPublicConfig')
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
cy.wrapIframe().find('[data-cy="downloadTranscriptBtn"]').click()
|
||||
cy.readTranscriptForProj(projName).then((doc) => {
|
||||
expect(doc.numpages).to.equal(2)
|
||||
expect(clean(doc.text)).to.include('SkillTree Transcript')
|
||||
expect(clean(doc.text)).to.include(projName)
|
||||
expect(clean(doc.text)).to.include('Level: 0 / 5 ')
|
||||
expect(clean(doc.text)).to.include('Points: 0 / 100 ')
|
||||
expect(clean(doc.text)).to.include('Skills: 0 / 2 ')
|
||||
expect(clean(doc.text)).to.include(userName)
|
||||
expect(clean(doc.text)).to.not.include('Badges')
|
||||
|
||||
// should be a title on the 2nd page
|
||||
expect(clean(doc.text)).to.include('Subject: Subject 0'.toUpperCase())
|
||||
|
||||
expect(clean(doc.text)).to.include(expectedHeaderAndFooter)
|
||||
expect(clean(doc.text)).to.not.include(expectedHeaderAndFooterCommunityProtected)
|
||||
expect(clean(doc.text)).to.not.include('null')
|
||||
})
|
||||
});
|
||||
if (!Cypress.env('oauthMode')) {
|
||||
it('export user transcript - community protected header', () => {
|
||||
cy.intercept('GET', '/public/config', (req) => {
|
||||
req.reply((res) => {
|
||||
const conf = res.body;
|
||||
conf.exportHeaderAndFooter = 'For {{community.project.descriptor}} enjoyment';
|
||||
res.send(conf);
|
||||
});
|
||||
}).as('getPublicConfig');
|
||||
const projName = 'Export3'
|
||||
cy.createDefaultTinyProject('proj1', projName)
|
||||
|
||||
const allDragonsUser = '[email protected]'
|
||||
cy.fixture('vars.json').then((vars) => {
|
||||
cy.backendLogout();
|
||||
cy.backendRegister('user1', vars.defaultPass);
|
||||
cy.backendLogin(vars.rootUser, vars.defaultPass, true);
|
||||
cy.backendPost(`/root/users/user1/tags/dragons`, {tags: ['DivineDragon']});
|
||||
cy.backendPost(`/root/users/${vars.defaultUser}/tags/dragons`, {tags: ['DivineDragon']});
|
||||
cy.backendLogout();
|
||||
|
||||
cy.backendRegister(allDragonsUser, vars.defaultPass);
|
||||
cy.backendLogout();
|
||||
|
||||
cy.backendLogin(vars.defaultUser, vars.defaultPass);
|
||||
});
|
||||
cy.backendPost(`/admin/projects/proj1`, {
|
||||
projectId: 'proj1',
|
||||
name: projName,
|
||||
enableProtectedUserCommunity: true
|
||||
})
|
||||
|
||||
// visit client display
|
||||
cy.visitSkillsDisplay();
|
||||
cy.wait('@getPublicConfig')
|
||||
cy.clientDisplay().find(selectors.titleSection).contains('User Skills');
|
||||
cy.clientDisplay().find(selectors.myRankButton)
|
||||
|
||||
cy.wrapIframe().find('[data-cy="downloadTranscriptBtn"]').click()
|
||||
const pathToPdf = `cypress/downloads/${projName} - Firstname LastName (user1) - Transcript.pdf`
|
||||
|
||||
cy.readTranscript(pathToPdf).then((doc) => {
|
||||
expect(doc.numpages).to.equal(2)
|
||||
expect(clean(doc.text)).to.include('SkillTree Transcript')
|
||||
expect(clean(doc.text)).to.include(projName)
|
||||
expect(clean(doc.text)).to.include('Level: 0 / 5 ')
|
||||
expect(clean(doc.text)).to.include('Points: 0 / 100 ')
|
||||
expect(clean(doc.text)).to.include('Skills: 0 / 2 ')
|
||||
expect(clean(doc.text)).to.include(userName)
|
||||
expect(clean(doc.text)).to.not.include('Badges')
|
||||
|
||||
// should be a title on the 2nd page
|
||||
expect(clean(doc.text)).to.include('Subject: Subject 0'.toUpperCase())
|
||||
|
||||
expect(clean(doc.text)).to.not.include(expectedHeaderAndFooter)
|
||||
expect(clean(doc.text)).to.include(expectedHeaderAndFooterCommunityProtected)
|
||||
expect(clean(doc.text)).to.not.include('null')
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var semver = require('semver');
|
||||
|
||||
export default {
|
||||
versionLaterThan (lib, minVersion){
|
||||
const versionToCompare = Cypress.env(lib);
|
||||
if (!versionToCompare) {
|
||||
return true;
|
||||
}
|
||||
const shouldSkip = semver.lt(versionToCompare, minVersion);
|
||||
return !shouldSkip;
|
||||
}
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
const iFrameTimeout = 3000;
|
||||
let skillsWebsocketConnected
|
||||
|
||||
Cypress.Commands.add('visitHomePage', () => {
|
||||
skillsWebsocketConnected = null;
|
||||
cy.visit('/native/index.html', {
|
||||
onBeforeLoad(win) {
|
||||
skillsWebsocketConnected = cy.spy().as('skillsWebsocketConnected')
|
||||
const postMessage = win.postMessage.bind(win)
|
||||
win.postMessage = (what, target) => {
|
||||
if (Cypress._.isPlainObject(what) && what.skillsWebsocketConnected) {
|
||||
skillsWebsocketConnected(what)
|
||||
}
|
||||
return postMessage(what, target)
|
||||
}
|
||||
cy.spy(win, 'postMessage').as('postMessage')
|
||||
}
|
||||
});
|
||||
// wait for web socket to connect
|
||||
cy.get('@skillsWebsocketConnected').its('lastCall.args.0').its('skillsWebsocketConnected').should('eq', true);
|
||||
});
|
||||
|
||||
context("Native JS Tests", () => {
|
||||
if (Utils.versionLaterThan('@skills/skills-client-reporter', '1.1.1')) {
|
||||
it("global event show correct results", () => {
|
||||
cy.createDefaultProject();
|
||||
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
|
||||
cy.visitHomePage();
|
||||
cy.clickSubmit();
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
});
|
||||
}
|
||||
if (Utils.versionLaterThan('@skills/skills-client-reporter', '1.1.1')) {
|
||||
it("global event show correct results (skills reported directly to backend endpoint)", () => {
|
||||
cy.createDefaultProject();
|
||||
|
||||
cy.visitHomePage();
|
||||
cy.reportSkillForUser("IronMan", "user1");
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
});
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-reporter', '1.1.1')) {
|
||||
it('global event does not update when skill reported for a different project', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.createDefaultTinyProject('proj2')
|
||||
|
||||
cy.visitHomePage();
|
||||
cy.reportSkillForUser('IronMan', 'user1', 'proj2')
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
}
|
||||
if (Utils.versionLaterThan('@skills/skills-client-reporter', '1.1.1')) {
|
||||
it('global event is not reported when skill is not applied (skill reported directly to backend endpoint)', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
|
||||
cy.visitHomePage();
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
|
||||
cy.get('[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
}
|
||||
if (Utils.versionLaterThan('@skills/skills-client-reporter', '1.1.1')) {
|
||||
it('global event is not reported when skill is not applied', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
|
||||
cy.visitHomePage();
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
cy.clickSubmit()
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-reporter', '1.1.1')) {
|
||||
it('global event is reported even when skill is not applied when notifyIfSkillNotApplied=true ', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
|
||||
const sendEventViaDropdownId = "#exampleDirectiveClickEvent";
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click();
|
||||
});
|
||||
|
||||
cy.visitHomePage();
|
||||
cy.get('[type="checkbox"]').check()
|
||||
cy.clickSubmit()
|
||||
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"pointsEarned": 0')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"skillApplied": false')
|
||||
cy.get('pre[data-cy=globalEventResult]').contains('"explanation": "This skill reached its maximum points"')
|
||||
})
|
||||
}
|
||||
|
||||
it("skill display", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.server()
|
||||
.route("/api/users/user1/token")
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: "user1",
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visit("/native/clientDisplay.html");
|
||||
cy.wait(iFrameTimeout);
|
||||
|
||||
cy.iframe(body => {
|
||||
cy.wrap(body).contains("My Level");
|
||||
cy.wrap(body).contains("50 Points earned Today");
|
||||
cy.wrap(body).contains("Subject 0");
|
||||
|
||||
cy.wrap(body)
|
||||
.find(".skills-page-title-text-color")
|
||||
.should("have.css", "background-color")
|
||||
.and("equal", "rgb(255, 255, 255)");
|
||||
});
|
||||
});
|
||||
|
||||
it("skill display - summary only", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.server()
|
||||
.route("/api/users/user1/token")
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: "user1",
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visit("/native/clientDisplay.html?isSummaryOnly=true");
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe(body => {
|
||||
cy.wrap(body).contains("My Level");
|
||||
cy.wrap(body).contains("50 Points earned Today");
|
||||
cy.wrap(body)
|
||||
.contains("Subject 0")
|
||||
.should("not.exist");
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body)
|
||||
.find(".skills-page-title-text-color")
|
||||
.should("have.css", "background-color")
|
||||
.and("equal", "rgb(255, 255, 255)");
|
||||
});
|
||||
});
|
||||
|
||||
it("skill display - theme", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.server()
|
||||
.route("/api/users/user1/token")
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: "user1",
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visit("/native/clientDisplay.html?themeName=Dark Blue");
|
||||
cy.wait("@getToken");
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe(body => {
|
||||
cy.wrap(body).contains("My Level");
|
||||
cy.wrap(body).contains("50 Points earned Today");
|
||||
cy.wrap(body).contains("Subject 0");
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body)
|
||||
.find(".skills-page-title-text-color")
|
||||
.should("have.css", "background-color")
|
||||
.and("equal", "rgb(21, 46, 77)");
|
||||
});
|
||||
});
|
||||
|
||||
it("skill display - summary only - theme", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.server()
|
||||
.route("/api/users/user1/token")
|
||||
.as("getToken");
|
||||
cy.backendPost("/api/projects/proj1/skills/Thor", {
|
||||
userId: "user1",
|
||||
timestamp: Date.now()
|
||||
});
|
||||
cy.visit(
|
||||
"/native/clientDisplay.html?themeName=Dark Blue&isSummaryOnly=true"
|
||||
);
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe(body => {
|
||||
// cy.wait('@getToken')
|
||||
cy.wrap(body).contains("My Level");
|
||||
cy.wrap(body).contains("50 Points earned Today");
|
||||
cy.wrap(body)
|
||||
.contains("Subject 0")
|
||||
.should("not.exist");
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body)
|
||||
.find(".skills-page-title-text-color")
|
||||
.should("have.css", "background-color")
|
||||
.and("equal", "rgb(21, 46, 77)");
|
||||
});
|
||||
});
|
||||
|
||||
it("client display should display an error if skills service is down", () => {
|
||||
cy.createDefaultTinyProject();
|
||||
cy.server()
|
||||
.route({
|
||||
method: "GET",
|
||||
url: "/public/status",
|
||||
status: 503, // server is down
|
||||
response: {}
|
||||
})
|
||||
.as("getStatus");
|
||||
cy.visit("/native/clientDisplay.html");
|
||||
cy.wait("@getStatus");
|
||||
|
||||
cy.contains("Could NOT reach Skills Service");
|
||||
});
|
||||
|
||||
it("only display skills up-to the provided version", () => {
|
||||
const noVersionPoints = 'Earn up to 200 points';
|
||||
const v1Points = 'Earn up to 150 points';
|
||||
const v0Points = 'Earn up to 100 points';
|
||||
cy.createDefaultTinyProject();
|
||||
cy.server()
|
||||
.route("/api/users/user1/token")
|
||||
.as("getToken");
|
||||
cy.backendAddSkill("skillv1", 1);
|
||||
cy.backendAddSkill("skillv2", 2);
|
||||
cy.visit("/native/clientDisplay.html");
|
||||
cy.wait("@getToken");
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe(body => {
|
||||
cy.wrap(body).contains(noVersionPoints);
|
||||
});
|
||||
|
||||
cy.visit("/native/index.html");
|
||||
cy.visit("/native/clientDisplay.html?skillsVersion=1");
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe(body => {
|
||||
cy.wrap(body).contains(v1Points);
|
||||
});
|
||||
|
||||
cy.visit("/native/index.html");
|
||||
cy.visit("/native/clientDisplay.html?skillsVersion=0");
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe(body => {
|
||||
cy.wrap(body).contains(v0Points);
|
||||
});
|
||||
});
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-js', '1.1.1')) {
|
||||
it('skillsClientVersion is reported correctly', () => {
|
||||
cy.createDefaultProject()
|
||||
|
||||
cy.server().route('POST', '/api/projects/proj1/skillsClientVersion').as('reportClientVersion')
|
||||
|
||||
cy.visit('/native/index.html')
|
||||
cy.wait('@reportClientVersion')
|
||||
cy.get('@reportClientVersion').then((xhr) => {
|
||||
expect(xhr.status).to.eq(200)
|
||||
expect(xhr.responseBody).to.have.property('success').to.eq(true)
|
||||
});
|
||||
cy.get('@reportClientVersion').should((xhr) => {
|
||||
expect(xhr.request.body, 'request body').
|
||||
to.have.property('skillsClientVersion').
|
||||
and.to.contain('@skills/skills-client-js-')
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
|
||||
const iFrameTimeout = 3000;
|
||||
let skillsWebsocketConnected
|
||||
|
||||
Cypress.Commands.add('visitHomePage', () => {
|
||||
skillsWebsocketConnected = null;
|
||||
cy.visit('/react/index.html#/', {
|
||||
onBeforeLoad(win) {
|
||||
skillsWebsocketConnected = cy.spy().as('skillsWebsocketConnected')
|
||||
const postMessage = win.postMessage.bind(win)
|
||||
win.postMessage = (what, target) => {
|
||||
if (Cypress._.isPlainObject(what) && what.skillsWebsocketConnected) {
|
||||
skillsWebsocketConnected(what)
|
||||
}
|
||||
return postMessage(what, target)
|
||||
}
|
||||
cy.spy(win, 'postMessage').as('postMessage')
|
||||
}
|
||||
});
|
||||
// wait for web socket to connect
|
||||
cy.get('@skillsWebsocketConnected').its('lastCall.args.0').its('skillsWebsocketConnected').should('eq', true);
|
||||
});
|
||||
|
||||
context('React Tests', () => {
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('level component should be reactive (skills reported directly to backend endpoint)', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.reportSkillForUser('Thor', 'user1')
|
||||
cy.contains('Level 2')
|
||||
|
||||
cy.reportSkillForUser('subj1_skill0', 'user1')
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.reportSkillForUser('subj1_skill1', 'user1')
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.reportSkillForUser('subj2_skill0', 'user1')
|
||||
cy.contains('Level 4')
|
||||
|
||||
cy.reportSkillForUser('subj2_skill1', 'user1')
|
||||
cy.contains('Level 5')
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('global event show correct results', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.get('[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('level component should be reactive', () => {
|
||||
cy.createDefaultProject()
|
||||
const sendEventViaDropdownId = '#exampleDirectiveClickEvent';
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click()
|
||||
})
|
||||
Cypress.Commands.add("selectSkill", (skill) => {
|
||||
cy.get(`${sendEventViaDropdownId} select`).select(`${skill}`)
|
||||
})
|
||||
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.selectSkill('IronMan')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.selectSkill('Thor')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 2')
|
||||
|
||||
cy.selectSkill('subj1_skill0')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.selectSkill('subj1_skill1')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.selectSkill('subj2_skill0')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 4')
|
||||
|
||||
cy.selectSkill('subj2_skill1')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 5')
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('global event does not update when skill reported for a different project', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.createDefaultTinyProject('proj2')
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1', 'proj2')
|
||||
|
||||
cy.contains('Level 0')
|
||||
cy.get('[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('level component should not update when admin reports skill for other user', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', '[email protected]')
|
||||
cy.contains('Level 0')
|
||||
})
|
||||
}
|
||||
|
||||
it('skill display', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/react/index.html#/showSkills')
|
||||
cy.wait('@getToken')
|
||||
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0')
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(255, 255, 255)');
|
||||
});
|
||||
})
|
||||
|
||||
it('skill display - summary only', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/react/index.html#/showSkills?isSummaryOnly=true')
|
||||
cy.wait('@getToken')
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0').should('not.exist')
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(255, 255, 255)');
|
||||
})
|
||||
})
|
||||
|
||||
it('skill display - theme', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/react/index.html#/showSkills?themeName=Dark Blue')
|
||||
cy.wait('@getToken')
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0')
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(21, 46, 77)');
|
||||
})
|
||||
})
|
||||
|
||||
it('skill display - summary only - theme', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/react/index.html#/showSkills?themeName=Dark Blue&isSummaryOnly=true')
|
||||
cy.wait('@getToken')
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0').should('not.exist')
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(21, 46, 77)');
|
||||
})
|
||||
})
|
||||
|
||||
it('client display should display an error if skills service is down', () => {
|
||||
cy.server().route({
|
||||
method: 'GET',
|
||||
url: '/public/status',
|
||||
status: 503, // server is down
|
||||
response: {}
|
||||
}).as('getStatus')
|
||||
cy.visit('/react/index.html#/showSkills')
|
||||
cy.wait('@getStatus')
|
||||
|
||||
cy.contains('Could NOT reach Skills Service')
|
||||
});
|
||||
|
||||
it('only display skills up-to the provided version', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendAddSkill('skillv1', 1)
|
||||
cy.backendAddSkill('skillv2', 2)
|
||||
cy.visit('/react/index.html#/showSkills')
|
||||
cy.wait('@getToken')
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('Earn up to 200 points')
|
||||
})
|
||||
|
||||
cy.visit('/react/index.html#/')
|
||||
cy.visit('/react/index.html#/showSkills?skillsVersion=1')
|
||||
cy.wait('@getToken')
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe((body) => {
|
||||
cy.wrap(body).contains('Earn up to 150 points')
|
||||
})
|
||||
|
||||
cy.visit('/react/index.html#/')
|
||||
cy.visit('/react/index.html#/showSkills?skillsVersion=0')
|
||||
cy.wait('@getToken')
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe((body) => {
|
||||
cy.wrap(body).contains('Earn up to 100 points')
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('skillsClientVersion is reported correctly', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visit('/react/index.html#/')
|
||||
|
||||
cy.server().route('POST', '/api/projects/proj1/skillsClientVersion').as('reportClientVersion')
|
||||
|
||||
cy.wait('@reportClientVersion')
|
||||
cy.get('@reportClientVersion').then((xhr) => {
|
||||
expect(xhr.status).to.eq(200)
|
||||
expect(xhr.responseBody).to.have.property('success').to.eq(true)
|
||||
});
|
||||
cy.get('@reportClientVersion').should((xhr) => {
|
||||
expect(xhr.request.body, 'request body').
|
||||
to.have.property('skillsClientVersion').
|
||||
and.to.contain('@skills/skills-client-react-')
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,383 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Utils from "./Utils";
|
||||
|
||||
const iFrameTimeout = 3000;
|
||||
let skillsWebsocketConnected
|
||||
|
||||
Cypress.Commands.add('visitHomePage', () => {
|
||||
skillsWebsocketConnected = null;
|
||||
cy.visit('/vuejs#/', {
|
||||
onBeforeLoad(win) {
|
||||
skillsWebsocketConnected = cy.spy().as('skillsWebsocketConnected')
|
||||
const postMessage = win.postMessage.bind(win)
|
||||
win.postMessage = (what, target) => {
|
||||
if (Cypress._.isPlainObject(what) && what.skillsWebsocketConnected) {
|
||||
skillsWebsocketConnected(what)
|
||||
}
|
||||
return postMessage(what, target)
|
||||
}
|
||||
cy.spy(win, 'postMessage').as('postMessage')
|
||||
}
|
||||
});
|
||||
// wait for web socket to connect
|
||||
cy.get('@skillsWebsocketConnected').its('lastCall.args.0').its('skillsWebsocketConnected').should('eq', true);
|
||||
});
|
||||
|
||||
context('Vue Tests', () => {
|
||||
|
||||
if (Utils.versionLaterThan("@skills/skills-client-vue", '1.1.1')) {
|
||||
it('level component should be reactive', () => {
|
||||
cy.createDefaultProject()
|
||||
const sendEventViaDropdownId = '#PureJSReportAnySkill';
|
||||
Cypress.Commands.add("clickSubmit", () => {
|
||||
cy.get(`${sendEventViaDropdownId} .btn`).click()
|
||||
})
|
||||
Cypress.Commands.add("selectSkill", (skill) => {
|
||||
cy.get(`${sendEventViaDropdownId} .multiselect`).type(`${skill}{enter}`)
|
||||
})
|
||||
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.selectSkill('IronMan')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.selectSkill('Thor')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 2')
|
||||
|
||||
cy.selectSkill('subj1_skill0')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.selectSkill('subj1_skill1')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.selectSkill('subj2_skill0')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 4')
|
||||
|
||||
cy.selectSkill('subj2_skill1')
|
||||
cy.clickSubmit()
|
||||
cy.contains('Level 5')
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan("@skills/skills-client-vue", '1.1.1')) {
|
||||
it('level component should be reactive (skills reported directly to backend endpoint)', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.reportSkillForUser('Thor', 'user1')
|
||||
cy.contains('Level 2')
|
||||
|
||||
cy.reportSkillForUser('subj1_skill0', 'user1')
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.reportSkillForUser('subj1_skill1', 'user1')
|
||||
cy.contains('Level 3')
|
||||
|
||||
cy.reportSkillForUser('subj2_skill0', 'user1')
|
||||
cy.contains('Level 4')
|
||||
|
||||
cy.reportSkillForUser('subj2_skill1', 'user1')
|
||||
cy.contains('Level 5')
|
||||
})
|
||||
}
|
||||
|
||||
if (Utils.versionLaterThan("@skills/skills-client-vue", '1.1.1')) {
|
||||
it('global event show correct results', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
|
||||
cy.contains('Level 1')
|
||||
cy.get('[data-cy=globalEventResult]').contains('"skillId": "IronMan"')
|
||||
cy.get('[data-cy=globalEventResult]').contains('"pointsEarned": 50')
|
||||
cy.get('[data-cy=globalEventResult]').contains('"skillApplied": true')
|
||||
cy.get('[data-cy=globalEventResult]').contains(/completed": [[][^]*"type": "Overall",[^]\s*"level": 1/)
|
||||
})
|
||||
}
|
||||
if (Utils.versionLaterThan("@skills/skills-client-vue", '1.1.1')) {
|
||||
it('global event does not update when skill reported for a different project', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.createDefaultTinyProject('proj2')
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1', 'proj2')
|
||||
|
||||
cy.contains('Level 0')
|
||||
cy.get('[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
}
|
||||
if (Utils.versionLaterThan("@skills/skills-client-vue", '1.1.1')) {
|
||||
it('global event is not reported when skill is not applied', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.reportSkillForUser('IronMan', 'user1')
|
||||
cy.contains('Level 1')
|
||||
|
||||
cy.get('[data-cy=globalEventResult]').should('be.empty');
|
||||
})
|
||||
}
|
||||
if (Utils.versionLaterThan("@skills/skills-client-vue", '1.1.1')) {
|
||||
it('level component should not update when admin reports skill for other user', () => {
|
||||
|
||||
cy.createDefaultProject()
|
||||
Cypress.Commands.add("reportSkill", (skillId) => {
|
||||
cy.backendPost(`/api/projects/proj1/skills/${skillId}`)
|
||||
})
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.contains('Level 0')
|
||||
|
||||
cy.reportSkillForUser('IronMan', '[email protected]')
|
||||
cy.contains('Level 0')
|
||||
})
|
||||
}
|
||||
|
||||
it('v-skill directive on click', () => {
|
||||
cy.createDefaultProject(1, 2, 50, 2)
|
||||
|
||||
cy.server().route('POST', '/api/projects/proj1/skills/IronMan').as('postSkill')
|
||||
|
||||
cy.visit('/vuejs#/')
|
||||
|
||||
Cypress.Commands.add("clickOnDirectiveBtn", (skillApplied = true) => {
|
||||
cy.get('#SkillsDirectiveClickEvent button').click()
|
||||
cy.wait('@postSkill')
|
||||
cy.get('@postSkill').then((xhr) => {
|
||||
expect(xhr.status).to.eq(200)
|
||||
expect(xhr.responseBody).to.have.property('skillApplied').to.eq(skillApplied)
|
||||
});
|
||||
})
|
||||
|
||||
cy.clickOnDirectiveBtn()
|
||||
cy.clickOnDirectiveBtn()
|
||||
cy.clickOnDirectiveBtn(false)
|
||||
})
|
||||
|
||||
|
||||
it('v-skill directive on input', () => {
|
||||
cy.createDefaultProject(1, 2, 50, 2)
|
||||
cy.server().route('POST', '/api/projects/proj1/skills/Thor').as('postSkill')
|
||||
|
||||
cy.visitHomePage();
|
||||
|
||||
Cypress.Commands.add("typeToInput", (skillApplied = true) => {
|
||||
cy.get('#SkillsDirectiveInputEvent input').type('h')
|
||||
cy.wait('@postSkill')
|
||||
cy.get('@postSkill').then((xhr) => {
|
||||
expect(xhr.status).to.eq(200)
|
||||
expect(xhr.responseBody).to.have.property('skillApplied').to.eq(skillApplied)
|
||||
});
|
||||
})
|
||||
|
||||
cy.typeToInput()
|
||||
cy.typeToInput()
|
||||
cy.typeToInput(false)
|
||||
})
|
||||
|
||||
it('v-skill directive on click with error', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('POST', '/api/projects/proj1/skills/DoesNotExist').as('postSkill')
|
||||
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.get('#SkillsDirectiveErrorwithButton button').click()
|
||||
cy.wait('@postSkill');
|
||||
cy.get('@postSkill').then((xhr) => {
|
||||
expect(xhr.status).to.eq(400)
|
||||
expect(xhr.responseBody).to.have.property('explanation').to.eq('Failed to report skill event because skill definition does not exist.')
|
||||
});
|
||||
})
|
||||
|
||||
it('v-skill directive on input with error', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('POST', '/api/projects/proj1/skills/DoesNotExist').as('postSkill')
|
||||
|
||||
cy.visitHomePage();
|
||||
|
||||
cy.get('#SkillsDirectiveErrorwithInput input').type('h')
|
||||
cy.wait('@postSkill');
|
||||
cy.get('@postSkill').then((xhr) => {
|
||||
expect(xhr.status).to.eq(400)
|
||||
expect(xhr.responseBody).to.have.property('explanation').to.eq('Failed to report skill event because skill definition does not exist.')
|
||||
});
|
||||
})
|
||||
|
||||
it('skill display', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/vuejs#/showSkills')
|
||||
cy.wait('@getToken')
|
||||
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0')
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(255, 255, 255)');
|
||||
});
|
||||
})
|
||||
|
||||
it('skill display - summary only', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/vuejs#/showSkills?isSummaryOnly=true')
|
||||
cy.wait('@getToken')
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0').should('not.exist')
|
||||
|
||||
// verify that there is no background set
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(255, 255, 255)');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('skill display - theme', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/vuejs#/showSkills?themeName=Dark Blue')
|
||||
cy.wait('@getToken')
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0')
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(21, 46, 77)');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('skill display - summary only - theme', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: 'user1', timestamp: Date.now()})
|
||||
cy.visit('/vuejs#/showSkills?themeName=Dark Blue&isSummaryOnly=true')
|
||||
cy.wait('@getToken')
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('My Level')
|
||||
cy.wrap(body).contains('50 Points earned Today')
|
||||
cy.wrap(body).contains('Subject 0').should('not.exist')
|
||||
|
||||
// verify dark blue background of hex #152E4d
|
||||
// cypress always validates against rgb
|
||||
cy.wrap(body).find('.skills-page-title-text-color')
|
||||
.should('have.css', 'background-color').and('equal', 'rgb(21, 46, 77)');
|
||||
})
|
||||
})
|
||||
|
||||
it('client display should display an error if skills service is down', () => {
|
||||
cy.server().route({
|
||||
method: 'GET',
|
||||
url: '/public/status',
|
||||
status: 503, // server is down
|
||||
response: {}
|
||||
}).as('getStatus')
|
||||
cy.visit('/vuejs#/showSkills')
|
||||
cy.wait('@getStatus')
|
||||
|
||||
cy.contains('Could NOT reach Skills Service')
|
||||
});
|
||||
|
||||
it('only display skills up-to the provided version', () => {
|
||||
cy.createDefaultTinyProject()
|
||||
cy.server().route('/api/users/user1/token').as('getToken')
|
||||
cy.backendAddSkill('skillv1', 1)
|
||||
cy.backendAddSkill('skillv2', 2)
|
||||
cy.visit('/vuejs#/showSkills')
|
||||
cy.wait('@getToken')
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe((body) => {
|
||||
cy.wait('@getToken')
|
||||
cy.wrap(body).contains('Earn up to 200 points')
|
||||
})
|
||||
|
||||
cy.visit('/vuejs#/')
|
||||
cy.visit('/vuejs#/showSkills?skillsVersion=1')
|
||||
cy.wait('@getToken')
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe((body) => {
|
||||
cy.wrap(body).contains('Earn up to 150 points')
|
||||
})
|
||||
|
||||
cy.visit('/vuejs#/')
|
||||
cy.visit('/vuejs#/showSkills?skillsVersion=0')
|
||||
cy.wait('@getToken')
|
||||
cy.wait(iFrameTimeout);
|
||||
cy.iframe((body) => {
|
||||
cy.wrap(body).contains('Earn up to 100 points')
|
||||
})
|
||||
});
|
||||
|
||||
if (Utils.versionLaterThan('@skills/skills-client-react', '1.1.1')) {
|
||||
it('skillsClientVersion is reported correctly', () => {
|
||||
cy.createDefaultProject()
|
||||
cy.visit('/vuejs#/')
|
||||
|
||||
cy.server().route('POST', '/api/projects/proj1/skillsClientVersion').as('reportClientVersion')
|
||||
|
||||
cy.wait('@reportClientVersion')
|
||||
cy.get('@reportClientVersion').then((xhr) => {
|
||||
expect(xhr.status).to.eq(200)
|
||||
expect(xhr.responseBody).to.have.property('success').to.eq(true)
|
||||
});
|
||||
cy.get('@reportClientVersion').should((xhr) => {
|
||||
expect(xhr.request.body, 'request body').
|
||||
to.have.property('skillsClientVersion').
|
||||
and.to.contain('@skills/skills-client-vue-')
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
const { readPdf } = require('./read-pdf')
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
@@ -39,4 +40,8 @@ module.exports = (on, config) => {
|
||||
}
|
||||
return launchOptions;
|
||||
});
|
||||
|
||||
on("task", {
|
||||
readPdf
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,13 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const proxy = require('http-proxy-middleware');
|
||||
module.exports = function(app) {
|
||||
app.use(
|
||||
'/api',
|
||||
proxy({
|
||||
target: 'http://localhost:8090',
|
||||
changeOrigin: true,
|
||||
})
|
||||
);
|
||||
};
|
||||
const fs = require('fs')
|
||||
const pdf = require('pdf-parse')
|
||||
|
||||
const readPdf = (filename) => {
|
||||
const dataBuffer = fs.readFileSync(filename)
|
||||
return pdf(dataBuffer).then(function (data) {
|
||||
return {
|
||||
numpages: data.numpages,
|
||||
text: data.text,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { readPdf }
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,109 +38,268 @@
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
import selectors from './selectors.js'
|
||||
|
||||
const backend = 'http://localhost:8080';
|
||||
const baseUrl = Cypress.config().baseUrl;
|
||||
const skillsDisplayHomePage = '/native/clientDisplay.html'
|
||||
|
||||
|
||||
Cypress.Commands.add('onlyOn', (enabled) => {
|
||||
if (enabled !== true) {
|
||||
cy.state('runnable').ctx.skip()
|
||||
}
|
||||
})
|
||||
|
||||
Cypress.Commands.add("visitSkillsDisplay", (url = '') => {
|
||||
cy.visit(`${skillsDisplayHomePage}${url}`);
|
||||
})
|
||||
|
||||
Cypress.Commands.add("backendRegister", (user, pass, grantRoot) => {
|
||||
return cy.request(`${backend}/app/users/validExistingDashboardUserId/${user}`)
|
||||
.then((response) => {
|
||||
if (response.body !== true) {
|
||||
cy.log(`Creating user [${user}]`)
|
||||
cy.request('PUT', `${backend}/createAccount`, {
|
||||
firstName: 'Firstname',
|
||||
lastName: 'LastName',
|
||||
email: user,
|
||||
password: pass,
|
||||
});
|
||||
if (grantRoot) {
|
||||
cy.request('POST', `${backend}/grantFirstRoot`);
|
||||
}
|
||||
cy.request('POST', `${backend}/logout`);
|
||||
} else {
|
||||
cy.log(`User [${user}] already exist`)
|
||||
}
|
||||
return cy.request(`${backend}/app/users/validExistingDashboardUserId/${user}`)
|
||||
.then((response) => {
|
||||
if (response.body !== true) {
|
||||
cy.log(`Creating user [${user}]`)
|
||||
cy.request('PUT', `${backend}/createAccount`, {
|
||||
firstName: 'Firstname',
|
||||
lastName: 'LastName',
|
||||
email: user,
|
||||
password: pass,
|
||||
});
|
||||
if (grantRoot) {
|
||||
cy.request('POST', `${backend}/grantFirstRoot`);
|
||||
}
|
||||
cy.backendLogout()
|
||||
} else {
|
||||
cy.log(`User [${user}] already exists`)
|
||||
}
|
||||
});
|
||||
});
|
||||
Cypress.Commands.add("backendLogout", () => {
|
||||
return cy.request('POST', `${backend}/logout`);
|
||||
})
|
||||
|
||||
Cypress.Commands.add("backendPost", (url) => {
|
||||
return cy.request('POST', `${backend}/${url}`);
|
||||
})
|
||||
|
||||
Cypress.Commands.add("backendLogin", (user, pass) => {
|
||||
cy.request( {
|
||||
method: 'POST',
|
||||
url: `${backend}/performLogin`,
|
||||
body: {
|
||||
username: user,
|
||||
password: pass
|
||||
},
|
||||
form: true,
|
||||
})
|
||||
return cy.request({
|
||||
method: 'POST',
|
||||
url: `${backend}/performLogin`,
|
||||
body: {
|
||||
username: user,
|
||||
password: pass
|
||||
},
|
||||
form: true,
|
||||
})
|
||||
});
|
||||
|
||||
Cypress.Commands.add("backendLogout", () => {
|
||||
cy.request('POST', `${backend}/logout`);
|
||||
return cy.request('POST', `${backend}/logout`).as('request')
|
||||
});
|
||||
|
||||
|
||||
Cypress.Commands.add("backendPost", (url, body) => {
|
||||
cy.request('POST', `${backend}${url}`, body)
|
||||
return cy.request('POST', `${backend}${url}`, body)
|
||||
});
|
||||
|
||||
Cypress.Commands.add("reportSkill", (skillId, projId = 'proj1') => {
|
||||
cy.backendPost(`/api/projects/${projId}/skills/${skillId}`)
|
||||
cy.backendPost(`/api/projects/${projId}/skills/${skillId}`)
|
||||
})
|
||||
|
||||
Cypress.Commands.add("reportSkillForUser", (skillId, userId, projId = 'proj1', timestamp = Date.now()) => {
|
||||
cy.backendPost(`/api/projects/${projId}/skills/${skillId}`, {userId: userId, timestamp: timestamp})
|
||||
cy.backendPost(`/api/projects/${projId}/skills/${skillId}`, { userId: userId, timestamp: timestamp })
|
||||
})
|
||||
|
||||
Cypress.Commands.add("backendAddSkill", (skillId, version = 0, projId ='proj1', subjId='subj0', pointIncrement = 50, numPerformToCompletion = 1) => {
|
||||
cy.backendPost(`/admin/projects/${projId}/subjects/${subjId}/skills/${skillId}`, {
|
||||
projectId: projId,
|
||||
subjectId: subjId,
|
||||
skillId: skillId,
|
||||
name: `This is ${skillId}`,
|
||||
type: "Skill",
|
||||
pointIncrement: pointIncrement,
|
||||
numPerformToCompletion: numPerformToCompletion,
|
||||
pointIncrementInterval: 0,
|
||||
numMaxOccurrencesIncrementInterval: -1,
|
||||
description: "This skill a skill!",
|
||||
version: version,
|
||||
})
|
||||
Cypress.Commands.add("backendAddSkill", (skillId, version = 0, projId = 'proj1', subjId = 'subj0', pointIncrement = 50, numPerformToCompletion = 1) => {
|
||||
cy.backendPost(`/admin/projects/${projId}/subjects/${subjId}/skills/${skillId}`, {
|
||||
projectId: projId,
|
||||
subjectId: subjId,
|
||||
skillId: skillId,
|
||||
name: `This is ${skillId}`,
|
||||
type: "Skill",
|
||||
pointIncrement: pointIncrement,
|
||||
numPerformToCompletion: numPerformToCompletion,
|
||||
pointIncrementInterval: 0,
|
||||
numMaxOccurrencesIncrementInterval: -1,
|
||||
description: "This skill a skill!",
|
||||
version: version,
|
||||
})
|
||||
});
|
||||
|
||||
Cypress.Commands.add("createDefaultProject", (numSubj = 3, numSkillsPerSubj = 2, pointIncrement = 50, numPerformToCompletion = 1, projId ='proj1') => {
|
||||
const skillIdsToCreate = ['IronMan', 'Thor']
|
||||
cy.backendPost(`/app/projects/${projId}`, {
|
||||
projectId: projId,
|
||||
name: `Very Cool Project with id ${projId}`
|
||||
})
|
||||
|
||||
for(let i=0; i < numSubj; i++){
|
||||
const subjId = `subj${i}`
|
||||
cy.backendPost(`/admin/projects/${projId}/subjects/${subjId}`, {
|
||||
projectId: 'proj1',
|
||||
subjectId: subjId,
|
||||
name: `Subject ${i}`
|
||||
})
|
||||
|
||||
for(let j=0; j < numSkillsPerSubj; j++) {
|
||||
let skillId = `${subjId}_skill${j}`
|
||||
if (skillIdsToCreate.length > 0){
|
||||
skillId = skillIdsToCreate.pop()
|
||||
}
|
||||
cy.backendAddSkill(skillId, 0, projId, subjId, pointIncrement, numPerformToCompletion)
|
||||
}
|
||||
Cypress.Commands.add("createDefaultProject", (numSubj = 3, numSkillsPerSubj = 2, pointIncrement = 50, numPerformToCompletion = 1, projId = 'proj1', projName = null) => {
|
||||
const skillIdsToCreate = ['IronMan', 'Thor']
|
||||
cy.backendPost(`/app/projects/${projId}`, {
|
||||
projectId: projId,
|
||||
name: projName || `Very Cool Project with id ${projId}`
|
||||
}).then((resp => {
|
||||
if (Cypress.env('oauthMode')) {
|
||||
// if we're in oauthMode, then the foo-hyrda user will own the project. so we need to give the
|
||||
// defaultUser admin rights since the user will access the project from the skills-int-service app
|
||||
cy.fixture('vars.json').then((vars) => {
|
||||
cy.backendPost(`/admin/projects/${projId}/users/${vars.defaultUser}/roles/ROLE_PROJECT_ADMIN`)
|
||||
})
|
||||
}
|
||||
}))
|
||||
|
||||
for (let i = 0; i < numSubj; i++) {
|
||||
const subjId = `subj${i}`
|
||||
cy.backendPost(`/admin/projects/${projId}/subjects/${subjId}`, {
|
||||
projectId: 'proj1',
|
||||
subjectId: subjId,
|
||||
name: `Subject ${i}`
|
||||
})
|
||||
|
||||
for (let j = 0; j < numSkillsPerSubj; j++) {
|
||||
let skillId = `${subjId}_skill${j}`
|
||||
if (skillIdsToCreate.length > 0) {
|
||||
skillId = skillIdsToCreate.pop()
|
||||
}
|
||||
cy.backendAddSkill(skillId, 0, projId, subjId, pointIncrement, numPerformToCompletion)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Cypress.Commands.add("createDefaultTinyProject", (projId ='proj1') => {
|
||||
cy.createDefaultProject(1, 2, 50, 1, projId)
|
||||
Cypress.Commands.add("createDefaultTinyProject", (projId = 'proj1', projName = null) => {
|
||||
cy.createDefaultProject(1, 2, 50, 1, projId, projName)
|
||||
});
|
||||
|
||||
Cypress.Commands.add("iframe", (handleIframeBody) => {
|
||||
// iframe is not support natively (as of now)
|
||||
cy.get('iframe').then((iframe) => {
|
||||
const body = iframe.contents().find('body');
|
||||
handleIframeBody(body);
|
||||
})
|
||||
// iframe is not support natively (as of now)
|
||||
cy.get('iframe').then((iframe) => {
|
||||
const body = iframe.contents().find('body');
|
||||
handleIframeBody(body);
|
||||
})
|
||||
});
|
||||
|
||||
Cypress.Commands.add('visitHomePage', (homepage) => {
|
||||
const winMessage = cy.stub().as('message')
|
||||
cy.visit(homepage, {
|
||||
onBeforeLoad(win) {
|
||||
win.addEventListener('message', (e) => {
|
||||
winMessage(e.data)
|
||||
})
|
||||
}
|
||||
})
|
||||
// wait for web socket to connect
|
||||
cy.get('@message').should('have.been.calledWith', {skillsWebsocketConnected:true})
|
||||
cy.window().should('have.property', 'skillsLogger')
|
||||
cy.skillsLog(`Visit Home page for test [${Cypress.mocha.getRunner().test.title}]`)
|
||||
});
|
||||
|
||||
Cypress.Commands.add("cdClickSubj", () => {
|
||||
cy.wrapIframe().find(selectors.firstSubjectTileBtn).click();
|
||||
cy.wrapIframe().find(selectors.titleSection).contains('Subject 0');
|
||||
});
|
||||
|
||||
Cypress.Commands.add("cdBack", (expectedTitle = 'User Skills') => {
|
||||
cy.wrapIframe().find(selectors.backButton).click()
|
||||
cy.wrapIframe().contains(expectedTitle);
|
||||
|
||||
// back button should not exist on the home page, whose title is the default value
|
||||
if (expectedTitle === 'User Skills') {
|
||||
cy.wrapIframe().find(selectors.backButton).should('not.exist');
|
||||
}
|
||||
});
|
||||
|
||||
Cypress.Commands.add("clientDisplay", (firstVisit=false, project='proj1') => {
|
||||
cy.intercept(`/api/projects/${project}/rank`).as(`getRank${project}`)
|
||||
cy.intercept(`/api/projects/${project}/pointHistory`).as(`getPointsHistory${project}`)
|
||||
if (firstVisit) {
|
||||
cy.wait(`@getRank${project}`)
|
||||
cy.wait(`@getPointsHistory${project}`)
|
||||
}
|
||||
return cy.wrapIframe();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('wrapIframe', () => {
|
||||
return cy.get('iframe')
|
||||
.its('0.contentDocument.body').should('not.be.empty')
|
||||
.then(cy.wrap)
|
||||
});
|
||||
|
||||
Cypress.Commands.add('skillsLog', (message) => {
|
||||
cy.window().then(win => {
|
||||
if (win.skillsLogger) {
|
||||
win.skillsLogger.info(message)
|
||||
} else {
|
||||
console.error('no skillsLogger found in window');
|
||||
console.log(message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('loginBySingleSignOn', (projId = 'proj1') => {
|
||||
Cypress.log({
|
||||
name: 'loginBySingleSignOn',
|
||||
})
|
||||
|
||||
// first try to get a skills token,
|
||||
cy.request({
|
||||
url: `http://localhost:8080/api/projects/${projId}/token`,
|
||||
failOnStatusCode: false,
|
||||
}).then((tokenResp) => {
|
||||
if (tokenResp.status === 401) {
|
||||
cy.skillsLog('Skills token request failed, authenticating with OAuth provider...');
|
||||
cy.request({
|
||||
url: 'http://localhost:8080/oauth2/authorization/hydra',
|
||||
qs: { skillsRedirectUri: baseUrl, },
|
||||
// qs: { skillsRedirectUri: `${baseUrl}${homePage}` },
|
||||
}).then((resp) => {
|
||||
expect(resp.status).to.eq(200)
|
||||
|
||||
// parse out the authenticity_token
|
||||
const $html = Cypress.$(resp.body)
|
||||
const authenticityToken = $html.find('input[name=_csrf]').val()
|
||||
const challenge = $html.find('input[name=challenge]').val()
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: 'http://localhost:3000/login',
|
||||
form: true, // we are submitting a regular form body
|
||||
body: {
|
||||
_csrf: authenticityToken,
|
||||
challenge,
|
||||
email: '[email protected]',
|
||||
password: 'foobar',
|
||||
submit: 'Log in',
|
||||
remember: '1',
|
||||
},
|
||||
};
|
||||
|
||||
cy.request(options).then((resp2) => {
|
||||
expect(resp2.status).to.eq(200)
|
||||
|
||||
if (resp2.redirects[resp2.redirects.length-1].includes('/consent?consent_challenge')) {
|
||||
cy.skillsLog('Granting consent with OAuth provider...');
|
||||
const $html = Cypress.$(resp2.body)
|
||||
const authenticityToken = $html.find('input[name=_csrf]').val()
|
||||
const challenge = $html.find('input[name=challenge]').val()
|
||||
// const consentUrl = resp2.redirects.filter(r => r.includes('/consent?consent_challenge'))[0].split(' ')[1]
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: 'http://localhost:3000/consent',
|
||||
form: true, // we are submitting a regular form body
|
||||
qs: { consent_challenge: challenge },
|
||||
body: {
|
||||
_csrf: authenticityToken,
|
||||
challenge,
|
||||
grant_scope: 'openid',
|
||||
// grant_scope: 'offline',
|
||||
submit: 'Allow access',
|
||||
remember: '1',
|
||||
},
|
||||
failOnStatusCode: false,
|
||||
};
|
||||
|
||||
cy.request(options).then((resp3) => {
|
||||
expect(resp3.status).to.eq(200)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
cy.skillsLog('Received Skills token, already authenticated with OAuth provider.');
|
||||
}
|
||||
})
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
before(() => {
|
||||
cy.readFile('../skills-int-client-js/package.json').then((packageJson) => {
|
||||
const skillsClientJsVersion = packageJson['dependencies']['@skilltree/skills-client-js']
|
||||
Cypress.env('skills-client-js-version', skillsClientJsVersion)
|
||||
cy.log(`Running with skills-client-js version [${skillsClientJsVersion}]`)
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
// first call to npm fails, looks like this may be the bug: https://github.com/cypress-io/cypress/issues/6081
|
||||
cy.exec('npm version', { failOnNonZeroExit: false })
|
||||
cy.exec('npm run backend:resetDb')
|
||||
|
||||
cy.log(`Running with skills-client-js version [${Cypress.env('skills-client-js-version')}]`)
|
||||
|
||||
cy.fixture('vars.json').then((vars) => {
|
||||
cy.request('api/config').then(resp => {
|
||||
cy.backendRegister(vars.rootUser, vars.defaultPass, true);
|
||||
cy.backendRegister(vars.defaultUser, vars.defaultPass); // used by the skills-int-service app
|
||||
if (!Cypress.env('oauthMode')) {
|
||||
cy.backendLogin(vars.defaultUser, vars.defaultPass);
|
||||
Cypress.env('proxyUser', 'user1')
|
||||
Cypress.env('tokenUrl', '/api/users/user1/token')
|
||||
} else {
|
||||
cy.loginBySingleSignOn()
|
||||
Cypress.env('proxyUser', 'foo-hydra')
|
||||
Cypress.env('tokenUrl', 'http://localhost:8080/api/projects/proj1/token')
|
||||
}
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
cy.skillsLog(`Completed test [${Cypress.mocha.getRunner().test.title}]`)
|
||||
})
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
// first call to npm fails, looks like this may be the bug: https://github.com/cypress-io/cypress/issues/6081
|
||||
cy.exec('npm version', {failOnNonZeroExit: false})
|
||||
cy.exec('npm run backend:resetDb')
|
||||
|
||||
cy.fixture('vars.json').then((vars) => {
|
||||
cy.backendRegister(vars.rootUser, vars.defaultPass, true);
|
||||
cy.backendRegister(vars.defaultUser, vars.defaultPass);
|
||||
cy.backendLogin(vars.defaultUser, vars.defaultPass);
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2025 SkillTree
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Utils from "../e2e/Utils";
|
||||
|
||||
const buildFirstSubjectTileBtnSelector = () => {
|
||||
if (Utils.skillsServiceVersionLaterThan('3.0.0')) {
|
||||
return '[data-cy="subjectTile-subj0"] [data-cy="subjectTileBtn"]'
|
||||
}
|
||||
|
||||
return '[data-cy="subjectTile"]:nth-child(1)'
|
||||
}
|
||||
|
||||
const buildMyRankBtnSelector = () => {
|
||||
if (Utils.skillsServiceVersionLaterThan('3.0.0')) {
|
||||
return '[data-cy="myRankBtn"]'
|
||||
}
|
||||
|
||||
return '[data-cy="myRank"]'
|
||||
}
|
||||
|
||||
|
||||
const buildSkillLinkSelector = (skillId) => {
|
||||
if (Utils.skillsServiceVersionLaterThan('3.0.0')) {
|
||||
return `[data-cy="skillProgressTitle-${skillId}"] [data-cy="skillProgressTitle"]`
|
||||
}
|
||||
|
||||
return `#skillRow-${skillId} [data-cy="skillProgressTitle"]`
|
||||
}
|
||||
|
||||
const buildSkillTitleSelector = (skillId) => {
|
||||
if (Utils.skillsServiceVersionLaterThan('3.0.0')) {
|
||||
return `[data-cy="skillProgressTitle-${skillId}"]`
|
||||
}
|
||||
|
||||
return `#skillProgressTitle-${skillId}`
|
||||
}
|
||||
|
||||
const buildBreadcrumbLinkSelector = (itemId) => {
|
||||
if (Utils.skillsServiceVersionLaterThan('3.0.0')) {
|
||||
return `[data-cy="breadcrumbLink-${itemId}"]`
|
||||
}
|
||||
return`[data-cy="breadcrumb-${itemId}"]`
|
||||
}
|
||||
|
||||
|
||||
const selectors = {
|
||||
backButton: '[data-cy=back]',
|
||||
myRankButton: buildMyRankBtnSelector(),
|
||||
titleSection: '[data-cy="skillsTitle"]',
|
||||
nextSkillButton: '[data-cy="nextSkill"]',
|
||||
firstSubjectTileBtn: buildFirstSubjectTileBtnSelector(),
|
||||
buildSkillLinkSelector: buildSkillLinkSelector,
|
||||
buildSkillTitleSelector: buildSkillTitleSelector,
|
||||
buildBreadcrumbLinkSelector: buildBreadcrumbLinkSelector
|
||||
}
|
||||
export default selectors
|
||||
@@ -1,4 +1,4 @@
|
||||
-- Copyright 2020 SkillTree
|
||||
-- Copyright 2025 SkillTree
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
@@ -12,7 +12,20 @@
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
-- creating Inception project is expensive so lets not delete it
|
||||
delete from PROJECT_DEFINITION where PROJECT_ID <> 'Inception';
|
||||
delete from USER_ATTRS where USER_ID <> '[email protected]' and USER_ID <> '[email protected]';
|
||||
delete from GLOBAL_BADGE_LEVEL_DEFINITION;
|
||||
delete from SKILL_DEFINITION where PROJECT_ID is null;
|
||||
delete from project_definition where project_id <> 'Inception';
|
||||
delete from quiz_definition;
|
||||
delete from user_attrs where user_id <> '[email protected]' and user_id <> '[email protected]';
|
||||
delete from user_roles where user_id = '[email protected]' and (role_name = 'ROLE_SUPER_DUPER_USER' OR role_name = 'ROLE_SUPERVISOR' OR role_name = 'ROLE_PROJECT_ADMIN' OR role_name = 'ROLE_PRIVATE_PROJECT_USER' OR role_name = 'ROLE_DASHBOARD_ADMIN_ACCESS');
|
||||
delete from user_roles where user_id = '[email protected]' and role_name = 'ROLE_SUPERVISOR';
|
||||
delete from global_badge_level_definition;
|
||||
delete from skill_definition where project_id is null;
|
||||
delete from user_achievement;
|
||||
delete from settings where setting_group <> 'project.inception';
|
||||
delete from user_points where project_id = 'Inception';
|
||||
delete from user_achievement where project_id = 'Inception';
|
||||
delete from user_performed_skill where project_id = 'Inception';
|
||||
delete from user_events where project_id = 'Inception';
|
||||
delete from user_tags;
|
||||
delete from notifications;
|
||||
delete from user_actions_history;
|
||||
delete from custom_icons;
|
||||
@@ -0,0 +1,36 @@
|
||||
###########################################################################
|
||||
####### FOR DEMONSTRATION PURPOSES ONLY #######
|
||||
###########################################################################
|
||||
# #
|
||||
# If you have not yet read the tutorial, do so now: #
|
||||
# https://www.ory.sh/docs/hydra/5min-tutorial #
|
||||
# #
|
||||
# This set up is only for demonstration purposes. The login #
|
||||
# endpoint can only be used if you follow the steps in the tutorial. #
|
||||
# #
|
||||
###########################################################################
|
||||
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
|
||||
hydra-migrate:
|
||||
image: oryd/hydra:v1.8.5
|
||||
environment:
|
||||
- DSN=mysql://root:secret@tcp(mysqld:3306)/mysql?max_conns=20&max_idle_conns=4
|
||||
command:
|
||||
migrate sql -e --yes
|
||||
restart: on-failure
|
||||
|
||||
hydra:
|
||||
depends_on:
|
||||
- hydra-migrate
|
||||
environment:
|
||||
- DSN=mysql://root:secret@tcp(mysqld:3306)/mysql?max_conns=20&max_idle_conns=4
|
||||
|
||||
mysqld:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=secret
|
||||
@@ -0,0 +1,44 @@
|
||||
###########################################################################
|
||||
####### FOR DEMONSTRATION PURPOSES ONLY #######
|
||||
###########################################################################
|
||||
# #
|
||||
# If you have not yet read the tutorial, do so now: #
|
||||
# https://www.ory.sh/docs/hydra/5min-tutorial #
|
||||
# #
|
||||
# This set up is only for demonstration purposes. The login #
|
||||
# endpoint can only be used if you follow the steps in the tutorial. #
|
||||
# #
|
||||
###########################################################################
|
||||
|
||||
version: '2.2'
|
||||
|
||||
services:
|
||||
|
||||
hydra-migrate:
|
||||
image: oryd/hydra:v1.8.5
|
||||
mem_limit: 512m
|
||||
container_name: hydra_migrate
|
||||
environment:
|
||||
- DSN=postgres://hydra:secret@postgresd:5433/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
|
||||
command:
|
||||
migrate sql -e --yes
|
||||
restart: on-failure
|
||||
|
||||
hydra:
|
||||
depends_on:
|
||||
- hydra-migrate
|
||||
environment:
|
||||
- DSN=postgres://hydra:secret@postgresd:5433/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
|
||||
|
||||
postgresd:
|
||||
image: postgres:9.6
|
||||
mem_limit: 512m
|
||||
container_name: hydra_postgres
|
||||
ports:
|
||||
- "5433:5433"
|
||||
environment:
|
||||
- POSTGRES_USER=hydra
|
||||
- POSTGRES_PASSWORD=secret
|
||||
- POSTGRES_DB=hydra
|
||||
- POSTGRES_PORT=5433
|
||||
- PGPORT=5433
|
||||