93 lines
3.6 KiB
TypeScript
93 lines
3.6 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { expect, test } from "../../fixtures/test-base";
|
|
import {
|
|
MOCK_CODEX_CONFIG_BUNDLE_ID,
|
|
portableConfigInfo,
|
|
portableConfigSection,
|
|
selectedBundleIds,
|
|
selectPortableConfigBundle,
|
|
} from "./executor-agent-config-helpers";
|
|
|
|
test.describe("portable agent configuration settings", () => {
|
|
test("saves configuration independently from authentication and reloads it", async ({
|
|
apiClient,
|
|
backend,
|
|
testPage,
|
|
}) => {
|
|
// The baseline E2E agent has no credentials by design. Add the mock Codex
|
|
// alias for this settings-only scenario so the auth checkbox remains a real,
|
|
// independently selectable control without requiring provider secrets.
|
|
await backend.restart({ KANDEV_MOCK_PROVIDERS: "codex-acp" });
|
|
const configDir = path.join(backend.tmpDir, ".mock-agent");
|
|
fs.mkdirSync(configDir, { recursive: true });
|
|
fs.writeFileSync(path.join(configDir, "settings.json"), '{"source":"settings"}\n');
|
|
const catalog = await apiClient.listAgentConfigBundles();
|
|
expect(
|
|
catalog.bundles.some(
|
|
(bundle) => bundle.id === MOCK_CODEX_CONFIG_BUNDLE_ID && bundle.agent_id === "codex-acp",
|
|
),
|
|
).toBe(true);
|
|
|
|
const executor = await apiClient.createExecutor("E2E portable config executor", "local_docker");
|
|
const profile = await apiClient.createExecutorProfile(executor.id, {
|
|
name: "E2E portable config profile",
|
|
config: {},
|
|
prepare_script: "",
|
|
cleanup_script: "",
|
|
env_vars: [],
|
|
});
|
|
|
|
try {
|
|
await testPage.goto(`/settings/executors/${profile.id}`);
|
|
|
|
const agentTrigger = testPage.getByRole("button", { name: /Mock Codex/ });
|
|
await expect(agentTrigger).toBeVisible();
|
|
await agentTrigger.click();
|
|
|
|
const section = portableConfigSection(testPage, "codex-acp");
|
|
await expect(section).toBeVisible();
|
|
const info = portableConfigInfo(testPage, "codex-acp");
|
|
await expect(info).toBeVisible();
|
|
await info.hover();
|
|
await expect(testPage.getByRole("tooltip")).toContainText("without changes");
|
|
|
|
await selectPortableConfigBundle(testPage, MOCK_CODEX_CONFIG_BUNDLE_ID, "codex-acp");
|
|
await expect(
|
|
section
|
|
.getByTestId(`portable-config-bundle-${MOCK_CODEX_CONFIG_BUNDLE_ID}`)
|
|
.getByRole("checkbox"),
|
|
).toBeChecked();
|
|
|
|
await testPage.getByRole("button", { name: "Mock Codex Not Configured" }).click();
|
|
const authChoice = testPage.getByRole("checkbox", { name: "Copy auth files" }).first();
|
|
await expect(authChoice).toBeVisible();
|
|
await authChoice.click();
|
|
await expect(authChoice).toBeChecked();
|
|
|
|
const saveButton = testPage
|
|
.getByTestId("settings-floating-save")
|
|
.getByRole("button", { name: "Save changes" });
|
|
await expect(saveButton).toBeEnabled();
|
|
await saveButton.click();
|
|
await expect(testPage.getByText("Profile saved")).toBeVisible();
|
|
|
|
const saved = await apiClient.getExecutorProfile(executor.id, profile.id);
|
|
expect(selectedBundleIds(saved.config)).toEqual([MOCK_CODEX_CONFIG_BUNDLE_ID]);
|
|
expect(JSON.parse(saved.config?.remote_credentials ?? "[]").length).toBeGreaterThan(0);
|
|
|
|
await testPage.reload();
|
|
await testPage.getByRole("button", { name: /Mock Codex/ }).click();
|
|
await expect(section).toBeVisible();
|
|
await expect(
|
|
section
|
|
.getByTestId(`portable-config-bundle-${MOCK_CODEX_CONFIG_BUNDLE_ID}`)
|
|
.getByRole("checkbox"),
|
|
).toBeChecked();
|
|
} finally {
|
|
await apiClient.deleteExecutor(executor.id).catch(() => {});
|
|
await backend.restart();
|
|
}
|
|
});
|
|
});
|