Skip to content

Commit 4685b68

Browse files
committed
Fix shadow issue
1 parent ef36c44 commit 4685b68

File tree

8 files changed

+80
-193
lines changed

8 files changed

+80
-193
lines changed

e2e/helpers.ts

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

3-
const CI_SETTLE_DELAY_MS = 250
4-
const LOCAL_SETTLE_DELAY_MS = 100
5-
6-
function getSettleDelayMs(): number {
7-
return process.env.CI ? CI_SETTLE_DELAY_MS : LOCAL_SETTLE_DELAY_MS
8-
}
9-
103
/**
114
* Wait for all fonts to be loaded and a rendering frame to complete.
125
* Replaces waitForTimeout(1000) after page.goto()
@@ -15,43 +8,14 @@ function getSettleDelayMs(): number {
158
* (page.evaluate is not available in JS-disabled contexts).
169
*/
1710
export async function waitForFontsReady(page: Page): Promise<void> {
18-
await page.waitForLoadState('load')
19-
2011
try {
21-
await page.evaluate(async (settleDelayMs) => {
22-
const wait = (ms: number) =>
23-
new Promise<void>((resolve) => window.setTimeout(resolve, ms))
24-
const nextFrame = () =>
25-
new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
26-
27-
if ('fonts' in document) {
28-
await document.fonts.ready
29-
}
30-
31-
const pendingImages = Array.from(document.images).filter(
32-
(image) => !image.complete,
33-
)
34-
35-
await Promise.all(
36-
pendingImages.map(
37-
(image) =>
38-
new Promise<void>((resolve) => {
39-
image.addEventListener('load', () => resolve(), {
40-
once: true,
41-
})
42-
image.addEventListener('error', () => resolve(), {
43-
once: true,
44-
})
45-
}),
46-
),
47-
)
48-
49-
await nextFrame()
50-
await nextFrame()
51-
await wait(settleDelayMs)
52-
}, getSettleDelayMs())
12+
await page.evaluate(async () => {
13+
await document.fonts.ready
14+
await page.waitForLoadState('load')
15+
})
5316
} catch {
54-
await page.waitForTimeout(getSettleDelayMs())
17+
// JS disabled — fall back to load event (fires after fonts in CSS are loaded)
18+
await page.waitForLoadState('load')
5519
}
5620
}
5721

@@ -62,44 +26,5 @@ export async function waitForFontsReady(page: Page): Promise<void> {
6226
* Falls back to waitForLoadState('load') when JavaScript is disabled.
6327
*/
6428
export async function waitForStyleSettle(page: Page): Promise<void> {
65-
try {
66-
await page.waitForFunction(() => {
67-
return Array.from(
68-
document.querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]'),
69-
).every((link) => {
70-
if (!link.href) {
71-
return true
72-
}
73-
74-
const { sheet } = link
75-
if (!sheet) {
76-
return false
77-
}
78-
79-
try {
80-
void sheet.cssRules
81-
return true
82-
} catch {
83-
return false
84-
}
85-
})
86-
})
87-
} catch {
88-
await page.waitForLoadState('load')
89-
}
90-
91-
try {
92-
await page.evaluate(async (settleDelayMs) => {
93-
const wait = (ms: number) =>
94-
new Promise<void>((resolve) => window.setTimeout(resolve, ms))
95-
const nextFrame = () =>
96-
new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
97-
98-
await nextFrame()
99-
await nextFrame()
100-
await wait(settleDelayMs)
101-
}, getSettleDelayMs())
102-
} catch {
103-
await page.waitForTimeout(getSettleDelayMs())
104-
}
29+
await page.waitForTimeout(100)
10530
}

packages/next-plugin/src/__tests__/css-loader.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ describe('devupUICssLoader', () => {
348348
})
349349

350350
expect(error.message).toBe('Coordinator port file not found')
351-
}, 15000)
351+
})
352352

