Skip to content

Commit 87f507b

Browse files
authored
fix: wait on app initialization before creating the component (#177)
Closes #176
1 parent 6be4511 commit 87f507b

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

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

+21-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { ChangeDetectorRef, Component, Type, NgZone, SimpleChange, OnChanges, SimpleChanges } from '@angular/core';
1+
import {
2+
ChangeDetectorRef,
3+
Component,
4+
Type,
5+
NgZone,
6+
SimpleChange,
7+
OnChanges,
8+
SimpleChanges,
9+
ApplicationInitStatus,
10+
} from '@angular/core';
211
import { ComponentFixture, TestBed } from '@angular/core/testing';
312
import { By } from '@angular/platform-browser';
413
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
@@ -74,7 +83,7 @@ export async function render<SutType, WrapperType = SutType>(
7483
});
7584
}
7685

77-
const fixture = createComponentFixture(sut, { template, wrapper });
86+
const fixture = await createComponentFixture(sut, { template, wrapper });
7887
setComponentProperties(fixture, { componentProperties });
7988

8089
if (removeAngularAttributes) {
@@ -174,15 +183,21 @@ export async function render<SutType, WrapperType = SutType>(
174183
};
175184
}
176185

177-
function createComponentFixture<SutType>(
186+
async function createComponent<SutType>(component: Type<SutType>): Promise<ComponentFixture<SutType>> {
187+
/* Make sure angular application is initialized before creating component */
188+
await TestBed.inject(ApplicationInitStatus).donePromise;
189+
return TestBed.createComponent(component);
190+
}
191+
192+
async function createComponentFixture<SutType>(
178193
component: Type<SutType>,
179194
{ template, wrapper }: Pick<RenderDirectiveOptions<SutType, any>, 'template' | 'wrapper'>,
180-
): ComponentFixture<SutType> {
195+
): Promise<ComponentFixture<SutType>> {
181196
if (template) {
182197
TestBed.overrideTemplate(wrapper, template);
183-
return TestBed.createComponent(wrapper);
198+
return createComponent(wrapper);
184199
}
185-
return TestBed.createComponent(component);
200+
return createComponent(component);
186201
}
187202

188203
function setComponentProperties<SutType>(

projects/testing-library/tests/render.spec.ts

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { Component, NgModule, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
1+
import {
2+
Component,
3+
NgModule,
4+
Input,
5+
OnChanges,
6+
OnInit,
7+
SimpleChanges,
8+
APP_INITIALIZER,
9+
ApplicationInitStatus,
10+
} from '@angular/core';
211
import { NoopAnimationsModule, BrowserAnimationsModule } from '@angular/platform-browser/animations';
312
import { TestBed } from '@angular/core/testing';
413
import { render, fireEvent } from '../src/public_api';
@@ -116,3 +125,29 @@ describe('Angular component life-cycle hooks', () => {
116125
expect(nameChanged.mock.invocationCallOrder[0]).toBeLessThan(nameInitialized.mock.invocationCallOrder[0]);
117126
});
118127
});
128+
129+
test('Waits for angular app initialization before rendering components', (done) => {
130+
let resolve;
131+
132+
const promise = new Promise((res) => {
133+
resolve = res;
134+
});
135+
136+
render(FixtureComponent, {
137+
providers: [
138+
{
139+
provide: APP_INITIALIZER,
140+
useFactory: () => () => promise,
141+
multi: true,
142+
},
143+
],
144+
})
145+
.then(() => {
146+
expect(TestBed.inject(ApplicationInitStatus).done).toEqual(true);
147+
done();
148+
})
149+
.catch(done);
150+
151+
// Wait a bit so the test will fail if render completes without us resolving the promise
152+
setTimeout(resolve, 1000);
153+
});

0 commit comments

Comments
 (0)