Skip to content

Commit

Permalink
feat(#7462) add cht-form web component for standalone Enketo form sup…
Browse files Browse the repository at this point in the history
…port (#8153)

Co-authored-by: Mokhtar <[email protected]>
Co-authored-by: Tatiana Lépiz <[email protected]>
Co-authored-by: tatilepizs <[email protected]>
  • Loading branch information
4 people authored Nov 22, 2023
1 parent 1332879 commit 15bd199
Show file tree
Hide file tree
Showing 87 changed files with 5,337 additions and 609 deletions.
19 changes: 18 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,23 @@ jobs:
- name: Run Tests
run: npm run ${{ matrix.cmd }}

test-cht-form:
needs: build
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v3
- name: Use Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
- run: sudo apt-get install -y xsltproc
- run: npm ci
- name: Build cht-form Web Component
run: npm run build-cht-form
- name: Run Tests
run: npm run wdio-cht-form

tests:
needs: build
name: ${{ matrix.cmd }}-${{ matrix.suite || '' }}${{ matrix.chrome-version == '90' && '-minimum-browser' || '' }}
Expand Down Expand Up @@ -247,7 +264,7 @@ jobs:
if: ${{ failure() }}

publish:
needs: [tests, config-tests]
needs: [tests, config-tests, test-cht-form]
name: Publish branch build
runs-on: ubuntu-22.04
if: ${{ github.event_name != 'pull_request' }}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"build-dev-watch": "npm run build-dev && cd webapp && npm run build -- --configuration=development --watch=true & node ./scripts/build/watch.js",
"build-documentation": "./scripts/build/build-documentation.sh",
"build-webapp-dev": "cd webapp && npm run build -- --configuration=development && npm run compile",
"build-cht-form": "./scripts/build/build-prepare.sh && cd webapp && npm run build:cht-form",
"copy-api-resources": "cp -r api/src/public/* api/build/static/",
"dev-api": "./scripts/build/copy-static-files.sh && TZ=UTC nodemon --inspect=0.0.0.0:9229 --ignore 'api/build/static' --ignore 'api/build/public' --watch api --watch 'shared-libs/**/src/**' api/server.js -- --allow-cors",
"dev-sentinel": "TZ=UTC nodemon --inspect=0.0.0.0:9228 --watch sentinel --watch 'shared-libs/**/src/**' sentinel/server.js",
Expand All @@ -40,11 +41,12 @@
"unit-api": "UNIT_TEST_ENV=1 mocha 'api/tests/mocha/**/*.js'",
"unit-sentinel": "UNIT_TEST_ENV=1 mocha 'sentinel/tests/**/*.js'",
"unit-shared-lib": "UNIT_TEST_ENV=1 npm test --workspaces --if-present",
"unit-webapp": "UNIT_TEST_ENV=1 mocha 'webapp/tests/mocha/**/*.spec.js' && cd webapp && npm run unit -- --watch=false",
"unit-webapp": "UNIT_TEST_ENV=1 mocha 'webapp/tests/mocha/**/*.spec.js' && cd webapp && npm run unit -- --watch=false && npm run unit:cht-form -- --watch=false",
"unit-webapp-continuous": "cd webapp && npm run unit -- --watch=true",
"unit-nginx": "cd nginx/tests && make test",
"unit-haproxy": "cd haproxy/tests && make test",
"wdio-local": "export VERSION=$(node ./scripts/build/get-version.js) && ./scripts/build/build-service-images.sh && wdio run ./tests/e2e/default/wdio.conf.js",
"wdio-cht-form": "wdio run ./tests/e2e/cht-form/wdio.conf.js",
"-- CI SCRIPTS ": "-----------------------------------------------------------------------------------------------",
"build": "./scripts/build/build-ci.sh",
"ci-compile": "node scripts/ci/check-versions.js && node scripts/build/cli npmCiModules && npm run lint && npm run build && npm run integration-api && npm run unit && npm run unit-nginx && npm run unit-haproxy",
Expand Down
4 changes: 4 additions & 0 deletions scripts/build/build-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ echo "build-ci: building webapp"
cd webapp
npm run build -- --configuration=production
npm run compile

echo "build-ci: building cht-form"
npm run build:cht-form -- --configuration=production

cd ..

node ./scripts/build/cli createStagingDoc
Expand Down
60 changes: 60 additions & 0 deletions tests/e2e/cht-form/default/death-report.wdio-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const mockConfig = require('../mock-config');
const moment = require('moment');
const deathReportForm = require('@page-objects/default/enketo/death-report.page');
const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page');

describe('cht-form web component - Death Report Form', () => {

it('should submit a death report', async () => {
await mockConfig.loadForm('default', 'app', 'death_report');

await browser.execute(() => {
const myForm = document.getElementById('myform');
myForm.content = { contact: { _id: '12345'} };
});

const date = moment().format('YYYY-MM-DD');
const deathNote = 'Test note';
const title = await genericForm.getFormTitle();
expect(title).to.equal('Death report');

await deathReportForm.selectDeathPlace(deathReportForm.PLACE_OF_DEATH.healthFacility);
await deathReportForm.setDeathInformation(deathNote);
await deathReportForm.setDeathDate(date);
await genericForm.nextPage();

const {deathDate, deathInformation} = await deathReportForm.getSummaryDetails();
expect(deathDate).to.equal(date);
expect(deathInformation).to.equal(deathNote);

const [doc, ...additionalDocs] = await mockConfig.submitForm();
const jsonObj = doc.fields.death_details;

expect(additionalDocs).to.be.empty;

expect(jsonObj.date_of_death).to.equal(date);
expect(jsonObj.death_information).to.equal(deathNote);
expect(jsonObj.place_of_death).to.equal(deathReportForm.PLACE_OF_DEATH.healthFacility);
});

it('should render form in the language set for the user', async () => {
await mockConfig.loadForm('default', 'test', 'death_report_es');

await browser.execute(() => {
const myForm = document.getElementById('myform');
myForm.content = { contact: { _id: '12345', name: 'John' } };
myForm.user = { language: 'es' };
});

const labelsValues = await deathReportForm.getLabelsValues();
expect(labelsValues.details).to.equal('Detalles del fallecimiento');
expect(labelsValues.date).to.equal('Fecha del fallecimiento');
expect(labelsValues.place).to.equal('Lugar del fallecimiento');
expect(labelsValues.healthFacility).to.equal('Centro de salud');
expect(labelsValues.home).to.equal('Casa');
expect(labelsValues.other).to.equal('Otro');
expect(labelsValues.notes)
.to.equal('Provea cualquier información relevante relacionada con el fallecimiento de John.');
});

});
139 changes: 139 additions & 0 deletions tests/e2e/cht-form/default/delivery.wdio-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
const mockConfig = require('../mock-config');
const moment = require('moment');
const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page');
const deliveryForm = require('@page-objects/default/enketo/delivery.wdio.page');

describe('cht-form web component - Delivery Form', () => {
const DATE = moment().format('YYYY-MM-DD');

it('should submit a delivery - Alive mother and baby', async () => {
await mockConfig.loadForm('default', 'app', 'delivery');

await browser.execute(() => {
const myForm = document.getElementById('myform');
myForm.contactSummary = { pregnancy_uuid: 'test UUID' };
myForm.content = { contact: { _id: '12345', patient_id: '79376', name: 'Pregnant Woman' } };
});

const BABY_NAME = 'Benja';
const BABY_SEX = 'male';
const title = await genericForm.getFormTitle();
expect(title).to.equal('Delivery');

await deliveryForm.selectDeliveryConditionWomanOutcome('alive_well');
await genericForm.nextPage();
await deliveryForm.selectDeliveryPostnatalDangerSignsFever('no');
await deliveryForm.selectDeliveryPostnatalDangerSevereHeadache('no');
await deliveryForm.selectDeliveryPostnatalDangerVaginalBleeding('no');
await deliveryForm.selectDeliveryPostnatalDangerVaginalDischarge('no');
await deliveryForm.selectDeliveryPostnatalDangerConvulsion('no');

await genericForm.nextPage();
await deliveryForm.selectDeliveryOutcomeBabiesDelivered('1');
await deliveryForm.selectDeliveryOutcomeBabiesAlive('1');
await deliveryForm.selectDeliveryOutcomeDeliveryPlace('health_facility');
await deliveryForm.selectDeliveryOutcomeDeliveryMode('vaginal');
await deliveryForm.setDeliveryOutcomeDateOfDelivery(DATE);

await genericForm.nextPage();

await deliveryForm.selectDeliveryBabyCondition('alive_well');
await deliveryForm.setDeliveryBabyName(BABY_NAME);
await deliveryForm.selectDeliveryBabySex(BABY_SEX);
await deliveryForm.selectDeliveryBabyBirthWeightKnown('no');
await deliveryForm.selectDeliveryBabyBirthLengthKnown('no');
await deliveryForm.selectDeliveryBabyVaccinesReceived('none');
await deliveryForm.selectDeliveryBabyBreastfeeding('yes');
await deliveryForm.selectDeliveryBabyBreastfeedingWithin1Hour('yes');
await deliveryForm.selectDeliveryBabyInfectedUmbilicalCord('no');
await deliveryForm.selectDeliveryBabyConvulsion('no');
await deliveryForm.selectDeliveryBabyDifficultyFeeding('no');
await deliveryForm.selectDeliveryBabyVomit('no');
await deliveryForm.selectDeliveryBabyDrowsy('no');
await deliveryForm.selectDeliveryBabyStiff('no');
await deliveryForm.selectDeliveryBabyYellowSkin('no');
await deliveryForm.selectDeliveryBabyFever('no');
await deliveryForm.selectDeliveryBabyBlueSkin('no');
await genericForm.nextPage();
await genericForm.nextPage();
await deliveryForm.selectDeliveryPncVisits('none');
await genericForm.nextPage();

const summaryInfo = await deliveryForm.getSummaryInfo();
expect(summaryInfo.womanCondition).to.equal('Alive and well');
expect(summaryInfo.deliveryDate).to.equal(DATE);
expect(summaryInfo.deliveryPlace).to.equal('Health facility');
expect(summaryInfo.deliveredBabies).to.equal('1');
expect(summaryInfo.deceasedBabies).to.equal('0');
expect(summaryInfo.pncVisits).to.equal('None');

const data = await mockConfig.submitForm();
const jsonObjMother = data[0].fields;
const jsonObjBaby = data[1];

expect(jsonObjMother.patient_uuid).to.equal('12345');
expect(jsonObjMother.patient_id).to.equal('79376');
expect(jsonObjMother.patient_name).to.equal('Pregnant Woman');
expect(jsonObjMother.data.meta.__pregnancy_uuid).to.equal('test UUID');
expect(jsonObjMother.condition.woman_outcome).to.equal('alive_well');
expect(jsonObjMother.pnc_danger_sign_check.r_pnc_danger_sign_present).to.equal('no');
expect(jsonObjMother.delivery_outcome.babies_delivered).to.equal('1');
expect(jsonObjMother.delivery_outcome.babies_alive).to.equal('1');
expect(jsonObjMother.delivery_outcome.delivery_date).to.equal(DATE);
expect(jsonObjMother.delivery_outcome.delivery_place).to.equal('health_facility');
expect(jsonObjMother.delivery_outcome.delivery_mode).to.equal('vaginal');
expect(jsonObjMother.babys_condition.baby_repeat[0].baby_details.baby_condition).to.equal('alive_well');
expect(jsonObjMother.babys_condition.baby_repeat[0].baby_details.baby_name).to.equal(BABY_NAME);
expect(jsonObjMother.babys_condition.baby_repeat[0].baby_details.baby_sex).to.equal(BABY_SEX);
expect(jsonObjMother.babys_condition.r_baby_danger_sign_present_any).to.equal('no');

expect(jsonObjBaby.name).to.equal(BABY_NAME);
expect(jsonObjBaby.sex).to.equal(BABY_SEX);
expect(jsonObjBaby.date_of_birth).to.equal(DATE);
expect(jsonObjBaby.t_danger_signs_referral_follow_up).to.equal('no');
});

it('should submit a delivery - Death mother and baby', async () => {
await mockConfig.loadForm('default', 'app', 'delivery');

await browser.execute(() => {
const myForm = document.getElementById('myform');
myForm.content = { contact: { _id: '12345' } };
myForm.user = { phone: '+50689999999' };
});

const title = await genericForm.getFormTitle();
expect(title).to.equal('Delivery');

await deliveryForm.selectDeliveryConditionWomanOutcome('deceased');
await genericForm.nextPage();
await deliveryForm.fillWomanDeathInformation({
date: DATE,
place: 'health_facility',
notes: 'Test notes - Mother\'s death'
});
await $('.form-footer').click();
await genericForm.nextPage();

const data = await mockConfig.submitForm();
const jsonObjDeliveryReport = data[0].fields;
const jsonObjDeathReport = data[1];

expect(jsonObjDeliveryReport.inputs.user.phone).to.equal('+50689999999');
expect(jsonObjDeliveryReport.patient_uuid).to.equal('12345');
expect(jsonObjDeliveryReport.condition.woman_outcome).to.equal('deceased');
expect(jsonObjDeliveryReport.death_info_woman.woman_death_date).to.equal(DATE);
expect(jsonObjDeliveryReport.death_info_woman.woman_death_place).to.equal('health_facility');
expect(jsonObjDeliveryReport.death_info_woman.woman_death_birth).to.equal('no');
expect(jsonObjDeliveryReport.death_info_woman.woman_death_add_notes).to.equal('Test notes - Mother\'s death');
expect(jsonObjDeliveryReport.death_info_woman.death_report.form).to.equal('death_report');
expect(jsonObjDeliveryReport.death_info_woman.death_report.from).to.equal('+50689999999');

expect(jsonObjDeathReport.form).to.equal('death_report');
expect(jsonObjDeathReport.from).to.equal('+50689999999');
expect(jsonObjDeathReport.fields.death_details.date_of_death).to.equal(DATE);
expect(jsonObjDeathReport.fields.death_details.place_of_death).to.equal('health_facility');
expect(jsonObjDeathReport.fields.death_details.death_information).to.equal('Test notes - Mother\'s death');
});

});
99 changes: 99 additions & 0 deletions tests/e2e/cht-form/default/enketo-widgets.wdio-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const mockConfig = require('../mock-config');
const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page');
const enketoWidgetsPage = require('@page-objects/default/enketo/enketo-widgets.wdio.page');

describe('cht-form web component - Enketo Widgets', () => {

it('should submit the Enketo Widgets form', async () => {
await mockConfig.loadForm('default', 'test', 'enketo_widgets');

const title = await genericForm.getFormTitle();
expect(title).to.equal('Enketo Widgets');

await enketoWidgetsPage.openDropdown(await enketoWidgetsPage.selectMultipleDropdown());
await enketoWidgetsPage.selectDropdownOptions(await enketoWidgetsPage.selectMultipleDropdown(), 'checkbox', 'a');
await enketoWidgetsPage.selectDropdownOptions(await enketoWidgetsPage.selectMultipleDropdown(), 'checkbox', 'c');
expect(await enketoWidgetsPage.getDropdownValue(await enketoWidgetsPage.selectMultipleDropdown()))
.to.contain('numberselected');

await enketoWidgetsPage.openDropdown(await enketoWidgetsPage.selectOneDropdown());
await enketoWidgetsPage.selectDropdownOptions(await enketoWidgetsPage.selectOneDropdown(), 'radio', 'd');
expect(await enketoWidgetsPage.getDropdownValue(await enketoWidgetsPage.selectOneDropdown()))
.to.equal('option d');

// try to move to next page without filling the mandatory phone number field
await genericForm.nextPage(1, false);
expect(await enketoWidgetsPage.phoneFieldRequiredMessage().getAttribute('data-i18n'))
.to.equal('constraint.required');

// try to move to next page with an invalid phone number
await enketoWidgetsPage.setPhoneNumber('+4076');
await genericForm.nextPage(1, false);
expect(await enketoWidgetsPage.phoneFieldConstraintMessage().getAttribute('data-itext-id'))
.to.equal('/enketo_widgets/enketo_test_select/phone:jr:constraintMsg');

// finally set a valid phone number and continue
await enketoWidgetsPage.setPhoneNumber('+40766565656');

await $('.form-footer').click();
await genericForm.nextPage();

await enketoWidgetsPage.selectCountryRadio('usa');
await enketoWidgetsPage.selectCityRadio('nyc');
await enketoWidgetsPage.selectNeighborhoodRadio('bronx');
await enketoWidgetsPage.openDropdown(await enketoWidgetsPage.countryDropdown());
await enketoWidgetsPage.selectDropdownOptions(await enketoWidgetsPage.countryDropdown(), 'radio', 'nl');
await enketoWidgetsPage.openDropdown(await enketoWidgetsPage.cityDropdown());
expect(await enketoWidgetsPage.getDropdownTotalOptions(await enketoWidgetsPage.cityDropdown()))
.to.equal(3);
await enketoWidgetsPage.selectDropdownOptions(await enketoWidgetsPage.cityDropdown(), 'radio', 'dro');
await enketoWidgetsPage.openDropdown(await enketoWidgetsPage.neighborhoodDropdown());
expect(await enketoWidgetsPage.getDropdownTotalOptions(await enketoWidgetsPage.neighborhoodDropdown()))
.to.equal(1);
await enketoWidgetsPage.selectDropdownOptions(
await enketoWidgetsPage.neighborhoodDropdown(), 'radio', 'havendr'
);

await genericForm.nextPage();
await enketoWidgetsPage.setPatientName('Eli');
await enketoWidgetsPage.setPatientUuid('123 456 789');

expect(await (await enketoWidgetsPage.patientNameErrorLabel()).isExisting()).to.be.true;

await enketoWidgetsPage.setPatientName('Elias');
await enketoWidgetsPage.setPatientId('12345');

expect(await (await enketoWidgetsPage.patientNameErrorLabel()).isExisting()).to.be.false;

const [doc, ...additionalDocs] = await mockConfig.submitForm();
const jsonObj = doc.fields;

expect(additionalDocs).to.be.empty;

expect(jsonObj.patient_uuid).to.equal('123 456 789');
expect(jsonObj.patient_id).to.equal('12345');
expect(jsonObj.patient_name).to.equal('Elias');
expect(jsonObj.enketo_test_select.select_spinner).to.equal('a c');
expect(jsonObj.enketo_test_select.select1_spinner).to.equal('d');
expect(jsonObj.enketo_test_select.phone).to.equal('+40766565656');
expect(jsonObj.cascading_widgets.group1.country).to.equal('usa');
expect(jsonObj.cascading_widgets.group1.city).to.equal('nyc');
expect(jsonObj.cascading_widgets.group1.neighborhood).to.equal('bronx');
expect(jsonObj.cascading_widgets.group2.country2).to.equal('nl');
expect(jsonObj.cascading_widgets.group2.city2).to.equal('dro');
expect(jsonObj.cascading_widgets.group2.neighborhood2).to.equal('havendr');
});

it('should verify the cancel button', async () => {
await mockConfig.loadForm('default', 'test', 'enketo_widgets');
expect(await genericForm.getFormTitle()).to.equal('Enketo Widgets');

const cancelResult = await browser.executeAsync((resolve) => {
const myForm = document.getElementById('myform');
myForm.addEventListener('onCancel', () => resolve('Form Canceled'));
$('.enketo .cancel').click();
});
expect(cancelResult).to.equal('Form Canceled');
});

});
Loading

0 comments on commit 15bd199

Please sign in to comment.