Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['**/tests/**/*.test.js'],
testTimeout: 30000,
coverageDirectory: 'coverage',
collectCoverageFrom: [
'applications/tools/**/*.js',
'!**/node_modules/**',
'!**/dist/**'
]
};
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
83 changes: 83 additions & 0 deletions tests/integration/README.md
Original file line number Diff line number Diff line change
@@ -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
133 changes: 133 additions & 0 deletions tests/integration/build.test.js
Original file line number Diff line number Diff line change
@@ -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');
});
});
});
139 changes: 139 additions & 0 deletions tests/integration/html-loading.test.js
Original file line number Diff line number Diff line change
@@ -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('<!DOCTYPE html>');
expect(content).toContain('<html>');
expect(content).toContain('<head>');
expect(content).toContain('<body>');

// 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('<!DOCTYPE html>');
expect(content).toContain('<html>');
expect(content).toContain('<script');

// RequireJS integration
expect(content).toContain('require.js');
expect(content).toContain('FileTester');
}
});
});

test('should validate build tool HTML interface', () => {
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
}
});
});
});
});