Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Navigation triggered outside Angular zone" warning in unit tests #25837

Closed
cexbrayat opened this issue Sep 6, 2018 · 34 comments
Closed

"Navigation triggered outside Angular zone" warning in unit tests #25837

cexbrayat opened this issue Sep 6, 2018 · 34 comments
Assignees
Labels
area: router area: testing Issues related to Angular testing features, such as TestBed area: zones freq3: high P4 A relatively minor issue that is not relevant to core functions state: confirmed type: bug/fix
Milestone

Comments

@cexbrayat
Copy link
Member

I'm submitting a...


[x] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

Using the last Angular 6.1.7 which introduced a warning if a navigation is triggered outside a zone (see 010e35d),
a simple unit test calling router.navigate yields the warning (resulting in hundreds of warnings in the console).

Expected behavior

The warning should not be emitted in unit tests.
It's currently possible to remove it by using zone.run or using NoopNgZone, but this is cumbersome. A way to disable it in unit tests would be great.

Minimal reproduction of the problem with instructions

Build a minimal app with the CLI

ng new router-warning --routing

Then replace the default unit test with:

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';

import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', async(() => {
    const router = TestBed.get(Router) as Router;
    router.navigateByUrl('/');
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
});

Run ng test, and the following warning should appear:

WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'

Environment


Angular version: 6.1.7 or 7.0.0-beta.5

Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 8.11.3
- Platform:  Mac

cc @trotyl

@trotyl
Copy link
Contributor

trotyl commented Sep 6, 2018

Relates to #24181 (#24185), caused by NgZone.isInAngularZone() implementation.

CC @JiaLiPassion, any suggestion on checking whether it's Angular zone?

trotyl added a commit to trotyl/angular that referenced this issue Sep 6, 2018
@IgorMinar IgorMinar added area: testing Issues related to Angular testing features, such as TestBed area: router area: zones labels Sep 6, 2018
@ngbot ngbot bot added this to the needsTriage milestone Sep 6, 2018
@vasiliy0s
Copy link

The same for us. But our tests watches console.warn logging and this issue was sensitive for tests fail.

@JiaLiPassion
Copy link
Contributor

@trotyl, yeah, several other issues have the same problems, in test, NgZone.isInAngularZone() will be false, we may need a TestNgZone to work with ComponentFixture.autoDetectChanges

@webben-de
Copy link

+1

1 similar comment
@iotshaman
Copy link

+1

@orjandesmet
Copy link

I'd say you don't need to navigate in unit tests.
You should spy on those methods and assert that they have been called.

@dhhyi
Copy link

dhhyi commented Oct 20, 2018

I'd say you don't need to navigate in unit tests.

For unit tests, yes. But the same framework can also be used for integration tests where you should be able to instantiate routing and do navigation.

@samuelt1
Copy link

samuelt1 commented Oct 29, 2018

I am getting this in my actual code. Not just in the tests.
this.router.navigate([this.returnUrl])

@ItzhakBokris
Copy link

Workaround:

constructor(private ngZone: NgZone, private router: Router) {}

public navigate(commands: any[]): void {
    this.ngZone.run(() => this.router.navigate(commands)).then();
}

@CharlyRipp
Copy link

In unit test:

it('should just work', async(() => {
    fixture.ngZone.run(() => {
        router.navigate(['path1']);
        fixture.detectChanges();
        fixture.whenStable().then(() => {
            expect({stuff}).toHaveBeenCalled();
        });
    });
}));

@AliakbarSu
Copy link

You also need to wrap router.initialNavigation();

fixture.ngZone.run(() => {
      router.initialNavigation();
});

@calebeaires
Copy link

Workround proposed by @ItzhakBokris worked, but it must not be a permanent solution. Waiting to angular team!

this.ngZone.run(() => this.router.navigate(['home'])).then();

@quirogamauricio
Copy link

I'm getting this warning not in a test, but in the actual application, when navigating from a component to another. I'm doing a sort of hack to be able to navigate using the router, from links present in a table that's generated with DataTables. Basically I'm temporarily adding a property to the window object, which holds a function that calls a component's method that uses the router. I'm not sure if the warning is actually correctly displayed or if this is a bug. Also I'd appreciate if someone could provide a better way to trigger navigation from dynamically generated content.

