63 lines
4.8 KiB
TypeScript
63 lines
4.8 KiB
TypeScript
/** Real Chromium fixture, isolated callbacks only: no IPC, sessions, models, or original app. */
|
|
import React from 'react'
|
|
import { createRoot } from 'react-dom/client'
|
|
import { flushSync } from 'react-dom'
|
|
import '../src/renderer/src/workbuddy/typography/tokens.css'
|
|
import '../src/renderer/src/styles/tokens.css'
|
|
import '../src/renderer/src/ui/tokens.css'
|
|
import '../src/renderer/src/styles/app.css'
|
|
import '../src/renderer/src/styles/sidebar.css'
|
|
import '../src/renderer/src/workbuddy/conversation/source-styles.css'
|
|
import '../src/renderer/src/workbuddy/conversation/source-adapters.css'
|
|
import '../src/renderer/src/components/workspace-source.css'
|
|
import '../src/renderer/src/components/source-select/source-select-recovered.css'
|
|
import '../src/renderer/src/components/source-select/source-select.css'
|
|
import { TaskPopconfirm } from '../src/renderer/src/components/TaskPopconfirm'
|
|
const root = createRoot(document.getElementById('root')!)
|
|
const anchor = document.getElementById('anchor')!
|
|
const results: unknown[] = []
|
|
const pause = () => new Promise(resolve => setTimeout(resolve, 200))
|
|
function check(actual: unknown, expected: unknown, label: string) {
|
|
results.push({label, actual, expected})
|
|
if (JSON.stringify(actual) !== JSON.stringify(expected)) throw Error(label + ': ' + JSON.stringify(actual))
|
|
}
|
|
const button = (name: string) => document.querySelector<HTMLButtonElement>('.task-popconfirm__' + name)!
|
|
async function run() {
|
|
for (const theme of ['light', 'dark']) for (const kind of ['archive', 'delete'] as const) for (const running of (kind === 'delete' ? [false, true] : [false])) {
|
|
document.documentElement.dataset.theme = theme
|
|
let calls = 0, closes = 0, resolve!: () => void, reject!: (cause: Error) => void
|
|
const close = () => { closes++; flushSync(() => root.render(null)) }
|
|
flushSync(() => root.render(<TaskPopconfirm kind={kind} running={running} anchor={anchor} onClose={close} onConfirm={() => { calls++; return new Promise<void>((yes, no) => { resolve = yes; reject = no }) }} />))
|
|
await pause()
|
|
const label = `${theme}/${kind}/${running}`
|
|
const dark = theme === 'dark'
|
|
const confirm = button('confirm'), cancel = button('cancel')
|
|
for (const node of [confirm, cancel]) {
|
|
const s = getComputedStyle(node)
|
|
check([s.minWidth, s.paddingLeft, s.paddingRight, s.height, s.borderRadius, s.fontSize], ['66px', '19px', '19px', '28px', '6px', '12px'], label + ' geometry')
|
|
}
|
|
const primary = getComputedStyle(confirm), secondary = getComputedStyle(cancel)
|
|
check([primary.backgroundColor, primary.color], kind === 'delete' ? [dark ? 'rgb(175, 25, 26)' : 'rgb(232, 92, 92)', 'rgb(255, 255, 255)'] : dark ? ['rgba(255, 255, 255, 0.9)', 'rgba(0, 0, 0, 0.9)'] : ['rgba(0, 0, 0, 0.9)', 'rgb(255, 255, 255)'], label + ' primary/danger colors')
|
|
check([secondary.backgroundColor, secondary.borderTopWidth, secondary.borderTopStyle, secondary.borderTopColor], [dark ? 'rgb(38, 38, 38)' : 'rgb(255, 255, 255)', '1px', 'solid', dark ? 'rgb(61, 61, 61)' : 'rgb(222, 222, 222)'], label + ' secondary colors/border')
|
|
const popup = document.querySelector<HTMLElement>('.task-popconfirm')!
|
|
check([getComputedStyle(popup).width, getComputedStyle(popup).borderRadius, getComputedStyle(document.querySelector('.task-popconfirm__title')!).fontWeight], ['240px', '16px', '600'], label + ' shell')
|
|
check(getComputedStyle(popup).backgroundColor, dark ? 'rgb(36, 36, 36)' : 'rgb(255, 255, 255)', label + ' shell background')
|
|
check(document.activeElement === confirm, true, label + ' initial focus')
|
|
if (running) check(confirm.textContent, '停止并删除', label + ' running delete semantic')
|
|
confirm.click(); confirm.click(); await pause()
|
|
check([calls, confirm.disabled, cancel.disabled, confirm.textContent], [1, true, true, '处理中…'], label + ' busy prevents duplicates')
|
|
document.dispatchEvent(new KeyboardEvent('keydown', {key:'Escape', bubbles:true})); cancel.click()
|
|
check(closes, 0, label + ' busy cannot dismiss')
|
|
if (kind === 'delete') check(getComputedStyle(confirm).backgroundColor, dark ? 'rgb(128, 56, 56)' : 'rgb(245, 185, 185)', label + ' danger busy background')
|
|
reject(new Error('fixture failure')); await pause()
|
|
check(document.querySelector('[role="alert"]')?.textContent, 'fixture failure', label + ' failure retained')
|
|
check(confirm.disabled, false, label + ' retry enabled')
|
|
confirm.click(); await pause(); resolve(); await pause()
|
|
check([calls, closes, !!document.querySelector('.task-popconfirm')], [2, 1, false], label + ' retry success')
|
|
}
|
|
}
|
|
run().then(() => finish(true), error => finish(false, String(error)))
|
|
function finish(pass: boolean, error?: string) {
|
|
const output = document.createElement('pre'); output.id = 'result'; output.textContent = JSON.stringify({pass, error, results}); document.body.append(output)
|
|
}
|