From 743a77dc192b0cc00483e9b46484d9403a368338 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Smyrek?=
Date: Wed, 3 Jun 2026 14:37:00 +0200
Subject: [PATCH 1/3] Refactored tests to fix OS-related path handling.
---
.../tests/utils/parallelworker.js | 15 +++++++--------
.../tests/utils/automated-tests/getkarmaconfig.js | 2 +-
.../tests/utils/manual-tests/copyassets.js | 4 ++--
.../tests/utils/manual-tests/createserver.js | 4 +++-
.../tests/servetranslations.js | 4 ++--
5 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/packages/ckeditor5-dev-release-tools/tests/utils/parallelworker.js b/packages/ckeditor5-dev-release-tools/tests/utils/parallelworker.js
index aae303e51..bf2a40912 100644
--- a/packages/ckeditor5-dev-release-tools/tests/utils/parallelworker.js
+++ b/packages/ckeditor5-dev-release-tools/tests/utils/parallelworker.js
@@ -30,17 +30,16 @@ vi.mock( 'node:worker_threads', () => ( {
describe( 'parallelWorker (worker defined in executeInParallel())', () => {
it( 'should execute a module from specified path and pass a package path and task options as arguments', async () => {
+ const postMessage = vi.mocked( parentPort ).postMessage;
+
await import( '../../lib/utils/parallelworker.js' );
- // It's needed because `parallelworker` does not export anything. Instead, it processes
- // an asynchronous loop. We must wait until the current JavaScript loop ends. Adding a new promise at the end
- // forces it.
- await new Promise( resolve => {
- setTimeout( resolve, 100 );
- } );
+ // Importing the worker starts async work, so wait until it reports completion.
+ await vi.waitFor( () => {
+ expect( postMessage ).toHaveBeenCalledTimes( 2 );
+ expect( postMessage ).toHaveBeenCalledWith( 'done:package' );
+ }, { timeout: 1000 } );
- expect( vi.mocked( parentPort ).postMessage ).toHaveBeenCalledTimes( 2 );
- expect( vi.mocked( parentPort ).postMessage ).toHaveBeenCalledWith( 'done:package' );
expect( vi.mocked( virtual ) ).toHaveBeenCalledTimes( 2 );
expect( vi.mocked( virtual ) ).toHaveBeenCalledWith( '/home/ckeditor/packages/a', taskOptions );
expect( vi.mocked( virtual ) ).toHaveBeenCalledWith( '/home/ckeditor/packages/b', taskOptions );
diff --git a/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js b/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js
index f9d5a4fa8..55b8c70b4 100644
--- a/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js
+++ b/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js
@@ -119,7 +119,7 @@ describe( 'getKarmaConfig()', () => {
expect( karmaConfig.files ).toEqual( expect.arrayContaining( [
'workspace/entry-file.js',
expect.objectContaining( {
- pattern: expect.stringContaining( 'ckeditor5-utils/tests/_assets/**/*' )
+ pattern: expect.stringMatching( /ckeditor5-utils[/\\]tests[/\\]_assets[/\\]\*\*[/\\]\*/ )
} )
] ) );
} );
diff --git a/packages/ckeditor5-dev-tests/tests/utils/manual-tests/copyassets.js b/packages/ckeditor5-dev-tests/tests/utils/manual-tests/copyassets.js
index 4bb12d9c7..5383c71c1 100644
--- a/packages/ckeditor5-dev-tests/tests/utils/manual-tests/copyassets.js
+++ b/packages/ckeditor5-dev-tests/tests/utils/manual-tests/copyassets.js
@@ -31,7 +31,7 @@ describe( 'copyAssets()', () => {
const buildDir = '/build';
copyAssets( buildDir );
- expect( mkdirSync ).toHaveBeenCalledWith( buildDir + '/assets', expect.any( Object ) );
+ expect( mkdirSync ).toHaveBeenCalledWith( path.join( buildDir, 'assets' ), expect.any( Object ) );
expect( copyFileSync ).toHaveBeenCalledTimes( ASSETS.length + 1 );
const scriptPath = path.resolve( import.meta.dirname, '..', '..', '..', 'lib', 'utils', 'manual-tests' );
@@ -40,7 +40,7 @@ describe( 'copyAssets()', () => {
expect( copyFileSync ).toHaveBeenNthCalledWith(
index + 1,
path.resolve( scriptPath, assetPath ),
- path.resolve( buildDir, 'assets', path.basename( assetPath ) )
+ path.join( buildDir, 'assets', path.basename( assetPath ) )
);
}
} );
diff --git a/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js b/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js
index e67bf8cb8..4dc87f18b 100644
--- a/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js
+++ b/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js
@@ -31,6 +31,8 @@ describe( 'createManualTestServer()', () => {
info: loggerStub
} );
+ vi.spyOn( process, 'platform', 'get' ).mockReturnValue( 'linux' );
+
vi.spyOn( http, 'createServer' ).mockImplementation( ( ...theArgs ) => {
server = createServer( ...theArgs );
servers.push( server );
@@ -160,7 +162,7 @@ describe( 'createManualTestServer()', () => {
describe( 'request handler', () => {
beforeEach( async () => {
- createManualTestServer( 'workspace/build/.manual-tests', 49800 );
+ createManualTestServer( 'workspace/build/.manual-tests', 49700 );
await vi.waitFor( () => {
expect( loggerStub ).toHaveBeenCalled();
diff --git a/packages/ckeditor5-dev-translations/tests/servetranslations.js b/packages/ckeditor5-dev-translations/tests/servetranslations.js
index 3dbd4ad98..67e1612f1 100644
--- a/packages/ckeditor5-dev-translations/tests/servetranslations.js
+++ b/packages/ckeditor5-dev-translations/tests/servetranslations.js
@@ -30,7 +30,7 @@ describe( 'serveTranslations()', () => {
let cwdSpy;
beforeEach( () => {
- cwdSpy = vi.spyOn( process, 'cwd' ).mockReturnValue( '/project' );
+ cwdSpy = vi.spyOn( process, 'cwd' ).mockReturnValue( path.join( path.sep, 'project' ) );
vi.mocked( fs.existsSync ).mockReturnValue( false );
vi.mocked( fs.readFileSync ).mockReset();
vi.mocked( rimraf.sync ).mockReset();
@@ -141,7 +141,7 @@ describe( 'serveTranslations()', () => {
expect( module.loaders[ 0 ].options.translateSource( 'SOURCE', 'file.ts' ) ).to.equal( 'translated:file.ts' );
expect( translationService.translateSource ).toHaveBeenCalledWith( 'SOURCE', 'file.ts' );
expect(
- translationService.loadPackage.mock.calls.some( call => String( call[ 0 ] ).includes( 'packages/ckeditor5-foo/' ) )
+ translationService.loadPackage.mock.calls.some( call => /packages[/\\]ckeditor5-foo[/\\]/.test( String( call[ 0 ] ) ) )
).to.equal( true );
compilation.hooks.optimizeChunkAssets.call( [ { files: [ 'main.js', 'other.js' ] } ] );
From 25d65aa410d482202d5ea27a9363d10478f9146d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Smyrek?=
Date: Fri, 5 Jun 2026 07:52:57 +0200
Subject: [PATCH 2/3] Stop binding real webserver sockets in the unit tests.
---
.../tests/utils/manual-tests/createserver.js | 35 +++++++++++++++----
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js b/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js
index 4dc87f18b..9a127bad3 100644
--- a/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js
+++ b/packages/ckeditor5-dev-tests/tests/utils/manual-tests/createserver.js
@@ -37,7 +37,11 @@ describe( 'createManualTestServer()', () => {
server = createServer( ...theArgs );
servers.push( server );
- vi.spyOn( server, 'listen' );
+ vi.spyOn( server, 'listen' ).mockImplementation( ( _port, callback ) => {
+ process.nextTick( callback );
+
+ return server;
+ } );
return server;
} );
@@ -123,11 +127,28 @@ describe( 'createManualTestServer()', () => {
} );
it( 'should try next port when the requested port is in use', async () => {
- // Occupy the port first.
- const blockingServer = http.createServer.getMockImplementation()();
+ const originalCreateServer = http.createServer.getMockImplementation();
+ let attempt = 0;
+
+ vi.mocked( http.createServer ).mockImplementation( ( ...args ) => {
+ const currentServer = originalCreateServer( ...args );
+
+ attempt++;
- await new Promise( resolve => {
- blockingServer.listen( 49555, resolve );
+ if ( attempt === 1 ) {
+ vi.mocked( currentServer.listen ).mockImplementation( () => {
+ process.nextTick( () => {
+ const error = new Error( 'EADDRINUSE: port is already in use' );
+ error.code = 'EADDRINUSE';
+
+ currentServer.emit( 'error', error );
+ } );
+
+ return currentServer;
+ } );
+ }
+
+ return currentServer;
} );
createManualTestServer( 'workspace/build/.manual-tests', 49555 );
@@ -136,9 +157,9 @@ describe( 'createManualTestServer()', () => {
expect( loggerStub ).toHaveBeenCalledWith( '[Server] Server running at http://localhost:49556/' );
} );
+ expect( servers[ 0 ].listen ).toHaveBeenCalledWith( 49555, expect.any( Function ) );
+ expect( servers[ 1 ].listen ).toHaveBeenCalledWith( 49556, expect.any( Function ) );
expect( loggerStub ).toHaveBeenCalledWith( '[Server] Port 49555 is in use, trying 49556...' );
-
- blockingServer.close();
} );
it( 'should reject when a non-EADDRINUSE error occurs', async () => {
From 91dad47ab8419556105d85a3f35c4a92e08cf5c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Smyrek?=
Date: Fri, 5 Jun 2026 11:47:02 +0200
Subject: [PATCH 3/3] Simplified tests.
---
.../tests/utils/automated-tests/getkarmaconfig.js | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js b/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js
index 55b8c70b4..ee8fa5780 100644
--- a/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js
+++ b/packages/ckeditor5-dev-tests/tests/utils/automated-tests/getkarmaconfig.js
@@ -8,18 +8,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import getWebpackConfigForAutomatedTests from '../../../lib/utils/automated-tests/getwebpackconfig.js';
import getKarmaConfig from '../../../lib/utils/automated-tests/getkarmaconfig.js';
-vi.mock( 'node:path', async () => {
- const originalModule = await vi.importActual( 'node:path' );
-
- return {
- default: {
- join: vi.fn( ( ...chunks ) => chunks.join( '/' ) ),
- dirname: vi.fn(),
- resolve: originalModule.resolve
- }
- };
-} );
-
vi.mock( '../../../lib/utils/automated-tests/getwebpackconfig.js' );
vi.mock( '../../../lib/utils/resolve-path.js', () => ( {
@@ -119,7 +107,7 @@ describe( 'getKarmaConfig()', () => {
expect( karmaConfig.files ).toEqual( expect.arrayContaining( [
'workspace/entry-file.js',
expect.objectContaining( {
- pattern: expect.stringMatching( /ckeditor5-utils[/\\]tests[/\\]_assets[/\\]\*\*[/\\]\*/ )
+ pattern: expect.stringContaining( path.join( 'ckeditor5-utils', 'tests', '_assets', '**', '*' ) )
} )
] ) );
} );