class TestReport { constructor() { this.tests = []; } createTest(name) { const test = { name, result: true, messages: [] }; this.tests.push(test); return test; } throwErrors() { const latest = this.tests[this.tests.length - 1]; if (!latest.result) { const msgs = latest.messages.map(m => m.description).join('\n'); throw new Error(`${latest.name} test failed with ${latest.messages.length} messages.\n\n${msgs}`); } } checkPassed(passed, message) { if (!passed) { const latest = this.tests[this.tests.length - 1]; latest.result = false; latest.messages.push(message); } } async verifyLinks(page) { const links = await page.getLinks(); for (const link of links) { if (link.startsWith('mailto')) continue; try { const response = await fetch(link); if (!response.ok) { this.checkPassed(false, { color: 'red', title: 'Bad Link', description: `${link} failed on page ${page.url} with status code ${response.status}` }); } } catch (e) { this.checkPassed(false, { color: 'red', title: 'Bad Link', description: `${link} failed on page ${page.url} with error ${e.message}` }); } } } didTestsPass() { return this.tests.every(t => t.result); } getMessages() { if (this.didTestsPass()) { return [{ title: 'Passed', color: 0x00FF00, description: `All ${this.tests.length} tests passed.` }]; } const messages = []; for (const test of this.tests) { for (const msg of test.messages) { messages.push({ title: msg.title, color: parseInt(msg.color, 16), description: msg.description }); } } return messages; } } module.exports = TestReport;