test: a list key waits for the list's registration, not only its rows
gate / frontend (push) Successful in 6m5s
gate / backend (push) Successful in 7m10s
gate / frontend (push) Successful in 6m5s
gate / backend (push) Successful in 7m10s
The server gate's frontend job went red on 0.96.0: PlexPlaylistView's j/Delete test pressed j after the rows painted but before useListNav's passive effect registered the list, so the key did nothing on the slower runner. Every test that presses a list key after an async load now waits for [data-nav-list] on its list first (PlexPlaylistView, Playlists, Home, PlexDiscover). Checked against a 30 ms delayed registration: the old tests fail, the new ones pass.
This commit is contained in:
@@ -96,6 +96,10 @@ const toast = () =>
|
||||
.map((c) => c[0] as { message: string; action?: { label: string; onClick: () => void } })
|
||||
.filter((n) => n.message?.startsWith("plex.playlist.removedToast"))
|
||||
.pop();
|
||||
// The list's keys are live once its effect has registered it (`data-nav-list`), a passive effect that
|
||||
// can run AFTER the rows are on screen: a key pressed on a slow machine in between did nothing (CI flake).
|
||||
const keysLiveOn = (el: Element) =>
|
||||
waitFor(() => expect(el.closest("[data-nav-list]")).not.toBeNull());
|
||||
const pressKey = (key: string) =>
|
||||
act(() => {
|
||||
(document.activeElement ?? document.body).dispatchEvent(
|
||||
@@ -254,7 +258,7 @@ describe("PlexPlaylistView · reordering without a drag (WCAG 2.5.7)", () => {
|
||||
describe("PlexPlaylistView · the keyboard", () => {
|
||||
it("walks the rows with j and takes out the walked one on Delete", async () => {
|
||||
mount([movie("1"), movie("2"), movie("3")]);
|
||||
await screen.findByText("Movie 3");
|
||||
await keysLiveOn(await screen.findByText("Movie 3"));
|
||||
vi.spyOn(api, "plexPlaylistRemoveItem").mockResolvedValue({} as never);
|
||||
pressKey("j");
|
||||
pressKey("j");
|
||||
@@ -268,7 +272,7 @@ describe("PlexPlaylistView · the keyboard", () => {
|
||||
it("walks an open show's episodes after its header, and Delete on the header takes the show", async () => {
|
||||
mount([ep("e1", 1, 1), ep("e2", 1, 2), movie("9")]);
|
||||
fireEvent.click(await screen.findByText("The Show"));
|
||||
await screen.findByText("Ep e2");
|
||||
await keysLiveOn(await screen.findByText("Ep e2"));
|
||||
pressKey("j");
|
||||
expect(document.activeElement).toBe(rowOf("The Show"));
|
||||
pressKey("j");
|
||||
|
||||
Reference in New Issue
Block a user