ng-apimock icon indicating copy to clipboard operation
ng-apimock copied to clipboard

ngapimockid cookie is set too late

Open jpzwarte opened this issue 7 years ago • 7 comments

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 avatar Jul 04 '18 08:07 jpzwarte

@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 avatar Jul 04 '18 08:07 wswebcreation

@wswebcreation see https://gist.github.com/jpzwarte/a98149513b0f7437d3957d07abe79da8

jpzwarte avatar Jul 04 '18 08:07 jpzwarte

@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 avatar Jul 04 '18 09:07 jpzwarte

@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

wswebcreation avatar Jul 04 '18 11:07 wswebcreation

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 :)

jpzwarte avatar Jul 04 '18 11:07 jpzwarte

👍

Can we close the issue then?

wswebcreation avatar Jul 04 '18 12:07 wswebcreation

The bug report is still valid right? If so, i would keep it open to track progress.

jpzwarte avatar Jul 04 '18 12:07 jpzwarte