From 19017de4bd65062c7be3c36e9e606d038de90f51 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 Aug 2025 23:04:26 +0000 Subject: [PATCH 1/2] Initial plan From 6ff29b60491534286bcba790b4925ea7b3590764 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 Aug 2025 23:24:47 +0000 Subject: [PATCH 2/2] Add comprehensive integration tests for build system and HTML loading Co-authored-by: trojal <1402635+trojal@users.noreply.github.com> --- jest.config.js | 11 ++ package.json | 7 +- tests/integration/README.md | 83 +++++++++++++++ tests/integration/build.test.js | 133 +++++++++++++++++++++++ tests/integration/html-loading.test.js | 139 +++++++++++++++++++++++++ 5 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 jest.config.js create mode 100644 tests/integration/README.md create mode 100644 tests/integration/build.test.js create mode 100644 tests/integration/html-loading.test.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..d9f43f3a --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +module.exports = { + testEnvironment: 'node', + testMatch: ['**/tests/**/*.test.js'], + testTimeout: 30000, + coverageDirectory: 'coverage', + collectCoverageFrom: [ + 'applications/tools/**/*.js', + '!**/node_modules/**', + '!**/dist/**' + ] +}; \ No newline at end of file diff --git a/package.json b/package.json index d345c5f0..ebaec676 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "build:all": "npm run build -- --all", "build:all:minify": "npm run build -- --all --m", "build:pwa": "npm run build -- --O --T --PWA", - "build:nw": "build --concurrent --tasks win-x86,win-x64 --mirror https://dl.nwjs.io/ ./applications/nwjs" + "build:nw": "build --concurrent --tasks win-x86,win-x64 --mirror https://dl.nwjs.io/ ./applications/nwjs", + "test": "jest", + "test:integration": "jest tests/integration" }, "author": "Vincent Thibault", "license": "GNU GPL V3", @@ -29,7 +31,8 @@ "nw": "^0.99.0-sdk", "nwjs-builder-phoenix": "^1.15.0", "requirejs": "^2.3.6", - "terser": "^5.19.4" + "terser": "^5.19.4", + "jest": "^29.7.0" }, "build": { "nwVersion": "stable", diff --git a/tests/integration/README.md b/tests/integration/README.md new file mode 100644 index 00000000..d9582d63 --- /dev/null +++ b/tests/integration/README.md @@ -0,0 +1,83 @@ +# Integration Tests + +This directory contains integration tests for the browserLegacy repository, specifically testing the build/compression system and HTML page loading functionality. + +## Overview + +The integration tests validate two main areas: + +1. **Build System Tests** (`build.test.js`) - Tests the JavaScript compilation and compression process +2. **HTML Loading Tests** (`html-loading.test.js`) - Tests HTML page structure and configuration + +## Running Tests + +To run all integration tests: +```bash +npm test +``` + +To run only integration tests: +```bash +npm run test:integration +``` + +To run specific test suites: +```bash +# Build system tests only +npx jest tests/integration/build.test.js + +# HTML loading tests only +npx jest tests/integration/html-loading.test.js +``` + +## Test Coverage + +### Build System Tests + +- **JavaScript Build Process** + - Validates ThreadEventHandler builds successfully + - Validates GrfViewer builds successfully + - Confirms output files are created with expected content + +- **JavaScript Compression Process** + - Tests minification functionality + - Validates minified output contains required components (headers, require.js) + +- **Build Validation** + - Checks that all application cases exist in builder + - Validates output file format and structure + +### HTML Loading Tests + +- **HTML Structure Validation** + - Validates main index.html structure + - Tests tool HTML files (action.html, altitude.html, etc.) + - Checks build tool interface HTML + +- **Application Configuration Validation** + - Validates ROConfig object in index.html + - Tests RequireJS configurations in test files + +- **Resource Loading Validation** + - Confirms required JavaScript dependencies exist + - Validates core module AMD structure + +## Requirements + +The tests require the following dependencies: +- Jest testing framework +- Node.js file system and child process modules + +## Test Timeouts + +Build tests have extended timeouts (60 seconds) due to the compilation process time. The test framework is configured with a 30-second default timeout. + +## Adding New Tests + +When adding new tests: + +1. Place build-related tests in `build.test.js` +2. Place HTML/page-related tests in `html-loading.test.js` +3. Use appropriate timeouts for build operations +4. Clean up generated files in test cleanup hooks +5. Follow the existing test patterns for consistency \ No newline at end of file diff --git a/tests/integration/build.test.js b/tests/integration/build.test.js new file mode 100644 index 00000000..3901974a --- /dev/null +++ b/tests/integration/build.test.js @@ -0,0 +1,133 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +describe('Build System Integration Tests', () => { + const distPath = path.join(process.cwd(), 'dist', 'Web'); + + beforeEach(() => { + // Clean dist directory before each test + if (fs.existsSync(distPath)) { + fs.rmSync(distPath, { recursive: true, force: true }); + } + }); + + afterAll(() => { + // Clean up after all tests + if (fs.existsSync(distPath)) { + fs.rmSync(distPath, { recursive: true, force: true }); + } + }); + + describe('JavaScript Build Process', () => { + test('should build ThreadEventHandler successfully', () => { + const output = execSync('npm run build:threadhandler', { + encoding: 'utf8', + cwd: process.cwd(), + timeout: 60000 // 60 second timeout + }); + + expect(output).toContain('ThreadEventHandler.js has been created'); + + const outputFile = path.join(distPath, 'ThreadEventHandler.js'); + expect(fs.existsSync(outputFile)).toBe(true); + + const stats = fs.statSync(outputFile); + expect(stats.size).toBeGreaterThan(1000); + }); + + test('should build GrfViewer successfully', () => { + const output = execSync('npm run build -- -D', { + encoding: 'utf8', + cwd: process.cwd(), + timeout: 60000 // 60 second timeout + }); + + expect(output).toContain('GrfViewer.js has been created'); + + const outputFile = path.join(distPath, 'GrfViewer.js'); + expect(fs.existsSync(outputFile)).toBe(true); + + const stats = fs.statSync(outputFile); + expect(stats.size).toBeGreaterThan(1000); + }); + }); + + describe('JavaScript Compression Process', () => { + test('should build and minify ThreadEventHandler', () => { + // Test minified build with smaller application + const output = execSync('npm run build -- -T --m', { + encoding: 'utf8', + cwd: process.cwd(), + timeout: 60000 + }); + + expect(output).toContain('ThreadEventHandler.js has been created'); + expect(output).toContain('Minifying'); + + const outputFile = path.join(distPath, 'ThreadEventHandler.js'); + expect(fs.existsSync(outputFile)).toBe(true); + + // Minified file should still be substantial + const stats = fs.statSync(outputFile); + expect(stats.size).toBeGreaterThan(1000); + }); + + test('should verify minified code contains required components', () => { + execSync('npm run build -- -T --m', { + encoding: 'utf8', + cwd: process.cwd(), + timeout: 60000 + }); + + const outputFile = path.join(distPath, 'ThreadEventHandler.js'); + const content = fs.readFileSync(outputFile, 'utf8'); + + // Should contain header comment + expect(content).toContain('Build with RONW Builder'); + expect(content).toContain('ROBrowser'); + + // Should contain require.js + expect(content).toContain('require'); + }); + }); + + describe('Build Validation', () => { + test('should validate all build applications exist', () => { + const builderPath = path.join(process.cwd(), 'applications', 'tools', 'builder-web.js'); + const builderContent = fs.readFileSync(builderPath, 'utf8'); + + // Extract application names from builder + const appMatches = builderContent.match(/case "([^"]+)":/g); + expect(appMatches).toBeTruthy(); + expect(appMatches.length).toBeGreaterThan(5); // Should have multiple applications + + // Verify some key applications are included + expect(builderContent).toContain('case "ThreadEventHandler"'); + expect(builderContent).toContain('case "Online"'); + expect(builderContent).toContain('case "GrfViewer"'); + }); + + test('should verify builder output format', () => { + execSync('npm run build:threadhandler', { + encoding: 'utf8', + cwd: process.cwd(), + timeout: 60000 + }); + + const outputFile = path.join(distPath, 'ThreadEventHandler.js'); + const content = fs.readFileSync(outputFile, 'utf8'); + + // Check for proper JavaScript structure + expect(content).toMatch(/function\s*\(/); // Should contain functions + + // Should contain header + expect(content).toContain('Build with RONW Builder'); + expect(content).toContain('ROBrowser'); + + // Should contain define calls (AMD modules) + expect(content).toContain('define('); + expect(content).toContain('require'); + }); + }); +}); \ No newline at end of file diff --git a/tests/integration/html-loading.test.js b/tests/integration/html-loading.test.js new file mode 100644 index 00000000..ae2e049f --- /dev/null +++ b/tests/integration/html-loading.test.js @@ -0,0 +1,139 @@ +const fs = require('fs'); +const path = require('path'); + +describe('HTML Page Loading Integration Tests', () => { + + describe('HTML Structure Validation', () => { + test('should validate main index.html structure', () => { + const indexPath = path.join(process.cwd(), 'index.html'); + expect(fs.existsSync(indexPath)).toBe(true); + + const content = fs.readFileSync(indexPath, 'utf8'); + + // Basic HTML structure + expect(content).toContain(''); + expect(content).toContain(''); + expect(content).toContain(''); + expect(content).toContain(''); + + // ROBrowser specific content + expect(content).toContain('ROConfig'); + expect(content).toContain('Online.js'); + expect(content).toContain('TitanRO2'); + }); + + test('should validate test HTML files structure', () => { + const testFiles = [ + 'applications/tools/tests/action.html', + 'applications/tools/tests/altitude.html', + 'applications/tools/tests/targa.html' + ]; + + testFiles.forEach(testFile => { + const filePath = path.join(process.cwd(), testFile); + if (fs.existsSync(filePath)) { + const content = fs.readFileSync(filePath, 'utf8'); + + // Basic HTML structure + expect(content).toContain(''); + expect(content).toContain(''); + expect(content).toContain(' { + const buildIndexPath = path.join(process.cwd(), 'applications', 'tools', 'build', 'index.html'); + expect(fs.existsSync(buildIndexPath)).toBe(true); + + const content = fs.readFileSync(buildIndexPath, 'utf8'); + + // Build tool specific content + expect(content).toContain('Compilation Tool'); + expect(content).toContain('data-app="App/Online"'); + expect(content).toContain('data-app="Core/ThreadEventHandler"'); + expect(content).toContain('data-app="App/GrfViewer"'); + }); + }); + + describe('Application Configuration Validation', () => { + test('should validate ROConfig in index.html', () => { + const indexPath = path.join(process.cwd(), 'index.html'); + const content = fs.readFileSync(indexPath, 'utf8'); + + // Extract ROConfig object + const configMatch = content.match(/ROConfig\s*=\s*{[\s\S]*?};/); + expect(configMatch).toBeTruthy(); + + const configStr = configMatch[0]; + + // Validate config properties + expect(configStr).toContain('development:'); + expect(configStr).toContain('servers:'); + expect(configStr).toContain('TitanRO2'); + expect(configStr).toContain('packetver:'); + }); + + test('should validate test configurations', () => { + const testConfigFiles = [ + 'applications/tools/tests/action.html' + ]; + + testConfigFiles.forEach(testFile => { + const filePath = path.join(process.cwd(), testFile); + if (fs.existsSync(filePath)) { + const content = fs.readFileSync(filePath, 'utf8'); + + // Should have basic RequireJS config + expect(content).toContain('baseUrl:'); + expect(content).toContain('paths:'); + expect(content).toContain('text:'); + expect(content).toContain('jquery:'); + } + }); + }); + }); + + describe('Resource Loading Validation', () => { + test('should validate required JavaScript dependencies exist', () => { + const requiredFiles = [ + 'src/Vendors/require.js', + 'src/Vendors/text.require.js', + 'src/Vendors/jquery-1.9.1.js' + ]; + + requiredFiles.forEach(file => { + const filePath = path.join(process.cwd(), file); + expect(fs.existsSync(filePath)).toBe(true); + + if (fs.existsSync(filePath)) { + const stats = fs.statSync(filePath); + expect(stats.size).toBeGreaterThan(0); + } + }); + }); + + test('should validate core module structure', () => { + const coreModules = [ + 'src/Core/Client.js', + 'src/Core/Thread.js', + 'src/Core/Configs.js' + ]; + + coreModules.forEach(module => { + const modulePath = path.join(process.cwd(), module); + if (fs.existsSync(modulePath)) { + const content = fs.readFileSync(modulePath, 'utf8'); + + // Should be AMD modules + expect(content).toContain('define('); + expect(content).toMatch(/return\s+\w+/); // Should return something + } + }); + }); + }); +}); \ No newline at end of file