Files
buzz/desktop/tests/e2e/project-commit-detail.spec.ts

174 lines
6.1 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { waitForAnimations } from "../helpers/animations";
import { installMockBridge } from "../helpers/bridge";
const SHOTS = "test-results/project-commit-detail";
// The projects surface is a preview feature — opt in before the app mounts.
// Must run before installMockBridge so React reads the override on mount.
async function enableProjectsFeature(page: import("@playwright/test").Page) {
await page.addInitScript(() => {
window.localStorage.setItem(
"buzz-feature-overrides-v1",
JSON.stringify({ projects: true }),
);
});
}
test("commit detail opens from the commits feed with a diff", async ({
page,
}) => {
await enableProjectsFeature(page);
await installMockBridge(page);
// The preview server is a static file server without SPA fallback, so
// enter at "/" and navigate via the sidebar.
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.getByTestId("open-projects-view").click();
// The overview no longer lists repository cards — switch to the
// Repositories filter to reveal the project cards/rows.
await page.getByRole("button", { name: "Repositories", exact: true }).click();
// Open the first mock project (dtag "buzz" from the e2e bridge fixture).
const projectEntry = page
.locator(
'[data-testid="project-card-buzz"], [data-testid="project-row-buzz"]',
)
.first();
await expect(projectEntry).toBeVisible({ timeout: 10_000 });
await projectEntry.click();
await page.getByRole("tab", { name: "Commits" }).click();
const commitRows = page.getByTestId("project-activity-feed-item");
await expect(commitRows.first()).toBeVisible({ timeout: 10_000 });
// GitHub-style feed: commits grouped under a date header with a hash cell.
await expect(page.getByText(/^Commits on /).first()).toBeVisible();
await waitForAnimations(page);
await page.screenshot({
fullPage: false,
path: `${SHOTS}/02-commits-feed.png`,
});
// Open the newest commit via its subject button.
await commitRows
.first()
.getByRole("button", { name: /Add Trello board workflow details/ })
.click();
// Detail header: author line, subject, and hash.
await expect(page.getByText("Commit from")).toBeVisible();
await expect(
page.getByRole("heading", { name: "Add Trello board workflow details" }),
).toBeVisible();
await expect(
page.getByRole("button", { name: "Copy commit hash" }),
).toBeVisible();
// Diff from the mocked get_project_repo_diff renders changed files.
await expect(page.getByText("2 changed files")).toBeVisible({
timeout: 10_000,
});
await expect(
page.getByText("CommunityTabs({ selectedCommitHash })"),
).toBeVisible();
await waitForAnimations(page);
await page.screenshot({
fullPage: false,
path: `${SHOTS}/01-commit-detail.png`,
});
// Breadcrumb category segment steps back to the commits feed.
await page
.getByRole("navigation", { name: "Project breadcrumb" })
.getByRole("button", { name: "Commits", exact: true })
.click();
await expect(commitRows.first()).toBeVisible();
// The commits feed itself gets a grayed sub-tab crumb.
await expect(
page.getByRole("navigation", { name: "Project breadcrumb" }),
).toContainText("Commits");
// The project-name segment goes to the project home (Overview tab).
await commitRows
.first()
.getByRole("button", { name: /Add Trello board workflow details/ })
.click();
await expect(page.getByText("Commit from")).toBeVisible();
await page
.getByRole("navigation", { name: "Project breadcrumb" })
.getByRole("button", { name: "buzz", exact: true })
.click();
await expect(page.getByRole("tab", { name: "Overview" })).toHaveAttribute(
"aria-selected",
"true",
);
// The Projects root segment leaves the project entirely.
await page
.getByRole("navigation", { name: "Project breadcrumb" })
.getByRole("button", { name: "Projects", exact: true })
.click();
await expect(projectEntry).toBeVisible();
});
test("pull request and issue feeds share the commit row structure", async ({
page,
}) => {
await enableProjectsFeature(page);
await installMockBridge(page);
await page.goto("/", { waitUntil: "domcontentloaded" });
await page.getByTestId("open-projects-view").click();
// The overview no longer lists repository cards — switch to the
// Repositories filter to reveal the project cards/rows.
await page.getByRole("button", { name: "Repositories", exact: true }).click();
const projectEntry = page
.locator(
'[data-testid="project-card-buzz"], [data-testid="project-row-buzz"]',
)
.first();
await expect(projectEntry).toBeVisible({ timeout: 10_000 });
await projectEntry.click();
// PR rows use the shared feed row: title button + #id cluster cell.
await page.getByRole("tab", { name: "PRs" }).click();
const prRows = page.getByTestId("project-pull-request-row");
await expect(prRows.first()).toBeVisible({ timeout: 10_000 });
await expect(
prRows.first().getByRole("button", { name: /^#/ }),
).toBeVisible();
await waitForAnimations(page);
await page.screenshot({ fullPage: false, path: `${SHOTS}/03-prs-feed.png` });
// The #id cell opens the PR detail, same as clicking the title.
await prRows.first().getByRole("button", { name: /^#/ }).click();
await expect(
page.getByRole("navigation", { name: "Project breadcrumb" }),
).toContainText("PRs");
// Step back to the feed so the community tabs are available again.
await page
.getByRole("navigation", { name: "Project breadcrumb" })
.getByRole("button", { name: "PRs", exact: true })
.click();
await expect(prRows.first()).toBeVisible();
// Issue rows share the same structure.
await page.getByRole("tab", { name: "Issues" }).click();
const issueRows = page.getByTestId("project-issue-row");
await expect(issueRows.first()).toBeVisible({ timeout: 10_000 });
await expect(
issueRows.first().getByRole("button", { name: /^#/ }),
).toBeVisible();
await waitForAnimations(page);
await page.screenshot({
fullPage: false,
path: `${SHOTS}/04-issues-feed.png`,
});
});