diff --git a/frontend/src/pages/tools/EndpointsTab.tsx b/frontend/src/pages/tools/EndpointsTab.tsx index 21dfa747..1eeb0b6a 100644 --- a/frontend/src/pages/tools/EndpointsTab.tsx +++ b/frontend/src/pages/tools/EndpointsTab.tsx @@ -30,10 +30,11 @@ const rowsOf = (env?: EndpointEnv): HeaderRow[] => Object.entries(env?.headers ? /** 请求头名称:HTTP 的 token(和服务端 capabilities/secrets.header_problem 同一条规矩,服务端为准) */ const HEADER_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/ -function headerProblem(row: HeaderRow, rows: HeaderRow[]): string | null { +/** 一行认证头的问题。重名只标后来的那一行:前面那一行本身没错,删掉或改掉后加的就好 */ +function headerProblem(row: HeaderRow, rows: HeaderRow[], index: number): string | null { if (!row.k.trim()) return T.headerEmpty if (!HEADER_NAME.test(row.k)) return T.headerInvalid - if (rows.filter((r) => r.k.toLowerCase() === row.k.toLowerCase()).length > 1) return T.headerDuplicate + if (rows.slice(0, index).some((r) => r.k.toLowerCase() === row.k.toLowerCase())) return T.headerDuplicate return null } @@ -168,7 +169,7 @@ function EndpointEditor({ row, onClose, onSaved, onConflict }: { const [timeout, setTimeoutS] = useState(row?.timeout_s ?? 20) const [busy, setBusy] = useState(false) // 配了的环境里有标红的请求头(名称空、不合法、重复):不让保存 - const headerBlocked = ENVS.some((env) => envs[env] && headers[env].some((r) => headerProblem(r, headers[env]))) + const headerBlocked = ENVS.some((env) => envs[env] && headers[env].some((r, i) => headerProblem(r, headers[env], i))) const idemProblem = HEADER_NAME.test(idem) ? null : T.headerInvalid const setEnv = (env: EnvKey, patch: Partial | null) => setEnvs((cur) => { @@ -259,7 +260,7 @@ function EnvEditor({ env, value, onChange, headers, onHeaders }: {
{T.headers} · {T.headersHint}
{headers.map((r, i) => { - const problem = headerProblem(r, headers) + const problem = headerProblem(r, headers, i) const errorId = `endpoint-${env}-header-${i}-error` return (
diff --git a/scripts/check-app-editor.mjs b/scripts/check-app-editor.mjs index 90e7a960..5ad406c0 100644 --- a/scripts/check-app-editor.mjs +++ b/scripts/check-app-editor.mjs @@ -585,7 +585,8 @@ await section('岗位与授权:三档各写标题和说明;搭建者从名 && (await rows.nth(1).innerText()).includes('全部实例') && (await rows.nth(2).innerText()).includes('编辑、发布')) const use = rows.first() check('已选的名录里没有:标签上标出来', await waitFor(page, async () => await use.locator('[data-principal-problem="missing"]').count() === 1)) - const input = use.getByRole('textbox') + // 挂了候选列表(list)的输入框角色是 combobox,不是 textbox + const input = use.locator('input').first() const chips = () => use.locator('li[data-principal]').count() await input.fill('nobody') await input.press('Enter') diff --git a/scripts/check-apps.mjs b/scripts/check-apps.mjs index 0356bae1..7d53ea85 100644 --- a/scripts/check-apps.mjs +++ b/scripts/check-apps.mjs @@ -468,7 +468,7 @@ await section('实例页:状态、进度、待办卡、动作状态', async () await page.locator('[data-view-renderer]').waitFor({ timeout: 15000 }) check('写出发起人', (await page.locator('[data-instance-page]').innerText()).includes('由「张三」发起')) check('实例状态按服务端的说法写(结果未知:等待核实写入结果,不是「等待审批」)', - (await page.locator('[data-component="instance_header"] [data-status]').innerText()).includes('等待核实写入结果') + (await page.locator('[data-component="instance_header"] span[data-status]').first().innerText()).includes('等待核实写入结果') && !(await page.locator('[data-component="instance_header"]').innerText()).includes('等待审批')) check('进度按节点列出', (await page.locator('[data-timeline-step]').count()) === 3) check('结果未知的那一步写「结果未知」,不写「完成」',