@trotyl
Copy link
Contributor

trotyl commented Nov 20, 2018

@quirogamauricio It's the expected warning, when perform navigation outside Angular zone than no change detection will be triggered. You do can perform navigation from anywhere of the JavaScript engine, but just need to ensure it inside Angular zone.

@rajugvsn
Copy link

I guess It is because latest angular CLI creates routing in a separate module
app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

so to run navigation with in Angular zone it is required to implement work around -

constructor(private ngZone: NgZone, private router: Router) {}

public navigate(commands: any[]): void {
    this.ngZone.run(() => this.router.navigate(commands)).then();
}

Alternatively if you define routing with in app module, it works fine.
app.routing.ts

import { Routes, RouterModule } from '@angular/router';

const appRoutes: Routes = [
    //add app routes here
];

export const routing = RouterModule.forRoot(appRoutes);

@DDieudonne
Copy link

Works perfectly for me @calebeaires thanks !!

@hollygood
Copy link

hollygood commented Feb 6, 2019

I also received the same warning by using ngrx/effects:

@Effect({ dispatch: false })
redirectToLogin$: Observable<Action> = this.actions$.pipe(
  ofType<RedirectToLogin>(AuthActionTypes.REDIRECT_TO_LOGIN),
    tap(() => {
      this.router.navigate(['/signin']);
     })
  );

@dianjuar
Copy link
Contributor

dianjuar commented Feb 11, 2019

To avoid the callback hell in the @CharlyRipp suggestion you can use I used await

await fixture.ngZone.run(async () => {
    await router.navigate(['/home']);
});

// Put your asserts here
expect(true).toBeTruthy();

@fpellanda
Copy link

I suggest as workaround to run navigate in fixture.ngZone with a spy:

    // run navigate in ngZone
    beforeEach(() => {
      const originalNavigate = TestBed.get(Router).navigate;
      spyOn(TestBed.get(Router), 'navigate').and.callFake((...options) => {
        fixture.ngZone.run(() => {
          originalNavigate.apply(TestBed.get(Router), options);
        });
      });
    });

@anlexN
Copy link

anlexN commented Apr 30, 2019

import { Location } from '@angular/common';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { Router, Routes } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import { HeroesComponent } from './heroes/heroes.component';
import { MessagesComponent } from './messages/messages.component';

describe('AppComponent', () => {
  const routes: Routes = [
    { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
    { path: 'dashboard', component: DashboardComponent },
    { path: 'heroes', component: HeroesComponent },
    { path: 'detail/:id', component: HeroDetailComponent }
  ];

  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;
  let compiled: HTMLElement;
  let router: Router;
  let location: Location;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        HeroesComponent,
        HeroDetailComponent,
        MessagesComponent,
        DashboardComponent
      ],
      imports: [FormsModule, RouterTestingModule.withRoutes(routes)]
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.debugElement.componentInstance;
        compiled = fixture.debugElement.nativeElement;
        router = TestBed.get(Router);
        location = TestBed.get(Location);

        fixture.detectChanges();

        fixture.ngZone.run(() => {
          router.initialNavigation();
        });
      });
  }));

  it('should create the component', () => {
    expect(component).toBeTruthy();
  });

  it('should render title in a h1 tag', () => {
    fixture.detectChanges();
    expect(compiled.querySelector('h1').textContent).toContain(
      'Tour of Heroes'
    );
  });

  it('should get 4 RouterLinks', () => {
    expect(router.config.length).toEqual(4);
  });

  it('should redirect to /dashboard when navigate to ""', async(() => {
    fixture.ngZone.run(() => {
      fixture.whenStable().then(() => {
        router.navigate(['']).then(() => {
          expect(location.path()).toEqual('/dashboard');
        });
      });
    });
  }));

  it('should navigate to /heroes', async(() => {
    fixture.ngZone.run(() => {
      fixture.whenStable().then(() => {
        router.navigate(['/heroes']).then(() => {
          expect(location.path()).toEqual('/heroes');
        });
      });
    });
  }));
});

