Skip to content

Commit f656b5a

Browse files
committed
add awesome tests for exercise 4
1 parent 562d807 commit f656b5a

File tree

36 files changed

+336
-136
lines changed

36 files changed

+336
-136
lines changed

exercises/04.router/01.problem.router/tests/smoke.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ test('should display the home page and perform search', async ({ page }) => {
1717
const shipList = page.getByRole('list').first()
1818

1919
// Wait for the list to be filtered down to two items
20-
await expect(async () => {
21-
const items = await shipList.getByRole('listitem').all()
22-
expect(items.length).toBe(2)
23-
}).toPass()
20+
await expect(shipList.getByRole('listitem')).toHaveCount(2)
2421

2522
// Verify filtered results
2623
const shipLinks = page

exercises/04.router/01.solution.router/tests/smoke.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ test('should display the home page and perform search', async ({ page }) => {
1717
const shipList = page.getByRole('list').first()
1818

1919
// Wait for the list to be filtered down to two items
20-
await expect(async () => {
21-
const items = await shipList.getByRole('listitem').all()
22-
expect(items.length).toBe(2)
23-
}).toPass()
20+
await expect(shipList.getByRole('listitem')).toHaveCount(2)
2421

2522
// Verify filtered results
2623
const shipLinks = page
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test, expect } from '@playwright/test'
2+
import { searchShips } from '../db/ship-api.js'
3+
4+
test('should display pending UI when performing a search and selecting a ship', async ({
5+
page,
6+
}) => {
7+
const {
8+
ships: [firstShip],
9+
} = await searchShips({ search: '' })
10+
await page.goto(`/${firstShip.id}`)
11+
12+
await page.waitForSelector('li a:has-text("... loading")', {
13+
state: 'detached',
14+
})
15+
16+
// simulate a slow network for the /rsc endpoint so we force the pending UI to show up
17+
await page.route('/rsc/*', async route => {
18+
await new Promise(resolve => setTimeout(resolve, 400))
19+
await route.continue()
20+
})
21+
22+
const searchInput = page.getByRole('searchbox', { name: /ships/i })
23+
await searchInput.fill('s')
24+
25+
await expect(page.getByRole('list').first()).toHaveCSS('opacity', '0.6')
26+
27+
await expect(page.getByRole('list').first()).toHaveCSS('opacity', '1')
28+
29+
const firstShipLink = page.locator('li a').first()
30+
const shipName = await firstShipLink.textContent()
31+
await firstShipLink.click()
32+
33+
await expect(page.locator('.details')).toHaveCSS('opacity', '0.6')
34+
35+
await expect(page.locator('.details')).toHaveCSS('opacity', '1')
36+
37+
const shipTitle = page.getByRole('heading', { level: 2 })
38+
await expect(shipTitle).toHaveText(shipName)
39+
})

exercises/04.router/02.problem.pending-ui/tests/smoke.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ test('should display the home page and perform search', async ({ page }) => {
1717
const shipList = page.getByRole('list').first()
1818

1919
// Wait for the list to be filtered down to two items
20-
await expect(async () => {
21-
const items = await shipList.getByRole('listitem').all()
22-
expect(items.length).toBe(2)
23-
}).toPass()
20+
await expect(shipList.getByRole('listitem')).toHaveCount(2)
2421

2522
// Verify filtered results
2623
const shipLinks = page

exercises/04.router/02.problem.pending-ui/tests/solution.test.js

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test, expect } from '@playwright/test'
2+
import { searchShips } from '../db/ship-api.js'
3+
4+
test('should display pending UI when performing a search and selecting a ship', async ({
5+
page,
6+
}) => {
7+
const {
8+
ships: [firstShip],
9+
} = await searchShips({ search: '' })
10+
await page.goto(`/${firstShip.id}`)
11+
12+
await page.waitForSelector('li a:has-text("... loading")', {
13+
state: 'detached',
14+
})
15+
16+
// simulate a slow network for the /rsc endpoint so we force the pending UI to show up
17+
await page.route('/rsc/*', async route => {
18+
await new Promise(resolve => setTimeout(resolve, 400))
19+
await route.continue()
20+
})
21+
22+
const searchInput = page.getByRole('searchbox', { name: /ships/i })
23+
await searchInput.fill('s')
24+
25+
await expect(page.getByRole('list').first()).toHaveCSS('opacity', '0.6')
26+
27+
await expect(page.getByRole('list').first()).toHaveCSS('opacity', '1')
28+
29+
const firstShipLink = page.locator('li a').first()
30+
const shipName = await firstShipLink.textContent()
31+
await firstShipLink.click()
32+
33+
await expect(page.locator('.details')).toHaveCSS('opacity', '0.6')
34+
35+
await expect(page.locator('.details')).toHaveCSS('opacity', '1')
36+
37+
const shipTitle = page.getByRole('heading', { level: 2 })
38+
await expect(shipTitle).toHaveText(shipName)
39+
})

exercises/04.router/02.solution.pending-ui/tests/smoke.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ test('should display the home page and perform search', async ({ page }) => {
1717
const shipList = page.getByRole('list').first()
1818

1919
// Wait for the list to be filtered down to two items
20-
await expect(async () => {
21-
const items = await shipList.getByRole('listitem').all()
22-
expect(items.length).toBe(2)
23-
}).toPass()
20+
await expect(shipList.getByRole('listitem')).toHaveCount(2)
2421

2522
// Verify filtered results
2623
const shipLinks = page

exercises/04.router/02.solution.pending-ui/tests/solution.test.js

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { test, expect } from '@playwright/test'
2+
3+
test('should not update URL for out-of-order responses', async ({ page }) => {
4+
await page.goto('/')
5+
6+
// Simulate varying network delays
7+
await page.route('/rsc/*', async route => {
8+
const url = route.request().url()
9+
if (url.includes('search=st')) {
10+
await new Promise(resolve => setTimeout(resolve, 2000)) // Longer delay for 'st'
11+
}
12+
await route.continue()
13+
})
14+
15+
const searchInput = page.getByRole('searchbox', { name: /ships/i })
16+
17+
// Perform rapid searches
18+
await searchInput.fill('s')
19+
await searchInput.fill('st')
20+
await searchInput.fill('sta')
21+
22+
// Wait for the last search to complete
23+
await page.waitForURL('**/*?search=sta')
24+
25+
// Wait for all in-flight requests to finish
26+
await page.waitForLoadState('networkidle')
27+
28+
// Check that the URL ends with 'sta', not 'st'
29+
expect(page.url()).toMatch(/search=sta$/)
30+
})

exercises/04.router/03.problem.race-conditions/tests/smoke.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ test('should display the home page and perform search', async ({ page }) => {
1717
const shipList = page.getByRole('list').first()
1818

1919
// Wait for the list to be filtered down to two items
20-
await expect(async () => {
21-
const items = await shipList.getByRole('listitem').all()
22-
expect(items.length).toBe(2)
23-
}).toPass()
20+
await expect(shipList.getByRole('listitem')).toHaveCount(2)
2421

2522
// Verify filtered results
2623
const shipLinks = page

0 commit comments

Comments
 (0)