Compare commits

...
216 Commits
Author SHA1 Message Date
Don Walizer 9ccaa12ac9 Add ability to specify ID for skill reporting event 2023-12-15 13:35:08 -05:00
Dima May 594d61503d Merge pull request #233 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-js/axios-1.6.0
Bump axios from 0.27.2 to 1.6.0 in /skills-client-js
2023-12-14 08:09:56 -05:00
Don Walizer e11f7ec67f Modify version 2023-12-13 12:41:41 -05:00
Don Walizer f2f6104e7c Update axios, axios-mock-adapter, add ignore pattern 2023-12-13 10:10:36 -05:00
Don Walizer 53bd0136a5 Merge pull request #230 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-integration/skills-int-client-js/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-integration/skills-int-client-js
2023-12-08 15:21:40 -05:00
Don Walizer 6fbc73c259 Merge pull request #232 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-integration/skills-int-client-react18/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-integration/skills-int-client-react18
2023-12-08 15:16:51 -05:00
Don Walizer 67c5d77730 Merge pull request #231 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-integration/skills-int-client-react17/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-integration/skills-int-client-react17
2023-12-08 15:16:21 -05:00
Don Walizer a1d17002fc Merge pull request #229 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-integration/skills-int-client-vue/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-integration/skills-int-client-vue
2023-12-08 15:16:15 -05:00
Don Walizer f236d29053 Merge pull request #228 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-vue/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-vue
2023-12-08 15:15:45 -05:00
Don Walizer 752aff86e6 Merge pull request #227 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-integration/skills-int-client-react/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-integration/skills-int-client-react
2023-12-08 15:15:31 -05:00
Don Walizer 109f1a900f Merge pull request #226 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-react/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-react
2023-12-08 15:15:24 -05:00
Don Walizer 7c6a7293f7 Merge pull request #225 from NationalSecurityAgency/dependabot/npm_and_yarn/skills-client-integration/skills-int-client-ng/axios-1.6.0
Bump axios from 0.23.0 to 1.6.0 in /skills-client-integration/skills-int-client-ng
2023-12-08 15:15:04 -05:00
Dima May 8a9c9ffe56 Merge pull request #234 from NationalSecurityAgency/update-spring
Update spring
2023-12-08 14:56:59 -05:00
Don Walizer 2678017cde Update reference to PropertiesLauncher 2023-11-30 10:49:27 -05:00
Don Walizer a8b1ce9593 Upgrade to Spring Boot 3.2.0, adjust licenses 2023-11-30 10:36:58 -05:00
dependabot[bot] 39f8779394 Bump axios from 0.27.2 to 1.6.0 in /skills-client-js
Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.27.2...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-11 05:50:05 +00:00
dependabot[bot] 67a9d5fe90 Bump axios in /skills-client-integration/skills-int-client-react18
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:38:30 +00:00
dependabot[bot] b4efd29492 Bump axios in /skills-client-integration/skills-int-client-react17
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:32:15 +00:00
dependabot[bot] abcb97d564 Bump axios in /skills-client-integration/skills-int-client-js
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:29:00 +00:00
dependabot[bot] fc3af550de Bump axios in /skills-client-integration/skills-int-client-vue
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:29:00 +00:00
dependabot[bot] bcb42fc81d Bump axios from 0.23.0 to 1.6.0 in /skills-client-vue
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:28:51 +00:00
dependabot[bot] 4b05314e3b Bump axios in /skills-client-integration/skills-int-client-react
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:28:51 +00:00
dependabot[bot] 712dcbcde8 Bump axios from 0.23.0 to 1.6.0 in /skills-client-react
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:28:50 +00:00
dependabot[bot] e0f5c18b61 Bump axios in /skills-client-integration/skills-int-client-ng
Bumps [axios](https://github.com/axios/axios) from 0.23.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.23.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-11-10 21:28:50 +00:00
Dima May b4cd851b0d Merge pull request #224 from NationalSecurityAgency/t#223/deprecate-libraries
T#223/deprecate libraries
2023-10-27 12:59:00 -04:00
Don Walizer e2738f48e0 #223 Remove deprecated tests 2023-10-18 13:55:41 -04:00
Don Walizer 3e569f461d #223 Remove non-native libraries from build 2023-10-18 13:23:16 -04:00
Ryan Mayo d5975ce4ce Merge pull request #222 from NationalSecurityAgency/t#220/remove_cupress_cloud
T#220/remove cupress cloud
2023-09-19 16:42:52 -04:00
EVOFORGE\dimay 4622afab09 #220: fixing nightly CIs 2023-09-19 15:55:55 -04:00
EVOFORGE\dimay 9888f5168d #220: fixing nightly CIs 2023-09-19 15:45:38 -04:00
Don Walizer c866aabab8 Merge pull request #221 from NationalSecurityAgency/t#220/remove_cupress_cloud
T#220/remove cupress cloud
2023-09-18 13:48:04 -04:00
EVOFORGE\dimay e45c87ca43 #220: fixing download 2023-09-18 13:16:21 -04:00
EVOFORGE\dimay 68111db2f5 #220: fixing download skills-service script 2023-09-18 12:32:27 -04:00
EVOFORGE\dimay 78a17e4171 #220: adding npm link step back 2023-09-18 11:31:22 -04:00
EVOFORGE\dimay 54ed00f701 #220: download latest skills-service release instead of building the jar; removed npm link step 2023-09-18 11:17:52 -04:00
EVOFORGE\dimay abb9b195ef #220: fixed header checks 2023-09-18 11:03:03 -04:00
EVOFORGE\dimay bc0694c9a2 #220: removing usage of spring cloud 2023-09-18 10:27:52 -04:00
EVOFORGE\dimay 31e1bafeb9 increased maven heap space for CI runs that build skills-service 2023-08-11 06:26:25 -04:00
rmmayo 7f922d1b58 fixed typo 2023-08-02 13:23:31 -04:00
rmmayo 4521549eb2 allows the secrets to be passed in via file instead of using command line or env variables 2023-07-27 13:23:03 -04:00
rmmayo 63aa1c1631 allows the secrets to be passed in via file instead of using command line or env variables 2023-07-27 13:16:23 -04:00
rmmayo 64fb8abf5a upgrade to latest springboot (v3.1.1) 2023-07-05 11:14:31 -04:00
Dima May 1790088cd0 Merge pull request #215 from NationalSecurityAgency/t#214/upgrade-angular
T#214/upgrade angular
2023-06-27 14:11:52 -04:00
Don Walizer b39fc1c4d3 #214 Adjust package.json versioning 2023-06-21 13:40:25 -04:00
Don Walizer 28b0a845f8 #214 Remove script, remove commented out code 2023-06-21 13:13:58 -04:00
Don Walizer 77300ee065 #214 Remove script from workflow script 2023-06-21 11:38:31 -04:00
Don Walizer 2f703c3ad4 #214 Modify install process 2023-06-21 11:21:56 -04:00
Don Walizer 768bab4a48 #214 Make some script changes 2023-06-14 14:40:48 -04:00
Don Walizer 740b7213c9 #214 Test with a separate script for angular projects 2023-06-09 10:00:53 -04:00
Don Walizer cb3720fdb1 #214 Increase version to 3.6.0 2023-06-08 11:48:44 -04:00
Don Walizer 773ace12b5 #214 Upgrade to Angular 14 2023-06-08 09:53:40 -04:00
Dima May 58a553afb2 Merge pull request #211 from NationalSecurityAgency/t#210/ci_failures
T#210/ci failures
2023-05-09 14:27:34 -04:00
rmmayo 2bf35c08af #210 - upgrading typescript version for skills-client-ng 2023-05-09 09:26:54 -04:00
rmmayo 3739560564 #210 - increase mvn heap size 2023-05-09 08:53:52 -04:00
rmmayo 26ba60cd64 use SSLContexts.createSystemDefault() for SSLContext 2023-03-17 16:17:44 -04:00
Dima May 9922f4557c Merge pull request #208 from NationalSecurityAgency/t#205/ci_failures
T#205/ci failures
2023-03-14 21:54:12 -04:00
rmmayo 0fb897a6b4 #205 - 3.5.0 needs to use JDK 11 also. All future version will use the default configured JDK (19 as of now), unless otherwise specified in the skills.versionProps.altJavaHomeEnv prop for that version(s) 2023-03-14 18:08:19 -04:00
rmmayo ba3212014a #205 - add 0BSD license for react 17 and react18 2023-03-14 17:06:52 -04:00
rmmayo ac5971b56f #205 - add 0BSD license for react 17 and react18 2023-03-14 14:12:32 -04:00
rmmayo 46a567e464 #205 - add 0BSD license for react 17 and react18 2023-03-14 14:12:19 -04:00
rmmayo 2f394bb429 #205 - updated patch files to use postgres for older versions 2023-03-14 12:36:03 -04:00
rmmayo 0600e60ee8 #205 - updated patch files to use postgres for older versions 2023-03-14 10:30:56 -04:00
rmmayo b6f87077d8 #205 - fixed duplicate entres in pom.xml files. Need to pass the existing ENV in addition to the new ENV var 2023-03-13 18:44:28 -04:00
rmmayo 26c547e1d9 #205 - rolling back "temporarily revert jdk setup" changes 2023-03-13 12:35:15 -04:00
rmmayo 37f04a01dd #205 - temporarily revert jdk setup 2023-03-13 12:18:18 -04:00
rmmayo 3a449716cd #205 - temporarily revert jdk setup 2023-03-13 12:10:45 -04:00
rmmayo e6d4870b8e #205 - temporarily revert jdk setup 2023-03-13 12:07:27 -04:00
rmmayo cfe7bde356 #205 - temporarily revert jdk setup 2023-03-13 11:55:01 -04:00
rmmayo 3ef80b042a #205 - temporarily revert jdk setup 2023-03-13 11:38:55 -04:00
rmmayo 4ee343a34e #205 - temporarily revert jdk setup 2023-03-13 11:24:49 -04:00
rmmayo c98a11b0dd #205 - add npm logs to result artifacts 2023-03-13 07:44:37 -04:00
rmmayo 6b3e3f2ac8 #205 - pass JAVA_HOME to the process 2023-03-13 07:14:14 -04:00
rmmayo 76d661f0bc #205 - pass JAVA_HOME to the process 2023-03-13 06:59:02 -04:00
rmmayo 303c6745e1 #205 - pass JAVA_HOME to the process 2023-03-12 21:59:54 -04:00
rmmayo 68e4ef032b #205 - pass JAVA_HOME to the process 2023-03-12 21:38:03 -04:00
rmmayo 9c3f9c7560 #205 - pass JAVA_HOME to the process 2023-03-12 21:10:31 -04:00
rmmayo b086acfc24 #205 - pass JAVA_HOME to the process 2023-03-12 20:19:53 -04:00
rmmayo 2485580b6c #205 - export JAVA_HOME 2023-03-12 19:58:52 -04:00
rmmayo d5770a9265 #205 - fix property name 2023-03-12 19:28:41 -04:00
rmmayo 413b9cd866 #205 - accidentally removed node setup 2023-03-12 18:52:42 -04:00
rmmayo a7dd33bbed #205 - added back commented out code 2023-03-11 18:44:51 -05:00
rmmayo e92abd6e95 #205 - don't skip client-display 2023-03-11 18:43:55 -05:00
rmmayo 6ea48bf8b6 #205 - remove private, fix main class 2023-03-11 18:41:42 -05:00
rmmayo e197764af3 #205 - conver to string 2023-03-10 18:01:52 -05:00
rmmayo cad546df90 #205 - skipping client-display temporarily 2023-03-10 17:53:22 -05:00
rmmayo ca13cfebb9 #205 - trying to work around error: enoent ENOENT: no such file or directory, lstat '/home/runner/work/skills-client/skills-client/skills-service/client-display/target/lib' 2023-03-10 17:44:41 -05:00
rmmayo 5c903c4eed #205 - try zulu jdk 2023-03-10 16:50:16 -05:00
rmmayo 72ac5eb86d #205 - skip building skills-service temporarily 2023-03-10 16:48:15 -05:00
rmmayo 258b0625d4 #205 - attempt using alternative JAVA_HOME per version if configured 2023-03-10 15:21:25 -05:00
rmmayo 3bad415dd6 - updating user-info-service to use latest version w/ springboot 3 2023-03-10 09:58:58 -05:00
rmmayo ae2ac64cf5 - testing out multi jdk setup 2023-03-10 09:28:57 -05:00
rmmayo a82d3033bf - testing out multi jdk setup 2023-03-10 09:26:16 -05:00
Ryan Mayo b6e0c33f8e Merge pull request #207 from NationalSecurityAgency/t#205/ci_failures
#205 - increase wait time to account for JwtTimestampValidator.DEFAUL…
2023-03-09 15:37:29 -05:00
rmmayo 59e17efac6 #205 - increase wait time to account for JwtTimestampValidator.DEFAULT_MAX_CLOCK_SKEW (60 seconds) 2023-03-09 12:34:08 -05:00
Dima May 8fcc80ad7b Merge pull request #206 from NationalSecurityAgency/t#205/ci_failures
T#205/ci failures
2023-03-08 09:47:08 -05:00
rmmayo ededef0757 #205 - change database props to use postgres 2023-03-06 10:46:03 -05:00
rmmayo 6cc340184f #205 - need to run postgres 2023-03-06 09:46:58 -05:00
rmmayo ee19257234 #205 - need to run postgres 2023-03-06 09:28:09 -05:00
rmmayo 03295fff6b #205 - remove -v option from wait-port call 2023-03-04 17:56:39 -05:00
rmmayo 793a6f2a97 #205 - change database props to use postgres 2023-03-04 14:32:57 -05:00
rmmayo c2d81a82a2 #205 - upgrade to groovy 4.0.7 2023-03-03 14:59:11 -05:00
rmmayo 603e86d87b #2002 - upgrade to latest springboot 3 and jdk 19 2023-03-03 14:33:59 -05:00
rmmayo 8211a8d8e6 #2002 - upgrade to latest springboot 3 and jdk 19 2023-03-03 14:33:46 -05:00
rmmayo 0ea6ccd6f2 #205 - upgrade to jdk 19 2023-03-03 13:37:43 -05:00
rmmayo 43e6f12b6a #1954 - use different port for hydra postgres 2023-02-20 16:06:20 -05:00
rmmayo 2c741eac92 #1954 - use different port for hydra postgres 2023-02-20 16:02:00 -05:00
rmmayo dc6ef05bb2 #1954 - use different port for hydra postgres 2023-02-20 15:56:59 -05:00
rmmayo f8775c3c6b #1954 - use different port for hydra postgres 2023-02-20 15:53:34 -05:00
rmmayo aebb2311c9 #1954 - use different port for hydra postgres 2023-02-20 15:49:59 -05:00
rmmayo 01e4fe78eb #1954 - use different port for hydra postgres 2023-02-20 15:45:16 -05:00
Dima May 9a73384d61 Merge pull request #202 from evenstensberg/master
fix(imports): correct import ordering and remove unused code
2023-01-17 08:53:46 -05:00
Even Stensberg fbf391628f fix(imports): correct import ordering and remove dead code 2023-01-14 15:14:50 +01:00
Dima May 78fbfaa07c Merge pull request #199 from NationalSecurityAgency/t#198/failing_ci
T#198/failing ci
2022-12-19 13:07:57 -05:00
rmmayo 79263e3dd1 #198 - added 0BSD to onlyAllow list 2022-12-19 09:06:14 -05:00
rmmayo 117540d768 #198 - added 0BSD to onlyAllow list 2022-12-19 08:36:53 -05:00
Ryan Mayo eed5f8166b Merge pull request #197 from NationalSecurityAgency/dependabot/maven/skills-client-integration/skills-int-e2e-test/org.apache.commons-commons-text-1.10.0
Bump commons-text from 1.9 to 1.10.0 in /skills-client-integration/skills-int-e2e-test
2022-11-09 11:54:43 -05:00
Ryan Mayo 96d6575959 Merge pull request #193 from NationalSecurityAgency/dependabot/maven/skills-client-integration/skills-int-e2e-test/org.codehaus.groovy-groovy-2.5.14
Bump groovy from 2.5.13 to 2.5.14 in /skills-client-integration/skills-int-e2e-test
2022-11-09 11:54:31 -05:00
dependabot[bot] 4555d67463 Bump commons-text in /skills-client-integration/skills-int-e2e-test
Bumps commons-text from 1.9 to 1.10.0.

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-text
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-11-09 16:48:12 +00:00
Ryan Mayo de96156a18 Merge pull request #196 from NationalSecurityAgency/t#195/upgrade_springboot
#195 - upgrade spring boot
2022-11-09 11:45:52 -05:00
rmmayo cc188e092f #195 - upgrade spring boot 2022-11-09 09:20:17 -05:00
Ryan Mayo afedea47c2 Merge pull request #194 from NationalSecurityAgency/t#191/upgrade_spring_boot
#191 - upgrade spring boot
2022-10-12 15:34:35 -04:00
rmmayo 5c2206bbe6 #191 - upgrade spring boot 2022-10-12 15:20:28 -04:00
dependabot[bot] 70a17c87f0 Bump groovy in /skills-client-integration/skills-int-e2e-test
Bumps [groovy](https://github.com/apache/groovy) from 2.5.13 to 2.5.14.
- [Release notes](https://github.com/apache/groovy/releases)
- [Commits](https://github.com/apache/groovy/commits)

---
updated-dependencies:
- dependency-name: org.codehaus.groovy:groovy
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-10-11 16:21:41 +00:00
Dima May 6dd0f5870d Merge pull request #192 from NationalSecurityAgency/t#191/upgrade_spring_boot
#191 - upgrade spring boot
2022-10-11 12:21:21 -04:00
rmmayo 1058baff54 #191 - upgrade spring boot 2022-10-10 13:54:04 -04:00
rmmayo d568f2ac6b #191 - upgrade spring boot 2022-10-10 13:40:39 -04:00
rmmayo b38de3a31d creating_release_version_3.5.0 2022-09-27 07:03:15 -04:00
EVOFORGE\dimay 17c3038bcc #188: props updates 2022-09-26 19:48:59 -04:00
rmmayo 13264dc2b8 #188 - set scrollTopOffset to 134 2022-09-26 16:57:39 -04:00
rmmayo 8c3a762ab9 #188 - set scrollTopOffset to 156 2022-09-26 16:53:45 -04:00
Ryan Mayo b4f841ff0d Merge pull request #190 from NationalSecurityAgency/t#188/do-scroll-event
T#188/do scroll event
2022-09-26 14:16:18 -04:00
EVOFORGE\dimay 7d6a0d55a1 #188: fixed an issue where top of the iframe is not in the viewable area 2022-09-26 14:14:21 -04:00
Dima May a577262c80 Merge pull request #189 from NationalSecurityAgency/t#187/uprgade_libs
#187 - Upgraded axios and sockjs-client dependencies
2022-09-26 13:29:49 -04:00
EVOFORGE\dimay b6cd4a22f2 #188: fixed an issue where top of the iframe is not in the viewable area 2022-09-26 13:16:40 -04:00
EVOFORGE\dimay b8ea4df736 #188: inroduced do-scroll event to respond to a scroll event from the iframe's child code 2022-09-26 12:32:46 -04:00
rmmayo 7b2fb60c98 #187 - Upgraded axios and sockjs-client dependencies 2022-09-26 11:56:59 -04:00
Dima May a86011369b Merge pull request #186 from NationalSecurityAgency/t#183/dependabot_alerts
T#183/dependabot alerts
2022-09-23 13:04:59 -04:00
rmmayo b1f21f3f0d #183 - removing internationalization/localization 2022-09-23 09:13:32 -04:00
rmmayo 3c067b63e9 #183 - removing internationalization/localization 2022-09-23 08:14:26 -04:00
rmmayo d634045115 #183 - address Dependabot alerts 2022-09-22 17:52:21 -04:00
rmmayo c7cf667693 #183 - address Dependabot alerts 2022-09-22 17:44:11 -04:00
Ryan Mayo 59d265e29f Merge pull request #185 from NationalSecurityAgency/t#184/pass_options_to_child
T#184/pass options to child
2022-09-22 16:46:48 -04:00
EVOFORGE\dimay 9e250296ba #183: removed localize as it was failing licence dependency check 2022-09-22 15:00:49 -04:00
rmmayo 1807838179 #183 - address Dependabot alerts 2022-09-22 13:38:10 -04:00
rmmayo 18aea74e4d #183 - address Dependabot alerts 2022-09-22 12:37:33 -04:00
rmmayo e5008d4b7b #183 - address Dependabot alerts 2022-09-22 12:25:29 -04:00
rmmayo 925f20e8b8 #183 - address Dependabot alerts 2022-09-22 12:15:38 -04:00
EVOFORGE\dimay d523848ae8 #184: fixed tests 2022-09-22 11:21:32 -04:00
EVOFORGE\dimay 417b3370d2 #184: passed down options to the child iframe and removed options' validation 2022-09-22 09:33:43 -04:00
rmmayo 80ffb33439 #183 - address Dependabot alerts 2022-09-21 15:08:27 -04:00
Dima May 5bb2e96c52 Merge pull request #180 from NationalSecurityAgency/t#179/remove_history_lib
#179 - remove history library dependency
2022-09-20 19:54:20 -04:00
Dima May ba8ae49ed8 Merge pull request #182 from NationalSecurityAgency/t#181/failing_client_backwards_compat_ci
T#181/failing client backwards compat ci
2022-09-20 19:51:53 -04:00
rmmayo 6b882d8fb0 #181 - limit the number of skills-service version tested during client-libs backwards compatibility CI testing. 2022-09-20 12:19:19 -04:00
rmmayo 35bbbcd42c #181 - limit the number of skills-service version tested during client-libs backwards compatibility CI testing. 2022-09-20 11:44:11 -04:00
rmmayo 175e309412 #181 - limit the number of skills-service version tested during client-libs backwards compatibility CI testing. 2022-09-20 10:45:17 -04:00
rmmayo eba7c6e156 #175 - setting initial version for skills-int-client-react18 to 3.4.2 2022-09-20 08:05:26 -04:00
rmmayo 14565ca0c4 #179 - remove history library dependency 2022-09-19 15:43:30 -04:00
Dima May 82f916abae Merge pull request #178 from NationalSecurityAgency/t#177/destroy_race_condition
#177 - handle race condition where the client calls the `SkillsDispla…
2022-09-15 15:14:02 -04:00
rmmayo ee27a3613f #177 - handle race condition where the client calls the SkillsDisplayJS.destroy() method before the PostMate.handshake() is invoked 2022-09-15 13:55:06 -04:00
Dima May 7246fb9385 Merge pull request #176 from NationalSecurityAgency/t#175/react18-int-app
T#175/react18 int app
2022-09-13 14:55:05 -04:00
rmmayo f34c597fa1 #175 - adding links for react 17 and 18 integration test apps 2022-09-13 07:01:39 -04:00
rmmayo 766c34a0c0 #175 - change them method used to listen for the websocket connection message 2022-09-12 18:58:07 -04:00
rmmayo 13431c6092 #175 - adding skills-int-client-react18 - WIP 2022-08-29 15:46:26 -04:00
rmmayo 5e0a5c5b93 #175 - adding skills-int-client-react18 - WIP 2022-08-29 14:03:24 -04:00
rmmayo eab8a4b428 #175 - reload after initial visit 2022-08-29 12:28:04 -04:00
rmmayo e91adb64a7 #175 - aupdated history dependency to 5.3.0, added test on build back 2022-08-29 11:37:46 -04:00
rmmayo a425a85c35 #175 - adding skills-int-client-react18 - WIP 2022-08-29 10:53:40 -04:00
rmmayo db9c0a5b79 #175 - trying different rendering methods 2022-08-23 11:31:00 -04:00
rmmayo 3c6867d3d5 #175 - remove reload after visiting page to troubleshoot initial page loading issue 2022-08-23 08:38:53 -04:00
rmmayo e66066ec84 #175 - reload after visiting page to troubleshoot initial page loading issue 2022-08-23 07:02:21 -04:00
rmmayo 8419a5326f #175 - reload after visiting page to troubleshoot initial page loading issue 2022-08-22 16:28:08 -04:00
rmmayo 5e21f0e9b4 #175 - remove test from build script temporarily 2022-08-22 15:09:09 -04:00
rmmayo 9b81e6f9a2 #175 - removed .only 2022-08-22 14:25:38 -04:00
rmmayo b895d17065 #175 - adding skills-int-client-react18 - WIP 2022-08-22 14:05:27 -04:00
Dima May 5345e59e30 Merge pull request #174 from NationalSecurityAgency/t#173/failing_ci
T#173/failing ci
2022-08-12 11:41:11 -04:00
rmmayo c36d9f7aae #173 - fix failing dashboard backwards compatibility tests after renaming title of the RankDetails page in the skills-display component (skills-service#1194) 2022-08-11 12:23:05 -04:00
rmmayo 5a4c0c9019 #173 - fix failing dashboard backwards compatibility tests after renaming title of the RankDetails page in the skills-display component (skills-service#1194) 2022-08-11 10:21:19 -04:00
rmmayo 75011312f4 #173 - fix failing dashboard backwards compatibility tests after renaming title of the RankDetails page in the skills-display component (skills-service#1194) 2022-08-11 09:01:18 -04:00
rmmayo 606f9aad1a #173 - fix failing client backwards compatibility tests after renaming title of the RankDetails page in the skills-display component (skills-service#1194) 2022-08-10 16:30:54 -04:00
Dima May 7e6102dca3 Merge pull request #170 from NationalSecurityAgency/t#169/ci_failure
T#169/ci failure
2022-01-10 09:20:15 -05:00
Dima May 47f0f58f5d Merge pull request #168 from NationalSecurityAgency/t#167/CVE-2021-45105
#167 upgrade log4j to 2.17.0 in response to CVE-2021-45105
2022-01-10 09:15:37 -05:00
rmmayo 3dac672ba3 #169 - explicitly specify highlight.js dependency and version to prevent version changing on transitive dependency of ngx-highlightjs 2022-01-08 12:52:34 -05:00
rmmayo 8ef383ac9f #169 - explicitly specify highlight.js dependency and version to prevent version changing on transitive dependency of ngx-highlightjs 2022-01-08 11:56:58 -05:00
rmmayo 744c022711 #169 - show node version 2022-01-08 10:36:05 -05:00
mosefer 3f53069e3b #167 upgrade log4j to 2.17.0 in response to CVE-2021-45105 2021-12-19 14:49:40 -05:00
Chris Moses 9d00b0196b Merge pull request #166 from NationalSecurityAgency/t#165/log4j_upgrade
#165: log4j upgrade
2021-12-14 10:57:44 -05:00
EVOFORGE\dimay 352e7d5c76 #165: log4j upgrade 2021-12-14 10:20:00 -05:00
rmmayo 6ea600aaf2 creating_release_version_3.4.1 2021-12-02 09:43:12 -05:00
rmmayo 18e8dc4e98 #133 - adding --force option for link now that we are getting unresolved peer dependencies for react related to changes in #158 I believe 2021-12-02 07:38:14 -05:00
rmmayo bf289d98dd #133 - adding --force option for link now that we are getting unresolved peer dependencies for react related to changes in #158 I believe 2021-12-01 14:46:15 -05:00
Dima May 22046c5d42 Merge pull request #163 from NationalSecurityAgency/t#162/reconnect_ws_invalid_token
T#162/reconnect ws invalid token
2021-11-24 11:16:17 -05:00
rmmayo 9cff37008d #162 - changed workflow to run on daily schedule instead of push/pull_request 2021-11-23 15:46:23 -05:00
rmmayo c631b60c26 #162 - added a badge for the expired token tests 2021-11-23 15:02:08 -05:00
rmmayo aed37a7882 #162 - added cypress tests and CI workflow that validates proper behavior when a skills proxy token has expired 2021-11-23 14:48:46 -05:00
rmmayo c23baf54c5 #162 - start the RetryChecker afterConfigure so that if there are any errors stored in local storage they will be retried after reload w/o having to wait for another skill to be reported. 2021-11-23 11:53:48 -05:00
rmmayo 3dc2c001fc #162 - capture when the websocket connection errors, and if the message indicates a invalid_token, then attempt deactivate the connection and then reconnect 2021-11-23 06:54:12 -05:00
mosefer d0b55b8152 backwards compat tests should not try to inject invalid depoendency into skills-client-int package.json 2021-11-08 09:12:52 -05:00
mosefer ef8300b94d creating_release_version_3.4.0 2021-11-03 18:39:02 -04:00
mosefer 66ef35e83f #160 set initialVersion for skills-int-client-react17 in NpmProjBuilder 2021-11-02 10:16:39 -04:00
Dima May 4992b35f10 Merge pull request #159 from NationalSecurityAgency/t#158/support_react_v17
T#158/support react v17
2021-11-01 15:28:21 -04:00
mosefer 1ff576d583 #158 add force:true to select and submit interactions in integration test 2021-10-27 15:13:46 -04:00
mosefer 816971184a #158 updated lint rules due to updated react-scripts version 2021-10-26 15:07:46 -04:00
mosefer 7dd7a0f4fb #158 change homepage for react17 test, upgrade react-scripts version to craco compatible version 2021-10-26 14:51:08 -04:00
mosefer f10cd880f1 #158 use craco to force int-client apps to load the react version specified in their pom as opposed to the skills-client-react devDependency version pulled in via npm link 2021-10-26 13:27:40 -04:00
mosefer 317103654c #158 lint fix 2021-10-25 12:14:31 -04:00
mosefer b1d0784f81 #158 remove symlinking react module to all projects, fix ts bug in skills-int-client-ng 2021-10-25 11:26:57 -04:00
mosefer 57a78b25b4 #158 make sure to actually add the new int project to git 2021-10-21 14:35:35 -04:00
mosefer 1abf6850d1 #158 support react v17 in the skills-react-client, update axios versions as per dependabot notice, update axios-auth-refresh version, update dependencies in skills-client-js to latest patch versions, add react v17 integration app and tests 2021-10-21 14:25:39 -04:00
Dima May b20c94aa2f Merge pull request #157 from NationalSecurityAgency/t#156/add_BSD-2-Clause
#156 - adding BSD-2-Clause to allowable licenses
2021-09-22 16:32:26 -04:00
rmmayo 8ec08545f7 #156 - adding BSD-2-Clause to allowable licenses 2021-09-21 11:24:50 -04:00
rmmayo 965b264db4 #156 - added BSD-2-Clause to the onlyAllow clause of the licenseDepCheck script 2021-09-21 10:13:21 -04:00
Dima May ac8187d800 Merge pull request #154 from NationalSecurityAgency/t#152/retry_queue_auth_failures
#152 - use the same retryQueue for auth errors as non-auth errors
2021-09-13 11:08:50 -04:00
Dima May fea209f199 Merge pull request #155 from NationalSecurityAgency/t#153/upgrade_ws_libs
T#153/upgrade ws libs
2021-09-13 11:05:56 -04:00
rmmayo 04fad73b74 #153 - force change detection on globalEventResult 2021-09-01 08:32:25 -04:00
rmmayo 4b78e9f4a5 #153
- replaced webstomp-client with @stomp/stompjs client
 - upgraded sockjs to latest version.
2021-08-31 12:45:04 -04:00
rmmayo 65e6b007ca #152 - use the same retryQueue for auth errors as non-auth errors 2021-08-30 13:35:03 -04:00
134 changed files with 5653 additions and 2385 deletions

No files matched your search

@@ -0,0 +1,134 @@
# This is a basic workflow to help you get started with Actions
name: Continuous Integration expired token tests
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@v2
- uses: actions/setup-node@v2-beta
with:
node-version: '14'
- uses: actions/setup-java@v1
with:
java-version: '19' # The JDK version to make available on the path.
- name: Print Versions
run: |
mvn --version
java -version
npm -version
node --version
- name: Cache local Maven repository
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Cache npm
uses: actions/cache@v2
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: 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@v2
# 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/integration/timeout.specs.js
# env: 'timeout=true'
# 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@v2
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
+52 -17
View File
@@ -25,6 +25,24 @@ jobs:
# 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
@@ -36,13 +54,14 @@ jobs:
- uses: actions/setup-java@v1
with:
java-version: '11.X.X' # The JDK version to make available on the path.
java-version: '19' # The JDK version to make available on the path.
- name: Print Versions
run: |
mvn --version
java -version
npm -version
node --version
- name: Cache local Maven repository
uses: actions/cache@v2
@@ -60,8 +79,13 @@ jobs:
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: setup npm links
run: ./.github/workflows/scripts/setupNpmLinks.sh
@@ -106,20 +130,26 @@ jobs:
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 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() }}
@@ -132,3 +162,8 @@ jobs:
./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
+39 -15
View File
@@ -22,6 +22,24 @@ jobs:
# 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
@@ -33,13 +51,14 @@ jobs:
- uses: actions/setup-java@v1
with:
java-version: '11.X.X' # The JDK version to make available on the path.
java-version: '19' # The JDK version to make available on the path.
- name: Print Versions
run: |
mvn --version
java -version
npm -version
node --version
- name: Cache local Maven repository
uses: actions/cache@v2
@@ -57,13 +76,20 @@ jobs:
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: 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
@@ -77,19 +103,12 @@ jobs:
npm run cyServices:start:integration-apps
cd ../../
- name: Run Cypress tests
uses: cypress-io/github-action@v2
with:
working-directory: skills-client-integration/skills-int-e2e-test
record: true
parallel: false
group: 'skills-client tests'
tag: "${{ github.workflow }}"
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 }}
run: |
cd skills-client-integration/skills-int-e2e-test
npm run cy:run
cd ../../
- name: upload result artifacts
if: ${{ always() }}
@@ -102,3 +121,8 @@ jobs:
./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
@@ -21,6 +21,24 @@ jobs:
# 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
@@ -32,13 +50,14 @@ jobs:
- uses: actions/setup-java@v1
with:
java-version: '13.X.X' # The JDK version to make available on the path.
java-version: '19' # The JDK version to make available on the path.
- name: Print Versions
run: |
mvn --version
java -version
npm -version
node --version
- name: Cache local Maven repository
uses: actions/cache@v2
@@ -79,7 +98,7 @@ jobs:
mvn --batch-mode clean package
export NO_COLOR=1
export CYPRESS_RECORD_KEY=${{ secrets.CYPRESS_RECORD_KEY }}
java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.TestClientLibsBackwardsCompat org.springframework.boot.loader.PropertiesLauncher -record -tag "${{ github.workflow }}"
java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.TestClientLibsBackwardsCompat org.springframework.boot.loader.launch.PropertiesLauncher -record -tag "${{ github.workflow }}" --minVersion "1.9.0"
cd ../../
- name: upload result artifacts
+33 -32
View File
@@ -28,38 +28,39 @@ if [[ "$myGitBranch" == *"HEAD detached at pull"* ]]; then
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 "Checkout skill-service code and build it."
git clone https://github.com/NationalSecurityAgency/skills-service.git
cd ./skills-service/
switchToBranch="master"
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 "Building skill-service from [master] 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 ./service/target/*.jar)
mv $jar ./
cd ../
echo "------- DONE: Build skills-service jar -------"
+1 -1
View File
@@ -22,6 +22,6 @@ mvn --batch-mode clean package -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli
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
java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.SetupNpmLinks org.springframework.boot.loader.launch.PropertiesLauncher
cd ../../
echo "------- DONE: Setup npm links -------"
@@ -21,6 +21,24 @@ jobs:
# 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
@@ -30,15 +48,19 @@ jobs:
with:
node-version: '14'
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
java-version: '13.X.X' # The JDK version to make available on the path.
distribution: 'temurin'
java-version: |
11
19
- name: Print Versions
run: |
mvn --version
java -version
npm -version
node --version
- name: Cache local Maven repository
uses: actions/cache@v2
@@ -56,16 +78,22 @@ jobs:
restore-keys: |
${{ runner.os }}-node-
- name: build skill-service
run: ./.github/workflows/scripts/getSkillsService.sh
# - 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: run backwards compat tests
run: |
cd skills-client-integration/skills-int-e2e-test
mvn --batch-mode clean package
export NO_COLOR=1
export CYPRESS_RECORD_KEY=${{ secrets.CYPRESS_RECORD_KEY }}
java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.TestDashboardBackwardCompat org.springframework.boot.loader.PropertiesLauncher -record -tag "${{ github.workflow }}"
java -jar target/skills-int-e2e-test-*.jar
cd ../../
- name: upload result artifacts
@@ -79,3 +107,4 @@ jobs:
./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/*
+2
View File
@@ -12,6 +12,8 @@ These pages provide in-depth guidance on the installation, usage and contributio
[![Run integration tests using OAuth](https://github.com/NationalSecurityAgency/skills-client/workflows/Continuous%20Integration%20with%20OAuth/badge.svg)](https://github.com/NationalSecurityAgency/skills-client/actions?query=workflow%3A%22Continuous+Integration+with+OAuth%22)
[![Run integration tests for expired tokens](https://github.com/NationalSecurityAgency/skills-client/workflows/Continuous%20Integration%20expired%20token%20tests/badge.svg)](https://github.com/NationalSecurityAgency/skills-client/actions?query=workflow%3A%22Continuous+Integration+expired+token+tests%22)
[![Skills-service Backward Compatibility](https://github.com/NationalSecurityAgency/skills-client/workflows/Skills-service%20Backward%20Compatibility/badge.svg)](https://github.com/NationalSecurityAgency/skills-client/actions?query=workflow%3A%22Skills-service+Backward+Compatibility%22)
[![Client Libs Backward Compatibility](https://github.com/NationalSecurityAgency/skills-client/workflows/Client%20Libs%20Backward%20Compatibility/badge.svg)](https://github.com/NationalSecurityAgency/skills-client/actions?query=workflow%3A%22Client+Libs+Backward+Compatibility%22)
@@ -3,7 +3,7 @@
"rollup.config.js", "app/assets/**", "target/**", "pom.xml",
"build/**", "**/robots.txt", "**.svg", "vue.config.js",
"cypress/videos/**", "**/*.jar", "**.xml", "src/license/*.properties",
"nohup.out", "logs/*", "**.patch"
"nohup.out", "logs/*", "**.patch", "**.yml"
],
"license": "../license-add/LICENSE-HEADER.txt",
"licenseFormats": {
+3 -5
View File
@@ -7,13 +7,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>skills</groupId>
<artifactId>skills-client-integration</artifactId>
<packaging>pom</packaging>
<version>3.3.1-SNAPSHOT</version>
<version>3.5.0-SNAPSHOT</version>
<licenses>
<license>
@@ -25,9 +25,6 @@
<modules>
<module>skills-int-client-js</module>
<module>skills-int-client-vue</module>
<module>skills-int-client-react</module>
<module>skills-int-client-ng</module>
<module>skills-int-service</module>
<module>skills-int-e2e-test</module>
</modules>
@@ -36,6 +33,7 @@
<nexusServer>${nexus.url}</nexusServer>
<frontend-maven-plugin.version>1.10.3</frontend-maven-plugin.version>
<node.version>v14.15.0</node.version>
<java.version>19</java.version>
</properties>
</project>
@@ -33,7 +33,11 @@ limitations under the License.
SkillsConfiguration.configure(result.data);
});
SkillsReporter.addSuccessHandler((result) => {
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);
});
@@ -41,16 +45,22 @@ limitations under the License.
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);
});
};
document.querySelector('#exampleDirectiveClickEvent').addEventListener('click', () => { reportSkill('IronMan'); });
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();
SkillsConfiguration.afterConfigure()
.then(() => {
if (window.Cypress) {
@@ -89,13 +99,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)
@@ -105,11 +115,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>
@@ -1,6 +1,6 @@
{
"name": "skills-int-client-js",
"version": "3.3.1",
"version": "3.5.0",
"license": "Apache-2.0",
"description": "SkillTree Client Lib Integration Tests - Native JS",
"main": "index.js",
@@ -16,8 +16,8 @@
},
"author": "SkillTree Team",
"dependencies": {
"@skilltree/skills-client-js": "3.3.1",
"axios": "0.21.1",
"@skilltree/skills-client-js": "3.5.0",
"axios": "1.6.0",
"bootstrap": "4.5.2",
"jquery": "3.5.1",
"js-beautify": "1.13.0"
@@ -28,4 +28,4 @@
"license-checker": "25.0.1",
"live-server": "1.2.1"
}
}
}
@@ -7,7 +7,7 @@
<parent>
<groupId>skills</groupId>
<artifactId>skills-client-integration</artifactId>
<version>3.3.1-SNAPSHOT</version>
<version>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-client-js</artifactId>
@@ -51,7 +51,6 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
@@ -82,12 +81,6 @@
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "skills-int-client-ng:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
@@ -1,55 +1,58 @@
{
"name": "skills-int-client-ng",
"version": "3.3.1",
"version": "3.6.0",
"license": "Apache-2.0",
"description": "SkillTree Client Lib - Angular",
"author": "SkillTree Team",
"scripts": {
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-3-Clause;Apache-2.0;0BSD' --summary",
"licenseDepCheck2": "license-checker --production --onlyAllow='MIT;ISC;Apache-2.0;0BSD' --summary",
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-3-Clause;Apache-2.0;0BSD;CC-BY-4.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 ",
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
"serve": "npm run start",
"build": "npm run licenseCheck && ng build --prod --deploy-url=/angular/",
"build": "npm run licenseCheck && ng build --configuration production --deploy-url=/angular/",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"dependencies": {
"@angular/animations": "10.1.5",
"@angular/common": "10.1.5",
"@angular/compiler": "10.1.5",
"@angular/core": "10.1.5",
"@angular/forms": "10.1.5",
"@angular/localize": "10.1.5",
"@angular/platform-browser": "10.1.5",
"@angular/platform-browser-dynamic": "10.1.5",
"@angular/router": "10.0.14",
"@ng-bootstrap/ng-bootstrap": "7.0.0",
"@skilltree/skills-client-ng": "3.3.1",
"@angular/animations": "14.3.0",
"@angular/common": "14.3.0",
"@angular/compiler": "14.3.0",
"@angular/core": "14.3.0",
"@angular/forms": "14.3.0",
"@angular/platform-browser": "14.3.0",
"@angular/platform-browser-dynamic": "14.3.0",
"@angular/router": "14.3.0",
"@ng-bootstrap/ng-bootstrap": "13.0.0",
"@popperjs/core": "2.11.8",
"@skilltree/skills-client-ng": "3.6.0",
"@types/js-beautify": "1.11.0",
"axios": "0.21.1",
"axios": "1.6.0",
"bootstrap": "4.5.3",
"highlight.js": "11.3.1",
"jquery": "3.5.1",
"js-beautify": "1.13.0",
"ngx-highlightjs": "4.1.2",
"popper.js": "^1.16.1",
"rxjs": "6.6.3",
"tslib": "2.0.3",
"zone.js": "0.11.1"
"zone.js": "0.12.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "0.1001.6",
"@angular/cli": "10.1.6",
"@angular/compiler-cli": "10.1.5",
"@types/jasmine": "3.5.14",
"@angular-devkit/build-angular": "14.2.11",
"@angular/cli": "14.2.11",
"@angular/compiler-cli": "14.3.0",
"@types/jasmine": "3.6.0",
"@types/jasminewd2": "2.0.8",
"@types/node": "14.11.8",
"codelyzer": "6.0.1",
"jasmine-core": "3.6.0",
"jasmine-spec-reporter": "6.0.0",
"karma": "5.2.3",
"karma": "6.4.1",
"karma-chrome-launcher": "3.1.0",
"karma-coverage-istanbul-reporter": "3.0.3",
"karma-jasmine": "4.0.1",
@@ -59,6 +62,6 @@
"protractor": "7.0.0",
"ts-node": "9.0.0",
"tslint": "6.1.3",
"typescript": "4.0.3"
"typescript": "4.6.2"
}
}
}
@@ -7,7 +7,7 @@
<parent>
<groupId>skills</groupId>
<artifactId>skills-client-integration</artifactId>
<version>3.3.1-SNAPSHOT</version>
<version>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-client-ng</artifactId>
@@ -40,7 +40,7 @@ export class AnySkillCodeExampleComponent implements OnInit {
axios.get("/api/skills")
.then((result) => {
this.available = result.data;
this.available = result.data as string[];
});
}
@@ -66,8 +66,8 @@ export class AnySkillCodeExampleComponent implements OnInit {
let sampleCode = `SkillsReporter.reportSkill(this.skill)
.then((res) => {
this.reportResult = res;
});`
});`;
sampleCode = 'SkillsReporter.reportSkill(this.skill)\n .then((res) => {\n this.reportResult = res;\n \});';
return sampleCode
return sampleCode;
}
}
@@ -13,7 +13,17 @@ 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 { Component, OnInit, AfterViewInit, OnDestroy, ComponentFactoryResolver, ViewChildren, ViewContainerRef, QueryList } from '@angular/core';
import {
Component,
OnInit,
AfterViewInit,
OnDestroy,
ComponentFactoryResolver,
ViewChildren,
ViewContainerRef,
QueryList,
ChangeDetectorRef
} from '@angular/core';
import { Example } from './code-example/example'
import { ExampleService } from './code-example/example.service';
import { CodeExampleLayoutComponent } from './code-example/code-example-layout.component'
@@ -32,11 +42,14 @@ export class ReportSkillsComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChildren('examplesTarget', { read: ViewContainerRef }) exampleTargets: QueryList<ViewContainerRef>;
constructor(private exampleService: ExampleService, private componentFactoryResolver: ComponentFactoryResolver) { }
constructor(private exampleService: ExampleService, private componentFactoryResolver: ComponentFactoryResolver, private ref: ChangeDetectorRef) { }
ngOnInit() {
SkillsReporter.addSuccessHandler(result => {
this.globalEventResult = JSON.stringify(result, null, ' ')
// force change detection
this.ref.detectChanges();
});
}
@@ -16,7 +16,7 @@ limitations under the License.
/***************************************************************************************************
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
*/
import '@angular/localize/init';
// import '@angular/localize/init';
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
@@ -0,0 +1,25 @@
/*
* 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.
*/
const path = require('path');
module.exports = {
webpack: {
alias: {
'react': path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom'),
},
},
};
@@ -1,12 +1,12 @@
{
"name": "skills-int-client-react",
"version": "3.3.1",
"version": "3.5.0",
"license": "Apache-2.0",
"description": "SkillTree Client Lib Integration Tests - React",
"homepage": "/react/",
"dependencies": {
"@skilltree/skills-client-react": "3.3.1",
"axios": "0.21.1",
"@skilltree/skills-client-react": "3.5.0",
"axios": "1.6.0",
"bootstrap": "4.5.3",
"core-js": "3.6.5",
"highlightjs": "9.16.2",
@@ -20,7 +20,7 @@
"react-router-dom": "5.2.0"
},
"scripts": {
"serve": "PORT=8083 react-scripts start",
"serve": "PORT=8083 craco start",
"buildDepsAndServe": "cd ../../skills-client-js/ && npm run build && cd ../skills-client-react/ && npm run build && cd ../skills-client-integration/skills-int-client-react/ && npm run serve",
"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'",
@@ -28,9 +28,9 @@
"licenseCheck": "npm run licenseHeaderCheck && npm run licenseDepCheck ",
"clean": "find node_modules/ -maxdepth 1 ! -name \"@skilltree\" ! -name node_modules -exec rm -rf {} \\;",
"reinstall": "npm run clean && npm install",
"build": "npm run licenseCheck && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"build": "npm run licenseCheck && craco build",
"test": "craco test",
"eject": "craco eject"
},
"eslintConfig": {
"extends": "react-app"
@@ -50,6 +50,7 @@
"devDependencies": {
"license-check-and-add": "3.0.4",
"license-checker": "25.0.1",
"react-scripts": "3.4.3"
"react-scripts": "4.0.3",
"@craco/craco": "6.4.0"
}
}
}
@@ -7,7 +7,7 @@
<parent>
<groupId>skills</groupId>
<artifactId>skills-client-integration</artifactId>
<version>3.3.1-SNAPSHOT</version>
<version>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-client-react</artifactId>
@@ -84,7 +84,7 @@ const ShowSkill = () => {
return '';
});
const [options, setOptions] = React.useState({ isSummaryOnly: isSummaryOnly, internalBackButton: internalBackButton, autoScrollStrategy: 'top-offset', scrollTopOffset: 110 });
const [options, setOptions] = React.useState({ isSummaryOnly: isSummaryOnly, internalBackButton: internalBackButton, autoScrollStrategy: 'top-offset', scrollTopOffset: 134 });
const previousIsSummaryOnly = usePrevious(isSummaryOnly);
const previousInternalBackButton = usePrevious(internalBackButton);
@@ -140,11 +140,11 @@ const ShowSkill = () => {
</DropdownButton>
<Button variant={isSummaryOnly ? 'primary' : 'outline-primary'}
onClick={() => { setIsSummaryOnly(!isSummaryOnly);
setOptions({isSummaryOnly:!isSummaryOnly,internalBackButton:internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 110}) }}>Summary Only</Button>
setOptions({isSummaryOnly:!isSummaryOnly,internalBackButton:internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 134}) }}>Summary Only</Button>
<Button variant={internalBackButton ? 'primary' : 'outline-primary'}
onClick={() => { setInternalBackButton(!internalBackButton);
setOptions({isSummaryOnly:isSummaryOnly,internalBackButton:!internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 110}) }}>Internal Back Button</Button>
setOptions({isSummaryOnly:isSummaryOnly,internalBackButton:!internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 134}) }}>Internal Back Button</Button>
<Button variant={internalBackButton ? 'primary' : 'outline-primary'}
onClick={navigate} data-cy="navigateButton">Navigate</Button>
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default {
const exported = {
default: {
name: 'Bright (default)',
theme: {
@@ -47,4 +47,5 @@ export default {
graphLegendBorderColor: '1px solid grey',
},
}
}
};
export default exported;
@@ -0,0 +1 @@
BROWSER=none
@@ -0,0 +1,24 @@
# 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*
/skills-int-client-react.iml
@@ -0,0 +1 @@
package-lock=false
@@ -0,0 +1,83 @@
<!---
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
@@ -0,0 +1,25 @@
/*
* 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.
*/
const path = require('path');
module.exports = {
webpack: {
alias: {
'react': path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom'),
},
},
};
@@ -0,0 +1,56 @@
{
"name": "skills-int-client-react17",
"version": "3.5.0",
"license": "Apache-2.0",
"description": "SkillTree Client Lib Integration Tests - React",
"homepage": "/react17/",
"dependencies": {
"@skilltree/skills-client-react": "3.5.0",
"axios": "1.6.0",
"bootstrap": "5.1.3",
"core-js": "3.6.5",
"highlightjs": "9.16.2",
"js-beautify": "1.14.0",
"prop-types": "15.7.2",
"react": "17.0.2",
"react-bootstrap": "2.0.0",
"react-dom": "17.0.2",
"react-highlight": "0.14.0",
"react-router": "5.2.1",
"react-router-dom": "5.3.0"
},
"scripts": {
"serve": "PORT=8084 craco start",
"buildDepsAndServe": "cd ../../skills-client-js/ && npm run build && cd ../skills-client-react/ && npm run build && cd ../skills-client-integration/skills-int-client-react/ && npm run serve",
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;0BSD;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 ",
"clean": "find node_modules/ -maxdepth 1 ! -name \"@skilltree\" ! -name node_modules -exec rm -rf {} \\;",
"reinstall": "npm run clean && npm install",
"build": "npm run licenseCheck && craco build",
"test": "craco test",
"eject": "craco 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": "4.0.3",
"@craco/craco": "6.4.0"
}
}
@@ -0,0 +1,75 @@
<?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>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-client-react17</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>${frontend-maven-plugin.version}</version>
<configuration>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v12.6.0</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,60 @@
<!--
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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,25 @@
{
"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"
}
@@ -0,0 +1,2 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
@@ -0,0 +1,37 @@
/*
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.
*/
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #09d3ac;
}
@@ -0,0 +1,45 @@
/*
* 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>
);
}
@@ -0,0 +1,28 @@
/*
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;
}
@@ -0,0 +1,41 @@
/*
* 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, Logger } from '@skilltree/skills-client-react';
axios.get("/api/config")
.then((result) => {
SkillsConfiguration.configure(result.data);
})
.then(() => {
SkillsConfiguration.afterConfigure().then(() => {
if (window.Cypress) {
window.skillsLogger = Logger;
}
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();
@@ -0,0 +1 @@
<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

After

Width:  |  Height:  |  Size: 8.0 KiB

@@ -0,0 +1,150 @@
/*
* 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();
});
}
}
@@ -0,0 +1,25 @@
/*
* 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.
*/
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
proxy({
target: 'http://localhost:8090',
changeOrigin: true,
})
);
};
@@ -0,0 +1,54 @@
/*
* 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 '@skilltree/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 v17 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?isSummaryOnly=false&internalBackButton=false&themeName=Bright%20(default)&skillsVersion=">User Display</NavLink>
</Nav>
</Navbar.Collapse>
<Button variant="primary">
<SkillsLevel />
</Button>
</Navbar>
</div>
);
};
export default Navigation;
@@ -0,0 +1,112 @@
/*
* 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 '@skilltree/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;
@@ -0,0 +1,68 @@
/*
* 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 '@skilltree/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);
@@ -0,0 +1,168 @@
/*
* 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 '@skilltree/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);
const handleRouteChanged = (newPath) => {
document.querySelector('#skillsDisplayPath').innerHTML = `Skills Display Path: [${newPath}]`;
};
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 [internalBackButton, setInternalBackButton] = React.useState(() => {
const urlInternalBackButton = getUrlParam('internalBackButton');
if ( urlInternalBackButton ) {
return JSON.parse(urlInternalBackButton)
}
return false;
});
const [skillsVersion] = React.useState(() => {
const skillsVersion = getUrlParam("skillsVersion");
if(skillsVersion) {
return skillsVersion;
}
return '';
});
const [options, setOptions] = React.useState({ isSummaryOnly: isSummaryOnly, internalBackButton: internalBackButton, autoScrollStrategy: 'top-offset', scrollTopOffset: 134 });
const previousIsSummaryOnly = usePrevious(isSummaryOnly);
const previousInternalBackButton = usePrevious(internalBackButton);
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.replace({pathname:history.location.pathname, search: params});
};
if (isSummaryOnly !== previousIsSummaryOnly || internalBackButton !== previousInternalBackButton || selectedTheme !== previousSelectedTheme) {
saveUrlParam({'isSummaryOnly': isSummaryOnly, 'internalBackButton': internalBackButton, 'themeName': selectedTheme.name, 'skillsVersion': skillsVersion});
}
}, [isSummaryOnly, internalBackButton, selectedTheme, skillsVersion, previousIsSummaryOnly, previousInternalBackButton, previousSelectedTheme, previousSkillsVersion, history]);
const sampleCodeRef = React.createRef();
const skillsDisplayRef = React.createRef();
const executeScroll = () => scrollToRef(sampleCodeRef);
const navigate = () => {
skillsDisplayRef.current.navigate('/subjects/subj0');
};
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,internalBackButton:internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 134}) }}>Summary Only</Button>
<Button variant={internalBackButton ? 'primary' : 'outline-primary'}
onClick={() => { setInternalBackButton(!internalBackButton);
setOptions({isSummaryOnly:isSummaryOnly,internalBackButton:!internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 134}) }}>Internal Back Button</Button>
<Button variant={internalBackButton ? 'primary' : 'outline-primary'}
onClick={navigate} data-cy="navigateButton">Navigate</Button>
<Button variant="link" onClick={executeScroll}>Show Source</Button>
</div>
<div>
<span id="skillsDisplayPath" data-cy="skillsDisplayPath"></span>
</div>
<div className="border rounded">
<SkillsDisplay ref={skillsDisplayRef} options={options} theme={selectedTheme.theme} version={skillsVersion} handleRouteChanged={handleRouteChanged}/>
</div>
<div ref={sampleCodeRef}>
<SampleCode options={options} selectedTheme={selectedTheme}/>
</div>
</div>
);
};
export default ShowSkill;
@@ -0,0 +1,51 @@
/*
* 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.
*/
const exportedObj = {
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',
},
}
};
export default exportedObj;
@@ -0,0 +1 @@
BROWSER=none
@@ -0,0 +1,24 @@
# 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*
/skills-int-client-react.iml
@@ -0,0 +1 @@
package-lock=false
@@ -0,0 +1,83 @@
<!---
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
@@ -0,0 +1,25 @@
/*
* 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.
*/
const path = require('path');
module.exports = {
webpack: {
alias: {
'react': path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom'),
},
},
};
@@ -0,0 +1,55 @@
{
"name": "skills-int-client-react18",
"version": "3.5.0",
"license": "Apache-2.0",
"description": "SkillTree Client Lib Integration Tests - React",
"homepage": "/react18/",
"dependencies": {
"@skilltree/skills-client-react": "3.5.0",
"axios": "1.6.0",
"bootstrap": "5.1.3",
"core-js": "3.6.5",
"js-beautify": "1.14.0",
"prop-types": "15.7.2",
"react": "18.2.0",
"react-bootstrap": "2.5.0",
"react-dom": "18.2.0",
"react-highlight": "0.14.0",
"react-router": "6.3.0",
"react-router-dom": "6.3.0"
},
"scripts": {
"serve": "PORT=8085 craco start",
"buildDepsAndServe": "cd ../../skills-client-js/ && npm run build && cd ../skills-client-react/ && npm run build && cd ../skills-client-integration/skills-int-client-react18/ && npm run serve",
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;0BSD;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 ",
"clean": "find node_modules/ -maxdepth 1 ! -name \"@skilltree\" ! -name node_modules -exec rm -rf {} \\;",
"reinstall": "npm run clean && npm install",
"build": "npm run licenseCheck && craco build",
"test": "craco test",
"eject": "craco 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": "4.0.3",
"@craco/craco": "6.4.5"
}
}
@@ -0,0 +1,75 @@
<?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>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-client-react18</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>${frontend-maven-plugin.version}</version>
<configuration>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v12.6.0</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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,60 @@
<!--
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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,25 @@
{
"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"
}
@@ -0,0 +1,2 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
@@ -0,0 +1,37 @@
/*
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.
*/
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #09d3ac;
}
@@ -0,0 +1,39 @@
/*
* 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,
Routes,
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>
<Routes>
<Route path="/showSkills" element={<ShowSkills/>} />
<Route path="/" element={<ReportSkill/>} />
</Routes>
</Router>
);
}
@@ -0,0 +1,28 @@
/*
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;
}
@@ -0,0 +1,41 @@
/*
* 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 { createRoot } from 'react-dom/client';
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, Logger } from '@skilltree/skills-client-react';
SkillsConfiguration.afterConfigure().then(() => {
if (window.Cypress) {
window.skillsLogger = Logger;
}
const container = document.getElementById('root');
const root = createRoot(container); // createRoot(container!) if you use TypeScript
root.render(<App />);
})
axios.get("/api/config")
.then((result) => {
SkillsConfiguration.configure(result.data);
})
// 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();
@@ -0,0 +1 @@
<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

After

Width:  |  Height:  |  Size: 8.0 KiB

@@ -0,0 +1,150 @@
/*
* 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();
});
}
}
@@ -0,0 +1,25 @@
/*
* 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.
*/
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
proxy({
target: 'http://localhost:8090',
changeOrigin: true,
})
);
};
@@ -0,0 +1,54 @@
/*
* 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 '@skilltree/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 v18 Integration Examples</Navbar.Brand>
<Navbar.Toggle target="nav-collapse"></Navbar.Toggle>
<Navbar.Collapse id="nav-collapse" is-nav="true">
<Nav>
<NavLink data-cy="reportSkillsLink" className={({ isActive }) => "nav-link" + (isActive ? " activated" : "")} to="/">Report Skill Events</NavLink>
<NavLink data-cy="skillsDisplayLink" className={({ isActive }) => "nav-link" + (isActive ? " activated" : "")} to="/showSkills?isSummaryOnly=false&internalBackButton=false&themeName=Bright%20(default)&skillsVersion=">User Display</NavLink>
</Nav>
</Navbar.Collapse>
<Button variant="primary">
<SkillsLevel />
</Button>
</Navbar>
</div>
);
};
export default Navigation;
@@ -0,0 +1,112 @@
/*
* 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 '@skilltree/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;
@@ -0,0 +1,68 @@
/*
* 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 '@skilltree/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);
@@ -0,0 +1,168 @@
/*
* 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 '@skilltree/skills-client-react';
import DropdownButton from "react-bootstrap/DropdownButton";
import Dropdown from 'react-bootstrap/Dropdown';
import Button from 'react-bootstrap/Button';
import { useLocation, useNavigate } 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);
const handleRouteChanged = (newPath) => {
document.querySelector('#skillsDisplayPath').innerHTML = `Skills Display Path: [${newPath}]`;
};
function usePrevious(value){
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
});
return ref.current;
}
const ShowSkill = () => {
const location = useLocation();
const navigator = useNavigate();
const getUrlParam = (name) => {
const urlSearchParams = new URLSearchParams(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 [internalBackButton, setInternalBackButton] = React.useState(() => {
const urlInternalBackButton = getUrlParam('internalBackButton');
if ( urlInternalBackButton ) {
return JSON.parse(urlInternalBackButton)
}
return false;
});
const [skillsVersion] = React.useState(() => {
const skillsVersion = getUrlParam("skillsVersion");
if(skillsVersion) {
return skillsVersion;
}
return '';
});
const [options, setOptions] = React.useState({ isSummaryOnly: isSummaryOnly, internalBackButton: internalBackButton, autoScrollStrategy: 'top-offset', scrollTopOffset: 134 });
const previousIsSummaryOnly = usePrevious(isSummaryOnly);
const previousInternalBackButton = usePrevious(internalBackButton);
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(/&$/,'');
navigator({pathname:location.pathname, search: params}, {replace: true});
};
if (isSummaryOnly !== previousIsSummaryOnly || internalBackButton !== previousInternalBackButton || selectedTheme !== previousSelectedTheme) {
saveUrlParam({'isSummaryOnly': isSummaryOnly, 'internalBackButton': internalBackButton, 'themeName': selectedTheme.name, 'skillsVersion': skillsVersion});
}
}, [isSummaryOnly, internalBackButton, selectedTheme, skillsVersion, previousIsSummaryOnly, previousInternalBackButton, previousSelectedTheme, previousSkillsVersion, location, navigator]);
const sampleCodeRef = React.createRef();
const skillsDisplayRef = React.createRef();
const executeScroll = () => scrollToRef(sampleCodeRef);
const navigate = () => {
skillsDisplayRef.current.navigate('/subjects/subj0');
};
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,internalBackButton:internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 134}) }}>Summary Only</Button>
<Button variant={internalBackButton ? 'primary' : 'outline-primary'}
onClick={() => { setInternalBackButton(!internalBackButton);
setOptions({isSummaryOnly:isSummaryOnly,internalBackButton:!internalBackButton,autoScrollStrategy: 'top-offset', scrollTopOffset: 134}) }}>Internal Back Button</Button>
<Button variant={internalBackButton ? 'primary' : 'outline-primary'}
onClick={navigate} data-cy="navigateButton">Navigate</Button>
<Button variant="link" onClick={executeScroll}>Show Source</Button>
</div>
<div>
<span id="skillsDisplayPath" data-cy="skillsDisplayPath"></span>
</div>
<div className="border rounded">
<SkillsDisplay ref={skillsDisplayRef} options={options} theme={selectedTheme.theme} version={skillsVersion} handleRouteChanged={handleRouteChanged}/>
</div>
<div ref={sampleCodeRef}>
<SampleCode options={options} selectedTheme={selectedTheme}/>
</div>
</div>
);
};
export default ShowSkill;
@@ -0,0 +1,51 @@
/*
* 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.
*/
const exportedObj = {
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',
},
}
};
export default exportedObj;
@@ -1,12 +1,12 @@
{
"name": "skills-int-client-vue",
"version": "3.3.1",
"version": "3.5.0",
"license": "Apache-2.0",
"description": "SkillTree Client Lib Integration Tests - Vue",
"scripts": {
"serve": "vue-cli-service serve",
"buildDepsAndServe": "cd ../../skills-client-js/ && npm run build && cd ../skills-client-vue/ && npm run build && cd ../skills-client-integration/skills-int-client-vue/ && npm run serve",
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-3-Clause;Apache-2.0' --summary",
"licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-2-Clause;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 ",
@@ -14,8 +14,8 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@skilltree/skills-client-vue": "3.3.1",
"axios": "0.21.1",
"@skilltree/skills-client-vue": "3.5.0",
"axios": "1.6.0",
"bootstrap": "4.5.3",
"bootstrap-vue": "2.17.3",
"core-js": "3.2.1",
@@ -50,18 +50,14 @@
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
},
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {
}
"autoprefixer": {}
}
}
}
}
@@ -7,7 +7,7 @@
<parent>
<groupId>skills</groupId>
<artifactId>skills-client-integration</artifactId>
<version>3.3.1-SNAPSHOT</version>
<version>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-client-vue</artifactId>
@@ -1,469 +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 homePage = '/angular/reportSkills'
context('Angular Tests', () => {
const laterThan_1_4_0 = Utils.skillsServiceVersionLaterThan('1.4.0');
const missingSkillErrorCode = laterThan_1_4_0 ? 404 : 400;
const noThemeBackground = laterThan_1_4_0 ? 'rgba(0, 0, 0, 0)' : 'rgb(255, 255, 255)';
it('level component should be reactive', () => {
cy.createDefaultProject()
const sendEventViaDropdownId = '#PureJSReportAnySkill';
Cypress.Commands.add("clickSubmit", () => {
cy.get(`${sendEventViaDropdownId} .btn`).contains('Report Skill').click()
})
Cypress.Commands.add("selectSkill", (skill) => {
cy.get('[data-cy=anySkillDropDownButton]').click()
cy.get('[data-cy=anySkillDropDownItemButton]').contains(skill).click()//.select(`${skill}`)
})
cy.visitHomePage(homePage);
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')
})
it('level component should load initial level', () => {
cy.createDefaultProject()
// cy.reportSkill('subj1_skill0')
// 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('IronMan', '[email protected]')
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.visitHomePage(homePage);
cy.contains('Level 1')
})
it('level component should be reactive (skills reported directly to backend endpoint)', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.contains('Level 1')
cy.reportSkillForUser('Thor', Cypress.env('proxyUser'))
cy.contains('Level 2')
cy.reportSkillForUser('subj1_skill0', Cypress.env('proxyUser'))
cy.contains('Level 3')
cy.reportSkillForUser('subj1_skill1', Cypress.env('proxyUser'))
cy.contains('Level 3')
cy.reportSkillForUser('subj2_skill0', Cypress.env('proxyUser'))
cy.contains('Level 4')
cy.reportSkillForUser('subj2_skill1', Cypress.env('proxyUser'))
cy.contains('Level 5')
})
it('global event show correct results', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
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/)
})
it('global event does not update when skill reported for a different project', () => {
cy.createDefaultProject()
cy.createDefaultTinyProject('proj2')
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'), 'proj2')
cy.contains('Level 0')
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);
cy.contains('Level 1')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.contains('Level 1')
cy.get('[data-cy=globalEventResult]').should('be.empty');
})
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(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', '[email protected]')
cy.contains('Level 0')
})
it('skilltree directive on click', () => {
cy.createDefaultProject(1, 2, 50, 2)
cy.intercept('POST', '/api/projects/proj1/skills/IronMan').as('postSkill')
cy.visitHomePage(homePage);
Cypress.Commands.add("clickOnDirectiveBtn", (skillApplied = true) => {
cy.get('#SkillsDirectiveClickEvent button').click()
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(200)
expect(intercept.response.body).to.have.property('skillApplied').to.eq(skillApplied)
});
})
cy.clickOnDirectiveBtn()
cy.clickOnDirectiveBtn()
cy.clickOnDirectiveBtn(false)
})
it('skilltree directive on input', () => {
cy.createDefaultProject(1, 2, 50, 2)
cy.intercept('POST', '/api/projects/proj1/skills/Thor').as('postSkill')
cy.visitHomePage(homePage);
Cypress.Commands.add("typeToInput", (skillApplied = true) => {
cy.get('#SkillsDirectiveInputEvent input').type('h')
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(200)
expect(intercept.response.body).to.have.property('skillApplied').to.eq(skillApplied)
});
})
cy.typeToInput()
cy.typeToInput()
cy.typeToInput(false)
})
it('skilltree directive on click with error', () => {
cy.createDefaultTinyProject()
cy.intercept('POST', '/api/projects/proj1/skills/DoesNotExist').as('postSkill')
cy.visitHomePage(homePage);
cy.get('#SkillsDirectiveErrorwithButton button').click()
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(missingSkillErrorCode)
expect(intercept.response.body).to.have.property('explanation').to.eq('Failed to report skill event because skill definition does not exist.')
});
})
it('skilltree directive on input with error', () => {
cy.createDefaultTinyProject()
cy.intercept('POST', '/api/projects/proj1/skills/DoesNotExist').as('postSkill')
cy.visitHomePage(homePage);
cy.get('#SkillsDirectiveErrorwithInput input').type('h')
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(missingSkillErrorCode)
expect(intercept.response.body).to.have.property('explanation').to.eq('Failed to report skill event because skill definition does not exist.')
});
})
it('skill display', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/angular/showSkills')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0')
// verify that there is no background set
// cypress always validates against rgb
cy.clientDisplay().find('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', 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.visit('/angular/showSkills?isSummaryOnly=true')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0').should('not.exist')
// verify that there is no background set
// cypress always validates against rgb
cy.clientDisplay().find('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', noThemeBackground);
})
it('skill display - theme', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/angular/showSkills?themeName=Dark Blue')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0')
// verify dark blue background of hex #152E4d
// cypress always validates against rgb
cy.clientDisplay().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.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/angular/showSkills?themeName=Dark Blue&isSummaryOnly=true')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0').should('not.exist')
// verify dark blue background of hex #152E4d
// cypress always validates against rgb
cy.clientDisplay().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.intercept('/public/status',
{
statusCode: 503, // server is down
body: {}
}).as('getStatus')
cy.visit('/angular/showSkills')
cy.wait('@getStatus')
cy.contains('Could NOT reach Skilltree Service')
});
it('only display skills up-to the provided version', () => {
cy.createDefaultTinyProject()
cy.backendAddSkill('skillv1', 1)
cy.backendAddSkill('skillv2', 2)
cy.visit('/angular/showSkills')
cy.clientDisplay(true).contains('Earn up to 200 points')
cy.visit('/angular/reportSkills')
cy.get('#globalEventResultDiv').should('be.visible');
cy.visit('/angular/showSkills?skillsVersion=1')
cy.clientDisplay().contains('Earn up to 150 points')
cy.visit('/angular/reportSkills')
cy.get('#globalEventResultDiv').should('be.visible');
cy.visit('/angular/showSkills?skillsVersion=0')
cy.clientDisplay().contains('Earn up to 100 points')
});
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-ng-')
req.reply((res) => {
expect(res.statusCode).to.eq(200)
expect(res.body).to.have.property('success').to.eq(true)
})
}).as('reportClientVersion')
cy.visit(homePage)
cy.wait('@reportClientVersion')
})
if (Utils.skillsServiceVersionLaterThan('1.5.0')) {
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
cy.visit('/angular/showSkills?internalBackButton=true');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview that contains the back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').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.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/angular/showSkills?internalBackButton=false');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
// click the browser back button and verify that we are still in the
// client display (Subject page)
cy.go('back') // browser back button
cy.clientDisplay().contains('Subject 0');
// then back one more time and we should be back on the client display home page
cy.go('back') // browser back button
cy.clientDisplay().contains('User Skills');
});
it('deep link and reload', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// navigate to Rank Overview via direct link
cy.visit('/angular/showSkills?skillsClientDisplayPath=%2Frank');
cy.clientDisplay().contains('Rank Overview');
// reload and confirm we are still on Rank Overview page
cy.reload();
cy.clientDisplay().contains('Rank Overview');
});
it('back button after reload', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/angular/showSkills?internalBackButton=false');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.reload();
cy.clientDisplay().contains('Rank Overview');
// click the browser back button and verify that we are still in the
// client display (Subject page)
cy.go('back') // browser back button
cy.clientDisplay().contains('Subject 0');
// then back one more time and we should be back on the client display home page
cy.go('back') // browser back button
cy.clientDisplay().contains('User Skills');
});
it('route change is passed to the client app', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/angular/showSkills?internalBackButton=false');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/]');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
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('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0/rank]');
});
}
if (Utils.skillsServiceVersionLaterThan('1.6.0')) {
it('navigate skills-display programatically', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/angular/showSkills?internalBackButton=false');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/]');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.get('[data-cy=navigateButton]').click();
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0]');
});
}
})
@@ -20,7 +20,9 @@ const homePage = '/native/index.html'
context("Native JS Tests", () => {
const laterThan_1_4_0 = Utils.skillsServiceVersionLaterThan('1.4.0');
const laterThan_1_11_1 = Utils.skillsServiceVersionLaterThan('1.11.1');
const noThemeBackground = laterThan_1_4_0 ? 'rgba(0, 0, 0, 0)' : 'rgb(255, 255, 255)';
const rankDetailsTitle = laterThan_1_11_1 ? 'My Rank' : 'Rank Overview'
it("global event show correct results", () => {
cy.createDefaultProject();
@@ -78,6 +80,7 @@ context("Native JS Tests", () => {
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');
@@ -283,7 +286,7 @@ context("Native JS Tests", () => {
cy.contains('Level 0')
cy.reportSkillForUser('subj1_skill0', Cypress.env('proxyUser'))
cy.visitHomePage(homePage);
// cy.visitHomePage(homePage);
cy.contains('Level 1')
})
@@ -302,7 +305,7 @@ context("Native JS Tests", () => {
// navigate to Rank Overview that contains the back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
cy.clientDisplay().find('[data-cy=back]').should('exist');
// now visit the "Report Skills" (external) page
@@ -328,7 +331,7 @@ context("Native JS Tests", () => {
// navigate to Rank Overview that contains the back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
cy.clientDisplay().find('[data-cy=back]').should('exist');
// click the back button and verify that we are still in the
@@ -354,7 +357,7 @@ context("Native JS Tests", () => {
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
// click the browser back button and verify that we are still in the
@@ -373,11 +376,11 @@ context("Native JS Tests", () => {
// navigate to Rank Overview via direct link
cy.visit('/native/clientDisplay.html?skillsClientDisplayPath=%2Frank#/showSkills');
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
// reload and confirm we are still on Rank Overview page
cy.reload();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
});
it('back button after reload', () => {
@@ -395,11 +398,11 @@ context("Native JS Tests", () => {
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.reload();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
// click the browser back button and verify that we are still in the
// client display (Subject page)
@@ -425,7 +428,7 @@ context("Native JS Tests", () => {
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().contains(rankDetailsTitle);
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0/rank]');
});
@@ -1,394 +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 homePage = '/react/index.html#/'
context('React Tests', () => {
const laterThan_1_4_0 = Utils.skillsServiceVersionLaterThan('1.4.0');
const noThemeBackground = laterThan_1_4_0 ? 'rgba(0, 0, 0, 0)' : 'rgb(255, 255, 255)';
it('level component should be reactive (skills reported directly to backend endpoint)', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.contains('Level 1')
cy.reportSkillForUser('Thor', Cypress.env('proxyUser'))
cy.contains('Level 2')
cy.reportSkillForUser('subj1_skill0', Cypress.env('proxyUser'))
cy.contains('Level 3')
cy.reportSkillForUser('subj1_skill1', Cypress.env('proxyUser'))
cy.contains('Level 3')
cy.reportSkillForUser('subj2_skill0', Cypress.env('proxyUser'))
cy.contains('Level 4')
cy.reportSkillForUser('subj2_skill1', Cypress.env('proxyUser'))
cy.contains('Level 5')
})
it('level component should load initial level', () => {
cy.createDefaultProject()
// cy.reportSkill('subj1_skill0')
// this will increment levels for the default user = [email protected] but Level and display components display data for Cypress.env('proxyUser')
// validate that level is still 0
cy.reportSkillForUser('IronMan', '[email protected]')
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.visitHomePage(homePage);
cy.contains('Level 1')
})
it('global event show correct results', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
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/)
})
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(homePage);
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')
})
it('global event does not update when skill reported for a different project', () => {
cy.createDefaultProject()
cy.createDefaultTinyProject('proj2')
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'), 'proj2')
cy.contains('Level 0')
cy.get('[data-cy=globalEventResult]').should('be.empty');
})
it('level component should not update when admin reports skill for other user', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', '[email protected]')
cy.contains('Level 0')
})
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.visit('/react/index.html#/showSkills')
cy.wait('@getToken')
cy.wait('@getToken')
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('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', 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.visit('/react/index.html#/showSkills?isSummaryOnly=true')
cy.wait('@getToken')
cy.wait('@getToken')
cy.wrapIframe().contains('My Level')
cy.wrapIframe().contains('50 Points earned Today')
cy.wrapIframe().contains('Subject 0').should('not.exist')
// verify that there is no background set
// cypress always validates against rgb
cy.wrapIframe().find('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', 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.visit('/react/index.html#/showSkills?themeName=Dark Blue')
cy.wait('@getToken')
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('.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.intercept(Cypress.env('tokenUrl')).as('getToken')
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/react/index.html#/showSkills?themeName=Dark Blue&isSummaryOnly=true')
cy.wait('@getToken')
cy.wait('@getToken')
cy.wrapIframe().contains('My Level')
cy.wrapIframe().contains('50 Points earned Today')
cy.wrapIframe().contains('Subject 0').should('not.exist')
// verify dark blue background of hex #152E4d
// cypress always validates against rgb
cy.wrapIframe().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.intercept('/public/status',
{
statusCode: 503, // server is down
body: {}
}).as('getStatus')
cy.visit('/react/index.html#/showSkills')
cy.wait('@getStatus')
cy.contains('Could NOT reach Skilltree Service')
});
it('only display skills up-to the provided version', () => {
cy.createDefaultTinyProject()
cy.intercept(Cypress.env('tokenUrl')).as('getToken')
cy.backendAddSkill('skillv1', 1)
cy.backendAddSkill('skillv2', 2)
cy.visit('/react/index.html#/showSkills')
cy.wait('@getToken')
cy.wait('@getToken')
cy.wrapIframe().contains('Earn up to 200 points')
cy.visit('/react/index.html#/')
cy.visit('/react/index.html#/showSkills?skillsVersion=1')
cy.wait('@getToken')
cy.wrapIframe().contains('Earn up to 150 points')
cy.visit('/react/index.html#/')
cy.visit('/react/index.html#/showSkills?skillsVersion=0')
cy.wait('@getToken')
cy.wrapIframe().contains('Earn up to 100 points')
});
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-react-')
req.reply((res) => {
expect(res.statusCode).to.eq(200)
expect(res.body).to.have.property('success').to.eq(true)
})
}).as('reportClientVersion')
cy.visit('/react/index.html#/')
cy.wait('@reportClientVersion')
})
if (Utils.skillsServiceVersionLaterThan('1.5.0')) {
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
cy.visit('/react/index.html#/showSkills?internalBackButton=true');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview that contains the back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').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.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/react/index.html#/showSkills?internalBackButton=false');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
// click the browser back button and verify that we are still in the
// client display (Subject page)
cy.go('back') // browser back button
cy.clientDisplay().contains('Subject 0');
// then back one more time and we should be back on the client display home page
cy.go('back') // browser back button
cy.clientDisplay().contains('User Skills');
});
it('deep link and reload', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// navigate to Rank Overview via direct link
cy.visit('/react/index.html?skillsClientDisplayPath=%2Frank#/showSkills');
cy.clientDisplay().contains('Rank Overview');
// reload and confirm we are still on Rank Overview page
cy.reload();
cy.clientDisplay().contains('Rank Overview');
});
it('back button after reload', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/react/index.html#/showSkills?internalBackButton=false');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.reload();
cy.clientDisplay().contains('Rank Overview');
// click the browser back button and verify that we are still in the
// client display (Subject page)
cy.go('back') // browser back button
cy.clientDisplay().contains('Subject 0');
// then back one more time and we should be back on the client display home page
cy.go('back') // browser back button
cy.clientDisplay().contains('User Skills');
});
it('route change is passed to the client app', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/react/index.html#/showSkills?internalBackButton=false');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/]');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
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('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0/rank]');
});
}
if (Utils.skillsServiceVersionLaterThan('1.6.0')) {
it('navigate skills-display programatically', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/react/index.html#/showSkills?internalBackButton=false');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/]');
cy.clientDisplay().contains('User Skills');
// 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 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.
*/
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(0, 'Subject 0');
});
} else {
it('timeout var not set, not tests to run', () => {
cy.log(`timeout env var is not true [${Cypress.env('timeout')}], skipping test.`)
});
}
});
@@ -1,582 +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 homePage = '/vuejs#/'
context('Vue Tests', () => {
const laterThan_1_4_0 = Utils.skillsServiceVersionLaterThan('1.4.0');
const laterThan_1_5_0 = Utils.skillsServiceVersionLaterThan('1.5.0');
const missingSkillErrorCode = laterThan_1_4_0 ? 404 : 400;
const noThemeBackground = laterThan_1_4_0 ? 'rgba(0, 0, 0, 0)' : 'rgb(255, 255, 255)';
const clientDisplayWithInternalBackButtonParams = laterThan_1_5_0 ? '?refreshPage=false&internalBackButton=true' : '?refreshPage=false';
it('level component should be reactive', () => {
// cy.window().then(win => {
// const skillsLogger = win.skillsLogger;
// skillsLogger.info('enter: 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(homePage);
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')
})
it('level component should load initial level', () => {
cy.createDefaultProject()
// cy.reportSkill('subj1_skill0')
// 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('IronMan', '[email protected]')
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.visitHomePage(homePage);
cy.contains('Level 1')
})
it('level component should be reactive (skills reported directly to backend endpoint)', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.contains('Level 1')
cy.reportSkillForUser('Thor', Cypress.env('proxyUser'))
cy.contains('Level 2')
cy.reportSkillForUser('subj1_skill0', Cypress.env('proxyUser'))
cy.contains('Level 3')
cy.reportSkillForUser('subj1_skill1', Cypress.env('proxyUser'))
cy.contains('Level 3')
cy.reportSkillForUser('subj2_skill0', Cypress.env('proxyUser'))
cy.contains('Level 4')
cy.reportSkillForUser('subj2_skill1', Cypress.env('proxyUser'))
cy.contains('Level 5')
})
it('global event show correct results', () => {
cy.createDefaultProject()
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
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/)
})
it('global event does not update when skill reported for a different project', () => {
cy.createDefaultProject()
cy.createDefaultTinyProject('proj2')
cy.visitHomePage(homePage);
cy.contains('Level 0')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'), 'proj2')
cy.contains('Level 0')
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);
cy.contains('Level 1')
cy.reportSkillForUser('IronMan', Cypress.env('proxyUser'))
cy.contains('Level 1')
cy.get('[data-cy=globalEventResult]').should('be.empty');
})
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(homePage);
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.intercept('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').then((intercept) => {
expect(intercept.response.statusCode).to.eq(200)
expect(intercept.response.body).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.intercept('POST', '/api/projects/proj1/skills/Thor').as('postSkill')
cy.visitHomePage(homePage);
Cypress.Commands.add("typeToInput", (skillApplied = true) => {
cy.get('#SkillsDirectiveInputEvent input').type('h')
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(200)
expect(intercept.response.body).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.intercept('POST', '/api/projects/proj1/skills/DoesNotExist').as('postSkill')
cy.visitHomePage(homePage);
cy.get('#SkillsDirectiveErrorwithButton button').click()
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(missingSkillErrorCode)
expect(intercept.response.body).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.intercept('POST', '/api/projects/proj1/skills/DoesNotExist').as('postSkill')
cy.visitHomePage(homePage);
cy.get('#SkillsDirectiveErrorwithInput input').type('h')
cy.wait('@postSkill').then((intercept) => {
expect(intercept.response.statusCode).to.eq(missingSkillErrorCode)
expect(intercept.response.body).to.have.property('explanation').to.eq('Failed to report skill event because skill definition does not exist.')
});
})
it('skill display', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/vuejs#/showSkills')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0')
// verify that there is no background set
// cypress always validates against rgb
cy.clientDisplay().find('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', noThemeBackground);
})
it('Proxy Skills Display', () => {
if (!Cypress.env('oauthMode')) {
cy.createDefaultTinyProject()
cy.createDefaultTinyProject('proj2')
cy.intercept(Cypress.env('tokenUrl')).as('getToken')
cy.intercept('/api/users/proj2/user2/token').as('getToken2')
cy.intercept('api/projects/proj1/rank').as('getRankUser2')
cy.intercept('api/projects/proj1/pointHistory').as('getPointsHistoryUser2')
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/vuejs#/showSkills')
cy.wait('@getToken')
// cy.wait('@getToken')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0')
// verify that there is no background set
// cypress always validates against rgb
cy.clientDisplay().find('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', noThemeBackground);
cy.visit('/vuejs#/proxyShowSkills')
cy.wait('@getToken2')
cy.wait('@getRankUser2')
cy.wait('@getPointsHistoryUser2')
cy.clientDisplay().contains('My Level')
cy.clientDisplay().contains('0 Points earned Today')
}
})
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.visit('/vuejs#/showSkills?isSummaryOnly=true')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0').should('not.exist')
// verify that there is no background set
// cypress always validates against rgb
cy.clientDisplay().find('.skills-page-title-text-color')
.should('have.css', 'background-color').and('equal', noThemeBackground);
})
it('skill display - theme', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/vuejs#/showSkills?themeName=Dark Blue')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0')
// verify dark blue background of hex #152E4d
// cypress always validates against rgb
cy.clientDisplay().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.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.visit('/vuejs#/showSkills?themeName=Dark Blue&isSummaryOnly=true')
cy.clientDisplay(true).contains('My Level')
cy.clientDisplay().contains('50 Points earned Today')
cy.clientDisplay().contains('Subject 0').should('not.exist')
// verify dark blue background of hex #152E4d
// cypress always validates against rgb
cy.clientDisplay().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.intercept('/public/status',
{
statusCode: 503, // server is down
body: {}
}).as('getStatus')
cy.visit('/vuejs#/showSkills')
cy.wait('@getStatus')
cy.contains('Could NOT reach Skilltree Service')
});
it('only display skills up-to the provided version', () => {
cy.createDefaultTinyProject()
cy.backendAddSkill('skillv1', 1)
cy.backendAddSkill('skillv2', 2)
cy.visit('/vuejs#/showSkills')
cy.clientDisplay(true).contains('Earn up to 200 points')
cy.visit('/vuejs#/')
cy.get('[data-cy=reportSkillsLink]').should('be.visible');
cy.visit('/vuejs#/showSkills?skillsVersion=1')
cy.clientDisplay().contains('Earn up to 150 points')
cy.visit('/vuejs#/')
cy.get('[data-cy=reportSkillsLink]').should('be.visible');
cy.visit('/vuejs#/showSkills?skillsVersion=0')
cy.clientDisplay().contains('Earn up to 100 points')
});
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-vue-')
req.reply((res) => {
expect(res.statusCode).to.eq(200)
expect(res.body).to.have.property('success').to.eq(true)
})
}).as('reportClientVersion')
cy.visit('/vuejs#/')
cy.wait('@reportClientVersion')
})
/*it('Proxy User Display', () => {
cy.createDefaultProject()
cy.createDefaultTinyProject('proj2')
//need a view that is the default user and a view to show another user
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(homePage);
cy.contains('Level 0')
cy.selectSkill('IronMan')
cy.clickSubmit()
cy.contains('Level 1')
cy.intercept(Cypress.env('tokenUrl')).as('getToken')
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
cy.get('[data-cy=userDisplayLink]').click();
//cy.contains('User Display').click();
/!*cy.wait('@getToken')
console.log('got token')
cy.iframe((body) => {
cy.wait('@getToken')
console.log('got token again')
cy.wrap(body).contains('My Level')
// 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)');
});*!/
})*/
if (Utils.skillsServiceVersionLaterThan('1.2.0')) {
it('back button when when returning from an external page', () => {
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
cy.visit('/vuejs#/showSkills'+clientDisplayWithInternalBackButtonParams)
// cy.wait('@getToken')
cy.clientDisplay(true).find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// navigate to Rank Overview that contains the back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').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()
});
}
if (Utils.skillsServiceVersionLaterThan('1.2.0')) {
it('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
cy.visit('/vuejs#/showSkills'+clientDisplayWithInternalBackButtonParams)
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview that contains the back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').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()
// verify we are still on the Rank Overview page
cy.clientDisplay(true).contains('Rank Overview');
// 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');
});
}
if (Utils.skillsServiceVersionLaterThan('1.5.0')) {
it('browser back button works correctly when internal back button is not present', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/vuejs#/showSkills?internalBackButton=false');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
// click the browser back button and verify that we are still in the
// client display (Subject page)
cy.go('back') // browser back button
cy.clientDisplay().contains('Subject 0');
// then back one more time and we should be back on the client display home page
cy.go('back') // browser back button
cy.clientDisplay().contains('User Skills');
});
it('deep link and reload', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// navigate to Rank Overview via direct link
cy.visit('/vuejs/?skillsClientDisplayPath=%2Frank#/showSkills?refreshPage=true');
cy.clientDisplay().contains('Rank Overview');
// reload and confirm we are still on Rank Overview page
cy.reload();
cy.clientDisplay().contains('Rank Overview');
});
it('back button after reload', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/vuejs#/showSkills?internalBackButton=false');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
// navigate to Rank Overview and that it does NOT contains the internal back button
cy.clientDisplay().find('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.clientDisplay().find('[data-cy=back]').should('not.exist');
cy.reload();
cy.clientDisplay().contains('Rank Overview');
// click the browser back button and verify that we are still in the
// client display (Subject page)
cy.go('back') // browser back button
cy.clientDisplay().contains('Subject 0');
// then back one more time and we should be back on the client display home page
cy.go('back') // browser back button
cy.clientDisplay().contains('User Skills');
});
it('route change is passed to the client app', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/vuejs#/showSkills?internalBackButton=false');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/]');
// to subject page
cy.cdClickSubj(0, 'Subject 0');
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('[data-cy=myRank]').click();
cy.clientDisplay().contains('Rank Overview');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0/rank]');
});
}
if (Utils.skillsServiceVersionLaterThan('1.6.0')) {
it('navigate skills-display programatically', () => {
cy.createDefaultTinyProject()
cy.backendPost('/api/projects/proj1/skills/Thor', {userId: Cypress.env('proxyUser'), timestamp: Date.now()})
// visit client display
cy.visit('/vuejs#/showSkills?internalBackButton=false');
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/]');
cy.clientDisplay().contains('User Skills');
// to subject page
cy.get('[data-cy=navigateButton]').click();
cy.get('[data-cy=skillsDisplayPath]').contains('Skills Display Path: [/subjects/subj0]');
});
}
})
@@ -153,22 +153,16 @@ Cypress.Commands.add("iframe", (handleIframeBody) => {
});
Cypress.Commands.add('visitHomePage', (homepage) => {
let skillsWebsocketConnected = null;
const winMessage = cy.stub().as('message')
cy.visit(homepage, {
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')
win.addEventListener('message', (e) => {
winMessage(e.data)
})
}
});
})
// wait for web socket to connect
cy.get('@skillsWebsocketConnected').its('lastCall.args.0').its('skillsWebsocketConnected').should('eq', true);
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}]`)
});
@@ -19,7 +19,7 @@ services:
mem_limit: 512m
container_name: hydra_migrate
environment:
- DSN=postgres://hydra:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
- DSN=postgres://hydra:secret@postgresd:5433/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
command:
migrate sql -e --yes
restart: on-failure
@@ -28,15 +28,17 @@ services:
depends_on:
- hydra-migrate
environment:
- DSN=postgres://hydra:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
- 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:
- "5432:5432"
- "5433:5433"
environment:
- POSTGRES_USER=hydra
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=hydra
- POSTGRES_PORT=5433
- PGPORT=5433
@@ -13,9 +13,9 @@
"test": "echo \"Error: no test specified\" && exit 1",
"cy:open": "cypress open",
"cy:run": "npm run licenseCheck && cypress run",
"cy:open:dev:vue": "cypress open --config baseUrl=http://localhost:8091",
"cy:run:oauth": "npm run licenseCheck && cypress run --env authMode=oauth",
"cy:run:timeout": "npm run licenseCheck && cypress run --env timeout=true --spec \"cypress/integration/timeout.specs.js\"",
"cy:open:dev:js": "cypress open --config baseUrl=http://localhost:8092",
"cy:open:dev:react": "cypress open --config baseUrl=http://localhost:8083",
"cy:open:dev:ng": "cypress open --config baseUrl=http://localhost:4200",
"integration:start": "java -Dspring.config.location=classpath:/application.properties,file:serverConfigs/integration_application.properties -jar ../skills-int-service/target/skills-int-service-*.jar",
"integration:start:oauth": "java -Dskills.service.authenticator=hydra -Dspring.config.location=classpath:/application.properties,file:serverConfigs/integration_application.properties -jar ../skills-int-service/target/skills-int-service-*.jar",
@@ -27,21 +27,25 @@
"backend:start:background": "mkdir -p ./target/logs && npm run backend:start | awk '/ClientLoggingController/{ print > \"./target/logs/skills-client.out\" }!/ClientLoggingController/{ print > \"./target/logs/skills-service.out\" }' &",
"backend:start:ci": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ../../skills-service/skills-service-*.jar",
"backend:start:ci:oauth": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties,file:serverConfigs/backend_oauth_application.properties -jar ../../skills-service/skills-service-*.jar",
"backend:start:ci:rabbitmq": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -Dsecurity.oauth2.jwt.accessTokenValiditySeconds=10 -Dskills.websocket.enableStompBrokerRelay=true -Dskills.websocket.relayHost=localhost -Dlogging.level.org.springframework.web.socket=TRACE -jar ../../skills-service/skills-service-*.jar",
"backend:start:ci:expired-token": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -Dsecurity.oauth2.jwt.accessTokenValiditySeconds=10 -Dlogging.level.org.springframework.web.socket=TRACE -jar ../../skills-service/skills-service-*.jar",
"backend:start:ci:background": "mkdir -p ./target/logs && npm run backend:start:ci | awk '/ClientLoggingController/{ print > \"./target/logs/skills-client.out\" }!/ClientLoggingController/{ print > \"./target/logs/skills-service.out\" }' &",
"backend:start:ci:background:oauth": "mkdir -p ./target/logs && npm run backend:start:ci:oauth | awk '/ClientLoggingController/{ print > \"./target/logs/skills-client.out\" }!/ClientLoggingController/{ print > \"./target/logs/skills-service.out\" }' &",
"backend:start:ci:background:expired-token": "mkdir -p ./target/logs && npm run backend:start:ci:expired-token | awk '/ClientLoggingController/{ print > \"./target/logs/skills-client.out\" }!/ClientLoggingController/{ print > \"./target/logs/skills-service.out\" }' &",
"backend:start:release": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ./target/servicesJars/skills-service-*.jar",
"backend:waitToStart": "npx wait-port -v -t 60000 localhost:8080",
"backend:resetDb": "java -cp ./db/h2-1.4.200.jar org.h2.tools.RunScript -url jdbc:h2:tcp://localhost:9090/mem:skills -user sa -script ./db/reset.sql",
"backend:waitToStart": "npx wait-port -t 60000 localhost:8080",
"backend:resetDb": "export PGPASSWORD=skillsPassword && psql -U postgres -h localhost -d skills -f ./db/reset.sql",
"release": "release-it --dry-run",
"cyServices:start:skills-service": "npm run backend:start:background && npm run backend:waitToStart && echo 'skill-service started!!'",
"cyServices:start:skills-service:ci": "npm run backend:start:ci:background && npm run backend:waitToStart && echo 'skill-service started!!'",
"cyServices:start:skills-service:ci:oauth": "npm run backend:start:ci:background:oauth && npm run backend:waitToStart && echo 'skill-service started!!'",
"cyServices:start:skills-service:ci:expired-token": "npm run backend:start:ci:background:expired-token && npm run backend:waitToStart && echo 'skill-service started!!'",
"cyServices:start:integration-apps": "npm run integration:start:background && npm run integration:waitToStart && echo 'integration apps started!!'",
"cyServices:start:integration-apps:oauth": "npm run integration:start:background:oauth && npm run integration:waitToStart && echo 'integration apps started!!'",
"cyServices:start": "npm run cyServices:start:skills-service && npm run cyServices:start:integration-apps",
"cyServices:kill": "for procid in $(ps -aux | grep \"serverConfigs/.*properties\" | grep \"jar$\" | awk '{print $2}'); do echo \"killing ${procid}\"; kill -9 $procid; done",
"dev:setupNpmLinks": "mvn --batch-mode clean package && java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.SetupNpmLinks org.springframework.boot.loader.PropertiesLauncher",
"dev:removeNpmLinks": "mvn --batch-mode clean package && java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.RemoveNpmLinks org.springframework.boot.loader.PropertiesLauncher"
"dev:setupNpmLinks": "mvn --batch-mode clean package && java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.SetupNpmLinks org.springframework.boot.loader.launch.PropertiesLauncher",
"dev:removeNpmLinks": "mvn --batch-mode clean package && java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.RemoveNpmLinks org.springframework.boot.loader.launch.PropertiesLauncher"
},
"devDependencies": {
"cypress": "6.6.0",
@@ -5,30 +5,35 @@
<parent>
<groupId>skills</groupId>
<artifactId>skills-client-integration</artifactId>
<version>3.3.1-SNAPSHOT</version>
<version>3.5.0-SNAPSHOT</version>
</parent>
<artifactId>skills-int-e2e-test</artifactId>
<description>End to End tests for Skills client libs using skills-int-service app</description>
<properties>
<groovy.version>4.0.7</groovy.version>
</properties>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${groovy.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-json</artifactId>
<version>${groovy.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-json-direct</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-xml</artifactId>
<version>${groovy.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.groovy</groupId>-->
<!-- <artifactId>groovy-json-direct</artifactId>-->
<!-- <version>2.5.13</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
@@ -43,25 +48,6 @@
<artifactId>zt-exec</artifactId>
<version>1.12</version>
</dependency>
<!--<dependency>-->
<!--<groupId>profile</groupId>-->
<!--<artifactId>call-stack-profiler</artifactId>-->
<!--<version>1.0.2</version>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>org.slf4j</groupId>-->
<!--<artifactId>slf4j-api</artifactId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<groupId>log4j</groupId>-->
<!--<artifactId>log4j</artifactId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<groupId>org.slf4j</groupId>-->
<!--<artifactId>slf4j-log4j12</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>semver4j</artifactId>
@@ -73,13 +59,14 @@
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-cli-picocli</artifactId>
<version>${groovy.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.9</version>
<version>1.10.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -90,13 +77,13 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>skills.NpmProjBuilder</mainClass>
<mainClass>skills.TestDashboardBackwardCompat</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.11.0</version>
<version>2.1.0</version>
<executions>
<execution>
<goals>
@@ -150,6 +137,7 @@
<licenseMerges>
<licenseMerge>The Apache Software License, Version 2.0|Apache License, Version 2.0</licenseMerge>
<licenseMerge>The Apache Software License, Version 2.0|Apache 2</licenseMerge>
<licenseMerge>The Apache Software License, Version 2.0|Apache-2.0</licenseMerge>
<licenseMerge>The Apache Software License, Version 2.0|The Apache License, Version 2.0</licenseMerge>
<licenseMerge>The Apache Software License, Version 2.0|The Apache Software License, version 2.0</licenseMerge>
<licenseMerge>Eclipse Public License - Version 1.0|Eclipse Public License 1.0</licenseMerge>
@@ -11,10 +11,9 @@
# 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.
spring.datasource.url=jdbc:h2:mem:skills
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.username = postgres
spring.datasource.url = jdbc:postgresql://localhost:5432/skills
spring.datasource.password = skillsPassword
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
logging.level.org.springframework.security.web.access.intercept.FilterSecurityInterceptor=DEBUG
@@ -1,3 +1,16 @@
# 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.
spring.security.oauth2.client.registration.hydra.client-id: skilltree-test
spring.security.oauth2.client.registration.hydra.client-secret: client-secret
@@ -0,0 +1,32 @@
/*
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.
*/
package skills
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.stereotype.Component
@Component
@ConfigurationProperties(prefix="skills")
class Config {
List<VersionProps> versionProps
static class VersionProps {
String version
String altJavaHomeEnv
}
}
@@ -30,14 +30,6 @@ class NpmProj {
// indicates whether it has node_modules/@skilltree/
boolean hasLinksToOtherProjects = true
// need extra npm link setup for react apps/modules
boolean reactModule = false
boolean reactApp = false
// need extra npm link setup for angular apps/modules
boolean angularModule = false
boolean angularApp = false
// for backwards compatibility testing
String initialVersion
@@ -65,24 +57,6 @@ class NpmProj {
return skillsModules
}
File getReactModuleDir(boolean checkForExistence = true) {
File reactModule = new File(getNodeModulesDir(checkForExistence), "react/")
if (checkForExistence) {
assert reactModule.exists()
}
return reactModule
}
File getAngularModuleLinkDir(boolean checkForExistence = true) {
// dist/skilltree/skills-client-ng
File ngModuleLinkDir = new File(new File(new File(loc, "dist/"), "skilltree"), this.name)
if (checkForExistence) {
assert ngModuleLinkDir.exists()
}
return ngModuleLinkDir
}
static JsonSlurper slurper = new JsonSlurper()
def getPackageJson() {
@@ -44,13 +44,7 @@ class NpmProjBuilder {
private List<NpmProj> projs = [
new NpmProj(name: "skills-client-js", doOthersLinkToMe: true, hasLinksToOtherProjects: false, initialVersion: '2.0.0'),
new NpmProj(name: "skills-client-vue", doOthersLinkToMe: true, initialVersion: '2.0.0'),
new NpmProj(name: "skills-client-react", doOthersLinkToMe: true, reactModule: true, initialVersion: '2.0.0'),
new NpmProj(name: "skills-client-ng", doOthersLinkToMe: true, angularModule: true, initialVersion: '3.0.0'),
new NpmProj(name: "skills-int-client-js", doOthersLinkToMe: false, initialVersion: '2.0.0'),
new NpmProj(name: "skills-int-client-vue", doOthersLinkToMe: false, initialVersion: '2.0.0'),
new NpmProj(name: "skills-int-client-react", doOthersLinkToMe: false, reactApp: true, initialVersion: '2.0.0'),
new NpmProj(name: "skills-int-client-ng", doOthersLinkToMe: false, angularApp: true, initialVersion: '3.0.0'),
]
private void assertExist() {
@@ -18,6 +18,7 @@ package skills
import groovy.util.logging.Slf4j
import org.apache.commons.text.StringTokenizer
import org.apache.commons.text.matcher.StringMatcherFactory
import org.codehaus.groovy.runtime.ProcessGroovyMethods
import org.zeroturnaround.exec.stream.TeeOutputStream
import org.zeroturnaround.exec.stream.slf4j.Slf4jStream
@@ -37,6 +38,7 @@ class ProcessRunner {
// OutputStream sout = new StringBuilder()
// Appendable serr = new StringBuilder()
File loc = new File("./")
List env = []
ProcessRes run(String cmd) {
StringTokenizer st = new StringTokenizer(cmd)
@@ -53,11 +55,16 @@ class ProcessRunner {
String name = loc.name
if (dryRun) {
log.info("DRY RUN [${cmd}] in [${loc.absoluteFile.absolutePath}]")
log.info("DRY RUN [${cmd}] in [${loc.absoluteFile.absolutePath}]${env ? " Custom ENV ${env}" : ""}")
return new ProcessRes(serr: "", sout: "")
} else {
log.info("Executing: [${cmd}] in [$loc.absoluteFile.absolutePath]")
Process p = cmd.execute(null, loc)
log.info("Executing: [${cmd}] in [$loc.absoluteFile.absolutePath]${env ? " Custom ENV ${env}" : ""}")
Process p
if (env) {
p = ProcessGroovyMethods.execute(cmd, env, loc)
} else {
p = cmd.execute(null, loc)
}
if (waitForOutput) {
if (printOutput) {
@@ -16,6 +16,7 @@ limitations under the License.
package skills
import groovy.util.logging.Slf4j
import groovy.xml.XmlSlurper
import skills.helpers.NextVersionHelper
import skills.helpers.ScriptParamsHelper
@@ -51,13 +51,6 @@ class RemoveNpmLinks {
FileUtils.deleteDirectory(depDir.absoluteFile)
}
}
if (proj.isReactApp()) {
File reactModuleDir = proj.getReactModuleDir(false)
if (reactModuleDir.exists()) {
log.info("Deleting [{}]", reactModuleDir.absoluteFile.absolutePath)
FileUtils.deleteDirectory(reactModuleDir.absoluteFile)
}
}
}
if (npmInstall){
@@ -52,7 +52,6 @@ class SetupNpmLinks {
createLinks()
npmLinkToSkills()
install()
npmLinkToReact()
validateLinks()
build()
}
@@ -61,10 +60,7 @@ class SetupNpmLinks {
private void install() {
titlePrinter.printTitle("install")
projs.each { NpmProj npmProj ->
if (!npmProj.isAngularModule()) {
// angular modules were installed within createLinks()
npmProj.exec("npm install --force")
}
npmProj.exec("npm install --force")
}
}
@@ -72,10 +68,7 @@ class SetupNpmLinks {
private void build() {
titlePrinter.printTitle("build")
projs.each { NpmProj npmProj ->
if (!npmProj.isAngularModule()) {
// angular modules were built within createLinks()
npmProj.exec("npm run build")
}
npmProj.exec("npm run build")
}
}
@@ -91,12 +84,6 @@ class SetupNpmLinks {
assert Files.isSymbolicLink(shouldBeSymbolic.toPath())
}
}
projs.findAll({ it.isReactApp() }).each { NpmProj npmProj ->
titlePrinter.printSubTitle("validating [${npmProj.getReactModuleDir().absolutePath}]")
npmProj.exec("ls -l node_modules/react/")
assert Files.isSymbolicLink(npmProj.getReactModuleDir().toPath())
}
}
// @Profile
@@ -105,27 +92,9 @@ class SetupNpmLinks {
projs.findAll({ it.hasLinksToOtherProjects }).each { NpmProj npmProj ->
npmProj.skillsDependenciesFromPackageJson.each {
titlePrinter.printSubTitle("Linking module [${it}] in project [${npmProj}]")
if (npmProj.getAngularApp() || npmProj.getAngularModule()) {
npmProj.exec("npm install --force")
}
npmProj.exec("npm link ${it}".toString())
if (npmProj.getAngularModule()) {
File origLoc = npmProj.loc
npmProj.loc = npmProj.getAngularModuleLinkDir(true)
npmProj.exec("npm link ${it}".toString())
npmProj.loc = origLoc
}
}
}
}
// @Profile
private void npmLinkToReact() {
titlePrinter.printTitle("link react")
projs.findAll({ it.reactApp }).each { NpmProj npmProj ->
File reactModuleDir = projs.find { it.reactModule }.getReactModuleDir()
titlePrinter.printSubTitle("Linking react module [${reactModuleDir.absoluteFile.absolutePath}]")
npmProj.exec("npm link ${reactModuleDir.absoluteFile.absolutePath}".toString())
npmProj.exec("npm link --force ${it}".toString())
}
}
}
@@ -133,21 +102,10 @@ class SetupNpmLinks {
private void createLinks() {
titlePrinter.printTitle("create links")
projs.findAll({ it.doOthersLinkToMe }).each {
File origLoc
if (it.isAngularModule()) {
titlePrinter.printTitle("install and build angular module")
it.exec("npm install --force")
it.exec("npm run build")
origLoc = it.loc;
it.loc = it.getAngularModuleLinkDir(true)
}
titlePrinter.printSubTitle("create link for ${it.loc.name}")
it.exec("ls")
it.exec("node -v")
it.exec("npm link")
if (it.isAngularModule()) {
it.loc = origLoc
}
}
}
}
@@ -19,6 +19,7 @@ import groovy.cli.picocli.CliBuilder
import groovy.json.JsonSlurper
import groovy.util.logging.Slf4j
import org.apache.commons.io.FileUtils
import skills.helpers.NextVersionHelper
@Slf4j
class TestClientLibsBackwardsCompat {
@@ -27,13 +28,18 @@ class TestClientLibsBackwardsCompat {
def cli = new CliBuilder()
cli.record(type: boolean, 'record tests in cypress dashboard')
cli.tag(type: String, 'tag to give cypress test')
cli.minVersion(type: String, 'the minimum skills-service version to test against', defaultValue: '1.9.0')
def options = cli.parse(args)
def shouldRecord = options.record
String tag
if (options.tag && options.tag instanceof String) {
tag = options.tag
}
new TestClientLibsBackwardsCompat(recordInDashboard: shouldRecord, tag: tag).init().test()
String minVersionToTest
if (options.minVersion && options.minVersion instanceof String) {
minVersionToTest = options.minVersion
}
new TestClientLibsBackwardsCompat(recordInDashboard: shouldRecord, tag: tag, minVersionToTest: minVersionToTest).init().test()
}
private TitlePrinter titlePrinter = new TitlePrinter()
@@ -41,6 +47,7 @@ class TestClientLibsBackwardsCompat {
private String serviceName = "skills-service"
boolean recordInDashboard = false
String tag
String minVersionToTest
TestClientLibsBackwardsCompat init() {
JsonSlurper jsonSlurper = new JsonSlurper()
@@ -57,7 +64,7 @@ class TestClientLibsBackwardsCompat {
}
void test() {
List<String> versions = getBackendVersionsToTest()
List<File> versions = getBackendVersionsToTest()
CypressTestsHelper cypressTestsHelper = new CypressTestsHelper(e2eDir: e2eDir, recordInDashboard: recordInDashboard, tag: "'${tag}'")
versions.each { File versionFile ->
titlePrinter.printTitle("Testing against skills-service version [${versionFile.name}]")
@@ -105,7 +112,8 @@ class TestClientLibsBackwardsCompat {
}
}
versions = versions.sort({ it.name })
titlePrinter.printTitle("Backend versions to test:\n ${versions.join('\n ')}\n")
return versions
List<File> versionsToTest = new NextVersionHelper().getVersionsToTest(minVersionToTest, versions)
titlePrinter.printTitle("Backend versions to test:\n ${versionsToTest.join('\n ')}\n")
return versionsToTest
}
}
@@ -19,25 +19,17 @@ import groovy.cli.picocli.CliBuilder
import groovy.json.JsonOutput
import groovy.util.logging.Slf4j
import org.apache.commons.io.FileUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.core.io.Resource
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
import org.springframework.core.io.support.ResourcePatternResolver
@Slf4j
class TestDashboardBackwardCompat {
static void main(String[] args) {
def cli = new CliBuilder()
cli.record(type: boolean, 'record tests in cypress dashboard')
cli.tag(type: String, 'tag to give cypress test')
def options = cli.parse(args)
def shouldRecord = options.record
String tag
if (options.tag && options.tag instanceof String) {
tag = options.tag
}
new TestDashboardBackwardCompat(recordInDashboard: shouldRecord, tag: tag).testNew()
}
@SpringBootApplication
class TestDashboardBackwardCompat implements CommandLineRunner {
File workDir = new File("./target/skills-client")
TitlePrinter titlePrinter = new TitlePrinter()
@@ -45,6 +37,27 @@ class TestDashboardBackwardCompat {
boolean recordInDashboard = false
String tag
@Autowired
Config config
static void main(String[] args) {
SpringApplication.run(TestDashboardBackwardCompat.class, args)
}
@Override
void run(String... args) {
def cli = new CliBuilder()
cli.record(type: boolean, 'record tests in cypress dashboard')
cli.tag(type: String, 'tag to give cypress test')
def options = cli.parse(args)
this.recordInDashboard = options.record
String tag
if (options.tag && options.tag instanceof String) {
this.tag = options.tag
}
this.testNew()
}
void checkoutWorkingCopy() {
if (workDir.exists()) {
FileUtils.deleteDirectory(workDir)
@@ -64,7 +77,6 @@ class TestDashboardBackwardCompat {
}
}
assert serviceJar
assert serviceJar
File dest = new File(serviceDir, serviceJar.name)
FileUtils.copyFile(serviceJar, dest)
assert dest.exists()
@@ -99,7 +111,7 @@ class TestDashboardBackwardCompat {
String tagsStrs = new ProcessRunner(loc: workDir).run("git tag").sout
assert tagsStrs
List<String> versionsToTest = tagsStrs.split("\n").toList();
List<String> versionsToTest = tagsStrs.split("\n").toList()
versionsToTest.removeAll(versionsToExclude)
log.info("Versions to test:\n ${versionsToTest.join("\n ")}")
@@ -117,13 +129,13 @@ class TestDashboardBackwardCompat {
titlePrinter.printSubTitle("[${version}]: Update package.json and prune")
intProjs.each { NpmProj intProj ->
String lookForDep = intProj.name.replaceAll("-int", "")
updatePackageJsonDeps(intProj, "@skilltree/$lookForDep", version)
String lookForDep = intProj.name.replaceAll("-int", "").replaceAll("\\d","")
updatePackageJsonDeps(intProj, "@skilltree/$lookForDep".toString(), version)
intProj.exec("npm prune")
}
titlePrinter.printSubTitle("[${version}]: Building Client Examples App")
new ProcessRunner(loc: clientIntLoc).run("mvn --batch-mode clean package")
new ProcessRunner(loc: clientIntLoc, env: getEnvWithAltJavaHome(version)).run("mvn --batch-mode clean package")
titlePrinter.printSubTitle("[${version}]: Running cypress test with")
String output = "Testing version [$version]"
@@ -132,17 +144,36 @@ class TestDashboardBackwardCompat {
}
}
private void updatePackageJsonDeps(NpmProj packageToChange, String depName, String version) {
List<String> getEnvWithAltJavaHome(String version) {
String altJavaHomeEnv = config?.versionProps?.find {it.version == version}?.altJavaHomeEnv
if (altJavaHomeEnv) {
log.info("Using alternative JAVA_HOME [${altJavaHomeEnv}]")
Map<String, String> currentEnv = new HashMap<>(System.getenv())
String javaHomeAlt = currentEnv.get(altJavaHomeEnv)
assert javaHomeAlt, "Failed to find expected JAVA_HOME alternative env variable [${altJavaHomeEnv}]. Current env: ${currentEnv}"
log.info("Setting alternative JAVA_HOME to [${javaHomeAlt}]")
currentEnv.put('JAVA_HOME', javaHomeAlt)
return currentEnv.collect {key, value -> "${key}=${value}"}
} else {
return [] // inherit env from parent process
}
}
void updatePackageJsonDeps(NpmProj packageToChange, String depName, String version) {
assert packageToChange && depName && version
def json = packageToChange.getPackageJson()
json.dependencies."${depName}" = version
String jsonToSave = JsonOutput.prettyPrint(JsonOutput.toJson(json))
File f = new File(packageToChange.loc, "package.json")
assert f.exists()
f.write(jsonToSave)
if (json.dependencies."${depName}") {
json.dependencies."${depName}" = version
String jsonToSave = JsonOutput.prettyPrint(JsonOutput.toJson(json))
File f = new File(packageToChange.loc, "package.json")
assert f.exists()
f.write(jsonToSave)
// sanity check
assert packageToChange.packageJson.dependencies."${depName}" == version
// sanity check
assert packageToChange.packageJson.dependencies."${depName}" == version
} else {
throw new RuntimeException("[$depName] not foundin package.json [${packageToChange.loc}]")
}
}
}
@@ -16,6 +16,8 @@ limitations under the License.
package skills.helpers
import com.vdurmont.semver4j.Semver
import groovy.transform.Sortable
import org.apache.commons.lang3.StringUtils
class NextVersionHelper {
ScriptParamsHelper.ReleaseMode releaseMode
@@ -38,4 +40,36 @@ class NextVersionHelper {
}
newVersion
}
// returns on the most recent patch version for each unique major.minor version and exclude and version < minVersion
List<File> getVersionsToTest(String minVersion, List<File> jarFiles) {
Semver minVersionToTest = new Semver(minVersion)
List<File> versionsToTest = []
List<FileWithVersion> filesWithVersion = []
jarFiles.each { jarFile ->
String version = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(jarFile.name, '-'), '.')
if (new Semver(version).isGreaterThanOrEqualTo(minVersionToTest)) {
filesWithVersion.add(new FileWithVersion(file: jarFile, version: new Semver(version)))
}
}
if (filesWithVersion) {
filesWithVersion = filesWithVersion.toSorted()
FileWithVersion last
filesWithVersion.each {
if (last != null && (it.version.major != last.version.major || it.version.minor != last.version.minor)) {
versionsToTest.add(last.file)
}
last = it
}
versionsToTest.add(last.file)
}
return versionsToTest
}
@Sortable(excludes = ['file'])
static class FileWithVersion {
Semver version
File file
}
}
@@ -0,0 +1,35 @@
skills:
versionProps:
-
version: 2.0.1
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.0.0
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.0.1
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.1.0
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.1.1
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.2.0
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.3.0
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.3.1
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.4.0
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.4.1
altJavaHomeEnv: JAVA_HOME_11_X64
-
version: 3.5.0
altJavaHomeEnv: JAVA_HOME_11_X64
@@ -9,8 +9,21 @@ index 745a168..90d231c 100755
- <node.version>v11.6.0</node.version>
+ <node.version>v14.15.0</node.version>
</properties>
<distributionManagement>
diff --git a/skills-client-integration/skills-int-client-vue/package.json b/skills-client-integration/skills-int-client-vue/package.json
index 046ba82..127b69b 100644
--- a/skills-client-integration/skills-int-client-vue/package.json
+++ b/skills-client-integration/skills-int-client-vue/package.json
@@ -5,7 +5,7 @@
"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",
+ "licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-2-Clause;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 ",
diff --git a/skills-client-integration/skills-int-e2e-test/cypress.json b/skills-client-integration/skills-int-e2e-test/cypress.json
index 52f9451..a87626c 100644
--- a/skills-client-integration/skills-int-e2e-test/cypress.json
@@ -39,7 +52,7 @@ index 2b73362..2787c53 100644
+ .and("equal", "rgba(0, 0, 0, 0)");
});
});
@@ -175,7 +175,7 @@ context("Native JS Tests", () => {
cy.wrap(body)
.find(".skills-page-title-text-color")
@@ -48,7 +61,7 @@ index 2b73362..2787c53 100644
+ .and("equal", "rgba(0, 0, 0, 0)");
});
});
diff --git a/skills-client-integration/skills-int-e2e-test/cypress/integration/react.specs.js b/skills-client-integration/skills-int-e2e-test/cypress/integration/react.specs.js
index 1cc8b29..8e4895f 100644
--- a/skills-client-integration/skills-int-e2e-test/cypress/integration/react.specs.js
@@ -61,7 +74,7 @@ index 1cc8b29..8e4895f 100644
+ .should('have.css', 'background-color').and('equal', 'rgba(0, 0, 0, 0)');
});
})
@@ -186,7 +186,7 @@ context('React Tests', () => {
// verify that there is no background set
// cypress always validates against rgb
@@ -70,7 +83,7 @@ index 1cc8b29..8e4895f 100644
+ .should('have.css', 'background-color').and('equal', 'rgba(0, 0, 0, 0)');
})
})
diff --git a/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js b/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js
index 2283896..665e697 100644
--- a/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js
@@ -101,7 +114,7 @@ index 2283896..665e697 100644
+ .should('have.css', 'background-color').and('equal', 'rgba(0, 0, 0, 0)');
});
})
@@ -274,7 +274,7 @@ context('Vue Tests', () => {
// verify that there is no background set
// cypress always validates against rgb
@@ -110,9 +123,9 @@ index 2283896..665e697 100644
+ .should('have.css', 'background-color').and('equal', 'rgba(0, 0, 0, 0)');
})
})
diff --git a/skills-client-integration/skills-int-e2e-test/package.json b/skills-client-integration/skills-int-e2e-test/package.json
index 2dfe4e3..6d7ec41 100644
index 2dfe4e3..ff3112f 100644
--- a/skills-client-integration/skills-int-e2e-test/package.json
+++ b/skills-client-integration/skills-int-e2e-test/package.json
@@ -18,16 +18,21 @@
@@ -124,11 +137,13 @@ index 2dfe4e3..6d7ec41 100644
"backend:start": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ../../../skills-service/service/target/skills-service-*.jar",
- "backend:start:ci": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -Dlogging.level.org.springframework.web.socket=TRACE -Dlogging.level.skills.services.events.SkillEventPublisher=TRACE -Dlogging.level.org.springframework.messaging=TRACE -jar ../../skills-service/backend-*.jar",
- "backend:start:release": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ./target/servicesJars/backend-*.jar",
- "backend:waitToStart": "npx wait-port -v -t 60000 localhost:8080",
- "backend:resetDb": "java -cp ./db/h2-1.4.200.jar org.h2.tools.RunScript -url jdbc:h2:tcp://localhost:9090/mem:skills -user sa -script ./db/reset.sql",
+ "backend:start:ci": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -Dlogging.level.org.springframework.web.socket=TRACE -Dlogging.level.skills.services.events.SkillEventPublisher=TRACE -Dlogging.level.org.springframework.messaging=TRACE -jar ../../skills-service/skills-service-*.jar",
+ "backend:start:ci:background": "mkdir -p ./target/logs && npm run backend:start:ci > ./target/logs/skills-service.out &",
+ "backend:start:release": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ./target/servicesJars/skills-service-*.jar",
"backend:waitToStart": "npx wait-port -v -t 60000 localhost:8080",
"backend:resetDb": "java -cp ./db/h2-1.4.200.jar org.h2.tools.RunScript -url jdbc:h2:tcp://localhost:9090/mem:skills -user sa -script ./db/reset.sql",
+ "backend:waitToStart": "npx wait-port -t 60000 localhost:8080",
+ "backend:resetDb": "export PGPASSWORD=skillsPassword && psql -U postgres -h localhost -d skills -f ./db/reset.sql",
+ "cyServices:start:skills-service:ci": "npm run backend:start:ci:background && npm run backend:waitToStart && echo 'skill-service started!!'",
+ "cyServices:start:integration-apps": "npm run integration:start:background && npm run integration:waitToStart && echo 'integration apps started!!'",
+ "cyServices:kill": "for procid in $(ps -aux | grep \"serverConfigs/.*properties\" | grep \"jar$\" | awk '{print $2}'); do echo \"killing ${procid}\"; kill -9 $procid; done",
@@ -175,6 +190,24 @@ index 10d22b8..f28ba3e 100644
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>semver4j</artifactId>
diff --git a/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties b/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties
index f193eb2..e83910b 100644
--- a/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties
+++ b/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties
@@ -11,10 +11,9 @@
# 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.
-spring.datasource.url=jdbc:h2:mem:skills
-spring.datasource.driverClassName=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
+spring.datasource.username = postgres
+spring.datasource.url = jdbc:postgresql://localhost:5432/skills
+spring.datasource.password = skillsPassword
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
logging.level.org.springframework.security.web.access.intercept.FilterSecurityInterceptor=DEBUG
diff --git a/skills-client-integration/skills-int-e2e-test/src/main/groovy/skills/DownloadServiceJars.groovy b/skills-client-integration/skills-int-e2e-test/src/main/groovy/skills/DownloadServiceJars.groovy
index 80ed5f3..ad2889c 100644
--- a/skills-client-integration/skills-int-e2e-test/src/main/groovy/skills/DownloadServiceJars.groovy
@@ -182,16 +215,16 @@ index 80ed5f3..ad2889c 100644
@@ -15,7 +15,7 @@ limitations under the License.
*/
package skills
-import callStack.profiler.Profile
+//import callStack.profiler.Profile
import groovy.util.logging.Slf4j
import org.apache.commons.io.FileUtils
@@ -29,7 +29,7 @@ class DownloadServiceJars {
// internal
TitlePrinter titlePrinter = new TitlePrinter()
- @Profile
+ // @Profile
void cleanOutputDir(){
@@ -200,7 +233,7 @@ index 80ed5f3..ad2889c 100644
@@ -40,7 +40,7 @@ class DownloadServiceJars {
// outputDir.mkdirs()
}
- @Profile
+ //@Profile
void remove(String artifact, String version) {
@@ -209,7 +242,7 @@ index 80ed5f3..ad2889c 100644
@@ -49,7 +49,7 @@ class DownloadServiceJars {
}
}
- @Profile
+ //@Profile
void download(String artifact, String version) {
@@ -222,16 +255,16 @@ index 168e90d..ea13f9c 100644
@@ -15,7 +15,7 @@ limitations under the License.
*/
package skills
-import callStack.profiler.Profile
+//import callStack.profiler.Profile
import groovy.util.logging.Slf4j
@Slf4j
@@ -57,7 +57,7 @@ class NpmProjBuilder {
}
}
- @Profile
+ // @Profile
List<NpmProj> build() {
@@ -244,16 +277,16 @@ index 4b8ba60..724ca5b 100644
@@ -15,7 +15,7 @@ limitations under the License.
*/
package skills
-import callStack.profiler.Profile
+//import callStack.profiler.Profile
import groovy.util.logging.Slf4j
import org.apache.commons.io.FileUtils
@@ -39,7 +39,7 @@ class ProjectsOps {
new File(workDir, "skills-client")
}
- @Profile
+ // @Profile
private void clearWorkDir() {
@@ -262,7 +295,7 @@ index 4b8ba60..724ca5b 100644
@@ -51,7 +51,7 @@ class ProjectsOps {
workDir.mkdirs()
}
- @Profile
+ // @Profile
void checkoutLinkedNpmLibs(String switchToBranch = null) {
@@ -270,8 +303,8 @@ index 4b8ba60..724ca5b 100644
titlePrinter.printTitle("Checkout skills-client")
@@ -68,7 +68,7 @@ class ProjectsOps {
}
- @Profile
+ //@Profile
void buildClientIntApp() {
@@ -279,8 +312,8 @@ index 4b8ba60..724ca5b 100644
File loc = new File(skillsClient, "skills-client-integration")
@@ -76,7 +76,7 @@ class ProjectsOps {
}
- @Profile
+ //@Profile
void runCypressTests(File location, String msg, List<String> cypressEnv = [], String npmIntegrationNamespace = "integration") {
@@ -293,14 +326,14 @@ index 0193982..cfad14d 100644
@@ -15,8 +15,8 @@ limitations under the License.
*/
package skills
-import callStack.profiler.CProf
-import callStack.profiler.Profile
+//import callStack.profiler.CProf
+//import callStack.profiler.Profile
import groovy.util.logging.Slf4j
import org.apache.commons.io.FileUtils
@@ -29,7 +29,7 @@ class SetupNpmLinks {
static void main(String[] args) {
boolean shouldPrune = args.find({ it.equalsIgnoreCase("--prune") })
@@ -308,12 +341,12 @@ index 0193982..cfad14d 100644
- log.info("Execution Prof:\n{}", CProf.prettyPrint())
+ //log.info("Execution Prof:\n{}", CProf.prettyPrint())
}
// configure
@@ -44,7 +44,7 @@ class SetupNpmLinks {
return this
}
- @Profile
+ // @Profile
void doLink() {
@@ -322,7 +355,7 @@ index 0193982..cfad14d 100644
@@ -57,7 +57,7 @@ class SetupNpmLinks {
build()
}
- @Profile
+ //@Profile
void removeAnyExistingLinks() {
@@ -331,7 +364,7 @@ index 0193982..cfad14d 100644
@@ -78,7 +78,7 @@ class SetupNpmLinks {
}
}
- @Profile
+ //@Profile
private void build() {
@@ -340,7 +373,7 @@ index 0193982..cfad14d 100644
@@ -86,7 +86,7 @@ class SetupNpmLinks {
}
}
- @Profile
+ //@Profile
private void validateLinks() {
@@ -349,7 +382,7 @@ index 0193982..cfad14d 100644
@@ -106,7 +106,7 @@ class SetupNpmLinks {
}
}
- @Profile
+ // @Profile
private void npmLinkToSkills() {
@@ -358,7 +391,7 @@ index 0193982..cfad14d 100644
@@ -117,7 +117,7 @@ class SetupNpmLinks {
}
}
- @Profile
+ //@Profile
private void npmLinkToReact() {
@@ -367,7 +400,7 @@ index 0193982..cfad14d 100644
@@ -127,7 +127,7 @@ class SetupNpmLinks {
}
}
- @Profile
+ //@Profile
private void createLinks() {
@@ -376,7 +409,7 @@ index 0193982..cfad14d 100644
@@ -138,7 +138,7 @@ class SetupNpmLinks {
}
}
- @Profile
+ //@Profile
private void npmInstall() {
@@ -389,7 +422,7 @@ index 55c9c7c..d399b1b 100644
@@ -15,8 +15,8 @@ limitations under the License.
*/
package skills
-import callStack.profiler.CProf
-import callStack.profiler.Profile
+//import callStack.profiler.CProf
@@ -400,9 +433,9 @@ index 55c9c7c..d399b1b 100644
@@ -64,7 +64,7 @@ class TestDashboardBackwardCompat {
log.info("Profile \n{}", CProf.prettyPrint())
}
- @Profile
+ // @Profile
private void doTest() {
titlePrinter.printTitle("Release Dashboard")
@@ -18,6 +18,19 @@ index ed5628a..d21af9c 100644
-}
\ No newline at end of file
+}
diff --git a/skills-client-integration/skills-int-client-vue/package.json b/skills-client-integration/skills-int-client-vue/package.json
index f69bb27..c952b4b 100644
--- a/skills-client-integration/skills-int-client-vue/package.json
+++ b/skills-client-integration/skills-int-client-vue/package.json
@@ -6,7 +6,7 @@
"scripts": {
"serve": "vue-cli-service serve",
"buildDepsAndServe": "cd ../../skills-client-js/ && npm run build && cd ../skills-client-vue/ && npm run build && cd ../skills-client-integration/skills-int-client-vue/ && npm run serve",
- "licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-3-Clause;Apache-2.0' --summary",
+ "licenseDepCheck": "license-checker --production --onlyAllow='MIT;ISC;BSD-2-Clause;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 ",
diff --git a/skills-client-integration/skills-int-e2e-test/cypress.json b/skills-client-integration/skills-int-e2e-test/cypress.json
index 52f9451..a87626c 100644
--- a/skills-client-integration/skills-int-e2e-test/cypress.json
@@ -128,7 +141,7 @@ index d0d7a1d..3ca2982 100644
})
diff --git a/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js b/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js
index b010108..95e7b93 100644
index b010108..bd66f3a 100644
--- a/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js
+++ b/skills-client-integration/skills-int-e2e-test/cypress/integration/vue.specs.js
@@ -204,7 +204,7 @@ context('Vue Tests', () => {
@@ -167,6 +180,42 @@ index b010108..95e7b93 100644
})
})
@@ -378,7 +378,7 @@ context('Vue Tests', () => {
// navigate to Rank Overview that contains the back button
cy.wrap(body).find('[data-cy=myRank]').click();
- cy.wrap(body).contains('Rank Overview');
+ cy.wrap(body).contains('My Rank');
cy.wrap(body).find('[data-cy=back]').should('exist');
});
@@ -390,7 +390,7 @@ context('Vue Tests', () => {
cy.get('[data-cy=userDisplayLink]').click()
// cy.iframe((body) => {
// // verify we are still on the Rank Overview page
- // cy.wrap(body).contains('Rank Overview');
+ // cy.wrap(body).contains('My Rank');
//
// // click the back button and verify that we are still in the
// // client display (main page), and not on the "Report Skills" page
@@ -419,7 +419,7 @@ context('Vue Tests', () => {
// navigate to Rank Overview that contains the back button
cy.wrap(body).find('[data-cy=myRank]').click();
- cy.wrap(body).contains('Rank Overview');
+ cy.wrap(body).contains('My Rank');
cy.wrap(body).find('[data-cy=back]').should('exist');
});
@@ -431,7 +431,7 @@ context('Vue Tests', () => {
cy.get('[data-cy=userDisplayLink]').click()
cy.iframe((body) => {
// verify we are still on the Rank Overview page
- cy.wrap(body).contains('Rank Overview');
+ cy.wrap(body).contains('My Rank');
// click the back button and verify that we are still in the
// client display (Subject page)
diff --git a/skills-client-integration/skills-int-e2e-test/cypress/support/commands.js b/skills-client-integration/skills-int-e2e-test/cypress/support/commands.js
index 6a65d80..689aa4f 100644
--- a/skills-client-integration/skills-int-e2e-test/cypress/support/commands.js
@@ -181,9 +230,20 @@ index 6a65d80..689aa4f 100644
// back button should not exist on the home page, whose title is the default value
if (expectedTitle === 'User Skills'){
diff --git a/skills-client-integration/skills-int-e2e-test/package.json b/skills-client-integration/skills-int-e2e-test/package.json
index 8664332..7209ea6 100644
index 8664332..5bedcd4 100644
--- a/skills-client-integration/skills-int-e2e-test/package.json
+++ b/skills-client-integration/skills-int-e2e-test/package.json
@@ -26,8 +26,8 @@
"backend:start:ci": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ../../skills-service/skills-service-*.jar",
"backend:start:ci:background": "mkdir -p ./target/logs && npm run backend:start:ci > ./target/logs/skills-service.out &",
"backend:start:release": "java -Dspring.config.location=classpath:/application.yml,file:serverConfigs/backend_application.properties -jar ./target/servicesJars/skills-service-*.jar",
- "backend:waitToStart": "npx wait-port -v -t 60000 localhost:8080",
- "backend:resetDb": "java -cp ./db/h2-1.4.200.jar org.h2.tools.RunScript -url jdbc:h2:tcp://localhost:9090/mem:skills -user sa -script ./db/reset.sql",
+ "backend:waitToStart": "npx wait-port -t 60000 localhost:8080",
+ "backend:resetDb": "export PGPASSWORD=skillsPassword && psql -U postgres -h localhost -d skills -f ./db/reset.sql",
"release": "release-it --dry-run",
"cyServices:start:skills-service": "npm run backend:start:background && npm run backend:waitToStart && echo 'skill-service started!!'",
"cyServices:start:skills-service:ci": "npm run backend:start:ci:background && npm run backend:waitToStart && echo 'skill-service started!!'",
@@ -38,7 +38,7 @@
"dev:removeNpmLinks": "mvn --batch-mode clean package && java -cp target/skills-int-e2e-test-*.jar -Dloader.main=skills.RemoveNpmLinks org.springframework.boot.loader.PropertiesLauncher"
},
@@ -193,3 +253,21 @@ index 8664332..7209ea6 100644
"license-check-and-add": "3.0.4",
"license-checker": "25.0.1",
"semver": "7.1.2",
diff --git a/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties b/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties
index ae6bbb4..7b4bf1b 100644
--- a/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties
+++ b/skills-client-integration/skills-int-e2e-test/serverConfigs/backend_application.properties
@@ -11,10 +11,9 @@
# 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.
-spring.datasource.url=jdbc:h2:mem:skills
-spring.datasource.driverClassName=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
+spring.datasource.username = postgres
+spring.datasource.url = jdbc:postgresql://localhost:5432/skills
+spring.datasource.password = skillsPassword
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
logging.level.org.springframework.security.web.access.intercept.FilterSecurityInterceptor=DEBUG
Loaded 100 of 134 files, more files were not shown because too many files have changed in this diff. Show more