From 3437e96f3d5d1a089775959ed6cac6854622d971 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 9 Dec 2020 16:17:41 +0100 Subject: [PATCH 1/3] docs: add bovandersteene as a contributor (#173) --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5386a0de..d32934f4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -159,6 +159,15 @@ "contributions": [ "doc" ] + }, + { + "login": "bovandersteene", + "name": "Bo Vandersteene", + "avatar_url": "https://avatars1.githubusercontent.com/u/1673799?v=4", + "profile": "http://wwww.reibo.be", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 078632b0..64dac4f5 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,7 @@ Thanks goes to these people ([emoji key][emojis]):
Benjamin Blackwood

📖 ⚠️
Gustavo Porto

📖 +
Bo Vandersteene

💻 From 6be4511d60cbe3b73a490d6ad5a3994f223f712a Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Tue, 15 Dec 2020 09:51:35 +0100 Subject: [PATCH 2/3] docs: add dialog example (#175) --- .../app/examples/15-dialog.component.spec.ts | 63 +++++++++++++++++++ .../app/examples/15-dialog.component.ts | 38 +++++++++++ package.json | 1 + 3 files changed, 102 insertions(+) create mode 100644 apps/example-app/app/examples/15-dialog.component.spec.ts create mode 100644 apps/example-app/app/examples/15-dialog.component.ts diff --git a/apps/example-app/app/examples/15-dialog.component.spec.ts b/apps/example-app/app/examples/15-dialog.component.spec.ts new file mode 100644 index 00000000..f5849abc --- /dev/null +++ b/apps/example-app/app/examples/15-dialog.component.spec.ts @@ -0,0 +1,63 @@ +import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { render, screen, fireEvent, waitForElementToBeRemoved } from '@testing-library/angular'; + +import { DialogComponent, DialogContentComponent, DialogContentComponentModule } from './15-dialog.component'; + +test('dialog closes', async () => { + const closeFn = jest.fn(); + await render(DialogContentComponent, { + imports: [MatDialogModule], + providers: [ + { + provide: MatDialogRef, + useValue: { + close: closeFn, + }, + }, + ], + }); + + const cancelButton = await screen.findByRole('button', { name: /cancel/i }); + fireEvent.click(cancelButton); + + expect(closeFn).toHaveBeenCalledTimes(1); +}); + +test('opens and closes the dialog with buttons', async () => { + await render(DialogComponent, { + imports: [MatDialogModule, DialogContentComponentModule], + }); + + const openDialogButton = await screen.findByRole('button', { name: /open dialog/i }); + fireEvent.click(openDialogButton); + + await screen.findByRole('dialog'); + await screen.findByRole('heading', { name: /dialog title/i }); + + const cancelButton = await screen.findByRole('button', { name: /cancel/i }); + fireEvent.click(cancelButton); + + await waitForElementToBeRemoved(() => screen.getByRole('dialog')); + + const dialogTitle = screen.queryByRole('heading', { name: /dialog title/i }); + expect(dialogTitle).not.toBeInTheDocument(); +}); + +test('closes the dialog via the backdrop', async () => { + await render(DialogComponent, { + imports: [MatDialogModule, DialogContentComponentModule], + }); + + const openDialogButton = await screen.findByRole('button', { name: /open dialog/i }); + fireEvent.click(openDialogButton); + + await screen.findByRole('dialog'); + await screen.findByRole('heading', { name: /dialog title/i }); + + fireEvent.click(document.querySelector('.cdk-overlay-backdrop')); + + await waitForElementToBeRemoved(() => screen.getByRole('dialog')); + + const dialogTitle = screen.queryByRole('heading', { name: /dialog title/i }); + expect(dialogTitle).not.toBeInTheDocument(); +}); diff --git a/apps/example-app/app/examples/15-dialog.component.ts b/apps/example-app/app/examples/15-dialog.component.ts new file mode 100644 index 00000000..ba7eb0da --- /dev/null +++ b/apps/example-app/app/examples/15-dialog.component.ts @@ -0,0 +1,38 @@ +import { Component, NgModule } from '@angular/core'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'dialog-overview-example', + template: ``, +}) +export class DialogComponent { + constructor(public dialog: MatDialog) {} + + openDialog(): void { + this.dialog.open(DialogContentComponent); + } +} + +@Component({ + selector: 'dialog-overview-example-dialog', + template: ` +

Dialog Title

+
Dialog content
+
+ + +
+ `, +}) +export class DialogContentComponent { + constructor(public dialogRef: MatDialogRef) {} + + cancel(): void { + this.dialogRef.close(); + } +} + +@NgModule({ + declarations: [DialogContentComponent], +}) +export class DialogContentComponentModule {} diff --git a/package.json b/package.json index 07227646..79939bad 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.0.0-semantically-released", "scripts": { "ng": "ng", + "postinstall": "ngcc", "start": "ng serve", "build": "nx run-many --target=build --projects=testing-library,jest-utils", "test": "nx run-many --target=test --all", From 87f507b5784dea08bba9a843ee65305347128746 Mon Sep 17 00:00:00 2001 From: Janek <23141806+jbchr@users.noreply.github.com> Date: Tue, 12 Jan 2021 19:07:55 +0100 Subject: [PATCH 3/3] fix: wait on app initialization before creating the component (#177) Closes #176 --- .../src/lib/testing-library.ts | 27 +++++++++++--- projects/testing-library/tests/render.spec.ts | 37 ++++++++++++++++++- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index c5237fdb..66631dc8 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -1,4 +1,13 @@ -import { ChangeDetectorRef, Component, Type, NgZone, SimpleChange, OnChanges, SimpleChanges } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + Type, + NgZone, + SimpleChange, + OnChanges, + SimpleChanges, + ApplicationInitStatus, +} from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -74,7 +83,7 @@ export async function render( }); } - const fixture = createComponentFixture(sut, { template, wrapper }); + const fixture = await createComponentFixture(sut, { template, wrapper }); setComponentProperties(fixture, { componentProperties }); if (removeAngularAttributes) { @@ -174,15 +183,21 @@ export async function render( }; } -function createComponentFixture( +async function createComponent(component: Type): Promise> { + /* Make sure angular application is initialized before creating component */ + await TestBed.inject(ApplicationInitStatus).donePromise; + return TestBed.createComponent(component); +} + +async function createComponentFixture( component: Type, { template, wrapper }: Pick, 'template' | 'wrapper'>, -): ComponentFixture { +): Promise> { if (template) { TestBed.overrideTemplate(wrapper, template); - return TestBed.createComponent(wrapper); + return createComponent(wrapper); } - return TestBed.createComponent(component); + return createComponent(component); } function setComponentProperties( diff --git a/projects/testing-library/tests/render.spec.ts b/projects/testing-library/tests/render.spec.ts index ea6b9062..22d6567e 100644 --- a/projects/testing-library/tests/render.spec.ts +++ b/projects/testing-library/tests/render.spec.ts @@ -1,4 +1,13 @@ -import { Component, NgModule, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { + Component, + NgModule, + Input, + OnChanges, + OnInit, + SimpleChanges, + APP_INITIALIZER, + ApplicationInitStatus, +} from '@angular/core'; import { NoopAnimationsModule, BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { TestBed } from '@angular/core/testing'; import { render, fireEvent } from '../src/public_api'; @@ -116,3 +125,29 @@ describe('Angular component life-cycle hooks', () => { expect(nameChanged.mock.invocationCallOrder[0]).toBeLessThan(nameInitialized.mock.invocationCallOrder[0]); }); }); + +test('Waits for angular app initialization before rendering components', (done) => { + let resolve; + + const promise = new Promise((res) => { + resolve = res; + }); + + render(FixtureComponent, { + providers: [ + { + provide: APP_INITIALIZER, + useFactory: () => () => promise, + multi: true, + }, + ], + }) + .then(() => { + expect(TestBed.inject(ApplicationInitStatus).done).toEqual(true); + done(); + }) + .catch(done); + + // Wait a bit so the test will fail if render completes without us resolving the promise + setTimeout(resolve, 1000); +});