news 2026/9/17 18:59:45

Slate v2 Lexical 测试收割处理指南:从 1996 条上游测试到可执行的测试处理台账

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Slate v2 Lexical 测试收割处理指南:从 1996 条上游测试到可执行的测试处理台账

Slate v2 Lexical 测试收割处理指南:从 1996 条上游测试到可执行的测试处理台账

【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate

本篇技术指南围绕 Slate v2 Lexical Harvest Test Processing Ralplan 展开,讲解如何将 Lexical 编辑器的测试收割(harvest)成果系统化地处理为 Slate v2 的测试处理计划。读者将掌握一套可复用的方法论:以处理台账(processing ledger)为骨架,以「行为家族分组 + 证明类型分离 + 保守 Issue 声明」为纪律,把 271 条上游测试行逐条路由为 already-applied、covered、refactor-existing、create-new、defer、reject 六类状态,并生成可直接交给执行端的小粒度实施切片。

背景:Lexical 测试收割完成了什么

Slate v2 项目将 Lexical 视为测试语料库(test corpus)而非架构捐赠者。收割阶段(harvest)对 Lexical 仓库的全部测试文件做了系统盘点,产出三类核心工件:

工件关键数据位置
收割报告收割完成,评分0.93inventory.md
全量清单271 条清单行、196 条可运行行、124 条 portable、13 条 portable-mixed、33 条 product-shell、12 条 harness、89 条 skip、0 条 uncertaininventory.md
测试名索引137 个 portable/portable-mixed 可运行文件、1996 条 test/describe/it 名称test-index.md

从 inventory.md 记录的清单命令可以看出,收割按测试路径特征(__tests__testspece2eplaywrightfixtures等)与排除规则(distbuildnode_modules__snapshots__)过滤,最终形成全量分类。

一个关键的背景约束是:之前的选择性实施车道(selected apply lane)只覆盖了 IME/history、剪贴板语料、浏览器传输、表格包含(containment)四个领域,其余全部处于 backlog。因此「Lexical 收割已完成」不等于「Lexical 测试已处理完毕」——这正是本计划诞生的原因。

核心判断:不要逐条复制 Lexical 测试

计划的首要结论非常明确:

正确的下一步不是「复制全部 Lexical 测试」,那会既嘈杂又错误。正确做法是:把每一条 Lexical 源行处理进一份 Slate owner 台账,然后让执行端(ralph)只实现那些作为可移植(portable)Slate 行为存活下来的行。

原因是收割数据的广度足以淹没实现:271 条清单行中,大量行编码的是 Lexical 内部实现(节点类、命令注册表、Composer/插件身份、私有 MIME 格式、Playground 产品外壳)、应用外壳或重复行为,逐条搬运只会让 Slate 更难维护。

决策原则

  1. 保留可移植行为,不保留 Lexical 架构:只搬运不变量(invariant),不搬运节点类生命周期、命令分发或框架外壳。
  2. 保持 Slate 原始(raw)且不预设立场:不把 Lexical 的整表选择模型、autolink 策略等悄悄塞进核心。
  3. 证明必须匹配行为类型:浏览器传输用浏览器行证明,模型不变量用单元行证明,真机移动端声明必须用真机行证明。
  4. DRY 胜过测试数量虚荣:已有 owner 时优先加强现有测试,而不是新建重复测试。
  5. Issue 声明需要精确复现证明,而不是「感觉」

选项评估

选项结论理由
逐条移植全部 Lexical 测试拒绝大多数行编码 Lexical 内部、应用外壳或重复行为,会让 Slate 更难维护
认为选择性实施车道已经足够拒绝用户明确要求处理全部 Lexical 测试,报告仍将更广泛的行标记为 backlog
先构建源行处理台账采纳台账覆盖所有行、让 skip 保持诚实、给执行端可运行的小切片
现在就强行关闭真机/表格/yjs拒绝当前证明 owner 不支持这些声明,缺设备/模型/协作车道

边界声明(Non-goals)

