164 lines
6.1 KiB
TypeScript
164 lines
6.1 KiB
TypeScript
import { test, expect } from "../../fixtures/test-base";
|
|
import { KanbanPage } from "../../pages/kanban-page";
|
|
|
|
test.describe("Branch selector behavior with executor types", () => {
|
|
test.describe.configure({ retries: 1 });
|
|
|
|
test("branch selector is disabled for local executor with local repo", async ({
|
|
testPage,
|
|
apiClient,
|
|
}) => {
|
|
// Find the system "local" executor and create a profile on it
|
|
const { executors } = await apiClient.listExecutors();
|
|
const localExec = executors.find((e) => e.type === "local");
|
|
if (!localExec) {
|
|
test.skip(true, "No local executor available");
|
|
return;
|
|
}
|
|
const profile = await apiClient.createExecutorProfile(localExec.id, "E2E Local Profile");
|
|
|
|
try {
|
|
const kanban = new KanbanPage(testPage);
|
|
await kanban.goto();
|
|
|
|
await kanban.createTaskButton.first().click();
|
|
const dialog = testPage.getByTestId("create-task-dialog");
|
|
await expect(dialog).toBeVisible();
|
|
|
|
// Fill title + description
|
|
await testPage.getByTestId("task-title-input").fill("Branch Selector Test");
|
|
await testPage.getByTestId("task-description-input").fill("testing branch selector disable");
|
|
|
|
// Select the local executor profile
|
|
const executorSelector = testPage.getByTestId("executor-profile-selector");
|
|
await executorSelector.click();
|
|
await testPage.getByRole("option", { name: /E2E Local Profile/i }).click();
|
|
|
|
// Branch selector should be disabled when local executor is selected
|
|
const branchSelector = testPage.getByTestId("branch-selector");
|
|
await expect(branchSelector).toBeDisabled({ timeout: 5_000 });
|
|
} finally {
|
|
await apiClient.deleteExecutorProfile(profile.id).catch(() => {});
|
|
}
|
|
});
|
|
|
|
test("branch selector re-enables when switching from local to worktree executor", async ({
|
|
testPage,
|
|
apiClient,
|
|
}) => {
|
|
// Find executors
|
|
const { executors } = await apiClient.listExecutors();
|
|
const localExec = executors.find((e) => e.type === "local");
|
|
const worktreeExec = executors.find((e) => e.type === "worktree");
|
|
if (!localExec || !worktreeExec) {
|
|
test.skip(true, "Need both local and worktree executors");
|
|
return;
|
|
}
|
|
const profile = await apiClient.createExecutorProfile(localExec.id, "E2E Local");
|
|
const worktreeProfile = worktreeExec.profiles?.[0];
|
|
if (!worktreeProfile) {
|
|
test.skip(true, "No worktree profile available");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const kanban = new KanbanPage(testPage);
|
|
await kanban.goto();
|
|
|
|
await kanban.createTaskButton.first().click();
|
|
const dialog = testPage.getByTestId("create-task-dialog");
|
|
await expect(dialog).toBeVisible();
|
|
|
|
await testPage.getByTestId("task-title-input").fill("Switch Executor Test");
|
|
await testPage.getByTestId("task-description-input").fill("testing executor switch");
|
|
|
|
// Select local executor -> branch should be disabled
|
|
const executorSelector = testPage.getByTestId("executor-profile-selector");
|
|
await executorSelector.click();
|
|
await testPage.getByRole("option", { name: /E2E Local/i }).click();
|
|
|
|
const branchSelector = testPage.getByTestId("branch-selector");
|
|
await expect(branchSelector).toBeDisabled({ timeout: 5_000 });
|
|
|
|
// Switch to worktree executor -> branch should be enabled
|
|
await executorSelector.click();
|
|
await testPage.getByRole("option", { name: worktreeProfile.name }).click();
|
|
|
|
await expect(branchSelector).toBeEnabled({ timeout: 5_000 });
|
|
} finally {
|
|
await apiClient.deleteExecutorProfile(profile.id).catch(() => {});
|
|
}
|
|
});
|
|
|
|
test("branch selector stays enabled for local executor with GitHub URL", async ({
|
|
testPage,
|
|
apiClient,
|
|
seedData,
|
|
backend,
|
|
}) => {
|
|
const fs = await import("fs");
|
|
const { execSync } = await import("child_process");
|
|
const gitEnv = {
|
|
...process.env,
|
|
HOME: backend.tmpDir,
|
|
GIT_AUTHOR_NAME: "E2E Test",
|
|
GIT_AUTHOR_EMAIL: "e2e@test.local",
|
|
GIT_COMMITTER_NAME: "E2E Test",
|
|
GIT_COMMITTER_EMAIL: "e2e@test.local",
|
|
};
|
|
|
|
// Find local executor and create profile
|
|
const { executors } = await apiClient.listExecutors();
|
|
const localExec = executors.find((e) => e.type === "local");
|
|
if (!localExec) {
|
|
test.skip(true, "No local executor available");
|
|
return;
|
|
}
|
|
const profile = await apiClient.createExecutorProfile(localExec.id, "E2E Local GitHub URL");
|
|
|
|
try {
|
|
// Create a unique repo for this test
|
|
const repoDir = `${backend.tmpDir}/repos/e2e-branch-gh`;
|
|
fs.mkdirSync(repoDir, { recursive: true });
|
|
execSync("git init -b main", { cwd: repoDir, env: gitEnv });
|
|
execSync('git commit --allow-empty -m "init"', { cwd: repoDir, env: gitEnv });
|
|
|
|
// Seed mock GitHub branches
|
|
await apiClient.createRepository(seedData.workspaceId, repoDir, "main", {
|
|
name: "branch-test-owner/branch-test-repo",
|
|
provider: "github",
|
|
provider_owner: "branch-test-owner",
|
|
provider_name: "branch-test-repo",
|
|
});
|
|
await apiClient.mockGitHubAddBranches("branch-test-owner", "branch-test-repo", [
|
|
{ name: "main" },
|
|
{ name: "develop" },
|
|
]);
|
|
|
|
const kanban = new KanbanPage(testPage);
|
|
await kanban.goto();
|
|
|
|
await kanban.createTaskButton.first().click();
|
|
const dialog = testPage.getByTestId("create-task-dialog");
|
|
await expect(dialog).toBeVisible();
|
|
|
|
// Toggle to GitHub URL mode
|
|
await testPage.getByTestId("toggle-github-url").click();
|
|
await testPage
|
|
.getByTestId("github-url-input")
|
|
.fill("https://github.com/branch-test-owner/branch-test-repo");
|
|
|
|
// Select local executor profile
|
|
const executorSelector = testPage.getByTestId("executor-profile-selector");
|
|
await executorSelector.click();
|
|
await testPage.getByRole("option", { name: /E2E Local GitHub URL/i }).click();
|
|
|
|
// Branch selector should NOT be disabled (GitHub URL mode overrides)
|
|
const branchSelector = testPage.getByTestId("branch-selector");
|
|
await expect(branchSelector).toBeEnabled({ timeout: 10_000 });
|
|
} finally {
|
|
await apiClient.deleteExecutorProfile(profile.id).catch(() => {});
|
|
}
|
|
});
|
|
});
|