test(blocks-screenshot): align mock workspace with scratch-blocks v2 API#637
Conversation
`blocks-screenshot.js` was already migrated to the v2 method-style API (`workspace.getCanvas()` / `workspace.getBubbleCanvas()`), but the unit test mock still exposed the v1 direct-property surface (`svgBlockCanvas_` / `svgBubbleCanvas_`). 9 tests failed with `TypeError: workspace.getBubbleCanvas is not a function` on feat/upstream-merge-2026-05 CI. Update `makeMockWorkspace` to return jest.fn-wrapped getters, and replace the one inline `svgBubbleCanvas_` access with the equivalent method call. Closes #636
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/fix/blocks-screenshot-getbubblecanvas/ |
…th comments Three coordinated fixes that together stop `toBlob()` from throwing `SecurityError: Tainted canvases may not be exported.` when the workspace contains the `@ruby:*` comments produced by the Ruby→Blocks converter: 1. Strip `<foreignObject>` from the BLOCK canvas clone, not only the bubble canvas. In scratch-blocks v2 (Blockly v12), block-attached comments are nested inside the block canvas and contain a `<foreignObject>` for the editing UI. Once the export SVG is loaded via `blob://`, those foreign objects taint the canvas. 2. Strip external `url(...)` references from injected `<style>` blocks via a new `stripExternalCssUrls` helper. The blocky stylesheet that carries the `blocklyText` color rules also contains `url(./static/blocks-media/.../sprites.png)` and friends — they're only used for cursors and toolbox sprite chrome, but the relative refs taint the rasteriser. 3. Drop hidden `<image>` elements that have an empty `href` (used as placeholders inside dynamic-block dropdowns, `display:none`). An empty href falls back to the document URL and tainted canvas under blob origin. Adds unit tests for each piece and exports `stripExternalCssUrls` for isolated testing. Verified live: project with `puts(a.max)` / `t.sort!` etc. that emit multiple `@ruby:*` comments now exports a PNG without errors.
|
手動動作確認中に追加の bug を発見したため、本 issue / PR の scope に含めました。 追加で修正した問題
原因3 つの canvas-taint 源があった:
修正
検証
dynamic block 実行確認merge の影響を受ける各 dynamic block を実機で flag → 実行 → 状態確認:
|
…t its joined string
`executeArrayMethod` (non-bang) reconstructed `items` from
`String(args.RECEIVER).split(' ')`. Scratch's `data_listcontents`
joins single-character items with NO separator (e.g. `[3,1,4,1,5,9,2,6]`
becomes `"31415926"`), so the split returned a single token and every
method (max/min/first/last/sort/join/reverse) returned that joined
string back rather than the computed value.
Walk the block tree from `util.thread.peekStack()` to find the
RECEIVER input block; if it's a `data_listcontents`, look up the list
directly via `target.lookupVariableById` / `lookupVariableByNameAndType`
and operate on `list.value`. Falls back to the space-split heuristic
for non-list receivers (e.g. literal strings).
Verified live: `arr = [3,1,4,1,5,9,2,6]` now reports
- arr.max = "9", arr.min = "1", arr.first = "3", arr.last = "6"
- arr.sort.join(",") = "1,1,2,3,4,5,6,9"
- arr.sort! mutates the list to [1,1,2,3,4,5,6,9]
- arr.join("-") = "1-1-2-3-4-5-6-9"
さらに重要なバグ発見 — 配列メソッドの実行結果が壊れていた「実行時にエラーがないことは当然として、結果が正しいことを確認してください」 という指示で実機検証したところ、新たな本番バグを発見したため scope に含めました。 現象
原因
修正
ハッシュ・文字列メソッドは多くが多文字なので影響を受けない (検証済み)。 動作確認実機 Playwright で 文字列・ハッシュ・bang 含む追加 18 ケースも全て期待値:
既存 unit test (42 件) も全て pass。 |
e15939b
into
feat/upstream-merge-2026-05
Summary
feat/upstream-merge-2026-05で CI を 9 件失敗させていたblocks-screenshot.test.jsのモックを scratch-blocks v2 の API に追従させる。本体blocks-screenshot.jsは既にworkspace.getCanvas()/workspace.getBubbleCanvas()を使う v2 形式に移行済みで、テストモックだけが v1 の直接プロパティアクセス (svgBlockCanvas_/svgBubbleCanvas_) のままだった。Changes Made
makeMockWorkspaceの戻り値を v2 メソッド形式に変更 (getCanvas/getBubbleCanvasをjest.fnで公開)workspace.svgBubbleCanvas_を直接参照していた 2 箇所をworkspace.getBubbleCanvas()経由 /workspace.getBubbleCanvas = jest.fn(() => null)に書き換えTest Coverage
ローカルで全 21 テスト緑、Prettier も pass。
Related Issues
Closes #636