fix(B01): retain native card state and restore mode and confirmation styles
This commit is contained in:
1 parent
ddd677bae3
commit
1ed71b63b5
14 files changed
+407
-37
No files matched your search
@@ -0,0 +1,47 @@
|
||||
/** Isolated DOM regression; not a browser layout/pixel or original-app acceptance test. */
|
||||
import assert from 'node:assert/strict'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { createRequire } from 'node:module'
|
||||
import { build } from 'esbuild'
|
||||
const require = createRequire(import.meta.url)
|
||||
const { JSDOM } = require(process.env.YCODE_TEST_DOM_MODULE || process.env.YCODE_JSDOM_PATH || 'jsdom')
|
||||
const output = fs.mkdtempSync(path.resolve('.tmp/mode-chip-dom-'))
|
||||
await build({ entryPoints: ['src/renderer/src/workbuddy/composer/ModeChip.tsx'], bundle: true, platform: 'node', format: 'cjs', jsx: 'automatic', packages: 'external', loader: { '.css': 'empty' }, outfile: path.join(output, 'component.cjs'), logLevel: 'error' })
|
||||
const dom = new JSDOM('<html><head></head><body><div id="root"></div></body></html>', { url: 'http://localhost' })
|
||||
Object.assign(globalThis, { window: dom.window, document: dom.window.document, HTMLElement: dom.window.HTMLElement, IS_REACT_ACT_ENVIRONMENT: true })
|
||||
const React = require('react'), { createRoot } = require('react-dom/client')
|
||||
const { ModeChip } = require(path.join(output, 'component.cjs'))
|
||||
const css = fs.readFileSync('src/renderer/src/workbuddy/composer/mode-chip.css', 'utf8')
|
||||
const style = document.createElement('style'); style.textContent = css; document.head.append(style)
|
||||
const root = createRoot(document.getElementById('root')); let clears = 0, checks = 0
|
||||
const check = (actual, expected, message) => { assert.deepEqual(actual, expected, message); checks++ }
|
||||
const render = async (mode, disabled = false) => React.act(async () => root.render(React.createElement(ModeChip, { mode, disabled, onClear: () => { clears++ } })))
|
||||
for (const mode of ['plan', 'ask']) {
|
||||
await render(mode)
|
||||
const chip = document.querySelector('.yc-mode-chip'), slot = chip.querySelector('.yc-mode-chip__icon-slot'), button = slot.querySelector('button'), icon = slot.querySelector('.yc-mode-chip__mode-icon')
|
||||
check(chip.textContent, mode === 'plan' ? '计划' : '仅问答', 'mode label has no extra X text')
|
||||
check(chip.getAttribute('role'), 'group', 'chip remains a group, not a menu')
|
||||
check(button.type, 'button', 'clear cannot submit composer')
|
||||
check(button.getAttribute('aria-label'), `退出${chip.textContent}模式`, 'accessible exit name')
|
||||
check(icon.parentElement === button.parentElement, true, 'icon and close share one slot')
|
||||
check(dom.window.getComputedStyle(slot).display, 'grid', 'shared grid slot')
|
||||
check(dom.window.getComputedStyle(button).gridArea, '1 / 1', 'button occupies original icon cell')
|
||||
check(dom.window.getComputedStyle(icon).gridArea, '1 / 1', 'mode occupies same original cell')
|
||||
check(dom.window.getComputedStyle(button).position, 'static', 'no floating absolute close')
|
||||
check(dom.window.getComputedStyle(chip).backgroundColor, 'rgba(0, 0, 0, 0)', 'transparent background')
|
||||
await React.act(async () => button.focus())
|
||||
check(document.activeElement === button, true, 'native button receives keyboard focus')
|
||||
const before = clears
|
||||
await React.act(async () => button.click())
|
||||
check(clears, before + 1, 'activation calls existing host clear exactly once')
|
||||
await render(mode, true)
|
||||
check(document.querySelector('button'), null, 'disabled mode exposes no clear action')
|
||||
check(document.querySelector('.yc-mode-chip').getAttribute('aria-disabled'), 'true', 'disabled state is announced')
|
||||
check(document.querySelector('.yc-mode-chip').tabIndex, -1, 'disabled mode not in keyboard tab order')
|
||||
}
|
||||
await render('craft'); check(document.querySelector('.yc-mode-chip'), null, 'craft stays hidden')
|
||||
// CSS contracts complement DOM checks; test-mode-chip-native.mjs is an unexecuted native hover/focus/layout probe.
|
||||
for (const contract of ['border-radius:var(--yc-radius-full)', 'color:var(--cr-text-secondary)', ':hover .yc-mode-chip__mode-icon', ':focus-within .yc-mode-chip__mode-icon', ':hover .yc-mode-chip__clear', ':focus-within .yc-mode-chip__clear']) check(css.includes(contract), true, contract)
|
||||
await React.act(async () => root.unmount()); dom.window.close()
|
||||
console.log(JSON.stringify({ checks, passed: true, scope: 'Isolated React DOM and CSS contracts; no native keyboard/layout/pixel acceptance' }))
|
||||
Reference in new issue
Block a user