Unverified 提交 c227a08d authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Gateway e2e (#323)

上级 fc1ebe9e
import { test } from "./helpers/test_helper"; import { test } from "./helpers/test_helper";
import * as fs from "fs"; import * as fs from "fs";
// It's hard to read the snapshots, but they should be identical across
// all test cases in this file, so we use the same snapshot name to ensure
// the outputs are identical.
const SNAPSHOT_NAME = "attach-image";
// attach image is implemented in two separate components // attach image is implemented in two separate components
// - HomeChatInput // - HomeChatInput
// - ChatInput // - ChatInput
...@@ -13,7 +18,7 @@ test("attach image - home chat", async ({ po }) => { ...@@ -13,7 +18,7 @@ test("attach image - home chat", async ({ po }) => {
.locator("input[type='file']") .locator("input[type='file']")
.setInputFiles("e2e-tests/fixtures/images/logo.png"); .setInputFiles("e2e-tests/fixtures/images/logo.png");
await po.sendPrompt("[dump]"); await po.sendPrompt("[dump]");
await po.snapshotServerDump("last-message"); await po.snapshotServerDump("last-message", { name: SNAPSHOT_NAME });
await po.snapshotMessages({ replaceDumpPath: true }); await po.snapshotMessages({ replaceDumpPath: true });
}); });
...@@ -27,7 +32,7 @@ test("attach image - chat", async ({ po }) => { ...@@ -27,7 +32,7 @@ test("attach image - chat", async ({ po }) => {
.locator("input[type='file']") .locator("input[type='file']")
.setInputFiles("e2e-tests/fixtures/images/logo.png"); .setInputFiles("e2e-tests/fixtures/images/logo.png");
await po.sendPrompt("[dump]"); await po.sendPrompt("[dump]");
await po.snapshotServerDump("last-message"); await po.snapshotServerDump("last-message", { name: SNAPSHOT_NAME });
await po.snapshotMessages({ replaceDumpPath: true }); await po.snapshotMessages({ replaceDumpPath: true });
}); });
...@@ -65,6 +70,6 @@ test("attach image via drag - chat", async ({ po }) => { ...@@ -65,6 +70,6 @@ test("attach image via drag - chat", async ({ po }) => {
// submit and verify // submit and verify
await po.sendPrompt("[dump]"); await po.sendPrompt("[dump]");
// Note: this should match EXACTLY the server dump from the previous test. // Note: this should match EXACTLY the server dump from the previous test.
await po.snapshotServerDump("last-message"); await po.snapshotServerDump("last-message", { name: SNAPSHOT_NAME });
await po.snapshotMessages({ replaceDumpPath: true }); await po.snapshotMessages({ replaceDumpPath: true });
}); });
...@@ -10,3 +10,21 @@ test("send message to engine", async ({ po }) => { ...@@ -10,3 +10,21 @@ test("send message to engine", async ({ po }) => {
await po.snapshotServerDump("request"); await po.snapshotServerDump("request");
await po.snapshotMessages({ replaceDumpPath: true }); await po.snapshotMessages({ replaceDumpPath: true });
}); });
test("send message to gateway", async ({ po }) => {
await po.setUpDyadPro();
await po.selectModel({ provider: "Google", model: "Gemini 2.5 Flash" });
await po.sendPrompt("[dump] tc=gateway-simple");
await po.snapshotServerDump("request");
await po.snapshotMessages({ replaceDumpPath: true });
});
// auto (defaults to Gemini 2.5 Flash)
test("auto should send message to gateway", async ({ po }) => {
await po.setUpDyadPro();
await po.sendPrompt("[dump] tc=gateway-simple");
await po.snapshotServerDump("request");
await po.snapshotMessages({ replaceDumpPath: true });
});
...@@ -141,6 +141,7 @@ class PageObject { ...@@ -141,6 +141,7 @@ class PageObject {
async snapshotServerDump( async snapshotServerDump(
type: "all-messages" | "last-message" | "request" = "all-messages", type: "all-messages" | "last-message" | "request" = "all-messages",
{ name = "" }: { name?: string } = {},
) { ) {
// Get the text content of the messages list // Get the text content of the messages list
const messagesListText = await this.page const messagesListText = await this.page
...@@ -164,14 +165,14 @@ class PageObject { ...@@ -164,14 +165,14 @@ class PageObject {
// Perform snapshot comparison // Perform snapshot comparison
const parsedDump = JSON.parse(dumpContent); const parsedDump = JSON.parse(dumpContent);
if (type === "request") { if (type === "request") {
expect(dumpContent).toMatchSnapshot("server-dump-request.json"); expect(dumpContent).toMatchSnapshot(name);
return; return;
} }
expect( expect(
prettifyDump(parsedDump["body"]["messages"], { prettifyDump(parsedDump["body"]["messages"], {
onlyLastMessage: type === "last-message", onlyLastMessage: type === "last-message",
}), }),
).toMatchSnapshot("server-dump.txt"); ).toMatchSnapshot(name);
} }
async waitForChatCompletion() { async waitForChatCompletion() {
...@@ -473,6 +474,7 @@ export const test = base.extend<{ ...@@ -473,6 +474,7 @@ export const test = base.extend<{
process.env.LM_STUDIO_BASE_URL_FOR_TESTING = process.env.LM_STUDIO_BASE_URL_FOR_TESTING =
"http://localhost:3500/lmstudio"; "http://localhost:3500/lmstudio";
process.env.DYAD_LOCAL_ENGINE = "http://localhost:3500/engine/v1"; process.env.DYAD_LOCAL_ENGINE = "http://localhost:3500/engine/v1";
process.env.DYAD_GATEWAY_URL = "http://localhost:3500/gateway/v1";
process.env.E2E_TEST_BUILD = "true"; process.env.E2E_TEST_BUILD = "true";
// This is just a hack to avoid the AI setup screen. // This is just a hack to avoid the AI setup screen.
process.env.OPENAI_API_KEY = "sk-test"; process.env.OPENAI_API_KEY = "sk-test";
......
- paragraph: "[dump] tc=gateway-simple"
- paragraph: "[[dyad-dump-path=*]]"
- button "Retry":
- img
\ No newline at end of file
- paragraph: "[dump] tc=gateway-simple"
- paragraph: "[[dyad-dump-path=*]]"
- button "Retry":
- img
\ No newline at end of file
...@@ -180,14 +180,14 @@ app.get("/lmstudio/api/v0/models", (req, res) => { ...@@ -180,14 +180,14 @@ app.get("/lmstudio/api/v0/models", (req, res) => {
res.json(lmStudioModels); res.json(lmStudioModels);
}); });
app.post( ["lmstudio", "gateway", "engine"].forEach((provider) => {
"/lmstudio/v1/chat/completions", app.post(
createChatCompletionHandler("lmstudio"), `/${provider}/v1/chat/completions`,
); createChatCompletionHandler(provider),
);
app.post("/engine/v1/chat/completions", createChatCompletionHandler("engine")); });
// Handle POST requests to /v1/chat/completions // Default test provider handler:
app.post("/v1/chat/completions", createChatCompletionHandler(".")); app.post("/v1/chat/completions", createChatCompletionHandler("."));
// Start the server // Start the server
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论