test(e2e): freeze the four reproductions this work started from
Each was written first and watched fail first: - `view-lifecycle` — pressing `s` on Settings must not skip an album out of the Autotag queue, and on Autotag the same key must not also toggle shuffle. - `player-truth` — the elapsed clock tracks the backend through steady playback and four keyboard seeks (the measurement that failed by 30 s), a finished queue keeps the track on the bar at 0:00, and auto-advance skips a missing file and reaches the next track. - `offline-icons` — blocks every non-local request and asserts on the <svg> *inside* each icon's shadow root, since asserting the element exists would have passed before the fix too. Verified red: 24 empty icons. - `failure-voice` — induces a real binding failure through /__test/sql and asserts a sentence appears. Its first version renamed the decoy library to its own name, which the backend accepts: it failed at the right assertion while never inducing the failure, so it now picks the row by the seeded library's name from /__test/health. - `play-count` — a finished track does not refetch the library. The queue spec now opens the panel before asserting on its rows and waits for it to close again: the panel's width is animated and the transport slides with it, so a click issued during the close lands on whichever button moved under the pointer.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { test, expect } from '../support/fixtures.js';
|
||||
|
||||
/**
|
||||
* Plan 007 phase 3: a failure the user caused has to reach the user.
|
||||
*
|
||||
* The failure is induced through `/__test/sql` rather than staged in the
|
||||
* UI: a second library called "Decoy" makes `RenameLibrary` reject with
|
||||
* its duplicate-name error, which is a real binding rejection on a path
|
||||
* the audit found ends at `console.error` (errors.m5).
|
||||
*/
|
||||
test.describe('a failed binding says so', () => {
|
||||
const DECOY = 'Decoy';
|
||||
|
||||
test.afterEach(async ({ testctl }) => {
|
||||
await testctl.sql('DELETE FROM libraries WHERE name = ?', [DECOY]);
|
||||
});
|
||||
|
||||
test('a rejected rename reaches the user, not the console', async ({
|
||||
app,
|
||||
testctl,
|
||||
}) => {
|
||||
// The library that was seeded by running the app, i.e. the one row
|
||||
// that is not the decoy.
|
||||
const health = await testctl.health();
|
||||
const seeded = health.libraries[0].name as string;
|
||||
|
||||
await testctl.sql(
|
||||
'INSERT INTO libraries (name, path) VALUES (?, ?)',
|
||||
[DECOY, '/tmp/yj-decoy-library'],
|
||||
);
|
||||
|
||||
await app.getByTestId('nav-settings').click();
|
||||
|
||||
const page = app.locator('config-page');
|
||||
|
||||
// Config sections start collapsed.
|
||||
await page
|
||||
.locator('config-section[heading="Libraries"]')
|
||||
.locator('.header')
|
||||
.click();
|
||||
|
||||
// Renaming the decoy to its own name is a no-op the backend
|
||||
// accepts, so the rename has to happen on the other row.
|
||||
const row = page.locator('.library-row').filter({ hasText: seeded });
|
||||
|
||||
// Through the overflow menu, not by clicking the name: the name's
|
||||
// own click bubbles to config-page's document handler, which closes
|
||||
// the editor it just opened.
|
||||
await expect(row).toBeVisible();
|
||||
await row.locator('.overflow-btn').click();
|
||||
await row.getByText('Rename', { exact: true }).click();
|
||||
|
||||
const input = row.locator('.edit-input');
|
||||
|
||||
await input.fill(DECOY);
|
||||
await input.press('Enter');
|
||||
|
||||
// The message is the assertion: a name it can act on, and none of
|
||||
// the Go error's wrapping.
|
||||
const notice = app.getByTestId('notification').first();
|
||||
|
||||
await expect(notice).toBeVisible();
|
||||
await expect(notice).toContainText(DECOY);
|
||||
await expect(notice).not.toContainText('could not rename library:');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user