From c1ccbe87cd30628977f2ffa58ce0864f31ee7175 Mon Sep 17 00:00:00 2001
From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Thu, 20 Jan 2022 21:38:22 +0100
Subject: [PATCH] docs(angular): Update docs to reflect v11 of ATL
---
docs/angular-testing-library/api.mdx | 141 ++++++++++++++--------
docs/angular-testing-library/examples.mdx | 14 ++-
2 files changed, 99 insertions(+), 56 deletions(-)
diff --git a/docs/angular-testing-library/api.mdx b/docs/angular-testing-library/api.mdx
index d3f6565bb..e30c42729 100644
--- a/docs/angular-testing-library/api.mdx
+++ b/docs/angular-testing-library/api.mdx
@@ -5,12 +5,9 @@ sidebar_label: API
---
`Angular Testing Library` re-exports everything from `DOM Testing Library` as
-well as these methods:
+well as the `render` method.
-- [`render`](#render)
-
-Some of the `DOM Testing Library` re-exports are patched to work easier with
-Angular:
+The following re-exports are patched to make them easier to use with Angular:
- The events on `fireEvent` automatically invoke a change detection cycle after
the event has been fired
@@ -21,15 +18,61 @@ Angular:
## `render`
+With Angular Testing Library, the component can be rendered in two ways, via the
+component's type or with a template.
+
+> By default, `render` also imports the `NoopAnimationsModule`.
+
+## `Type`
+
+To render a component, you need to pass component's type to the `render` method.
+For components that don't use other parts of your application (for example
+design modules or services), rendering a component can be as simple as the
+following example.
+
+```typescript
+await render(AppComponent)
+```
+
+## `template`
+
+Instead of passing the component's type as first argument, you can also provide
+a template. This practice is required to render directives but can also be
+applied to components, it might even be more useful. The directive's (or
+component's) type must then be added to the `declarations`.
+
+**example with directive**:
+
+```typescript
+await render('
', {
+ declarations: [SpoilerDirective],
+})
+```
+
+**example with component**:
+
+```typescript
+await render(
+ '',
+ {
+ declarations: [AppComponent],
+ componentProperties: {
+ anotherValue: 'valueOfAnotherProperty',
+ sendValue: jest.fn(),
+ },
+ },
+)
+```
+
```typescript
-async function render(
+export async function render(
component: Type,
renderOptions?: RenderComponentOptions,
): Promise>
-async function render(
- component: Type,
- renderOptions?: RenderDirectiveOptions,
-): Promise>
+export async function render(
+ template: string,
+ renderOptions?: RenderTemplateOptions,
+): Promise>
```
## Component RenderOptions
@@ -105,7 +148,8 @@ await render(AppComponent, {detectChanges: false})
### `excludeComponentDeclaration`
Exclude the component to be automatically be added as a declaration. This is
-needed when the component is declared in an imported module.
+needed when the component is declared in an imported module, for example with
+SCAMs.
**default** : `false`
@@ -238,39 +282,6 @@ await render(AppComponent, {
})
```
-## Directive RenderOptions
-
-To test a directive, the render API is a bit different. The API has the same
-options as the Component RenderOptions, but has more options:
-
-### `template`
-
-The template to render the directive.
-
-**example**:
-
-```typescript
-await render(SpoilerDirective, {
- template: ``,
-})
-```
-
-### `wrapper`
-
-An Angular component to wrap the directive in.
-
-**default**: `WrapperComponent` , an empty component that strips the
-`ng-version` attribute.
-
-**example**:
-
-```typescript
-await render(SpoilerDirective, {
- template: ``
- wrapper: CustomWrapperComponent
-})
-```
-
## `RenderResult`
### `container`
@@ -290,19 +301,46 @@ const {debug} = await render(AppComponent)
debug()
```
+### `change`
+
+Change the input of the component. This calls `detectChanges` after the props
+are updated.
+
+```typescript
+const {change} = await render(Counter, {
+ componentProperties: {count: 4, name: 'Sarah'},
+})
+
+expect(screen.getByTestId('count-value').textContent).toBe('4')
+expect(screen.getByTestId('name-value').textContent).toBe('Sarah')
+
+change({count: 7})
+
+// count updated to 7
+expect(screen.getByTestId('count-value').textContent).toBe('7')
+// name keeps the same value
+expect(screen.getByTestId('name-value').textContent).toBe('Sarah')
+```
+
### `rerender`
-Re-render the same component with different props. Will call `detectChanges`
-after props has been updated.
+Re-render the same component with different props. Input properties that are not
+defined are cleared. This calls `detectChanges` after the props are updated.
```typescript
-const {rerender} = await render(Counter, {componentProperties: {count: 4}})
+const {rerender} = await render(Counter, {
+ componentProperties: {count: 4, name: 'Sarah'},
+})
expect(screen.getByTestId('count-value').textContent).toBe('4')
+expect(screen.getByTestId('name-value').textContent).toBe('Sarah')
rerender({count: 7})
+// count updated to 7
expect(screen.getByTestId('count-value').textContent).toBe('7')
+// name is undefined because it's not provided in rerender
+expect(screen.getByTestId('name-value').textContent).toBeUndefined()
```
### `detectChanges`
@@ -328,7 +366,8 @@ For more info see the
```typescript
const {fixture} = await render(AppComponent)
-const componentInstance = fixture.componentInstance as AppComponent
+// componentInstance is typed as AppComponent
+const componentInstance = fixture.componentInstance
```
> 🚨 If you find yourself using `fixture` to access the component's internal
@@ -363,6 +402,8 @@ See [Queries](queries/about.mdx) for a complete list.
```typescript
const {getByText, queryByLabelText} = await render(AppComponent)
-getByText('Hello world')
-queryByLabelText('First name:')
+screen.getByRole('heading', {
+ name: /api/i,
+})
+queryByLabelText(/First name/i')
```
diff --git a/docs/angular-testing-library/examples.mdx b/docs/angular-testing-library/examples.mdx
index 5bddb7a48..265565d64 100644
--- a/docs/angular-testing-library/examples.mdx
+++ b/docs/angular-testing-library/examples.mdx
@@ -4,9 +4,10 @@ title: Examples
sidebar_label: Examples
---
-> Read
-> [Good testing practices with 🦔 Angular Testing Library](https://timdeschryver.dev/posts/good-testing-practices-with-angular-testing-library)
-> for a guided example
+> Read about
+> [best practices](https://timdeschryver.dev/blog/good-testing-practices-with-angular-testing-library),
+> or follow the
+> [guided example](https://timdeschryver.dev/blog/getting-the-most-value-out-of-your-angular-component-tests)
counter.component.ts
@@ -44,7 +45,7 @@ describe('Counter', () => {
componentProperties: {counter: 5},
})
- expect(screen.getByText('Current Count: 5'))
+ expect(screen.getByText('Current Count: 5')).toBeInTheDocument()
})
test('should increment the counter on click', async () => {
@@ -54,7 +55,7 @@ describe('Counter', () => {
fireEvent.click(screen.getByText('+'))
- expect(screen.getByText('Current Count: 6'))
+ expect(screen.getByText('Current Count: 6')).toBeInTheDocument()
})
})
```
@@ -66,7 +67,8 @@ These examples include:
- `@Input` and `@Output` properties
- (Reactive) Forms
- Integration with NgRx (mock) Store
-- And more
+- And
+ [more](https://github.com/testing-library/angular-testing-library/tree/master/apps/example-app/src/app/examples)
If you're looking for an example that isn't on the list, please feel free to
create a