From 92b080202de922c4de5095ab0abe2338f1cfecfd Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Wed, 23 Jul 2025 13:29:08 -0700 Subject: [PATCH] test(router): Use autoTick feature in router tests (#62776) This updates async router tests to use the jasmine autoTick feature. Observed test timings for the chromium tests went down from ~7.5s to ~3.5-4s. For node, these decreased from ~5.5s to ~3s. In addition to the speed improvement, this feature: * Removes the need to be careful about timeout ordering when there are several timeouts in tests. * Removes the need to ensure test timeouts are kept sufficiently small * Reduces overall flakiness PR Close #62776 --- packages/router/test/apply_redirects.spec.ts | 3 ++- packages/router/test/bootstrap.spec.ts | 2 ++ .../router/test/computed_state_restoration.spec.ts | 3 ++- packages/router/test/directives/router_outlet.spec.ts | 3 ++- packages/router/test/helpers.ts | 10 ++++++++++ packages/router/test/integration/integration.spec.ts | 2 ++ packages/router/test/operators/resolve_data.spec.ts | 2 ++ packages/router/test/recognize.spec.ts | 2 ++ packages/router/test/router_preloader.spec.ts | 3 ++- 9 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/router/test/apply_redirects.spec.ts b/packages/router/test/apply_redirects.spec.ts index ca9729cf3a4..213ace19ba5 100644 --- a/packages/router/test/apply_redirects.spec.ts +++ b/packages/router/test/apply_redirects.spec.ts @@ -24,9 +24,10 @@ import { UrlTree, } from '../src/url_tree'; import {getLoadedRoutes, getProvidersInjector} from '../src/utils/config'; -import {timeout} from './helpers'; +import {timeout, useAutoTick} from './helpers'; describe('redirects', () => { + useAutoTick(); const serializer = new DefaultUrlSerializer(); it('should return the same url tree when no redirects', () => { diff --git a/packages/router/test/bootstrap.spec.ts b/packages/router/test/bootstrap.spec.ts index 95510c48f5f..e9af22a3626 100644 --- a/packages/router/test/bootstrap.spec.ts +++ b/packages/router/test/bootstrap.spec.ts @@ -37,6 +37,7 @@ import { RouterOutlet, withEnabledBlockingInitialNavigation, } from '../index'; +import {useAutoTick} from './helpers'; // This is needed, because all files under `packages/` are compiled together as part of the // [legacy-unit-tests-saucelabs][1] CI job, including the `lib.webworker.d.ts` typings brought in by @@ -49,6 +50,7 @@ import { declare var window: Window; describe('bootstrap', () => { + useAutoTick(); let log: any[] = []; let testProviders: any[] = null!; diff --git a/packages/router/test/computed_state_restoration.spec.ts b/packages/router/test/computed_state_restoration.spec.ts index 24f42c1e2dd..27fc3767f88 100644 --- a/packages/router/test/computed_state_restoration.spec.ts +++ b/packages/router/test/computed_state_restoration.spec.ts @@ -15,10 +15,11 @@ import {EMPTY, of} from 'rxjs'; import {provideRouter} from '../src/provide_router'; import {isUrlTree} from '../src/url_tree'; -import {timeout} from './helpers'; +import {timeout, useAutoTick} from './helpers'; import {afterNextNavigation} from '../src/utils/navigations'; describe('`restoredState#ɵrouterPageId`', () => { + useAutoTick(); @Injectable({providedIn: 'root'}) class MyCanDeactivateGuard { allow: boolean = true; diff --git a/packages/router/test/directives/router_outlet.spec.ts b/packages/router/test/directives/router_outlet.spec.ts index aec6106e417..11f388d5ef9 100644 --- a/packages/router/test/directives/router_outlet.spec.ts +++ b/packages/router/test/directives/router_outlet.spec.ts @@ -27,9 +27,10 @@ import { } from '../../index'; import {RouterTestingHarness} from '../../testing'; import {InjectionToken} from '../../../core/src/di'; -import {timeout} from '../helpers'; +import {timeout, useAutoTick} from '../helpers'; describe('router outlet name', () => { + useAutoTick(); it('should support name binding', async () => { @Component({ template: '', diff --git a/packages/router/test/helpers.ts b/packages/router/test/helpers.ts index 8c48ff80971..989546a2a56 100644 --- a/packages/router/test/helpers.ts +++ b/packages/router/test/helpers.ts @@ -54,3 +54,13 @@ export async function timeout(ms?: number): Promise { setTimeout(resolve, ms); }); } + +export function useAutoTick() { + beforeEach(() => { + jasmine.clock().install(); + jasmine.clock().autoTick(); + }); + afterEach(() => { + jasmine.clock().uninstall(); + }); +} diff --git a/packages/router/test/integration/integration.spec.ts b/packages/router/test/integration/integration.spec.ts index 2948f8129c3..39f0fb5b3f7 100644 --- a/packages/router/test/integration/integration.spec.ts +++ b/packages/router/test/integration/integration.spec.ts @@ -71,9 +71,11 @@ import {navigationIntegrationTestSuite} from './navigation.spec'; import {eagerUrlUpdateStrategyIntegrationSuite} from './eager_url_update_strategy.spec'; import {duplicateInFlightNavigationsIntegrationSuite} from './duplicate_in_flight_navigations.spec'; import {navigationErrorsIntegrationSuite} from './navigation_errors.spec'; +import {useAutoTick} from '../helpers'; for (const browserAPI of ['navigation', 'history'] as const) { describe(`${browserAPI}-based routing`, () => { + useAutoTick(); const noopConsole: Console = {log() {}, warn() {}}; beforeEach(() => { diff --git a/packages/router/test/operators/resolve_data.spec.ts b/packages/router/test/operators/resolve_data.spec.ts index 5479fbc65ab..da9a3b4a05a 100644 --- a/packages/router/test/operators/resolve_data.spec.ts +++ b/packages/router/test/operators/resolve_data.spec.ts @@ -11,8 +11,10 @@ import {TestBed} from '@angular/core/testing'; import {ActivatedRouteSnapshot, provideRouter, Router} from '../../index'; import {RouterTestingHarness} from '../../testing'; import {EMPTY, interval, NEVER, of} from 'rxjs'; +import {useAutoTick} from '../helpers'; describe('resolveData operator', () => { + useAutoTick(); it('should take only the first emitted value of every resolver', async () => { TestBed.configureTestingModule({ providers: [provideRouter([{path: '**', children: [], resolve: {e1: () => interval()}}])], diff --git a/packages/router/test/recognize.spec.ts b/packages/router/test/recognize.spec.ts index 5cedd0bba82..721f0988f82 100644 --- a/packages/router/test/recognize.spec.ts +++ b/packages/router/test/recognize.spec.ts @@ -15,8 +15,10 @@ import {RouterConfigLoader} from '../src/router_config_loader'; import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../src/router_state'; import {Params, PRIMARY_OUTLET} from '../src/shared'; import {DefaultUrlSerializer, UrlTree} from '../src/url_tree'; +import {useAutoTick} from './helpers'; describe('recognize', () => { + useAutoTick(); it('should work', async () => { const s = await recognize([{path: 'a', component: ComponentA}], 'a'); checkActivatedRoute(s.root, '', {}, RootComponent); diff --git a/packages/router/test/router_preloader.spec.ts b/packages/router/test/router_preloader.spec.ts index 0a96db41056..e6da3ac9813 100644 --- a/packages/router/test/router_preloader.spec.ts +++ b/packages/router/test/router_preloader.spec.ts @@ -42,9 +42,10 @@ import { getLoadedRoutes, getProvidersInjector, } from '../src/utils/config'; -import {timeout} from './helpers'; +import {timeout, useAutoTick} from './helpers'; describe('RouterPreloader', () => { + useAutoTick(); @Component({ template: '', standalone: false,