mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 12:56:01 -06:00
fix(ui): clear stale new-session worktree base (#105331)
This commit is contained in:
committed by
GitHub
parent
cfe88cfd40
commit
83dfb8e78f
@@ -18,6 +18,8 @@ const describeControlUiE2e = chromiumAvailable || !allowMissingChromium ? descri
|
||||
|
||||
const WORKSPACE = "/home/peter/openclaw";
|
||||
const PICKED = "/home/peter/openclaw/packages";
|
||||
const SOURCE_REPO = "/tmp/source-repo";
|
||||
const TARGET_REPO = "/tmp/target-repo";
|
||||
const NODE_HOME = "/Users/peter";
|
||||
const NODE_PICKED = "/Users/peter/Projects";
|
||||
const NODE_UNC = "\\\\server\\share\\repo";
|
||||
@@ -174,6 +176,110 @@ describeControlUiE2e("Control UI new-session page mocked Gateway E2E", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("does not submit a previous repository's worktree base while branches load", async () => {
|
||||
const context = await browser.newContext({
|
||||
locale: "en-US",
|
||||
serviceWorkers: "block",
|
||||
viewport: { height: 900, width: 1280 },
|
||||
});
|
||||
const page = await context.newPage();
|
||||
const gateway = await installMockGateway(page, {
|
||||
workspaceGit: true,
|
||||
methodResponses: {
|
||||
"agents.list": {
|
||||
agents: [
|
||||
{
|
||||
id: "main",
|
||||
identity: { name: "Main" },
|
||||
name: "Main",
|
||||
workspace: SOURCE_REPO,
|
||||
workspaceGit: true,
|
||||
},
|
||||
],
|
||||
defaultId: "main",
|
||||
mainKey: "main",
|
||||
scope: "agent",
|
||||
},
|
||||
"fs.listDir": {
|
||||
cases: [
|
||||
{
|
||||
match: { path: SOURCE_REPO },
|
||||
response: {
|
||||
path: SOURCE_REPO,
|
||||
parent: "/tmp",
|
||||
home: "/home/peter",
|
||||
entries: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"worktrees.branches": {
|
||||
cases: [
|
||||
{
|
||||
match: { repoRoot: SOURCE_REPO },
|
||||
response: {
|
||||
branches: [{ kind: "local", name: "alpha" }],
|
||||
headBranch: "alpha",
|
||||
repoRoot: SOURCE_REPO,
|
||||
},
|
||||
},
|
||||
{
|
||||
match: { repoRoot: TARGET_REPO },
|
||||
response: {
|
||||
branches: [{ kind: "local", name: "main" }],
|
||||
headBranch: "main",
|
||||
repoRoot: TARGET_REPO,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"sessions.create": { key: "agent:main:repo-switch" },
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
await page.goto(`${server.baseUrl}new`);
|
||||
await gateway.waitForRequest("worktrees.branches");
|
||||
|
||||
const whereSelect = page.locator(
|
||||
".new-session-page__select:not(.new-session-page__select--folder)",
|
||||
);
|
||||
await whereSelect.locator("summary").click();
|
||||
await page.getByRole("menuitemradio", { name: "Worktree" }).click();
|
||||
const baseInput = page.getByLabel("Base branch");
|
||||
await expect.poll(() => baseInput.inputValue()).toBe("alpha");
|
||||
const branchRequestsBeforeSwitch = (await gateway.getRequests("worktrees.branches")).length;
|
||||
|
||||
await gateway.deferNext("worktrees.branches");
|
||||
const folderSelect = page.locator(".new-session-page__select--folder");
|
||||
await folderSelect.locator("summary").click();
|
||||
await page
|
||||
.locator(".new-session-page__browser-list")
|
||||
.getByRole("button", { name: "Gateway" })
|
||||
.click();
|
||||
await page.locator("input.new-session-page__browser-path").fill(TARGET_REPO);
|
||||
await page.getByRole("button", { name: "Use this folder" }).click();
|
||||
await expect
|
||||
.poll(async () => (await gateway.getRequests("worktrees.branches")).length)
|
||||
.toBe(branchRequestsBeforeSwitch + 1);
|
||||
|
||||
expect(await baseInput.inputValue()).toBe("");
|
||||
expect(await baseInput.getAttribute("placeholder")).toBe("Loading…");
|
||||
|
||||
await page.locator(".new-session-page__message").fill("use the selected repository");
|
||||
await page.getByRole("button", { name: "Start session" }).click();
|
||||
const create = await gateway.waitForRequest("sessions.create");
|
||||
expect(create.params).toMatchObject({
|
||||
cwd: TARGET_REPO,
|
||||
worktree: true,
|
||||
});
|
||||
expect(create.params).not.toHaveProperty("worktreeBaseRef");
|
||||
await gateway.resolveDeferred("worktrees.branches");
|
||||
} finally {
|
||||
await context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps a rejected first message visible and retryable after reload", async () => {
|
||||
const context = await browser.newContext({
|
||||
locale: "en-US",
|
||||
|
||||
@@ -318,11 +318,13 @@ class NewSessionPage extends OpenClawLightDomElement {
|
||||
}
|
||||
|
||||
private maybeLoadBranches() {
|
||||
// Branch data belongs to one repository selection. Clear it before any
|
||||
// exit or request so a previous repo's ref can never reach sessions.create.
|
||||
const requestId = ++this.branchesRequestToken;
|
||||
this.branches = null;
|
||||
this.branchesLoading = false;
|
||||
this.baseRef = "";
|
||||
if (this.execNode) {
|
||||
this.branchesRequestToken += 1;
|
||||
this.branches = null;
|
||||
this.branchesLoading = false;
|
||||
this.baseRef = "";
|
||||
return;
|
||||
}
|
||||
const repoRoot = this.folder.trim() || this.workspacePath();
|
||||
@@ -336,7 +338,6 @@ class NewSessionPage extends OpenClawLightDomElement {
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
const requestId = ++this.branchesRequestToken;
|
||||
this.branchesLoading = true;
|
||||
void client
|
||||
.request<DraftBranches>("worktrees.branches", { repoRoot })
|
||||
|
||||
Reference in New Issue
Block a user