Skip to content

Commit c40d30c

Browse files
committed
update 06
1 parent eb82f0b commit c40d30c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+5615
-19065
lines changed

05-testing/03-e2e/06-edit-hotel/.babelrc

Lines changed: 0 additions & 8 deletions
This file was deleted.

05-testing/03-e2e/06-edit-hotel/README.md

Lines changed: 55 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ We will start from `05-custom-commands`.
1212
npm install
1313
```
1414

15-
- To edit an hotel we need to visit `hotels` and click on edit button:
15+
To edit an hotel we need to visit `hotels` and click on edit button:
1616

17-
### ./cypress/e2e/hotel-edit.spec.ts
17+
_./cypress/e2e/hotel-edit.spec.ts_
1818

1919
```javascript
2020
describe('Hotel edit specs', () => {
@@ -26,9 +26,9 @@ describe('Hotel edit specs', () => {
2626
});
2727
```
2828

29-
- To get available `edit button selector`, we need to add accessibility label:
29+
To get available `edit button selector`, we need to add accessibility label:
3030

31-
### ./src/pods/hotel-collection/components/hotel-card.component.tsx
31+
_./src/pods/hotel-collection/components/hotel-card.component.tsx_
3232

3333
```diff
3434
...
@@ -42,260 +42,126 @@ describe('Hotel edit specs', () => {
4242
</CardActions>
4343
```
4444

45-
- Add spec:
45+
Add spec:
4646

47-
### ./cypress/e2e/hotel-edit.spec.ts
47+
_./cypress/e2e/hotel-edit.spec.ts_
4848

4949
```diff
5050
...
5151
it('should navigate to second hotel when click on edit second hotel', () => {
5252
// Arrange
53+
+ cy.intercept('GET', '/api/hotels').as('fetchHotels');
5354

5455
// Act
55-
+ cy.loadAndVisit('/api/hotels', '/hotel-collection');
56-
+ cy.findAllByRole('button', { name: 'Edit hotel' }).then((buttons) => {
57-
+ buttons[1].click();
58-
+ });
56+
+ cy.visit('/hotel-collection');
57+
+ cy.wait('@fetchHotels');
58+
+ cy.findAllByRole('button', { name: /edit hotel/i })
59+
+ .eq(1)
60+
+ .click();
5961

6062
// Assert
6163
+ cy.url().should('equal', 'http://localhost:8080/#/hotel-edit/2');
6264
});
6365

6466
```
65-
67+
> [eq command](https://docs.cypress.io/api/commands/eq)
68+
>
69+
> See also:
70+
>
71+
> `cy.findAllByRole('button', { name: 'Edit hotel' }).then((buttons) => { buttons[1].click(); });`
72+
>
6673
> [Official docs](https://docs.cypress.io/api/commands/then)
6774
68-
- Add update hotel spec:
75+
Add update hotel spec:
6976

70-
### ./cypress/e2e/hotel-edit.spec.ts
77+
_./cypress/e2e/hotel-edit.spec.ts_
7178

7279
```diff
7380
...
7481
+ it('should update hotel name when it edits an hotel and click on save button', () => {
7582
+ // Arrange
83+
+ cy.intercept('GET', '/api/hotels').as('fetchHotels');
7684

7785
+ // Act
78-
+ cy.loadAndVisit('/api/hotels', '/hotel-collection');
79-
80-
+ cy.findAllByRole('button', { name: 'Edit hotel' }).then(($buttons) => {
81-
+ $buttons[1].click();
82-
+ });
86+
+ cy.visit('/hotel-collection');
87+
+ cy.wait('@fetchHotels');
88+
+ cy.findAllByRole('button', { name: /edit hotel/i })
89+
+ .eq(1)
90+
+ .click();
8391

8492
+ cy.findByLabelText('Name').clear().type('Updated hotel two');
85-
8693
+ cy.findByRole('button', { name: 'Save' }).click();
8794

8895
+ // Assert
8996
+ cy.findByText('Updated hotel two');
9097
+ });
9198
```
9299

93-
- The previous spec could works or not, due to we are not waiting to be resolved the get hotel request. If we change network to `Fast 3G` on `Chrome options` to simulate it, we will need do something like:
100+
The previous spec could works or not, due to we are not waiting to be resolved the get hotel request:
94101

95-
### ./cypress/e2e/hotel-edit.spec.ts
102+
_./cypress/e2e/hotel-edit.spec.ts_
96103

97104
```diff
98105
...
99106
it('should update hotel name when it edits an hotel and click on save button', () => {
100107
// Arrange
108+
cy.intercept('GET', '/api/hotels').as('fetchHotels');
109+
+ cy.intercept('GET', '/api/hotels/2').as('fetchHotel');
110+
+ cy.intercept('GET', '/api/cities').as('fetchCities');
101111

102112
// Act
103-
cy.loadAndVisit('/api/hotels', '/hotel-collection');
113+
cy.visit('/hotel-collection');
114+
cy.wait('@fetchHotels');
115+
cy.findAllByRole('button', { name: /edit hotel/i })
116+
.eq(1)
117+
.click();
104118

105-
+ cy.intercept('GET', '/api/hotels/2').as('loadHotel');
106-
107-
cy.findAllByRole('button', { name: 'Edit hotel' }).then(($buttons) => {
108-
$buttons[1].click();
109-
});
110-
111-
+ cy.wait('@loadHotel');
112-
+ cy.findByLabelText('Name').should('not.have.value', '');
119+
+ cy.wait('@fetchHotel');
120+
+ cy.wait('@fetchCities');
113121

114122
cy.findByLabelText('Name').clear().type('Updated hotel two');
115-
116123
cy.findByRole('button', { name: 'Save' }).click();
117124

118125
// Assert
119-
+ cy.wait('@load'); // TODO: Refactor custom command loadAndVisit
126+
+ cy.wait('@fetchHotels');
120127
cy.findByText('Updated hotel two');
121128
});
122129
```
123130

124-
> Notice: some this has to wait until it has some value.
125-
>
126-
> [Wait default timeouts](https://docs.cypress.io/guides/references/configuration#Timeouts)
127-
128-
- Refactor command:
129-
130-
### ./cypress/support/commands.ts
131-
132-
```diff
133-
+ interface Resource {
134-
+ path: string;
135-
+ fixture?: string;
136-
+ alias?: string;
137-
+ }
138-
139-
Cypress.Commands.add(
140-
'loadAndVisit',
141-
- (apiPath: string, routePath: string, fixture?: string) => {
142-
+ (visitUrl: string, resources: Resource[], callbackAfterVisit?: () => void) => {
143-
- Boolean(fixture)
144-
- ? cy.intercept('GET', apiPath, { fixture }).as('load')
145-
- : cy.intercept('GET', apiPath).as('load');
146-
+ const aliasList = resources.map((resource, index) => {
147-
+ const alias = resource.alias || `load-${index}`;
148-
+ Boolean(resource.fixture)
149-
+ ? cy
150-
+ .intercept('GET', resource.path, { fixture: resource.fixture })
151-
+ .as(alias)
152-
+ : cy.intercept('GET', resource.path).as(alias);
153-
154-
+ return alias;
155-
+ });
156-
157-
- cy.visit(routePath);
158-
+ cy.visit(visitUrl);
159-
+ if (callbackAfterVisit) {
160-
+ callbackAfterVisit();
161-
+ }
162-
163-
- cy.wait('@load');
164-
+ aliasList.forEach((alias) => {
165-
+ cy.wait(`@${alias}`);
166-
+ });
167-
}
168-
);
169-
170-
```
171-
172-
- Update `d.ts`:
173-
174-
### ./cypress/support/index.d.ts
175-
176-
```diff
177-
declare namespace Cypress {
178-
+ interface Resource {
179-
+ path: string;
180-
+ fixture?: string;
181-
+ alias?: string;
182-
+ }
183-
184-
interface Chainable {
185-
loadAndVisit(
186-
- apiPath: string,
187-
+ visitUrl: string,
188-
- routePath: string,
189-
+ resources: Resource[],
190-
- fixture?: string
191-
+ callbackAfterVisit?: () => void
192-
): Chainable<Element>;
193-
}
194-
}
195-
196-
```
131+
But if we change network to `Fast 4G` on `Chrome options` to simulate a device with a slow connection, it will fail. Because it takes more time to render the hotel page with the new values from the server and the spec is not waiting for it.
197132

198-
- Update specs:
133+
In this case, we can use a selector to wait for the component to have some value before writing the new one:
199134

200-
### ./cypress/e2e/hotel-edit.spec.ts
135+
_./cypress/e2e/hotel-edit.spec.ts_
201136

202137
```diff
203138
...
204-
it('should navigate to second hotel when click on edit second hotel', () => {
205-
// Arrange
206-
207-
// Act
208-
- cy.loadAndVisit('/api/hotels', '/hotel-collection');
209-
+ cy.loadAndVisit('/hotel-collection', [{ path: '/api/hotels' }]);
210-
211-
cy.findAllByRole('button', { name: 'Edit hotel' }).then(($buttons) => {
212-
$buttons[1].click();
213-
});
214-
215-
// Assert
216-
cy.url().should('eq', 'http://localhost:8080/#/hotel-edit/2');
217-
});
218-
219139
it('should update hotel name when it edits an hotel and click on save button', () => {
220140
// Arrange
141+
cy.intercept('GET', '/api/hotels').as('fetchHotels');
142+
cy.intercept('GET', '/api/hotels/2').as('fetchHotel');
143+
cy.intercept('GET', '/api/cities').as('fetchCities');
221144

222145
// Act
223-
- cy.loadAndVisit('/api/hotels', '/hotel-collection');
224-
+ cy.loadAndVisit(
225-
+ '/hotel-collection',
226-
+ [
227-
+ { path: '/api/hotels', alias: 'loadHotels' },
228-
+ { path: '/api/hotels/2' },
229-
+ { path: '/api/cities' },
230-
+ ],
231-
+ () => {
232-
+ cy.findAllByRole('button', { name: 'Edit hotel' }).then((buttons) => {
233-
+ buttons[1].click();
234-
+ });
235-
+ }
236-
+ );
237-
238-
- cy.intercept('GET', '/api/hotels/2').as('loadHotel');
239-
240-
- cy.findAllByRole('button', { name: 'Edit hotel' }).then(($buttons) => {
241-
- $buttons[1].click();
242-
- });
243-
244-
- cy.wait('@loadHotel');
245-
246-
cy.findByLabelText('Name').should('not.have.value', '');
146+
cy.visit('/hotel-collection');
147+
cy.wait('@fetchHotels');
148+
cy.findAllByRole('button', { name: /edit hotel/i })
149+
.eq(1)
150+
.click();
247151

248-
cy.findByLabelText('Name').clear().type('Updated hotel two');
152+
cy.wait('@fetchHotel');
153+
cy.wait('@fetchCities');
249154

155+
+ cy.findByLabelText('Name').should('not.have.value', '');
156+
cy.findByLabelText('Name').clear().type('Updated hotel two');
250157
cy.findByRole('button', { name: 'Save' }).click();
251158

252159
// Assert
253-
- cy.wait('@load'); // TODO: Refactor custom command loadAndVisit
254-
+ cy.wait('@loadHotels');
160+
cy.wait('@fetchHotels');
255161
cy.findByText('Updated hotel two');
256162
});
257163
```
258164

259-
### ./cypress/e2e/hotel-collection.spec.ts
260-
261-
```diff
262-
...
263-
it('should fetch hotel list and show it in screen when visit /hotel-collection url', () => {
264-
// Arrange
265-
266-
// Act
267-
- cy.loadAndVisit('/api/hotels', '/hotel-collection');
268-
+ cy.loadAndVisit('/hotel-collection', [{ path: '/api/hotels' }]);
269-
270-
// Assert
271-
cy.findAllByRole('listitem').should('have.length', 10);
272-
});
273-
274-
it('should fetch hotel list greater than 0 when visit /hotel-collection url', () => {
275-
// Arrange
276-
277-
// Act
278-
- cy.loadAndVisit('/api/hotels', '/hotel-collection');
279-
+ cy.loadAndVisit('/hotel-collection', [{ path: '/api/hotels' }]);
280-
281-
// Assert
282-
cy.findAllByRole('listitem').should('have.length.greaterThan', 0);
283-
});
284-
285-
it('should fetch two hotels when visit /hotel-collection url', () => {
286-
// Arrange
287-
288-
// Act
289-
- cy.loadAndVisit('/api/hotels', '/hotel-collection', 'hotels.json');
290-
+ cy.loadAndVisit('/hotel-collection', [
291-
+ { path: '/api/hotels', fixture: 'hotels' },
292-
+ ]);
293-
294-
// Assert
295-
cy.findAllByRole('listitem').should('have.length', 2);
296-
});
297-
```
298-
299165
# About Basefactor + Lemoncode
300166

301167
We are an innovating team of Javascript experts, passionate about turning your ideas into robust products.

05-testing/03-e2e/06-edit-hotel/config/webpack/base.js

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)