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 diff --git a/packages/blockly/scripts/gulpfiles/test_tasks.mjs b/packages/blockly/scripts/gulpfiles/test_tasks.mjs index 37f9884440d..a47c0918d09 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'); } /** @@ -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'); } 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...');