Skip to content

Commit

Permalink
fix: wait on app initialization before creating the component (#177)
Browse files Browse the repository at this point in the history
Closes #176
  • Loading branch information
jbchr authored Jan 12, 2021
1 parent 6be4511 commit 87f507b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
27 changes: 21 additions & 6 deletions projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -74,7 +83,7 @@ export async function render<SutType, WrapperType = SutType>(
});
}

const fixture = createComponentFixture(sut, { template, wrapper });
const fixture = await createComponentFixture(sut, { template, wrapper });
setComponentProperties(fixture, { componentProperties });

if (removeAngularAttributes) {
Expand Down Expand Up @@ -174,15 +183,21 @@ export async function render<SutType, WrapperType = SutType>(
};
}

function createComponentFixture<SutType>(
async function createComponent<SutType>(component: Type<SutType>): Promise<ComponentFixture<SutType>> {
/* Make sure angular application is initialized before creating component */
await TestBed.inject(ApplicationInitStatus).donePromise;
return TestBed.createComponent(component);
}

async function createComponentFixture<SutType>(
component: Type<SutType>,
{ template, wrapper }: Pick<RenderDirectiveOptions<SutType, any>, 'template' | 'wrapper'>,
): ComponentFixture<SutType> {
): Promise<ComponentFixture<SutType>> {
if (template) {
TestBed.overrideTemplate(wrapper, template);
return TestBed.createComponent(wrapper);
return createComponent(wrapper);
}
return TestBed.createComponent(component);
return createComponent(component);
}

function setComponentProperties<SutType>(
Expand Down
37 changes: 36 additions & 1 deletion projects/testing-library/tests/render.spec.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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);
});

0 comments on commit 87f507b

Please sign in to comment.