diff --git a/tests/test_verify.mjs b/tests/test_verify.mjs index ee67d99..49892d4 100755 --- a/tests/test_verify.mjs +++ b/tests/test_verify.mjs @@ -8,7 +8,7 @@ * 2. Site with third-party domains (pudelek.pl) → badge > 0 */ -import { Builder, By, until } from 'selenium-webdriver'; +import { Builder } from 'selenium-webdriver'; import firefox from 'selenium-webdriver/firefox.js'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; @@ -17,97 +17,90 @@ import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); -const isTTY = process.stdout.isTTY; +// Load test library once +const testLibPath = join(__dirname, 'test-lib.js'); +const testLib = readFileSync(testLibPath, 'utf-8'); -function red(text) { - return isTTY ? `\x1b[91m${text}\x1b[0m` : text; +/** + * Test badge count for a specific URL + * @param {WebDriver} driver - Selenium WebDriver instance + * @param {string} url - URL to test + * @param {number} waitMs - How long to wait after page load + * @returns {Promise} Badge count or null on failure + */ +async function testUrl(driver, url, waitMs = 5000) { + await driver.get(url); + await driver.sleep(waitMs); + + const badgeCount = await driver.executeAsyncScript(` + const testLibCode = arguments[0]; + const callback = arguments[1]; + + eval(testLibCode); + testBadgeCount().then(callback).catch(err => callback(null)); + `, testLib); + + return badgeCount; +} + +/** + * Verify badge count matches expected value + * @param {number|null} actual - Actual badge count + * @param {number|string} expected - Expected value (number or '>0') + * @returns {boolean} Whether assertion passed + */ +function assertBadgeCount(actual, expected) { + if (actual === null) return false; + if (expected === '>0') return actual > 0; + return actual === expected; } 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 + await driver.installAddon(extensionPath, true); + + // Test cases: [url, expectedBadgeCount, waitMs, name] + const testCases = [ + ['https://news.ycombinator.com', 0, 5000, 'news.ycombinator.com'], + ['https://pudelek.pl', '>0', 10000, 'pudelek.pl'] + ]; 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'); + for (const [url, expected, waitMs, name] of testCases) { + console.log(` Testing ${name} (expected: ${expected === '>0' ? '>0' : expected} third-party domains)...`); + const badgeCount = await testUrl(driver, url, waitMs); + results[name] = badgeCount; + console.log(` → Badge count: ${badgeCount}`); - // 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}`); + if (!assertBadgeCount(badgeCount, expected)) { + await driver.quit(); + return { + success: false, + error: `${name}: expected ${expected}, got ${badgeCount}` + }; + } + } 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)` - }; - } + return { success: true, results }; } catch (error) { if (driver) { @@ -125,13 +118,15 @@ async function main() { console.log(''); if (!result.success) { - console.log(red(`FAIL: ${result.error}`)); + console.log(`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`); + const resultNames = Object.keys(result.results); + for (const name of resultNames) { + console.log(` - ${name}: ${result.results[name]} third-party domains`); + } process.exit(0); } @@ -140,6 +135,6 @@ process.on('SIGINT', () => process.exit(130)); process.on('SIGTERM', () => process.exit(143)); main().catch(error => { - console.error(red(`ERROR: ${error.message}`)); + console.error(`ERROR: ${error.message}`); process.exit(1); });