blob: dd37d1f2932f8c1f367d46642e6d4141642ca18c [file] [log] [blame]
Sean McCulloughb29f8912025-04-20 15:39:11 -07001import { test, expect } from "@sand4rt/experimental-ct-web";
2import { SketchContainerStatus } from "./sketch-container-status";
Sean McCullough86b56862025-04-18 13:04:03 -07003import { State } from "../types";
4
Sean McCulloughb29f8912025-04-20 15:39:11 -07005// Mock complete state for testing
6const mockCompleteState: State = {
Philip Zeyligerd03318d2025-05-08 13:09:12 -07007 state_version: 2,
Sean McCulloughb29f8912025-04-20 15:39:11 -07008 hostname: "test-host",
9 working_dir: "/test/dir",
10 initial_commit: "abcdef1234567890",
11 message_count: 42,
12 os: "linux",
Josh Bleecher Snyder19969a92025-06-05 14:34:02 -070013 slug: "test-session",
Sean McCulloughb29f8912025-04-20 15:39:11 -070014 total_usage: {
15 input_tokens: 1000,
16 output_tokens: 2000,
17 cache_read_input_tokens: 300,
18 cache_creation_input_tokens: 400,
19 total_cost_usd: 0.25,
Sean McCulloughd9f13372025-04-21 15:08:49 -070020 start_time: "",
21 messages: 0,
22 tool_uses: {},
Sean McCulloughb29f8912025-04-20 15:39:11 -070023 },
Philip Zeyliger99a9a022025-04-27 15:15:25 +000024 outstanding_llm_calls: 0,
25 outstanding_tool_calls: [],
Philip Zeyligerc72fff52025-04-29 20:17:54 +000026 session_id: "test-session-id",
27 ssh_available: false,
Philip Zeyliger2c4db092025-04-28 16:57:50 -070028 in_container: true,
29 first_message_index: 0,
Sean McCulloughb29f8912025-04-20 15:39:11 -070030};
31
32test("render props", async ({ mount }) => {
33 const component = await mount(SketchContainerStatus, {
34 props: {
35 state: mockCompleteState,
36 },
37 });
38 await expect(component.locator("#hostname")).toContainText(
39 mockCompleteState.hostname,
40 );
41 // Check that all expected elements exist
42 await expect(component.locator("#workingDir")).toContainText(
43 mockCompleteState.working_dir,
44 );
Autoformatter3d040bd2025-06-06 02:35:19 +000045
Josh Bleecher Snyder44f847a2025-06-05 14:33:50 -070046 // Show details to access the popup elements
philip.zeyliger6d3de482025-06-10 19:38:14 -070047 await component.locator(".info-toggle").click();
Autoformatter3d040bd2025-06-06 02:35:19 +000048
Sean McCulloughb29f8912025-04-20 15:39:11 -070049 await expect(component.locator("#initialCommit")).toContainText(
50 mockCompleteState.initial_commit.substring(0, 8),
51 );
52
Autoformatter5c70bfe2025-04-25 21:28:00 +000053 await expect(component.locator("#messageCount")).toContainText(
Sean McCulloughb29f8912025-04-20 15:39:11 -070054 mockCompleteState.message_count + "",
55 );
Josh Bleecher Snyder35889972025-04-24 20:48:16 +000056 const expectedTotalInputTokens =
57 mockCompleteState.total_usage.input_tokens +
58 mockCompleteState.total_usage.cache_read_input_tokens +
59 mockCompleteState.total_usage.cache_creation_input_tokens;
Sean McCulloughb29f8912025-04-20 15:39:11 -070060 await expect(component.locator("#inputTokens")).toContainText(
Josh Bleecher Snydera0801ad2025-04-25 19:34:53 +000061 expectedTotalInputTokens.toLocaleString(),
Sean McCulloughb29f8912025-04-20 15:39:11 -070062 );
63 await expect(component.locator("#outputTokens")).toContainText(
Josh Bleecher Snydera0801ad2025-04-25 19:34:53 +000064 mockCompleteState.total_usage.output_tokens.toLocaleString(),
Sean McCulloughb29f8912025-04-20 15:39:11 -070065 );
Sean McCulloughb29f8912025-04-20 15:39:11 -070066 await expect(component.locator("#totalCost")).toContainText(
67 "$" + mockCompleteState.total_usage.total_cost_usd.toFixed(2),
68 );
69});
70
Sean McCulloughb29f8912025-04-20 15:39:11 -070071test("renders with partial state data", async ({ mount }) => {
72 const partialState: Partial<State> = {
Philip Zeyligerd03318d2025-05-08 13:09:12 -070073 state_version: 2,
Sean McCulloughb29f8912025-04-20 15:39:11 -070074 hostname: "partial-host",
75 message_count: 10,
Sean McCullough86b56862025-04-18 13:04:03 -070076 os: "linux",
Josh Bleecher Snyder19969a92025-06-05 14:34:02 -070077 slug: "partial-test",
Philip Zeyligerc72fff52025-04-29 20:17:54 +000078 session_id: "partial-session",
79 ssh_available: false,
Sean McCullough86b56862025-04-18 13:04:03 -070080 total_usage: {
Sean McCulloughb29f8912025-04-20 15:39:11 -070081 input_tokens: 500,
Sean McCulloughd9f13372025-04-21 15:08:49 -070082 start_time: "",
83 messages: 0,
84 output_tokens: 0,
85 cache_read_input_tokens: 0,
86 cache_creation_input_tokens: 0,
87 total_cost_usd: 0,
88 tool_uses: {},
Sean McCullough71941bd2025-04-18 13:31:48 -070089 },
Sean McCullough86b56862025-04-18 13:04:03 -070090 };
91
Sean McCulloughb29f8912025-04-20 15:39:11 -070092 const component = await mount(SketchContainerStatus, {
93 props: {
94 state: partialState as State,
95 },
Sean McCullough86b56862025-04-18 13:04:03 -070096 });
97
Sean McCulloughb29f8912025-04-20 15:39:11 -070098 // Check that elements with data are properly populated
99 await expect(component.locator("#hostname")).toContainText("partial-host");
Autoformatter3d040bd2025-06-06 02:35:19 +0000100
Josh Bleecher Snyder44f847a2025-06-05 14:33:50 -0700101 // Show details to access the popup elements
philip.zeyliger6d3de482025-06-10 19:38:14 -0700102 await component.locator(".info-toggle").click();
Sean McCulloughb29f8912025-04-20 15:39:11 -0700103 await expect(component.locator("#messageCount")).toContainText("10");
Josh Bleecher Snyder35889972025-04-24 20:48:16 +0000104
105 const expectedTotalInputTokens =
106 partialState.total_usage.input_tokens +
107 partialState.total_usage.cache_read_input_tokens +
108 partialState.total_usage.cache_creation_input_tokens;
109 await expect(component.locator("#inputTokens")).toContainText(
Josh Bleecher Snydera0801ad2025-04-25 19:34:53 +0000110 expectedTotalInputTokens.toLocaleString(),
Josh Bleecher Snyder35889972025-04-24 20:48:16 +0000111 );
Sean McCullough86b56862025-04-18 13:04:03 -0700112
Sean McCulloughb29f8912025-04-20 15:39:11 -0700113 // Check that elements without data are empty
114 await expect(component.locator("#workingDir")).toContainText("");
115 await expect(component.locator("#initialCommit")).toContainText("");
Josh Bleecher Snyder35889972025-04-24 20:48:16 +0000116 await expect(component.locator("#outputTokens")).toContainText("0");
Josh Bleecher Snyder44f847a2025-06-05 14:33:50 -0700117 // totalCost element should not exist when cost is 0
118 await expect(component.locator("#totalCost")).toHaveCount(0);
Sean McCulloughb29f8912025-04-20 15:39:11 -0700119});