Skip to content

Commit 47c6cb7

Browse files
feat: add DeferBlockBehavior (#431)
1 parent 11cd312 commit 47c6cb7

File tree

3 files changed

+63
-19
lines changed

3 files changed

+63
-19
lines changed

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

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Type, DebugElement } from '@angular/core';
2-
import { ComponentFixture, DeferBlockState, TestBed } from '@angular/core/testing';
2+
import {ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed} from '@angular/core/testing';
33
import { Routes } from '@angular/router';
44
import { BoundFunction, Queries, queries, Config as dtlConfig, PrettyDOMOptions } from '@testing-library/dom';
55

@@ -369,7 +369,17 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
369369
*/
370370
configureTestBed?: (testbed: TestBed) => void;
371371

372+
/**
373+
* @description
374+
* Set the initial state of a deferrable block.
375+
*/
372376
deferBlockStates?: DeferBlockState | { deferBlockState: DeferBlockState; deferBlockIndex: number }[];
377+
378+
/**
379+
* @description
380+
* Set the defer blocks behavior.
381+
*/
382+
deferBlockBehavior?: DeferBlockBehavior
373383
}
374384

375385
export interface ComponentOverride<T> {

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

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
import {
2+
ApplicationInitStatus,
23
ChangeDetectorRef,
34
Component,
4-
Type,
5+
isStandalone,
56
NgZone,
6-
SimpleChange,
77
OnChanges,
8+
SimpleChange,
89
SimpleChanges,
9-
ApplicationInitStatus,
10-
isStandalone,
10+
Type,
1111
} from '@angular/core';
12-
import { ComponentFixture, DeferBlockState, TestBed, tick } from '@angular/core/testing';
13-
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
14-
import { NavigationExtras, Router } from '@angular/router';
15-
import { RouterTestingModule } from '@angular/router/testing';
12+
import {ComponentFixture, DeferBlockState, TestBed, tick} from '@angular/core/testing';
13+
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
14+
import {NavigationExtras, Router} from '@angular/router';
15+
import {RouterTestingModule} from '@angular/router/testing';
16+
import type {BoundFunctions, Queries} from '@testing-library/dom';
1617
import {
18+
configure as dtlConfigure,
1719
getQueriesForElement as dtlGetQueriesForElement,
1820
prettyDOM as dtlPrettyDOM,
21+
queries as dtlQueries,
22+
screen as dtlScreen,
1923
waitFor as dtlWaitFor,
2024
waitForElementToBeRemoved as dtlWaitForElementToBeRemoved,
21-
screen as dtlScreen,
22-
within as dtlWithin,
2325
waitForOptions as dtlWaitForOptions,
24-
configure as dtlConfigure,
25-
queries as dtlQueries,
26+
within as dtlWithin,
2627
} from '@testing-library/dom';
27-
import type { Queries, BoundFunctions } from '@testing-library/dom';
28-
import { RenderComponentOptions, RenderTemplateOptions, RenderResult, ComponentOverride } from './models';
29-
import { getConfig } from './config';
28+
import {ComponentOverride, RenderComponentOptions, RenderResult, RenderTemplateOptions} from './models';
29+
import {getConfig} from './config';
3030

3131
const mountedFixtures = new Set<ComponentFixture<any>>();
3232
const safeInject = TestBed.inject || TestBed.get;
@@ -66,6 +66,7 @@ export async function render<SutType, WrapperType = SutType>(
6666
defaultImports = [],
6767
initialRoute = '',
6868
deferBlockStates = undefined,
69+
deferBlockBehavior = undefined,
6970
configureTestBed = () => {
7071
/* noop*/
7172
},
@@ -94,6 +95,7 @@ export async function render<SutType, WrapperType = SutType>(
9495
}),
9596
providers: [...providers],
9697
schemas: [...schemas],
98+
deferBlockBehavior: deferBlockBehavior as any
9799
});
98100
overrideComponentImports(sut, componentImports);
99101
overrideChildComponentProviders(childComponentOverrides);

projects/testing-library/tests/defer-blocks.spec.ts

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { Component } from '@angular/core';
2-
import { DeferBlockState } from '@angular/core/testing';
3-
import { render, screen } from '../src/public_api';
1+
import {Component} from '@angular/core';
2+
import {DeferBlockBehavior, DeferBlockState} from '@angular/core/testing';
3+
import {render, screen} from '../src/public_api';
4+
import {fireEvent} from "@testing-library/dom";
45

56
test('renders a defer block in different states using the official API', async () => {
67
const { fixture } = await render(FixtureComponent);
@@ -28,6 +29,26 @@ test('renders a defer block in different states using ATL', async () => {
2829
expect(screen.queryByText(/load/i)).not.toBeInTheDocument();
2930
});
3031

32+
test('renders a defer block in different states using DeferBlockBehavior.Playthrough', async () => {
33+
await render(FixtureComponent, {
34+
deferBlockBehavior: DeferBlockBehavior.Playthrough
35+
});
36+
37+
expect(await screen.findByText(/loading/i)).toBeInTheDocument();
38+
expect(await screen.findByText(/Defer block content/i)).toBeInTheDocument();
39+
});
40+
41+
test('renders a defer block in different states using DeferBlockBehavior.Playthrough event', async () => {
42+
await render(FixtureComponentWithEvents, {
43+
deferBlockBehavior: DeferBlockBehavior.Playthrough
44+
});
45+
46+
const button = screen.getByRole('button', {name: /click/i});
47+
fireEvent.click(button)
48+
49+
expect(screen.getByText(/empty defer block/i)).toBeInTheDocument();
50+
});
51+
3152
test('renders a defer block initially in the loading state', async () => {
3253
await render(FixtureComponent, {
3354
deferBlockStates: DeferBlockState.Loading,
@@ -65,3 +86,14 @@ test('renders a defer block in an initial state using the array syntax', async (
6586
`,
6687
})
6788
class FixtureComponent {}
89+
90+
@Component({
91+
template: `
92+
<button #trigger>Click</button>
93+
@defer(on interaction(trigger)) {
94+
<div>empty defer block</div>
95+
}
96+
`,
97+
})
98+
class FixtureComponentWithEvents {}
99+

0 commit comments

Comments
 (0)