From f1b44c25ff6d715cd3b9f65bc09be7cb6801c152 Mon Sep 17 00:00:00 2001 From: B_head Date: Thu, 9 Apr 2026 04:57:33 +0900 Subject: [PATCH 1/4] fix: use posixPath for webdriver file:// URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generators and compile webdriver scripts built `file://` URLs by concatenating `__dirname` directly. On Windows `__dirname` contains backslashes, which yields a malformed URL like `file://S:\source\blockly\.../tests/compile/index.html` that Chrome refuses to load — making the `generators` and `advanced_compile_in_browser` test steps fail. Route both URLs through the existing `posixPath()` helper in `scripts/helpers.js`, matching the pattern already used in `tests/mocha/webdriver.js`. The helper is a no-op on POSIX so this keeps existing Linux/macOS behaviour unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/blockly/tests/compile/webdriver.js | 3 ++- packages/blockly/tests/generators/webdriver.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/blockly/tests/compile/webdriver.js b/packages/blockly/tests/compile/webdriver.js index 3e07ca23ec2..26332479002 100644 --- a/packages/blockly/tests/compile/webdriver.js +++ b/packages/blockly/tests/compile/webdriver.js @@ -9,6 +9,7 @@ * Chrome, via webdriver. */ const webdriverio = require('webdriverio'); +const {posixPath} = require('../../scripts/helpers'); /** @@ -51,7 +52,7 @@ async function runCompileCheckInBrowser() { }; } - const url = 'file://' + __dirname + '/index.html'; + const url = 'file://' + posixPath(__dirname) + '/index.html'; console.log('Starting webdriverio...'); const browser = await webdriverio.remote(options); diff --git a/packages/blockly/tests/generators/webdriver.js b/packages/blockly/tests/generators/webdriver.js index 004b5c878a2..3241953701c 100644 --- a/packages/blockly/tests/generators/webdriver.js +++ b/packages/blockly/tests/generators/webdriver.js @@ -10,6 +10,7 @@ var webdriverio = require('webdriverio'); var fs = require('fs'); var path = require('path'); +var {posixPath} = require('../../scripts/helpers'); /** @@ -60,7 +61,7 @@ async function runGeneratorsInBrowser(outputDir) { options.capabilities['goog:chromeOptions'].args.push('--disable-gpu'); } - var url = 'file://' + __dirname + '/index.html'; + var url = 'file://' + posixPath(__dirname) + '/index.html'; var prefix = path.join(outputDir, 'generated'); console.log('Starting webdriverio...'); From 2e3a65250096df02f313c686856ed546d8a412de Mon Sep 17 00:00:00 2001 From: B_head Date: Thu, 9 Apr 2026 04:57:49 +0900 Subject: [PATCH 2/4] chore: force LF line endings via .gitattributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `eslint-plugin-prettier` inherits Prettier's `endOfLine: 'lf'` default, so any source file checked out with CRLF on a Windows machine that has `core.autocrlf=true` fails lint with `Delete \`␍\`` errors. Setting `* text=auto eol=lf` makes git always check out detected text files with LF regardless of the user's local autocrlf setting, removing the class of failures at its source. Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitattributes | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 176a458f94e..81038ee4e15 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,4 @@ -* text=auto +# Force LF on checkout for all detected text files. Without this, Windows +# users with core.autocrlf=true get CRLF in source files, which makes +# Prettier (run as an ESLint rule) fail with "Delete `␍`" errors. +* text=auto eol=lf From 0fbeff96dc26be6bf90dc95c9c7671d4f6d7c6f5 Mon Sep 17 00:00:00 2001 From: B_head Date: Thu, 9 Apr 2026 04:58:23 +0900 Subject: [PATCH 3/4] fix: invoke validate-renamings.mjs via node The renamings test step ran the `.mjs` file directly via execSync, relying on its `#!/usr/bin/env node` shebang. Windows `cmd.exe` does not honor shebangs and `.mjs` has no default file association, so the step failed with "is not recognized as an internal or external command". Prefix the invocation with `node` so it works on every platform. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/blockly/scripts/gulpfiles/test_tasks.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blockly/scripts/gulpfiles/test_tasks.mjs b/packages/blockly/scripts/gulpfiles/test_tasks.mjs index 37f9884440d..8b0270af708 100644 --- a/packages/blockly/scripts/gulpfiles/test_tasks.mjs +++ b/packages/blockly/scripts/gulpfiles/test_tasks.mjs @@ -153,7 +153,7 @@ function build() { * @return {Promise} Asynchronous result. */ function renamings() { - return runTestCommand('renamings', 'tests/migration/validate-renamings.mjs'); + return runTestCommand('renamings', 'node tests/migration/validate-renamings.mjs'); } /** From 1fecb83ed808866ccbc40676f0dd825e232f50a4 Mon Sep 17 00:00:00 2001 From: B_head Date: Thu, 9 Apr 2026 04:59:02 +0900 Subject: [PATCH 4/4] fix: auto-create blockly-test junction for node tests on Windows `tests/node/node_modules/blockly-test` is a git symlink (mode 120000) pointing at `../../../dist`. With `core.symlinks` disabled (the default on Windows) git checks it out as a 13-byte text file containing the link target literally, so `import 'blockly-test'` in `tests/node/run_node_test.mjs` fails with `ERR_MODULE_NOT_FOUND` and the `node` test step never runs. Add an `ensureBlocklyTestLink` helper that runs immediately before the node test step. It detects the broken state via `lstatSync`, replaces the file with a junction (which works on Windows without admin rights and is treated as a regular symlink on POSIX), then best-effort marks the path `skip-worktree` so the resulting "deleted symlink" diff stays out of `git status`. Unexpected failures of the skip-worktree step are surfaced as a warning rather than silently swallowed. The helper is idempotent and a no-op on Linux/macOS, where the git checkout already produces a usable symlink. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../blockly/scripts/gulpfiles/test_tasks.mjs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/packages/blockly/scripts/gulpfiles/test_tasks.mjs b/packages/blockly/scripts/gulpfiles/test_tasks.mjs index 8b0270af708..a47c0918d09 100644 --- a/packages/blockly/scripts/gulpfiles/test_tasks.mjs +++ b/packages/blockly/scripts/gulpfiles/test_tasks.mjs @@ -353,11 +353,48 @@ export async function generators() { }); } +/** + * Ensure tests/node/node_modules/blockly-test resolves to the packaged + * blockly bundle in dist/. + * + * The repository stores this path as a git symlink (mode 120000) pointing at + * ../../../dist. On Windows without core.symlinks enabled (the default), git + * checks it out as a plain text file containing the link target, which makes + * `import 'blockly-test'` in tests/node/run_node_test.mjs fail with + * ERR_MODULE_NOT_FOUND. Detect that case and replace it with a junction so the + * node tests can resolve the packaged blockly bundle. Also mark the path as + * skip-worktree so the resulting "deleted symlink" diff doesn't pollute + * `git status`. + */ +function ensureBlocklyTestLink() { + const linkPath = path.join('tests', 'node', 'node_modules', 'blockly-test'); + // throwIfNoEntry:false → returns undefined instead of throwing on ENOENT, + // so unrelated errors (EACCES, etc.) still propagate normally. + const stat = fs.lstatSync(linkPath, {throwIfNoEntry: false}); + if (stat && (stat.isSymbolicLink() || stat.isDirectory())) return; + if (stat) fs.rmSync(linkPath, {force: true}); + fs.mkdirSync(path.dirname(linkPath), {recursive: true}); + fs.symlinkSync(path.resolve(RELEASE_DIR), linkPath, 'junction'); + // Best-effort: silence the resulting "deleted symlink" diff in git status. + // Expected failure modes (not a git checkout, git not on PATH, file not in + // index) are non-fatal — the junction itself is enough to make the test + // pass. Surface anything unexpected as a warning so it isn't fully hidden. + try { + execSync(`git update-index --skip-worktree ${linkPath}`, {stdio: 'pipe'}); + } catch (e) { + console.warn( + `ensureBlocklyTestLink: could not mark ${linkPath} skip-worktree ` + + `(${e.stderr?.toString().trim() || e.message}). ` + + `'git status' may show this file as deleted.`); + } +} + /** * Run Node tests. * @return {Promise} Asynchronous result. */ function node() { + ensureBlocklyTestLink(); return runTestCommand('node', 'mocha tests/node --config tests/node/.mocharc.js'); }