Files
DadaoTask/web/e2e/knowledge-paging.mjs
T

125 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 知识列表翻页的界面验收:点「加载更多」能把 84 条翻到底,不出错。
*
* 这条脚本是有来历的:接口的游标字段名写错(`cur.item_id`),第二页直接 500,
* 但库小于一页时永远碰不到——导入 84 条旧备忘之后用户一点就撞上了。
*
* 用法:
* node web/e2e/knowledge-paging.mjs # 默认打生产
* WEB=http://127.0.0.1:5180 PHONE=13900000001 node web/e2e/knowledge-paging.mjs
*/
import { chromium } from "playwright-core";
const WEB = process.env.WEB ?? "http://192.168.8.188:8200";
const API = process.env.API ?? `${WEB}/api/v1`;
const PHONE = process.env.PHONE ?? "13605513683";
const CODE = process.env.CODE ?? "123456";
const CODE_PIN = process.env.CODE_PIN ?? "123456"; // 生产 pin 就是验证码本身
const CHROME =
process.env.CHROME ??
`${process.env.LOCALAPPDATA}\\ms-playwright\\chromium-1223\\chrome-win64\\chrome.exe`;
let pass = 0;
let fail = 0;
function check(name, ok, extra = "") {
if (ok) {
pass += 1;
console.log(`PASS ${name}`);
} else {
fail += 1;
console.log(`FAIL ${name} ${extra}`);
}
}
async function login() {
const r = await fetch(`${API}/auth/sms/send`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ phone: PHONE }),
});
const sent = await r.json();
if (sent.code !== 0) throw new Error(`发码失败:${sent.message}`);
const login = await fetch(`${API}/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ phone: PHONE, code: CODE_PIN }),
});
const body = await login.json();
if (body.code !== 0) throw new Error(`登录失败:${body.message}`);
return { tokens: body.data.tokens, workspaces: await workspaces(body.data.tokens) };
}
async function workspaces(tokens) {
const r = await fetch(`${API}/workspaces`, {
headers: { Authorization: `Bearer ${tokens.access_token}` },
});
const body = await r.json();
return body.data?.items ?? body.data ?? [];
}
async function main() {
void CODE;
const { tokens, workspaces: spaces } = await login();
if (!spaces.length) throw new Error("这个账号没有工作区");
const ws = spaces[0];
// 先问接口一共有多少条,作为界面上应该数出来的数字
const head = await fetch(`${API}/workspaces/${ws.id}/knowledge?limit=100`, {
headers: { Authorization: `Bearer ${tokens.access_token}` },
});
const headBody = await head.json();
const total = (headBody.data?.items ?? []).length;
const browser = await chromium.launch({ executablePath: CHROME });
const context = await browser.newContext({ viewport: { width: 1440, height: 960 } });
await context.addInitScript(
([access, refresh]) => {
localStorage.setItem("dadao.access", access);
localStorage.setItem("dadao.refresh", refresh);
},
[tokens.access_token, tokens.refresh_token],
);
const page = await context.newPage();
const errors = [];
const bad = [];
page.on("pageerror", (e) => errors.push(String(e)));
page.on("response", (r) => {
if (r.url().includes("/knowledge?") && r.status() >= 400) bad.push(`${r.status()} ${r.url()}`);
});
await page.goto(`${WEB}/w/${ws.id}/knowledge`, { waitUntil: "networkidle" });
const cards = () => page.locator("li");
const first = await cards().count();
check("首屏有列表", first > 0, `count=${first}`);
let rounds = 0;
while (rounds < 20) {
const more = page.getByRole("button", { name: "加载更多" });
if ((await more.count()) === 0) break;
const before = await cards().count();
await more.first().click();
const grew = async () => (await cards().count()) > before;
for (let i = 0; i < 40 && !(await grew()); i += 1) await page.waitForTimeout(100);
if (!(await grew())) break;
rounds += 1;
}
const shown = await cards().count();
check("点「加载更多」能把列表翻到底", shown >= total, `shown=${shown} total=${total}`);
check("翻页接口没有报错", bad.length === 0, bad.slice(0, 3).join(" | "));
const toast = await page.locator("text=服务器内部错误").count();
check("页面上没有「服务器内部错误」", toast === 0);
check("控制台零报错", errors.length === 0, errors.slice(0, 2).join(" | "));
await page.screenshot({ path: "e2e/artifacts/knowledge-paging.png" });
await browser.close();
console.log(`\n${fail === 0 ? "ALL PASS" : "SOME FAILED"} — pass ${pass}, fail ${fail}`);
process.exit(fail === 0 ? 0 : 1);
}
main().catch((err) => {
console.error("脚本异常 —", err?.message ?? err);
process.exit(1);
});