fix(web): 补齐 iframe 与分栏交互状态
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
// @vitest-environment jsdom
|
||||
// SPEC: PJ2026-010405 云端控制台.
|
||||
// Implementation reference: draft-2026-07-13-p0-cloud-console.
|
||||
// Responsibility: 验证 OpenCode frame URL 换票完成后仍等待 iframe load,并提供失败、超时与重试状态。
|
||||
|
||||
import { flushPromises, mount } from "@vue/test-utils";
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import OpenCodeFrameView from "./OpenCodeFrameView.vue";
|
||||
|
||||
vi.mock("@/config/runtime", () => ({
|
||||
opencodeFrameUrl: () => "https://opencode.example.test"
|
||||
}));
|
||||
|
||||
function successfulFrameUrlResponse(): Response {
|
||||
return new Response(JSON.stringify({ url: "/opencode/proxy/?ticket=redacted" }), {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" }
|
||||
});
|
||||
}
|
||||
|
||||
describe("OpenCodeFrameView", () => {
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal("fetch", vi.fn(async () => successfulFrameUrlResponse()));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
test("waits for iframe load before reporting ready", async () => {
|
||||
const wrapper = mount(OpenCodeFrameView);
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("loading");
|
||||
expect(wrapper.get("iframe").attributes("src")).toBe("/opencode/proxy/?ticket=redacted");
|
||||
expect(wrapper.get("[role='status']").text()).toContain("OpenCode 加载中");
|
||||
|
||||
await wrapper.get("iframe").trigger("load");
|
||||
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("ready");
|
||||
expect(wrapper.find("[role='status']").exists()).toBe(false);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test("shows a retry after iframe error and starts a fresh bounded load", async () => {
|
||||
const wrapper = mount(OpenCodeFrameView);
|
||||
await flushPromises();
|
||||
|
||||
await wrapper.get("iframe").trigger("error");
|
||||
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("error");
|
||||
expect(wrapper.get("[role='status']").text()).toContain("iframe 加载失败");
|
||||
expect(wrapper.find("iframe").exists()).toBe(false);
|
||||
|
||||
await wrapper.get("button").trigger("click");
|
||||
await flushPromises();
|
||||
expect(fetch).toHaveBeenCalledTimes(2);
|
||||
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("loading");
|
||||
expect(wrapper.find("iframe").exists()).toBe(true);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test("fails a frame that does not load within the bounded timeout", async () => {
|
||||
vi.useFakeTimers();
|
||||
const wrapper = mount(OpenCodeFrameView);
|
||||
await flushPromises();
|
||||
|
||||
await vi.advanceTimersByTimeAsync(15_000);
|
||||
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("error");
|
||||
expect(wrapper.get("[role='status']").text()).toContain("iframe 加载超时");
|
||||
expect(wrapper.find("iframe").exists()).toBe(false);
|
||||
wrapper.unmount();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user