mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 07:11:57 +00:00
数据目录起草(前端):模型拿不准、留空的列(中文名和含义都没给)单独写出来,不算没写全、表照样是已完成。起草对话框逐表写「12 列模型拿不准、留空了」,列名悬停看得到、也可以展开(最多 5 个,没列全写一共几列);结束后写合计「共 13 列模型拿不准、留空了(2 张表)」和办法——在起草要求里补充缩写和术语的含义,再重新起草这几张表,已有的内容不会丢;「重新起草这 N 张表」回到设置,范围就是这几张、勾着用模型、焦点在起草要求,补完再开始;结束后默认列出的表连同有留空列的(「只看未写全、有留空列的表」);关着对话框时结束的提示也接着写留空的列;设置阶段的「上一次起草」都写完了、只是有留空列的也提,写明几列。清单上上次起草有留空列的表一行淡色轻提示(不是失败标记,和失败、部分完成的标记分开;还在起草的那一次不算「上次」);表详情顶部同样提示(只有留空列时是提示、不是失败;部分完成又有留空列的并在一条里),给「重新起草这张表」和「补充起草要求」(打开起草设置,范围只有这张表)。类型加 CatalogDraftTask.blank_columns、blank_sample,CatalogDraftJob.blank_columns,last_draft.blank_columns(老服务端没有,按 0)。check-catalog 新加一节覆盖逐表与汇总、展开列名、默认列表、清单轻提示(颜色同次要信息、不是警告色)、进行中不算「上次」、回到设置重新起草(先存起草要求再建任务)、结束提示、表详情的两个按钮,窄屏展开列名一并量;check-all 里数据目录的耗时按实测改成 130 秒
This commit is contained in:
@@ -97,7 +97,7 @@ const ORDER = [
|
||||
const ESTIMATE = {
|
||||
challenge: 30,
|
||||
stream: 173, chat: 160, studio: 149, manage: 145, runs: 112, publish: 92, shell: 87,
|
||||
evidence: 91, versions: 60, catalog: 110, 'ui-kit': 70, ui: 61, guards: 8, 'canvas-layout': 2, copy: 2, tokens: 1, trace: 1, decode: 1,
|
||||
evidence: 91, versions: 60, catalog: 130, 'ui-kit': 70, ui: 61, guards: 8, 'canvas-layout': 2, copy: 2, tokens: 1, trace: 1, decode: 1,
|
||||
// 占位,换成真检查时按实测改
|
||||
schedules: 60, compare: 45, verify: 71, inquiry: 60, bundle: 16, whatif: 33, 'report-export': 30,
|
||||
}
|
||||
|
||||
+168
-7
@@ -429,7 +429,7 @@ const PART_COLUMNS = 40
|
||||
* 建一个排队的任务:表结构里没有的表照样建进任务、记 skipped。重试建的记着原任务(retry_of,界面不用)。
|
||||
* 超过 40 列的宽表均匀分段:列分段数 = ceil(列数 / 40),段进度是「表级一段 + 列分段」。
|
||||
* 用模型的任务记着当前每段最多几列(part_columns,额度用完、超时多了服务端会减半)、调用接连没写出来时的提醒(notice),
|
||||
* 用量里另记超时和没写出来的调用次数
|
||||
* 用量里另记超时和没写出来的调用次数;逐表记模型拿不准、留空的列数和前几个列名(blank_columns、blank_sample)
|
||||
*/
|
||||
function newJob(state, src, { tables, use_model, note = null, retry_of = null }) {
|
||||
const id = `check-job-${++state.jobSeq}`
|
||||
@@ -439,7 +439,7 @@ function newJob(state, src, { tables, use_model, note = null, retry_of = null })
|
||||
return {
|
||||
table_name: name, status: t ? 'pending' : 'skipped', columns: cols,
|
||||
parts_total: t && use_model ? (cols > PART_COLUMNS ? 1 + Math.ceil(cols / PART_COLUMNS) : 1) : null, parts_done: 0,
|
||||
added: 0, updated: 0, removed: 0, version: t?.version ?? 0, model_items: null,
|
||||
added: 0, updated: 0, removed: 0, version: t?.version ?? 0, model_items: null, blank_columns: 0, blank_sample: [],
|
||||
error: t ? null : `表结构里没有 ${name},请先重新探查结构`, model_error: null,
|
||||
started_at: null, finished_at: t ? null : isoNow(),
|
||||
}
|
||||
@@ -454,14 +454,14 @@ function newJob(state, src, { tables, use_model, note = null, retry_of = null })
|
||||
return job
|
||||
}
|
||||
|
||||
/** 接口返回的形状:计数、合计由逐表算出来 */
|
||||
/** 接口返回的形状:计数、合计(含留空的列数)由逐表算出来 */
|
||||
function jobOut(job) {
|
||||
const counts = { pending: 0, running: 0, ok: 0, partial: 0, failed: 0, skipped: 0, cancelled: 0 }
|
||||
for (const t of job.tasks) counts[t.status]++
|
||||
const sum = (k) => job.tasks.reduce((n, t) => n + t[k], 0)
|
||||
const { stopAsked, ...rest } = job
|
||||
return clone({ ...rest, total: job.tasks.length, done: job.tasks.filter((t) => TASK_END.has(t.status)).length, counts,
|
||||
added: sum('added'), updated: sum('updated'), removed: sum('removed') })
|
||||
added: sum('added'), updated: sum('updated'), removed: sum('removed'), blank_columns: sum('blank_columns') })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,7 +527,10 @@ function lastDraftOf(state, src, name) {
|
||||
for (const job of [...state.jobs].reverse()) {
|
||||
if (job.source_id !== src) continue
|
||||
const t = job.tasks.find((x) => x.table_name === name)
|
||||
if (t) return { status: t.status, job_id: job.id, finished_at: t.finished_at, error: t.error, model_error: t.model_error }
|
||||
if (t) {
|
||||
return { status: t.status, job_id: job.id, finished_at: t.finished_at, error: t.error, model_error: t.model_error,
|
||||
blank_columns: t.blank_columns }
|
||||
}
|
||||
}
|
||||
return state.tables[src]?.find((x) => x.name === name)?.lastDraft ?? null
|
||||
}
|
||||
@@ -688,6 +691,10 @@ const WIDE_ERR = '这张表 50 列,分 3 段起草,第 3 段(promo_attr_19
|
||||
const CALL_ERR = '调用模型出错:服务暂时不可用(已重试 2 次)'
|
||||
/** 调用接连没写出来时服务端给的提醒(虚构的一句,照约定写明次数、原因和办法) */
|
||||
const DRAFT_NOTICE = '最近 6 次调用有 4 次没写出来(3 次超时、1 次额度用完)。建议在「设置 → 偏好设置」的「起草模型」换一个模型、缩小起草范围,或者停止这次起草'
|
||||
/** 宽表里模型拿不准、留空的列(服务端最多给 5 个列名) */
|
||||
const BLANK_SAMPLE = ['promo_attr_31', 'promo_attr_32', 'promo_attr_33', 'promo_attr_34', 'promo_attr_35']
|
||||
/** 补上缩写含义的起草要求(虚构) */
|
||||
const GUIDANCE_ABBR = `${S1_GUIDANCE}。promo_attr 开头的列是促销活动的附加属性,按列名后面的编号区分`
|
||||
const detail = (page) => page.locator('[data-catalog-detail]')
|
||||
const version = async (page) => Number(await detail(page).getAttribute('data-version'))
|
||||
const panel = (page) => page.locator('[data-item-panel]')
|
||||
@@ -1379,6 +1386,158 @@ await section('数据目录 · 起草:接连没写出来的提醒、超时与
|
||||
await close()
|
||||
})
|
||||
|
||||
await section('数据目录 · 起草:模型拿不准、留空的列', async () => {
|
||||
const state = freshState()
|
||||
// 不在这次起草里的一张表:上一次起草部分完成,又有留空的列
|
||||
state.tables[S1].find((t) => t.name === 'channels').lastDraft = {
|
||||
status: 'partial', job_id: 'check-job-old', finished_at: T0, error: null, model_error: CALL_ERR, blank_columns: 4,
|
||||
}
|
||||
const { page, sent, errors, natives, close } = await open(`/data/catalog/${S1}`, { handlers: catalogHandlers(state) })
|
||||
await page.locator('[data-catalog-row]').first().waitFor()
|
||||
check('开始起草(闸机到会员 3 张,用模型)', await startDraft(page, { select: ['gates', 'members'], model: true }))
|
||||
const job = state.jobs.at(-1)
|
||||
|
||||
// 留空的列:模型列出了、中文名和含义都没给。表的状态不因此变。闸机表写完了;宽表还在起草,已经有几列留空
|
||||
settle(state, job, 'gates', { added: 2, model_items: 3, blank_columns: 1, blank_sample: ['gate_code'] })
|
||||
settle(state, job, 'store_sales', { status: 'running', parts_done: 2, blank_columns: 5, blank_sample: BLANK_SAMPLE })
|
||||
const blankOf = (n) => draftBox(page).locator(`[data-draft-task="${n}"] [data-draft-task-blank]`)
|
||||
const rowBlank = (n) => page.locator(`[data-catalog-row="${n}"] [data-row-blank]`)
|
||||
check('起草中:逐表跟着写留空的列;清单上写完的表才提示「上次起草」,还在起草的不提示',
|
||||
await until(async () => (await blankOf('store_sales').innerText({ timeout: 500 }).catch(() => '')).includes('5 列模型拿不准、留空了')
|
||||
&& (await rowBlank('gates').count()) === 1)
|
||||
&& (await rowBlank('store_sales').count()) === 0 && (await page.locator('[data-catalog-row="store_sales"] [data-row-last-draft]').count()) === 0,
|
||||
`${await draftText(page, '[data-draft-task="store_sales"]')} · ${await rowBlank('gates').count()} · ${await rowBlank('store_sales').count()}`)
|
||||
settle(state, job, 'store_sales', { added: 30, model_items: 38, blank_columns: 12, blank_sample: BLANK_SAMPLE })
|
||||
check('逐表:写完的宽表写「12 列模型拿不准、留空了」,状态照旧是「已完成」',
|
||||
await until(async () => (await blankOf('store_sales').innerText({ timeout: 500 }).catch(() => '')).includes('12 列模型拿不准、留空了'))
|
||||
&& (await draftText(page, '[data-draft-task="store_sales"] [data-draft-task-status]')) === '已完成',
|
||||
await draftText(page, '[data-draft-task="store_sales"]'))
|
||||
const sample = blankOf('store_sales').locator('[data-draft-task-blank-sample]')
|
||||
check('……悬停看得到是哪几列', ((await blankOf('store_sales').locator('summary').getAttribute('title')) ?? '').includes(BLANK_SAMPLE.join('、')),
|
||||
await blankOf('store_sales').locator('summary').getAttribute('title').catch(() => ''))
|
||||
check('……列名默认收起', !(await sample.isVisible()))
|
||||
await blankOf('store_sales').locator('summary').click()
|
||||
check('……展开写出列名,列不全时写一共几列', await until(async () => sample.isVisible())
|
||||
&& (await draftText(page, '[data-draft-task="store_sales"] [data-draft-task-blank-sample]')) === `留空的列:${BLANK_SAMPLE.join('、')} 等 12 列`,
|
||||
await draftText(page, '[data-draft-task="store_sales"] [data-draft-task-blank-sample]'))
|
||||
settle(state, job, 'members', { added: 3, model_items: 3 })
|
||||
finishJob(job)
|
||||
check('结束:标题照旧「起草完成」(留空的列不算没写全),不给「只重试失败的表」',
|
||||
await until(async () => (await draftPhase(page)) === 'done') && (await draftText(page, '[data-draft-title]')) === '起草完成'
|
||||
&& await page.locator('[data-draft-retry]').count() === 0, await draftText(page, '[data-draft-title]'))
|
||||
const blankSum = await draftText(page, '[data-draft-blank-summary]')
|
||||
check('……汇总写合计:共 13 列模型拿不准、留空了(2 张表)', blankSum.includes('共 13 列模型拿不准、留空了(2 张表)'), blankSum)
|
||||
check('……并给出办法:在起草要求里补充缩写和术语的含义,再重新起草这几张表,已有的内容不会丢',
|
||||
blankSum.includes('在起草要求里补充缩写和术语的含义') && blankSum.includes('重新起草这几张表') && blankSum.includes('已有的内容不会丢'), blankSum)
|
||||
const shown = await draftBox(page).locator('[data-draft-task]').evaluateAll((els) => els.map((e) => e.getAttribute('data-draft-task')))
|
||||
check('……逐表默认只列有留空列的 2 张,没有留空列的那张不写,可以显示全部', shown.join(',') === 'gates,store_sales'
|
||||
&& await draftBox(page).locator('[data-draft-show-all]').count() === 1, shown.join(','))
|
||||
await draftBox(page).locator('[data-draft-show-all]').click()
|
||||
check('……显示全部:没有留空列的表不写留空', (await draftBox(page).locator('[data-draft-task]').count()) === 3 && await blankOf('members').count() === 0)
|
||||
await shot(page, 'catalog-draft-blank')
|
||||
|
||||
// 清单:有留空列的表显示轻提示,不是失败标记
|
||||
check('清单:有留空列的表显示轻提示「上次起草有 12 列模型拿不准、留空了」',
|
||||
await until(async () => (await rowBlank('store_sales').innerText({ timeout: 500 }).catch(() => '')).includes('上次起草有 12 列模型拿不准、留空了')),
|
||||
await rowBlank('store_sales').innerText({ timeout: 500 }).catch(() => ''))
|
||||
const colors = await page.evaluate(() => {
|
||||
const color = (q) => { const el = document.querySelector(q); return el ? getComputedStyle(el).color : null }
|
||||
return { blank: color('[data-catalog-row="store_sales"] [data-row-blank]'), faint: color('[data-catalog-row="store_sales"] [data-row-usage]'),
|
||||
partial: color('[data-catalog-row="channels"] [data-row-last-draft]') }
|
||||
})
|
||||
check('……不是失败标记:不写「上次起草失败 / 部分完成」,用次要信息的淡色,不用警告色', await page.locator('[data-catalog-row="store_sales"] [data-row-last-draft]').count() === 0
|
||||
&& !!colors.blank && colors.blank === colors.faint && colors.blank !== colors.partial, JSON.stringify(colors))
|
||||
check('……没有留空列的表不提示', await rowBlank('members').count() === 0)
|
||||
check('……部分完成又有留空列的表:失败标记和留空提示都在', (await page.locator('[data-catalog-row="channels"] [data-row-last-draft="partial"]').count()) === 1
|
||||
&& (await rowBlank('channels').innerText().catch(() => '')).includes('上次起草有 4 列模型拿不准、留空了'))
|
||||
|
||||
// 「重新起草这 2 张表」:回到设置,范围就是这 2 张、勾着用模型,焦点在起草要求;补上缩写的含义再开始
|
||||
await draftBox(page).locator('[data-draft-blank-redraft]').click()
|
||||
check('「重新起草这 2 张表」:回到设置,范围是有留空列的这 2 张,勾着用模型,焦点在起草要求',
|
||||
await until(async () => (await draftPhase(page)) === 'setup')
|
||||
&& await draftBox(page).locator('[data-draft-scope="preset"] input').isChecked()
|
||||
&& (await draftText(page, '[data-draft-scope="preset"]')).includes('有留空列的 2 张表')
|
||||
&& await draftBox(page).locator('[data-draft-model] input').isChecked()
|
||||
&& await until(async () => page.evaluate(() => document.activeElement?.id === 'catalog-draft-guidance')),
|
||||
`${await draftText(page, '[data-draft-scope="preset"]')} · ${await page.evaluate(() => document.activeElement?.id ?? '')}`)
|
||||
check('……起草按钮写「起草 2 张表」', (await page.locator('[data-draft-start]').innerText()).includes('起草 2 张表'))
|
||||
await draftBox(page).locator('[data-draft-guidance] textarea').fill(GUIDANCE_ABBR)
|
||||
await page.locator('[data-draft-start]').click()
|
||||
check('……先存起草要求,再建只含这 2 张表、用模型的任务', await until(async () => (await draftPhase(page)) === 'running')
|
||||
&& JSON.stringify(lastBody(sent, /catalog\/guidance$/)) === JSON.stringify({ guidance: GUIDANCE_ABBR })
|
||||
&& JSON.stringify(lastBody(sent, /draft-jobs$/)) === JSON.stringify({ tables: ['gates', 'store_sales'], use_model: true }),
|
||||
JSON.stringify(lastBody(sent, /draft-jobs$/)))
|
||||
// 这一回宽表仍有几列拿不准(已有的内容不丢由服务端保证)。关着对话框时结束:提示里也写留空的列
|
||||
const again = state.jobs.at(-1)
|
||||
await page.locator('[data-draft-hide]').click()
|
||||
await until(async () => (await draftBox(page).count()) === 0)
|
||||
settle(state, again, 'gates', { model_items: 3 })
|
||||
settle(state, again, 'store_sales', { updated: 5, model_items: 40, blank_columns: 7, blank_sample: BLANK_SAMPLE })
|
||||
finishJob(again)
|
||||
const toastBox = page.locator('[data-toast]').filter({ hasText: '起草完成' })
|
||||
check('关着对话框时结束:提示里写「7 列模型拿不准、留空了」', await until(async () => (await toastBox.count()) > 0)
|
||||
&& (await toastBox.first().innerText()).includes('7 列模型拿不准、留空了'),
|
||||
await page.locator('[data-toast]').allInnerTexts().then((t) => t.join(' | ')).catch(() => ''))
|
||||
await toastBox.getByRole('button', { name: '查看结果' }).click()
|
||||
check('……点「查看结果」:汇总写合计', await until(async () => (await draftText(page, '[data-draft-blank-summary]')).includes('共 7 列模型拿不准、留空了(1 张表)')),
|
||||
await draftText(page, '[data-draft-blank-summary]'))
|
||||
await page.locator('[data-draft-close]').click()
|
||||
// 再打开起草:设置阶段写明上一次有留空的列,可以点开
|
||||
await page.locator('[data-catalog-draft]').first().click()
|
||||
await draftBox(page).waitFor()
|
||||
check('再打开起草:设置阶段写明上一次起草有 7 列模型拿不准、留空了,可以点开', await until(async () => (await draftText(page, '[data-draft-last]')).includes('7 列模型拿不准、留空了'))
|
||||
&& await draftBox(page).locator('[data-draft-last-open]').count() === 1, await draftText(page, '[data-draft-last]'))
|
||||
await page.keyboard.press('Escape')
|
||||
await until(async () => (await draftBox(page).count()) === 0)
|
||||
|
||||
// 表详情:顶部同样提示(不是失败),给「重新起草这张表」和「补充起草要求」
|
||||
await page.locator('[data-catalog-row="store_sales"] [data-catalog-open-row]').click()
|
||||
const tip = page.locator('[data-catalog-last-draft]')
|
||||
check('表详情:顶部写「上次起草有 7 列模型拿不准、留空了」,是提示(不是失败)',
|
||||
await until(async () => (await tip.innerText({ timeout: 500 }).catch(() => '')).includes('上次起草有 7 列模型拿不准、留空了'))
|
||||
&& (await tip.getAttribute('data-notice')) === 'info', await tip.innerText({ timeout: 500 }).catch(() => ''))
|
||||
check('……写明办法:补充起草要求再重新起草,已有的内容不会丢;给「重新起草这张表」', (await tip.innerText()).includes('已有的内容不会丢')
|
||||
&& await tip.locator('[data-catalog-redraft]').count() === 1, await tip.innerText())
|
||||
await shot(page, 'catalog-blank-detail')
|
||||
const jobsBefore = count(sent, /^POST .*draft-jobs$/)
|
||||
await tip.locator('[data-catalog-draft-guidance]').click()
|
||||
check('「补充起草要求」:打开起草设置,范围只有这张表,勾着用模型,焦点在起草要求',
|
||||
await until(async () => (await draftPhase(page)) === 'setup')
|
||||
&& await draftBox(page).locator('[data-draft-scope="preset"] input').isChecked()
|
||||
&& (await draftText(page, '[data-draft-scope="preset"]')).includes('store_sales')
|
||||
&& await draftBox(page).locator('[data-draft-model] input').isChecked()
|
||||
&& (await page.locator('[data-draft-start]').innerText()).includes('起草 1 张表')
|
||||
&& await until(async () => page.evaluate(() => document.activeElement?.id === 'catalog-draft-guidance')),
|
||||
`${await draftText(page, '[data-draft-scope="preset"]')} · ${await page.evaluate(() => document.activeElement?.id ?? '')}`)
|
||||
await page.keyboard.press('Escape')
|
||||
check('……没改就关掉:不建任务', await until(async () => (await draftBox(page).count()) === 0) && count(sent, /^POST .*draft-jobs$/) === jobsBefore)
|
||||
await tip.locator('[data-catalog-redraft]').click()
|
||||
check('「重新起草这张表」:建只含这张表、用模型的任务', await until(async () => count(sent, /^POST .*draft-jobs$/) === jobsBefore + 1)
|
||||
&& JSON.stringify(lastBody(sent, /draft-jobs$/)) === JSON.stringify({ tables: ['store_sales'], use_model: true }),
|
||||
JSON.stringify(lastBody(sent, /draft-jobs$/)))
|
||||
const third = state.jobs.at(-1)
|
||||
await until(async () => (await draftPhase(page)) === 'running')
|
||||
settle(state, third, 'store_sales', { model_items: 40 })
|
||||
finishJob(third)
|
||||
await until(async () => (await draftPhase(page)) === 'done')
|
||||
await page.locator('[data-draft-close]').click()
|
||||
check('……这回没有留空的列:清单的轻提示和详情的提示都收起', await until(async () => (await rowBlank('store_sales').count()) === 0 && (await tip.count()) === 0))
|
||||
|
||||
// 部分完成又有留空列的表:一条说明里写原因和留空的列,只有一个「重新起草这张表」
|
||||
await page.locator('[data-catalog-row="channels"] [data-catalog-open-row]').click()
|
||||
check('部分完成又有留空列的表:详情里一条说明写原因和留空的列,只有一个「重新起草这张表」',
|
||||
await until(async () => (await tip.innerText({ timeout: 500 }).catch(() => '')).includes('上次起草部分完成'))
|
||||
&& (await tip.innerText()).includes(CALL_ERR) && (await tip.innerText()).includes('4 列模型拿不准、留空了')
|
||||
&& (await tip.getAttribute('data-notice')) === 'warn' && await tip.locator('[data-catalog-redraft]').count() === 1,
|
||||
await tip.innerText({ timeout: 500 }).catch(() => ''))
|
||||
await cleanCopy(page, '留空列的提示')
|
||||
check('只发过起草任务相关的写请求', writes(sent, /./).every((s) => /catalog\/(draft-jobs|guidance)/.test(s.key)),
|
||||
JSON.stringify(writes(sent, /./).map((s) => s.key)))
|
||||
check('没有原生对话框', natives.length === 0, natives.join(' | '))
|
||||
check('没有运行时报错', errors.length === 0, errors[0] ?? '')
|
||||
await close()
|
||||
})
|
||||
|
||||
await section('数据目录 · 表详情与单项审阅', async () => {
|
||||
const state = freshState()
|
||||
const { page, sent, errors, natives, close } = await open(`/data/catalog/${S1}`, { handlers: catalogHandlers(state) })
|
||||
@@ -2469,14 +2628,16 @@ await section('数据目录 · 窄屏', async () => {
|
||||
await until(async () => (await draftPhase(page)) === 'running')
|
||||
const narrowJob = state.jobs.at(-1)
|
||||
settle(state, narrowJob, 'visits', { added: 2 })
|
||||
settle(state, narrowJob, 'store_sales', { status: 'partial', parts_done: 2, added: 4, model_error: WIDE_ERR })
|
||||
settle(state, narrowJob, 'store_sales', { status: 'partial', parts_done: 2, added: 4, model_error: WIDE_ERR, blank_columns: 12, blank_sample: BLANK_SAMPLE })
|
||||
// 接连没写出来的提醒、超时和没写出来的次数、段缩小的说明也都在
|
||||
Object.assign(narrowJob.usage, { timeouts: 3, failed_calls: 4 })
|
||||
Object.assign(narrowJob, { part_columns: 20, notice: DRAFT_NOTICE })
|
||||
await until(async () => (await draftText(page, '[data-draft-task="store_sales"] [data-draft-task-reason]')).includes('第 3 段')
|
||||
&& (await draftText(page, '[data-draft-notice]')) === DRAFT_NOTICE)
|
||||
await draftBox(page).locator('[data-draft-task="store_sales"] [data-draft-task-blank] summary').click().catch(() => {})
|
||||
const runFit = await draftFits()
|
||||
check('……起草进行中:段进度、长原因、提醒都折行,弹窗不横向滚动', runFit.ok, JSON.stringify(runFit))
|
||||
check('……起草进行中:段进度、长原因、提醒、展开的留空列名都折行,弹窗不横向滚动', runFit.ok
|
||||
&& await draftBox(page).locator('[data-draft-task-blank-sample]').isVisible().catch(() => false), JSON.stringify(runFit))
|
||||
await shot(page, 'catalog-narrow-draft')
|
||||
await page.locator('[data-draft-hide]').click()
|
||||
await until(async () => (await page.locator('[data-catalog-draft-progress]').count()) === 1)
|
||||
|
||||
Reference in New Issue
Block a user