Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4fea701

Browse files
feat: release v18 (#533)
* feat: update to Angular 20 (#530) BREAKING CHANGE: The angular minimum version has changed. BEFORE: Angular 17,18,19 were supported. AFTER: Angular 20 (and up) is supported. Reason: The method `TestBed.get` has been removed. * feat: remove animations dependency (#531) BREAKING CHANGE: Angular recommends using CSS animations, https://angular.dev/guide/animations/migration Because of the removal of the animations dependency, the `NoopAnimationsModule` is no longer automatically imported in the render function. BEFORE: The `NoopAnimationsModule` was always imported to the render the component. AFTER: Import the `NoopAnimationsModule` in your render configuration (where needed): ```ts await render(SutComponent, { imports: [NoopAnimationsModule], }); ``` * feat: add stronger types (#413)
1 parent 420f0d3 commit 4fea701

File tree

12 files changed

+70
-88
lines changed

12 files changed

+70
-88
lines changed

‎.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222

2323
strategy:
2424
matrix:
25-
node-version: ${{ fromJSON((github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') && '[22]' || '[18, 20, 22]') }}
25+
node-version: ${{ fromJSON((github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') && '[22]' || '[20, 22, 24]') }}
2626
os: ${{ fromJSON((github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') && '["ubuntu-latest"]' || '["ubuntu-latest", "windows-latest"]') }}
2727
runs-on: ${{ matrix.os }}
2828

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ yarn.lock
4646
Thumbs.db
4747
.cursor/rules/nx-rules.mdc
4848
.github/instructions/nx.instructions.md
49+
.history

‎README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,16 @@ You may also be interested in installing `jest-dom` so you can use
177177
178178
## Version compatibility
179179

180-
| Angular | Angular Testing Library |
181-
| ------- | ---------------------------- |
182-
| 19.x | 17.x, 16.x, 15.x, 14.x, 13.x |
183-
| 18.x | 17.x, 16.x, 15.x, 14.x, 13.x |
184-
| 17.x | 17.x, 16.x, 15.x, 14.x, 13.x |
185-
| 16.x | 14.x, 13.x |
186-
| >= 15.1 | 14.x, 13.x |
187-
| < 15.1 | 12.x, 11.x |
188-
| 14.x | 12.x, 11.x |
180+
| Angular | Angular Testing Library |
181+
| ------- | ---------------------------------- |
182+
| 20.x | 18.x, 17.x, 16.x, 15.x, 14.x, 13.x |
183+
| 19.x | 17.x, 16.x, 15.x, 14.x, 13.x |
184+
| 18.x | 17.x, 16.x, 15.x, 14.x, 13.x |
185+
| 17.x | 17.x, 16.x, 15.x, 14.x, 13.x |
186+
| 16.x | 14.x, 13.x |
187+
| >= 15.1 | 14.x, 13.x |
188+
| < 15.1 | 12.x, 11.x |
189+
| 14.x | 12.x, 11.x |
189190

190191
## Guiding Principles
191192

‎apps/example-app-karma/src/app/issues/issue-491.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component } from '@angular/core';
22
import { Router } from '@angular/router';
3-
import { render, screen,waitForElementToBeRemoved } from '@testing-library/angular';
3+
import { render, screen } from '@testing-library/angular';
44
import userEvent from '@testing-library/user-event';
55

66
it('test click event with router.navigate', async () => {
@@ -31,8 +31,6 @@ it('test click event with router.navigate', async () => {
3131

3232
await user.click(screen.getByRole('button', { name: 'submit' }));
3333

34-
await waitForElementToBeRemoved(() => screen.queryByRole('heading', { name: 'Login' }));
35-
3634
expect(await screen.findByRole('heading', { name: 'Logged In' })).toBeVisible();
3735
});
3836

‎apps/example-app/src/app/examples/15-dialog.component.spec.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { MatDialogRef } from '@angular/material/dialog';
2+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
23
import { render, screen } from '@testing-library/angular';
34
import userEvent from '@testing-library/user-event';
45

@@ -9,6 +10,7 @@ test('dialog closes', async () => {
910

1011
const closeFn = jest.fn();
1112
await render(DialogContentComponent, {
13+
imports: [NoopAnimationsModule],
1214
providers: [
1315
{
1416
provide: MatDialogRef,
@@ -28,7 +30,9 @@ test('dialog closes', async () => {
2830
test('closes the dialog via the backdrop', async () => {
2931
const user = userEvent.setup();
3032

31-
await render(DialogComponent);
33+
await render(DialogComponent, {
34+
imports: [NoopAnimationsModule],
35+
});
3236

3337
const openDialogButton = await screen.findByRole('button', { name: /opendialog/i });
3438
await user.click(openDialogButton);
@@ -50,7 +54,9 @@ test('closes the dialog via the backdrop', async () => {
5054
test('opens and closes the dialog with buttons', async () => {
5155
const user = userEvent.setup();
5256

53-
await render(DialogComponent);
57+
await render(DialogComponent, {
58+
imports: [NoopAnimationsModule],
59+
});
5460

5561
const openDialogButton = await screen.findByRole('button', { name: /opendialog/i });
5662
await user.click(openDialogButton);

‎package.json

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727
"prepare": "git config core.hookspath .githooks"
2828
},
2929
"dependencies": {
30-
"@angular/animations": "19.2.14",
31-
"@angular/cdk": "19.2.18",
32-
"@angular/common": "19.2.14",
33-
"@angular/compiler": "19.2.14",
34-
"@angular/core": "19.2.14",
35-
"@angular/material": "19.2.18",
36-
"@angular/platform-browser": "19.2.14",
37-
"@angular/platform-browser-dynamic": "19.2.14",
38-
"@angular/router": "19.2.14",
30+
"@angular/animations": "20.0.0",
31+
"@angular/cdk": "20.0.0",
32+
"@angular/common": "20.0.0",
33+
"@angular/compiler": "20.0.0",
34+
"@angular/core": "20.0.0",
35+
"@angular/material": "20.0.0",
36+
"@angular/platform-browser": "20.0.0",
37+
"@angular/platform-browser-dynamic": "20.0.0",
38+
"@angular/router": "20.0.0",
3939
"@ngrx/store": "19.0.0",
4040
"@nx/angular": "21.1.2",
4141
"@testing-library/dom": "^10.4.0",
@@ -44,26 +44,26 @@
4444
"zone.js": "^0.15.0"
4545
},
4646
"devDependencies": {
47-
"@angular-devkit/build-angular": "19.2.9",
48-
"@angular-devkit/core": "19.2.9",
49-
"@angular-devkit/schematics": "19.2.9",
47+
"@angular-devkit/build-angular": "20.0.0",
48+
"@angular-devkit/core": "20.0.0",
49+
"@angular-devkit/schematics": "20.0.0",
5050
"@angular-eslint/builder": "19.2.0",
5151
"@angular-eslint/eslint-plugin": "19.2.0",
5252
"@angular-eslint/eslint-plugin-template": "19.2.0",
5353
"@angular-eslint/schematics": "19.2.0",
5454
"@angular-eslint/template-parser": "19.2.0",
55-
"@angular/cli": "~19.2.0",
56-
"@angular/compiler-cli": "19.2.14",
57-
"@angular/forms": "19.2.14",
58-
"@angular/language-service": "19.2.14",
55+
"@angular/cli": "~20.0.0",
56+
"@angular/compiler-cli": "20.0.0",
57+
"@angular/forms": "20.0.0",
58+
"@angular/language-service": "20.0.0",
5959
"@eslint/eslintrc": "^2.1.1",
6060
"@nx/eslint": "21.1.2",
6161
"@nx/eslint-plugin": "21.1.2",
6262
"@nx/jest": "21.1.2",
6363
"@nx/node": "21.1.2",
6464
"@nx/plugin": "21.1.2",
6565
"@nx/workspace": "21.1.2",
66-
"@schematics/angular": "19.2.9",
66+
"@schematics/angular": "20.0.0",
6767
"@testing-library/jasmine-dom": "^1.3.3",
6868
"@testing-library/jest-dom": "^6.6.3",
6969
"@testing-library/user-event": "^14.5.2",
@@ -91,7 +91,7 @@
9191
"karma-jasmine-html-reporter": "2.0.0",
9292
"lint-staged": "^15.3.0",
9393
"ng-mocks": "^14.13.1",
94-
"ng-packagr": "19.2.2",
94+
"ng-packagr": "20.0.0",
9595
"nx": "21.1.2",
9696
"postcss": "^8.4.49",
9797
"postcss-import": "14.1.0",
@@ -102,7 +102,7 @@
102102
"semantic-release": "^24.2.1",
103103
"ts-jest": "29.1.0",
104104
"ts-node": "10.9.1",
105-
"typescript": "5.7.3",
105+
"typescript": "5.8.2",
106106
"typescript-eslint": "^8.19.0"
107107
}
108108
}

‎projects/testing-library/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@
2929
"migrations": "./schematics/migrations/migrations.json"
3030
},
3131
"peerDependencies": {
32-
"@angular/animations": ">= 17.0.0",
33-
"@angular/common": ">= 17.0.0",
34-
"@angular/platform-browser": ">= 17.0.0",
35-
"@angular/router": ">= 17.0.0",
36-
"@angular/core": ">= 17.0.0",
32+
"@angular/common": ">= 20.0.0",
33+
"@angular/platform-browser": ">= 20.0.0",
34+
"@angular/router": ">= 20.0.0",
35+
"@angular/core": ">= 20.0.0",
3736
"@testing-library/dom": "^10.0.0"
3837
},
3938
"dependencies": {

‎projects/testing-library/src/lib/config.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ let config: Config = {
77

88
export function configure(newConfig: Partial<Config> | ((config: Partial<Config>) => Partial<Config>)) {
99
if (typeof newConfig === 'function') {
10-
// Pass the existing config out to the provided function
11-
// and accept a delta in return
1210
newConfig = newConfig(config);
1311
}
1412

15-
// Merge the incoming config delta
1613
config = {
1714
...config,
1815
...newConfig,

‎projects/testing-library/src/lib/models.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { Type, DebugElement, EventEmitter, Signal, InputSignalWithTransform } from '@angular/core';
1+
import {
2+
Type,
3+
DebugElement,
4+
ModuleWithProviders,
5+
EventEmitter,
6+
EnvironmentProviders,
7+
Provider,
8+
Signal,
9+
InputSignalWithTransform,
10+
} from '@angular/core';
211
import { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed } from '@angular/core/testing';
312
import { Routes } from '@angular/router';
413
import { BoundFunction, Queries, queries, Config as dtlConfig, PrettyDOMOptions } from '@testing-library/dom';
@@ -153,7 +162,7 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
153162
* declarations: [ CustomerDetailComponent, ButtonComponent ]
154163
* })
155164
*/
156-
declarations?: any[];
165+
declarations?: (Type<unknown>|unknown[])[];
157166
/**
158167
* @description
159168
* A collection of providers needed to render the component via Dependency Injection, for example, injectable services or tokens.
@@ -174,16 +183,15 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
174183
* ]
175184
* })
176185
*/
177-
providers?: any[];
186+
providers?: (Provider|EnvironmentProviders)[];
178187
/**
179188
* @description
180189
* A collection of imports needed to render the component, for example, shared modules.
181-
* Adds `NoopAnimationsModule` by default if `BrowserAnimationsModule` isn't added to the collection.
182190
*
183191
* For more info see https://angular.io/api/core/NgModule#imports
184192
*
185193
* @default
186-
* `[NoopAnimationsModule]`
194+
* `[]`
187195
*
188196
* @example
189197
* await render(AppComponent, {
@@ -193,7 +201,7 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
193201
* ]
194202
* })
195203
*/
196-
imports?: any[];
204+
imports?: (Type<unknown>|ModuleWithProviders<unknown>)[];
197205
/**
198206
* @description
199207
* A collection of schemas needed to render the component.
@@ -315,7 +323,7 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
315323
* ]
316324
* })
317325
*/
318-
componentProviders?: any[];
326+
componentProviders?: Provider[];
319327
/**
320328
* @description
321329
* Collection of child component specified providers to override with
@@ -349,7 +357,7 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
349357
* ]
350358
* })
351359
*/
352-
componentImports?: (Type<any> | any[])[];
360+
componentImports?: (Type<unknown> | unknown[])[];
353361
/**
354362
* @description
355363
* Queries to bind. Overrides the default set from DOM Testing Library unless merged.
@@ -463,7 +471,7 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
463471

464472
export interface ComponentOverride<T> {
465473
component: Type<T>;
466-
providers: any[];
474+
providers: Provider[];
467475
}
468476

469477
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
@@ -497,5 +505,5 @@ export interface Config extends Pick<RenderComponentOptions<any>, 'excludeCompon
497505
/**
498506
* Imports that are added to the imports
499507
*/
500-
defaultImports: any[];
508+
defaultImports?: (Type<unknown>|ModuleWithProviders<unknown>)[];
501509
}

‎projects/testing-library/src/lib/testing-library.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import {
66
OnChanges,
77
OutputRef,
88
OutputRefSubscription,
9+
Provider,
910
SimpleChange,
1011
SimpleChanges,
1112
Type,
1213
isStandalone,
1314
} from '@angular/core';
1415
import { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed, tick } from '@angular/core/testing';
15-
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
1616
import { NavigationExtras, Router } from '@angular/router';
1717
import { RouterTestingModule } from '@angular/router/testing';
1818
import type { BoundFunctions, Queries } from '@testing-library/dom';
@@ -40,7 +40,6 @@ import {
4040
type SubscribedOutput<T> = readonly [key: keyof T, callback: (v: any) => void, subscription: OutputRefSubscription];
4141

4242
const mountedFixtures = new Set<ComponentFixture<any>>();
43-
const safeInject = TestBed.inject || TestBed.get;
4443

4544
export async function render<ComponentType>(
4645
component: Type<ComponentType>,
@@ -108,7 +107,7 @@ export async function render<SutType, WrapperType = SutType>(
108107
imports: imports.concat(defaultImports),
109108
routes,
110109
}),
111-
providers: [...providers],
110+
providers,
112111
schemas: [...schemas],
113112
deferBlockBehavior: deferBlockBehavior ?? DeferBlockBehavior.Manual,
114113
});
@@ -126,8 +125,8 @@ export async function render<SutType, WrapperType = SutType>(
126125

127126
const componentContainer = createComponentFixture(sut, wrapper);
128127

129-
const zone = safeInject(NgZone);
130-
const router = safeInject(Router);
128+
const zone = TestBed.inject(NgZone);
129+
const router = TestBed.inject(Router);
131130
const _navigate = async (elementOrPath: Element | string, basePath = ''): Promise<boolean> => {
132131
const href = typeof elementOrPath === 'string' ? elementOrPath : elementOrPath.getAttribute('href');
133132
const [path, params] = (basePath + href).split('?');
@@ -338,7 +337,7 @@ export async function render<SutType, WrapperType = SutType>(
338337

339338
async function createComponent<SutType>(component: Type<SutType>): Promise<ComponentFixture<SutType>> {
340339
/* Make sure angular application is initialized before creating component */
341-
await safeInject(ApplicationInitStatus).donePromise;
340+
await TestBed.inject(ApplicationInitStatus).donePromise;
342341
return TestBed.createComponent(component);
343342
}
344343

@@ -435,7 +434,7 @@ function overrideComponentImports<SutType>(sut: Type<SutType> | string, imports:
435434
function overrideChildComponentProviders(componentOverrides: ComponentOverride<any>[]) {
436435
if (componentOverrides) {
437436
for (const { component, providers } of componentOverrides) {
438-
TestBed.overrideComponent(component, { set: { providers } });
437+
TestBed.overrideComponent(component, { set: { providers: providersasProvider[] } });
439438
}
440439
}
441440
}
@@ -498,7 +497,7 @@ function addAutoDeclarations<SutType>(
498497
wrapper,
499498
}: Pick<RenderTemplateOptions<any>, 'declarations' | 'excludeComponentDeclaration' | 'wrapper'>,
500499
) {
501-
const nonStandaloneDeclarations = declarations?.filter((d) => !isStandalone(d));
500+
const nonStandaloneDeclarations = declarations.filter((d) => !isStandalone(dasType<any>));
502501
if (typeof sut === 'string') {
503502
if (wrapper && isStandalone(wrapper)) {
504503
return nonStandaloneDeclarations;
@@ -514,15 +513,9 @@ function addAutoImports<SutType>(
514513
sut: Type<SutType> | string,
515514
{ imports = [], routes }: Pick<RenderComponentOptions<any>, 'imports' | 'routes'>,
516515
) {
517-
const animations = () => {
518-
const animationIsDefined =
519-
imports.indexOf(NoopAnimationsModule) > -1 || imports.indexOf(BrowserAnimationsModule) > -1;
520-
return animationIsDefined ? [] : [NoopAnimationsModule];
521-
};
522-
523516
const routing = () => (routes ? [RouterTestingModule.withRoutes(routes)] : []);
524517
const components = () => (typeof sut !== 'string' && isStandalone(sut) ? [sut] : []);
525-
return [...imports, ...components(), ...animations(), ...routing()];
518+
return [...imports, ...components(), ...routing()];
526519
}
527520

528521
async function renderDeferBlock<SutType>(

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /