feat: add contextual help and stabilize repository layout
ForgeFlow quality gate / secret-scan (push) Failing after 28s
ForgeFlow quality gate / quality (push) Failing after 0s

This commit is contained in:
NuklearRabbit
2026-08-27 01:19:36 +02:00
parent d47c7b5e41
commit e882656e85
17 changed files with 660 additions and 82 deletions
+34 -2
View File
@@ -83,7 +83,7 @@ async function assertScrollableWhenOverflowing(page, selector) {
}
test("shell, overview, repositories and settings remain responsive and accessible", async ({ page }, testInfo) => {
await assertSurface(page);
for (const view of ["overview", "deployments", "settings"]) {
for (const view of ["overview", "deployments", "settings", "help"]) {
await page.locator(`.nav-button[data-action="navigate"][data-view="${view}"]`).click();
await expect(page.locator("main")).toBeVisible();
await assertSurface(page);
@@ -116,8 +116,40 @@ test("repository changes, Git tools and Git Validator complete their primary flo
await expect(page.locator(":focus")).toBeVisible();
});
test("repository context, tabs and content never overlap in a compact workspace", async ({ page }) => {
await page.setViewportSize({ width: 1024, height: 768 });
await page.locator('[data-action="select-repo"][data-deployment-count]:not([data-deployment-count="0"])').first().click();
await page.locator('[data-action="repo-tab"][data-tab="gittools"]').click();
const layout = await page.evaluate(() => {
const context = document.querySelector(".repo-context")?.getBoundingClientRect();
const tabs = document.querySelector(".tabs")?.getBoundingClientRect();
const content = document.querySelector(".repo-content")?.getBoundingClientRect();
return {
contextEndsBeforeTabs: Boolean(context && tabs && context.bottom <= tabs.top + 0.5),
tabsEndBeforeContent: Boolean(tabs && content && tabs.bottom <= content.top + 0.5),
horizontalTabFallback: Boolean(tabs && document.querySelector(".tabs").scrollWidth >= document.querySelector(".tabs").clientWidth),
};
});
expect(layout).toEqual({ contextEndsBeforeTabs: true, tabsEndBeforeContent: true, horizontalTabFallback: true });
});
test("Help center is searchable and contextual guidance opens the requested topic", async ({ page }) => {
await page.locator('.nav-button[data-view="help"]').click();
await expect(page.getByRole("heading", { name: "How can we help?" })).toBeVisible();
await expect(page.locator(".help-topic")).toHaveCount(8);
await page.locator("#help-search").fill("deploy key");
await expect(page.locator(".help-topic")).toHaveCount(1);
await expect(page.locator(".help-topic")).toContainText("Repair repository deploy keys");
await page.locator('[data-action="select-repo"]').first().click();
await page.locator('[data-action="repo-tab"][data-tab="gittools"]').click();
await page.locator('[data-action="open-context-help"][data-topic="workspace-sync"]').click();
await expect(page.locator('[data-help-topic="workspace-sync"]')).toHaveAttribute("open", "");
await expect(page.locator('[data-help-topic="workspace-sync"]')).toContainText("Make a local project match Gitea");
await assertSurface(page);
});
test("every long application surface retains a working vertical scroll owner", async ({ page }) => {
for (const view of ["overview", "deployments", "diagnostics", "settings"]) {
for (const view of ["overview", "deployments", "diagnostics", "settings", "help"]) {
await test.step(`${view} view scrolls`, async () => {
const navigation = page.locator(`.nav-button[data-view="${view}"]`);
await navigation.click();