require("dotenv").config(); const lighthouse = require("lighthouse/core/index.cjs"); const puppeteer = require("puppeteer"); const config = require("./config"); const getAccount = require("./account"); const buildUrlsFromAPI = require("./urls"); const login = require("./login"); const processResults = require("./processor"); const { ERROR, WARNING } = require("./constants"); const outputAudit = ( { title, description, url, id, selector, snippet, explanation }, emoji ) => { console.log(""); console.log(`${emoji} ${id}: ${title}`); console.log(description, "\n"); console.log({ url, selector, snippet }, "\n"); console.log(explanation, "\n"); } (async () => { // TODO: If dev, check if zcli is running const isDev = process.argv[2] === "-d"; const results = { stats: {}, audits: [], }; // Reading account console.log("Reading account...", "\n"); const account = getAccount(); // Build list of urls to audit if (!account.urls || account.urls.length === 0) { console.log( "No urls were found in .a11yrc.json or as env variable. Building urls from the API...", "\n" ); account.urls = await buildUrlsFromAPI(account); } // Set login URL account.loginUrl = isDev ? `https://${account.subdomain}.zendesk.com/hc/admin/local_preview/start` : `https://${account.subdomain}.zendesk.com/hc/en-us/signin`; // Output account console.log("Account:"); console.log( { subdomain: account.subdomain, email: account.email, urls: account.urls, loginUrl: account.loginUrl, }, "\n" ); // Use Puppeteer to launch headless Chrome console.log("Starting headless Chrome..."); const browser = await puppeteer.launch({ headless: true }); // Login console.log(`Logging in using ${account.loginUrl}...`, "\n"); await login(browser, account); // Run lighthouse on all pages for (let url of account.urls) { console.log(`Running lighthouse in ${url}`); const page = await browser.newPage(); const { lhr } = await lighthouse( url, { port: new URL(browser.wsEndpoint()).port, logLevel: "silent" }, config.lighthouse, page ); // Output run warnings lhr.runWarnings.forEach((message) => console.warn(message)); // Analyze / process results const { stats, audits } = processResults(lhr); results.stats[url] = stats; results.audits = [...results.audits, ...audits]; console.log(""); } // Close browser await browser.close(); // Output table with stats for each url console.table(results.stats); // Output warnings const warnings = results.audits.filter((audit) => audit.result === WARNING); warnings.forEach((audit) => outputAudit(audit, "⚠️")); // Output errors const errors = results.audits.filter((audit) => audit.result === ERROR); errors.forEach((audit) => outputAudit(audit, "❌")); // Output totals console.log( "\n", `Total of ${errors.length} errors and ${warnings.length} warnings`, "\n" ); // Exit with error if there is at least one audit with an error if (errors.length > 0) { process.exit(1); } else { process.exit(0); } })();