mirror of
https://github.com/actionbook/actionbook.git
synced 2026-09-19 03:28:06 +08:00
731cc340d8
* [packages/cli]test: add comprehensive CLI test suite with E2E browser tests - Add unit tests for wrapper (actionbook.js), postinstall, config, profile, search, get, and sources commands - Add Tier 1 browser tests (arg validation, help output, defaults) - Add Tier 2 browser E2E tests (navigation, interaction, screenshots, cookies, tabs, error handling, JSON output) - Fix E2E test reliability: add --wait for element readiness after navigation, use eval-based form submit for login flow, match actual CLI exit codes - Suppress macOS Keychain dialogs in tests via --use-mock-keychain config - Set testTimeout to 60s for browser E2E operations - Export modules from actionbook.js and postinstall.js for testability Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * [packages/cli]fix: resolve Windows .exe suffix when locating test CLI binary Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * [packages/cli]fix: skip shell-script mock tests on Windows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import { describe, it, expect, beforeAll } from "vitest";
|
|
import { getActionbookBinary, runCli } from "./helpers/binary";
|
|
import { isApiAvailable } from "./helpers/api";
|
|
import { createIsolatedEnv } from "./helpers/config";
|
|
|
|
const binary = getActionbookBinary();
|
|
const hasBinary = !!binary;
|
|
|
|
let apiAvailable = false;
|
|
|
|
describe.skipIf(!hasBinary)("sources command", () => {
|
|
let isolatedEnv: ReturnType<typeof createIsolatedEnv>;
|
|
|
|
beforeAll(async () => {
|
|
isolatedEnv = createIsolatedEnv();
|
|
apiAvailable = await isApiAvailable();
|
|
});
|
|
|
|
describe("argument validation", () => {
|
|
it("requires a subcommand", async () => {
|
|
const result = await runCli(["sources"], { env: isolatedEnv.env });
|
|
expect(result.exitCode).toBe(2);
|
|
expect(result.stderr).toContain("subcommand");
|
|
});
|
|
|
|
it("sources search requires a query", async () => {
|
|
const result = await runCli(["sources", "search"], {
|
|
env: isolatedEnv.env,
|
|
});
|
|
expect(result.exitCode).toBe(2);
|
|
expect(result.stderr).toContain("QUERY");
|
|
});
|
|
});
|
|
|
|
describe.skipIf(!apiAvailable)("with API", () => {
|
|
it("lists sources", async () => {
|
|
const result = await runCli(["sources", "list"], {
|
|
env: isolatedEnv.env,
|
|
timeout: 30000,
|
|
});
|
|
expect(result.exitCode).toBe(0);
|
|
});
|
|
|
|
it("lists sources in JSON format", async () => {
|
|
const result = await runCli(["--json", "sources", "list"], {
|
|
env: isolatedEnv.env,
|
|
timeout: 30000,
|
|
});
|
|
expect(result.exitCode).toBe(0);
|
|
// Verify output is valid JSON
|
|
expect(() => JSON.parse(result.stdout)).not.toThrow();
|
|
});
|
|
|
|
it("searches sources by keyword", async () => {
|
|
const result = await runCli(["sources", "search", "airbnb"], {
|
|
env: isolatedEnv.env,
|
|
timeout: 30000,
|
|
});
|
|
expect(result.exitCode).toBe(0);
|
|
});
|
|
});
|
|
});
|