дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
Merge remote-tracking branch 'origin/main' into fix/agent-chat-transcript
# Conflicts: # src/platform/locales/text/en.json
Цей коміт міститься в:
коміт
021e1165a7
22 files changed
+442
-75
No files matched your search
@@ -0,0 +1,90 @@
|
||||
import { expect, ipcCalls, stubDesktop, test } from "./fixtures";
|
||||
|
||||
test("opens a commit's branch menu and acts in its linked repository", async ({ workbench: page }) => {
|
||||
await stubDesktop(page);
|
||||
await page.evaluate(async () => {
|
||||
const primary = "/dev/acme-api";
|
||||
const linked = "/dev/acme-web";
|
||||
const tip = "1".repeat(40);
|
||||
const h = window.__ipc.handlers;
|
||||
h.vcs_roots = () =>
|
||||
[
|
||||
{ root: primary, head: "main" },
|
||||
{ root: linked, head: "release" },
|
||||
].map((repo) => ({ ...repo, operation: null, headCommit: tip }));
|
||||
h.vcs_branch_info = ({ repo }) => ({
|
||||
head: repo === linked ? "release" : "main",
|
||||
headCommit: tip,
|
||||
upstream: null,
|
||||
ahead: 0,
|
||||
behind: 0,
|
||||
operation: null,
|
||||
});
|
||||
h.vcs_branches = ({ repo }) =>
|
||||
[repo === linked ? "origin/dev" : "origin/other"].map((name) => ({
|
||||
name,
|
||||
commit: tip,
|
||||
remote: true,
|
||||
current: false,
|
||||
upstream: null,
|
||||
ahead: 0,
|
||||
behind: 0,
|
||||
lastCommitMs: 0,
|
||||
}));
|
||||
h.vcs_log = ({ repo }) => {
|
||||
const summary = repo === linked ? "Linked repository commit" : "Primary repository commit";
|
||||
return [
|
||||
{
|
||||
id: tip,
|
||||
shortId: tip.slice(0, 8),
|
||||
parents: [],
|
||||
refs: [repo === linked ? "origin/dev" : "origin/other"],
|
||||
author: "A",
|
||||
email: "[email protected]",
|
||||
timeMs: 0,
|
||||
summary,
|
||||
message: summary,
|
||||
},
|
||||
];
|
||||
};
|
||||
h.vcs_log_refs = () => ({});
|
||||
h.vcs_log_details_batch = ({ revisions }) =>
|
||||
(revisions as string[]).map(() => ({
|
||||
message: "Linked repository commit",
|
||||
containingBranches: [],
|
||||
signature: "N",
|
||||
signer: "",
|
||||
key: "",
|
||||
fingerprint: "",
|
||||
}));
|
||||
h.vcs_commit_files = () => [];
|
||||
h.vcs_config_get = () => null;
|
||||
h.vcs_tags = () => [];
|
||||
h.vcs_status = () => [];
|
||||
h.vcs_create_branch = () => null;
|
||||
const vcsModule = "/src/features/vcs/store.ts";
|
||||
const { useVcs, refreshNow } = await import(/* @vite-ignore */ vcsModule);
|
||||
useVcs.setState({ available: true, root: primary, repo: primary });
|
||||
await refreshNow();
|
||||
const contextModule = "/src/platform/context.ts";
|
||||
const { setContext } = await import(/* @vite-ignore */ contextModule);
|
||||
setContext("vcsAvailable", true);
|
||||
const actionsModule = "/src/platform/actions.ts";
|
||||
const { executeAction } = await import(/* @vite-ignore */ actionsModule);
|
||||
await executeAction("vcs.showLog");
|
||||
});
|
||||
|
||||
await page.getByRole("option", { name: /Linked repository commit/ }).click({ button: "right" });
|
||||
const menu = page.getByRole("menu", { name: "Context menu" });
|
||||
await expect(menu.getByRole("menuitem", { name: "Branch 'origin/other'" })).toHaveCount(0);
|
||||
await menu.getByRole("menuitem", { name: "Branch 'origin/dev'" }).hover();
|
||||
await expect(page.getByRole("menuitem", { name: "Pull into 'release' Using Rebase" })).toBeVisible();
|
||||
const newBranch = page.getByRole("menuitem", { name: "New Branch from 'origin/dev'…" });
|
||||
await newBranch.click();
|
||||
const dialog = page.getByRole("dialog", { name: "Create New Branch from origin/dev" });
|
||||
await dialog.getByRole("textbox", { name: "New branch name:" }).fill("test-branch");
|
||||
await dialog.getByRole("button", { name: "Create", exact: true }).click();
|
||||
await expect
|
||||
.poll(() => ipcCalls(page, "vcs_create_branch"))
|
||||
.toMatchObject([{ repo: "/dev/acme-web", name: "test-branch", start: "origin/dev", checkout: true }]);
|
||||
});
|
||||
@@ -7,30 +7,47 @@ import { expect, ipcCalls, stubDesktop, test } from "./fixtures";
|
||||
|
||||
const ROOT = "/dev/acme-api";
|
||||
|
||||
async function openNewBranchDialog(page: Page) {
|
||||
async function openNewBranchDialog(page: Page, from?: string) {
|
||||
await stubDesktop(page);
|
||||
await page.evaluate(async (root) => {
|
||||
const h = window.__ipc.handlers;
|
||||
h.vcs_roots = () => [{ root, operation: null, head: "main", headCommit: "1111111" }];
|
||||
h.vcs_branch_info = () => ({
|
||||
head: "main",
|
||||
headCommit: "1111111",
|
||||
upstream: null,
|
||||
ahead: 0,
|
||||
behind: 0,
|
||||
operation: null,
|
||||
});
|
||||
h.vcs_status = () => [];
|
||||
h.vcs_create_branch = () => null;
|
||||
const vcsModule = "/src/features/vcs/store.ts";
|
||||
const { useVcs, refreshNow } = await import(/* @vite-ignore */ vcsModule);
|
||||
useVcs.setState({ available: true, root, repo: root, branchesLoaded: false, stashesLoaded: false });
|
||||
await refreshNow();
|
||||
const actionsModule = "/src/platform/actions.ts";
|
||||
const { executeAction } = await import(/* @vite-ignore */ actionsModule);
|
||||
void executeAction("vcs.newBranch");
|
||||
}, ROOT);
|
||||
const dialog = page.getByRole("dialog", { name: "Create New Branch" });
|
||||
await page.evaluate(
|
||||
async ({ root, from }) => {
|
||||
const h = window.__ipc.handlers;
|
||||
h.vcs_roots = () => [{ root, operation: null, head: "main", headCommit: "1111111" }];
|
||||
h.vcs_branch_info = () => ({
|
||||
head: "main",
|
||||
headCommit: "1111111",
|
||||
upstream: null,
|
||||
ahead: 0,
|
||||
behind: 0,
|
||||
operation: null,
|
||||
});
|
||||
h.vcs_status = () => [];
|
||||
h.vcs_branches = () => [
|
||||
{
|
||||
name: "main",
|
||||
current: true,
|
||||
remote: false,
|
||||
upstream: null,
|
||||
ahead: 0,
|
||||
behind: 0,
|
||||
lastCommitMs: null,
|
||||
commit: "1111111",
|
||||
},
|
||||
];
|
||||
h.vcs_create_branch = () => null;
|
||||
const vcsModule = "/src/features/vcs/store.ts";
|
||||
const { useVcs, refreshNow, loadBranches } = await import(/* @vite-ignore */ vcsModule);
|
||||
useVcs.setState({ available: true, root, repo: root, branchesLoaded: false, stashesLoaded: false });
|
||||
await refreshNow();
|
||||
await loadBranches();
|
||||
const actionsModule = "/src/platform/actions.ts";
|
||||
const { executeAction } = await import(/* @vite-ignore */ actionsModule);
|
||||
if (from) void executeAction("vcs.log.newBranch", { id: from, summary: "Selected commit", repo: root });
|
||||
else void executeAction("vcs.newBranch");
|
||||
},
|
||||
{ root: ROOT, from },
|
||||
);
|
||||
const dialog = page.getByRole("dialog", { name: from ? `Create New Branch from ${from}` : "Create New Branch" });
|
||||
const input = dialog.getByRole("textbox", { name: "New branch name:" });
|
||||
await expect(input).toBeVisible();
|
||||
return { dialog, input };
|
||||
@@ -48,6 +65,29 @@ test("a typed space becomes a separator and Create stays enabled", async ({ work
|
||||
expect(call).toMatchObject({ name: "fix-login-redirect" });
|
||||
});
|
||||
|
||||
test("overwrites a local branch only after explicitly opting in", async ({ workbench: page }) => {
|
||||
const from = "2".repeat(40);
|
||||
const { dialog, input } = await openNewBranchDialog(page, from);
|
||||
await input.fill("main");
|
||||
const create = dialog.getByRole("button", { name: "Create", exact: true });
|
||||
await expect(create).toBeDisabled();
|
||||
const overwrite = dialog.getByRole("checkbox", { name: "Overwrite existing branch" });
|
||||
await expect(overwrite).toBeVisible();
|
||||
await expect(overwrite).not.toBeChecked();
|
||||
await overwrite.check();
|
||||
await expect(create).toBeEnabled();
|
||||
await input.fill("new-branch");
|
||||
await expect(overwrite).toHaveCount(0);
|
||||
await input.fill("main");
|
||||
await expect(overwrite).not.toBeChecked();
|
||||
await expect(create).toBeDisabled();
|
||||
await overwrite.check();
|
||||
await create.click();
|
||||
await expect
|
||||
.poll(() => ipcCalls(page, "vcs_create_branch"))
|
||||
.toEqual([{ repo: ROOT, name: "main", start: from, checkout: true, overwrite: true }]);
|
||||
});
|
||||
|
||||
test("a space typed in the middle keeps the caret after it", async ({ workbench: page }) => {
|
||||
const { input } = await openNewBranchDialog(page);
|
||||
await input.fill("ab");
|
||||
|
||||
Reference in new issue
Заблокувати користувача