计划明确划出不做的事:不移植 Lexical 节点类、命令注册表、Composer/插件身份、私有 MIME 格式、Playground 产品外壳、ESLint 工具链、发布夹具、框架外壳行为;不用桌面 Playwright 移动视口冒充真机 IME 证明;不把原始 Slate 悄悄改造成 Lexical 的整表选择模型;不创建 1996 个一次性测试。

处理台账:六类状态与文件级路由

计划的核心产出是 slate-processing-ledger.md,它以文件粒度为每个 portable 与 portable-mixed 源文件分配处理状态:

状态含义
already-applied选择性实施车道已添加或加强对应的 Slate v2 证明
covered当前 Slate v2 已有足够好的证明行,除非后续审计发现漂移
refactor-existing加强、拆分、重命名或拓宽现有 Slate 测试;优先于重复新建
create-new新增一条 Slate v2 单元/浏览器行
defer行为有效,但需要真机设备、yjs 浏览器、表格模型或后续接受的 owner
reject不是可移植的原始 Slate 行为目标

台账的最终账目覆盖了全部 137 个 portable/portable-mixed 源文件:5个 already-applied、1个 covered、12个 create-new、83个 refactor-existing、21个 defer、15个 reject。此外台账还定义了plate-owned覆盖层:当残差行为真正适合 Plate 插件/示例/文档而非原始 Slate v2 时,路由到 Plate 侧(链接/autolink 语法、列表缩进、markdown 导入导出、mention/hashtag 等插件文法、React Composer/工具栏外壳)。

行为家族核算

收割清单按行为家族统计并分派处理车道:

家族行数处理车道
portable editor behavior39核心模型、选择、变换、历史、浏览器拆分
serialization-parsing / marks-inline20列表/markdown/html/richtext 单元与浏览器行
selection-dom-mapping / void-atom19DOM 选择、行内原子、caret、mention/link/void 边界
core package behavior16Slate 包单元契约;拒绝仅 Lexical 生命周期场景
clipboard-paste / browser-engine14剪贴板契约与 paste-html 浏览器语料
tables-grid / selection-dom-mapping10现在只做包含(containment);表格模型行另立
mixed portable invariant9从产品插件行为中拆出有用的原始不变量
beforeinput-input / browser-engine7model-input 策略与 Playwright 输入传输行
ime-composition / history-undo-redo2基本已应用;核验无未处理命名行
collaboration-remote / history-undo-redo1基质已覆盖;yjs 浏览器延迟
harness12仅技术手法,无直接 Slate 行为行
product-shell33除非拆出原始不变量,否则拒绝
skip89保留原因地拒绝

现有 Slate v2 证明 owner 分布

计划在实时源码中盘点出当前 Slate v2 的证明 owner,这决定了「已覆盖」与「需要新建」的边界:

行为当前 owner(文档记录路径)状态
IME 经浏览器运行时rendering-strategy-runtime.test.tsrichtext.test.tsmentions.test.ts强已有/应用覆盖
IME 行内 void 与 undo 压力generated-editing.test.ts选择性车道已覆盖
组合历史(composition history)slate-history/test/history-contract.ts选择性车道已覆盖
浏览器插入传输plaintext.test.ts选择性车道已覆盖
合成粘贴兼容plaintext.test.ts已覆盖;Firefox skip 诚实
Google Docs 字号粘贴paste-html.test.ts选择性车道已覆盖
Google Sheets 表格粘贴paste-html.test.ts选择性车道已覆盖
表格三击包含tables.test.ts选择性车道已覆盖
表格拖拽包含tables.test.ts已覆盖;非整表选择
DOM 覆盖 IMEdom-coverage-boundaries.test.ts有用证明 owner

实施阶段:Phase 0 到 Phase 8

