NORTHSET
Proof-of-Pass Receipt — M-008
CONTRIBUTOR SELF-RUN — NOT MAINTAINER VERIFICATION
Project
RaspberryPiFoundation/blockly-samples
Work
workspace-search buttons need type=button · PR #2748
Verification execution
runtime: northset-oss executor v0
human operator: aeziz
Code
- base
c37ab067e848da5e8b136d4cf16d8cdffc653ee5- recorded patch commit
db5ccc98b2dcb5751fb2121075e067e0439ced40
declared metadata; not execution-bound- patch diff SHA-256
sha256:d171e1897e488dbb5f732e13f892ab2380eec800be4d4aea07862dd413fad922
bound to executed patch bytes
Environment
- image reference
- node:22-bookworm
- repository digest
node@sha256:a25c9934ff6382cd4f08b6bc26c82bf4ea69b1e6f8dabfb2ead457374127c365- network
- phaseA:bridge,phaseB:none
Declared checks
Execution summary
1/1 declared command returned exit 0 in the recorded environment
npm run test --workspace=@blockly/plugin-workspace-searchexit 0 · 6.5s
unclassified executor time (derived residual) 2m09s
run wall (derived from recorded timestamps) 2m16s
PASS — 1/1 declared command
Every command listed returned exit 0 in the declared environment. Only the listed commands are in scope. Unlisted test, lint, typecheck, build, coverage, compiler, full-suite, and CI gates are not implied or recorded.
Public scope interpretation
The declared network-off check runs the workspace-search plugin's Mocha unit suite (17 tests including the new button-type regression test) on Node 22, after a disclosed online phase-A install (npm ci + the plugin's build, npm cache redirected to /workspace/.npmcache). It does not run the full monorepo test/lint/format matrix; upstream CI additionally runs Node 22 and 24, eslint, and prettier --check across all packages.
Record details
- payment
- none · not merge-contingent
- redactions
- 1 email
- Bundle contents digest
sha256:58c3a6dd0c2e142a486cdf7c7e112fa6aa75affcc6c77a139fd5a694cf0cd64c- Signed asset SHA-256
sha256:78d81249cc1b429983365ad72de44971530936d65e938f42cdc75b8e1eb56638- Signed provenance recorded
- verified 2026-07-14T14:21:48Z
NOT INCLUDED
- Does not prove code quality
- Does not prove security
- Contributor self-run record of Northset's own contribution; not the maintainer's verification.
- The declared network-off check runs the workspace-search plugin's Mocha unit suite (17 tests including the new button-type regression test) on Node 22, after a disclosed online phase-A install (npm ci + the plugin's build, npm cache redirected to /workspace/.npmcache). It does not run the full monorepo test/lint/format matrix; upstream CI additionally runs Node 22 and 24, eslint, and prettier --check across all packages.
Signed bundle
Verify this receipt
gh attestation verify run-record-M-008.tar.gz --repo northset-oss/verification-pilot --signer-workflow northset-oss/verification-pilot/.github/workflows/attest-bundle.ymlAttestation confirms that Northset's signing workflow produced this exact bundle. The signer does not witness the recorded run, and verification does not turn it into maintainer verification.
QR → receipt pageCommitted patch.diff
diff --git a/plugins/workspace-search/src/workspace_search.ts b/plugins/workspace-search/src/workspace_search.ts
index dbb0bcb3a29fca5a61854f29dbced25d9a8e4192..81268317ae9d1fdf7bc39b7320a5b761a0d7398d 100644
--- a/plugins/workspace-search/src/workspace_search.ts
+++ b/plugins/workspace-search/src/workspace_search.ts
@@ -282,6 +282,7 @@ export class WorkspaceSearch implements Blockly.IPositionable {
// Create the button
const btn = document.createElement('button');
Blockly.utils.dom.addClass(btn, className);
+ btn.type = 'button';
btn.setAttribute('aria-label', text);
return btn;
}
diff --git a/plugins/workspace-search/test/workspace_search_test.mocha.js b/plugins/workspace-search/test/workspace_search_test.mocha.js
index 1e231adf8a1c6dfae6de24a5dd95061e6c140631..5ab7e35dc9747df9d664de20f286c5c7a990694a 100644
--- a/plugins/workspace-search/test/workspace_search_test.mocha.js
+++ b/plugins/workspace-search/test/workspace_search_test.mocha.js
@@ -101,6 +101,24 @@ suite('WorkspaceSearch', function () {
});
});
+ suite('createBtn()', function () {
+ test('Buttons have type button', function () {
+ this.workspaceSearch.init();
+ const nextBtn = document.querySelector(
+ 'button.blockly-ws-search-next-btn',
+ );
+ const previousBtn = document.querySelector(
+ 'button.blockly-ws-search-previous-btn',
+ );
+ const closeBtn = document.querySelector(
+ 'button.blockly-ws-search-close-btn',
+ );
+ assert.equal(nextBtn.type, 'button');
+ assert.equal(previousBtn.type, 'button');
+ assert.equal(closeBtn.type, 'button');
+ });
+ });
+
suite('dispose()', function () {
test('DOM is disposed', function () {
this.workspaceSearch.init();
Redacted stdout
=== cmd 1: npm run test --workspace=@blockly/plugin-workspace-search ===
> @[REDACTED:email] test
> blockly-scripts test
Building tests for @blockly/plugin-workspace-search
assets by path [1m[32m../dist/src/*.ts[39m[22m 8.94 KiB
asset [1m[32m../dist/src/workspace_search.d.ts[39m[22m 8.57 KiB [1m[33m[compared for emit][39m[22m
asset [1m[32m../dist/src/css.d.ts[39m[22m 216 bytes [1m[33m[compared for emit][39m[22m
asset [1m[32m../dist/src/index.d.ts[39m[22m 159 bytes [1m[33m[compared for emit][39m[22m
assets by path [1m[32m../dist/src/*.map[39m[22m 2.66 KiB
asset [1m[32m../dist/src/workspace_search.d.ts.map[39m[22m 2.36 KiB [1m[33m[compared for emit][39m[22m
asset [1m[32m../dist/src/css.d.ts.map[39m[22m 158 bytes [1m[33m[compared for emit][39m[22m
asset [1m[32m../dist/src/index.d.ts.map[39m[22m 141 bytes [1m[33m[compared for emit][39m[22m
asset [1m[32mworkspace_search_test.mocha.js[39m[22m 7.46 MiB [1m[33m[compared for emit][39m[22m (name: workspace_search_test)
runtime modules 937 bytes 4 modules
modules by path [1m../../node_modules/[39m[22m 1.2 MiB 154 modules
modules by path [1m./[39m[22m 38.8 KiB
[1m./test/workspace_search_test.mocha.js[39m[22m 16.8 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1m./src/index.ts[39m[22m 124 bytes [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1m./src/workspace_search.ts[39m[22m 18.9 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1m./src/css.ts[39m[22m 3.08 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
optional modules 84 bytes [1m[33m[optional][39m[22m
[1mexternal "timers"[39m[22m 42 bytes [1m[33m[optional][39m[22m [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1mexternal "timers/promises"[39m[22m 42 bytes [1m[33m[optional][39m[22m [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1mexternal "assert"[39m[22m 42 bytes [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1mexternal "jsdom"[39m[22m 42 bytes [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
[1mexternal "util"[39m[22m 42 bytes [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
webpack 5.107.2 compiled [1m[32msuccessfully[39m[22m in 2750 ms
Running tests for @blockly/plugin-workspace-search
WorkspaceSearch
init()
✔ CSS is injected at init()
✔ DOM is intialized at init()
createBtn()
✔ Buttons have type button
dispose()
✔ DOM is disposed
searchAndHighlight()
✔ Match all blocks
✔ Match no blocks
✔ Match all non-fields
✔ Match all field and collapsed blocks
✔ Preserve current, in results
✔ Preserve current, not in results
next()
✔ next() with unset current
✔ next() wrap around
previous()
✔ previous() with unset current
✔ previous() wrap around
focus
✔ close with match focuses found block
✔ close with no match restores focus to workspace
✔ close with match followed by non-match still focuses last found block
17 passing (554ms)
Redacted stderr
=== cmd 1: npm run test --workspace=@blockly/plugin-workspace-search ===
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
(node:29) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 17)
(Use `node --trace-warnings ...` to show where the warning was created)
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.