Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#7375): service worker auto update #9417

Merged
merged 37 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1355ca5
move moment-locales-webpack-plugin to webapp
dianabarsan Aug 29, 2024
95d9705
handle organic service worker updates
dianabarsan Aug 30, 2024
d0f57a1
Merge branch 'master' into 7375-service-worker-auto-update
dianabarsan Aug 30, 2024
6a0b335
change how we try to sync
dianabarsan Sep 5, 2024
ab6baf8
Merge remote-tracking branch 'origin/master' into 7375-service-worker…
dianabarsan Sep 6, 2024
878c1ae
close modal before hamburger menu
dianabarsan Sep 6, 2024
5f6f1bd
close modal before hamburger menu
dianabarsan Sep 6, 2024
119c976
close modal before hamburger menu
dianabarsan Sep 7, 2024
d0df488
close modal before hamburger menu
dianabarsan Sep 20, 2024
d30ecb0
Merge remote-tracking branch 'origin/master' into 7375-service-worker…
dianabarsan Sep 23, 2024
b532821
update sync retry
dianabarsan Sep 24, 2024
2d3660c
fix linting
dianabarsan Sep 24, 2024
77d8f9a
wait for a standard amount of time
dianabarsan Sep 24, 2024
727b5f8
try with longer pause
dianabarsan Sep 24, 2024
ae17825
try with longer pause
dianabarsan Sep 24, 2024
849aa42
try with longer pause
dianabarsan Sep 25, 2024
99757cb
try with longer pause
dianabarsan Sep 25, 2024
da63297
try with longer pause
dianabarsan Sep 25, 2024
5f1feca
try with longer pause
dianabarsan Sep 25, 2024
a2205d9
try with longer pause
dianabarsan Sep 25, 2024
7e0cc39
try with longer pause
dianabarsan Sep 25, 2024
344c1dd
try with longer pause
dianabarsan Sep 25, 2024
c4158fd
try with longer pause
dianabarsan Sep 25, 2024
b49caa8
try with longer pause
dianabarsan Sep 26, 2024
8984619
try with longer pause
dianabarsan Sep 26, 2024
7d70f7d
try with longer pause
dianabarsan Sep 26, 2024
595ef11
Merge remote-tracking branch 'origin/master' into 7375-service-worker…
dianabarsan Oct 14, 2024
4d2586b
delete feedback docs when sync failures are expected.
dianabarsan Oct 16, 2024
04cb549
What is this value?
dianabarsan Oct 16, 2024
4a61dce
Merge remote-tracking branch 'refs/remotes/origin/master' into 7375-s…
dianabarsan Oct 16, 2024
707b8ce
resolve conflicts
dianabarsan Oct 16, 2024
e22ddc5
fix sync on client side muting
dianabarsan Oct 16, 2024
06e806c
try with longer pause
dianabarsan Oct 28, 2024
275d38f
wait for both
dianabarsan Oct 28, 2024
0ada33c
disable muting again. omg.
dianabarsan Oct 30, 2024
529229d
cleanup
dianabarsan Oct 31, 2024
7b5c4b4
add comment and be clear it's not the browser we're waiting for.
dianabarsan Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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