计划按阶段推进,前两阶段是纯规划,后续按证明类型分闸:

  • Phase 0(处理台账):只创建slate-processing-ledger.md,为每个 portable/portable-mixed 源文件记账,不触碰.tmp/slate-v2
  • Phase 1(文本单元与破坏性删除包级对齐):从 Lexical #7163 grapheme 矩阵起步,重构text-units-contract.ts与现有 delete/unit-character 夹具而非创建重复行;首切片仅包级,除非暴露浏览器专属缺口。首要命令:cd .tmp/slate-v2 && bun test ./packages/slate/test/text-units-contract.ts;实现后关闭命令:cd .tmp/slate-v2 && bun check
  • Phase 2(剪贴板 HTML 源钻取):逐行打开 Lexical link/list/text-format/table 源行,为每行命名预期的 Slate value/DOM 输出,并判定属于原始解析器行为还是示例应用策略。此阶段不编辑代码,不重跑 ClawSweeper(除非声明变化)。已于 2026-05-09 完成,接受/拒绝/延迟行全部记录在台账的Clipboard HTML Row-Level Source Drill节。
  • Phase 3(剪贴板 HTML 语料残差):按小切片实施——先是 text-format HTML(Google Docs BIU 跨度 + 安全的语义<b>处理);再是简单 anchor 导入;再是 Lexical #3193 风格的 noisy link-in-list 最小夹具;再是基础无序列表导入;再是紧凑嵌套列表语料;再是列表项内的嵌套div文本边界;再是 Google Docs 表格导入(rows/cells、多段落单元格、11pt文本);最后是 Quip 表格导入(单元格内b<br>b换行文本)。每个切片都在 paste-html.test.ts 对应的浏览器 owner(.tmp/slate-v2/playwright/integration/examples/paste-html.test.ts)留下浏览器证明。
  • Phase 4(DOM 突变修复残差):把 LexicalMutations.spec.mjs当作refactor-existing;只有当压力复查确认richtext.test.ts、生成压力或策略单元 owner 缺失不变量时才加强。浏览器突变行为必须用 Playwright 证明,包策略测试只作支撑。
  • Phase 5(焦点、滚动与原生浏览器输入):处理 TextEntry、Events、Keyboard、Focus、AutoScroll 与剩余 Mutations 行;原生传输或 DOM 权威是行为本身时必须用浏览器证明;不把桌面视口行冒充真机/原始 IME 关闭。
  • Phase 6(选择与行内/void 原子残差):mention 删除/粘贴边界、link/hashtag/HR 导航(仅当 Slate 拥有等价原始不变量);把原始行内行为与产品工具栏、autolink、应用外壳策略分离。
  • Phase 7(表格模型决策):保留 containment 与三击证明;在 Slate 接受表格选择模型前不声明多单元格/整表选择;本计划不接受表格选择模型。
  • Phase 8(协作/浏览器):保留协作/历史基质行;只有存在真实 collab owner 时才添加 yjs/browser 行;本计划不声明协作浏览器对等。

Ralph-ready 切片:允许做什么、禁止做什么

顺序切片允许的工作禁止的工作必需证明
1文本单元/删除包级对等只向现有 Slate text-unit/delete owner 添加缺失的 Lexical #7163 破坏性 Unicode 行无浏览器、真机、表格、协作或 Issue 声明;不重写删除行为bun test text-units-contract.ts;触碰夹具时补单元命令;关闭前bun check
2剪贴板 HTML 源钻取读取精确 Lexical link/list/text-format/table 行并映射到预期输出与 owner不改.tmp/slate-v2代码;声明不变则不重跑 ClawSweeper仅规划产物
3剪贴板残差实施只添加源钻取命名的解析器/浏览器缺口无产品工具栏/autolink 行为;不重复已有覆盖聚焦包/浏览器证明 +bun check
4DOM 突变/焦点/行内残差命名缺失不变量后加强现有浏览器或策略 owner无单元-only 关闭浏览器行为;无真机声明聚焦 Playwright owner + 相关包策略证明
5表格/真机/协作车道仅独立未来计划不隐藏整表选择、真机或 slate-yjs 浏览器声明先存在表格模型、真机或协作浏览器证明 owner

压力测试、维护者异议与高风险门禁

压力测试结论

