mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 00:21:58 +00:00
完整关口收尾:端点认证头重名只标后加的那一行(原有的那行本身没错);check-apps 实例状态只认状态标签本身(标签里嵌着带 data-status 的图标);check-app-editor 选人输入框挂了候选列表,角色是 combobox,按输入框定位
This commit is contained in:
@@ -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<EndpointEnv> | null) =>
|
||||
setEnvs((cur) => {
|
||||
@@ -259,7 +260,7 @@ function EnvEditor({ env, value, onChange, headers, onHeaders }: {
|
||||
<div>
|
||||
<div className="mb-1 text-2xs text-faint">{T.headers} · {T.headersHint}</div>
|
||||
{headers.map((r, i) => {
|
||||
const problem = headerProblem(r, headers)
|
||||
const problem = headerProblem(r, headers, i)
|
||||
const errorId = `endpoint-${env}-header-${i}-error`
|
||||
return (
|
||||
<div key={i} className="mb-1" data-endpoint-header={i}>
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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('结果未知的那一步写「结果未知」,不写「完成」',
|
||||
|
||||
Reference in New Issue
Block a user