image

That's all , thank you! No errors, No warnings. very good! 😄

@TravisLRiffle
Copy link

@anlexN This worked for me! Thanks!!

@ChrisMBarr
Copy link

ChrisMBarr commented May 15, 2019

If you need to run tests in IE11 Proxy does not exist and will give the error:

ReferenceError: 'Proxy' is undefined
error properties: Object({ number: -2146823279 })

However, we can install a polyfill for this this by running npm i proxy-polyfill --save-dev

So here's the full solution to do this cross-browser:

import 'proxy-polyfill/proxy.min.js';

declare const ProxyPolyfill: ProxyConstructor;

/**
 * Wrapper of Angular router (only for testing purpose)
 * Meant to run all router operations within Angular zone
 *  * Keep change detection enabled
 *  * Avoids flooded console with warnings
 *    https://github.com/angular/angular/issues/25837#issuecomment-445796236
 *
 * @see Router
 */
export function wrapRouterInNgZone(router: Router, ngZone: NgZone): Router {
    return new ProxyPolyfill(router, {
        get(target: Router, p: PropertyKey): unknown {
            //@ts-ignore Element implicitly has an 'any' type because type 'Router' has no index signature.ts(7017)
            const invokedProperty = target[p];
            if (typeof invokedProperty !== 'function') {
                return invokedProperty;
            }

            return (...args: Array<unknown>): unknown => {
                return ngZone.run(() => invokedProperty.apply(target, args));
            };
        }
    });
}

Please note that we have to import from the minified version since they stupidly include some ES6 syntax in the un-minified version (which kinda defeats the purpose of the polyfill in the first place!) There's an open issue about it here

mosdevly pushed a commit to LinguaTechnica/herobook that referenced this issue Jun 4, 2019
@renegare
Copy link

renegare commented Jul 2, 2019

any luck with this bug/inconvenience being resolved?

FWIW I'm using this helper as a workaround:

const ngZoneRun = async (fixture, cb) => {
  return new Promise((resolve, reject) => {
    try {
      fixture.ngZone.run(async () => {
        try {
          resolve(await cb());
        } catch (error) {
          reject(error);
        }
      });
    } catch (error) {
      reject(error);
    }
  });
};

Disclaimer: new to TS and angular.

Idea: a wrapper that runs fixture.ngZone.run and also returns a Promise that will resolve to what your callback (cb) returns/resolves.

msorens added a commit to chef/automate that referenced this issue Sep 29, 2019
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'

This was being generated by the following components:
 - ClientRunsComponent
 - ServiceGroupsComponent
 - ReportingComponent
 - HttpClientAuthInterceptor

The warning stems from this issue introduced by Angular 7:
angular/angular#25837

The first two components are fixed by this commit,
cutting the test "noise" in half.
Unfortunately applying the same fix to ReportingComponent
breaks several unit tests.
And I have not yet found the place to hook into to
fix HttpClientAuthInterceptor.

Signed-off-by: michael sorens <msorens@chef.io>
@msorens
Copy link

msorens commented Sep 29, 2019

@piotrl Thank you for your workaround code! Just one more piece would be useful in my environment. I have a few tests that use variations of this:

spyOn(router, 'navigate');
// do stuff here
expect(router.navigate).toHaveBeenCalledWith([], {queryParams: { }});

But with your wrapRouterInNgZone in place that now yields this error:

   Error: <toHaveBeenCalledWith> : Expected a spy, but got Function.

Any thoughts on how to rewrite the above expectation to pass?

scottopherson pushed a commit to chef/automate that referenced this issue Oct 4, 2019
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'

This was being generated by the following components:
 - ClientRunsComponent
 - ServiceGroupsComponent
 - ReportingComponent
 - HttpClientAuthInterceptor

The warning stems from this issue introduced by Angular 7:
angular/angular#25837

The first two components are fixed by this commit,
cutting the test "noise" in half.
Unfortunately applying the same fix to ReportingComponent
breaks several unit tests.
And I have not yet found the place to hook into to
fix HttpClientAuthInterceptor.