压力测试保持计划保守,不新增 Issue 声明、不编辑.tmp/slate-v2

  • 文本单元/删除包级对等:保留第一。Lexical #7163 有密集的 portable Unicode 矩阵,当前 Slate 在text-units-contract.ts有清晰 owner,包级证明避免浏览器抖动与构建成本。压缩契约行在不改动架构的前提下增加价值。
  • 剪贴板 HTML 残差:保留第二但收窄。现有 Slate 已覆盖富片段、行内 void 复制粘贴、多行纯文本、Google Docs 字号、Google Sheets 表格与生成粘贴闯关。盲目移植 Lexical link/list 文件会重复覆盖并引入产品工具栏策略。实施前必须源钻取。
  • DOM 突变修复:降级为 refactor-existing。richtext.test.ts已同步粗体标记内的浏览器文本突变并记录 selectionchange/修复内核结果;新独立 suite 是重复,除非Mutations.spec.mjs暴露缺失断言。
  • 焦点/自动滚动:保留为后期浏览器切片。placeholder focus/IME 已存在,huge-document 只证明可见性;Lexical AutoScroll/Focus 行有价值但混合了原始编辑器行为与应用滚动策略。
  • 行内原子/链接粘贴:接受的原始行已应用。源读确认 portable 原始行是边界复制粘贴与部分链接片段保留;paste-inside-link 拆分是 link 插件策略而非通用核心法则。
  • 表格:保留延迟。现有表格测试证明 containment、三击、拖拽、Enter 与单元格导航;整表/合并单元格/多单元格行为是模型决策。
  • 真机与协作浏览器:保留延迟。桌面/移动视口证明无法满足真机行,当前协作证明仅为包级基质。

维护者异议台账(节选)

计划用「最有力公平异议 → 钢人反论 → 接受的修订」三段式逐条审问决策,代表性修订包括:剪贴板残差不能作为一次宽泛抓包实施、必须先源钻取;焦点/自动滚动必须证明原始编辑器行为而非产品外壳布局;DOM 突变修复保持 refactor-only 但要求下个 owner 先检查richtext或生成压力是否已覆盖;表格、真机、协作浏览器延迟是明确的非声明(non-claim)

高风险门禁与三场景预演

主要风险是虚假自信:单元行、台账行或规划命令被误认为浏览器、设备或 Issue 修复证明。门禁按爆炸半径设防:

  • 文本单元/删除:首个切片可从聚焦包证明出发,不做浏览器/真机/表格/Issue 声明;实现后必须全量bun check
  • 剪贴板 HTML:源钻取先于代码;声明不变时源钻取前无需 ClawSweeper 同步。
  • DOM 突变/焦点/滚动/行内:浏览器行不能被包测试关闭;只有命名缺失不变量后才新增或重构 Playwright 行。
  • 表格/真机/协作:显式非声明。#2558 不声明;真机需SLATE_BROWSER_RAW_MOBILE_REQUIRED=1 bun test:mobile-device-proof:raw门禁;协作浏览器需真实 slate-yjs/browser owner。
  • 规划与验证门禁:plate-2完成检查只证明规划状态;任何 Slate v2 行为声明必须引用从.tmp/slate-v2运行的命令。

三场景预演(pre-mortem):虚假证明(包行关闭浏览器粘贴/IME/焦点)→ 证明类型归属显式化;范围蔓延(剪贴板残差变成跨解析器/示例/列表/链接/表格的宽泛粘贴重写)→ Phase 2 仅源钻取,命名精确行后才允许代码;声明漂移(「已处理 Lexical 测试」被暗示为表格/真机/协作或 Issue 修复声明)→ 非声明在计划、检查点、续接提示中反复重申。

已执行切片成果:从 ralplan 到代码与测试

截至文档记录的 2026-05-09,ralph已执行大量源读与实施切片,形成「红行 → 实现 → 聚焦证明 → 全量bun check」的闭环。以下按家族摘录代表性成果(均为文档记录事实):

文本单元与删除

  • Lexical #7163 已应用:text-units-contract.ts获得显式 Slate 文本单元距离与前后向unit: "character"删除证明;delete-text.ts移除过时的复杂脚本反向删除恢复逻辑,使删除与getCharacterDistance遵循同一文本单元边界法则,泰语 unit-character 夹具同步对齐。
  • Lexical #7246 锁定:delete-contract.ts证明段首 Backspace 合并进前一个列表项。
  • Lexical #7319 拆分:可移植 block-void 行为暴露真实缺口——delete-text.ts现在把相邻 void/只读元素内的折叠删除目标视为路径删除,逐个删除相邻块 void,回归锁定在transforms/delete/voids-false/block-after-multiple-reverse.tsx
  • 通用法则沉淀为解决方案笔记:2026-05-09-slate-v2-adjacent-block-void-delete-must-path-delete-one-target.md。

