mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-04 23:44:41 +00:00
* fix(app): show current contents of collapsed folders after Files refresh Refresh only re-listed expanded folders, and expanding a folder skips the request when a listing is cached, so a folder collapsed during Refresh kept showing its old contents. Drop the cached listings Refresh does not re-list. The refresh helper moves to file-explorer/tree.ts so it can be tested. * test(app): cover refreshing collapsed folders through the browser Exercise the reported file creation, refresh and reopen sequence through a real daemon, then check refresh while expanded. Co-authored-by: hadan8977 <zc-huang23@mails.tsinghua.edu.cn> * fix(app): ignore directory replies invalidated by Refresh A directory request started before Refresh could finish afterwards and restore a stale collapsed listing. Track the refresh generation in explorer state and accept completion only from the current generation. Keep directory loading and invalidation in the file-explorer model. * fix(app): preserve expansion when Refresh cancels restoration Keep an invalidated directory operation distinct from a failed listing. Propagate cancellation through saved-folder restoration so it preserves the current expansion state instead of committing an incomplete restored path set. --------- Co-authored-by: hadan8977 <zc-huang23@mails.tsinghua.edu.cn> Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
118 lines
3.8 KiB
TypeScript
118 lines
3.8 KiB
TypeScript
import { writeFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { expect, test } from "../support/fixtures";
|
|
import {
|
|
collapseFolder,
|
|
expandFolder,
|
|
expectExplorerEntryHidden,
|
|
expectExplorerEntryVisible,
|
|
expectFileTabOpen,
|
|
openFileExplorer,
|
|
openFileFromExplorer,
|
|
} from "../support/helpers/file-explorer";
|
|
import { delayDirectoryListingResponse } from "../support/helpers/directory-listing-gate";
|
|
import { gotoWorkspace } from "../support/helpers/launcher";
|
|
import { seedWorkspace, type SeededWorkspace } from "../support/helpers/seed-client";
|
|
|
|
let workspace: SeededWorkspace;
|
|
|
|
test.beforeAll(async () => {
|
|
workspace = await seedWorkspace({
|
|
repoPrefix: "file-explorer-collapse-",
|
|
repo: {
|
|
files: [
|
|
{ path: "assets/logo.png", content: "image bytes for explorer e2e\n" },
|
|
{ path: "docs/guide.md", content: "# Guide\n" },
|
|
],
|
|
},
|
|
});
|
|
});
|
|
|
|
test.afterAll(async () => {
|
|
await workspace?.cleanup();
|
|
});
|
|
|
|
test.describe("File explorer collapse", () => {
|
|
test("collapses an opened image file parent folder and still expands other folders", async ({
|
|
page,
|
|
}) => {
|
|
await gotoWorkspace(page, workspace.workspaceId);
|
|
await openFileExplorer(page);
|
|
|
|
await expandFolder(page, "assets");
|
|
await expectExplorerEntryVisible(page, "logo.png");
|
|
|
|
await openFileFromExplorer(page, "logo.png");
|
|
await expectFileTabOpen(page, "assets/logo.png");
|
|
|
|
await collapseFolder(page, "assets");
|
|
await expectExplorerEntryHidden(page, "logo.png");
|
|
|
|
await expandFolder(page, "docs");
|
|
await expectExplorerEntryVisible(page, "guide.md");
|
|
});
|
|
});
|
|
|
|
test("Files Refresh reveals new files when a cached collapsed folder is reopened", async ({
|
|
page,
|
|
}) => {
|
|
await gotoWorkspace(page, workspace.workspaceId);
|
|
await openFileExplorer(page);
|
|
await expandFolder(page, "docs");
|
|
await expectExplorerEntryVisible(page, "guide.md");
|
|
await collapseFolder(page, "docs");
|
|
await expectExplorerEntryHidden(page, "guide.md");
|
|
await createFileOutsidePaseo("docs/NEW.md");
|
|
await refreshFiles(page);
|
|
await expandFolder(page, "docs");
|
|
await expectExplorerEntryVisible(page, "guide.md");
|
|
await expectExplorerEntryVisible(page, "NEW.md");
|
|
|
|
await createFileOutsidePaseo("docs/NEXT.md");
|
|
await refreshFiles(page);
|
|
await expectExplorerEntryVisible(page, "NEXT.md");
|
|
});
|
|
|
|
async function refreshFiles(page: import("@playwright/test").Page): Promise<void> {
|
|
const refresh = page.getByRole("button", { name: "Refresh files", exact: true });
|
|
await refresh.click();
|
|
await expect(refresh).toBeEnabled();
|
|
}
|
|
|
|
async function createFileOutsidePaseo(filePath: string): Promise<void> {
|
|
await writeFile(path.join(workspace.repoPath, filePath), "# New output\n");
|
|
}
|
|
|
|
test("Files Refresh ignores an old reply for a folder collapsed while loading", async ({
|
|
page,
|
|
}) => {
|
|
const reply = await delayDirectoryListingResponse(page, "docs");
|
|
await gotoWorkspace(page, workspace.workspaceId);
|
|
await openFileExplorer(page);
|
|
await expandFolder(page, "docs");
|
|
await reply.waitUntilHeld();
|
|
await collapseFolder(page, "docs");
|
|
await createFileOutsidePaseo("docs/DELAYED.md");
|
|
await refreshFiles(page);
|
|
await reply.release();
|
|
await expandFolder(page, "docs");
|
|
await expectExplorerEntryVisible(page, "DELAYED.md");
|
|
});
|
|
|
|
test("Files Refresh preserves expanded folders while their saved view is restoring", async ({
|
|
page,
|
|
}) => {
|
|
await gotoWorkspace(page, workspace.workspaceId);
|
|
await openFileExplorer(page);
|
|
await expandFolder(page, "docs");
|
|
await expectExplorerEntryVisible(page, "guide.md");
|
|
const reply = await delayDirectoryListingResponse(page, "docs");
|
|
await page.reload();
|
|
await openFileExplorer(page);
|
|
await reply.waitUntilHeld();
|
|
await refreshFiles(page);
|
|
await expectExplorerEntryVisible(page, "guide.md");
|
|
await reply.release();
|
|
await expectExplorerEntryVisible(page, "guide.md");
|
|
});
|