353353
it('should error when coordinator returns non-200 status', async () => {
354354
const server = http.createServer((_req, res) => {

packages/next-plugin/src/__tests__/loader.test.ts

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,10 @@ describe('devupUILoader', () => {
183183
'utf-8',
184184
)
185185

186-
// Verify cssFile branch — now writes actual CSS content
186+
// Verify cssFile && watch branch (lines 100-111)
187187
expect(writeFileSpy).toHaveBeenCalledWith(
188188
join('cssDir', 'devup-ui-1.css'),
189-
'base-css',
190-
'utf-8',
189+
'/* watch-init.tsx 0 */',
191190
)
192191
expect(writeFileSpy).toHaveBeenCalledWith('sheetFile', 'sheet')
193192
expect(writeFileSpy).toHaveBeenCalledWith('classMapFile', 'classMap')
@@ -347,7 +346,7 @@ describe('devupUILoader', () => {
347346
css: 'css',
348347
free: mock(),
349348
map: undefined,
350-
cssFile: 'devup-ui-1.css',
349+
cssFile: 'cssFile',
351350
updatedBaseStyle: false,
352351
[Symbol.dispose]: mock(),
353352
})
@@ -357,12 +356,12 @@ describe('devupUILoader', () => {
357356
})
358357
})
359358

360-
it('should write css files in build mode when cssFile is returned', async () => {
359+
it('should not write css files in build mode even with cssFile', async () => {
361360
const asyncCallback = mock()
362361
const t = {
363362
getOptions: () => ({
364363
package: 'package',
365-
cssDir: 'cssDir',
364+
cssDir: 'cssFile',
366365
watch: false,
367366
singleCss: true,
368367
defaultClassMap: {},
@@ -373,16 +372,12 @@ describe('devupUILoader', () => {
373372
resourcePath: 'index.tsx',
374373
addDependency: mock(),
375374
}
376-
getCssSpy.mockReturnValue('generated-css')
377-
exportSheetSpy.mockReturnValue('sheet')
378-
exportClassMapSpy.mockReturnValue('classMap')
379-
exportFileMapSpy.mockReturnValue('fileMap')
380375
codeExtractSpy.mockReturnValue({
381376
code: 'code',
382377
css: 'css',
383378
free: mock(),
384379
map: '{}',
385-
cssFile: 'devup-ui-1.css',
380+
cssFile: 'cssFile',
386381
updatedBaseStyle: true,
387382
[Symbol.dispose]: mock(),
388383
})
@@ -391,17 +386,8 @@ describe('devupUILoader', () => {
391386
await waitFor(() => {
392387
expect(asyncCallback).toHaveBeenCalledWith(null, 'code', {})
393388
})
394-
// CSS files are now written in build mode too
395-
expect(writeFileSpy).toHaveBeenCalledWith(
396-
join('cssDir', 'devup-ui.css'),
397-
'generated-css',
398-
'utf-8',
399-
)
400-
expect(writeFileSpy).toHaveBeenCalledWith(
401-
join('cssDir', 'devup-ui-1.css'),
402-
'generated-css',
403-
'utf-8',
404-
)
389+
// In build mode (watch=false), no CSS files should be written
390+
expect(writeFileSpy).not.toHaveBeenCalled()
405391
})
406392

407393
describe('coordinator mode', () => {
@@ -658,16 +644,16 @@ describe('devupUILoader', () => {
658644

659645
devupUILoader.bind(t as any)(Buffer.from('code'), 'fallback.tsx')
660646

661-
// Retries 200 times × 50ms = 10s max, then calls back with error
647+
// Retries 20 times × 50ms = 1s max, then calls back with error
662648
await waitFor(() => {
663649
expect(asyncCallback).toHaveBeenCalledWith(
664650
new Error('Coordinator port file not found'),
665651
)
666-
}, 15000)
652+
}, 3000)
667653

668654
// WASM should NOT be used — coordinator mode does not fall back
669655
expect(codeExtractSpy).not.toHaveBeenCalled()
670-
}, 20000)
656+
})
671657

672658
it('should retry and succeed when coordinatorPortFile appears after delay', async () => {
673659
// First few calls: port file doesn't exist, then it appears

packages/next-plugin/src/__tests__/plugin.test.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ describe('DevupUINextPlugin', () => {
185185
loader: '@devup-ui/next-plugin/css-loader',
186186
options: {
187187
watch: false,
188+
coordinatorPortFile: join('df', 'coordinator.port'),
188189
sheetFile: join('df', 'sheet.json'),
189190
classMapFile: join('df', 'classMap.json'),
190191
fileMapFile: join('df', 'fileMap.json'),
@@ -210,6 +211,7 @@ describe('DevupUINextPlugin', () => {
210211
options: {
211212
package: '@devup-ui/react',
212213
cssDir: resolve('df', 'devup-ui'),
214+
coordinatorPortFile: join('df', 'coordinator.port'),
213215
sheetFile: join('df', 'sheet.json'),
214216
classMapFile: join('df', 'classMap.json'),
215217
fileMapFile: join('df', 'fileMap.json'),
@@ -267,6 +269,7 @@ describe('DevupUINextPlugin', () => {
267269
loader: '@devup-ui/next-plugin/css-loader',
268270
options: {
269271
watch: false,
272+
coordinatorPortFile: join('df', 'coordinator.port'),
270273
sheetFile: join('df', 'sheet.json'),
271274
classMapFile: join('df', 'classMap.json'),
272275
fileMapFile: join('df', 'fileMap.json'),
@@ -304,6 +307,7 @@ describe('DevupUINextPlugin', () => {
304307
options: {
305308
package: '@devup-ui/react',
306309
cssDir: resolve('df', 'devup-ui'),
310+
coordinatorPortFile: join('df', 'coordinator.port'),
307311
sheetFile: join('df', 'sheet.json'),
308312
classMapFile: join('df', 'classMap.json'),
309313
fileMapFile: join('df', 'fileMap.json'),
@@ -357,6 +361,7 @@ describe('DevupUINextPlugin', () => {
357361
loader: '@devup-ui/next-plugin/css-loader',
358362
options: {
359363
watch: false,
364+
coordinatorPortFile: join('df', 'coordinator.port'),
360365
sheetFile: join('df', 'sheet.json'),
361366
classMapFile: join('df', 'classMap.json'),
362367
fileMapFile: join('df', 'fileMap.json'),
@@ -394,6 +399,7 @@ describe('DevupUINextPlugin', () => {
394399
options: {
395400
package: '@devup-ui/react',
396401
cssDir: resolve('df', 'devup-ui'),
402+
coordinatorPortFile: join('df', 'coordinator.port'),
397403
sheetFile: join('df', 'sheet.json'),
398404
classMapFile: join('df', 'classMap.json'),
399405
fileMapFile: join('df', 'fileMap.json'),
@@ -431,7 +437,7 @@ describe('DevupUINextPlugin', () => {
431437
'*',
432438
)
433439
})
434-
it('should not start coordinator in production mode', () => {
440+
it('should start coordinator even in production mode', () => {
435441
;(process.env as any).NODE_ENV = 'production'
436442
process.env.TURBOPACK = '1'
437443
existsSyncSpy
@@ -445,7 +451,20 @@ describe('DevupUINextPlugin', () => {
445451
rules: expect.any(Object),
446452
},
447453
})
448-
expect(startCoordinatorSpy).not.toHaveBeenCalled()
454+
expect(startCoordinatorSpy).toHaveBeenCalledWith({
455+
package: '@devup-ui/react',
456+
cssDir: resolve('df', 'devup-ui'),
457+
singleCss: false,
458+
sheetFile: join('df', 'sheet.json'),
459+
classMapFile: join('df', 'classMap.json'),
460+
fileMapFile: join('df', 'fileMap.json'),
461+
importAliases: {
462+
'@emotion/styled': 'styled',
463+
'@vanilla-extract/css': null,
464+
'styled-components': 'styled',
465+
},
466+
coordinatorPortFile: join('df', 'coordinator.port'),
467+
})
449468
})
450469
it('should create theme.d.ts file', async () => {
451470
process.env.TURBOPACK = '1'
@@ -567,8 +586,8 @@ describe('DevupUINextPlugin', () => {
567586
expect(importFileMapSpy).toHaveBeenCalledWith(prevFileMap)
568587
expect(registerThemeSpy).toHaveBeenCalledWith({})
569588

570-
// In non-dev mode, coordinator is not started, so no port file cleanup
571-
expect(unlinkSyncSpy).not.toHaveBeenCalled()
589+
// Verify stale port file was deleted before starting coordinator
590+
expect(unlinkSyncSpy).toHaveBeenCalledWith(join('df', 'coordinator.port'))
572591
})
573592
it('should handle missing state files gracefully on first run', () => {
574593
process.env.TURBOPACK = '1'

packages/next-plugin/src/css-loader.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type { RawLoaderDefinitionFunction } from 'webpack'
1414
export interface DevupUICssLoaderOptions {
1515
// turbo
1616
watch: boolean
17-
coordinatorPortFile?: string | null
17+
coordinatorPortFile?: string
1818
sheetFile: string
1919
classMapFile: string
2020
fileMapFile: string
@@ -28,8 +28,6 @@ export interface DevupUICssLoaderOptions {
2828
let init = false
2929
let cachedPort: number | null = null
3030
const keepAliveAgent = new Agent({ keepAlive: true })
31-
const COORDINATOR_STARTUP_RETRIES = 200
32-
const COORDINATOR_STARTUP_RETRY_DELAY_MS = 50
3331

3432
function readCoordinatorPort(portFile: string): number {
3533
if (cachedPort !== null) return cachedPort
@@ -100,10 +98,7 @@ const devupUICssLoader: RawLoaderDefinitionFunction<DevupUICssLoaderOptions> =
10098
const tryFetch = (retries: number) => {
10199
if (!existsSync(coordinatorPortFile)) {
102100
if (retries > 0) {
103-
setTimeout(
104-
() => tryFetch(retries - 1),
105-
COORDINATOR_STARTUP_RETRY_DELAY_MS,
106-
)
101+
setTimeout(() => tryFetch(retries - 1), 50)
107102
return
108103
}
109104
callback(new Error('Coordinator port file not found'))
@@ -125,7 +120,7 @@ const devupUICssLoader: RawLoaderDefinitionFunction<DevupUICssLoaderOptions> =
125120
callback(error as Error)
126121
}
127122
}
128-
tryFetch(COORDINATOR_STARTUP_RETRIES)
123+
tryFetch(20)
129124
return
130125
}
131126

0 commit comments

Comments
 (0)