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
This commit is contained in:
Andrew Scott 2025-07-23 13:29:08 -07:00 committed by Jessica Janiuk
parent 5b7408edb6
commit 92b080202d
9 changed files with 26 additions and 4 deletions

View file

@ -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', () => {

View file

@ -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!;

View file

@ -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;

View file

@ -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: '<router-outlet [name]="name"></router-outlet>',

View file

@ -54,3 +54,13 @@ export async function timeout(ms?: number): Promise<void> {
setTimeout(resolve, ms);
});
}
export function useAutoTick() {
beforeEach(() => {
jasmine.clock().install();
jasmine.clock().autoTick();
});
afterEach(() => {
jasmine.clock().uninstall();
});
}

View file

@ -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(() => {

View file

@ -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()}}])],

View file

@ -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);

View file

@ -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,