Skip to content

Commit 10f5389

Browse files
committed
Optimize
1 parent 075e7f2 commit 10f5389

11 files changed

Lines changed: 123 additions & 80 deletions

e2e/components-pages.spec.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { expect, test } from '@playwright/test'
22

3+
import { waitForFontsReady, waitForStyleSettle } from './helpers'
4+
35
test.describe('Components Pages', () => {
46
test.describe('Components link availability', () => {
57
test('header has Components link pointing to /components/overview', async ({
@@ -11,7 +13,7 @@ test.describe('Components Pages', () => {
1113
})
1214
const page = await context.newPage()
1315
await page.goto('/')
14-
await page.waitForTimeout(500)
16+
await waitForFontsReady(page)
1517

1618
const link = page.locator('a[href="/components/overview"]').first()
1719
await expect(link).toBeVisible()
@@ -26,7 +28,7 @@ test.describe('Components Pages', () => {
2628
})
2729
const page = await context.newPage()
2830
await page.goto('/')
29-
await page.waitForTimeout(500)
31+
await waitForFontsReady(page)
3032

3133
const link = page
3234
.locator('a[href="/components/overview"]')
@@ -42,7 +44,7 @@ test.describe('Components Pages', () => {
4244
})
4345
const page = await context.newPage()
4446
await page.goto('/')
45-
await page.waitForTimeout(500)
47+
await waitForFontsReady(page)
4648

4749
const link = page
4850
.locator('a[href="/components/overview"]')
@@ -59,7 +61,7 @@ test.describe('Components Pages', () => {
5961
})
6062
const page = await context.newPage()
6163
await page.goto('/')
62-
await page.waitForTimeout(500)
64+
await waitForFontsReady(page)
6365

6466
const link = page
6567
.locator('a[href="/components/overview"]')
@@ -77,7 +79,7 @@ test.describe('Components Pages', () => {
7779
})
7880
const page = await context.newPage()
7981
await page.goto('/')
80-
await page.waitForTimeout(500)
82+
await waitForFontsReady(page)
8183

8284
const link = page.locator('a[href="/storybook/index.html"]').first()
8385
await expect(link).toBeVisible()
@@ -91,7 +93,7 @@ test.describe('Components Pages', () => {
9193
})
9294
const page = await context.newPage()
9395
await page.goto('/')
94-
await page.waitForTimeout(500)
96+
await waitForFontsReady(page)
9597

9698
const link = page
9799
.locator('a[href="/storybook/index.html"]')
@@ -110,7 +112,7 @@ test.describe('Components Pages', () => {
110112
})
111113
const page = await context.newPage()
112114
await page.goto('/')
113-
await page.waitForTimeout(500)
115+
await waitForFontsReady(page)
114116

115117
await expect(page.getByText('Comparison Bechmarks').first()).toBeVisible()
116118
await context.close()
@@ -123,7 +125,7 @@ test.describe('Components Pages', () => {
123125
})
124126
const page = await context.newPage()
125127
await page.goto('/')
126-
await page.waitForTimeout(500)
128+
await waitForFontsReady(page)
127129

128130
const benchSection = page.getByText('Comparison Bechmarks').first()
129131
await benchSection.scrollIntoViewIfNeeded()
@@ -144,11 +146,11 @@ test.describe('Components Pages', () => {
144146
})
145147
const page = await context.newPage()
146148
await page.goto('/')
147-
await page.waitForTimeout(500)
149+
await waitForFontsReady(page)
148150

149151
const benchSection = page.getByText('Comparison Bechmarks').first()
150152
await benchSection.scrollIntoViewIfNeeded()
151-
await page.waitForTimeout(500)
153+
await waitForStyleSettle(page)
152154

153155
// Check that several competitor names are visible
154156
await expect(page.getByText('Chakra UI').first()).toBeVisible()
@@ -163,11 +165,11 @@ test.describe('Components Pages', () => {
163165
})
164166
const page = await context.newPage()
165167
await page.goto('/')
166-
await page.waitForTimeout(500)
168+
await waitForFontsReady(page)
167169

168170
const benchSection = page.getByText('Comparison Bechmarks').first()
169171
await benchSection.scrollIntoViewIfNeeded()
170-
await page.waitForTimeout(500)
172+
await waitForStyleSettle(page)
171173

172174
await expect(page).toHaveScreenshot(
173175
'components-benchmark-section-desktop.png',
@@ -183,11 +185,11 @@ test.describe('Components Pages', () => {
183185
})
184186
const page = await context.newPage()
185187
await page.goto('/')
186-
await page.waitForTimeout(500)
188+
await waitForFontsReady(page)
187189

188190
const benchSection = page.getByText('Comparison Bechmarks').first()
189191
await benchSection.scrollIntoViewIfNeeded()
190-
await page.waitForTimeout(500)
192+
await waitForStyleSettle(page)
191193

192194
await expect(page).toHaveScreenshot(
193195
'components-benchmark-section-mobile.png',
@@ -204,11 +206,11 @@ test.describe('Components Pages', () => {
204206
})
205207
const page = await context.newPage()
206208
await page.goto('/')
207-
await page.waitForTimeout(500)
209+
await waitForFontsReady(page)
208210

209211
const benchSection = page.getByText('Comparison Bechmarks').first()
210212
await benchSection.scrollIntoViewIfNeeded()
211-
await page.waitForTimeout(500)
213+
await waitForStyleSettle(page)
212214

213215
await expect(page).toHaveScreenshot(
214216
'dark-components-benchmark-section-desktop.png',
@@ -226,7 +228,7 @@ test.describe('Components Pages', () => {
226228
})
227229
const page = await context.newPage()
228230
await page.goto('/')
229-
await page.waitForTimeout(500)
231+
await waitForFontsReady(page)
230232

231233
const community = page.getByText('Join our community').first()
232234
await community.scrollIntoViewIfNeeded()
@@ -241,7 +243,7 @@ test.describe('Components Pages', () => {
241243
})
242244
const page = await context.newPage()
243245
await page.goto('/')
244-
await page.waitForTimeout(500)
246+
await waitForFontsReady(page)
245247

246248
const discordLink = page
247249
.locator('a[href="https://discord.gg/8zjcGc7cWh"]')
@@ -257,7 +259,7 @@ test.describe('Components Pages', () => {
257259
})
258260
const page = await context.newPage()
259261
await page.goto('/')
260-
await page.waitForTimeout(500)
262+
await waitForFontsReady(page)
261263

262264
const kakaoLink = page
263265
.locator('a[href="https://open.kakao.com/o/giONwVAh"]')

e2e/docs-pages.spec.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { expect, test } from '@playwright/test'
22

3+
import { waitForFontsReady, waitForStyleSettle } from './helpers'
4+
35
/**
46
* All tests use javaScriptEnabled: false because the Next.js static export
57
* serves correct SSR HTML, but client-side hydration triggers a 404 under
@@ -20,7 +22,7 @@ test.describe('Documentation Pages', () => {
2022
})
2123
const page = await context.newPage()
2224
await page.goto('/')
23-
await page.waitForTimeout(500)
25+
await waitForFontsReady(page)
2426

2527
const docsLink = page.locator('a[href="/docs/overview"]').first()
2628
await expect(docsLink).toBeVisible()
@@ -36,7 +38,7 @@ test.describe('Documentation Pages', () => {
3638
})
3739
const page = await context.newPage()
3840
await page.goto('/')
39-
await page.waitForTimeout(500)
41+
await waitForFontsReady(page)
4042

4143
const getStarted = page.locator('a[href="/docs/overview"]').filter({
4244
hasText: 'Get started',
@@ -53,7 +55,7 @@ test.describe('Documentation Pages', () => {
5355
})
5456
const page = await context.newPage()
5557
await page.goto('/')
56-
await page.waitForTimeout(500)
58+
await waitForFontsReady(page)
5759

5860
// The header nav link should not be visible on mobile
5961
const docsNavLink = page
@@ -72,7 +74,7 @@ test.describe('Documentation Pages', () => {
7274
})
7375
const page = await context.newPage()
7476
await page.goto('/')
75-
await page.waitForTimeout(500)
77+
await waitForFontsReady(page)
7678

7779
const docsNavLink = page
7880
.locator('a[href="/docs/overview"]')
@@ -91,7 +93,7 @@ test.describe('Documentation Pages', () => {
9193
})
9294
const page = await context.newPage()
9395
await page.goto('/')
94-
await page.waitForTimeout(500)
96+
await waitForFontsReady(page)
9597

9698
// The home page should mention Zero Runtime, which is a key concept
9799
await expect(page.getByText('Zero Runtime').first()).toBeVisible()
@@ -106,7 +108,7 @@ test.describe('Documentation Pages', () => {
106108
})
107109
const page = await context.newPage()
108110
await page.goto('/')
109-
await page.waitForTimeout(500)
111+
await waitForFontsReady(page)
110112

111113
await expect(page.getByText('Features').first()).toBeVisible()
112114

@@ -120,7 +122,7 @@ test.describe('Documentation Pages', () => {
120122
})
121123
const page = await context.newPage()
122124
await page.goto('/')
123-
await page.waitForTimeout(500)
125+
await waitForFontsReady(page)
124126

125127
await expect(page.getByText('Type Safety').first()).toBeVisible()
126128

@@ -134,7 +136,7 @@ test.describe('Documentation Pages', () => {
134136
})
135137
const page = await context.newPage()
136138
await page.goto('/')
137-
await page.waitForTimeout(500)
139+
await waitForFontsReady(page)
138140

139141
const figmaPlugin = page.getByText('Figma Plugin').first()
140142
await figmaPlugin.scrollIntoViewIfNeeded()
@@ -152,11 +154,11 @@ test.describe('Documentation Pages', () => {
152154
})
153155
const page = await context.newPage()
154156
await page.goto('/')
155-
await page.waitForTimeout(500)
157+
await waitForFontsReady(page)
156158

157159
const features = page.getByText('Features').first()
158160
await features.scrollIntoViewIfNeeded()
159-
await page.waitForTimeout(500)
161+
await waitForStyleSettle(page)
160162

161163
await expect(page).toHaveScreenshot('docs-features-section-desktop.png', {
162164
fullPage: false,
@@ -172,11 +174,11 @@ test.describe('Documentation Pages', () => {
172174
})
173175
const page = await context.newPage()
174176
await page.goto('/')
175-
await page.waitForTimeout(500)
177+
await waitForFontsReady(page)
176178

177179
const features = page.getByText('Features').first()
178180
await features.scrollIntoViewIfNeeded()
179-
await page.waitForTimeout(500)
181+
await waitForStyleSettle(page)
180182

181183
await expect(page).toHaveScreenshot('docs-features-section-mobile.png', {
182184
fullPage: false,
@@ -196,11 +198,11 @@ test.describe('Documentation Pages', () => {
196198
await page.evaluate(() =>
197199
document.documentElement.setAttribute('data-theme', 'dark'),
198200
)
199-
await page.waitForTimeout(500)
201+
await waitForStyleSettle(page)
200202

201203
const features = page.getByText('Features').first()
202204
await features.scrollIntoViewIfNeeded()
203-
await page.waitForTimeout(500)
205+
await waitForStyleSettle(page)
204206

205207
await expect(page).toHaveScreenshot(
206208
'dark-docs-features-section-desktop.png',
@@ -219,7 +221,7 @@ test.describe('Documentation Pages', () => {
219221
})
220222
const page = await context.newPage()
221223
await page.goto('/')
222-
await page.waitForTimeout(500)
224+
await waitForFontsReady(page)
223225

224226
const getStarted = page.getByText('Get started').first()
225227
await expect(getStarted).toBeVisible()
@@ -234,7 +236,7 @@ test.describe('Documentation Pages', () => {
234236
})
235237
const page = await context.newPage()
236238
await page.goto('/')
237-
await page.waitForTimeout(500)
239+
await waitForFontsReady(page)
238240

239241
const getStarted = page.getByText('Get started').first()
240242
await expect(getStarted).toBeVisible()

e2e/helpers.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { Page } from '@playwright/test'
2+
3+
/**
4+
* Wait for all fonts to be loaded and a rendering frame to complete.
5+
* Replaces waitForTimeout(1000) after page.goto()
6+
*/
7+
export async function waitForFontsReady(page: Page): Promise<void> {
8+
await page.evaluate(() => document.fonts.ready)
9+
// One extra rAF to let the browser paint with loaded fonts
10+
await page.evaluate(
11+
() => new Promise((resolve) => requestAnimationFrame(resolve)),
12+
)
13+
}
14+
15+
/**
16+
* Wait for CSS transitions to settle after a style/theme change.
17+
* Replaces waitForTimeout(100-300) after theme switches, scroll, evaluate, etc.
18+
*/
19+
export async function waitForStyleSettle(page: Page): Promise<void> {
20+
await page.evaluate(
21+
() => new Promise((resolve) => requestAnimationFrame(resolve)),
22+
)
23+
}

e2e/landing-header.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { expect, test } from '@playwright/test'
22

3+
import { waitForFontsReady, waitForStyleSettle } from './helpers'
4+
35
/**
46
* NOTE: Sub-page navigation is not possible in the current static export +
57
* `serve -s` setup. Header tests that required sub-page navigation have been
@@ -122,7 +124,7 @@ test.describe('Landing Page - Header & Navigation', () => {
122124

123125
// Scroll down significantly
124126
await page.evaluate(() => window.scrollBy(0, 1000))
125-
await page.waitForTimeout(300)
127+
await waitForStyleSettle(page)
126128

127129
// Logo should still be visible because header is fixed/sticky
128130
await expect(logoLink).toBeVisible()
@@ -159,7 +161,7 @@ test.describe('Landing Page - Header & Navigation', () => {
159161
}
160162
})
161163

162-
await page.waitForTimeout(500)
164+
await waitForStyleSettle(page)
163165

164166
const newTheme = await page.evaluate(() =>
165167
document.documentElement.getAttribute('data-theme'),
@@ -211,7 +213,7 @@ test.describe('Landing Page - Header & Navigation', () => {
211213
await expect(menuButton).toBeVisible()
212214

213215
await menuButton.click()
214-
await page.waitForTimeout(1000)
216+
await waitForFontsReady(page)
215217

216218
// After clicking menu, the URL should contain menu=1
217219
const url = page.url()
@@ -255,7 +257,7 @@ test.describe('Landing Page - Header & Navigation', () => {
255257

256258
if ((await searchInput.count()) > 0) {
257259
await searchInput.click()
258-
await page.waitForTimeout(500)
260+
await waitForStyleSettle(page)
259261

260262
const url = page.url()
261263
const hasSearchParam = url.includes('search=')

0 commit comments

Comments
 (0)