refactor: enhance type safety and improve test structure in replay controller and share conversation services

- Updated type assertions in the ManualReplayController to ensure proper event handling.
- Refactored test cases in replay-controller.test.ts for improved clarity and structure.
- Enhanced type definitions in share-conversation.ts to ensure metadata is correctly typed.
- Improved test assertions in share-conversation.test.ts for better reliability and readability.
This commit is contained in:
ropzislaw
2026-02-19 23:05:28 +08:00
parent 2527db20af
commit 6cebf39772
4 changed files with 16 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
ManualReplayController,
type ReplayEventCallback,
@@ -22,10 +22,12 @@ beforeEach(() => {
.mockResolvedValue([{ id: 100, url: "https://example.com" }]);
mockTabs.sendMessage = vi.fn().mockResolvedValue({ success: true });
mockTabs.onUpdated = {
addListener: vi.fn((cb: Function) => {
// Immediately call with 'complete' to simulate page load
setTimeout(() => cb(100, { status: "complete" }), 0);
}),
addListener: vi.fn(
(cb: (tabId: number, changeInfo: { status?: string }) => void) => {
// Immediately call with 'complete' to simulate page load
setTimeout(() => cb(100, { status: "complete" }), 0);
},
),
removeListener: vi.fn(),
};
});

View File

@@ -220,9 +220,12 @@ export class ManualReplayController {
switch (event.type) {
case "navigation":
return this.executeNavigation(event as NavigationEvent, step);
return this.executeNavigation(
event as unknown as NavigationEvent,
step,
);
case "click":
return this.executeClick(event as ClickEvent, step);
return this.executeClick(event as unknown as ClickEvent, step);
default:
return { success: false, error: `Unknown event type: ${event.type}` };
}
@@ -365,10 +368,7 @@ export class ManualReplayController {
private waitForTabLoad(): Promise<void> {
return new Promise((resolve) => {
const listener = (
tabId: number,
changeInfo: chrome.tabs.TabChangeInfo,
) => {
const listener = (tabId: number, changeInfo: { status?: string }) => {
if (tabId === this.targetTabId && changeInfo.status === "complete") {
chrome.tabs.onUpdated.removeListener(listener);
resolve();

View File

@@ -66,7 +66,7 @@ describe("shareConversation", () => {
expect(mockFetch).toHaveBeenCalledTimes(1);
const callBody = JSON.parse(mockFetch.mock.calls[0][1].body);
const callBody = JSON.parse(mockFetch.mock.calls[0]![1].body);
// Should only have 2 messages (user + assistant), not the system one
expect(callBody.messages).toHaveLength(2);
expect(callBody.messages[0].role).toBe("user");
@@ -162,7 +162,7 @@ describe("shareConversation", () => {
await shareConversation(messages);
const callBody = JSON.parse(mockFetch.mock.calls[0][1].body);
const callBody = JSON.parse(mockFetch.mock.calls[0]![1].body);
const toolPart = callBody.messages[0].content.parts[0];
// screenshot field should NOT be included in the shared payload
expect(toolPart.screenshot).toBeUndefined();

View File

@@ -98,7 +98,7 @@ export async function shareConversation(
id: msg.id,
role: msg.role,
content: { parts: msg.parts.map(toShareablePart) },
metadata: msg.metadata,
metadata: msg.metadata as Record<string, unknown> | undefined,
}));
const cookieHeader = await getAuthCookieHeader();