headless.test.ts 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // ---------------------------------------------------------------------------
  2. // CLI headless use cases (cline -y / cline --json / piped stdin)
  3. //
  4. // These tests run cline as a child process (no TUI harness) and assert on
  5. // stdout, stderr, and exit codes.
  6. //
  7. // Tests tagged @live require a configured provider and are skipped by default.
  8. // Run them with: CLINE_BIN=... npm test -- headless @live
  9. // ---------------------------------------------------------------------------
  10. import { test } from "@microsoft/tui-test"
  11. import { CLINE_BIN, TERMINAL_WIDE } from "../helpers/constants.js"
  12. import { clineEnv } from "../helpers/env.js"
  13. import { expectVisible } from "../helpers/terminal.js"
  14. // ---------------------------------------------------------------------------
  15. // cline -y "tell me a joke"
  16. // Golden path: prints "Task started" then LLM output, then exits 0.
  17. // Unauthenticated: prints "Not authenticated" and exits 1.
  18. // ---------------------------------------------------------------------------
  19. test.describe("cline -y (headless yolo mode) — unauthenticated", () => {
  20. test.use({
  21. program: { file: CLINE_BIN, args: ["-y", "tell me a joke"] },
  22. ...TERMINAL_WIDE,
  23. env: clineEnv("unauthenticated"),
  24. })
  25. test("prints Not authenticated and exits 1", async ({ terminal }) => {
  26. await expectVisible(terminal, /not authenticated/i)
  27. })
  28. })
  29. // ---------------------------------------------------------------------------
  30. // echo "max paulus" | cline -y "print only the second word I gave you"
  31. // Piped stdin test — uses TUI harness with stdin pre-written
  32. // ---------------------------------------------------------------------------
  33. test.describe("piped stdin | cline -y — unauthenticated", () => {
  34. test.use({
  35. program: {
  36. file: "sh",
  37. args: ["-c", `echo "max paulus" | ${CLINE_BIN} -y "print only the second word I gave you"`],
  38. },
  39. ...TERMINAL_WIDE,
  40. env: clineEnv("unauthenticated"),
  41. })
  42. test("prints Not Authenticated for piped stdin", async ({ terminal }) => {
  43. await expectVisible(terminal, /not authenticated/i)
  44. })
  45. })
  46. // ---------------------------------------------------------------------------
  47. // cline -y --verbose "tell me a joke" 2>&1
  48. // Golden path: prints task started, prompt, api request, reasoning, task_completion lines
  49. // ---------------------------------------------------------------------------
  50. test.describe("cline -y --verbose — unauthenticated", () => {
  51. test.use({
  52. program: {
  53. file: "sh",
  54. args: ["-c", `${CLINE_BIN} -y --verbose "tell me a joke" 2>&1`],
  55. },
  56. ...TERMINAL_WIDE,
  57. env: clineEnv("unauthenticated"),
  58. })
  59. test("shows verbose output or not-authenticated", async ({ terminal }) => {
  60. await expectVisible(terminal, /not authenticated|verbose|task/i)
  61. })
  62. })
  63. // ---------------------------------------------------------------------------
  64. // cline --json "tell me a joke"
  65. // All output must conform to JSON (one JSON object per line)
  66. // ---------------------------------------------------------------------------
  67. test.describe("cline --json — unauthenticated", () => {
  68. test.use({
  69. program: { file: CLINE_BIN, args: ["--json", "tell me a joke"] },
  70. ...TERMINAL_WIDE,
  71. env: clineEnv("unauthenticated"),
  72. })
  73. test("outputs JSON error for unauthenticated", async ({ terminal }) => {
  74. // cline --json when unauthenticated outputs a plain "Not authenticated" message
  75. await expectVisible(terminal, /not authenticated/i)
  76. })
  77. })