Search code examples
angularkarma-jasminekarma-runnerangular-test

Karma tests randomly restart and "double" iframe in Edge


I have a suite of Karma/Jasmine tests for my Angular 7 app. All my tests pass in Chrome and Firefox, but when I run them in Edge it will run for a little bit and then sometimes it will randomly reload the page and start over, and sometimes it will load karma again into the iframe, thus "doubling" it.

Here's what it looks like

double karma tests

However, when I click the "Debug" button it opens a new tab and all the tests run fine in there with no failures.

success debug karma tests

And here's what my console output looks like. you can see it runs a few tests and then just restarts them

enter image description here


What is going on here?

Why would it behave this way in Edge when there are no test failures?


Solution

  • I figured out what was wrong, and it turned out to be a navigation issue.

    I had a component with a href="#" in the template like this: <a href="#" (click)="doSomething($event)"> and then handled like this:

    doSomething($event: Event): void {
      $event.preventDefault();
      someService.whatever();
    }
    

    in my test I had something like this

    it('should call the doSomething() method when a link is clicked', () => {
        spyOn(component, 'doSomething');
    
        const link: HTMLAnchorElement = debugEl.query(By.css('a')).nativeElement;
        link.click();
        fixture.detectChanges();
    
        expect(component.doSomething).toHaveBeenCalled();
    });
    

    but this caused Edge (and not other browsers for some reason) to attempt to navigate to the # which caused the tests to reload. The solution was to just add .and.callThrough() so that the component can just run the $event.preventDefault() to prevent the navigation in the tests.

    So, the above test now just looks like this

    it('should call the doSomething() method when a link is clicked', () => {
        spyOn(component, 'doSomething').and.callThrough(); //call through to run preventDefault() on the click event
    
        const link: HTMLAnchorElement = debugEl.query(By.css('a')).nativeElement;
        link.click();
        fixture.detectChanges();
    
        expect(component.doSomething).toHaveBeenCalled();
    });