Skip to content

Commit

Permalink
Merge branch 'master' into 9543-flaky-e2e-test-incorrect-locale
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafa committed Nov 7, 2024
2 parents 2cb63bf + 6876239 commit 4778d74
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 29 deletions.
24 changes: 18 additions & 6 deletions scripts/docker-helper/cht-docker-compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ required_apps_installed(){
echo "${error}"
}

docker_not_installed(){
# special check for docker. We want to be sure both "docker" is installed AND
# that "docker compose" is installed. We deprecated "docker-compose" in CHT Core #8781
if [ -n "$(required_apps_installed "docker")" ];then
echo "Docker not installed"
else
docker compose &>/dev/null || echo "Docker Compose not installed"
fi
}

port_open(){
ip=$1
port=$2
Expand Down Expand Up @@ -186,9 +196,9 @@ docker_up_or_restart(){
sleep 3

# haproxy never starts on first "up" call, so you know, call it twice ;)
docker-compose --env-file "${envFile}" -f "${composeFile}" down >/dev/null 2>&1
docker-compose --env-file "${envFile}" -f "${composeFile}" up -d >/dev/null 2>&1
docker-compose --env-file "${envFile}" -f "${composeFile}" up -d >/dev/null 2>&1
docker compose --env-file "${envFile}" -f "${composeFile}" down >/dev/null 2>&1
docker compose --env-file "${envFile}" -f "${composeFile}" up -d >/dev/null 2>&1
docker compose --env-file "${envFile}" -f "${composeFile}" up -d >/dev/null 2>&1
}

install_local_ip_cert(){
Expand Down Expand Up @@ -237,7 +247,7 @@ local_ip_cert_expired(){
docker_down(){
envFile=$1
composeFile=$2
docker-compose --env-file "${envFile}" -f "${composeFile}" down >/dev/null 2>&1
docker compose --env-file "${envFile}" -f "${composeFile}" down >/dev/null 2>&1
}

docker_destroy(){
Expand Down Expand Up @@ -406,14 +416,16 @@ main (){
fi

# after valid env file is loaded, let's set all our constants
declare -r APP_STRING="docker;docker-compose;grep;head;cut;tr;nc;curl;file;wc;awk;tail;dirname"
declare -r APP_STRING="grep;head;cut;tr;nc;curl;file;wc;awk;tail;dirname"
declare -r MAX_REBOOTS=5
declare -r DEFAULT_SLEEP=$((60 * $((reboot_count + 1))))
declare -r ALL_IMAGES="medicmobile/medic-os:cht-3.9.0-rc.2 medicmobile/haproxy:rc-1.17"

# with constants set, let's ensure all the apps are present, exit if not
appStatus=$(required_apps_installed "$APP_STRING")
if [ -n "$appStatus" ]; then
dockerStatus=$(docker_not_installed)
allStatus="${appStatus}${dockerStatus}"
if [ -n "$allStatus" ]; then
window "WARNING: Missing Apps - (USE WITH CHT 3.x ONLY!)" "red" "100%"
append "Install before proceeding:"
append "$appStatus"
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/default/db/initial-replication.wdio-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ describe('initial-replication', () => {
setTimeout(() => browser.refresh(), 3000);
setTimeout(() => browser.refresh(), 5000);

await utils.delayPromise(5000); // wait for above timers to expire
await commonPage.waitForPageLoaded();
await validateReplication();
});
Expand Down
45 changes: 26 additions & 19 deletions tests/page-objects/default/common/common.wdio.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const FEEDBACK = '#feedback';
//About menu
const ABOUT_MENU = 'aria/About';
//Configuration App
const ELEMENT_DISPLAY_PAUSE = 500; // 500ms

const configurationAppMenuOption = () => $('aria/App Management');
const errorLog = () => $(`error-log`);
const sideBarMenuTitle = () => $('aria/Menu');
Expand All @@ -72,7 +74,7 @@ const waitForSnackbarToClose = async () => {

const clickFastActionById = async (id) => {
// Wait for the Angular Material's animation to complete.
await browser.pause(500);
await browser.pause(ELEMENT_DISPLAY_PAUSE);
await (await fastActionListContainer()).waitForDisplayed();
await (await fastActionById(id)).waitForClickable();
await (await fastActionById(id)).click();
Expand Down Expand Up @@ -107,7 +109,7 @@ const getFastActionItemsLabels = async () => {
await fab.waitForClickable();
await fab.click();

await browser.pause(500);
await browser.pause(ELEMENT_DISPLAY_PAUSE);
await (await fastActionListContainer()).waitForDisplayed();

const items = await fastActionItems();
Expand Down Expand Up @@ -202,10 +204,9 @@ const openHamburgerMenu = async () => {
if (!(await isHamburgerMenuOpen())) {
await (await hamburgerMenu()).waitForClickable();
await (await hamburgerMenu()).click();
// Adding pause here as we have to wait for sidebar nav menu animation to load
await browser.pause(ELEMENT_DISPLAY_PAUSE);
}

// Adding pause here as we have to wait for sidebar nav menu animation to load
await browser.pause(500);
await (await sideBarMenuTitle()).waitForDisplayed();
};

Expand Down Expand Up @@ -345,16 +346,25 @@ const syncAndNotWaitForSuccess = async () => {
await (await syncButton()).click();
};

const syncAndWaitForSuccess = async (timeout = 20000) => {
await openHamburgerMenu();
await (await syncButton()).waitForClickable();
await (await syncButton()).click();
await closeReloadModal(false);
await openHamburgerMenu();
if (await (await syncInProgress()).isExisting()) {
await (await syncInProgress()).waitForDisplayed({ reverse: true, timeout });
const syncAndWaitForSuccess = async (timeout = 20000, retry = 10) => {
if (retry < 0) {
throw new Error('Failed to sync after 10 retries');
}
await closeReloadModal(false, 0);

try {
await openHamburgerMenu();
if (!await (await syncInProgress()).isExisting()) {
await (await syncButton()).click();
await openHamburgerMenu();
}

await (await syncInProgress()).waitForDisplayed({ timeout, reverse: true });
await (await syncSuccess()).waitForDisplayed({ timeout });
} catch (err) {
console.error(err);
await syncAndWaitForSuccess(timeout, retry - 1);
}
await (await syncSuccess()).waitForDisplayed({ timeout });
};

const hideModalOverlay = () => {
Expand All @@ -372,15 +382,13 @@ const sync = async (expectReload, timeout) => {
let closedModal = false;
if (expectReload) {
// it's possible that sync already happened organically, and we already have the reload modal
closedModal = await closeReloadModal();
closedModal = await closeReloadModal(false, 0);
}

await syncAndWaitForSuccess(timeout);
if (expectReload && !closedModal) {
await closeReloadModal();
}
// sync status sometimes lies when multiple changes are fired in quick succession
await syncAndWaitForSuccess(timeout);
await closeHamburgerMenu();
};

Expand All @@ -393,12 +401,11 @@ const syncAndWaitForFailure = async () => {

const closeReloadModal = async (shouldUpdate = false, timeout = 5000) => {
try {
await browser.waitUntil( async () => await modalPage.modal().isDisplayed(), { timeout: 10000, interval: 500 } );
shouldUpdate ? await modalPage.submit(timeout) : await modalPage.cancel(timeout);
shouldUpdate && await waitForAngularLoaded();
return true;
} catch (err) {
console.error('Reload modal not showed up');
timeout && console.error('Reload modal has not showed up');
return false;
}
};
Expand Down
2 changes: 2 additions & 0 deletions webapp/src/ts/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ export class AppComponent implements OnInit, AfterViewInit {
}

private watchDDocChanges() {
this.updateServiceWorker.update(() => this.ngZone.run(() => this.showUpdateReady()));

this.changesService.subscribe({
key: 'ddoc',
filter: (change) => {
Expand Down
2 changes: 0 additions & 2 deletions webapp/src/ts/services/form.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as medicXpathExtensions from '../../js/enketo/medic-xpath-extensions';
import { DbService } from '@mm-services/db.service';
import { FileReaderService } from '@mm-services/file-reader.service';
import { LineageModelGeneratorService } from '@mm-services/lineage-model-generator.service';
import { SearchService } from '@mm-services/search.service';
import { SubmitFormBySmsService } from '@mm-services/submit-form-by-sms.service';
import { UserContactService } from '@mm-services/user-contact.service';
import { XmlFormsService } from '@mm-services/xml-forms.service';
Expand Down Expand Up @@ -46,7 +45,6 @@ export class FormService {
private dbService: DbService,
private fileReaderService: FileReaderService,
private lineageModelGeneratorService: LineageModelGeneratorService,
private searchService: SearchService,
private submitFormBySmsService: SubmitFormBySmsService,
private userContactService: UserContactService,
private userSettingsService:UserSettingsService,
Expand Down
24 changes: 22 additions & 2 deletions webapp/tests/karma/ts/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { UserSettingsService } from '@mm-services/user-settings.service';
import { FormService } from '@mm-services/form.service';
import { OLD_NAV_PERMISSION } from '@mm-components/header/header.component';
import { SidebarMenuComponent } from '@mm-components/sidebar-menu/sidebar-menu.component';
import { ReloadingComponent } from '@mm-modals/reloading/reloading.component';

describe('AppComponent', () => {
let component: AppComponent;
Expand Down Expand Up @@ -89,6 +90,7 @@ describe('AppComponent', () => {
let trainingCardsService;
let userSettingsService;
let formService;
let updateServiceWorkerService;
// End Services

let globalActions;
Expand Down Expand Up @@ -123,7 +125,11 @@ describe('AppComponent', () => {
unreadRecordsService = { init: sinon.stub() };
setLanguageService = { set: sinon.stub() };
translateService = { instant: sinon.stub().returnsArg(0) };
modalService = { show: sinon.stub().resolves() };
modalService = {
show: sinon.stub().returns({
afterClosed: sinon.stub().returns(of())
})
};
browserDetectorService = { isUsingOutdatedBrowser: sinon.stub().returns(false) };
chtDatasourceService = { isInitialized: sinon.stub() };
analyticsModulesService = { get: sinon.stub() };
Expand Down Expand Up @@ -175,6 +181,7 @@ describe('AppComponent', () => {
trainingCardsService = { initTrainingCards: sinon.stub() };
userSettingsService = { get: sinon.stub().resolves({ facility_id: ['facility'], contact_id: 'contact' }) };
formService = { setUserContext: sinon.stub() };
updateServiceWorkerService = { update: sinon.stub() };
consoleErrorStub = sinon.stub(console, 'error');

const mockedSelectors = [
Expand Down Expand Up @@ -203,7 +210,7 @@ describe('AppComponent', () => {
{ provide: AuthService, useValue: authService },
{ provide: ResourceIconsService, useValue: resourceIconsService },
{ provide: ChangesService, useValue: changesService },
{ provide: UpdateServiceWorkerService, useValue: {} },
{ provide: UpdateServiceWorkerService, useValue: updateServiceWorkerService },
{ provide: LocationService, useValue: locationService },
{ provide: ModalService, useValue: modalService },
{ provide: BrowserDetectorService, useValue: browserDetectorService},
Expand Down Expand Up @@ -282,6 +289,19 @@ describe('AppComponent', () => {
expect(userSettingsService.get.calledOnce).to.equal(true);
expect(globalActions.setUserFacilityIds.calledOnceWith(['facility'])).to.equal(true);
expect(globalActions.setUserContactId.calledOnceWith('contact')).to.equal(true);
expect(updateServiceWorkerService.update.callCount).to.equal(1);
});

it('should show reload popup when service worker is updated', async () => {
await getComponent();
await component.setupPromise;

expect(updateServiceWorkerService.update.callCount).to.equal(1);
const callback = updateServiceWorkerService.update.args[0][0];
callback();
expect(modalService.show.calledOnce).to.be.true;
expect(modalService.show.args[0]).to.have.deep.members([ReloadingComponent]);

});

it('should display browser compatibility modal if using outdated chrome browser', async () => {
Expand Down

0 comments on commit 4778d74

Please sign in to comment.