Signed-off-by: michael sorens <msorens@chef.io>
msorens added a commit to chef/automate that referenced this issue Oct 7, 2019
* Remove incompatible npm package

Attempts to upgrade Angular reported that the "ngrx-tslint-oftype"
package was not compatible.
But this package was only needed for preparing a particular ngrx transition
between versions, so its work is done and it can be removed.

Signed-off-by: michael sorens <msorens@chef.io>

* `ng update` generated changes

Signed-off-by: michael sorens <msorens@chef.io>

* Reverted typescript from 3.5.3 to 3.4.5

The update of @angular/core failed because it found
3.5.3 -- that the upgrade had installed itself.
I edited the package.json from  ^3.4.5 to ~3.4.5
to keep it to 3.4.x, then npm install,
and it updated this package-lock.json.

Signed-off-by: michael sorens <msorens@chef.io>

* @ViewChild fixes

These are auto-generated from:
ng update @angular/core --from 7 --to 8 --migrate-only

Signed-off-by: michael sorens <msorens@chef.io>

* @angular/material fixes

These are auto-generated from:
ng update @angular/material --from 7 --to 8 --migrate-only

Signed-off-by: michael sorens <msorens@chef.io>

* Try to fix npm issue

webpack/webpack#8656 (comment)
Add acorn to package.json.

Signed-off-by: michael sorens <msorens@chef.io>

* Import fresh wallaby.js

Commit 060eccd8d6e72997b769e7ddb8570d50e310d43b
from https://github.com/wallabyjs/ngCliWebpackSample/o
dated 2019-07-09

Signed-off-by: michael sorens <msorens@chef.io>

* Re-apply Chef customization from old wallaby.js

Signed-off-by: michael sorens <msorens@chef.io>

* Import fresh wallaby.js (again)

After I submitted an issue, they updated the config file for Angular 8.
wallabyjs/public#2141

Signed-off-by: michael sorens <msorens@chef.io>

* Import fresh wallaby.js (one more time)

Wallaby team adjusted the config file again; this time it worked.
wallabyjs/public#2141

Signed-off-by: michael sorens <msorens@chef.io>

* Update angular-devkit deps

Signed-off-by: Scott Christopherson <scott@chef.io>

* Update router-store initialization

Signed-off-by: Scott Christopherson <scott@chef.io>

* Re-sync after rebase

* Minor fix

Signed-off-by: michael sorens <msorens@chef.io>

* Use the updated action types in routerReducer

ngrx/platform@466e2cd#diff-c0c42c418c07609d7feedc294175d164

* Configure route serializer via StoreRouterConnectingModule

Old way still works but the new way is how it's currently documented now and it requires less imports.

* Lint cleanup

Teardown the kludgy lint command needed to filter out
the deprecated deprecation (really!) of `select`.

Also suppress one essentially invalid lint complaint.

Signed-off-by: michael sorens <msorens@chef.io>

* Fix compile error in e2e (protractor) tests

Was getting this error:
e2e/compliance-reporting.e2e-spec.ts(2,10): error TS2305:
Module '"...e2e/helpers/accessibility_helpers"' has no exported member 'expectUrlToBeAccessible'.

Not clear what the problem was but this change fixed it

Signed-off-by: michael sorens <msorens@chef.io>

* Upgrade lots of npm packages

Ran `npm update` and got package updates shown.
Also includes just one code change needed to get a successful build.
All unit tests pass.

