Skip to content

Commit

Permalink
delete feedback docs when sync failures are expected.
Browse files Browse the repository at this point in the history
  • Loading branch information
dianabarsan committed Oct 16, 2024
1 parent 595ef11 commit 4d2586b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,30 @@ const waitForConflicts = async (getDoc) => {
return utils.delayPromise(waitForConflicts(getDoc), 100);
};

/**
* 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();
}
};

describe('Create user for contacts', () => {
before(async () => {
await utils.saveDocIfNotExists(BASIC_FORM_DOC);
Expand Down Expand Up @@ -245,7 +269,12 @@ describe('Create user for contacts', () => {
expect(district.contact._id).to.equal(replacementContactId);

await browser.throttle('online');
await commonPage.syncAndNotWaitForSuccess();
try {
await commonPage.syncAndNotWaitForSuccess();
} catch {
// sync can happen organically
}

await (await loginPage.loginButton()).waitForDisplayed();

await sentinelUtils.waitForSentinel();
Expand Down Expand Up @@ -284,6 +313,8 @@ describe('Create user for contacts', () => {
const basicReport3 = await utils.getDoc(basicReportId3);
// New reports written by the old user are not re-parented
expect(basicReport3.contact._id).to.equal(originalContactId);

await assertFeedbackDocs();
});

it('creates a new user when the replace_user form is submitted while online', async () => {
Expand Down Expand Up @@ -332,6 +363,8 @@ describe('Create user for contacts', () => {
await commonPage.waitForPageLoaded();
const [cookie] = await browser.getCookies('userCtx');
expect(cookie.value).to.include(newUserSettings.name);

await assertFeedbackDocs();
});

it('does not assign new person as primary contact of parent place ' +
Expand Down Expand Up @@ -384,6 +417,8 @@ describe('Create user for contacts', () => {
await commonPage.waitForPageLoaded();
const [cookie] = await browser.getCookies('userCtx');
expect(cookie.value).to.include(newUserSettings.name);

await assertFeedbackDocs();
});

it('creates new user from latest replace_user form data ' +
Expand Down Expand Up @@ -449,7 +484,11 @@ describe('Create user for contacts', () => {
expect(district.contact._id).to.equal(replacementContactId1);

await browser.throttle('online');
await commonPage.syncAndNotWaitForSuccess();
try {
await commonPage.syncAndNotWaitForSuccess();
} catch {
// sync can happen organically
}
await (await loginPage.loginButton()).waitForDisplayed();

await sentinelUtils.waitForSentinel();
Expand Down Expand Up @@ -481,6 +520,8 @@ describe('Create user for contacts', () => {
// Basic form reports were successfully synced to the server
const basicReportsFromRemote = await utils.getDocs([basicReportId0, basicReportId1]);
basicReportsFromRemote.forEach((report, index) => expect(report).to.deep.equal(basicReports[index]));

await assertFeedbackDocs();
});

it('creates new user when replace_user form is submitted ' +
Expand Down Expand Up @@ -548,6 +589,8 @@ describe('Create user for contacts', () => {
await loginPage.login(otherUser);
await commonPage.waitForPageLoaded();
await commonPage.goToPeople(originalContactId);

await assertFeedbackDocs();
});

it('creates new user for the first version of a contact ' +
Expand Down Expand Up @@ -668,6 +711,8 @@ describe('Create user for contacts', () => {
// be deleted. This first call will delete the current "winning" version and then the subsequent call in
// afterEach will handle deleting the other version.
await utils.revertDb([/^form:/], true);

await assertFeedbackDocs();
});

it('does not create a new user or re-parent reports when the transition is disabled', async () => {
Expand Down Expand Up @@ -743,7 +788,11 @@ describe('Create user for contacts', () => {
await chtDbUtils.updateDoc(newContact._id, { ...newContact, phone: undefined }, true);

await browser.throttle('online');
await commonPage.syncAndNotWaitForSuccess();
try {
await commonPage.syncAndNotWaitForSuccess();
} catch {
// sync can happen organically
}
await (await loginPage.loginButton()).waitForDisplayed();

await sentinelUtils.waitForSentinel();
Expand Down
23 changes: 10 additions & 13 deletions tests/page-objects/default/common/common.wdio.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const fastActionListCloseButton = () => $(`${FAST_ACTION_LIST_CONTAINER} .panel-
const fastActionById = (id) => $(`${FAST_ACTION_LIST_CONTAINER} .fast-action-item[test-id="${id}"]`);
const fastActionItems = () => $$(`${FAST_ACTION_LIST_CONTAINER} .fast-action-item`);
const moreOptionsMenu = () => $('aria/Actions menu');
const hamburgerMenuItemSelector = '#header-dropdown li';
const hamburgerMenuItemSelector = 'mat-sidenav-content';
const logoutButton = () => $('aria/Log out');
const syncButton = () => $('aria/Sync now');
const messagesTab = () => $('#messages-tab');
Expand All @@ -26,9 +26,8 @@ const getTasksButtonLabel = () => $('#tasks-tab .button-label');
const getAllButtonLabels = async () => await $$('.header .tabs .button-label');
const loaders = () => $$('.container-fluid .loader');
const syncSuccess = () => $('aria/All reports synced');
const syncInProgress = () => $('*="Currently syncing"');
const syncRequired = () => $(`${hamburgerMenuItemSelector}.sync-status .required`);
const syncDone = () => $(`${hamburgerMenuItemSelector}.sync-status :is(.required,.success)`);
const syncInProgress = () => $(hamburgerMenuItemSelector).$('*="Currently syncing"');
const syncRequired = () => $(`${hamburgerMenuItemSelector} .sync-status .required`);
const jsonError = async () => (await $('pre')).getText();
const REPORTS_CONTENT_SELECTOR = '#reports-content';
const reportsFastActionFAB = () => $(`${REPORTS_CONTENT_SELECTOR} .fast-action-fab-button mat-icon`);
Expand Down Expand Up @@ -350,23 +349,22 @@ const syncAndNotWaitForSuccess = async () => {
};

const syncAndWaitForSuccess = async (timeout = 20000, retry = 10) => {
console.log('retry', retry, new Date().toISOString());
if (retry < 0) {
throw new Error('Failed to sync after 10 retries');
}
await closeReloadModal(false, 0);
await openHamburgerMenu();

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

await (await syncInProgress()).waitForDisplayed({ timeout, reverse: true });
await (await syncDone()).waitForDisplayed({ timeout });
try {
await (await syncInProgress()).waitForDisplayed({ timeout, reverse: true });
await (await syncSuccess()).waitForDisplayed({ timeout: ELEMENT_DISPLAY_PAUSE });
} catch (err) {
console.error(err);
await syncAndWaitForSuccess(timeout, retry - 1);
}
};
Expand Down Expand Up @@ -407,7 +405,6 @@ 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;
Expand Down

0 comments on commit 4d2586b

Please sign in to comment.