Z ZPI 文档 v0.3.8
介绍页

源码

tests/desktop/provider-menu.spec.ts

typescript90 行查看原文
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { runCleanup } from "../helpers/cleanup.ts";
import { launchDesktop } from "../helpers/desktop.ts";
import { expect, test } from "../helpers/test.ts";

test("provider menu appears above settings, supports keyboard access and deletes the chosen provider", async () => {
  const dir = await mkdtemp(join(tmpdir(), "zpi-provider-menu-"));
  let app: Awaited<ReturnType<typeof launchDesktop>>;
  try {
    app = await launchDesktop({ dir, url: "" });
    const page = await app.firstWindow();
    await page.evaluate(async () => {
      for (const [id, name] of [
        ["delete", "菜单测试"],
        ["keep", "保留供应商"],
      ]) {
        const result = await window.zpi.saveProvider({
          id,
          name,
          baseUrl: "http://127.0.0.1:1/v1",
          apiKey: "",
          models: Array.from({ length: 10 }, (_, i) => ({ id: `model-${i}`, reasoning: false })),
        });
        if (!result.ok) throw new Error(result.error.message);
      }
    });
    await page.reload();
    await page.getByRole("button", { name: "设置", exact: true }).click();
    await page.getByRole("button", { name: "模型", exact: true }).click();
    await page.getByRole("button", { name: "菜单测试", exact: true }).click();
    await page.getByRole("button", { name: "供应商操作", exact: true }).click();
    const item = page.getByRole("menuitem", { name: "删除", exact: true });
    await expect(item).toBeVisible();
    expect(
      await item.evaluate((element) => {
        const rect = element.getBoundingClientRect();
        return element.contains(document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2));
      }),
    ).toBe(true);
    await item.evaluate(async (el) => {
      await Promise.all(
        el
          .closest('[role="menu"]')
          ?.getAnimations()
          .map((animation) => animation.finished) ?? [],
      );
    });
    expect(await page.getByRole("menu").evaluate((el) => el.getBoundingClientRect().width)).toBe(128);
    await page.screenshot({ path: "test-results/provider-actions-menu.png" });
    await page.emulateMedia({ colorScheme: "dark" });
    await expect
      .poll(() => page.getByRole("menu").evaluate((el) => getComputedStyle(el).backgroundColor))
      .toBe("rgb(43, 43, 43)");
    await page.screenshot({ path: "test-results/provider-actions-menu-dark.png" });
    await page.emulateMedia({ colorScheme: "light" });
    await item.click();
    await expect(page.getByRole("button", { name: "确认删除", exact: true })).toBeInViewport();
    await page.screenshot({ path: "test-results/provider-delete-confirm.png" });
    await page.getByRole("button", { name: "取消", exact: true }).click();
    const trigger = page.getByRole("button", { name: "供应商操作", exact: true });
    await trigger.click();
    await page.getByRole("menuitem", { name: "重命名", exact: true }).click();
    const rename = page.getByLabel("重命名供应商", { exact: true });
    await expect(rename).toBeFocused();
    await rename.fill("取消重命名");
    await rename.press("Escape");
    await expect(page.locator(".provider-detail-heading h2")).toHaveText("菜单测试");
    await trigger.click();
    await page.getByRole("menuitem", { name: "重命名", exact: true }).click();
    await rename.fill("重命名后");
    await rename.press("Enter");
    await expect(page.locator(".provider-detail-heading h2")).toHaveText("重命名后");
    await expect(page.locator('[data-provider-id="delete"]')).toContainText("重命名后");
    await trigger.scrollIntoViewIfNeeded();
    await trigger.focus();
    await trigger.press("Enter");
    await item.press("Enter");
    await page.getByRole("button", { name: "确认删除", exact: true }).click();
    await expect(page.locator('[data-provider-id="delete"]')).toHaveCount(0);
    await expect(page.locator('[data-provider-id="keep"]')).toHaveCount(1);
    await page.reload();
    const settings = await page.evaluate(() => window.zpi.getSettings());
    expect(settings.ok && settings.value.providers.map((provider) => provider.id)).toEqual(["keep"]);
  } finally {
    await runCleanup([() => rm(dir, { recursive: true, force: true }), () => app?.close()]);
  }
});