feat(web): add repository defaults to saved GitHub queries (#1758)
* feat(web): add repository defaults to saved GitHub queries * fix(web): commit saved query draft after saving
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { test, expect } from "../../fixtures/test-base";
|
||||
|
||||
const DEFAULT_REPO = "defaultorg/defaultrepo";
|
||||
const DEFAULT_REPO_ISSUE = "Issue in saved default repo";
|
||||
const OTHER_REPO_ISSUE = "Issue outside saved default repo";
|
||||
const SAVED_QUERY_FILTER = "assignee:@me is:open saved-default-repo-e2e";
|
||||
|
||||
function issueRow(testPage: Page, title: string) {
|
||||
return testPage.getByTestId("issue-row").filter({ hasText: title });
|
||||
}
|
||||
|
||||
// The /github dashboard used to render its own w-60 presets rail next to the
|
||||
// global AppSidebar (a redundant "double sidebar"). On desktop that rail is now
|
||||
// a horizontal scope bar; this guards that it drives presets/kind and that the
|
||||
@@ -83,4 +93,93 @@ test.describe("Desktop /github scope bar", () => {
|
||||
"testorg/testrepo",
|
||||
);
|
||||
});
|
||||
|
||||
test("saved query defaults to its chosen repository and persists", async ({
|
||||
testPage,
|
||||
apiClient,
|
||||
}) => {
|
||||
const savedQuery = "Default repo issues";
|
||||
await apiClient.mockGitHubReset();
|
||||
await apiClient.mockGitHubSetUser("test-user");
|
||||
await apiClient.mockGitHubAddIssues([
|
||||
{
|
||||
number: 31,
|
||||
title: DEFAULT_REPO_ISSUE,
|
||||
state: "open",
|
||||
author_login: "test-user",
|
||||
repo_owner: "defaultorg",
|
||||
repo_name: "defaultrepo",
|
||||
assignees: ["test-user"],
|
||||
},
|
||||
{
|
||||
number: 32,
|
||||
title: OTHER_REPO_ISSUE,
|
||||
state: "open",
|
||||
author_login: "test-user",
|
||||
repo_owner: "otherorg",
|
||||
repo_name: "otherrepo",
|
||||
assignees: ["test-user"],
|
||||
},
|
||||
]);
|
||||
|
||||
await testPage.goto("/github");
|
||||
|
||||
const scopeBar = testPage.getByTestId("github-presets-scope-bar");
|
||||
const savedMenu = testPage.getByTestId("github-saved-queries-menu");
|
||||
const repoFilter = testPage.getByTestId("github-repo-filter-trigger");
|
||||
await expect(scopeBar).toBeVisible();
|
||||
await scopeBar.getByRole("button", { name: "Issues", exact: true }).click();
|
||||
const queryInput = testPage.getByPlaceholder(/Custom query/);
|
||||
await queryInput.fill(SAVED_QUERY_FILTER);
|
||||
await queryInput.press("Enter");
|
||||
await expect(testPage.getByTestId("issue-row")).toHaveCount(2, { timeout: 15_000 });
|
||||
|
||||
await savedMenu.click();
|
||||
await testPage.getByRole("menuitem", { name: "Save current query" }).click();
|
||||
const dialog = testPage.getByRole("dialog", { name: "Save query" });
|
||||
await dialog.getByLabel("Name").fill(savedQuery);
|
||||
const saveRepoTrigger = dialog.getByTestId("github-save-query-repo-trigger");
|
||||
await expect(saveRepoTrigger).toBeVisible();
|
||||
await expect
|
||||
.poll(async () => (await saveRepoTrigger.boundingBox())?.height ?? 0)
|
||||
.toBeCloseTo(36, 0);
|
||||
await saveRepoTrigger.click();
|
||||
const saveRepoDropdown = testPage.getByTestId("github-save-query-repo-dropdown");
|
||||
await expect(saveRepoDropdown).toBeVisible();
|
||||
await saveRepoDropdown.getByRole("option", { name: DEFAULT_REPO, exact: true }).click();
|
||||
const saveResponse = testPage.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes("/api/v1/github/workspace-settings") &&
|
||||
response.request().method() === "PUT" &&
|
||||
response.status() === 200,
|
||||
);
|
||||
await dialog.getByRole("button", { name: "Save", exact: true }).click();
|
||||
await saveResponse;
|
||||
|
||||
await expect(repoFilter).toContainText(DEFAULT_REPO);
|
||||
await expect(issueRow(testPage, DEFAULT_REPO_ISSUE)).toBeVisible();
|
||||
await expect(issueRow(testPage, OTHER_REPO_ISSUE)).toHaveCount(0);
|
||||
|
||||
await repoFilter.click();
|
||||
await testPage
|
||||
.getByTestId("github-repo-filter-dropdown")
|
||||
.getByRole("option", { name: "All repos", exact: true })
|
||||
.click();
|
||||
await expect(testPage.getByTestId("issue-row")).toHaveCount(2);
|
||||
|
||||
await savedMenu.click();
|
||||
await testPage.getByRole("menuitem").filter({ hasText: savedQuery }).click();
|
||||
await expect(repoFilter).toContainText(DEFAULT_REPO);
|
||||
await expect(issueRow(testPage, DEFAULT_REPO_ISSUE)).toBeVisible();
|
||||
await expect(issueRow(testPage, OTHER_REPO_ISSUE)).toHaveCount(0);
|
||||
|
||||
await testPage.reload();
|
||||
await expect(scopeBar).toBeVisible();
|
||||
await scopeBar.getByRole("button", { name: "Issues", exact: true }).click();
|
||||
await savedMenu.click();
|
||||
await testPage.getByRole("menuitem").filter({ hasText: savedQuery }).click();
|
||||
await expect(repoFilter).toContainText(DEFAULT_REPO);
|
||||
await expect(issueRow(testPage, DEFAULT_REPO_ISSUE)).toBeVisible();
|
||||
await expect(issueRow(testPage, OTHER_REPO_ISSUE)).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { test, expect } from "../../fixtures/test-base";
|
||||
import { MobileGitHubPage } from "../../pages/mobile-github-page";
|
||||
|
||||
const DEFAULT_REPO = "mobileorg/defaultrepo";
|
||||
const DEFAULT_REPO_ISSUE = "Mobile issue in saved default repo";
|
||||
const OTHER_REPO_ISSUE = "Mobile issue outside saved default repo";
|
||||
const SAVED_QUERY_FILTER = "assignee:@me is:open mobile-saved-default-repo-e2e";
|
||||
|
||||
test.describe("Mobile /github sidebar", () => {
|
||||
test("hamburger opens sheet and selecting a preset updates the toolbar", async ({
|
||||
testPage,
|
||||
@@ -82,4 +87,94 @@ test.describe("Mobile /github sidebar", () => {
|
||||
await testPage.getByRole("option", { name: "testorg/testrepo" }).tap();
|
||||
await expect(page.repoFilterTrigger).toContainText("testorg/testrepo");
|
||||
});
|
||||
|
||||
test("saved query defaults to its chosen repository and persists by touch", async ({
|
||||
testPage,
|
||||
apiClient,
|
||||
}) => {
|
||||
const savedQuery = "Mobile default repo issues";
|
||||
await apiClient.mockGitHubReset();
|
||||
await apiClient.mockGitHubSetUser("test-user");
|
||||
await apiClient.mockGitHubAddIssues([
|
||||
{
|
||||
number: 220,
|
||||
title: DEFAULT_REPO_ISSUE,
|
||||
state: "open",
|
||||
author_login: "test-user",
|
||||
repo_owner: "mobileorg",
|
||||
repo_name: "defaultrepo",
|
||||
assignees: ["test-user"],
|
||||
},
|
||||
{
|
||||
number: 221,
|
||||
title: OTHER_REPO_ISSUE,
|
||||
state: "open",
|
||||
author_login: "test-user",
|
||||
repo_owner: "otherorg",
|
||||
repo_name: "otherrepo",
|
||||
assignees: ["test-user"],
|
||||
},
|
||||
]);
|
||||
|
||||
const page = new MobileGitHubPage(testPage);
|
||||
await page.goto();
|
||||
await page.mobileMenuButton.tap();
|
||||
await page.mobileSidebar.getByRole("button", { name: "Issues", exact: true }).tap();
|
||||
const queryInput = testPage.getByPlaceholder(/Custom query/);
|
||||
await queryInput.fill(SAVED_QUERY_FILTER);
|
||||
await queryInput.press("Enter");
|
||||
await expect(testPage.getByTestId("issue-row")).toHaveCount(2, { timeout: 15_000 });
|
||||
|
||||
await page.mobileMenuButton.tap();
|
||||
await page.mobileSidebar.getByRole("button", { name: "Save current query" }).tap();
|
||||
const dialog = testPage.getByRole("dialog", { name: "Save query" });
|
||||
await dialog.getByLabel("Name").fill(savedQuery);
|
||||
await expect(page.saveQueryRepoTrigger).toBeVisible();
|
||||
await expect
|
||||
.poll(async () => (await page.saveQueryRepoTrigger.boundingBox())?.height ?? 0)
|
||||
.toBeCloseTo(44, 0);
|
||||
await page.saveQueryRepoTrigger.tap();
|
||||
await expect(page.saveQueryRepoDropdown).toBeVisible();
|
||||
await page.saveQueryRepoDropdown.getByRole("option", { name: DEFAULT_REPO, exact: true }).tap();
|
||||
const saveResponse = testPage.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes("/api/v1/github/workspace-settings") &&
|
||||
response.request().method() === "PUT" &&
|
||||
response.status() === 200,
|
||||
);
|
||||
await dialog.getByRole("button", { name: "Save", exact: true }).tap();
|
||||
await saveResponse;
|
||||
|
||||
await expect(page.repoFilterTrigger).toContainText(DEFAULT_REPO);
|
||||
await expect(page.issueRowByTitle(DEFAULT_REPO_ISSUE)).toBeVisible();
|
||||
await expect(page.issueRowByTitle(OTHER_REPO_ISSUE)).toHaveCount(0);
|
||||
|
||||
await page.repoFilterTrigger.tap();
|
||||
await testPage
|
||||
.getByTestId("github-repo-filter-dropdown")
|
||||
.getByRole("option", { name: "All repos", exact: true })
|
||||
.tap();
|
||||
await expect(testPage.getByTestId("issue-row")).toHaveCount(2);
|
||||
|
||||
await page.mobileMenuButton.tap();
|
||||
await page.savedQueryByLabel(savedQuery).tap();
|
||||
await expect(page.repoFilterTrigger).toContainText(DEFAULT_REPO);
|
||||
await expect(page.issueRowByTitle(DEFAULT_REPO_ISSUE)).toBeVisible();
|
||||
await expect(page.issueRowByTitle(OTHER_REPO_ISSUE)).toHaveCount(0);
|
||||
|
||||
await testPage.reload();
|
||||
await page.mobileMenuButton.waitFor({ state: "visible" });
|
||||
await page.mobileMenuButton.tap();
|
||||
await page.mobileSidebar.getByRole("button", { name: "Issues", exact: true }).tap();
|
||||
await page.mobileMenuButton.tap();
|
||||
await page.savedQueryByLabel(savedQuery).tap();
|
||||
await expect(page.repoFilterTrigger).toContainText(DEFAULT_REPO);
|
||||
await expect(page.issueRowByTitle(DEFAULT_REPO_ISSUE)).toBeVisible();
|
||||
await expect(page.issueRowByTitle(OTHER_REPO_ISSUE)).toHaveCount(0);
|
||||
expect(
|
||||
await testPage.evaluate(
|
||||
() => document.documentElement.scrollWidth <= document.documentElement.clientWidth,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user