Skip to content

Commit 245a470

Browse files
timdeschryveralexkrolick
authored andcommitted
Add angular testing library (testing-library#24)
* feat: add angular testing library * add homepage link
1 parent f26d215 commit 245a470

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
id: intro
3+
title: Introduction
4+
---
5+
6+
[`@angular-extensions/testing-library`][gh] is an [Angular][angular] adapter
7+
around `dom-testing-library`.
8+
9+
```bash
10+
npm install --save-dev @angular-extensions/testing-library
11+
```
12+
13+
- [@angular-extensions/testing-library on GitHub][gh]
14+
15+
## Usage
16+
17+
Use the `createComponent` function to create the component and the Angular
18+
TestBed.
19+
20+
After this, you can use all of `dom-testing-library`'s `getBy`, `getAllBy`,
21+
`queryBy` and `queryAllBy` queries. See [here](../api-queries) for more info.
22+
23+
Besides the `dom-testing-library`'s queries, all of the events (e.g. `click`,
24+
`input`, ...) are also exposed. After every event, this library will run the
25+
Angular change detection. See [here](../api-events) for more info.
26+
27+
## Examples
28+
29+
> **Note**
30+
>
31+
> There are two different ways to create a component, in both ways it's still
32+
> required to provide the Angular TestBed.
33+
34+
One way to create the component is via the component's selector:
35+
36+
```typescript
37+
test('a user can login', async () => {
38+
const {
39+
container,
40+
getByLabelText,
41+
getByText,
42+
input,
43+
submit,
44+
} = await createComponent<LoginFormComponent>('<login-form></login-form>', {
45+
declarations: [LoginFormComponent],
46+
imports: [ReactiveFormsModule],
47+
})
48+
49+
const usernameNode = getByLabelText(/username/i)
50+
const passwordNode = getByLabelText(/password/i)
51+
const submitButtonNode = getByText(/submit/i)
52+
const formNode = container.querySelector('form')
53+
54+
const fakeUser = { username: 'jackiechan', password: 'supersecurepassword' }
55+
56+
input(usernameNode, {
57+
target: {
58+
value: fakeUser.username,
59+
},
60+
})
61+
62+
passwordNode.value = fakeUser.password
63+
input(passwordNode)
64+
65+
submit(formNode)
66+
})
67+
```
68+
69+
Another way to create the component is via the `object` syntax. The only
70+
difference is the setup of the component, the assertions remain the same. This
71+
can come in handy in order to provide more complex parameters or to use a spy to
72+
verify output events.
73+
74+
```typescript
75+
test('a user can login', async () => {
76+
const login = {
77+
emit: jest.fn(),
78+
}
79+
80+
const {
81+
container,
82+
getByLabelText,
83+
getByText,
84+
input,
85+
submit,
86+
} = await createComponent(
87+
{
88+
component: LoginFormComponent,
89+
parameters: {
90+
login,
91+
},
92+
},
93+
{
94+
declarations: [LoginFormComponent],
95+
imports: [ReactiveFormsModule],
96+
}
97+
)
98+
99+
const usernameNode = getByLabelText(/username/i)
100+
const passwordNode = getByLabelText(/password/i)
101+
const submitButtonNode = getByText(/submit/i)
102+
const formNode = container.querySelector('form')
103+
104+
const fakeUser = { username: 'jackiechan', password: 'supersecurepassword' }
105+
106+
input(usernameNode, {
107+
target: {
108+
value: fakeUser.username,
109+
},
110+
})
111+
112+
passwordNode.value = fakeUser.password
113+
input(passwordNode)
114+
115+
submit(formNode)
116+
117+
expect(handleLogin.emit).toHaveBeenCalledWith(fakeUser)
118+
})
119+
```
120+
121+
Inside the project
122+
[tests folder](https://github.com/angular-extensions/testing-library/tree/master/projects/testing-library/tests)
123+
you can find some more simple tests.
124+
125+
[gh]: https://github.com/angular-extensions/testing-library
126+
[angular]: https://angular.io/

website/pages/en/angular.js

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/**
2+
* Copyright (c) 2017-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
const React = require('react')
9+
10+
const CompLibrary = require('../../core/CompLibrary.js')
11+
12+
const MarkdownBlock = CompLibrary.MarkdownBlock /* Used to read markdown */
13+
const Container = CompLibrary.Container
14+
const GridBlock = CompLibrary.GridBlock
15+
16+
class HomeSplash extends React.Component {
17+
render() {
18+
const { siteConfig, language = '' } = this.props
19+
const { baseUrl, docsUrl } = siteConfig
20+
const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`
21+
const langPart = `${language ? `${language}/` : ''}`
22+
const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`
23+
24+
const SplashContainer = props => (
25+
<div className="homeContainer">
26+
<div className="homeSplashFade">
27+
<div className="wrapper homeWrapper">{props.children}</div>
28+
</div>
29+
</div>
30+
)
31+
32+
const Logo = props => (
33+
<div className="projectLogo">
34+
<img
35+
src={props.img_src}
36+
alt="Project Logo"
37+
height={props.height || 128}
38+
/>
39+
</div>
40+
)
41+
42+
const ProjectTitle = () => (
43+
<div>
44+
<h2 className="projectTitle">Angular Testing Library</h2>
45+
<div className="projectTaglineWrapper">
46+
<p className="projectTagline">
47+
Simple and complete Angular DOM testing utilities that encourage
48+
good testing practices with <a href="https://angular.io">Angular</a>
49+
.
50+
</p>
51+
</div>
52+
</div>
53+
)
54+
55+
const PromoSection = props => (
56+
<div className="section promoSection">
57+
<div className="promoRow">
58+
<div className="pluginRowBlock">{props.children}</div>
59+
</div>
60+
</div>
61+
)
62+
63+
const Button = props => (
64+
<div className="pluginWrapper buttonWrapper">
65+
<a className="button" href={props.href} target={props.target}>
66+
{props.children}
67+
</a>
68+
</div>
69+
)
70+
71+
return (
72+
<SplashContainer>
73+
<Logo img_src={`${baseUrl}img/angular-250x250.png`} height={128} />
74+
<div className="inner">
75+
<ProjectTitle siteConfig={siteConfig} />
76+
<PromoSection>
77+
<Button href={docUrl('angular-testing-library/intro')}>
78+
Read the Docs
79+
</Button>
80+
</PromoSection>
81+
</div>
82+
</SplashContainer>
83+
)
84+
}
85+
}
86+
87+
class Index extends React.Component {
88+
render() {
89+
const { config: siteConfig, language = '' } = this.props
90+
const { baseUrl } = siteConfig
91+
92+
const Block = props => (
93+
<Container
94+
padding={['bottom', 'top']}
95+
id={props.id}
96+
background={props.background}
97+
>
98+
<GridBlock
99+
align={props.align || 'center'}
100+
imageAlign={props.imageAlign || 'center'}
101+
contents={props.children}
102+
layout={props.layout}
103+
/>
104+
</Container>
105+
)
106+
107+
const FeatureCallout = () => (
108+
<Container className="" background={'light'} padding={['top', 'bottom']}>
109+
<div style={{ textAlign: 'center' }}>
110+
<p>
111+
<i>
112+
The more your tests resemble the way your software is used, <br />
113+
the more confidence they can give you.
114+
</i>
115+
</p>
116+
<MarkdownBlock>
117+
`npm install --save-dev @angular-extensions/testing-library`
118+
</MarkdownBlock>
119+
</div>
120+
</Container>
121+
)
122+
const Features = () => (
123+
<React.Fragment>
124+
<Block layout="twoColumn">
125+
{[
126+
{
127+
content:
128+
'Tests only break when your app breaks, not implementation details',
129+
image: `${baseUrl}img/wrench-128x128.png`,
130+
imageAlign: 'top',
131+
title: 'Write Maintainable Tests',
132+
},
133+
{
134+
content: 'Interact with your app the same way as your users',
135+
image: `${baseUrl}img/check-128x128.png`,
136+
imageAlign: 'top',
137+
title: 'Develop with Confidence',
138+
},
139+
{
140+
content:
141+
'Built-in selectors use semantic HTML and ARIA roles to help you write inclusive code',
142+
image: `${baseUrl}img/tada-128x128.png`,
143+
imageAlign: 'top',
144+
title: 'Accessible by Default',
145+
},
146+
]}
147+
</Block>
148+
</React.Fragment>
149+
)
150+
151+
return (
152+
<div>
153+
<HomeSplash siteConfig={siteConfig} language={language} />
154+
<div className="mainContainer">
155+
<FeatureCallout />
156+
<Features />
157+
</div>
158+
</div>
159+
)
160+
}
161+
}
162+
163+
module.exports = Index

website/pages/en/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ class Index extends React.Component {
202202
imageAlign: 'top',
203203
title: '[Vue Testing Library](./vue)',
204204
},
205+
{
206+
content: 'For testing Angular Components',
207+
image: `${baseUrl}img/angular-250x250.png`,
208+
imageAlign: 'top',
209+
title: '[Angular Testing Library](./angular)',
210+
},
205211
{
206212
content: 'Explore the ecosystem',
207213
image: `${baseUrl}img/construction-128x128.png`,

website/sidebars.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
"type": "subcategory",
4141
"label": "Vue Testing Library",
4242
"ids": ["vue-testing-library/intro"]
43+
},
44+
{
45+
"type": "subcategory",
46+
"label": "Angular Testing Library",
47+
"ids": ["angular-testing-library/intro"]
4348
}
4449
],
4550
"Ecosystem": ["ecosystem-user-event", "ecosystem-jest-dom"],
2.33 KB
Loading

0 commit comments

Comments
 (0)