Contribution guidelines are currently a work-in-progress. Developer documentation can be found below.
@TODO
@TODO
@TODO
@TODO
@TODO
All relevant application-specific environment configurations (e.g. URLs, namespaces, etc.) are outlined here: https://docs.jboss.org/display/RHVCS/Environments.
@TODO
@TODO
Note: You must be on VPN to connect to hosted services
You can run the following commands to get your system ready for development:
# Clone the git repository
git clone https://github.com/VCS-Collection-System/frontend.git
# Go to the git repository directory
cd vcs-frontend
# Create a directory named public if it doesn't already exist
mkdir public The values in the config.js and the keycloak.json correspond to the yaml in the vcs-frontend-config repo. You will likely update these files (specifically the config.js file) when you are turning features on/off for specific regions. Your local config files should not be checked into vcs-frontend.
Running the following will populatate your keycloak.json file:
cat << EOF > keycloak/keycloak.json
{
"auth-server-url": "https://auth.test.vcs.example.com/auth",
"realm": "rhvcs-devtest",
"resource": "rhvcs-frontend-devtest"
}
EOFRunning the following will populate your config.js file: @TODO: Move to external example file
cat << EOF > public/config.js
window.REACT_APP_PAM_URL_BASE="https://api.example.com"
window.REACT_APP_PAM_USER=""
window.REACT_APP_PAM_PASSWORD=""
window.REACT_APP_KEYCLOAK_COUNTRY="attributes.agency[0]"
window.REACT_APP_KEYCLOAK_EMAIL="email"
window.REACT_APP_KEYCLOAK_FIRST_NAME="firstName"
window.REACT_APP_KEYCLOAK_GEO="Geo"
window.REACT_APP_KEYCLOAK_ID="attributes.workforceid[0]"
window.REACT_APP_KEYCLOAK_LAST_NAME="lastName"
window.REACT_APP_KEYCLOAK_TITLE="JobTitle"
window.REACT_APP_KEYCLOAK_TYPE="PersonType"
window.REACT_APP_FEATURE_FLAGS=[{see below}]
window.REACT_APP_MAX_DOSES={"AstraZeneca":2,"Comirnaty":2,"Covaxin":2,"Covishield":2,"Covovax":2,"Janssen":1,"Johnson":1,"Moderna":2,"Novavax":2,"Oxford":2,"Pfizer":2,"Sinopharm":2,"Sinovac_Coronavac":2,"Spikevax":2,"Sputnik":2,"Vaxzevria":2}
window.REACT_APP_ALTERNATE_CONSENT_LABEL="By checking this box, I agree that I am voluntarily providing my COVID-19 3G status (vaccinated/recovered/tested) to [COMPANY], and I agree that [COMPANY] may collect, process, and record my COVID-19 3G status, including the submission and validity dates, for the purposes and as described in [COMPANY]'s COVID-19 and VCS Privacy Notice (e.g., for protection of health and safety, resource and team planning, and complying with legal requirements), which includes further information about the processing of my personal data (including the retention and recipients of my personal data) and my rights as outlined in [COMPANY]'s Employee Personal Information Privacy Statement."
window.REACT_APP_CONSENT_LABEL="By checking, I agree to the collection and processing of my COVID-19 related information for the purposes set forth in [COMPANY]'s COVID-19 and VCS Privacy Notice, which also includes further information about the processing of my personal data including my relevant rights as described in the referenced Employee Personal Information Privacy Statement."
window.REACT_APP_BLOCKED_COUNTRIES=[]
window.INJECTED_VIA_CONFIG_MAP="true"
window.REACT_APP_GLOBAL_CONFIG={{
"AUS": {"dateOfBirth": true, "proof": false, "proofType": {"divoc": false}, "recovery": false},
"AUT": {"consentCheckboxAlternate": true, "covidTest": true, "proofType": {"divoc": false}},
"CAN": {"proofOptional": true, "recovery": false},
"CZE": {"proofOptional": true, "covidTest": true},
"DEU": {"consentCheckboxAlternate": true, "covidTest": true, "proof": false, "proofType": {"divoc": false}},
"ESP": {"proofOptional": true},
"GBR": {"recovery": false},
"HUN": {"proofOptional": true},
"IDN": {"recovery": false},
"IND": {"dateOfBirth": true, "recovery": false},
"IRL": {"proofOptional": true, "recovery": false},
"ISR": {"recovery": false},
"ITA": {"proofOptional": true, "proofType": {"greenPass": true, "divoc": false}},
"MYS": {"recovery": false},
"NOR": {"recovery": false},
"NZL": {"proofOptional": true, "recovery": false},
"PER": {"consentCheckbox": false},
"SAU": {"recovery": false},
"SGP": {"consentCheckbox": false, "dateOfBirth": true, "proofType": {"divoc": false}, "recovery": false},
"SVK": {"proofOptional": true},
"TWN": {"proofOptional": true},
"USA": {"consentCheckbox": false, "dateOfBirth": true, "proofType": {"cdcvax": true, "divoc": false}, "recovery": false},
"UAT": {"allowPdf": true, "dateOfBirth": true, "consentCheckbox": false, "consentCheckboxAlternate": false, "covidTest": true, "customInput": true, "hrdashboard": true, "hrsearch": true, "proofType": {"cdcvax": true, "divoc": true, "greenPass": true}, "recovery": true},
"default": {"allowPdf": false, "dateOfBirth": false, "consentCheckbox": true, "consentCheckboxAlternate": false, "covidTest": false, "customInput": true, "hrdashboard": true, "hrsearch": true, "proof": true, "proofOptional": false, "proofType": {"cdcvax": false, "divoc": true, "greenPass": false}, "recovery": true}
}
EOFFeature flags (the term is currently used loosely) are being utilized by the frontend to control if certain features should be rendered in the application.
The flag definitions when used locally are set in config.js and are overridden by the various environment-specific configurations
The Feature Flag mechanism is represented by an array of feature flag objects, where each object represents a specific feature.
To use any of the features, simply add the corresponding feature flag object into the window.REACT_APP_FEATURE_FLAGS in public/config.js
The structure of a feature flag object is as follows:
window.REACT_APP_FEATURE_FLAGS=[
{
"name": "featureName", // Required. Name of the feature
"active": true | false, // Required. Turns on or off the feature flag. Must be either true or false
}
]Use the following table as a guide for correctly setting the scope of your Feature Flag:
| featureFlag "active"1 | globalConfig[{userCountry}] | globalConfig[default] | scope |
|---|---|---|---|
| true | true | true | turned on for all countries |
| true | true | true | turned on for user country but off for others |
| true | false | true | turned off for user country but on for others |
| true | false | false | turned off for all countries |
| false | any | any | turned off for all countries |
- Add the feature flag to the
featureFlagobject and set the "active" value accordingly. - Add ('true') or omit ('false') to the
globalConfig.defaultobject in the format{"featureName", true/false}. - (If different than default value above) Add ('true') or omit ('false') to the
globalConfig.{userCountry}object in the format{"featureName", true/false}.
The REACT_APP_GLOBAL_CONFIG property allows for configuration of application components on a country-by-country basis, since specific application requirements can differ based on which country the user is located in. It is represented by an object of country keys and their associated config values. The final "country" in the configuration is the default configuration which represents default config for any country/property not explicitly defined elsewhere in the GLOBAL_CONFIG property.
To use any of these features, add it to window.REACT_APP_FEATURE_FLAGS in public/config.js:
When true, this property allows PDF files to be submitted as vaccine documentation proof.
When true, this property displays the consent disclaimer checkbox on the vaccine form.
When true, this property displays the alternate consent disclaimer checkbox on the vaccine form (defined by window.REACT_APP_ALTERNATE_CONSENT_LABEL).
When true, this property enables the COVID test form.
When true, this property displays the Date of Birth field on vaccine and test/recovery forms.
When true, this property enables the HR Dashboard.
When true, this property enables an HR user to search for a user by user ID on the HR Dashboard.
When true, this property displays the Proof Type dropdown and Proof Image Upload fields on the vaccine form.
When true, this property makes the Proof Type dropdown and Proof Image fields optional on the vaccine form.
This property is not applicable when the proof property is false.
This property expects an object of proof type keys, either enabled (true) or disabled (false). Available proof types are:
cdc (CDC Vaccination Card)
divoc (Digital Certificate of Vaccination)
greenPass (Green Pass)
Proof type "Other" is always available for all countries.
This feature exposes the capability to submit Certificates of Recovery.
{
"name": "recovery",
"active": true
}To find the appropriate country code to use in config.js, see https://spaces.redhat.com/display/RHVCS/Test+Users
Run the following commands to perform various build activities:
# Install development/build dependencies
npm install
# Start the development server
# This will open a browser window to `localhost:9000`
# It is highly recommended to open an incognito window and navigate to `localhost:9000` instead of using the default window session
npm run start:dev
# Run a production build (outputs to "dist" dir; rarely performed locally)
npm run buildTo run various tests, choose from the commands below:
# Run the full test suite including unit tests, linting, etc. (always a good idea before making commits)
npm run test
# Run a specific test
npm run test -- -t 'SPECIFIC_TEST_NAME'
Example: `npm run test -- -t '<EmployeeInfoCard />'
# Run the test suite with coverage
npm run test:coverage
# Run the linter
npm run lint
# Run the code formatter
npm run format
# Launch a tool to inspect the bundle size
npm run bundle-profile:analyze
# Start the express server (run a production build first)
npm run startTo prevent accidental pushes of untested code, the team has added a Husky pre-push hook that ensures that all unit tests first pass before completing the git push action.
There might be times when this functionality needs to be quickly overcome. Simply run git push --no-verify and your code will not be checked via the pre-push hook.
⚠️ Ask yourself if this is really necessary: You might be able to achieve the same level of testing using your browser's Device Emulation feature in Developer Tools.
If you would like to view the application on another device on your network (e.g. mobile device testing), you will need to do a few things:
Update the HOST variable in webpack.dev.js from localhost to 0.0.0.0
Open the firewall port the application is served on...
sudo systemctl start firewalld
export PORT=9000
sudo firewall-cmd --zone=public --add-port=${PORT}/tcp
Ensure that the Keycloak instance is configured to receive requests from your deployment URL. In the past this was localhost, but is likely now ${YOUR_IP}. The easiest way to do this is to change the setting in Keycloak to allow from all origins (*). However, this is inherently insecure. A better approach is to have your IP or domain added explicitly. This may be difficult/impossible to do if you do not manage the Keycloak instance, in which case you're out of luck.
git clone <repo>
cd vcs-frontend
./test_resources/prep_test_env.sh
./test_resources/run_tests.sh- Selenium - Browser based UI test automation
- Mocha - JavaScript test framework running on Node.js
- Allure - Test output visualization. Jenkins plugin available to get the reports directly in Jenkins attached to the builds.
Environment Variables that are required:
APP_ROUTE:Application Under Test Base UrlWEB_DRIVER_URL:Selenium Grid URLBROWSER:chromeorfirefoxUSER1:Non-privileged usernameUSER1_PASS:USER1 passwordUSER2:Username with HR Approver roleUSER2_PASS:USER2 password
For example, if running locally you should set these in the terminal window where the test command will be executed via export APP_ROUTE=my.vcs.deployment.com
Invoke tests via Mocha. Tests are discovered in ./test
# Execute tests
./node_modules/mocha/bin/mocha
# Execute a specific test
./node_modules/mocha/bin/mocha ./test/example.spec.js
# Execute tests and generate allure report data
./node_modules/mocha/bin/mocha --reporter mocha-allure-reporter
Leverage the Selenium IDE browser extension as a base for you tests. This can be downloaded selenium ide. This tool will allow you to record test scripts and export them in a variety of languages.
In order to create a test:
- Record a script with your desired test case.
- Right click on the name of the test and select "export". For this project export as
JavaScript - Mocha. - Save your file to the
./testdirectory - Run the
./test_resources/fix_export.shscript against the exported file - Set the environment variables for user logins.
export USER1="<user1>"
export USER1_PASS="<user1pass>"
export USER2="<user2>"
export USER2_PASS="<user2pass>"USER1 will be used to submit a new vaccine document whileUSER2 will search for this new submission and approve it via the HR Dashboard. At a minimum USER2 will need to have the ability to access the HR Dashboard for the successful completion of selenium test.
By default the tests will run against the WEB_DRIVER_URL. In order to execute the tests on your local machine (which can be helpful for debugging purposes) you will need to do the following:
Command line changes
npm install chromedriver
npm install geckodriverNote: If running on a machine where managed by Corporate IT (e.g. RHEL CSB) you will need to pay attention to your pre-installed Google Chrome version. For chromedriver the version installed needs to matches the Chrome version that's already on your system. If Corporate IT manages this installation you may be behind the latest version (e.g.
96) and should take the following actions:
- First, determine your Chrome version: Open Chrome -> Open the Three-Dot Menu -> Select Help -> Choose About Google Chrome. This will show you your Chrome version (e.g.
Version 95.0.4638.69 (Official Build) (64-bit)).- Next, remove any existing chromedriver installations:
npm remove chromedriver- Finally, install the chromedriver that matches the latest version of your Chrome installation:
CHROMEDRIVER_VERSION=LATEST_95 npm install chromedriver
Changes to .js files
Additional libraries need to be included for local test execution. Specifically the browser drivers. For local execution you need to add either the chromedriver or geckodriver npm libraries.
// For local
require("chromedriver");The way the selenium web driver gets instantiated needs to change from:
// For Selenium Grid
driver = new Builder().forBrowser(globals.browser).usingServer(globals.webDriverUrl).build()
driver.setFileDetector(new remote.FileDetector());To:
// For local
driver = new webdriver.Builder().forBrowser(globals.browser).build();NOTE: In the future it would be nice to figure out a way to have these implementations switched via an environment variable
The output of running the Mocha tests is a raw data file for Allure. From this output you can then generate the reports.
The export will put all test steps into a single test case. To provide more granular reporting we want to break these up into multiple test cases.
describefunction should wrap entire test caseitfunction should label each step
See ./test/e2e.spec.js
When you run the mocha tests with the --reporter mocha-allure-reporter parameter you will end up with the allure report data in a raw format. To generate the report dashboard from this data you can run the following:
# Use Allure CLI to generate the usable Reports which are saved to ./allure-report
./node_modules/allure-commandline/bin/allure generate allure-results --clean -o allure-reportTo start a node server locally to view the reports you can run:
# Spins up a node server to host the generated report, and opens your default browser to it.
./node_modules/allure-commandline/bin/allure open@TODO
@TODO
If you need an account to access the internal Keycloak instance, reach out to @HunterGerlach. He can help get you a Keycloak account created for use during development.