+ @angular/cdk@8.2.0
+ @angular/cli@8.3.5
+ @angular-devkit/core@8.3.5
+ @angular-devkit/schematics@8.3.5
+ @angular/forms@8.2.7
+ @angular/material@8.2.0
+ @angular/animations@8.2.7
+ @types/faker@4.1.5
+ @angular/platform-browser-dynamic@8.2.7
+ @angular/language-service@8.2.7
+ @angular/platform-browser@8.2.7
+ @angular/router@8.2.7
+ @angular/core@8.2.7
+ @angular/compiler@8.2.7
+ @types/jasminewd2@2.0.6
+ ajv@6.10.2
+ @types/lodash@4.14.138
+ codelyzer@5.1.1
+ axe-webdriverjs@2.3.0
+ d3@5.12.0
+ install@0.12.2
+ @types/node@10.14.18
+ core-js@2.6.9
+ karma-coverage-istanbul-reporter@2.1.0
+ karma-firefox-launcher@1.2.0
+ karma-jasmine-html-reporter@1.4.2
+ lodash@4.17.15
+ rxjs@6.5.3
+ moment@2.24.0
+ @angular/common@8.2.7
+ ngx-cookie@4.1.2
+ karma@3.1.4
+ @types/jasmine@2.8.16
+ tslib@1.10.0
+ sass-lint@1.13.1
+ tslint@5.20.0
+ rxjs-tslint@0.1.7
+ sniffr@1.2.0
+ tslint-defocus@2.0.6
+ wallaby-webpack@3.9.15
+ diff2html@2.11.3
+ @angular-devkit/build-angular@0.801.3
+ typescript@3.6.3
+ @angular/compiler-cli@8.2.7

added 397 packages from 78 contributors, removed 283 packages, updated 242 packages, moved 24 packages and audited 18418 packages in 134.542s

Signed-off-by: michael sorens <msorens@chef.io>

* More npm package updates

Signed-off-by: michael sorens <msorens@chef.io>

* and still more package updates

Signed-off-by: michael sorens <msorens@chef.io>

* Tighten version lock to patch only

@types/jasmine - generated error from `make unit`:
Per https://stackoverflow.com/a/57592510
need to wait for a patch

jasmine-core - just too new; came out yesterday! let's wait a bit on this one

tyepscript: generated error from `make server` that it needed angular < 3.6
so locking it at 3.5 until a later angular release

Signed-off-by: michael sorens <msorens@chef.io>

* Fix build warning

Warning message for the two SCSS files:
"start value has mixed support, consider using flex-start instead"

Signed-off-by: michael sorens <msorens@chef.io>

* Add reference comment

Signed-off-by: michael sorens <msorens@chef.io>

* Suppress ngrx runtime checks warnings

```
WARN: '@ngrx/store: runtime checks are currently opt-in but will be the default in the next major version with the possibility to opt-out, see https://ngrx.io/guide/migration/v8 for more information.'
```

Signed-off-by: Scott Christopherson <scott@chef.io>

* Suppress momentjs parse warning

```
WARN: 'Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
```

The test is purposefully testing an invalid string passed to `moment`. The warning is expected.

Signed-off-by: Scott Christopherson <scott@chef.io>

* Suppress unhandled router promise warning

```
ERROR: 'Unhandled Promise rejection:', 'Cannot match any routes. URL Segment: 'projects/uuid-1'', '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', Error: Cannot match any routes. URL Segment: 'projects/uuid-1'
Error: Cannot match any routes. URL Segment: 'projects/uuid-1'
```

Signed-off-by: Scott Christopherson <scott@chef.io>

* Ensure ui-lib is installed w/ other dependencies

Unit tests fail to run if ui-lib assets are not installed.

```
ERROR in ./src/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--15-3!./src/styles.scss)
Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Failed to find 'assets/chef-ui-library/chef/chef.css'
  in [
    /go/src/github.com/chef/automate/components/automate-ui/src
  ]
    at resolveModule.catch.catch (/go/src/github.com/chef/automate/components/automate-ui/node_modules/postcss-import/lib/resolve-id.js:35:13)
 @ ./src/styles.scss 1:14-241
 @ multi ./src/styles.scss
```

Signed-off-by: Scott Christopherson <scott@chef.io>

* Reduce unit test noise

WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'

This was being generated by the following components:
 - ClientRunsComponent
 - ServiceGroupsComponent
 - ReportingComponent
 - HttpClientAuthInterceptor

The warning stems from this issue introduced by Angular 7:
angular/angular#25837

The first two components are fixed by this commit,
cutting the test "noise" in half.
Unfortunately applying the same fix to ReportingComponent
breaks several unit tests.
And I have not yet found the place to hook into to
fix HttpClientAuthInterceptor.

Signed-off-by: michael sorens <msorens@chef.io>

