Files
kandev/apps/web/e2e/tests/github/mobile-github-results.spec.ts
T
2026-09-12 10:06:05 +02:00

179 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from "../../fixtures/test-base";
import { MobileGitHubPage } from "../../pages/mobile-github-page";
import { waitForFiniteAnimations } from "../../helpers/animations";
// @covers AC-INTEGRATIONS-GITHUB-MOBILE-001.3
// @covers AC-INTEGRATIONS-GITHUB-MOBILE-001.4
// @covers AC-INTEGRATIONS-GITHUB-MOBILE-001.5
test("phone results wrap long content, expose touch actions, and support every capped page", async ({
testPage,
apiClient,
}) => {
await apiClient.mockGitHubReset();
await apiClient.mockGitHubSetUser("test-user");
await apiClient.mockGitHubAddPRs(
Array.from({ length: 1050 }, (_, index) => ({
number: index + 1,
title: `Result ${index + 1}: A long pull request title that remains readable on a narrow phone screen`,
state: "open",
head_branch: `feature/${index}`,
base_branch: "main",
author_login: "test-user",
repo_owner: "a-long-organization-name",
repo_name: "a-very-long-repository-name-without-any-spaces",
})),
);
// The mock provider returns every seeded PR; model GitHub's bounded page response.
let resultTotal = 1050;
await testPage.route("**/api/v1/github/user/prs?**", async (route) => {
const response = await route.fetch();
const data = await response.json();
const params = new URL(route.request().url()).searchParams;
const page = Number(params.get("page") ?? 1);
const pageSize = Number(params.get("per_page") ?? 25);
await route.fulfill({
response,
json: {
...data,
total_count: resultTotal,
prs: data.prs.slice(0, resultTotal).slice((page - 1) * pageSize, page * pageSize),
},
});
});
await testPage.setViewportSize({ width: 320, height: 640 });
const github = new MobileGitHubPage(testPage);
await github.goto();
const query = testPage.getByPlaceholder(/Custom query/);
await query.fill("is:open");
await query.press("Enter");
await expect(testPage.getByTestId("pr-row")).toHaveCount(25);
const chooser = testPage.locator(
'button[aria-label="Choose results page"],select[aria-label="Choose results page"]',
);
await expect(chooser).toBeVisible();
expect(await chooser.evaluate((element) => element.tagName)).toBe("BUTTON");
expect((await chooser.boundingBox())!.height).toBeGreaterThanOrEqual(44);
await expect(testPage.getByRole("button", { name: "Previous page", exact: true })).toBeDisabled();
const firstRow = testPage.getByTestId("pr-row").first();
await expect(firstRow).toBeVisible();
expect(await firstRow.evaluate((element) => element.scrollWidth <= element.clientWidth)).toBe(
true,
);
const taskAction = firstRow.getByTestId("pr-start-task-trigger");
expect((await taskAction.boundingBox())!.height).toBeGreaterThanOrEqual(44);
await taskAction.tap();
await expect(testPage.getByTestId("pr-start-task-preset").first()).toBeVisible();
expect(
(await testPage.getByTestId("pr-start-task-preset").first().boundingBox())!.height,
).toBeGreaterThanOrEqual(44);
await testPage.keyboard.press("Escape");
await chooser.tap();
const pages = testPage.getByRole("dialog", { name: "Choose results page", exact: true });
await expect(pages).toBeVisible();
await waitForFiniteAnimations(pages);
await expect(pages.getByRole("button", { name: /^Page \d+ of 40$/ })).toHaveCount(40);
const pageFive = pages.getByRole("button", { name: "Page 5 of 40", exact: true });
expect((await pageFive.boundingBox())!.height).toBeGreaterThanOrEqual(44);
await pageFive.tap();
await expect(pages).toBeHidden();
await expect(chooser).toBeFocused();
await expect(testPage.getByText("101–125 of 1000+", { exact: true })).toBeVisible();
await chooser.tap();
const lastPage = pages.getByRole("button", { name: "Page 40 of 40", exact: true });
await lastPage.scrollIntoViewIfNeeded();
await lastPage.tap();
await expect(testPage.getByText("976–1000 of 1000+", { exact: true })).toBeVisible();
await chooser.tap();
await expect(lastPage).toBeInViewport();
await expect(lastPage).toHaveAttribute("aria-current", "page");
await testPage.keyboard.press("Escape");
await expect(pages).toBeHidden();
await expect(chooser).toBeFocused();
await expect(testPage.getByRole("button", { name: "Next page", exact: true })).toBeDisabled();
resultTotal = 50;
await testPage.getByRole("button", { name: "Refresh", exact: true }).tap();
await expect(chooser).toContainText("Page 40 of 2");
await chooser.tap();
await expect(pages.getByRole("button", { name: "Done", exact: true })).toBeFocused();
await pages.getByRole("button", { name: "Page 2 of 2", exact: true }).tap();
await expect(testPage.getByText("26–50 of 50", { exact: true })).toBeVisible();
await expect(chooser).toBeFocused();
expect(
await testPage.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth),
).toBe(true);
await testPage.setViewportSize({ width: 767, height: 640 });
await expect(chooser).toBeVisible();
await testPage.setViewportSize({ width: 768, height: 640 });
await expect(chooser).toBeHidden();
await expect(github.inlineSidebar).toBeVisible();
});
// @covers AC-INTEGRATIONS-GITHUB-MOBILE-001.2
// @covers AC-INTEGRATIONS-GITHUB-MOBILE-001.5
test("long view names do not compress result counts and refresh metadata", async ({
testPage,
apiClient,
seedData,
}) => {
await apiClient.mockGitHubReset();
await apiClient.mockGitHubSetUser("test-user");
await apiClient.mockGitHubAddPRs([
{
number: 1,
title: "Harbor dashboard",
state: "open",
head_branch: "feature/mobile",
base_branch: "main",
author_login: "test-user",
repo_owner: "harbor",
repo_name: "web",
},
]);
const settings = await apiClient.rawRequest(
"GET",
`/api/v1/github/workspace-settings?workspace_id=${seedData.workspaceId}`,
);
const baseline = await settings.json();
const saved = await apiClient.rawRequest("PUT", "/api/v1/github/workspace-settings", {
workspace_id: seedData.workspaceId,
saved_presets: [
{
id: "long-toolbar-view",
kind: "pr",
label: "Harbor navigation improvements ready for mobile review",
customQuery: "is:open",
repoFilter: "",
createdAt: "2026-09-11T00:00:00Z",
isDefault: true,
},
],
});
expect(saved.ok).toBe(true);
try {
await testPage.setViewportSize({ width: 320, height: 640 });
const github = new MobileGitHubPage(testPage);
await github.goto();
await expect(testPage.getByTestId("pr-row")).toBeVisible();
const refresh = testPage.getByRole("button", { name: "Refresh", exact: true });
const viewBounds = (await github.mobileMenuButton.boundingBox())!;
const refreshBounds = (await refresh.boundingBox())!;
expect(refreshBounds.y).toBeGreaterThanOrEqual(viewBounds.y + viewBounds.height);
expect(viewBounds.height).toBeLessThanOrEqual(48);
await expect(testPage.getByTestId("integration-mobile-result-count")).toHaveText("Result 1");
expect(
await testPage.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth),
).toBe(true);
await testPage.setViewportSize({ width: 767, height: 640 });
await expect(testPage.getByTestId("integration-mobile-result-count")).toBeVisible();
await testPage.setViewportSize({ width: 768, height: 640 });
await expect(testPage.getByTestId("integration-mobile-result-count")).toBeHidden();
await expect(github.inlineSidebar).toBeVisible();
} finally {
const restored = await apiClient.rawRequest("PUT", "/api/v1/github/workspace-settings", {
workspace_id: seedData.workspaceId,
saved_presets: baseline.saved_presets ?? [],
});
expect(restored.ok).toBe(true);
}
});