表:React 遷移下 Notebook 行為對(duì)等的驗(yàn)證體系)
數(shù)據(jù)分析數(shù)據(jù)可視化大數(shù)據(jù)后端前端任務(wù)調(diào)度【免費(fèi)下載鏈接】zeppelinWeb-based notebook that enables>項(xiàng)目地址https://gitcode.com/gh_mirrors/zeppe/zeppelin點(diǎn)擊查看免費(fèi)下載Zeppelin 的 Angular 前端正在逐步向 React 垂直切片vertical slice遷移遷移的前提是換實(shí)現(xiàn)、不換行為。本文介紹的zeppelin-web-angular/e2e/scenarios/notebook-parity.md正是為這一目標(biāo)建立的Notebook 行為對(duì)等parity場景注冊(cè)表它把 Angular Notebook 的關(guān)鍵行為固化為帶 ID、前置條件、可觀察結(jié)果與證據(jù)鏈的場景清單并由腳本自動(dòng)生成 Markdown、用 JSON Schema 強(qiáng)制約束、以 Playwright 測試標(biāo)簽雙向校驗(yàn)。讀完本文你將掌握注冊(cè)表的數(shù)據(jù)模型、生成與校驗(yàn)鏈路、10 個(gè)已登記場景的完整細(xì)節(jié)以及如何用這些場景驅(qū)動(dòng) React 遷移的質(zhì)量驗(yàn)收。Notebook Parity 注冊(cè)表要解決什么問題Zeppelin 前端存在 Angular 與 React 兩套實(shí)現(xiàn)舊殼zeppelin-web-angular/src/app下的 Angular 組件是當(dāng)前行為基準(zhǔn)source of truth而zeppelin-web-angular/projects/zeppelin-react正在以遠(yuǎn)程模塊方式逐步接管 Notebook 表面。按倉庫根 AGENTS.md 的遷移約定一個(gè)回歸只有在之前的行為從未被寫下來時(shí)才會(huì)變成預(yù)期結(jié)果——因此遷移要求在 Angular 仍是基準(zhǔn)時(shí)先把行為寫下來。這份注冊(cè)表承擔(dān)的就是先把行為寫下來的角色。它是一份優(yōu)先級(jí)化prioritized的基線而非完整的 Notebook 功能清單在一個(gè) React 垂直切片被宣告就緒之前必須把每一個(gè)受影響的行為登記進(jìn)注冊(cè)表并歸類其證據(jù)。文檔本身也明確給出了兩條使用紀(jì)律Scope note這是優(yōu)先化基線而非完整 Notebook 清單Coverage notecovered在機(jī)械含義上僅指注冊(cè)表指向了一個(gè)匹配的可執(zhí)行 Playwright 測試標(biāo)簽語義充分性與運(yùn)行時(shí)通過與否仍屬于 review 與 CI 證據(jù)角色期望只在結(jié)果隨角色變化時(shí)才記錄且角色驗(yàn)證記錄該期望是否已測試。也就是說注冊(cè)表解決的是有沒有人明確驗(yàn)證過某行為在新實(shí)現(xiàn)上仍然一致這一治理問題而不是替 CI 宣稱行為一定一致。注冊(cè)表的三種形態(tài)與生成鏈路同一份數(shù)據(jù)以三種形態(tài)存在全部位于zeppelin-web-angular/e2e/scenarios/目錄形態(tài)文件作用數(shù)據(jù)源notebook-parity.json場景注冊(cè)表的唯一事實(shí)來源由人維護(hù)模式約束notebook-parity.schema.jsonJSON Schema draft-07定義注冊(cè)表合法結(jié)構(gòu)發(fā)布文檔notebook-parity.md渲染產(chǎn)物禁止手改文件頭標(biāo)注Generated by scripts/generate-notebook-parity-scenarios.mjs. Do not edit directly.生成鏈路由兩個(gè)腳本驅(qū)動(dòng)見 notebook-parity-scenarios.mjs 與 generate-notebook-parity-scenarios.mjsloadRegistry(webRoot)讀取e2e/scenarios/notebook-parity.jsonvalidateRegistry(registry, webRoot)執(zhí)行全套校驗(yàn)見下節(jié)其中checkMarkdown: false用于生成前校驗(yàn)、checkMarkdown: true用于比對(duì)產(chǎn)物renderMarkdown(registry)將場景數(shù)組渲染為 Markdown 表格 場景明細(xì)writeFileSync寫回e2e/scenarios/notebook-parity.md。生成命令就是腳本自身報(bào)錯(cuò)時(shí)給出的提示npm run generate:notebook-parity-scenarios。若 Markdown 與 JSON 不一致validateRegistry會(huì)報(bào)notebook-parity.md is stale強(qiáng)制提交前重新生成從而保證文檔永遠(yuǎn)等于數(shù)據(jù)。校驗(yàn)器實(shí)際做了什么validateRegistry是這套體系最嚴(yán)謹(jǐn)?shù)牟糠炙褱y試與場景一一對(duì)應(yīng)變成機(jī)器可查的硬約束Schema 校驗(yàn)用 Ajv 編譯 schema 校驗(yàn)整個(gè)注冊(cè)表formatSchemaError會(huì)把a(bǔ)dditionalProperties、minItems、pattern、required、type等錯(cuò)誤轉(zhuǎn)換為可定位的location.message格式基準(zhǔn)提交存在性reviewedCommit必須是 40 位十六進(jìn)制并用git cat-file -e commit^{commit}驗(yàn)證當(dāng)前 checkout 里確實(shí)存在該提交當(dāng)前值為d5b57b12fd0c5e1d885767aabe06b242debf8300ID 紀(jì)律場景id全局唯一且必須按字典序嚴(yán)格遞增防止亂序追加outcome 的id必須以場景ID-OUTCOME-開頭且不重復(fù)uncoveredOutcomes必須引用真實(shí)存在的 outcome id角色一致性roleExpectations為not-applicable的角色其roleVerification必須是not-applicable反之亦然證據(jù)路徑存在性implementationEvidence/verificationEvidence中的每個(gè)path都必須真實(shí)存在于倉庫通過resolveRepositoryPath在模塊根與倉庫根兩個(gè)候選位置解析測試標(biāo)簽可執(zhí)行性最硬核的一步testDeclaresExecutableTag用TypeScript AST解析測試源文件——先找playwright/test導(dǎo)入綁定到的test標(biāo)識(shí)符再遍歷所有test(...)調(diào)用讀取第二參數(shù)的靜態(tài)tag字符串并排除位于describe.skip(...)內(nèi)部的調(diào)用isInsideSkippedDescribe。只有注冊(cè)表中的NB-PARITY-XXX標(biāo)簽確實(shí)由某個(gè)可執(zhí)行的test()聲明才算covered套件歸屬covered場景的測試路徑必須以zeppelin-web-angular/e2e/tests/notebook/開頭且test.tag必須恰好等于場景ID。這一整套校驗(yàn)意味著注冊(cè)表無法引用不存在的文件、無法指向被跳過或未聲明的測試、無法容忍標(biāo)簽與 ID 錯(cuò)位從機(jī)制上杜絕了假覆蓋。注冊(cè)表數(shù)據(jù)模型Schema 要點(diǎn)notebook-parity.schema.json 定義了場景的合法形狀理解它才能讀懂明細(xì)根對(duì)象必須有$schema固定指向./notebook-parity.schema.json、reviewedCommit40 位 hex、scenarios至少 1 項(xiàng)scenario 必需字段id^NB-PARITY-[0-9]{3}$、name、area、preconditions、action、observableOutcomes、interpreter、implementationEvidence、verificationEvidence、coveragearea 枚舉editor、execution、result、visualization、shortcut、permission、collaboration、navigation、persistence、lifecycle、theme、accessibility——當(dāng)前 10 個(gè)場景覆蓋了其中navigation、editor、shortcut、result、persistence、theme六類證據(jù)二元組每條 evidence 是{ path, symbol }例如{ path: zeppelin-web-angular/src/app/core/paragraph-base/paragraph-output-state.ts, symbol: ParagraphOutputState }把實(shí)現(xiàn)/驗(yàn)證錨點(diǎn)精確定位到文件與符號(hào)角色期望roleExpectations對(duì)owner、writer、reader、runner四個(gè)角色各給allow/deny/not-applicableroleVerification對(duì)同一角色集合給verified/unverified/not-applicable且兩者相互約束coverage 狀態(tài)機(jī)allOf組合約束這是理解covered/partial/gap的關(guān)鍵covered至少 1 個(gè)測試 0 個(gè)未覆蓋 outcomepartial至少 1 個(gè)測試 至少 1 個(gè) issue 至少 1 個(gè)未覆蓋 outcomegap/blocked0 個(gè)測試 至少 1 個(gè) issue 0 個(gè)未覆蓋 outcome。也就是說有測試不等于covered——只要還有 outcome 沒被驗(yàn)證如結(jié)果展示模式、可視化字段映射狀態(tài)就自動(dòng)降級(jí)為partial并強(qiáng)制登記 JIRA issue 與未覆蓋 outcome 清單。全量場景清單下表完整對(duì)應(yīng)注冊(cè)表的索引表含每個(gè)場景的測試文件與NB-PARITY-XXX標(biāo)簽角色期望僅在與角色相關(guān)時(shí)記錄IDAreaScenarioCoverageRolesTestsIssuesNB-PARITY-001navigationNotebook container structure is visiblecoverednot-applicablenotebook-container.spec.tsNB-PARITY-001NB-PARITY-002navigationNotebook title can be displayed and editedcoveredowner: allow; writer: allow; reader: deny; runner: not-applicableaction-bar-functionality.spec.tsNB-PARITY-002NB-PARITY-003editorParagraph enters editing mode on double clickcoveredowner: allow; writer: allow; reader: deny; runner: not-applicableparagraph-functionality.spec.tsNB-PARITY-003NB-PARITY-004editorParagraph add buttons are visiblecoveredowner: allow; writer: allow; reader: deny; runner: not-applicableparagraph-functionality.spec.tsNB-PARITY-004NB-PARITY-005shortcutShiftEnter executes a markdown paragraphcoveredowner: allow; writer: allow; reader: deny; runner: allownotebook-keyboard-shortcuts.spec.tsNB-PARITY-005NB-PARITY-010editorHistory inline completion can be dismissed without losing editor focuscoverednot-applicableinline-completion.spec.tsNB-PARITY-010NB-PARITY-011editorThe second Escape after inline completion dismissal blurs the editorcoverednot-applicableinline-completion.spec.tsNB-PARITY-011NB-PARITY-021resultText and table result displays preserve output semantics after paragraph executionpartialowner: allow; writer: allow; reader: deny; runner: allowparagraph-functionality.spec.tsNB-PARITY-021ZEPPELIN-6514, ZEPPELIN-6516NB-PARITY-022resultStreaming interpreter output accumulates while a paragraph is runningcoveredowner: allow; writer: allow; reader: deny; runner: allowparagraph-functionality.spec.tsNB-PARITY-022NB-PARITY-050persistenceNotebook editor persists the latest text after typing stopscoveredowner: allow; writer: allow; reader: deny; runner: not-applicablenotebook-save-timing.spec.tsNB-PARITY-050NB-PARITY-051persistenceNotebook editor does not lose an edit made while a prior save is in flightcoveredowner: allow; writer: allow; reader: deny; runner: not-applicablenotebook-save-timing.spec.tsNB-PARITY-051NB-PARITY-060themeNotebook honors host theme selectiongapnot-applicable無測試ZEPPELIN-6640場景分區(qū)詳解以下按文檔的 Scenario Details 逐項(xiàng)展開每個(gè)場景都標(biāo)注了前置條件、動(dòng)作、可觀察結(jié)果OUTCOME以及對(duì)應(yīng)的實(shí)現(xiàn)/驗(yàn)證證據(jù)。導(dǎo)航與容器NB-PARITY-001 Notebook container structure is visiblearea: navigationcoverage: covered前置條件打開一個(gè)可丟棄disposable的 notebook 路由動(dòng)作渲染 notebook 路由可觀察結(jié)果NB-PARITY-001-OUTCOME-001notebook 容器可見且?guī)в衅谕娜萜黝?。?yàn)證證據(jù)notebook-container.spec.tsNotebook Container Component與 notebook-page.tsNotebookPage。源碼印證測試在beforeEach中通過createTestNotebook(page)創(chuàng)建一次性 notebook 再導(dǎo)航進(jìn)入NotebookPage把.notebook-container、zeppelin-notebook-action-bar、可拖拽側(cè)欄.sidebar-area[nz-resizable]、網(wǎng)格布局段落容器.paragraph-inner[nz-row]、擴(kuò)展區(qū).extension-area等 DOM 錨點(diǎn)封裝為 Locator。同一套件還驗(yàn)證了側(cè)欄寬度約束40800px與點(diǎn)擊設(shè)置按鈕后擴(kuò)展區(qū)可見——這些是 React 切片需要逐一對(duì)齊的布局行為。NB-PARITY-002 Notebook title can be displayed and editedarea: navigationcoverage: covered角色期望owner/writer 允許reader 拒絕runner 不適用動(dòng)作打開標(biāo)題編輯器并重命名 notebook可觀察結(jié)果NB-PARITY-002-OUTCOME-001標(biāo)題編輯器可見且改名后的標(biāo)題反映在 notebook 頭部。驗(yàn)證證據(jù)action-bar-functionality.spec.tsNotebook Action Bar Functionality與 notebook-action-bar-page.tsNotebookActionBarPage。說明該場景同時(shí)登記了四角色的權(quán)限期望但目前owner/writer/reader的roleVerification均為unverified——即權(quán)限矩陣已記錄、尚未逐角色跑通這正是覆蓋注釋所說角色驗(yàn)證記錄的是該期望是否已測試的實(shí)例。段落編輯NB-PARITY-003 Paragraph enters editing mode on double clickarea: editorcoverage: covered前置條件打開一個(gè)至少含一個(gè)段落的 notebook動(dòng)作雙擊段落可觀察結(jié)果NB-PARITY-003-OUTCOME-001段落代碼編輯器變?yōu)榭梢?。?yàn)證證據(jù)paragraph-functionality.spec.tsNotebook Paragraph Functionality與 notebook-paragraph-page.tsNotebookParagraphPage。NB-PARITY-004 Paragraph add buttons are visiblearea: editorcoverage: covered動(dòng)作檢查段落控件可觀察結(jié)果NB-PARITY-004-OUTCOME-001添加段落的控件在可插入新段落的位置可見。驗(yàn)證證據(jù)同上。NB-PARITY-010 History inline completion can be dismissed without losing editor focusarea: editorcoverage: coveredinterpreter: python前置條件notebook 含一個(gè)可供給 inline completion 歷史文本的 Python 段落并以aiInlineComplete打開路由動(dòng)作在 Monaco 中鍵入補(bǔ)全前綴并在補(bǔ)全可見時(shí)按 Escape可觀察結(jié)果NB-PARITY-010-OUTCOME-001補(bǔ)全建議來自 notebook 歷史NB-PARITY-010-OUTCOME-002第一次 Escape 關(guān)閉建議后 Monaco 輸入框仍保持焦點(diǎn)。驗(yàn)證證據(jù)inline-completion.spec.tsInline completion與 notebook-keyboard-page.tsNotebookKeyboardPage。源碼印證E2E 通過page.goto(/#/notebook/id?aiInlineCompletetrue)開啟特性并專門用.monaco-editor .ghost-text-decoration, .ghost-text-decoration-preview定位 Monaco 的幽靈文本ghost text因?yàn)橛撵`文本沒有可訪問角色測試斷言補(bǔ)全文本收斂為tory)后才按 Escape隨后斷言inputArea仍toBeFocused()。NB-PARITY-011 The second Escape after inline completion dismissal blurs the editorarea: editorcoverage: coveredinterpreter: python前置條件同 NB-PARITY-010且瀏覽器為 Chromium動(dòng)作第一次 Escape 關(guān)閉補(bǔ)全第二次 Escape 再按一次可觀察結(jié)果NB-PARITY-011-OUTCOME-001第一次 Escape 保持 Monaco 焦點(diǎn)NB-PARITY-011-OUTCOME-002第二次 Escape 在 Chromium 中使 Monaco 輸入框失焦。源碼印證測試顯式test.skip(browserName ! chromium, ...)——Monaco 對(duì) Firefox/WebKit 的第二次 Escape 處理不同因此把瀏覽器差異固化進(jìn)場景本身而不是讓測試悄悄跨瀏覽器斷言失敗??旖萱I執(zhí)行NB-PARITY-005 ShiftEnter executes a markdown paragrapharea: shortcutcoverage: coveredinterpreter: md前置條件代碼編輯器中有焦點(diǎn)的可丟棄段落動(dòng)作鍵入 Markdown 內(nèi)容并按下 ShiftEnter可觀察結(jié)果NB-PARITY-005-OUTCOME-001段落執(zhí)行并渲染出 Markdown 標(biāo)題結(jié)果。驗(yàn)證證據(jù)notebook-keyboard-shortcuts.spec.tsParagraphActions.Run與 notebook-keyboard-page.tsNotebookKeyboardPage。源碼印證鍵盤套件基于ShortcutsMapsrc/app/key-binding/shortcuts-map.ts編寫頁面對(duì)象先等待 Monaco 的focused類再派發(fā)快捷鍵效果一律用 web-first 斷言。測試輸入%md\n# Test Heading\n\nThis is **bold** text.按pressRunParagraph()后先waitForParagraphExecution(0)以狀態(tài)文本收斂作為運(yùn)行完成的斷言再斷言結(jié)果區(qū)出現(xiàn)headingrole 且名稱為 Test Heading。該套件還覆蓋了ControlAltA/B插入上下段落、ControlAltK/J移動(dòng)段落、ControlAltD刪除、ControlAltW生成段落鏈接、ControlSpace自動(dòng)補(bǔ)全等大量快捷鍵是整個(gè) parity 矩陣?yán)锔采w面最廣的測試文件之一。結(jié)果渲染與流式輸出NB-PARITY-021 Text and table result displays preserve output semantics after paragraph executionarea: resultcoverage:partialinterpreter: python前置條件notebook 含一個(gè)打印文本的 Python 段落與一個(gè)返回表格輸出的段落動(dòng)作從段落控件運(yùn)行段落并檢查渲染的結(jié)果面板可觀察結(jié)果共 5 項(xiàng)NB-PARITY-021-OUTCOME-001結(jié)果展示變?yōu)榭梢娗曳强誑B-PARITY-021-OUTCOME-002UI 提供 Angular notebook 對(duì)返回結(jié)果類型暴露的每一種展示模式NB-PARITY-021-OUTCOME-003可視化控件變更保留結(jié)果列 → 維度/度量的字段映射NB-PARITY-021-OUTCOME-004可視化選項(xiàng)變更后段落的持久化 config 反映最終配置對(duì)象NB-PARITY-021-OUTCOME-005文本與表格結(jié)果按行暴露可訪問的表格輸出使 React 渲染的對(duì)比不依賴截圖。實(shí)現(xiàn)證據(jù)paragraph.component.htmlzeppelin-notebook-paragraph-result、progress.component.tsNotebookParagraphProgressComponent、table-transformation.tsTableTransformation、pivot-transformation.tsPivotTransformation、visualization.tsVisualization。未覆蓋 outcomeOUTCOME-002、003、004、005 均未覆蓋并關(guān)聯(lián) ZEPPELIN-6514、ZEPPELIN-6516 兩個(gè) issue。這是機(jī)械 covered ≠ 語義充分的最佳例證當(dāng)前測試只驗(yàn)證了結(jié)果可見非空而展示模式枚舉、可視化字段映射持久化、可訪問表格逐行輸出都還待補(bǔ)。NB-PARITY-022 Streaming interpreter output accumulates while a paragraph is runningarea: resultcoverage: coveredinterpreter: sh前置條件notebook 含一個(gè)帶延時(shí)分批輸出的 shell 段落且服務(wù)端開啟流式輸出zeppelin.websocket.paragraph_status_progress.enable為 true動(dòng)作運(yùn)行段落并在其結(jié)束前后觀察結(jié)果面板可觀察結(jié)果NB-PARITY-022-OUTCOME-001段落狀態(tài)仍為 RUNNING 時(shí)第一塊輸出已可見NB-PARITY-022-OUTCOME-002后續(xù)塊追加在先前的塊之后而非替換它們NB-PARITY-022-OUTCOME-003FINISHED 結(jié)果按發(fā)射順序恰好包含每一塊各一次。實(shí)現(xiàn)證據(jù)paragraph-output-state.tsParagraphOutputState、paragraph-base.tsParagraphBase.onParagraphAppendOutput/onParagraphUpdateOutput、AppendOutputRunner.javaAppendOutputRunner。驗(yàn)證證據(jù)paragraph-output-state.spec.ts單元測試、paragraph-output-stream.capture.jsonenabled、notebook-paragraph-page.ts。源碼印證ParagraphOutputState是這條行為的核心實(shí)現(xiàn)——它維護(hù)results數(shù)組與pendingAppends緩沖append(index, data)把新塊拼接到既有data之后并返回更新后的結(jié)果對(duì)象不替換update(index, type, data)對(duì)空 type 聲明采用 pending 追加內(nèi)容一旦finish()置位terminal后續(xù) append/update 一律返回undefined從而保證結(jié)束后的結(jié)果每塊恰好一次。snapshot()還特意保留服務(wù)端索引——缺失槽位未獲得類型前不截?cái)啾苊庾芳痈倯B(tài)導(dǎo)致渲染錯(cuò)位。單元測試與 E2E 雙保險(xiǎn)且 E2E 依賴服務(wù)端配置zeppelin.websocket.paragraph_status_progress.enabletrue這條配置項(xiàng)正是流式輸出語義的前置條件。保存時(shí)序NB-PARITY-050 Notebook editor persists the latest text after typing stopsarea: persistencecoverage: covered前置條件打開含一個(gè)可編輯段落的 notebook用戶可編輯該段落動(dòng)作替換段落文本并停止輸入足夠久讓保存路徑確認(rèn)該編輯可觀察結(jié)果NB-PARITY-050-OUTCOME-001持久化的段落文本等于最后鍵入的文本NB-PARITY-050-OUTCOME-002保存斷言基于可觀察的持久化或線上wire證據(jù)而非內(nèi)部計(jì)時(shí)器。實(shí)現(xiàn)證據(jù)code-editor.component.tsNotebookParagraphCodeEditorComponent驗(yàn)證證據(jù)notebook-save-timing.util.tsCommitParagraphSocketProbe與 notebook-keyboard-page.ts。源碼印證CommitParagraphSocketProbe通過page.routeWebSocket(/\/ws(\?|$)/)代理瀏覽器與 Zeppelin 的 WebSocket監(jiān)聽COMMIT_PARAGRAPH消息含msgId、noteId、paragraph。斷言不是等固定秒數(shù)而是expect.poll(...)等待 commit 數(shù)量與內(nèi)容真正做到了基于線上證據(jù)。測試還檢測COLLABORATIVE_MODE_STATUS與PATCH_PARAGRAPH——一旦 notebook 進(jìn)入?yún)f(xié)作模式編輯走PATCH_PARAGRAPHCOMMIT_PARAGRAPH不再出現(xiàn)probe 會(huì)直接拋錯(cuò)提示測試前提失效。NB-PARITY-051 Notebook editor does not lose an edit made while a prior save is in flightarea: persistencecoverage: covered前置條件第一個(gè)段落保存請(qǐng)求可在其完成前被觀察到動(dòng)作編輯段落、讓第一次保存在途再進(jìn)行第二次編輯可觀察結(jié)果NB-PARITY-051-OUTCOME-001在途的第一次保存不會(huì)覆蓋或丟棄第二次編輯NB-PARITY-051-OUTCOME-002稍后的可觀察保存或?qū)~reconciliation持久化第二次編輯。實(shí)現(xiàn)證據(jù)code-editor.component.ts、notebook.component.tsNotebookComponent、paragraph-base.tsParagraphBase驗(yàn)證證據(jù)notebook-save-timing.util.tsCommitParagraphSocketProbe。源碼印證probe 的holdFirstCommitParagraphResponse()會(huì)把第一個(gè)COMMIT_PARAGRAPH的服務(wù)端PARAGRAPH回執(zhí)扣留在代理層heldResponsesMap并在此后把服務(wù)端消息排進(jìn)隊(duì)列queuedResponses以保持順序隨后用releaseHeldResponseWithParagraphTitle(msgId, title)把被扣回執(zhí)改造成帶標(biāo)記標(biāo)題的段落快照放行測試據(jù)此斷言在途回執(zhí)應(yīng)用后第二次編輯仍在。這套扣留回執(zhí) 亂序恢復(fù)的機(jī)制把真實(shí)世界中最棘手的并發(fā)保存競態(tài)變成了可重復(fù)的確定性測試。主題NB-PARITY-060 Notebook honors host theme selectionarea: themecoverage:gap前置條件用戶可從宿主殼選擇 light / dark / system 主題動(dòng)作在 notebook 表面掛載期間切換宿主主題可觀察結(jié)果NB-PARITY-060-OUTCOME-001notebook 文本保持可讀NB-PARITY-060-OUTCOME-002結(jié)果與圖表輸出繼承宿主主題令牌tokensNB-PARITY-060-OUTCOME-003所選主題在刷新后持久。實(shí)現(xiàn)證據(jù)ZeppelinThemeProvider.tsxZeppelinThemeProvider驗(yàn)證證據(jù)dark-mode.spec.tsDark Mode Theme Switching。說明該場景當(dāng)前為gap——沒有登記任何匹配的測試標(biāo)簽且關(guān)聯(lián) ZEPPELIN-6640。按 schema 的狀態(tài)機(jī)gap強(qiáng)制要求 0 測試 至少 1 issue這正是已知缺口要顯式記賬的工程實(shí)踐缺口不被靜默遺忘而是在注冊(cè)表里以 issue 形式排隊(duì)。coverage 狀態(tài)與角色權(quán)限矩陣的工程語義從上面 10 個(gè)場景可以看出注冊(cè)表的 coverage 是一個(gè)三值邏輯而非布爾值covered8 個(gè)001/002/003/004/005/010/011/022/050/051 中的 9 個(gè)意味著存在可執(zhí)行測試標(biāo)簽且全部 outcome 均已登記驗(yàn)證例如 NB-PARITY-022 從單元測試、捕獲流量、E2E 三個(gè)層面閉環(huán)partial1 個(gè)021意味著有測試但語義未滿未覆蓋的 4 個(gè) outcome 與 2 個(gè) JIRA issue 被顯式列出防止團(tuán)隊(duì)誤把有測試當(dāng)作已驗(yàn)證gap1 個(gè)060意味著已知行為差異尚未有測試通過 issue 登記排隊(duì)。角色權(quán)限維度同樣講究記錄與驗(yàn)證分離roleExpectations寫明誰應(yīng)該能做什么如 reader 對(duì)編輯類操作一律deny而roleVerification誠實(shí)標(biāo)注unverified當(dāng)前 10 個(gè)場景中所有涉及角色的場景都尚未逐角色跑通。這種期望先行、驗(yàn)證后補(bǔ)的記賬方式讓 React 遷移的每一個(gè)垂直切片都能回答兩個(gè)問題行為是什么、哪個(gè)角色在哪個(gè)行為上還沒被驗(yàn)證。如何運(yùn)行與擴(kuò)展場景單元層核心狀態(tài)類如ParagraphOutputState在 paragraph-output-state.spec.ts 中用 Vitest 直接構(gòu)造斷言按 AGENTS.md 的約定npm run test:shell覆蓋src/與兩個(gè)庫。E2E 層所有場景標(biāo)簽都掛在 Playwright 套件上運(yùn)行入口為mvnw verify -Pweb-e2e對(duì)應(yīng) CI 的run-playwright-e2e-tests任務(wù)。測試文件通過test(..., { tag: NB-PARITY-XXX }, ...)聲明標(biāo)簽因此可以用標(biāo)簽精確篩選場景執(zhí)行。擴(kuò)展一個(gè)場景的標(biāo)準(zhǔn)流程由校驗(yàn)器倒逼在e2e/scenarios/notebook-parity.json的scenarios數(shù)組追加新對(duì)象id必須大于已有最大 ID 且遵守NB-PARITY-[0-9]{3}命名area從枚舉中選至少提供 implementationEvidence 或 verificationEvidence 之一并按其語義填寫coverage在e2e/tests/notebook/下編寫對(duì)應(yīng)的 Playwright 測試并聲明NB-PARITY-XXX標(biāo)簽注意校驗(yàn)器會(huì)檢查 AST跳過describe.skip內(nèi)的調(diào)用運(yùn)行npm run generate:notebook-parity-scenarios重新生成 Markdown提交時(shí)validateRegistry含checkMarkdown會(huì)校驗(yàn) schema、ID 順序、證據(jù)路徑存在性、標(biāo)簽可執(zhí)行性與 Markdown 新鮮度任何一環(huán)不滿足都會(huì)阻止合并。小結(jié)zeppelin-web-angular/e2e/scenarios/notebook-parity.md表面是一張場景表實(shí)質(zhì)是一套把行為對(duì)等工程化的治理機(jī)制JSON 作為唯一事實(shí)來源、Schema 定義合法形狀、腳本生成文檔、AST 校驗(yàn)測試標(biāo)簽、狀態(tài)機(jī)區(qū)分 covered/partial/gap、角色期望與驗(yàn)證分離。對(duì) Zeppelin 的 Angular → React 遷移而言它是可回溯的行為契約對(duì)任何正在做前端框架遷移的團(tuán)隊(duì)而言它也是一個(gè)可復(fù)制的遷移行為記賬范式——先寫行為再寫實(shí)現(xiàn)用可執(zhí)行的證據(jù)閉環(huán)防止回歸。贊分享數(shù)據(jù)分析數(shù)據(jù)可視化大數(shù)據(jù)后端前端任務(wù)調(diào)度【免費(fèi)下載鏈接】zeppelinWeb-based notebook that enables>項(xiàng)目地址https://gitcode.com/gh_mirrors/zeppe/zeppelin點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Apache Zeppelin 手動(dòng)升級(jí)指南notebook 與配置遷移全流程Apache Zeppelin 手動(dòng)升級(jí)指南notebook 與配置遷移全流程 本篇指南以 Apache Zeppelin 官方手動(dòng)升級(jí)流程為核心系統(tǒng)講數(shù)據(jù)分析數(shù)據(jù)可視化大數(shù)據(jù)后端前端任務(wù)調(diào)度JupyterLab與Notebook對(duì)比分析與應(yīng)用場景JupyterLab與Notebook對(duì)比分析與應(yīng)用場景 本文深入對(duì)比分析了Jupyter生態(tài)系統(tǒng)中的兩大核心編輯器——JupyterLab與Jupyter N開發(fā)工具Apache Zeppelin Notebook 授權(quán)Notebook Authorization配置與實(shí)踐指南Apache Zeppelin Notebook 授權(quán)Notebook Authorization配置與實(shí)踐指南 本指南講解如何在 Apache Zeppe數(shù)據(jù)分析數(shù)據(jù)可視化大數(shù)據(jù)后端前端任務(wù)調(diào)度上一篇3分鐘搞定Chrome瀏覽器Markdown閱讀難題markdownReader完全指南下一篇AGENTS.md 巨型指令文件為何失敗用 Progressive Disclosure 拆分指令路由learn-harness-engineering 實(shí)戰(zhàn)創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考