ngapimockid cookie is set too late
The problem i'm seeing is that the ngapimockid cookie is set too late, causing the calls to the (mock) backend to lack the cookie and always returning the default mocks, eventhough i'm calling selectScenario. See my analysis below.
When i add some console.log calls to my onPrepare method in protractor.conf and to the ng-apimock/lib/utils ngApimockRequest function, i see the following behavior:
PUT /ngapimock/mocks/defaults c3b27ce7-503a-4069-900c-60087b52471e
This is the setAllScenariosToDefault() call. The uuid is the ngapimockid value.
I then see the front-end doing a call: GET /teacher/groups undefined. The undefined here is the ngapimockid value.
After that, i get the console.log i put in the "hooker" code in .tmp/ngApimock/protractor.mock.js:
require('hooker').hook(browser, 'get', {
post: function (result) {
return result.then(function () {
// Since protractor 5.0.0 the addCookie is an object, see
// https://github.com/angular/protractor/blob/master/CHANGELOG.md#500
try {
console.log('setting ngapimockid cookie');
return browser.manage().addCookie({name: "ngapimockid", value: ngapimockid});
} catch (error) {
// Fallback protractor < 5.0.0
return browser.manage().addCookie('ngapimockid', ngapimockid);
}
});
}
});
When i add a browser.sleep(60000); in my it() and then refresh the browser, the ngapimockid cookie is present and passed to the mock server. I then get the appropriate mock back.
@jpzwarte
Can you please share your code that sets the state? I'm using ng-apimock for more than 2 years now and don't have problems with it. My first guess would be a promise implementation on your side.
@wswebcreation see https://gist.github.com/jpzwarte/a98149513b0f7437d3957d07abe79da8
@wswebcreation @mdasberg the hack below works 💪
// HACK: intercept the uuid call that ng-apimock makes in order to
// get the ngapimockid. There's a bug where the cookie is set too late,
// so fix that by doing it ourselves.
const uuid = require('../node_modules/ng-apimock/node_modules/uuid'),
originalFn = uuid.v4;
let ngapimockId;
uuid.v4 = function () {
const result = ngapimockId = originalFn();
return result;
}
// We need to be on a page in order to set the cookies
browser.driver.get(browser.baseUrl);
// Load ngApimock
global['ngApimock'] = require('../.tmp/ngApimock/protractor.mock.js');
beforeEach(() => global['ngApimock'].setAllScenariosToDefault());
// Manually set ngapimockid cookie
browser.manage().addCookie({ name: 'ngapimockid', value: ngapimockId });
@jpzwarte
I never relied on the control-flow of Protractor, so I don't know if
fit('should show a placeholder when no groups exist', () => {
ngApimock.selectScenario('teacher-groups', 'empty');
page.navigateTo();
page.sleep(60000);
expect(page.chooseExistingGroups.animation).toBeDisplayed();
expect(page.chooseExistingGroups.pointers).toBeDisplayed();
});
Works.
In my setup I'd always use this
fit('should show a placeholder when no groups exist', async () => {
await ngApimock.selectScenario('teacher-groups', 'empty');
await page.navigateTo();
expect(await page.chooseExistingGroups.animation).toBeDisplayed();
expect(await page.chooseExistingGroups.pointers).toBeDisplayed();
});
And this never gives problems
I thought about this, for example i tried adding async/wait for the selectScenario call and a browser.sleep() before the page.navigateTo() but that didn't work. Anyway, i heard via some people that this issue may be fixed in another branch and may be backported. In the mean time i'll use my hack :)
👍
Can we close the issue then?
The bug report is still valid right? If so, i would keep it open to track progress.