From 60742c1d150e14c2b2617b1969f9decb1ae71047 Mon Sep 17 00:00:00 2001 From: Jacob Logan Date: Fri, 17 Nov 2023 10:03:16 -0700 Subject: [PATCH] re add action to check for console errors --- .../workflows/check_for_console_errors.yml | 61 +++++++++++++ tasks/console-errors.js | 85 +++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 .github/workflows/check_for_console_errors.yml create mode 100644 tasks/console-errors.js diff --git a/.github/workflows/check_for_console_errors.yml b/.github/workflows/check_for_console_errors.yml new file mode 100644 index 00000000000..bdc7eeb3062 --- /dev/null +++ b/.github/workflows/check_for_console_errors.yml @@ -0,0 +1,61 @@ +name: CheckConsoleErrors +on: + pull_request: + branches: [main] + types: [opened, synchronize] +permissions: + contents: read +jobs: + CheckConsoleErrors: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 https://github.com/actions/checkout/commit/f43a0e5ff2bd294095638e18286ca9a3d1956744 + - name: Setup Node.js 16.x + uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 https://github.com/actions/setup-node/commit/e33196f7422957bea03ed53f6fbb155025ffc7b8 + with: + node-version: 16.x + - name: Install Dependencies + run: yarn + - name: Run Build + run: yarn build + env: + NODE_OPTIONS: --max_old_space_size=4096 + - name: Serve Files + uses: Eun/http-server-action@6befadcf3bf8d9a4fcc563c1ffba0e59f188a1e5 # v1.0.10 https://github.com/Eun/http-server-action/commit/6befadcf3bf8d9a4fcc563c1ffba0e59f188a1e5 + with: + directory: ${{ vars.BUILD_DIR }} + port: 3000 + no-cache: false + index-files: | + ["index.html", "index.htm"] + allowed-methods: | + ["GET", "HEAD"] + content-types: | + { + "appcache": "text/cache-manifest", + "css": "text/css", + "gif": "image/gif", + "html": "text/html", + "ico": "image/x-icon", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "js": "text/javascript", + "json": "application/json", + "png": "image/png", + "txt": "text/plain", + "xml": "text/xml" + } + log: 'log.txt' + logTime: 'true' + - name: Run Console Errors + id: consoleErrors + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 https://github.com/actions/github-script/commit/d7906e4ad0b1822421a7e6a35d5ca353c962f410 + with: + result-encoding: string + script: | + const { consoleErrors } = require('./tasks/console-errors.js'); + return await consoleErrors(); + - name: Fail if console errors have been found + if: ${{ steps.consoleErrors.outputs.result }} + run: exit 1 diff --git a/tasks/console-errors.js b/tasks/console-errors.js new file mode 100644 index 00000000000..535cc31bc1c --- /dev/null +++ b/tasks/console-errors.js @@ -0,0 +1,85 @@ +const puppeteer = require('puppeteer'); +const { getSitemapUrls } = require('./get-sitemap-links'); + +const excludedErrors = [ + { + type: 'Shortbread', + errorText: + "Shortbread failed to set user's cookie preference because the domain name that was passed" + } +]; + +const excludedScripts = [ + 'prod.assets.shortbread.aws', + 'prod.tools.shortbread.aws', + 'aa0.awsstatic.com' +]; + +const checkPage = async (url) => { + const errorsFound = []; + let browser = await puppeteer.launch({ headless: 'new' }); + + const page = await browser.newPage(); + + page + .on('pageerror', (message) => { + let errorText = message.message; + const excluded = excludedErrors.some((excludedError) => { + return errorText.includes(excludedError.errorText); + }); + + if (!excluded) { + errorsFound.push({ + page: url, + message: errorText + }); + } + }) + .on('console', (message) => { + if (message.type().toLowerCase() === 'error') { + let errorText = message.text(); + let callingScript = message.location().url; + const excludedFromError = excludedErrors.some((excludedError) => { + return errorText.includes(excludedError.errorText); + }); + const excludedFromScript = excludedScripts.some((excludedScript) => { + return callingScript.includes(excludedScript); + }); + const excluded = excludedFromError || excludedFromScript; + + if (!excluded) { + errorsFound.push({ + page: url, + message: errorText + }); + } + } + }); + + await page.goto(url, { waitUntil: 'domcontentloaded' }); + + await browser.close(); + + return errorsFound; +}; + +const consoleErrors = async (domain) => { + let pagesToCheck = await getSitemapUrls(domain); + let errorMessage = ''; + for (let i = 0; i < pagesToCheck.length; i++) { + let url = pagesToCheck[i]; + console.log(`checking page ${url}`); + let errorsFound = await checkPage(url); + errorsFound.forEach((error) => { + errorMessage += `${error.message} found on ${error.page}\n`; + }); + } + console.log(errorMessage); + return errorMessage; +}; + +module.exports = { + consoleErrors: async (domain = 'http://localhost:3000') => { + return await consoleErrors(domain); + } +};