Skip to content

Commit 64f6103

Browse files
refactor: better diagnostics reporting.
1 parent d0d3d4d commit 64f6103

6 files changed

Lines changed: 733 additions & 134 deletions

File tree

docs/next-steps.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ Focused follow-up work for `@knighted/develop`.
2121
5. **In-browser component testing**
2222
- Explore authoring and running component-focused tests in-browser (for example, a Vitest-compatible flow) using CDN-delivered tooling.
2323
- Define a lightweight test UX that supports writing tests, running them on demand, and displaying results in-app.
24+
25+
6. **App runtime modularization**
26+
- Plan a refactor that splits `src/app.js` into scoped modules organized by functionality (for example: diagnostics, render pipeline, editor integration, UI controls, and persistence).
27+
- Preserve `src/app.js` as the main runtime orchestration entrypoint while moving implementation details into focused modules.
28+
- Split stylesheet concerns into focused files (for example: layout/shell, panel controls, diagnostics, editor overrides, dialogs/overlays) while keeping `src/styles.css` as the single entrypoint via ordered `@import` directives.
29+
- Define clear module boundaries and shared interfaces so behavior stays stable while maintainability and readability improve.

playwright/app.spec.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,37 @@ test('transpiles TypeScript annotations in component source', async ({ page }) =
7070
await expect(page.locator('#preview-host button')).toContainText('typed')
7171
})
7272

73-
test('shows error status when component source is cleared', async ({ page }) => {
73+
test('clearing component source reports clear action without error status', async ({
74+
page,
75+
}) => {
7476
await waitForInitialRender(page)
7577

7678
const dialog = page.locator('#clear-confirm-dialog')
7779
await page.getByLabel('Clear component source').click()
7880
await expect(dialog).toHaveAttribute('open', '')
7981
await dialog.getByRole('button', { name: 'Clear' }).click()
8082

83+
await expect(page.locator('#status')).toHaveText('Component cleared')
84+
await expect(page.locator('#status')).toHaveClass(/status--neutral/)
85+
await expect(page.locator('#preview-host pre')).toHaveCount(0)
86+
})
87+
88+
test('jsx syntax errors affect status but not diagnostics toggle severity', async ({
89+
page,
90+
}) => {
91+
await waitForInitialRender(page)
92+
93+
await setComponentEditorSource(
94+
page,
95+
['const App = () => <button', 'const value = 1'].join('\n'),
96+
)
97+
8198
await expect(page.locator('#status')).toHaveText('Error')
82-
await expect(page.locator('#preview-host pre')).toContainText(
83-
'Expected a render() function or a component named App/View.',
99+
await expect(page.locator('#status')).toHaveClass(/status--error/)
100+
await expect(page.locator('#preview-host pre')).toContainText('[jsx]')
101+
await expect(page.locator('#diagnostics-toggle')).toHaveText('Diagnostics')
102+
await expect(page.locator('#diagnostics-toggle')).toHaveClass(
103+
/diagnostics-toggle--neutral/,
84104
)
85105
})
86106

@@ -186,3 +206,37 @@ test('clear styles action opens confirm dialog and clears on confirm', async ({
186206
await expect(cssEditor).toHaveValue('')
187207
await expect(page.locator('#status')).toHaveText('Styles cleared')
188208
})
209+
210+
test('clearing styles keeps diagnostics error state but resets status styling', async ({
211+
page,
212+
}) => {
213+
await waitForInitialRender(page)
214+
215+
await setComponentEditorSource(
216+
page,
217+
["const count: number = 'oops'", 'const App = () => <button>ready</button>'].join(
218+
'\n',
219+
),
220+
)
221+
222+
await page.getByRole('button', { name: 'Typecheck' }).click()
223+
224+
await expect(page.locator('#status')).toHaveText(/Rendered \(Type errors: [1-9]\d*\)/)
225+
await expect(page.locator('#status')).toHaveClass(/status--error/)
226+
await expect(page.locator('#diagnostics-toggle')).toHaveText(/Diagnostics \([1-9]\d*\)/)
227+
await expect(page.locator('#diagnostics-toggle')).toHaveClass(
228+
/diagnostics-toggle--error/,
229+
)
230+
231+
const dialog = page.locator('#clear-confirm-dialog')
232+
await page.getByLabel('Clear styles source').click()
233+
await expect(dialog).toHaveAttribute('open', '')
234+
await dialog.getByRole('button', { name: 'Clear' }).click()
235+
236+
await expect(page.locator('#status')).toHaveText('Styles cleared')
237+
await expect(page.locator('#status')).toHaveClass(/status--neutral/)
238+
await expect(page.locator('#diagnostics-toggle')).toHaveClass(
239+
/diagnostics-toggle--error/,
240+
)
241+
await expect(page.locator('#diagnostics-toggle')).toHaveText(/Diagnostics \([1-9]\d*\)/)
242+
})

0 commit comments

Comments
 (0)