剪贴板与粘贴 HTML

  • Google Docs BIU 跨度与安全语义<b>paste-html.test.ts证明 Google Docs<b style="font-weight:normal">包装不产生粗体、普通语义<b>映射粗体、body 级行内字符串先转文本节点再包段落。
  • 简单 anchor、noisy link-in-list(Lexical #3193 风格)、基础ul、紧凑嵌套列表、列表项内嵌套div边界、Google Docs 表格(2x3、多段落单元格、11pt)、Quip 表格(b<br>b换行文本)均已加入浏览器语料。
  • 核心 HTML 块形状(纯 DOM 文本、畸形<p>Hello!<p>、单个div、嵌套 span/div、div内嵌套 span、span 内嵌套div)由paste-html-import.ts以通用div块边界导入修复。配套法则见 2026-05-09-html-div-boundaries-must-survive-inline-wrappers.md。
  • 原生列表片段粘贴:insert-fragment.ts以显式结构化片段替换先于通用行内/块解包,clipboard-contract.ts覆盖部分列表项、选中文本内插入、列表项内段落片段、列表尾段落片段等七类行。配套法则见 2026-05-09-native-list-fragment-paste-must-run-before-generic-fragment-unwrapping.md。
  • 空目标片段粘贴保留首块包装:粘贴到空引用块时首文本块填充引用、尾段落提升其后。见 2026-05-09-empty-target-fragment-paste-keeps-first-block-wrapper.md。
  • 代码源 HTML 导入:Quip<pre>、VS Codewhite-space: prediv、GitHub 代码表导入为一个<pre><code>块,使用 DataTransfer 插入边界而非原生剪贴板(Chromium 会先压平<pre>)。见 2026-05-09-lexical-codeblock-harvest-rows-need-data-transfer-boundaries.md。
  • 图像 HTML:<p><img></p><figure><img><figcaption>两种 Lexical 导出形状;paste-html-import.ts解包仅含块元素的段落包装。见 2026-05-09-block-only-html-paragraphs-must-not-wrap-block-voids.md。

DOM 修复、焦点与滚动

  • dom-repair-policy-contract.ts新增结构恢复管理器策略证明:子列表突变回滚,字符数据突变保留用于文本同步。
  • 焦点/自动滚动:richtext.test.ts证明失焦时保留模型选择、可滚动编辑器根与可滚动父级中跨行输入时 caret 可见;editable.tsx对空行 caret 零矩形场景回退到滚动 leaf 矩形。

行内边界、caret 与选择重基

  • 行内粘贴/mention/link/HR 边界:inlines.test.ts证明行内链接边界纯文本与富 HTML 粘贴都留在链接外;clipboard-contract.ts证明部分链接片段复制/粘贴保留链接属性。
  • caret 破坏性范围删除矩阵:delete-contract.ts证明扩展范围删除在锚点折叠前修剪两侧兄弟 leaf 边与跨块边。
  • 选择重基不变量:selection-rebase-contract.ts证明被选 leaf 消失时选择落在最近存活行内点;LexicalRootNode切片进一步证明删除被选首块重基到下一个存活块、删除唯一被选块清空选择。
  • 原始文本操作选择修复:operations-contract.ts证明split_node跨分裂文本分支重基扩展选择、merge_node把选择重基进存活文本分支。
  • 行内链接插入后移出:inlines.tsx在折叠插入链接后移出一个偏移。见 2026-05-09-collapsed-inline-link-insertion-must-move-selection-outside.md。

历史、序列化、热键与状态 API

  • 历史栈法则:history-contract.ts证明 undo 后新编辑清空 redo 栈、选中块属性 undo/redo、忽略空更新同时捕获节点属性历史。
  • 序列化:state-tx-public-api-contract.ts证明富原始文档值经 JSON 往返、可重水合为initialValue、不序列化pathToId/idToPath运行时索引元数据。
  • 热键:hotkeys.ts证明isHotkey先按语义字母键匹配、处理大写、拒绝 ASCII 重映射布局物理键、对非英文单字母布局回退event.code
  • 根拆分拒绝:split-nodes.tsEditor.splitNodes(..., { at: [] })抛出直接编辑器根错误。

列表、标题、引用、markdown 与格式化

  • 相邻 markdown 列表合并(#3433):markdown-shortcuts.tsx合并相邻项目符号列表包装,浏览器行证明一个ultwoone前。
  • 标题/引用 Enter 策略:richtext.tsx用统一的 exit-on-Enter 策略处理heading-one/heading-two/block-quote,中间 Enter 走通用核心 split 路径。
  • 有序列表起始数字(25.ol start="25")与列表 Backspace 退出解包进入markdown-shortcuts.tsx
  • 清除格式:richtext.tsx暴露 clear-formatting 按钮,只移除选中文本 mark、重置块对齐、保留 blockquote 结构。
  • 空段落居中(ElementFormat):折叠选择下显式定位包含块路径。
  • mark 热键:tx.marks.toggle默认值改为true,插入前清空继承折叠 mark;snapshot-contract.ts证明Editor.toggleMark行为;richtext.tsx阻止编辑器自有 mark 热键的浏览器默认处理。
  • 列表工具函数:query-contract.ts证明嵌套列表深度、非根顶层列表祖先、后代列表祖先、terminal/非 terminal 列表项路径。
  • 代码行 Tab 缩进与 Shift+Tab 多行缩进进入code-highlighting.test.ts
  • 装饰文本令牌:highlighted-text.tsx为普通文本添加 hashtag 风格投影,覆盖 Space 拆分、Delete/Backspace 边界、瞬态前缀导航、分隔符增删与删除#后稳定 caret。
  • MacCtrl+Oopen-line:open-line插入断行变体经slate-dom热键与slate-react键盘/突变运行时实现,直接在当前块前插入空段落。
  • beforeinput 替换:runtime-before-input-events.ts在下一个模型属主 beforeinput 前冲刷排队原生文本修复,mutation-controller.ts应用提供替换目标范围,selection-reconciler.ts尊重扩展insertText目标范围;Mac 风格insertTranspose(Ctrl+T 交换相邻字符)成为一级transpose-character命令。

被拒/延迟的代表性行

  • LexicalElementHelpers(class 字符串增删)被拒为 Lexical DOM 工具助手。
  • SpecialTexts 括号触发高亮被拒为产品变换/主题策略。
  • Lexical markdown 导入/导出、markdown-link transformer、checklist 私有属性、HR 插入/拆分、自定义表宽/合并网格/rowspan/colspan/空行合成、paste-inside-link 拆分、原始 autolink 插件行为、表格单元格块归一化,全部延迟到显式未来 owner(markdown 序列化、list/checklist、HR/block-void、表格布局/模型、link 插件)。
  • 真机移动、协作浏览器、整表选择为显式非声明。

Issue 核算:零新增声明的纪律

计划在 Issue 核算上保持高度保守,最终核算为 no-op:

  • 计划记录0条新增精确Fixes #...Improves #...声明。
  • pr-description.md 保持固定 Issue 声明31、相关矩阵行158、Lexical 收割精确声明0
  • issue-coverage-matrix.md 保持 #5894Not claimed、#4730Related、#3387Related、#3872Related、#4716Related、#5355Not claimed、#2558Not claimed
  • 相关分类遵循「related/proof-route only」:表格类(#4658/#4643/#5355 相关压力,#2558/#5550/#5551/#5924/#4851 不声明)、剪贴板类(#4440/#3557/#4542/#3155/#4716/#2694 相关)、IME/真机类(#5912/#4223/#5281 非声明)等。
  • ClawSweeper 仅在公共行为、Issue 声明或相关表面发生实质变化时重跑;零声明变化时最终核算可为 no-op 复查。

关闭评分与验证命令

计划关闭评分0.92,六个维度均不低于0.85:台账核算0.95、Issue 诚实0.94、证明归属0.93、实施切片就绪0.91、非声明保护0.94、可维护性0.90。关闭门禁全部通过:最终评分达标、无维度低于0.85、10 个规划 pass 完成且第 11 个为关闭、无隐藏.tmp/slate-v2实现声明、首个ralph交接切片足够窄。

规划仓库门禁(文档记录,需在对应检出目录执行):

# 规划仓库(plate-2) pnpm lint:fix bun run completion-check -- --file .tmp/completion-checks/slate-v2-lexical-harvest-test-processing-ralplan.md

Slate v2 后续实施切片门禁:

# 在 .tmp/slate-v2(slate-v2 检出)中 bun test ./packages/slate/test/text-units-contract.ts bun test ./packages/slate-dom/test/clipboard-boundary.ts bun test ./packages/slate-history/test/history-contract.ts PLAYWRIGHT_RETRIES=0 bunx playwright test playwright/integration/examples/paste-html.test.ts --project=chromium PLAYWRIGHT_RETRIES=0 bunx playwright test playwright/integration/examples/tables.test.ts --project=chromium bun check

浏览器/发布关闭门禁:bun check:full;真机设备门禁:SLATE_BROWSER_RAW_MOBILE_REQUIRED=1 bun test:mobile-device-proof:raw

浏览器行纪律:当浏览器行构建或共享 Slate v2 站点时必须串行执行,不得并行运行多个站点支撑的 Playwright 命令;IME 行必须使用诚实的 DOM 组合边界,合成或仅模型选择不足以证明原生浏览器行为;DOM 选择计划必须按 owner 为外部测试源排序——Lexical 在浏览器回归形状与 skip 纪律上强,但不代表每个 DOM 选择架构选择都该采纳。

方法论总结:把上游测试语料变成可执行的工程资产

这份 ralplan 最有价值之处在于把「另一个编辑器的 271 条测试」转化为一份可审计、可执行、可关闭的工程计划:

  1. 台账先行:所有 portable/portable-mixed 源文件先路由到六类状态,让拒绝与延迟都有具体理由,杜绝「静默丢弃」。
  2. 按不变量家族分组,不按上游文件形状分组:优先加强已有 Slate 测试,只有不变量没有诚实证明时才新建。
  3. 证明类型与行为严格配对:模型不变量走包测试,浏览器传输走 Playwright,真机声明走真机门禁;绝不混合。
  4. 小切片 + 显式允许/禁止清单:每个ralph切片都写明允许的工作、禁止的工作与必需证明命令,避免范围蔓延。
  5. Issue 声明零容忍漂移:related/proof-route 与 not-claimed 是默认态,任何精确Fixes/Improves都需要复现证明。
  6. 每次执行沉淀可复用法则:30 余条解决方案笔记分布在 docs/solutions 的best-practiceslogic-errorsworkflow-issues分类下,把「红行 → 修复 → 法则」的循环固化下来。

对于任何需要跨编辑器移植测试覆盖、或在核心编辑器与插件层之间划分测试所有权的团队,这份计划提供了可直接套用的模板:先建台账、再定切片、最后用证明门禁收口。仓库中完整的处理台账见 slate-processing-ledger.md,行为家族与切片优先级可直接作为后续执行计划的输入。

【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 18:58:22

零基础选AI工具的3个关键问题决策法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 18:48:50

STM32 Bootloader与串口IAP实现:从原理到代码,轻松搞定固件升级

很多人刚接触单片机开发时&#xff0c;对 bootloader 总是有一种“高深莫测”的感觉。后来我自己做产品&#xff0c;才真正意识到它其实就是一段“先于主程序运行的小程序”&#xff0c;并没有想象中复杂。尤其是当你需要给已经出货的设备做固件升级时&#xff0c;IAP&#xff…

作者头像 李华
网站建设 2026/9/17 18:45:21

S7-1500 PLC硬件配置、电源预算与硬件诊断实战

简介&#xff1a;这份《S7-1500 PLC应用技术》第2章课件&#xff0c;面向自动化、电气控制专业学生及初学S7-1500的工程人员&#xff0c;用于梳理该系列PLC硬件体系与选型要点。内容分六部分&#xff1a;SIMATIC产品定位、CPU模块、电源模块、信号模块、通信模块与CPU操作模式。…

作者头像 李华