Skip to content

Commit

Permalink
fix: invoke change detection after callback in waitForElementToBeRemo…
Browse files Browse the repository at this point in the history
…ved (#236)
  • Loading branch information
timdeschryver authored Jul 6, 2021
1 parent 78646b0 commit 0cbd0fb
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 1 deletion.
3 changes: 2 additions & 1 deletion projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,9 @@ async function waitForElementToBeRemovedWrapper<T>(
}

return await dtlWaitForElementToBeRemoved(() => {
const result = cb();
detectChanges();
return cb();
return result;
}, options);
}

Expand Down
134 changes: 134 additions & 0 deletions projects/testing-library/tests/integration.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { Component, EventEmitter, Injectable, Input, Output } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import userEvent from '@testing-library/user-event';
import { of, BehaviorSubject } from 'rxjs';
import { debounceTime, switchMap, map, startWith } from 'rxjs/operators';
import { render, screen, waitFor, waitForElementToBeRemoved, within } from '../src/lib/testing-library';

const DEBOUNCE_TIME = 1_000;

@Injectable()
class EntitiesService {
fetchAll() {
return of([]);
}
}

@Injectable()
class ModalService {
open(...args: any[]) {
console.log('open', ...args);
}
}

@Component({
template: `
<h1>Entities Title</h1>
<button (click)="newEntityClicked()">Create New Entity</button>
<label>
Search entities
<input type="text" (input)="query.next($event.target.value)" />
</label>
<atl-table [entities]="entities | async" (edit)="editEntityClicked($event)"></atl-table>
`,
})
class EntitiesComponent {
query = new BehaviorSubject<string>('');
readonly entities = this.query.pipe(
debounceTime(DEBOUNCE_TIME),
switchMap((q) => this.entitiesService.fetchAll().pipe(map((ent) => ent.filter((e) => e.name.includes(q))))),
startWith(entities),
);

constructor(private entitiesService: EntitiesService, private modalService: ModalService) {}

newEntityClicked() {
this.modalService.open('new entity');
}

editEntityClicked(entity: string) {
setTimeout(() => {
this.modalService.open('edit entity', entity);
}, 100);
}
}

@Component({
selector: 'atl-table',
template: `
<table>
<tr *ngFor="let entity of entities">
<td>{{ entity.name }}</td>
<td><button (click)="edit.next(entity.name)">Edit</button></td>
</tr>
</table>
`,
})
class TableComponent {
@Input() entities: any[];
@Output() edit = new EventEmitter<string>();
}

const entities = [
{
id: 1,
name: 'Entity 1',
},
{
id: 2,
name: 'Entity 2',
},
{
id: 3,
name: 'Entity 3',
},
];

it('renders the table', async () => {
jest.useFakeTimers();

await render(EntitiesComponent, {
declarations: [TableComponent],
providers: [
{
provide: EntitiesService,
useValue: {
fetchAll: jest.fn().mockReturnValue(of(entities)),
},
},
{
provide: ModalService,
useValue: {
open: jest.fn(),
},
},
],
});
const modalMock = TestBed.inject(ModalService);

expect(await screen.findByRole('heading', { name: /Entities Title/i })).toBeInTheDocument();

expect(await screen.findByRole('cell', { name: /Entity 1/i })).toBeInTheDocument();
expect(await screen.findByRole('cell', { name: /Entity 2/i })).toBeInTheDocument();
expect(await screen.findByRole('cell', { name: /Entity 3/i })).toBeInTheDocument();

userEvent.type(await screen.findByRole('textbox', { name: /Search entities/i }), 'Entity 2', {});

jest.advanceTimersByTime(DEBOUNCE_TIME);

await waitForElementToBeRemoved(() => screen.queryByRole('cell', { name: /Entity 1/i }));
expect(await screen.findByRole('cell', { name: /Entity 2/i })).toBeInTheDocument();

userEvent.click(await screen.findByRole('button', { name: /New Entity/i }));
expect(modalMock.open).toHaveBeenCalledWith('new entity');

const row = await screen.findByRole('row', {
name: /Entity 2/i,
});
userEvent.click(
await within(row).findByRole('button', {
name: /edit/i,
}),
);
waitFor(() => expect(modalMock.open).toHaveBeenCalledWith('edit entity', 'Entity 2'));
});

0 comments on commit 0cbd0fb

Please sign in to comment.