diff --git a/tests/e2e/default/enketo/add-family.wdio-spec.js b/tests/e2e/default/enketo/add-family.wdio-spec.js index 6a605e88419..5d03750c5a1 100644 --- a/tests/e2e/default/enketo/add-family.wdio-spec.js +++ b/tests/e2e/default/enketo/add-family.wdio-spec.js @@ -9,7 +9,7 @@ const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdi describe('Family form', () => { before(async () => { - await commonEnketoPage.uploadForm('add-family-multiple-repeats'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/add-family-multiple-repeats`)); await cookieLogin(); }); diff --git a/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js b/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js index 6d4c09d9339..a3e72af44cf 100644 --- a/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js +++ b/tests/e2e/default/enketo/contact-summary-reports.wdio-spec.js @@ -26,7 +26,7 @@ describe('Contact summary', () => { )); before(async () => { - await commonEnketoPage.uploadForm('contact-summary-reports'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/contact-summary-reports`)); await chtConfUtils.initializeConfigDir(); const contactSummaryFile = path.join(__dirname, 'config/contact-summary-reports.js'); const { contactSummary } = await chtConfUtils.compileNoolsConfig({ contactSummary: contactSummaryFile }); diff --git a/tests/e2e/default/enketo/db-object-widget.wdio-spec.js b/tests/e2e/default/enketo/db-object-widget.wdio-spec.js index db3d724c36c..78614392c66 100644 --- a/tests/e2e/default/enketo/db-object-widget.wdio-spec.js +++ b/tests/e2e/default/enketo/db-object-widget.wdio-spec.js @@ -6,7 +6,6 @@ const commonPage = require('@page-objects/default/common/common.wdio.page'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); -const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); describe('DB Object Widget', () => { const places = placeFactory.generateHierarchy(); @@ -25,7 +24,7 @@ describe('DB Object Widget', () => { const personArea2 = personFactory.build({ name: 'Patricio', parent: { _id: area2._id, parent: area2.parent } }); before(async () => { - await commonEnketoPage.uploadForm('db-object-form'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/db-object-form`)); await utils.saveDocs([ ...places.values(), area2, personArea1, personArea2 ]); await utils.createUsers([ offlineUser ]); await loginPage.login(offlineUser); diff --git a/tests/e2e/default/enketo/edit-report-with-attachment.wdio-spec.js b/tests/e2e/default/enketo/edit-report-with-attachment.wdio-spec.js index ca46fb67788..b92f4949313 100644 --- a/tests/e2e/default/enketo/edit-report-with-attachment.wdio-spec.js +++ b/tests/e2e/default/enketo/edit-report-with-attachment.wdio-spec.js @@ -3,28 +3,28 @@ const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); const uuid = require('uuid').v4; const loginPage = require('@page-objects/default/login/login.wdio.page'); const utils = require('@utils'); -const commonElements = require('@page-objects/default/common/common.wdio.page'); +const commonPage = require('@page-objects/default/common/common.wdio.page'); const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); const { editReportWithAttachmentDoc } = require('@page-objects/default/enketo/custom-doc.wdio.page'); describe('Edit report with attachment', () => { before(async () => { - const formDoc = await commonEnketoPage.uploadForm('one-text-form', false); + const formDoc = commonPage.createFormDoc(`${__dirname}/forms/one-text-form`); formDoc.context = { expression: 'summary.alive', }; await utils.saveDoc(formDoc); await loginPage.cookieLogin(); - await commonElements.waitForPageLoaded(); - await commonElements.hideSnackbar(); + await commonPage.waitForPageLoaded(); + await commonPage.hideSnackbar(); }); it('should remove attachment when saving', async () => { editReportWithAttachmentDoc._id = uuid(); await utils.saveDoc(editReportWithAttachmentDoc); - await commonElements.goToReports(); + await commonPage.goToReports(); await reportsPage.openReport(editReportWithAttachmentDoc._id); await reportsPage.editReport(); @@ -48,7 +48,7 @@ describe('Edit report with attachment', () => { await utils.saveDoc(editReportWithAttachmentDoc); await browser.refresh(); - await commonElements.goToReports(); + await commonPage.goToReports(); await reportsPage.openReport(editReportWithAttachmentDoc._id); await reportsPage.editReport(); await commonEnketoPage.setInputValue('Enter text', 'initial text updated'); diff --git a/tests/e2e/default/enketo/enketo-widgets.wdio-spec.js b/tests/e2e/default/enketo/enketo-widgets.wdio-spec.js index 7069c825fad..41a92b16ebf 100644 --- a/tests/e2e/default/enketo/enketo-widgets.wdio-spec.js +++ b/tests/e2e/default/enketo/enketo-widgets.wdio-spec.js @@ -76,7 +76,7 @@ describe('Enketo Widgets', () => { }; before(async () => { - await commonEnketoPage.uploadForm('enketo_widgets_test'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/enketo_widgets_test`)); await utils.saveDoc(districtHospital); await utils.createUsers([offlineUser]); await sentinelUtils.waitForSentinel(); // we expect a shortcode to be generated for the user's contact diff --git a/tests/e2e/default/enketo/extension-lib-form.wdio-spec.js b/tests/e2e/default/enketo/extension-lib-form.wdio-spec.js index 8b82f0a5e33..9d40dbef943 100644 --- a/tests/e2e/default/enketo/extension-lib-form.wdio-spec.js +++ b/tests/e2e/default/enketo/extension-lib-form.wdio-spec.js @@ -8,7 +8,7 @@ const { extensionLibDoc } = require('@page-objects/default/enketo/custom-doc.wdi describe('Extension lib xpath function', () => { before(async () => { - await commonEnketoPage.uploadForm('extension-lib-average-calculator'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/extension-lib-average-calculator`)); await utils.saveDoc(extensionLibDoc); const waitForServiceWorker = await utils.waitForApiLogs(utils.SW_SUCCESSFUL_REGEX); diff --git a/tests/e2e/default/enketo/phone-widget.wdio-spec.js b/tests/e2e/default/enketo/phone-widget.wdio-spec.js index c493d93ee1c..c7bbdba53fd 100644 --- a/tests/e2e/default/enketo/phone-widget.wdio-spec.js +++ b/tests/e2e/default/enketo/phone-widget.wdio-spec.js @@ -14,7 +14,7 @@ describe('Phone widget', () => { const person1 = personFactory.build({ phone: '+254712345679' }); before(async () => { - await commonEnketoPage.uploadForm('phone_widget'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/phone_widget`)); await utils.saveDocs([person0, person1]); await loginPage.cookieLogin(); await commonPage.hideSnackbar(); diff --git a/tests/e2e/default/enketo/repeat.wdio-spec.js b/tests/e2e/default/enketo/repeat.wdio-spec.js index 3d04be61251..b84bac35d2e 100644 --- a/tests/e2e/default/enketo/repeat.wdio-spec.js +++ b/tests/e2e/default/enketo/repeat.wdio-spec.js @@ -24,9 +24,9 @@ describe('RepeatForm', () => { before(async () => { await utils.saveDocs(hierarchy.places); await utils.createUsers([hierarchy.user]); - await commonEnketoPage.uploadForm('repeat-translation-count'); - await commonEnketoPage.uploadForm('repeat-translation-button'); - await commonEnketoPage.uploadForm('repeat-translation-select'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/repeat-translation-count`)); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/repeat-translation-button`)); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/repeat-translation-select`)); }); afterEach(async () => { diff --git a/tests/e2e/default/enketo/submit-countdown-timer-form.wdio-spec.js b/tests/e2e/default/enketo/submit-countdown-timer-form.wdio-spec.js index 096cbd685e3..c685eaf317f 100644 --- a/tests/e2e/default/enketo/submit-countdown-timer-form.wdio-spec.js +++ b/tests/e2e/default/enketo/submit-countdown-timer-form.wdio-spec.js @@ -4,12 +4,11 @@ const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); const utils = require('@utils'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); -const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); describe('Countdown timer widget', () => { before(async () => { - await commonEnketoPage.uploadForm('countdown-timer'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/countdown-timer`)); await loginPage.cookieLogin(); await commonPage.hideSnackbar(); }); diff --git a/tests/e2e/default/enketo/submit-form.wdio-spec.js b/tests/e2e/default/enketo/submit-form.wdio-spec.js index 212f2936820..282f6b41a87 100644 --- a/tests/e2e/default/enketo/submit-form.wdio-spec.js +++ b/tests/e2e/default/enketo/submit-form.wdio-spec.js @@ -1,21 +1,22 @@ -const commonElements = require('@page-objects/default/common/common.wdio.page'); +const commonPage = require('@page-objects/default/common/common.wdio.page'); const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); const modalPage = require('@page-objects/default/common/modal.wdio.page'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); +const utils = require('@utils'); describe('Submit Enketo form', () => { before(async () => { - await commonEnketoPage.uploadForm('assessment'); - await commonEnketoPage.uploadForm('required-note'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/assessment`)); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/required-note`)); await loginPage.cookieLogin(); }); it('submits on reports tab', async () => { - await commonElements.goToReports(); - await commonElements.openFastActionReport('assessment', false); + await commonPage.goToReports(); + await commonPage.openFastActionReport('assessment', false); await commonEnketoPage.setInputValue('Person name', 'Jones'); await genericForm.submitForm(); @@ -27,33 +28,33 @@ describe('Submit Enketo form', () => { // If this test fails, it means something has gone wrong with the custom logic in openrosa2html5form.xsl // that should prevent notes from ever being required. it('allows forms with required notes to be submitted', async () => { - await commonElements.goToReports(); - await commonElements.openFastActionReport('required-note', false); + await commonPage.goToReports(); + await commonPage.openFastActionReport('required-note', false); await genericForm.submitForm(); }); it('cancelling form with no input does not trigger confirmation dialog', async () => { - await commonElements.goToReports(); + await commonPage.goToReports(); const originalReportsText = await reportsPage.getAllReportsText(); - await commonElements.openFastActionReport('assessment', false); + await commonPage.openFastActionReport('assessment', false); // Do not set any values before cancelling await (await genericForm.cancelButton()).click(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); await (await reportsPage.rightPanelSelectors.noReportSelectedLabel()).waitForDisplayed(); // No new report added expect(await reportsPage.getAllReportsText()).to.deep.equal(originalReportsText); }); it('cancelling form with input triggers confirmation dialog box', async () => { - await commonElements.goToReports(); + await commonPage.goToReports(); const originalReportsText = await reportsPage.getAllReportsText(); - await commonElements.openFastActionReport('assessment', false); + await commonPage.openFastActionReport('assessment', false); await commonEnketoPage.setInputValue('Person name', 'Jones'); await (await genericForm.cancelButton()).click(); await modalPage.submit(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); await (await reportsPage.rightPanelSelectors.noReportSelectedLabel()).waitForDisplayed(); // No new report added expect(await reportsPage.getAllReportsText()).to.deep.equal(originalReportsText); diff --git a/tests/e2e/default/enketo/submit-photo-upload-form.wdio-spec.js b/tests/e2e/default/enketo/submit-photo-upload-form.wdio-spec.js index f2f5335594b..548aacee22d 100644 --- a/tests/e2e/default/enketo/submit-photo-upload-form.wdio-spec.js +++ b/tests/e2e/default/enketo/submit-photo-upload-form.wdio-spec.js @@ -5,12 +5,11 @@ const utils = require('@utils'); const path = require('path'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); -const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); describe('Submit Photo Upload form', () => { before(async () => { - await commonEnketoPage.uploadForm('photo-upload'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/photo-upload`)); await loginPage.cookieLogin(); await commonPage.hideSnackbar(); }); diff --git a/tests/e2e/default/enketo/submit-z-score-form.wdio-spec.js b/tests/e2e/default/enketo/submit-z-score-form.wdio-spec.js index 33465faa9a6..44addd0b249 100644 --- a/tests/e2e/default/enketo/submit-z-score-form.wdio-spec.js +++ b/tests/e2e/default/enketo/submit-z-score-form.wdio-spec.js @@ -75,7 +75,7 @@ describe('Submit Z-Score form', () => { _id: 'zscore-charts', charts: charts }; - await commonEnketoPage.uploadForm('z-score'); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/z-score`)); await utils.saveDoc(chartsDoc); await loginPage.cookieLogin(); await commonPage.hideSnackbar(); diff --git a/tests/e2e/default/enketo/training-cards.wdio-spec.js b/tests/e2e/default/enketo/training-cards.wdio-spec.js index ae742e04904..b9bd689ba2f 100644 --- a/tests/e2e/default/enketo/training-cards.wdio-spec.js +++ b/tests/e2e/default/enketo/training-cards.wdio-spec.js @@ -5,11 +5,9 @@ const trainingCardsPage = require('@page-objects/default/enketo/training-cards.w const placeFactory = require('@factories/cht/contacts/place'); const userFactory = require('@factories/cht/users/users'); const personFactory = require('@factories/cht/contacts/person'); -const commonElements = require('@page-objects/default/common/common.wdio.page'); const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); const privacyPolicyFactory = require('@factories/cht/settings/privacy-policy'); const privacyPage = require('@page-objects/default/privacy-policy/privacy-policy.wdio.page'); -const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); const modalPage = require('@page-objects/default/common/modal.wdio.page'); describe('Training Cards', () => { @@ -29,7 +27,7 @@ describe('Training Cards', () => { const parent = placeFactory.place().build({ _id: 'dist1', type: 'district_hospital' }); const user = userFactory.build({ roles: [ 'nurse', 'chw' ] }); const patient = personFactory.build({ parent: { _id: user.place._id, parent: { _id: parent._id } } }); - const formDoc = await commonEnketoPage.uploadForm('training-cards-text-only', false); + const formDoc = commonPage.createFormDoc(`${__dirname}/forms/training-cards-text-only`); formDoc._id = `form:${formDocId}`; formDoc.internalId = formDocId; formDoc.context = { @@ -42,7 +40,7 @@ describe('Training Cards', () => { await utils.saveDoc(formDoc); await utils.createUsers([ user ]); await loginPage.login(user); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); }); it('should cancel training and not save it as completed', async () => { @@ -55,13 +53,13 @@ describe('Training Cards', () => { await trainingCardsPage.checkTrainingCardIsNotDisplayed(); await commonPage.goToReports(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); expect(await reportsPage.leftPanelSelectors.allReports()).to.be.empty; }); it('should display confirm message before navigating to different page', async () => { await commonPage.goToMessages(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); await setLastViewedDateInThePast(); // Unfinished trainings should appear again after reload. await browser.refresh(); @@ -87,7 +85,7 @@ describe('Training Cards', () => { await commonPage.goToMessages(); await commonPage.goToPeople(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); await setLastViewedDateInThePast(); // Unfinished trainings should appear again after reload. await browser.refresh(); @@ -135,7 +133,7 @@ describe('Training Cards', () => { const privacyPolicy = privacyPolicyFactory.privacyPolicy().build(); await utils.saveDocs([privacyPolicy]); await commonPage.goToReports(); - await commonElements.sync(); + await commonPage.sync(); await setLastViewedDateInThePast(); await browser.refresh(); @@ -147,7 +145,7 @@ describe('Training Cards', () => { it('should display training after reload and complete training', async () => { await commonPage.goToMessages(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); await setLastViewedDateInThePast(); // Unfinished trainings should appear again after reload. await browser.refresh(); @@ -176,7 +174,7 @@ describe('Training Cards', () => { it('should not display completed training', async () => { await commonPage.goToMessages(); - await commonElements.waitForPageLoaded(); + await commonPage.waitForPageLoaded(); // Completed trainings should not appear again after reload. await browser.refresh(); await trainingCardsPage.checkTrainingCardIsNotDisplayed(); diff --git a/tests/e2e/default/transitions/create-user-for-contacts.create-user.wdio-spec.js b/tests/e2e/default/transitions/create-user-for-contacts.create-user.wdio-spec.js index 6348f574cf4..4f3bb54d4e3 100644 --- a/tests/e2e/default/transitions/create-user-for-contacts.create-user.wdio-spec.js +++ b/tests/e2e/default/transitions/create-user-for-contacts.create-user.wdio-spec.js @@ -1,5 +1,3 @@ -const fs = require('fs'); -const { expect } = require('chai'); const utils = require('@utils'); const sentinelUtils = require('@utils/sentinel'); const messagesUtils = require('@utils/messages'); @@ -10,75 +8,25 @@ const loginPage = require('@page-objects/default/login/login.wdio.page'); const contactsPage = require('@page-objects/default/contacts/contacts.wdio.page'); const { BASE_URL } = require('@constants'); const { cookieLogin } = require('@page-objects/default/login/login.wdio.page'); -const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); +const createUserForContactsPage = require('@page-objects/default/enketo/create-user-for-contacts'); -const CONTACT_NAME = 'Bob_chw'; -const ADD_CHW_FORM = 'form[data-form-id="add_chw"]'; - -const chwNameField = () => $(`${ADD_CHW_FORM} input[name="/add_chw/chw_profile/name"]`); -const chwPhoneField = () => $(`${ADD_CHW_FORM} input[name="/add_chw/chw_profile/phone"]`); - -const setChwName = async (nameValue = 'Ron') => { - const name = await chwNameField(); - await name.waitForDisplayed(); - await name.setValue(nameValue); -}; - -const setChwPhone = async (phoneValue = '+40755696969') => { - const phone = await chwPhoneField(); - await phone.waitForDisplayed(); - await phone.setValue(phoneValue); -}; - -const submitAddChwForm = async ({ - name: nameValue, - phone: phoneValue, -} = {}) => { - await setChwName(nameValue); - await setChwPhone(phoneValue); - await genericForm.submitForm(); -}; - -const district = utils.deepFreeze( - placeFactory - .place() - .build({ type: 'district_hospital' }) -); - -const settings = utils.deepFreeze({ - transitions: { create_user_for_contacts: true }, - token_login: { enabled: true }, - app_url: BASE_URL -}); - -const settingsNoTransitions = utils.deepFreeze({ - transitions: { create_user_for_contacts: false }, - token_login: { enabled: true }, - app_url: BASE_URL -}); +describe('Create user when adding contact', () => { + const NEW_USERS = []; + const CONTACT_NAME = 'Bob_chw'; + const FORM_NAME = 'add_chw'; -const offlineUser = utils.deepFreeze(userFactory.build({ - username: 'offline_user_create', - place: district._id, -})); + const district = utils.deepFreeze( placeFactory.place().build({ type: 'district_hospital' }) ); -const addChwAppForm = utils.deepFreeze({ - _id: 'form:add_chw', - internalId: 'add_chw', - title: 'Add CHW', - type: 'form', - _attachments: { - xml: { - content_type: 'application/octet-stream', - data: Buffer - .from(fs.readFileSync(`${__dirname}/forms/add_chw.xml`, 'utf8')) - .toString('base64') - } - } -}); + const createSettings = (create_user_for_contacts) => utils.deepFreeze({ + transitions: { create_user_for_contacts }, + token_login: { enabled: true }, + app_url: BASE_URL + }); -describe('Create user when adding contact', () => { - const newUsers = []; + const offlineUser = utils.deepFreeze(userFactory.build({ + username: 'offline_user_create', + place: district._id, + })); const verifyUserCreation = async () => { const chwContactId = await contactsPage.getCurrentContactId(); @@ -93,7 +41,7 @@ describe('Create user when adding contact', () => { // New user created const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: chwContactId }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); // Open the texted link @@ -119,13 +67,15 @@ describe('Create user when adding contact', () => { expect(userSettings).to.be.empty; }; - before(async () => await utils.saveDocIfNotExists(addChwAppForm)); + before(async () => { + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/${FORM_NAME}`)); + }); beforeEach(async () => await utils.saveDocs([district])); afterEach(async () => { - await utils.deleteUsers(newUsers.map(username => ({ username }))); - newUsers.length = 0; + await utils.deleteUsers(NEW_USERS.map(username => ({ username }))); + NEW_USERS.length = 0; await utils.revertDb([/^form:/], true); await sentinelUtils.waitForSentinel(); await browser.reloadSession(); @@ -134,37 +84,30 @@ describe('Create user when adding contact', () => { it('Creates a new user while offline', async () => { await utils.createUsers([offlineUser]); - newUsers.push(offlineUser.username); - - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + NEW_USERS.push(offlineUser.username); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await loginPage.login(offlineUser); await commonPage.waitForPageLoaded(); await browser.throttle('offline'); await commonPage.goToPeople(district._id); - await contactsPage.addPerson({ name: CONTACT_NAME, phone: '+40755696969' }); - await browser.throttle('online'); await commonPage.sync(); - await verifyUserCreation(); }); it('creates a new user while online', async () => { - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await cookieLogin(); await commonPage.goToPeople(district._id); - await contactsPage.addPerson({ name: CONTACT_NAME, phone: '+40755696969' }); - await verifyUserCreation(); }); it('Creates a new user when adding a person while adding a place', async () => { - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await cookieLogin(); await commonPage.goToPeople(district._id); - await contactsPage.addPlace({ type: 'health_center', placeName: 'HC1', @@ -172,56 +115,45 @@ describe('Create user when adding contact', () => { phone: '+40755696969' }); await contactsPage.selectLHSRowByText(CONTACT_NAME); - await verifyUserCreation(); }); it('Does not create a new user when the transition is disabled', async () => { - await utils.updateSettings(settingsNoTransitions, 'sentinel'); + await utils.updateSettings(createSettings(false), 'sentinel'); await cookieLogin(); await commonPage.goToPeople(district._id); - await contactsPage.addPerson({ name: CONTACT_NAME, phone: '+40755696969' }); await contactsPage.selectLHSRowByText(CONTACT_NAME); - await verifyUserNotCreated(); }); it('creates a new user when contact is added from app form', async () => { - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await cookieLogin(); await commonPage.goToPeople(district._id); - - await commonPage.openFastActionReport(addChwAppForm.internalId); - await submitAddChwForm({ name: CONTACT_NAME }); + await createUserForContactsPage.submitAddChwForm({ name: CONTACT_NAME }); await contactsPage.selectLHSRowByText(CONTACT_NAME); - await verifyUserCreation(); }); it('Does not create a new user when the transition fails', async () => { - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await cookieLogin(); await commonPage.goToPeople(district._id); - - await commonPage.openFastActionReport(addChwAppForm.internalId); // Add contact with invalid phone number - await submitAddChwForm({ name: CONTACT_NAME, phone: '+40755' }); + await createUserForContactsPage.submitAddChwForm({ name: CONTACT_NAME, phone: '+40755' }); await contactsPage.selectLHSRowByText(CONTACT_NAME); - await verifyUserNotCreated({ ok: false }); }); it('Does not create a new user when editing contact', async () => { - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await cookieLogin(); await commonPage.goToPeople(district._id); - await commonPage.openFastActionReport(addChwAppForm.internalId); // Add contact with invalid phone number - await submitAddChwForm({ name: CONTACT_NAME, phone: '+40755' }); + await createUserForContactsPage.submitAddChwForm({ name: CONTACT_NAME, phone: '+40755' }); await contactsPage.selectLHSRowByText(CONTACT_NAME); await verifyUserNotCreated({ ok: false }); - // Edit contact to have valid phone number await contactsPage.editPerson(CONTACT_NAME, { phone: '+40755696969', dob: '2000-01-01' }); @@ -233,12 +165,10 @@ describe('Create user when adding contact', () => { }); it('creates a new user when Sentinel recovers from outage', async () => { - await utils.updateSettings(settings, {ignoreReload: 'sentinel'}); + await utils.updateSettings(createSettings(true), {ignoreReload: 'sentinel'}); await utils.stopSentinel(); - await cookieLogin(); await commonPage.goToPeople(district._id); - await contactsPage.addPerson({ name: CONTACT_NAME, phone: '+40755696969' }, false); await contactsPage.editPerson(CONTACT_NAME, { name: 'Edit 1' }); await contactsPage.editPerson('Edit 1', { name: 'Edit 2' }); diff --git a/tests/e2e/default/transitions/create-user-for-contacts.replace-user.wdio-spec.js b/tests/e2e/default/transitions/create-user-for-contacts.replace-user.wdio-spec.js index 19cc4bb1025..38c4cfd8cf5 100644 --- a/tests/e2e/default/transitions/create-user-for-contacts.replace-user.wdio-spec.js +++ b/tests/e2e/default/transitions/create-user-for-contacts.replace-user.wdio-spec.js @@ -1,4 +1,3 @@ -const fs = require('fs'); const utils = require('@utils'); const sentinelUtils = require('@utils/sentinel'); const chtDbUtils = require('@utils/cht-db'); @@ -10,206 +9,155 @@ const loginPage = require('@page-objects/default/login/login.wdio.page'); const commonPage = require('@page-objects/default/common/common.wdio.page'); const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); const contactsPage = require('@page-objects/default/contacts/contacts.wdio.page'); -const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); -const replaceUserForm = require('@page-objects/default/enketo/replace-user.wdio.page'); +const createUserForContactsPage = require('@page-objects/default/enketo/create-user-for-contacts'); const { BASE_URL, DEFAULT_USER_CONTACT_DOC } = require('@constants'); -const USER_CONTACT = utils.deepFreeze(personFactory.build({ role: 'chw' })); +describe('Create user for contacts', () => { + const NEW_USERS = []; + const REPLACE_USER_FORM_TITLE = 'Replace User'; + const REPLACE_USER_FORM_ID = 'replace_user'; + const OTHER_REPLACE_FORM_ID = 'other_replace_form'; + const DISABLED_USER_PASSWORD = 'n3wPassword!'; + + const USER_CONTACT = utils.deepFreeze(personFactory.build({ role: 'chw' })); + + const DISTRICT = utils.deepFreeze(placeFactory + .place() + .build({ + type: 'district_hospital', + contact: { + _id: USER_CONTACT._id, + } + })); -const DISTRICT = utils.deepFreeze(placeFactory - .place() - .build({ - type: 'district_hospital', - contact: { - _id: USER_CONTACT._id, - } + const ORIGINAL_USER = utils.deepFreeze(userFactory.build({ + username: `user_for_contacts_original_person`, + place: DISTRICT._id, + contact: USER_CONTACT, + })); + + const ONLINE_USER = utils.deepFreeze(userFactory.build({ + username: `user_for_contacts_online_user`, + place: DISTRICT._id, + contact: USER_CONTACT, + roles: ['program_officer', 'mm-online'], })); -const ORIGINAL_USER = utils.deepFreeze(userFactory.build({ - username: `user_for_contacts_original_person`, - place: DISTRICT._id, - contact: USER_CONTACT, -})); - -const ONLINE_USER = utils.deepFreeze(userFactory.build({ - username: `user_for_contacts_online_user`, - place: DISTRICT._id, - contact: USER_CONTACT, - roles: ['program_officer', 'mm-online'], -})); - -const newUsers = []; - -const REPLACE_USER_FORM_TITLE = 'Replace User'; -const REPLACE_USER_FORM_ID = 'replace_user'; - -const BASIC_FORM_DOC = utils.deepFreeze({ - _id: 'form:basic_form', - internalId: 'basic_form', - title: 'Form basic_form', - type: 'form', - _attachments: { - xml: { - content_type: 'application/octet-stream', - data: Buffer - .from(fs.readFileSync(`${__dirname}/forms/basic_form.xml`, 'utf8')) - .toString('base64') + const SETTINGS = utils.deepFreeze({ + transitions: { create_user_for_contacts: true }, + create_user_for_contacts: { replace_forms: [REPLACE_USER_FORM_ID, OTHER_REPLACE_FORM_ID] }, + token_login: { enabled: true }, + app_url: BASE_URL + }); + + const loginAsUser = async (user) => { + await utils.createUsers([user]); + NEW_USERS.push(user.username); + await loginPage.login(user); + await commonPage.waitForPageLoaded(); + }; + + /** + * Ongoing replication can be interrupted by the user being edited on the server side. + * A 401 for a replication request will create a feedback doc, which will fail the test. + */ + const assertFeedbackDocs = async () => { + const feedbackDocs = await chtDbUtils.getFeedbackDocs(); + if (!feedbackDocs.length) { + return; } - } -}); -const OTHER_REPLACE_FORM_DOC = utils.deepFreeze({ - _id: 'form:other_replace_form', - internalId: 'other_replace_form', - title: 'Replace User Again', - type: 'form', - _attachments: { - xml: { - content_type: 'application/octet-stream', - data: Buffer - .from(fs.readFileSync(`${__dirname}/../../../../config/default/forms/app/replace_user.xml`, 'utf8')) - .toString('base64') + const feedbackDocsToIgnore = [ 'Http failure response', 'Server error' ]; + + const unknownMessages = feedbackDocs + .map(doc => doc.info.message) + .filter(message => !feedbackDocsToIgnore.find(toIgnore => message.includes(toIgnore))); + + if (!unknownMessages.length) { + await chtDbUtils.clearFeedbackDocs(); } - } -}); + }; -const SETTINGS = utils.deepFreeze({ - transitions: { create_user_for_contacts: true }, - create_user_for_contacts: { replace_forms: [REPLACE_USER_FORM_ID, OTHER_REPLACE_FORM_DOC.internalId] }, - token_login: { enabled: true }, - app_url: BASE_URL -}); + const loginAsOfflineUser = () => loginAsUser(ORIGINAL_USER); + const loginAsOnlineUser = () => loginAsUser(ONLINE_USER); + + const assertReplaceUserReport = (replaceUserReport, originalContactId) => { + expect(replaceUserReport.fields.replacement_contact_id).to.not.be.empty; + expect(replaceUserReport.contact._id).to.equal(originalContactId); + }; -const loginAsUser = async (user) => { - await utils.createUsers([user]); - newUsers.push(user.username); - await loginPage.login(user); - await commonPage.waitForPageLoaded(); -}; - -/** - * Ongoing replication can be interrupted by the user being edited on the server side. - * A 401 for a replication request will create a feedback doc, which will fail the test. - */ -const assertFeedbackDocs = async () => { - const feedbackDocs = await chtDbUtils.getFeedbackDocs(); - if (!feedbackDocs.length) { - return; - } - - const feedbackDocsToIgnore = [ - 'Http failure response', - 'Server error' - ]; - - const unknownMessages = feedbackDocs - .map(doc => doc.info.message) - .filter(message => !feedbackDocsToIgnore.find(toIgnore => message.includes(toIgnore))); - - if (!unknownMessages.length) { - await chtDbUtils.clearFeedbackDocs(); - } -}; - -const loginAsOfflineUser = () => loginAsUser(ORIGINAL_USER); - -const loginAsOnlineUser = () => loginAsUser(ONLINE_USER); - -const populateReplaceUserForm = async (formID) => { - await commonPage.openFastActionReport(formID); - await replaceUserForm.selectAdminCode('1234'); - await genericForm.nextPage(); - await replaceUserForm.selectContactFullName('Replacement User'); - await replaceUserForm.selectContactSex(replaceUserForm.SEX.female); - await replaceUserForm.selectContactDobUnknown(); - await replaceUserForm.selectContactAgeYears(22); - await genericForm.nextPage(); -}; - -const submitBasicForm = async () => { - await commonPage.openFastActionReport('basic_form', false); - await genericForm.submitForm(); - return reportsPage.getCurrentReportId(); -}; - -const assertReplaceUserReport = (replaceUserReport, originalContactId) => { - expect(replaceUserReport.fields.replacement_contact_id).to.not.be.empty; - expect(replaceUserReport.contact._id).to.equal(originalContactId); -}; - -const assertOriginalContactUpdated = (originalContact, originalUsername, newContactId, status) => { - expect(originalContact.user_for_contact).to.deep.equal({ - replace: { - [originalUsername]: { - status, - replacement_contact_id: newContactId, + const assertOriginalContactUpdated = (originalContact, originalUsername, newContactId, status) => { + expect(originalContact.user_for_contact).to.deep.equal({ + replace: { + [originalUsername]: { + status, + replacement_contact_id: newContactId, + } } - } - }); -}; - -const assertNewContact = (newContact, originalUser, originalContact) => { - expect(newContact.phone).to.equal(originalUser.phone); - expect(newContact.parent._id).to.equal(originalContact.parent._id); - expect(newContact.name).to.equal('Replacement User'); - expect(newContact.sex).to.equal('female'); -}; - -const submitLoginRequest = ({ username, password }) => { - const opts = { - path: '/medic/login', - body: { user: username, password, locale: 'en' }, - method: 'POST', - simple: false, - noAuth: true, + }); }; - return utils.request(opts); -}; -const DISABLED_USER_PASSWORD = 'n3wPassword!'; + const assertNewContact = (newContact, originalUser, originalContact) => { + expect(newContact.phone).to.equal(originalUser.phone); + expect(newContact.parent._id).to.equal(originalContact.parent._id); + expect(newContact.name).to.equal('Replacement User'); + expect(newContact.sex).to.equal('female'); + }; -const assertUserPasswordChanged = async (user) => { - // Cannot login because user's password has been automatically reset - const resp0 = await submitLoginRequest(user); - expect(resp0.statusCode).to.equal(401); + const submitLoginRequest = ({ username, password }) => { + const opts = { + path: '/medic/login', + body: { user: username, password, locale: 'en' }, + method: 'POST', + simple: false, + noAuth: true, + }; + return utils.request(opts); + }; - // Update user's password to something we know - await utils.request({ - path: `/api/v1/users/${user.username}`, - method: 'POST', - body: { password: DISABLED_USER_PASSWORD } - }); + const assertUserPasswordChanged = async (user) => { + // Cannot login because user's password has been automatically reset + const resp0 = await submitLoginRequest(user); + expect(resp0.statusCode).to.equal(401); - // Can login with new password - const resp1 = await submitLoginRequest({ ...user, password: DISABLED_USER_PASSWORD }); - expect(resp1.statusCode).to.equal(302); -}; - -const assertNewUserSettings = (newUserSettings, newContact, originalUser) => { - expect(newUserSettings).to.deep.include({ - roles: originalUser.roles, - phone: newContact.phone, - facility_id: [newContact.parent._id], - contact_id: newContact._id, - fullname: newContact.name, - }); - expect(newUserSettings.token_login.active).to.be.true; - expect(newUserSettings._id).to.match(/^org\.couchdb\.user:replacement-user-\d\d\d\d$/); - expect(newUserSettings.name).to.match(/^replacement-user-\d\d\d\d$/); -}; - -const waitForConflicts = async (getDoc) => { - const doc = await getDoc(); - if (doc._conflicts) { - return doc; - } - return utils.delayPromise(waitForConflicts(getDoc), 100); -}; + // Update user's password to something we know + await utils.request({ + path: `/api/v1/users/${user.username}`, + method: 'POST', + body: { password: DISABLED_USER_PASSWORD } + }); + + // Can login with new password + const resp1 = await submitLoginRequest({ ...user, password: DISABLED_USER_PASSWORD }); + expect(resp1.statusCode).to.equal(302); + }; + + const assertNewUserSettings = (newUserSettings, newContact, originalUser) => { + expect(newUserSettings).to.deep.include({ + roles: originalUser.roles, + phone: newContact.phone, + facility_id: [newContact.parent._id], + contact_id: newContact._id, + fullname: newContact.name, + }); + expect(newUserSettings.token_login.active).to.be.true; + expect(newUserSettings._id).to.match(/^org\.couchdb\.user:replacement-user-\d\d\d\d$/); + expect(newUserSettings.name).to.match(/^replacement-user-\d\d\d\d$/); + }; + + const waitForConflicts = async (getDoc) => { + const doc = await getDoc(); + if (doc._conflicts) { + return doc; + } + return utils.delayPromise(waitForConflicts(getDoc), 100); + }; -describe('Create user for contacts', () => { before(async () => { - await utils.saveDocIfNotExists(BASIC_FORM_DOC); - await utils.saveDocIfNotExists(OTHER_REPLACE_FORM_DOC); + await utils.saveDocIfNotExists(commonPage.createFormDoc(`${__dirname}/forms/basic_form`)); + await utils.saveDocIfNotExists(commonPage.createFormDoc( + `${__dirname}/../../../../config/default/forms/app/replace_user`, 'other_replace_form' + )); }); beforeEach(async () => { @@ -217,8 +165,8 @@ describe('Create user for contacts', () => { }); afterEach(async () => { - await utils.deleteUsers(newUsers.map(username => ({ username }))); - newUsers.length = 0; + await utils.deleteUsers(NEW_USERS.map(username => ({ username }))); + NEW_USERS.length = 0; await utils.revertDb([/^form:/], true); await sentinelUtils.waitForSentinel(); await browser.reloadSession(); @@ -236,18 +184,17 @@ describe('Create user for contacts', () => { // Create existing report (before user is replaced) await commonPage.goToReports(); - const existingBasicReportId = await submitBasicForm(); + const existingBasicReportId = await createUserForContactsPage.submitBasicForm(); await commonPage.goToPeople(originalContactId, true); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); const reportNames = await contactsPage.getAllRHSReportsNames(); expect(reportNames.filter(name => name === REPLACE_USER_FORM_TITLE)).to.have.lengthOf(1); await commonPage.goToReports(); const reportId = await reportsPage.getLastSubmittedReportId(); // Submit several forms to be re-parented - const basicReportId0 = await submitBasicForm(); - const basicReportId1 = await submitBasicForm(); + const basicReportId0 = await createUserForContactsPage.submitBasicForm(); + const basicReportId1 = await createUserForContactsPage.submitBasicForm(); // Replace user report created const replaceUserReport = await chtDbUtils.getDoc(reportId); @@ -288,7 +235,7 @@ describe('Create user for contacts', () => { // New user created const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: replacementContactId }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); assertNewUserSettings(newUserSettings, newContact, ORIGINAL_USER); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); @@ -308,7 +255,7 @@ describe('Create user for contacts', () => { await commonPage.waitForPageLoaded(); await commonPage.sync(); await commonPage.goToReports(); - const basicReportId3 = await submitBasicForm(); + const basicReportId3 = await createUserForContactsPage.submitBasicForm(); const basicReport3 = await utils.getDoc(basicReportId3); // New reports written by the old user are not re-parented expect(basicReport3.contact._id).to.equal(originalContactId); @@ -322,8 +269,7 @@ describe('Create user for contacts', () => { const originalContactId = ORIGINAL_USER.contact._id; await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm({ waitForPageLoaded: false }); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID, false); // Logout triggered immediately await (await loginPage.loginButton()).waitForDisplayed(); @@ -352,12 +298,13 @@ describe('Create user for contacts', () => { // New user created const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: replacementContactId }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); assertNewUserSettings(newUserSettings, newContact, ORIGINAL_USER); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); // Open the texted link await commonPage.logout(); + await browser.url(loginLink); await commonPage.waitForPageLoaded(); const [cookie] = await browser.getCookies('userCtx'); @@ -376,8 +323,7 @@ describe('Create user for contacts', () => { const originalContactId = ORIGINAL_USER.contact._id; await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); // Logout triggered immediately await (await loginPage.loginButton()).waitForDisplayed(); @@ -406,7 +352,7 @@ describe('Create user for contacts', () => { // New user created const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: replacementContactId }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); assertNewUserSettings(newUserSettings, newContact, ORIGINAL_USER); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); @@ -429,15 +375,14 @@ describe('Create user for contacts', () => { await browser.throttle('offline'); await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); let reportNames = await contactsPage.getAllRHSReportsNames(); expect(reportNames.filter(name => name === REPLACE_USER_FORM_TITLE)).to.have.lengthOf(1); await commonPage.goToReports(); const reportId = await reportsPage.getLastSubmittedReportId(); // Submit several forms to be re-parented - const basicReportId0 = await submitBasicForm(); - const basicReportId1 = await submitBasicForm(); + const basicReportId0 = await createUserForContactsPage.submitBasicForm(); + const basicReportId1 = await createUserForContactsPage.submitBasicForm(); // Replace user report created const replaceUserReport = await chtDbUtils.getDoc(reportId); @@ -457,15 +402,14 @@ describe('Create user for contacts', () => { // Submit another replace user form await commonPage.goToPeople(replacementContactId0); - await populateReplaceUserForm(OTHER_REPLACE_FORM_DOC.internalId); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(OTHER_REPLACE_FORM_ID); reportNames = await contactsPage.getAllRHSReportsNames(); - expect(reportNames.filter(name => name === OTHER_REPLACE_FORM_DOC.title)).to.have.lengthOf(1); + expect(reportNames.filter(name => name === OTHER_REPLACE_FORM_ID)).to.have.lengthOf(1); await commonPage.goToReports(); const reportId1 = await reportsPage.getLastSubmittedReportId(); // Submit several forms to be re-parented - const basicReportId2 = await submitBasicForm(); - const basicReportId3 = await submitBasicForm(); + const basicReportId2 = await createUserForContactsPage.submitBasicForm(); + const basicReportId3 = await createUserForContactsPage.submitBasicForm(); const replaceUserReport1 = await chtDbUtils.getDoc(reportId1); const { replacement_contact_id: replacementContactId1 } = replaceUserReport1.fields; @@ -502,7 +446,7 @@ describe('Create user for contacts', () => { // New user created const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: replacementContactId1 }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); assertNewUserSettings(newUserSettings, newContact1, ORIGINAL_USER); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); @@ -534,13 +478,12 @@ describe('Create user for contacts', () => { contact: ORIGINAL_USER.contact._id }; await utils.createUsers([otherUser]); - newUsers.push(otherUser.username); + NEW_USERS.push(otherUser.username); const originalContactId = ORIGINAL_USER.contact._id; await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm({ waitForPageLoaded: false }); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID, false); // Logout triggered immediately await (await loginPage.loginButton()).waitForDisplayed(); @@ -569,7 +512,7 @@ describe('Create user for contacts', () => { // New user created const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: replacementContactId }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); assertNewUserSettings(newUserSettings, newContact, ORIGINAL_USER); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); @@ -604,13 +547,12 @@ describe('Create user for contacts', () => { contact: ORIGINAL_USER.contact._id }; await utils.createUsers([otherUser]); - newUsers.push(otherUser.username); + NEW_USERS.push(otherUser.username); await browser.throttle('offline'); await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); const reportNames = await contactsPage.getAllRHSReportsNames(); expect(reportNames.filter(name => name === REPLACE_USER_FORM_TITLE)).to.have.lengthOf(1); await commonPage.goToReports(); @@ -630,8 +572,8 @@ describe('Create user for contacts', () => { expect(district.contact._id).to.equal(replacementContactId); // Submit several forms to be re-parented - const basicReportId0 = await submitBasicForm(); - const basicReportId1 = await submitBasicForm(); + const basicReportId0 = await createUserForContactsPage.submitBasicForm(); + const basicReportId1 = await createUserForContactsPage.submitBasicForm(); // Basic form reports re-parented const basicReports = await chtDbUtils.getDocs([basicReportId0, basicReportId1]); basicReports.forEach((report) => expect(report.contact._id).to.equal(replacementContactId)); @@ -644,8 +586,7 @@ describe('Create user for contacts', () => { await loginPage.login(otherUser); await commonPage.waitForPageLoaded(); await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); // Logout triggered immediately await (await loginPage.loginButton()).waitForDisplayed(); @@ -675,7 +616,7 @@ describe('Create user for contacts', () => { const [newUserSettings, ...additionalUsers] = await utils.getUserSettings({ contactId: otherReplacementContactId }); expect(additionalUsers).to.be.empty; - newUsers.push(newUserSettings.name); + NEW_USERS.push(newUserSettings.name); assertNewUserSettings(newUserSettings, otherNewContact, otherUser); const loginLink = await messagesUtils.getTextedLoginLink(newUserSettings); @@ -721,12 +662,11 @@ describe('Create user for contacts', () => { const originalContactId = ORIGINAL_USER.contact._id; await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); // No logout triggered await commonPage.goToReports(); const reportId = await reportsPage.getLastSubmittedReportId(); - const basicReportId = await submitBasicForm(); + const basicReportId = await createUserForContactsPage.submitBasicForm(); // Replace user report created const replaceUserReport = await utils.getDoc(reportId); @@ -759,15 +699,14 @@ describe('Create user for contacts', () => { await browser.throttle('offline'); await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); const reportNames = await contactsPage.getAllRHSReportsNames(); expect(reportNames.filter(name => name === REPLACE_USER_FORM_TITLE)).to.have.lengthOf(1); await commonPage.goToReports(); const reportId = await reportsPage.getLastSubmittedReportId(); // Submit several forms to be re-parented - const basicReportId0 = await submitBasicForm(); - const basicReportId1 = await submitBasicForm(); + const basicReportId0 = await createUserForContactsPage.submitBasicForm(); + const basicReportId1 = await createUserForContactsPage.submitBasicForm(); // Replace user report created const replaceUserReport = await chtDbUtils.getDoc(reportId); @@ -827,8 +766,8 @@ describe('Create user for contacts', () => { const finalOriginalContactLocal = await chtDbUtils.getDoc(originalContactId); assertOriginalContactUpdated(finalOriginalContactLocal, ORIGINAL_USER.username, replacementContactId, 'ERROR'); await commonPage.goToReports(); - const basicReportId2 = await submitBasicForm(); - const basicReportId3 = await submitBasicForm(); + const basicReportId2 = await createUserForContactsPage.submitBasicForm(); + const basicReportId3 = await createUserForContactsPage.submitBasicForm(); const subsequentBasicReports = await chtDbUtils.getDocs([basicReportId2, basicReportId3]); subsequentBasicReports.forEach((report) => expect(report.contact._id).to.equal(originalContactId)); @@ -842,8 +781,7 @@ describe('Create user for contacts', () => { const originalContactId = ONLINE_USER.contact._id; await commonPage.goToPeople(originalContactId); - await populateReplaceUserForm(REPLACE_USER_FORM_ID); - await genericForm.submitForm(); + await createUserForContactsPage.submitReplaceUserForm(REPLACE_USER_FORM_ID); // No logout triggered await commonPage.goToReports(); const reportId = await reportsPage.getLastSubmittedReportId(); diff --git a/tests/e2e/default/translations/bikram-sambat-contact-template-config.js b/tests/e2e/default/translations/config/bikram-sambat-contact-template-config.js similarity index 100% rename from tests/e2e/default/translations/bikram-sambat-contact-template-config.js rename to tests/e2e/default/translations/config/bikram-sambat-contact-template-config.js diff --git a/tests/e2e/default/translations/enabled-languages.wdio-spec.js b/tests/e2e/default/translations/enabled-languages.wdio-spec.js index e64ac53261d..f176d1b53f1 100644 --- a/tests/e2e/default/translations/enabled-languages.wdio-spec.js +++ b/tests/e2e/default/translations/enabled-languages.wdio-spec.js @@ -2,31 +2,21 @@ const utils = require('@utils'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const adminPage = require('@page-objects/default/admin/admin.wdio.page'); -const settings = { - languages: [ - { - locale: 'en', - enabled: true, - }, - { - locale: 'es', - enabled: true, - }, - { - locale: 'fr', - enabled: true, - }, - ], -}; - describe('Enabling/disabling languages', () => { + const SETTINGS = { + languages: [ + { locale: 'en', enabled: true }, + { locale: 'es', enabled: true }, + { locale: 'fr', enabled: true }, + ], + }; afterEach(async () => { await utils.revertSettings(true); }); it('should disable a language and enable another', async () => { - await utils.updateSettings(settings, { ignoreReload: true }); + await utils.updateSettings(SETTINGS, { ignoreReload: true }); await browser.reloadSession(); await browser.url('/'); @@ -53,22 +43,10 @@ describe('Enabling/disabling languages', () => { // - Swahili has been enabled in the app_settings const updatedSettings = await utils.getSettings(); expect(updatedSettings.languages).to.deep.equal([ - { - locale: 'en', - enabled: true, - }, - { - locale: 'es', - enabled: false, - }, - { - locale: 'fr', - enabled: true, - }, - { - locale: 'sw', - enabled: true, - }, + { locale: 'en', enabled: true }, + { locale: 'es', enabled: false }, + { locale: 'fr', enabled: true }, + { locale: 'sw', enabled: true }, ]); // assert: diff --git a/tests/e2e/default/translations/incorrect-locale.wdio-spec.js b/tests/e2e/default/translations/incorrect-locale.wdio-spec.js index fcd00d38f8b..c107f185e7b 100644 --- a/tests/e2e/default/translations/incorrect-locale.wdio-spec.js +++ b/tests/e2e/default/translations/incorrect-locale.wdio-spec.js @@ -6,49 +6,43 @@ const loginPage = require('@page-objects/default/login/login.wdio.page'); const placeFactory = require('@factories/cht/contacts/place'); const sentinelUtils = require('@utils/sentinel'); -const languageCode = 'hil'; - -const createLanguage = async () => { - await utils.addTranslations(languageCode, { - 'n.month': '{MONTHS, plural, =1{1 luna} other{# luni}}', - 'n.week': '{WEEKS, plural, =1{1 saptamana} other{# saptamani}}', - 'reports.none.n.months': - '{MONTHS, plural, =1{No reports in the last month.} other{No reports in the last # months.}}', - 'task.days.left': '{DAYS, plural, =1{1 day left} other{# days left}', - 'tasks.none.n.weeks': '{WEEKS, plural, =1{No tasks in the next week.} other{No tasks in the next # weeks.}}', - 'Reports': 'HilReports', - 'view.all': 'View all' - }); - await utils.enableLanguage(languageCode); -}; +describe('Testing Incorrect locale', () => { + const LANGUAGE_CODE = 'hil'; -const createContact = () => { - return placeFactory.place().build({ + const place = placeFactory.place().build({ name: 'hil district', type: 'district_hospital', reported_date: 1000, parent: '', }); -}; -let contact; - -describe('Testing Incorrect locale', () => { + const createLanguage = async () => { + await utils.addTranslations(LANGUAGE_CODE, { + 'n.month': '{MONTHS, plural, =1{1 luna} other{# luni}}', + 'n.week': '{WEEKS, plural, =1{1 saptamana} other{# saptamani}}', + 'reports.none.n.months': + '{MONTHS, plural, =1{No reports in the last month.} other{No reports in the last # months.}}', + 'task.days.left': '{DAYS, plural, =1{1 day left} other{# days left}', + 'tasks.none.n.weeks': '{WEEKS, plural, =1{No tasks in the next week.} other{No tasks in the next # weeks.}}', + 'Reports': 'HilReports', + 'view.all': 'View all' + }); + await utils.enableLanguage(LANGUAGE_CODE); + }; - beforeEach(() => { - contact = createContact(); + before(async () => { + await loginPage.cookieLogin(); + await utils.saveDoc(place); + await sentinelUtils.waitForSentinel(); }); it('should work with incorrect locale', async () => { - await loginPage.cookieLogin(); - await utils.saveDoc(contact); - await sentinelUtils.waitForSentinel(); const waitForServiceWorker = await utils.waitForApiLogs(utils.SW_SUCCESSFUL_REGEX); await createLanguage(); await waitForServiceWorker.promise; await commonElements.closeReloadModal(true); - await userSettingsElements.setLanguage(languageCode); + await userSettingsElements.setLanguage(LANGUAGE_CODE); const text = await commonElements.getReportsButtonLabel().getText(); expect(text).to.equal('HilReports'); @@ -64,7 +58,7 @@ describe('Testing Incorrect locale', () => { expect(tasksFilter.sort()).to.deep.equal(['1 saptamana', '2 saptamani', 'View all'].sort()); await utils.revertSettings(true); - await utils.deleteDocs([ contact._id, `messages-${languageCode}` ]); + await utils.deleteDocs([ place._id, `messages-${LANGUAGE_CODE}` ]); await browser.setCookies({ name: 'locale', value: 'en' }); }); }); diff --git a/tests/e2e/default/translations/message-format.wdio-spec.js b/tests/e2e/default/translations/message-format.wdio-spec.js index 59575e77cbd..16bcb4e170f 100644 --- a/tests/e2e/default/translations/message-format.wdio-spec.js +++ b/tests/e2e/default/translations/message-format.wdio-spec.js @@ -3,15 +3,12 @@ const loginPage = require('@page-objects/default/login/login.wdio.page'); const placeFactory = require('@factories/cht/contacts/place'); const commonPage = require('@page-objects/default/common/common.wdio.page'); const contactElements = require('@page-objects/default/contacts/contacts.wdio.page'); -const district_hospital = placeFactory.generateHierarchy(['district_hospital']).get('district_hospital'); describe('MessageFormat', () => { - const createContact = async () => { - await utils.saveDoc(district_hospital); - }; + const district_hospital = placeFactory.generateHierarchy(['district_hospital']).get('district_hospital'); before(async () => { - await createContact(); + await utils.saveDoc(district_hospital); await loginPage.cookieLogin(); }); diff --git a/tests/e2e/default/translations/nepali-dates-and-numbers.wdio-spec.js b/tests/e2e/default/translations/nepali-dates-and-numbers.wdio-spec.js index d8d4d1d997f..9c356f7096c 100644 --- a/tests/e2e/default/translations/nepali-dates-and-numbers.wdio-spec.js +++ b/tests/e2e/default/translations/nepali-dates-and-numbers.wdio-spec.js @@ -11,103 +11,83 @@ const contactsPage = require('@page-objects/default/contacts/contacts.wdio.page' const chtConfUtils = require('@utils/cht-conf'); const gatewayApiUtils = require('@utils/gateway-api'); const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); +const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); -const NEPALI_LOCALE_CODE = 'ne'; - -const setLanguage = async (locale) => { - const localeCookie = 'locale'; - const existentCookie = await browser.getCookies(localeCookie); - if (existentCookie && existentCookie[0] && existentCookie[0].value === locale) { - return; - } - await browser.setCookies({ name: localeCookie, value: locale }); - await browser.refresh(); -}; - -const getReports = async () => { - const options = { - path: '/_design/medic-client/_view/reports_by_date', - qs: { include_docs: true }, - }; - const response = await utils.requestOnMedicDb(options); - return response.rows.map(row => row.doc); -}; - -const setExistentReportDates = async (dates) => { - const reports = await getReports(); - dates.forEach((date, idx) => reports[idx].reported_date = moment(date).valueOf()); - return utils.saveDocs(reports); -}; - -const momentToBikParts = (mDate) => { - return bikramSambat.toBik(moment(mDate).format('YYYY-MM-DD')); -}; - -const momentToBikYMD = (mDate) => { - const bsDate = momentToBikParts(mDate); - return `${bsDate.year}-${bsDate.month}-${bsDate.day}`; -}; - -const formIdBS = 'B'; -const formIdBSParts = 'C'; -const nineWeeksAgo = moment().subtract({ weeks: 9 }).startOf('day'); -const tenWeeksAgo = moment().subtract({ weeks: 10 }).startOf('day'); - -const forms = { - B: { - meta: { - code: formIdBS, - label: 'LMP with BS Date', +describe('Bikram Sambat date display', () => { + const NEPALI_LOCALE_CODE = 'ne'; + const FORM_ID_BS = 'B'; + const FORM_ID_BS_PARTS = 'C'; + const NINE_WEEKS_AGO = moment().subtract({ weeks: 9 }).startOf('day'); + const TEN_WEEKS_AGO = moment().subtract({ weeks: 10 }).startOf('day'); + + const FORMS = { + B: { + meta: { code: FORM_ID_BS, label: 'LMP with BS Date' }, + fields: { + name: { type: 'string', labels: { short: 'Name' } }, + lmp_date: { type: 'bsDate', labels: { short: 'LMP Date' } } + } }, - fields: { - name: { - type: 'string', - labels: { short: 'Name' } - }, - lmp_date: { - type: 'bsDate', - labels: { short: 'LMP Date' } + C: { + meta: { code: FORM_ID_BS_PARTS, label: 'LMP with BS date parts' }, + fields: { + name: { type: 'string', labels: { short: 'Name' } }, + lmp_year: { type: 'bsYear' }, + lmp_month: { type: 'bsMonth' }, + lmp_day: { type: 'bsDay' }, + lmp_date: { type: 'bsAggreDate', labels: { short: 'LMP Date' } } } } - }, - C: { - meta: { - code: formIdBSParts, - label: 'LMP with BS date parts' - }, - fields: { - name: { type: 'string', labels: { short: 'Name' } }, - lmp_year: { type: 'bsYear' }, - lmp_month: { type: 'bsMonth' }, - lmp_day: { type: 'bsDay' }, - lmp_date: { type: 'bsAggreDate', labels: { short: 'LMP Date' } } + }; + + const REGISTRATIONS = [ + { form: FORM_ID_BS, events: [{ name: 'on_create', trigger: 'add_expected_date' }] }, + { form: FORM_ID_BS_PARTS, events: [{ name: 'on_create', trigger: 'add_expected_date' }] } + ]; + + const TRANSITIONS = { registration: true }; + + const setLanguage = async (locale) => { + const localeCookie = 'locale'; + const existentCookie = await browser.getCookies(localeCookie); + if (existentCookie && existentCookie[0] && existentCookie[0].value === locale) { + return; } - } -}; - -const registrations = [ - { - form: formIdBS, - events: [{ name: 'on_create', trigger: 'add_expected_date' }] - }, - { - form: formIdBSParts, - events: [{ name: 'on_create', trigger: 'add_expected_date' }] - } -]; - -const transitions = { - registration: true -}; + await browser.setCookies({ name: localeCookie, value: locale }); + await browser.refresh(); + }; + + const getReports = async () => { + const options = { + path: '/_design/medic-client/_view/reports_by_date', + qs: { include_docs: true }, + }; + const response = await utils.requestOnMedicDb(options); + return response.rows.map(row => row.doc); + }; + + const setExistentReportDates = async (dates) => { + const reports = await getReports(); + dates.forEach((date, idx) => reports[idx].reported_date = moment(date).valueOf()); + return utils.saveDocs(reports); + }; + + const momentToBikParts = (mDate) => { + return bikramSambat.toBik(moment(mDate).format('YYYY-MM-DD')); + }; + + const momentToBikYMD = (mDate) => { + const bsDate = momentToBikParts(mDate); + return `${bsDate.year}-${bsDate.month}-${bsDate.day}`; + }; -describe('Bikram Sambat date display', () => { before(async () => { await chtConfUtils.initializeConfigDir(); - const contactSummaryFile = path.join(__dirname, 'bikram-sambat-contact-template-config.js'); + const contactSummaryFile = path.join(__dirname, 'config', 'bikram-sambat-contact-template-config.js'); const { contactSummary } = await chtConfUtils.compileNoolsConfig({ contactSummary: contactSummaryFile }); await utils.updateSettings( - { contact_summary: contactSummary, forms, registrations, transitions }, + { contact_summary: contactSummary, forms: FORMS, registrations: REGISTRATIONS, transitions: TRANSITIONS }, { ignoreReload: true } ); @@ -120,6 +100,7 @@ describe('Bikram Sambat date display', () => { after(async () => { await utils.revertDb([/^form:/], true); + await utils.revertSettings(true); }); it('enketo xpath extension function should display correct values when Nepali is not selected', async () => { @@ -129,16 +110,16 @@ describe('Bikram Sambat date display', () => { const date1 = '2021-01-01'; const dateBk1 = bikramSambat.toBik_text(date1); - await reportsPage.setDateInput('/bikram-sambat-dates/data/date1', date1); - expect(await reportsPage.getFieldValue('/bikram-sambat-dates/data/date1_text')).to.equal(dateBk1); - expect(await reportsPage.getSummaryField('/bikram-sambat-dates/summary/field1')).to.equal(`date1 = ${dateBk1}`); + await commonEnketoPage.setDateValue('Date 1', date1); + expect(await commonEnketoPage.getInputValue('to-bikram-sambat([date 1 path])')).to.equal(dateBk1); - const date2 = '2021-01-01'; + const date2 = '2021-02-02'; const dateBk2 = bikramSambat.toBik_text(date2); await reportsPage.setBikDateInput('/bikram-sambat-dates/data/date2', bikramSambat.toBik(date2)); - expect(await reportsPage.getFieldValue('/bikram-sambat-dates/data/date2_text')).to.equal(dateBk2); - expect(await reportsPage.getSummaryField('/bikram-sambat-dates/summary/field2')).to.equal(`date2 = ${dateBk2}`); + expect(await commonEnketoPage.getInputValue('to-bikram-sambat([date 2 path])')).to.equal(dateBk2); + + await commonEnketoPage.validateSummaryReport([dateBk1, dateBk2]); await genericForm.submitForm(); }); @@ -153,15 +134,15 @@ describe('Bikram Sambat date display', () => { const dateBk1 = bikramSambat.toBik_text(date1); await reportsPage.setBikDateInput('/bikram-sambat-dates/data/date1', bikramSambat.toBik(date1)); - expect(await reportsPage.getFieldValue('/bikram-sambat-dates/data/date1_text')).to.equal(dateBk1); - expect(await reportsPage.getSummaryField('/bikram-sambat-dates/summary/field1')).to.equal(`date1 = ${dateBk1}`); + expect(await commonEnketoPage.getInputValue('to-bikram-sambat([date 1 path])')).to.equal(dateBk1); - const date2 = '2021-01-01'; + const date2 = '2021-02-02'; const dateBk2 = bikramSambat.toBik_text(date2); await reportsPage.setBikDateInput('/bikram-sambat-dates/data/date2', bikramSambat.toBik(date2)); - expect(await reportsPage.getFieldValue('/bikram-sambat-dates/data/date2_text')).to.equal(dateBk2); - expect(await reportsPage.getSummaryField('/bikram-sambat-dates/summary/field2')).to.equal(`date2 = ${dateBk2}`); + expect(await commonEnketoPage.getInputValue('to-bikram-sambat([date 2 path])')).to.equal(dateBk2); + + await commonEnketoPage.validateSummaryReport([dateBk1, dateBk2]); await genericForm.submitForm(); }); @@ -243,7 +224,7 @@ describe('Bikram Sambat date display', () => { await gatewayApiUtils.api.postMessage({ id: 'lmp-id-bs', from: '+9779876543210', - content: `${formIdBS} Shrestha ${momentToBikYMD(tenWeeksAgo)}` + content: `${FORM_ID_BS} Shrestha ${momentToBikYMD(TEN_WEEKS_AGO)}` }); await commonPage.goToPeople(); @@ -251,8 +232,8 @@ describe('Bikram Sambat date display', () => { const firstReport = await reportsPage.leftPanelSelectors.firstReport(); await firstReport.click(); - const dateFormat = bikramSambat.toBik_text(tenWeeksAgo); - const relativeFormat = moment(tenWeeksAgo.toDate()).fromNow(); + const dateFormat = bikramSambat.toBik_text(TEN_WEEKS_AGO); + const relativeFormat = moment(TEN_WEEKS_AGO.toDate()).fromNow(); const lmpDateValue = await reportsPage.getReportDetailFieldValueByLabel('LMP Date'); expect(lmpDateValue).to.equal(`${dateFormat} (${relativeFormat})`); }); @@ -260,12 +241,12 @@ describe('Bikram Sambat date display', () => { it('SMS report shows bsAggreDate type as date field correctly', async () => { await setLanguage(NEPALI_LOCALE_CODE); moment.locale(NEPALI_LOCALE_CODE); - const lmpBSParts = momentToBikParts(nineWeeksAgo); + const lmpBSParts = momentToBikParts(NINE_WEEKS_AGO); await gatewayApiUtils.api.postMessage({ id: 'lmp-id-bs-parts', from: '+9779876543210', - content: `${formIdBSParts} Shrestha ` + + content: `${FORM_ID_BS_PARTS} Shrestha ` + `${lmpBSParts.year} ${lmpBSParts.month} ${lmpBSParts.day}` }); @@ -274,8 +255,8 @@ describe('Bikram Sambat date display', () => { const firstReport = await reportsPage.leftPanelSelectors.firstReport(); await firstReport.click(); - const dateFormat = bikramSambat.toBik_text(nineWeeksAgo); - const relativeFormat = moment(nineWeeksAgo.toDate()).fromNow(); + const dateFormat = bikramSambat.toBik_text(NINE_WEEKS_AGO); + const relativeFormat = moment(NINE_WEEKS_AGO.toDate()).fromNow(); const lmpDateValue = await reportsPage.getReportDetailFieldValueByLabel('LMP Date'); expect(lmpDateValue).to.equal(`${dateFormat} (${relativeFormat})`); }); diff --git a/tests/e2e/default/translations/new-language.wdio-spec.js b/tests/e2e/default/translations/new-language.wdio-spec.js index f184b53de10..16ee6e53765 100644 --- a/tests/e2e/default/translations/new-language.wdio-spec.js +++ b/tests/e2e/default/translations/new-language.wdio-spec.js @@ -8,17 +8,17 @@ const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const messagesPage = require('@page-objects/default/sms/messages.wdio.page'); -const ENG_LANG_CODE = 'en'; -const NEW_LANG_NAME = 'Afrikaans'; -const NEW_LANG_CODE = 'afr'; -const NEW_TRANSLATIONS = { - 'No messages found': 'Geen boodskappe gevind nie', - 'No contacts found': 'Geen mense gevind nie', - 'reports.none': 'Geen verslae gevind nie', - 'Analytics': 'Analytiks' -}; - describe('Adding new language', () => { + const ENG_LANG_CODE = 'en'; + const NEW_LANG_NAME = 'Afrikaans'; + const NEW_LANG_CODE = 'afr'; + const NEW_TRANSLATIONS = { + 'No messages found': 'Geen boodskappe gevind nie', + 'No contacts found': 'Geen mense gevind nie', + 'reports.none': 'Geen verslae gevind nie', + 'Analytics': 'Analytiks' + }; + const addTranslations = async (langCode, translations = {}) => { const waitForServiceWorker = await utils.waitForApiLogs(utils.SW_SUCCESSFUL_REGEX); await utils.addTranslations(langCode, translations); diff --git a/tests/e2e/default/users/add-user.wdio-spec.js b/tests/e2e/default/users/add-user.wdio-spec.js index 2fdff875d57..005b4023480 100644 --- a/tests/e2e/default/users/add-user.wdio-spec.js +++ b/tests/e2e/default/users/add-user.wdio-spec.js @@ -4,43 +4,29 @@ const placeFactory = require('@factories/cht/contacts/place'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const personFactory = require('@factories/cht/contacts/person'); -const onlineUserRole = 'program_officer'; -const offlineUserRole = 'chw'; -const username = 'jackuser'; -const password = 'Jacktest@123'; -const password2 = 'Jacktest@456'; -const username2 = 'jack_user'; -const incorrectpassword = 'Passwor'; -const places = placeFactory.generateHierarchy(); -const districtHospital = places.get('district_hospital'); -const districtHospital2 = placeFactory.place().build({ - name: 'district_hospital', - type: 'district_hospital', -}); - -const person = personFactory.build( - { - parent: { - _id: districtHospital._id, - parent: districtHospital.parent - }, - roles: [offlineUserRole] - } -); - - -const docs = [...places.values(), person, districtHospital2]; - describe('User Test Cases ->', () => { + const ONLINE_USER_ROLE = 'program_officer'; + const OFFLINE_USER_ROLE = 'chw'; + const USERNAME = 'jackuser'; + const PASSWORD = 'Jacktest@123'; + const USERNAME_2 = 'jack_user'; + const PASSWORD_2 = 'Jacktest@456'; + const INCORRECT_PASSWORD = 'Passwor'; + + const places = placeFactory.generateHierarchy(); + const districtHospital = places.get('district_hospital'); + const districtHospital2 = placeFactory.place().build({ + name: 'district_hospital', + type: 'district_hospital', + }); + + const person = personFactory.build({ parent: districtHospital, roles: [OFFLINE_USER_ROLE] }); before(async () => { const settings = await utils.getSettings(); - const permissions = { - ...settings.permissions, - can_have_multiple_places: [offlineUserRole], - }; + const permissions = { ...settings.permissions, can_have_multiple_places: [OFFLINE_USER_ROLE] }; await utils.updateSettings({ permissions }, { ignoreReload: true }); - await utils.saveDocs(docs); + await utils.saveDocs([...places.values(), person, districtHospital2]); await loginPage.cookieLogin(); }); @@ -52,85 +38,90 @@ describe('User Test Cases ->', () => { await usersAdminPage.openAddUserDialog(); }); + after(async () => { + await utils.revertSettings(true); + await utils.revertDb([/^form:/], true); + }); + describe('Creating Users ->', () => { - after(async () => await utils.deleteUsers([{ username: username }])); + after(async () => await utils.deleteUsers([{ username: USERNAME }])); it('should add user with valid password', async () => { await usersAdminPage.inputAddUserFields( - username, + USERNAME, 'Jack', - onlineUserRole, + ONLINE_USER_ROLE, districtHospital.name, person.name, - password + PASSWORD ); await usersAdminPage.saveUser(); - expect(await usersAdminPage.getAllUsernames()).to.include.members([username]); + expect(await usersAdminPage.getAllUsernames()).to.include.members([USERNAME]); }); it('should add user with multiple places with permission', async () => { await usersAdminPage.inputAddUserFields( 'new_jack', 'Jack', - offlineUserRole, + OFFLINE_USER_ROLE, [districtHospital.name, districtHospital2.name], person.name, - password + PASSWORD ); await usersAdminPage.saveUser(); - expect(await usersAdminPage.getAllUsernames()).to.include.members([username]); + expect(await usersAdminPage.getAllUsernames()).to.include.members([USERNAME]); }); it('should hide and reveal password value, and add user with a revealed password', async () => { await usersAdminPage.inputAddUserFields( - username2, + USERNAME_2, 'Jack', - onlineUserRole, + ONLINE_USER_ROLE, districtHospital.name, person.name, - password + PASSWORD ); let revealedPassword = await usersAdminPage.togglePassword(); expect(revealedPassword.type).to.equal('text'); - expect(revealedPassword.value).to.equal(password); + expect(revealedPassword.value).to.equal(PASSWORD); expect(revealedPassword.confirmType).to.equal('text'); - expect(revealedPassword.confirmValue).to.equal(password); + expect(revealedPassword.confirmValue).to.equal(PASSWORD); - await usersAdminPage.setUserPassword(password2); - await usersAdminPage.setUserConfirmPassword(password2); + await usersAdminPage.setUserPassword(PASSWORD_2); + await usersAdminPage.setUserConfirmPassword(PASSWORD_2); const hiddenPassword = await usersAdminPage.togglePassword(); expect(hiddenPassword.type).to.equal('password'); - expect(hiddenPassword.value).to.equal(password2); + expect(hiddenPassword.value).to.equal(PASSWORD_2); expect(hiddenPassword.confirmType).to.equal('password'); - expect(hiddenPassword.confirmValue).to.equal(password2); + expect(hiddenPassword.confirmValue).to.equal(PASSWORD_2); revealedPassword = await usersAdminPage.togglePassword(); expect(revealedPassword.type).to.equal('text'); - expect(revealedPassword.value).to.equal(password2); + expect(revealedPassword.value).to.equal(PASSWORD_2); expect(revealedPassword.confirmType).to.equal('text'); - expect(revealedPassword.confirmValue).to.equal(password2); + expect(revealedPassword.confirmValue).to.equal(PASSWORD_2); await usersAdminPage.saveUser(); - expect(await usersAdminPage.getAllUsernames()).to.include.members([username2]); + expect(await usersAdminPage.getAllUsernames()).to.include.members([USERNAME_2]); }); }); describe('Invalid entries -> ', () => { [ - { passwordValue: incorrectpassword, errorMessage: 'The password must be at least 8 characters long.' }, + { passwordValue: INCORRECT_PASSWORD, errorMessage: 'The password must be at least 8 characters long.' }, { passwordValue: 'weakPassword', errorMessage: 'The password is too easy to guess.' }, - { passwordValue: password, otherPassword: 'other-password', errorMessage: 'Passwords must match' }, + { passwordValue: PASSWORD, otherPassword: 'other-password', errorMessage: 'Passwords must match' }, { passwordValue: '', errorMessage: 'required' }, { passwordValue: '', errorMessage: 'required' } ].forEach(async (args) => { it(`TestCase for ${args.errorMessage}`, async () => { await usersAdminPage.inputAddUserFields( - username, + USERNAME, 'Jack', - onlineUserRole, + ONLINE_USER_ROLE, districtHospital.name, person.name, args.passwordValue, @@ -143,14 +134,16 @@ describe('User Test Cases ->', () => { }); it('should require username', async () => { - await usersAdminPage.inputAddUserFields('', 'Jack', onlineUserRole, districtHospital.name, person.name, password); + await usersAdminPage.inputAddUserFields( + '', 'Jack', ONLINE_USER_ROLE, districtHospital.name, person.name, PASSWORD + ); await usersAdminPage.saveUser(false); const text = await usersAdminPage.getUsernameErrorText(); expect(text).to.contain('required'); }); it('should require place and contact for restricted user', async () => { - await usersAdminPage.inputAddUserFields(username, 'Jack', offlineUserRole, null, null, password); + await usersAdminPage.inputAddUserFields(USERNAME, 'Jack', OFFLINE_USER_ROLE, null, null, PASSWORD); await usersAdminPage.saveUser(false); expect(await usersAdminPage.getPlaceErrorText()).to.contain('required'); expect(await usersAdminPage.getContactErrorText()).to.contain('required'); @@ -158,12 +151,12 @@ describe('User Test Cases ->', () => { it('should require user to have permission for multiple places', async () => { await usersAdminPage.inputAddUserFields( - username, + USERNAME, 'Jack', - onlineUserRole, + ONLINE_USER_ROLE, [districtHospital.name, districtHospital2.name], person.name, - password + PASSWORD ); await usersAdminPage.saveUser(false); expect(await usersAdminPage.getPlaceErrorText()).to.contain( diff --git a/tests/e2e/default/users/bulk-upload.wdio-spec.js b/tests/e2e/default/users/bulk-upload.wdio-spec.js index d6820885dd8..75dc4968959 100644 --- a/tests/e2e/default/users/bulk-upload.wdio-spec.js +++ b/tests/e2e/default/users/bulk-upload.wdio-spec.js @@ -26,7 +26,7 @@ describe('Bulk User Creation ->', () => { await usersAdminPage.inputUploadUsersFields(filePath); await usersAdminPage.uploadUsers(); await usersAdminPage.waitForUploadSummary(); - const successfulUploads = await usersAdminPage.getSuccessfulyUploadedUsers(); + const successfulUploads = await usersAdminPage.getSuccessfullyUploadedUsers(); const previouslyUploadedUsers = await usersAdminPage.getPreviouslyUploadedUsers(); const failedUploads = await usersAdminPage.getFailedUploadedUsers(); @@ -39,7 +39,7 @@ describe('Bulk User Creation ->', () => { await usersAdminPage.inputUploadUsersFields(filePath); await usersAdminPage.uploadUsers(); await usersAdminPage.waitForUploadSummary(); - const successfulUploadsSecondTime = await usersAdminPage.getSuccessfulyUploadedUsers(); + const successfulUploadsSecondTime = await usersAdminPage.getSuccessfullyUploadedUsers(); const previouslyUploadedUsersSecondTime = await usersAdminPage.getPreviouslyUploadedUsers(); const failedUploadsSecondTime = await usersAdminPage.getFailedUploadedUsers(); diff --git a/tests/e2e/default/users/create-meta-db.wdio-spec.js b/tests/e2e/default/users/create-meta-db.wdio-spec.js index 3fc07fcedc0..da553004b19 100644 --- a/tests/e2e/default/users/create-meta-db.wdio-spec.js +++ b/tests/e2e/default/users/create-meta-db.wdio-spec.js @@ -5,35 +5,35 @@ const commonPage = require('@page-objects/default/common/common.wdio.page'); const loginPage = require('@page-objects/default/login/login.wdio.page'); const uuid = require('uuid').v4; -const username = 'fulltester'; -const fullName = 'Roger Milla'; -const password = 'StrongP@ssword1'; - -const options = { - auth: { username: username, password }, - method: 'GET', - userName: username -}; - describe('Create user meta db : ', () => { + const USERNAME = 'fulltester'; + const FULL_NAME = 'Roger Milla'; + const PASSWORD = 'StrongP@ssword1'; + + const OPTIONS = { + auth: { username: USERNAME, password: PASSWORD }, + method: 'GET', + userName: USERNAME + }; before(async () => await loginPage.cookieLogin()); it('should allow a new user to read/write from meta db', async () => { await usersPage.goToAdminUser(); await usersPage.openAddUserDialog(); - await usersPage.inputAddUserFields(username, fullName, 'program_officer', '', '', password); + await usersPage.inputAddUserFields(USERNAME, FULL_NAME, 'program_officer', '', '', PASSWORD); await usersPage.saveUser(); + await commonPage.goToMessages(); await commonPage.logout(); - await loginPage.login({ username, password }); + await loginPage.login({ username: USERNAME, password: PASSWORD }); await commonPage.waitForPageLoaded(); await commonPage.goToReports(); const doc = { _id: uuid() }; - await utils.requestOnTestMetaDb(_.defaults({ method: 'POST', body: doc }, options)); + await utils.requestOnTestMetaDb(_.defaults({ method: 'POST', body: doc }, OPTIONS)); - const response = await utils.requestOnTestMetaDb(_.defaults({ path: '/_changes' }, options)); + const response = await utils.requestOnTestMetaDb(_.defaults({ path: '/_changes' }, OPTIONS)); const changes = response.results; const ids = changes.map(change => change.id); @@ -41,8 +41,8 @@ describe('Create user meta db : ', () => { // admins can also read and write from the users meta db const adminDoc = { _id: uuid() }; - await utils.requestOnTestMetaDb({ method: 'POST', body: adminDoc, userName: options.userName }); - const adminChanges = await utils.requestOnTestMetaDb({ path: '/_changes', userName: options.userName }); + await utils.requestOnTestMetaDb({ method: 'POST', body: adminDoc, userName: OPTIONS.userName }); + const adminChanges = await utils.requestOnTestMetaDb({ path: '/_changes', userName: OPTIONS.userName }); const adminChangeIds = adminChanges.results.map(change => change.id); expect(adminChangeIds).to.include.members(['_design/medic-user', doc._id, adminDoc._id]); }); diff --git a/tests/page-objects/default/common/common.wdio.page.js b/tests/page-objects/default/common/common.wdio.page.js index 3d2e371d606..938b8e20c1a 100644 --- a/tests/page-objects/default/common/common.wdio.page.js +++ b/tests/page-objects/default/common/common.wdio.page.js @@ -1,6 +1,7 @@ const modalPage = require('./modal.wdio.page'); const constants = require('@constants'); const aboutPage = require('@page-objects/default/about/about.wdio.page'); +const fs = require('fs'); const hamburgerMenu = () => $('aria/Application menu'); const closeSideBarMenu = () => $('.panel-header-close'); @@ -492,6 +493,28 @@ const getErrorLog = async () => { return { errorMessage, url, username, errorStack }; }; +const createFormDoc = (path, formId) => { + const id = formId ? formId : path.split('/').pop(); + const formXML = fs.readFileSync(`${path}.xml`, 'utf8'); + const formDoc = { + _id: `form:${id}`, + internalId: id, + title: id, + type: 'form', + context: { + person: true, + place: true, + }, + _attachments: { + xml: { + content_type: 'application/octet-stream', + data: Buffer.from(formXML).toString('base64'), + }, + }, + }; + return formDoc; +}; + module.exports = { openMoreOptionsMenu, closeFastActionList, @@ -558,4 +581,5 @@ module.exports = { reportsFastActionFAB, isReportActionDisplayed, getHeaderTitleOnMobile, + createFormDoc, }; diff --git a/tests/page-objects/default/enketo/common-enketo.wdio.page.js b/tests/page-objects/default/enketo/common-enketo.wdio.page.js index 83179793642..cd335d2bfd3 100644 --- a/tests/page-objects/default/enketo/common-enketo.wdio.page.js +++ b/tests/page-objects/default/enketo/common-enketo.wdio.page.js @@ -1,5 +1,3 @@ -const fs = require('fs'); -const utils = require('@utils'); const { formTitle } = require('@page-objects/default/enketo/generic-form.wdio.page'); const currentSection = () => $('section[class*="current"]'); @@ -60,6 +58,8 @@ const setInputValue = async (question, value) => { const setDateValue = async (question, value) => { await setValue('input.ignore.input-small', question, value); + //To close the date widget + await formTitle().click(); }; const setTextareaValue = async (question, value) => { @@ -80,30 +80,6 @@ const validateSummaryReport = async (textArray) => { } }; -const uploadForm = async (formName, saveDoc = true) => { - const formXML = fs.readFileSync(`${__dirname}/../../../e2e/default/enketo/forms/${formName}.xml`, 'utf8'); - const formDoc = { - _id: `form:${formName}`, - internalId: formName, - title: formName, - type: 'form', - context: { - person: true, - place: true, - }, - _attachments: { - xml: { - content_type: 'application/octet-stream', - data: Buffer.from(formXML).toString('base64'), - }, - }, - }; - if (saveDoc) { - await utils.saveDoc(formDoc); - } - return formDoc; -}; - const getValue = async (typeSelector, question) => { return await (await getCurrentPageSection()) .$(`label*=${question}`) @@ -170,7 +146,6 @@ module.exports = { setTextareaValue, addFileInputValue, validateSummaryReport, - uploadForm, getInputValue, getTextareaValue, isRequiredMessageDisplayed, diff --git a/tests/page-objects/default/enketo/create-user-for-contacts.js b/tests/page-objects/default/enketo/create-user-for-contacts.js new file mode 100644 index 00000000000..10ec1442805 --- /dev/null +++ b/tests/page-objects/default/enketo/create-user-for-contacts.js @@ -0,0 +1,39 @@ +const commonPage = require('@page-objects/default/common/common.wdio.page'); +const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); +const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page'); +const moment = require('moment/moment'); +const reportsPage = require('@page-objects/default/reports/reports.wdio.page'); + +const submitAddChwForm = async ({ + name: nameValue = 'Ron', + phone: phoneValue = '+40755696969', +} = {}) => { + await commonPage.openFastActionReport('add_chw'); + await commonEnketoPage.setInputValue('Name', nameValue); + await commonEnketoPage.setInputValue('Phone Number', phoneValue); + await genericForm.submitForm(); +}; + +const submitReplaceUserForm = async (formID, waitForPageLoaded = true) => { + await commonPage.openFastActionReport(formID); + await commonEnketoPage.setInputValue('Admin Code', '1234'); + await genericForm.nextPage(); + await commonEnketoPage.setInputValue('Full name', 'Replacement User'); + await commonEnketoPage.selectRadioButton('Sex', 'Female'); + await commonEnketoPage.setDateValue('Age', moment().subtract(22, 'years').format('YYYY-MM-DD')); + await genericForm.nextPage(); + await genericForm.submitForm({ waitForPageLoaded }); +}; + +const submitBasicForm = async () => { + await commonPage.openFastActionReport('basic_form', false); + await genericForm.submitForm(); + return reportsPage.getCurrentReportId(); +}; + + +module.exports = { + submitAddChwForm, + submitReplaceUserForm, + submitBasicForm, +}; diff --git a/tests/page-objects/default/enketo/replace-user.wdio.page.js b/tests/page-objects/default/enketo/replace-user.wdio.page.js deleted file mode 100644 index d49632a35fc..00000000000 --- a/tests/page-objects/default/enketo/replace-user.wdio.page.js +++ /dev/null @@ -1,54 +0,0 @@ -const SEX = { - female: 'female', - male: 'male' -}; - -const adminCodeField = () => $('input[name="/replace_user/intro/admin_code"]'); -const fullNameField = () => $('input[name="/replace_user/new_contact/name"]'); -const dobUnknownField = () => $('input[name="/replace_user/new_contact/ephemeral_dob/dob_method"]'); -const yearsField = () => $('input[name="/replace_user/new_contact/ephemeral_dob/age_years"]'); -const sexField = (sex) => $(`input[name="/replace_user/new_contact/sex"][value="${sex}"]`); -const warningMsgPhone = () => $('span[data-value=" /replace_user/new_contact_phone "]'); -const warningMsgContactName = () => $('span[data-value=" /replace_user/new_contact_name "]'); - -const selectAdminCode = async (code) => { - await (await adminCodeField()).waitForDisplayed(); - await (await adminCodeField()).setValue(code); -}; - -const selectContactFullName = async (name) => { - await (await fullNameField()).waitForDisplayed(); - await (await fullNameField()).setValue(name); -}; - -const selectContactDobUnknown = async () => { - await (await dobUnknownField()).waitForClickable(); - await (await dobUnknownField()).click(); -}; - -const selectContactAgeYears = async (years) => { - await (await yearsField()).waitForDisplayed(); - await (await yearsField()).setValue(years); -}; - -const selectContactSex = async (sex) => { - await (await sexField(sex)).waitForClickable(); - await (await sexField(sex)).click(); -}; - -const getWarningMsgDetails = async () => { - return { - phone: await warningMsgPhone().getText(), - contactName: await warningMsgContactName().getText(), - }; -}; - -module.exports = { - SEX, - selectAdminCode, - selectContactFullName, - selectContactDobUnknown, - selectContactAgeYears, - selectContactSex, - getWarningMsgDetails, -}; diff --git a/tests/page-objects/default/reports/reports.wdio.page.js b/tests/page-objects/default/reports/reports.wdio.page.js index bef97c85262..82577aa1dd9 100644 --- a/tests/page-objects/default/reports/reports.wdio.page.js +++ b/tests/page-objects/default/reports/reports.wdio.page.js @@ -1,6 +1,7 @@ const commonElements = require('@page-objects/default/common/common.wdio.page'); const modalPage = require('@page-objects/default/common/modal.wdio.page'); const utils = require('@utils'); +const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page'); const tabSelectors = { unreadCount: () => $('#reports-tab .mm-badge'), @@ -124,18 +125,8 @@ const setBikDateInput = async (name, date) => { await (await dateWidget.$('.dropdown-toggle')).click(); await (await (await dateWidget.$$('.dropdown-menu li'))[date.month - 1]).click(); await (await dateWidget.$('input[name="year"]')).setValue(date.year); -}; - -const getSummaryField = async (name) => { - const input = await $(`input[name="${name}"]`); - const summaryElement = await input.previousElement(); - return summaryElement.getText(); -}; - -const getFieldValue = async (name) => { - const input = await $(`input[name="${name}"]`); - await input.click(); - return input.getValue(); + //To close the date widget + await genericForm.formTitle().click(); }; const getElementText = async (element) => { @@ -514,9 +505,7 @@ module.exports = { filterByFacility, filterByStatus, setDateInput, - getFieldValue, setBikDateInput, - getSummaryField, reportsListDetails, selectAll, deselectAll, diff --git a/tests/page-objects/default/translations/languages.wdio.page.js b/tests/page-objects/default/translations/languages.wdio.page.js index c510b99aa37..e6f300eb298 100644 --- a/tests/page-objects/default/translations/languages.wdio.page.js +++ b/tests/page-objects/default/translations/languages.wdio.page.js @@ -28,8 +28,7 @@ const addNewLanguage = async (code, name) => { const languageDisplayed = async (code) => { const languageDiv = () => $(`#locale-${code}`); - const languageName = await (await languageDiv()).getText(); - return languageName; + return await (await languageDiv()).getText(); }; const selectLanguage = async (element, code) => { diff --git a/tests/page-objects/default/users/user.wdio.page.js b/tests/page-objects/default/users/user.wdio.page.js index 451bd8324dc..54b0566ab3b 100644 --- a/tests/page-objects/default/users/user.wdio.page.js +++ b/tests/page-objects/default/users/user.wdio.page.js @@ -1,5 +1,6 @@ const _ = require('lodash'); const commonElements = require('../common/common.wdio.page'); + const addUserButton = () => $('a#add-user'); const cancelButton = () => $('a[test-id="modal-cancel-btn"]'); const addUserDialog = () => $('div#edit-user-profile'); @@ -21,7 +22,7 @@ const uploadUsersButton = () => $('a#add-users'); const uploadUsersDialog = () => $('div#bulk-user-upload'); const confirmUploadUsersButton = () => $('a#upload-btn'); const uploadSummaryDialog = () => $('#finish-summary'); -const successfulyUploadedUsers = () => $('p.text-success'); +const successfullyUploadedUsers = () => $('p.text-success'); const previouslyUploadedUsers = () => $('p.text-muted'); const failedUploadedUsers = () => $('p.text-danger'); const backToUserListButton = () => $('a#back-to-app-btn'); @@ -187,8 +188,8 @@ const getContactErrorText = async () => { return await (await contactErrorMessage()).getText(); }; -const getSuccessfulyUploadedUsers = async () => { - return await (await successfulyUploadedUsers()).getText(); +const getSuccessfullyUploadedUsers = async () => { + return await (await successfullyUploadedUsers()).getText(); }; const getPreviouslyUploadedUsers = async () => { @@ -243,7 +244,7 @@ module.exports = { inputUploadUsersFields, uploadUsers, waitForUploadSummary, - getSuccessfulyUploadedUsers, + getSuccessfullyUploadedUsers, getPreviouslyUploadedUsers, getFailedUploadedUsers, backToUserList,