* One more pass of `npm update`

Have to move fast to keep on top of these changes.

This pass did these updates:
$ npm update
+ @angular-devkit/core@8.3.6
+ @angular/common@8.2.8
+ @angular/cdk@8.2.1
+ @angular/cli@8.3.6
+ @angular-devkit/schematics@8.3.6
+ @angular-devkit/build-angular@0.803.6
+ @angular/compiler-cli@8.2.8
+ @angular/language-service@8.2.8
+ @angular/platform-browser@8.2.8
+ @angular/core@8.2.8
+ @angular/platform-server@8.2.8
+ @angular/material@8.2.1
+ jasmine-core@3.5.0
+ @types/lodash@4.14.141
+ @angular/forms@8.2.8
+ @angular/platform-browser-dynamic@8.2.8
+ @types/node@10.14.19
+ @angular/router@8.2.8
+ codelyzer@5.1.2
+ @angular/compiler@8.2.8
+ @angular/animations@8.2.8

Signed-off-by: michael sorens <msorens@chef.io>

* Document package.json constraints

Certain few packages are specifically not updated
to their latest versions.
As package.json cannot contain comments,
I documented the reasons in the next best thing, the readme.

Signed-off-by: michael sorens <msorens@chef.io>

* Suppress ngZone warnings in reporting.component.spec

```
    applyParamFilters()
      ✔ parses multiple filters
      ✔ parses single filters
      ✔ parse interval
INFO: 'getEndDate calling router.navigate'
INFO: 'getEndDate calling router.navigate'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
      ✔ parse bad end date
INFO: 'getDateInterval calling router.navigate'
INFO: 'getDateInterval calling router.navigate'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
      ✔ parse invaild interval 2
INFO: 'getDateInterval calling router.navigate'
INFO: 'getDateInterval calling router.navigate'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
      ✔ parse invaild interval 1
INFO: 'getDateInterval calling router.navigate'
INFO: 'getDateInterval calling router.navigate'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
      ✔ parse bad interval
```

The `getEndDate` and `getDateInterval` methods call `router.navigate` which seems unexpected for methods that are named for getting and returning a value.

* Suppress ngZone warnings in service-groups.component.spec

Signed-off-by: Scott Christopherson <scott@chef.io>

* Suppress ngZone warnings in client-runs.component.spec

Signed-off-by: Scott Christopherson <scott@chef.io>

* Remove unused routing-helper

Ended up not needing it after refactoring specs to not rely on calling through `router.navigate`.

Signed-off-by: Scott Christopherson <scott@chef.io>
@alainkaiser
Copy link

Any news on this one?

@kygoh
Copy link

kygoh commented Feb 22, 2020

I tried this workaround to avoid the warning:

  it('should navigate "" to "/app"', async() => {
    const success = await fixture.ngZone.run(() => router.navigateByUrl(''));
    expect(success).toBeTruthy();
    expect(location.path()).toBe('/app');
  });

@whimzyLive
Copy link

I usually do this,

      const originalNavigate = TestBed.inject(Router).navigate;
      spyOn(TestBed.inject(Router), 'navigate').and.callFake((...options) => {
        new NgZone({}).run(() => {
          originalNavigate.apply(TestBed.inject(Router), options);
        });
      });

this ensures that navigation is performed inside ngZone.
thanks to @fpellanda

@JiaLiPassion JiaLiPassion self-assigned this May 28, 2020
@jelbourn jelbourn added P4 A relatively minor issue that is not relevant to core functions and removed severity2: inconvenient labels Oct 1, 2020
atscott pushed a commit to trotyl/angular that referenced this issue Dec 29, 2020
Do not warn that navigation was triggered outside Angular zone if the
Router was created outside Angular zone in the first place.

Closes angular#25837
atscott pushed a commit that referenced this issue Jan 11, 2021
Do not warn that navigation was triggered outside Angular zone if the
Router was created outside Angular zone in the first place.

Closes #25837

PR Close #25839
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: router area: testing Issues related to Angular testing features, such as TestBed area: zones freq3: high P4 A relatively minor issue that is not relevant to core functions state: confirmed type: bug/fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.