#!/usr/bin/env node /** * test_verify.mjs - Extension badge count verification test using Selenium WebDriver * * Verifies Rentgen's core functionality: counting third-party domains. * Tests two scenarios: * 1. Site without third-party domains (news.ycombinator.com) → badge = 0 * 2. Site with third-party domains (pudelek.pl) → badge > 0 */ import { Builder, By, until } from 'selenium-webdriver'; import firefox from 'selenium-webdriver/firefox.js'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const isTTY = process.stdout.isTTY; function red(text) { return isTTY ? `\x1b[91m${text}\x1b[0m` : text; } async function testBadgeCount() { let driver = null; try { // Load test library const testLibPath = join(__dirname, 'test-lib.js'); const testLib = readFileSync(testLibPath, 'utf-8'); // Find extension path (project root contains manifest.json and built files in lib/) const extensionPath = join(__dirname, '..'); console.log(' Launching Firefox with extension...'); // Set up Firefox options const options = new firefox.Options(); // Set headless mode based on environment if (process.env.HEADLESS !== 'false') { options.addArguments('-headless'); } // Create WebDriver instance driver = await new Builder() .forBrowser('firefox') .setFirefoxOptions(options) .build(); // Install the extension from the dist directory // Firefox WebDriver allows installing unpacked extensions console.log(' Installing extension...'); await driver.installAddon(extensionPath, true); // true = temporary install const results = {}; // Test 1: Site without third-party domains console.log(' Testing news.ycombinator.com (expected: 0 third-party domains)...'); await driver.get('https://news.ycombinator.com'); // Wait for page to load await driver.sleep(5000); const badgeCountHN = await driver.executeAsyncScript(` const testLibCode = arguments[0]; const callback = arguments[1]; eval(testLibCode); testBadgeCount().then(callback).catch(err => callback(null)); `, testLib); results.hn = badgeCountHN; console.log(` → Badge count: ${badgeCountHN}`); // Test 2: Site with third-party domains console.log(' Testing pudelek.pl (expected: >0 third-party domains)...'); await driver.get('https://pudelek.pl'); // Wait longer for tracking detection await driver.sleep(10000); const badgeCountPudelek = await driver.executeAsyncScript(` const testLibCode = arguments[0]; const callback = arguments[1]; eval(testLibCode); testBadgeCount().then(callback).catch(err => callback(null)); `, testLib); results.pudelek = badgeCountPudelek; console.log(` → Badge count: ${badgeCountPudelek}`); await driver.quit(); // Verify results if (badgeCountHN === null || badgeCountPudelek === null) { return { success: false, error: 'Test timed out or failed to get badge count' }; } if (badgeCountHN === 0 && badgeCountPudelek > 0) { return { success: true, results }; } else { return { success: false, error: `Unexpected results: HN=${badgeCountHN} (expected 0), Pudelek=${badgeCountPudelek} (expected >0)` }; } } catch (error) { if (driver) { await driver.quit(); } return { success: false, error: error.message }; } } async function main() { console.log('Starting Rentgen badge count verification test...'); console.log(''); const result = await testBadgeCount(); console.log(''); if (!result.success) { console.log(red(`FAIL: ${result.error}`)); process.exit(1); } console.log('PASS: Badge count test succeeded!'); console.log(` - news.ycombinator.com: ${result.results.hn} third-party domains`); console.log(` - pudelek.pl: ${result.results.pudelek} third-party domains`); process.exit(0); } // Handle signals process.on('SIGINT', () => process.exit(130)); process.on('SIGTERM', () => process.exit(143)); main().catch(error => { console.error(red(`ERROR: ${error.message}`)); process.exit(1); });