diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index adfcd7c..6797971 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node_version: [16, 18, 20] + node_version: [20] os: [ubuntu-latest, windows-latest, macOS-latest] steps: diff --git a/.github/workflows/e2e-linux.yml b/.github/workflows/e2e-linux.yml index 9c8a0b3..ddab055 100644 --- a/.github/workflows/e2e-linux.yml +++ b/.github/workflows/e2e-linux.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: node_version: - - 18 + - 20 os: - ubuntu-latest target_features: diff --git a/.github/workflows/e2e-macOS.yml b/.github/workflows/e2e-macOS.yml index 24be806..e5677c1 100644 --- a/.github/workflows/e2e-macOS.yml +++ b/.github/workflows/e2e-macOS.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: node_version: - - 18 + - 20 os: - macOS-latest target_features: diff --git a/.github/workflows/e2e-windows.yml b/.github/workflows/e2e-windows.yml index 2ed9973..c1fb2ab 100644 --- a/.github/workflows/e2e-windows.yml +++ b/.github/workflows/e2e-windows.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: node_version: - - 18 + - 20 os: - windows-latest target_features: diff --git a/cli-bundler/package.json b/cli-bundler/package.json index 5731a41..8d1832d 100644 --- a/cli-bundler/package.json +++ b/cli-bundler/package.json @@ -3,7 +3,7 @@ "del": "^6.1.0", // @if requirejs - "requirejs": "^2.3.6", + "requirejs": "^2.3.7", // @endif // @if alameda "alameda": "^1.4.0", @@ -26,20 +26,20 @@ // @endif // @if postcss - "gulp-postcss": "^9.0.1", - "postcss": "^8.4.24", - "autoprefixer": "^10.4.14", - "cssnano": "^6.0.1", + "gulp-postcss": "^10.0.0", + "postcss": "^8.4.47", + "autoprefixer": "^10.4.20", + "cssnano": "^7.0.6", "postcss-url": "^10.1.3", // @endif // @if sass "gulp-dart-sass": "^1.1.0", - "node-sass-package-importer": "^5.3.2", + "node-sass-package-importer": "^5.3.3", // @endif // @if stylus - "gulp-stylus": "^3.0.0", + "gulp-stylus": "^3.0.1", // @endif // @if htmlmin @@ -49,8 +49,8 @@ "connect": "^3.7.0", "connect-history-api-fallback": "^2.0.0", "connect-injector": "^0.4.4", - "serve-static": "^1.15.0", - "socket.io": "^4.7.1", + "serve-static": "^1.16.2", + "socket.io": "^4.8.0", "open": "^8.4.0", "server-destroy": "^1.0.1", diff --git a/common/.eslintrc.json b/common/.eslintrc.json index 1108443..aaead5a 100644 --- a/common/.eslintrc.json +++ b/common/.eslintrc.json @@ -34,6 +34,7 @@ "no-unused-vars": 0, // @if typescript "@typescript-eslint/no-unused-vars": 0, + "@typescript-eslint/no-explicit-any": 0, // @endif "no-prototype-builtins": 0, "no-console": 0, diff --git a/common/babel.config.json__if_babel b/common/babel.config.json__if_babel index 36f111a..246a545 100644 --- a/common/babel.config.json__if_babel +++ b/common/babel.config.json__if_babel @@ -7,7 +7,7 @@ ], "plugins": [ ["@babel/plugin-proposal-decorators", { "version": "legacy" }], - ["@babel/plugin-proposal-class-properties", { "loose": true }], + ["@babel/plugin-transform-class-properties", { "loose": true }], "@babel/plugin-syntax-dynamic-import" ] } diff --git a/common/package.json b/common/package.json index 3a60df5..87b08d5 100644 --- a/common/package.json +++ b/common/package.json @@ -9,41 +9,40 @@ "license": "MIT", // @if ! plugin "dependencies": { - "aurelia-bootstrapper": "^2.4.0", + "aurelia-bootstrapper": "^2.4.1", "aurelia-animator-css": "^1.0.4" }, // @endif "devDependencies": { "eslint": "^8.43.0", - "aurelia-cli": "^3.0.1", + "aurelia-cli": "^3.0.3", "aurelia-testing": "^1.1.0", "gulp": "^4.0.2", - "gulp-eslint-new": "^1.8.1", + "gulp-eslint-new": "^2.3.0", "minimatch": "^5.1.2", "promise-polyfill": "^8.3.0", // @if plugin - "aurelia-bootstrapper": "^2.4.0", + "aurelia-bootstrapper": "^2.4.1", "aurelia-animator-css": "^1.0.4", // @endif // @if babel - "@babel/eslint-parser": "^7.22.5", - "@babel/plugin-proposal-decorators": "^7.22.5", - "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/eslint-parser": "^7.25.8", + "@babel/plugin-proposal-decorators": "^7.25.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/preset-env": "^7.22.5", - "@babel/core": "^7.22.5", - "@babel/register": "^7.18.9", - "regenerator-runtime": "^0.13.11", + "@babel/preset-env": "^7.25.8", + "@babel/core": "^7.25.8", + "@babel/register": "^7.25.7", + "regenerator-runtime": "^0.14.1", // @endif // @if typescript - "typescript": "^5.1.6", - "tslib": "^2.6.0", - "@types/node": "^18.11.18", - "@typescript-eslint/eslint-plugin": "^5.60.1", - "@typescript-eslint/parser": "^5.60.1", + "typescript": "^5.6.3", + "tslib": "^2.8.0", + "@types/node": "^22.7.8", + "@typescript-eslint/eslint-plugin": "^8.11.0", + "@typescript-eslint/parser": "^8.11.0", // @endif }, // @if postcss || babel diff --git a/e2e-test.js b/e2e-test.js index 5e750c8..02ddcba 100644 --- a/e2e-test.js +++ b/e2e-test.js @@ -7,17 +7,20 @@ const spawn = require('cross-spawn'); const fs = require('fs'); const path = require('path'); -const del = require('del'); const test = require('ava'); -const puppeteer = require('puppeteer'); const kill = require('tree-kill'); +async function delay(secs) { + return new Promise((resolve) => { + setTimeout(resolve, secs); + }); +} + const isWin32 = process.platform === 'win32'; -const dir = __dirname; -const folder = path.join(dir, 'test-skeletons'); +const folder = path.join(__dirname, 'test-skeletons'); console.log('-- cleanup ' + folder); -del.sync(folder); +fs.rmSync(folder, {recursive: true, force: true}); fs.mkdirSync(folder); // Somehow taskkill on windows would not send SIGTERM signal to proc, @@ -32,7 +35,7 @@ function killProc(proc) { } -function run(command, dataCB, errorCB) { +function run(command, cwd, dataCB, errorCB) { const [cmd, ...args] = command.split(' '); return new Promise((resolve, reject) => { const env = Object.create(process.env); @@ -41,8 +44,9 @@ function run(command, dataCB, errorCB) { // need to reset NODE_ENV back to development because this whole // test is running in NODE_ENV=test which will affect gulp build env.NODE_ENV = 'development'; - const proc = spawn(cmd, args, {env}); - proc.on('exit', (code, signal) => { + const proc = spawn(cmd, args, {env, cwd}); + proc.on('exit', async (code, signal) => { + await delay(1); if (code && signal !== 'SIGTERM' && !win32Killed.has(proc.pid)) { reject(new Error(cmd + ' ' + args.join(' ') + ' process exit code: ' + code + ' signal: ' + signal)); } else { @@ -55,33 +59,26 @@ function run(command, dataCB, errorCB) { if (dataCB) { dataCB(data, () => { console.log(`-- kill "${command}"`); - killProc(proc); + setTimeout(() => killProc(proc), 500); }); } }); proc.stderr.on('data', data => { process.stderr.write(data); - // Ingore webpack warning - if (data.toString().includes('DeprecationWarning')) return; + // Skip webpack5 deprecation warning. + if (data.toString().toLowerCase().includes('deprecation')) return; + // Skip BABEL warning (used by dumber bundler) when reading @aurelia/runtime-html + if (data.toString().includes('The code generator has deoptimised the styling')) return; if (errorCB) { errorCB(data, () => { console.log(`-- kill "${command}"`); - killProc(proc); + setTimeout(() => killProc(proc), 500); }); } }) }); } -async function takeScreenshot(url, filePath) { - const browser = await puppeteer.launch(); - const page = await browser.newPage(); - await page.goto(url); - await new Promise(r => setTimeout(r, 6000)); - await page.screenshot({path: filePath}); - await browser.close(); -} - const targetCLI = (process.env.TARGET_CLI || null); const targetFeatures = (process.env.TARGET_FEATURES || '').toLowerCase().split(',').filter(p => p); @@ -154,26 +151,24 @@ skeletons.forEach((features, i) => { test.serial(title, async t => { console.log(title); - process.chdir(folder); - const makeCmd = `npx makes ${dir} ${appName} -s ${features.join(',')}`; + const makeCmd = `npx makes ${__dirname} ${appName} -s ${features.join(',')}`; console.log('-- ' + makeCmd); - await run(makeCmd); + await run(makeCmd, folder); t.pass('made skeleton'); - process.chdir(appFolder); patchPackageJson(appFolder, targetCLI); console.log('-- npm i'); - await run('npm i'); + await run('npm i', appFolder); t.pass('installed deps'); console.log('-- npm test'); - await run('npm test'); + await run('npm test', appFolder); t.pass('finished unit tests'); console.log('-- npx au generate attribute NewThing'); - await run('npx au generate attribute NewThing', null, + await run('npx au generate attribute NewThing', appFolder, null, (data, kill) => { t.fail('au generate attribute failed: ' + data.toString()); } @@ -181,7 +176,7 @@ skeletons.forEach((features, i) => { t.pass('generated attribute'); console.log('-- npx au generate component NewThing .'); - await run('npx au generate component NewThing .', null, + await run('npx au generate component NewThing .', appFolder, null, (data, kill) => { t.fail('au generate component failed: ' + data.toString()); } @@ -189,7 +184,7 @@ skeletons.forEach((features, i) => { t.pass('generated component'); console.log('-- npx au generate element NewThing'); - await run('npx au generate element NewThing', null, + await run('npx au generate element NewThing', appFolder, null, (data, kill) => { t.fail('au generate element failed: ' + data.toString()); } @@ -197,7 +192,7 @@ skeletons.forEach((features, i) => { t.pass('generated element'); console.log('-- npx au generate value-converter NewThing'); - await run('npx au generate value-converter NewThing', null, + await run('npx au generate value-converter NewThing', appFolder, null, (data, kill) => { t.fail('au generate value-converter failed: ' + data.toString()); } @@ -205,7 +200,7 @@ skeletons.forEach((features, i) => { t.pass('generated value-converter'); console.log('-- npx au generate binding-behavior NewThing'); - await run('npx au generate binding-behavior NewThing', null, + await run('npx au generate binding-behavior NewThing', appFolder, null, (data, kill) => { t.fail('au generate binding-behavior failed: ' + data.toString()); } @@ -213,7 +208,7 @@ skeletons.forEach((features, i) => { t.pass('generated binding-behavior'); console.log('-- npx au generate task NewThing'); - await run('npx au generate task NewThing', null, + await run('npx au generate task NewThing', appFolder, null, (data, kill) => { t.fail('au generate task failed: ' + data.toString()); } @@ -221,7 +216,7 @@ skeletons.forEach((features, i) => { t.pass('generated task'); console.log('-- npx au generate generator NewThing'); - await run('npx au generate generator NewThing', null, + await run('npx au generate generator NewThing', appFolder, null, (data, kill) => { t.fail('au generate generator failed: ' + data.toString()); } @@ -229,7 +224,7 @@ skeletons.forEach((features, i) => { t.pass('generated generator'); console.log('-- npm run build'); - await run('npm run build', null, + await run('npm run build', appFolder, null, (data, kill) => { t.fail('build failed: ' + data.toString()); } @@ -242,36 +237,25 @@ skeletons.forEach((features, i) => { if (!m) return; const url = m[1]; t.pass(m[0]); - - try { - if (!process.env.GITHUB_ACTIONS) { - console.log('-- take screenshot'); - await takeScreenshot(url, path.join(folder, appName + '.png')); - } - kill(); - } catch (e) { - t.fail(e.message); - kill(); - } + kill(); }; // Webpack5 now prints Loopback: http://localhost:5000 in stderr! - await run('npm start', runE2e, runE2e); + await run('npm start', appFolder, runE2e, runE2e); if (features.includes('playwright')) { console.log('-- npx playwright test --project chromium'); - await run('npx playwright install --with-deps'); - await run('npx playwright test --project chromium'); + await run('npx playwright install --with-deps', appFolder); + await run('npx playwright test --project chromium', appFolder); } if (process.platform === 'linux' && features.includes('docker')) { console.log('-- npm run docker:build'); - await run(`npm run docker:build`); + await run(`npm run docker:build`, appFolder); t.pass('passed docker:build'); } console.log('-- remove folder ' + appName); - process.chdir(folder); - await del(appFolder); + await fs.promises.rm(appFolder, {recursive: true}); }); }); diff --git a/jest/package.json b/jest/package.json index ecefb22..0b9bf5e 100644 --- a/jest/package.json +++ b/jest/package.json @@ -1,18 +1,18 @@ { "devDependencies": { - "jest": "^29.5.0", - "jest-cli": "^29.5.0", + "jest": "^29.7.0", + "jest-cli": "^29.7.0", "jest-transform-stub": "^2.0.0", "aurelia-loader-nodejs": "^1.1.0", "aurelia-pal-nodejs": "^2.0.0", // @if babel - "babel-jest": "^29.5.0", + "babel-jest": "^29.7.0", // @endif // @if typescript - "ts-jest": "^29.1.0", - "@types/jest": "^29.5.2", + "ts-jest": "^29.2.5", + "@types/jest": "^29.5.13", // @endif }, "scripts": { diff --git a/karma/package.json b/karma/package.json index cdd6b7a..3c4f9e7 100644 --- a/karma/package.json +++ b/karma/package.json @@ -1,10 +1,10 @@ { "devDependencies": { - "jasmine-core": "^4.5.0", - "karma": "^6.4.2", + "jasmine-core": "^5.4.0", + "karma": "^6.4.4", "karma-chrome-launcher": "^3.2.0", "karma-jasmine": "^5.1.0", - "karma-sourcemap-loader": "^0.3.8", + "karma-sourcemap-loader": "^0.4.0", // @if babel "karma-babel-preprocessor": "^8.0.2", @@ -12,7 +12,7 @@ // @if typescript "karma-typescript-preprocessor": "^0.4.0", - "@types/jasmine": "^4.3.5", + "@types/jasmine": "^5.1.4", // @endif }, diff --git a/package.json b/package.json index bb6ce55..205c1f0 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,10 @@ "ava": "^3.15.0", "cross-env": "^7.0.3", "cross-spawn": "^7.0.3", - "del": "^6.0.0", "glob": "^10.3.1", "makes": "^3.2.0", "mock-fs": "^5.2.0", "npm-check-updates": "^16.10.13", - "puppeteer": "^20.7.3", "semver": "^7.5.3", "standard-changelog": "^3.0.0", "tree-kill": "^1.2.2", diff --git a/playwright/package.json b/playwright/package.json index 0aaf2ac..7ad00c0 100644 --- a/playwright/package.json +++ b/playwright/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "@playwright/test": "^1.35.1", + "@playwright/test": "^1.48.1", }, "scripts": { "e2e": "playwright test" diff --git a/plugin/test__if_karma_or_jest/unit/attributes__if_plugin-scaffold-basic/color.spec.ext b/plugin/test__if_karma_or_jest/unit/attributes__if_plugin-scaffold-basic/color.spec.ext index 913f6ca..640a2a5 100644 --- a/plugin/test__if_karma_or_jest/unit/attributes__if_plugin-scaffold-basic/color.spec.ext +++ b/plugin/test__if_karma_or_jest/unit/attributes__if_plugin-scaffold-basic/color.spec.ext @@ -11,7 +11,7 @@ describe('color attribute', () => { } }); - it('sets font color', done => { + it('sets font color', async () => { let model = {color: 'green'}; component = StageComponent @@ -24,13 +24,8 @@ describe('color attribute', () => { .inView('
') .boundTo(model); - component.create(bootstrap).then(() => { - const view = component.element; - expect(view.style.color).toBe('green'); - done(); - }).catch(e => { - fail(e); - done(); - }); + await component.create(bootstrap); + const view = component.element; + expect(view.style.color).toBe('green'); }); }); diff --git a/plugin/test__if_karma_or_jest/unit/binding-behaviors__if_plugin-scaffold-basic/primary-click.spec.ext b/plugin/test__if_karma_or_jest/unit/binding-behaviors__if_plugin-scaffold-basic/primary-click.spec.ext index aa2979c..0e8dcf4 100644 --- a/plugin/test__if_karma_or_jest/unit/binding-behaviors__if_plugin-scaffold-basic/primary-click.spec.ext +++ b/plugin/test__if_karma_or_jest/unit/binding-behaviors__if_plugin-scaffold-basic/primary-click.spec.ext @@ -28,7 +28,7 @@ describe('primaryClick binding behavior', () => { } }); - it('sets font color', done => { + it('sets font color', async () => { let hitted = false; function hit() { hitted = true; } @@ -45,19 +45,16 @@ describe('primaryClick binding behavior', () => { .boundTo(model); let view; - component.create(bootstrap).then(() => { - view = component.element; - fireEvent(view, 'click', {button: 0}); - }).then(delay).then(() => { - expect(hitted).toBe(true); - hitted = false; - fireEvent(view, 'click', {button: 1}); - }).then(delay).then(() => { - expect(hitted).toBe(false); - done(); - }).catch(e => { - fail(e); - done(); - }); + await component.create(bootstrap); + view = component.element; + fireEvent(view, 'click', {button: 0}); + await delay(); + + expect(hitted).toBe(true); + hitted = false; + fireEvent(view, 'click', {button: 1}); + await delay(); + + expect(hitted).toBe(false); }); }); diff --git a/plugin/test__if_karma_or_jest/unit/elements/hello-world.spec.ext b/plugin/test__if_karma_or_jest/unit/elements/hello-world.spec.ext index d1a7b70..b376fb0 100644 --- a/plugin/test__if_karma_or_jest/unit/elements/hello-world.spec.ext +++ b/plugin/test__if_karma_or_jest/unit/elements/hello-world.spec.ext @@ -11,7 +11,7 @@ describe('hello-world element', () => { } }); - it('says hello world with message', done => { + it('says hello world with message', async () => { let model = {message: 'from me'}; component = StageComponent @@ -24,13 +24,8 @@ describe('hello-world element', () => { .inView('