From fbbed20eaabd71db5e480af54da738b151482c80 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:26:57 +0200 Subject: [PATCH 1/5] docs: add test case for #492 (#495) --- .../tests/issues/issue-492.spec.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 projects/testing-library/tests/issues/issue-492.spec.ts diff --git a/projects/testing-library/tests/issues/issue-492.spec.ts b/projects/testing-library/tests/issues/issue-492.spec.ts new file mode 100644 index 0000000..981f5de --- /dev/null +++ b/projects/testing-library/tests/issues/issue-492.spec.ts @@ -0,0 +1,48 @@ +import { AsyncPipe } from '@angular/common'; +import { Component, inject, Injectable } from '@angular/core'; +import { render, screen, waitFor } from '../../src/public_api'; +import { Observable, BehaviorSubject, map } from 'rxjs'; + +test('displays username', async () => { + // stubbed user service using a Subject + const user = new BehaviorSubject({ name: 'username 1' }); + const userServiceStub: Partial = { + getName: () => user.asObservable().pipe(map((u) => u.name)), + }; + + // render the component with injection of the stubbed service + await render(UserComponent, { + componentProviders: [ + { + provide: UserService, + useValue: userServiceStub, + }, + ], + }); + + // assert first username emitted is rendered + expect(await screen.findByRole('heading')).toHaveTextContent('username 1'); + + // emitting a second username + user.next({ name: 'username 2' }); + + // assert the second username is rendered + await waitFor(() => expect(screen.getByRole('heading')).toHaveTextContent('username 2')); +}); + +@Component({ + selector: 'atl-user', + standalone: true, + template: `

{{ username$ | async }}

`, + imports: [AsyncPipe], +}) +class UserComponent { + readonly username$: Observable = inject(UserService).getName(); +} + +@Injectable() +class UserService { + getName(): Observable { + throw new Error('Not implemented'); + } +} From be9c3d5cb990b98768f95bbc12e5ed33cbed72a6 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:30:37 +0200 Subject: [PATCH 2/5] docs: add test case for #492 --- projects/testing-library/tests/issues/issue-492.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/testing-library/tests/issues/issue-492.spec.ts b/projects/testing-library/tests/issues/issue-492.spec.ts index 981f5de..a1e44b0 100644 --- a/projects/testing-library/tests/issues/issue-492.spec.ts +++ b/projects/testing-library/tests/issues/issue-492.spec.ts @@ -1,6 +1,6 @@ import { AsyncPipe } from '@angular/common'; import { Component, inject, Injectable } from '@angular/core'; -import { render, screen, waitFor } from '../../src/public_api'; +import { render, screen } from '../../src/public_api'; import { Observable, BehaviorSubject, map } from 'rxjs'; test('displays username', async () => { @@ -21,13 +21,13 @@ test('displays username', async () => { }); // assert first username emitted is rendered - expect(await screen.findByRole('heading')).toHaveTextContent('username 1'); + expect(await screen.findByRole('heading', { name: 'username 1' })).toBeInTheDocument(); // emitting a second username user.next({ name: 'username 2' }); // assert the second username is rendered - await waitFor(() => expect(screen.getByRole('heading')).toHaveTextContent('username 2')); + expect(await screen.findByRole('heading', { name: 'username 2' })).toBeInTheDocument(); }); @Component({ From 2cfca82442cc2d51ba08e649f37b65fa285eadb6 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:35:35 +0200 Subject: [PATCH 3/5] docs: add test case for #491 (#494) --- .../src/app/issues/issue-491.spec.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 apps/example-app-karma/src/app/issues/issue-491.spec.ts diff --git a/apps/example-app-karma/src/app/issues/issue-491.spec.ts b/apps/example-app-karma/src/app/issues/issue-491.spec.ts new file mode 100644 index 0000000..7da4d6d --- /dev/null +++ b/apps/example-app-karma/src/app/issues/issue-491.spec.ts @@ -0,0 +1,57 @@ +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { render, screen, waitForElementToBeRemoved } from '@testing-library/angular'; +import userEvent from '@testing-library/user-event'; + +it('test click event with router.navigate', async () => { + const user = userEvent.setup(); + await render(``, { + routes: [ + { + path: '', + component: LoginComponent, + }, + { + path: 'logged-in', + component: LoggedInComponent, + }, + ], + }); + + expect(await screen.findByRole('heading', { name: 'Login' })).toBeVisible(); + expect(screen.getByRole('button', { name: 'submit' })).toBeInTheDocument(); + + const email = screen.getByRole('textbox', { name: 'email' }); + const password = screen.getByLabelText('password'); + + await user.type(email, 'user@example.com'); + await user.type(password, 'with_valid_password'); + + expect(screen.getByRole('button', { name: 'submit' })).toBeEnabled(); + + await user.click(screen.getByRole('button', { name: 'submit' })); + + await waitForElementToBeRemoved(() => screen.queryByRole('heading', { name: 'Login' })); + + expect(await screen.findByRole('heading', { name: 'Logged In' })).toBeVisible(); +}); + +@Component({ + template: ` +

Login

+ + + + `, +}) +class LoginComponent { + constructor(private router: Router) {} + onSubmit(): void { + this.router.navigate(['logged-in']); + } +} + +@Component({ + template: `

Logged In

`, +}) +class LoggedInComponent {} From e8ddcf469a5c6dbadd6a1497cfa113ae56920461 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Mon, 14 Oct 2024 19:06:58 +0200 Subject: [PATCH 4/5] docs: add test case for #493 (#496) --- .../tests/issues/issue-493.spec.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 projects/testing-library/tests/issues/issue-493.spec.ts diff --git a/projects/testing-library/tests/issues/issue-493.spec.ts b/projects/testing-library/tests/issues/issue-493.spec.ts new file mode 100644 index 0000000..a49bc80 --- /dev/null +++ b/projects/testing-library/tests/issues/issue-493.spec.ts @@ -0,0 +1,27 @@ +import { HttpClient, provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { Component, input } from '@angular/core'; +import { render, screen } from '../../src/public_api'; + +test('succeeds', async () => { + await render(DummyComponent, { + inputs: { + value: 'test', + }, + providers: [provideHttpClientTesting(), provideHttpClient()], + }); + + expect(screen.getByText('test')).toBeVisible(); +}); + +@Component({ + selector: 'atl-dummy', + standalone: true, + imports: [], + template: '

{{ value() }}

', +}) +class DummyComponent { + value = input.required(); + // @ts-ignore + constructor(private http: HttpClient) {} +} From 5a0665fad22a79af5837d0c110148a09ff963d11 Mon Sep 17 00:00:00 2001 From: Suguru Inatomi Date: Sun, 10 Nov 2024 01:58:38 +0900 Subject: [PATCH 5/5] fix: make wrapper component `standalone: false` explicitly (#498) --- projects/testing-library/src/lib/models.ts | 1 + projects/testing-library/src/lib/testing-library.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts index a52371d..0c34aa8 100644 --- a/projects/testing-library/src/lib/models.ts +++ b/projects/testing-library/src/lib/models.ts @@ -473,6 +473,7 @@ export interface RenderTemplateOptions