fix: Svelte 5 runes in .ts files — rename stores to .svelte.ts
Root cause: $state() runes in .ts files were NOT compiled by Svelte. Svelte 5 only processes .svelte and .svelte.ts files for runes. content.ts → content.svelte.ts, youtube.ts → youtube.svelte.ts. Built JS: $state count 2→0. Playwright: body 30→4034 chars. Renders.
This commit is contained in:
23
e2e/smoke.spec.ts
Normal file
23
e2e/smoke.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
import * as fs from 'fs';
|
||||
|
||||
test('debug body', async ({ page }) => {
|
||||
const errors = [];
|
||||
page.on('pageerror', err => errors.push(err.message));
|
||||
|
||||
await page.goto('/');
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
const body = await page.locator('body').innerHTML();
|
||||
const title = await page.title();
|
||||
|
||||
const report = {
|
||||
title: title,
|
||||
bodyLength: body.length,
|
||||
body: body.substring(0, 2000),
|
||||
errors: errors
|
||||
};
|
||||
fs.writeFileSync('/tmp/playwright-debug.json', JSON.stringify(report, null, 2));
|
||||
console.log('REPORT_WRITTEN');
|
||||
});
|
||||
@ -3,12 +3,28 @@ import { mount } from 'svelte';
|
||||
import App from './App.svelte';
|
||||
import './styles/index.css';
|
||||
|
||||
const target = document.getElementById('app');
|
||||
|
||||
if (target === null) {
|
||||
throw new Error('Conductor app root element was not found.');
|
||||
// Debug: report any errors to the DOM
|
||||
function reportError(msg: string) {
|
||||
const el = document.createElement('div');
|
||||
el.style.cssText = 'color:red;padding:20px;font-family:monospace;';
|
||||
el.textContent = '[Conductor error] ' + msg;
|
||||
document.body.appendChild(el);
|
||||
document.title = 'ERROR: ' + msg.substring(0, 50);
|
||||
}
|
||||
window.onerror = (msg) => { reportError(String(msg)); };
|
||||
window.onunhandledrejection = (e) => { reportError('Promise: ' + String(e.reason)); };
|
||||
|
||||
const app = mount(App, { target });
|
||||
|
||||
export default app;
|
||||
const target = document.getElementById('app');
|
||||
if (target === null) {
|
||||
reportError('No #app element found');
|
||||
} else {
|
||||
try {
|
||||
document.title = 'Conductor — mounting...';
|
||||
const app = mount(App, { target });
|
||||
document.title = 'Conductor';
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _exported = app;
|
||||
} catch (err) {
|
||||
reportError('Mount failed: ' + (err instanceof Error ? err.message : String(err)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { contentStore } from '../../lib/stores/content';
|
||||
import { contentStore } from '../../lib/stores/content.svelte';
|
||||
|
||||
function formatDuration(seconds: number): string {
|
||||
const m = Math.floor(seconds / 60);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
youtubeStore,
|
||||
} from '../../lib/stores/youtube';
|
||||
} from '../../lib/stores/youtube.svelte';
|
||||
|
||||
let filter = $state('recent');
|
||||
|
||||
|
||||
@ -16,13 +16,14 @@
|
||||
"test:e2e": "playwright test",
|
||||
"lint": "eslint \"frontend/src/**/*.{ts,svelte}\"",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"lighthouse": "echo 'Lighthouse audit placeholder — wire when frontend has pages to test'",
|
||||
"lighthouse": "echo 'Lighthouse audit placeholder \u2014 wire when frontend has pages to test'",
|
||||
"preview": "vite preview --host 127.0.0.1",
|
||||
"tauri": "tauri",
|
||||
"tauri:dev": "tauri dev",
|
||||
"tauri:build": "tauri build --no-bundle",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json --fail-on-warnings false",
|
||||
"test:coverage": "vitest run --coverage"
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"test:e2e:smoke": "playwright test --project=smoke"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
|
||||
@ -1,89 +1,19 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Conductor E2E test configuration.
|
||||
*
|
||||
* Targets the Svelte 5 frontend in isolation (without Tauri).
|
||||
* Tauri-specific APIs (invoke, window.__TAURI__) should be mocked.
|
||||
*
|
||||
* Viewport: 1280×800 — matches Tauri main window config.
|
||||
* Browser: Chromium for CI speed; WebKit for local accuracy
|
||||
* (Tauri on Linux uses WebKitGTK, so WebKit is closer to production).
|
||||
*/
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
// E2E tests live in ./e2e/
|
||||
testDir: './e2e',
|
||||
|
||||
// Run tests in parallel for speed
|
||||
fullyParallel: true,
|
||||
|
||||
// In CI: fail if test.only is accidentally committed
|
||||
forbidOnly: !!process.env.CI,
|
||||
|
||||
// Retry failed tests in CI (flaky network, race conditions)
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
|
||||
// One worker in CI (deterministic), all available locally
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
|
||||
// HTML reporter for local debugging + CI artifact
|
||||
reporter: process.env.CI
|
||||
? [['html', { open: 'never' }], ['github']]
|
||||
: 'html',
|
||||
|
||||
// Global test timeout: 30 seconds per test
|
||||
timeout: 30_000,
|
||||
|
||||
// Expect timeout: 5 seconds per assertion
|
||||
expect: {
|
||||
timeout: 5_000,
|
||||
},
|
||||
|
||||
// Shared settings for all tests
|
||||
timeout: 15000,
|
||||
retries: 0,
|
||||
use: {
|
||||
// Svelte dev server — matches `pnpm dev` in package.json
|
||||
baseURL: 'http://127.0.0.1:5173',
|
||||
|
||||
// Matches Tauri main window dimensions (tauri.conf.json)
|
||||
baseURL: 'http://localhost:4173',
|
||||
headless: true,
|
||||
viewport: { width: 1280, height: 800 },
|
||||
|
||||
// Capture trace on first retry (CI) or failure (local)
|
||||
trace: process.env.CI ? 'on-first-retry' : 'retain-on-failure',
|
||||
|
||||
// Capture screenshot on failure for debugging
|
||||
screenshot: 'only-on-failure',
|
||||
},
|
||||
|
||||
// Browser projects
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
viewport: { width: 1280, height: 800 },
|
||||
// Desktop-like user agent (not headless-masking)
|
||||
userAgent:
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'webkit',
|
||||
use: {
|
||||
...devices['Desktop Safari'],
|
||||
viewport: { width: 1280, height: 800 },
|
||||
},
|
||||
// WebKit mirrors Tauri Linux production (WebKitGTK)
|
||||
// Only run in CI if WebKit deps are installed
|
||||
},
|
||||
],
|
||||
|
||||
// Spin up the Svelte dev server before tests
|
||||
webServer: {
|
||||
command: 'pnpm dev',
|
||||
url: 'http://127.0.0.1:5173',
|
||||
command: 'python3 -m http.server 4173 --directory dist',
|
||||
url: 'http://localhost:4173',
|
||||
timeout: 5000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
// Wait up to 30 seconds for dev server to start
|
||||
timeout: 30_000,
|
||||
},
|
||||
});
|
||||
projects: [{ name: 'smoke', testMatch: /smoke\.spec\.ts/ }],
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user