1e1cf0bbce
Implements #339. CI ran one check on static/js -- a syntax parse -- so any behavioural regression shipped unnoticed until a user hit it. #335 is the case in point: "Export All Stems" became permanently unclickable after a single export, for every track, until the app restarted. It shipped in alpha 15 and a user found it. Setup is Playwright against the real backend. tests/e2e/serve.sh seeds a throwaway jobs directory with one finished track and execs uvicorn against it, with every data path redirected, so a run cannot read or touch a developer's library. Only the separation pipeline is skipped; the endpoints, the registry and the Range requests for stems are real. Two details in the fixtures are load-bearing, both learned by getting them wrong first: - The sidebar renders from the library store, not /api/jobs. A job on disk but absent from the store is invisible in the UI, and a test that clicks nothing passes for the wrong reason. - stubTauri installs a controllable window.__TAURI__ so the desktop code path runs. This is the point of the exercise: #335 was invisible in a browser, because there the synthetic <a>.click() closes the chip panel before the busy state is applied and the bug hides. The stub also leaves save_audio_file pending until the test settles it, so the busy state machine is driven rather than raced. Nine tests cover all four defects from #335 and #337: rows re-enabled after an export in both host modes, a second export still working, the busy state waiting on the save rather than a timer, failures surfacing and recovering, and export errors not offering a "Try again" that sends the user to the URL import field. Verified by reintroducing each defect and watching the suite fail: clearing only the visible rows on reset fails 3 tests (the panel is closed by then, so a visibility-filtered clear clears nothing), the fixed-timer reset fails 1, and the retry button fails 1. MP4 format switching is only partly covered. The video format is hidden unless the track has one, and a video fixture is its own piece of work, so what is here pins that MP4 is not offered for audio-only tracks. Beat grid and transport coverage remain open on #339. Closes #339
40 lines
1.4 KiB
JavaScript
40 lines
1.4 KiB
JavaScript
import { defineConfig, devices } from "@playwright/test";
|
|
|
|
// The backend is real: these tests exercise the actual endpoints, with only the
|
|
// separation pipeline skipped (tests/e2e/seed.py writes a finished job instead
|
|
// of running demucs to test a menu).
|
|
//
|
|
// serve.sh seeds a throwaway jobs directory and execs uvicorn against it, so a
|
|
// run can never see or touch a developer's real library.
|
|
const PORT = process.env.STEMDECK_E2E_PORT || "8123";
|
|
|
|
export default defineConfig({
|
|
testDir: "tests/e2e",
|
|
testMatch: /.*\.spec\.mjs/,
|
|
// A stuck export used to hang for 15 minutes by design (EXPORT_BUSY_MAX_MS),
|
|
// so a generous per-test timeout would hide exactly the bug these tests exist
|
|
// to catch.
|
|
timeout: 45_000,
|
|
expect: { timeout: 10_000 },
|
|
fullyParallel: false,
|
|
workers: 1,
|
|
forbidOnly: Boolean(process.env.CI),
|
|
retries: process.env.CI ? 1 : 0,
|
|
reporter: process.env.CI ? [["list"], ["github"]] : [["list"]],
|
|
use: {
|
|
baseURL: `http://127.0.0.1:${PORT}`,
|
|
trace: process.env.CI ? "retain-on-failure" : "off",
|
|
screenshot: "only-on-failure",
|
|
video: "off",
|
|
},
|
|
projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }],
|
|
webServer: {
|
|
command: `bash tests/e2e/serve.sh ${PORT}`,
|
|
url: `http://127.0.0.1:${PORT}/api/health`,
|
|
reuseExistingServer: !process.env.CI,
|
|
timeout: 120_000,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
},
|
|
});
|