Search code examples
javascriptwebiframekarma-runnerbrowser-history

history.back not behaving as expected in Karma


When I run a basic test case like this:

  fdescribe('Browser back button', () => {

    fit('should return to previous', async () => {

      const originalHref = window.location.href;
      window.history.pushState({}, 'Test', '/test');
      window.history.back();  // This doesn't seem to be working.
      expect(window.location.href).toEqual(originalHref);
    });

I get a failure with the message "Expected 'http://localhost:9876/test' to equal 'http://localhost:9876/context.html'." So clearly the pushState() worked but the back() did not.

Karma runs tests in an inner iframe. When I paste the first three lines in order into the browser's JavaScript console, the navigation works as expected. So there must be something different between the behavior of the window and the behavior of the inner iframe in this case.

This is Karma 5.1 on Chrome.

Any thoughts?


Solution

  • The issue is that history.back() API is asynchronous

    This method is asynchronous. Add a listener for the popstate event in order to determine when the navigation has completed.

    So the navigation back is triggered but the test does not wait for it to complete and the check fails.

    We need to convert the test into an asynchronous one by adding done param (it's one method I know, maybe there are other ways too). And use popstate event handler to wait for navigation and complete the test.

    fdescribe('Browser back button', () => {
      fit('should return to previous', (done) => {
        const originalHref = window.location.href;
        window.history.pushState({}, 'Test', '/test');
    
        window.history.back(); // gets executed asynchonously
        window.addEventListener('popstate', () => {
          // history.back() is done now
          expect(window.location.href).toEqual(originalHref);
          done();
        })
      });
    });