From 452b564092045df44c87851a91795761b1600595 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Sun, 4 Aug 2024 11:17:36 -0400 Subject: [PATCH 01/15] deps(npm): install axe-core --- package-lock.json | 22 ++++++++++++++++++++++ package.json | 1 + 2 files changed, 23 insertions(+) diff --git a/package-lock.json b/package-lock.json index 729273248a..b4679ce5a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "redis": "4.6.13" }, "devDependencies": { + "@axe-core/playwright": "^4.9.1", "lint-staged": "^15.2.2", "prettier": "3.2.5" } @@ -1198,6 +1199,18 @@ "tslib": "^2.3.1" } }, + "node_modules/@axe-core/playwright": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.9.1.tgz", + "integrity": "sha512-8m4WZbZq7/aq7ZY5IG8GqV+ZdvtGn/iJdom+wBg+iv/3BAOBIfNQtIu697a41438DzEEyptXWmC3Xl5Kx/o9/g==", + "dev": true, + "dependencies": { + "axe-core": "~4.9.1" + }, + "peerDependencies": { + "playwright-core": ">= 1.0.0" + } + }, "node_modules/@babel/parser": { "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", @@ -3918,6 +3931,15 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/axe-core": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", + "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/axios": { "version": "1.6.8", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", diff --git a/package.json b/package.json index 801e41e451..92d49f064c 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "redis": "4.6.13" }, "devDependencies": { + "@axe-core/playwright": "^4.9.1", "lint-staged": "^15.2.2", "prettier": "3.2.5" }, From 48416fe0ffeda45d334ee66b453287f12850b567 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Mon, 5 Aug 2024 14:20:32 -0400 Subject: [PATCH 02/15] feat: add accessibility test with report --- .../e2e_tests/a11y-report-template.html | 298 ++++++++++++++++++ integration/e2e_tests/axe.spec.js | 128 ++++++++ 2 files changed, 426 insertions(+) create mode 100644 integration/e2e_tests/a11y-report-template.html create mode 100644 integration/e2e_tests/axe.spec.js diff --git a/integration/e2e_tests/a11y-report-template.html b/integration/e2e_tests/a11y-report-template.html new file mode 100644 index 0000000000..16ffa422c9 --- /dev/null +++ b/integration/e2e_tests/a11y-report-template.html @@ -0,0 +1,298 @@ + + + + + + + + + axe-core test results + + +
+ +
+

+ Tested at +

+ +

+
+
+ + +
Failed
+ +
+ + + + + + +
Needs review
+ +
+ + + + These results were aborted and require further testing. This can happen either + because of technical restrictions to what the rule can test, or because a javascript error occurred. + + + + + +
Passed
+ +
+ + + + + +
Other checks
+ +
+ + + + These results indicate which rules did not run because no matching content was + found on the page. For example, with no video, those rules won't run. + + + +
+
+
+ + + + + + + + + diff --git a/integration/e2e_tests/axe.spec.js b/integration/e2e_tests/axe.spec.js new file mode 100644 index 0000000000..210118907d --- /dev/null +++ b/integration/e2e_tests/axe.spec.js @@ -0,0 +1,128 @@ +const { test, expect } = require("@playwright/test"); +const AxeBuilder = require('@axe-core/playwright').default; +const fs = require("fs"); +const path = require("path"); + +async function writeHTMLReport(pagePath, axeResult) { + const reportName = `axe-report-${pagePath.replaceAll("/", "-")}-${axeResult.timestamp}.html`; + const filePath = path.join(__dirname, "a11y-report-template.html"); + const html = await fs.promises.readFile(filePath, { encoding: 'utf8' }); + const $ = require('cheerio').load(html); + $('body').append(``); + const rendered = $.html(); + const reportPath = path.join(__dirname, reportName); + fs.writeFileSync(reportPath, rendered); + return { reportName, reportPath }; +} + +const axeTest = test.extend({ + makeAxeBuilder: async ({ page }, use, testInfo) => { + const makeAxeBuilder = () => new AxeBuilder({ page }) + .withTags(['wcag22aa']); + + await use(makeAxeBuilder); + } +}); + +function runAxeTest(pagePath) { + axeTest(`${pagePath} landing page`, async ({ page, makeAxeBuilder }, testInfo) => { + // default localhost:4001, specify HOST environment variable to change baseURL + await page.goto(`${pagePath}`); + + // Avoid repeatedly surfacing errors from the page template by only + // testing the main content area unless we're testing the homepage. + const axe = await makeAxeBuilder(); + if (pagePath !== "/") axe.include('main'); + + // Analyze the page! + const axeResult = await axe.analyze(); + + // Attach screenshots of target HTML elements noted in the test failures + const screenshots = await Promise.all(axeResult.violations + .flatMap(({ id, nodes }) => { + return nodes.flatMap(async ({ target }, index) => { + const shot = await page.locator(target[0]).screenshot(); + return { shot, shotName: `${id}-${index}` }; + }) + }) + ); + screenshots.forEach(async ({ shot, shotName }) => { + await testInfo.attach(shotName, { body: shot, contentType: 'image/png' }); + }); + + // Create custom HTML report from the axe output JSON and attach to test + const { reportName, reportPath } = await writeHTMLReport(pagePath, axeResult) + await testInfo.attach(reportName, { path: reportPath }); + fs.unlinkSync(reportPath); + + expect(axeResult.violations.length).toEqual(0); + }); +} + +axeTest.describe('has no automatically detectable accessibility issues', () => { + /** + * Top-level pages from the main navigation. + */ + [ + "/", + "/schedules/subway", + "/schedules/bus", + "/schedules/commuter-rail", + "/schedules/ferry", + "/accessibility/the-ride", + "/trip-planner", + "/alerts", + "/parking", + "/bikes", + "/guides", + "/holidays", + "/accessibility", + "/transit-near-me", + "/stops", + "/destinations", + "/maps", + "/fares", + "/fares/subway-fares", + "/fares/bus-fares", + "/fares/commuter-rail-fares", + "/fares/ferry-fares", + "/fares/charliecard-store", + "/fares/charliecard", + "/fares/retail-sales-locations", + "/customer-support", + "/customer-support/lost-and-found", + "/language-services", + "/transit-police", + "/transit-police/see-something-say-something", + "/mbta-at-a-glance", + "/leadership", + "/history", + "/financials", + "/events", + "/news", + "/policies", + "/safety", + "/quality-compliance-oversight", + "/careers", + "/pass-program", + "/business", + "/innovation", + "/engineering/design-standards-and-guidelines", + "/sustainability", + "/projects" + ].forEach(runAxeTest); + + /** + * Other specific pages and sub-pages to test. In the future, can write tests + * for different application states and interactions. + */ + [ + "/schedules/Red/line", + "/schedules/Orange/alerts", + "/schedules/111/line", + "/schedules/CR-Worcester/timetable", + "/schedules/Boat-F1", + "/stops/place-north", + "/stops/1" + ].forEach(runAxeTest); +}); From b057f3c8473af9332d8ff0cb17f8889674da71de Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Mon, 5 Aug 2024 14:20:41 -0400 Subject: [PATCH 03/15] wip: workflow to run tests --- .github/workflows/tests-axe.yml | 64 ++++++++++++++++++ deploy/dev-standalone.yml | 112 ++++++++++++++++++++++++++++++++ deploy/dev.yml | 6 ++ deploy/dotcom/dev/1/Dockerfile | 8 ++- deploy/dotcom/dev/2/Dockerfile | 4 +- 5 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/tests-axe.yml create mode 100644 deploy/dev-standalone.yml diff --git a/.github/workflows/tests-axe.yml b/.github/workflows/tests-axe.yml new file mode 100644 index 0000000000..dc95a48475 --- /dev/null +++ b/.github/workflows/tests-axe.yml @@ -0,0 +1,64 @@ +name: Accessibility tests +on: + workflow_dispatch: + pull_request: + paths-ignore: + - ".github/workflows/**" + - "*.md" + - "integration/**" + - AUTHORS + +concurrency: + group: ci-${{ github.ref }}-a11y + cancel-in-progress: true + +env: + MIX_ENV: dev + MBTA_API_BASE_URL: ${{ secrets.MBTA_API_BASE_URL }} + MBTA_API_KEY: ${{ secrets.MBTA_API_KEY }} + +jobs: + axe_test: + name: Run accessibility tests against Docker container + timeout-minutes: 30 + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version-file: .tool-versions + cache: npm + cache-dependency-path: package-lock.json + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + aws-region: us-east-1 + mask-aws-account-id: true + - run: npm install --ignore-scripts + - run: cp .env.template .env # The docker compose expects an .env file + - name: docker compose up + run: docker compose --file deploy/dev-standalone.yml up --build --detach --wait + - uses: docker://mcr.microsoft.com/playwright:v1.42.1-jammy + with: + args: npx playwright test axe + env: + CI: true + HOME: /root + - uses: actions/upload-artifact@v4 + if: always() + with: + name: axe-report-${{ github.sha }} + path: playwright-report + retention-days: 30 + - name: show docker container logs + run: docker compose --file deploy/dev-standalone.yml logs dotcom + if: ${{ failure() }} + - name: docker compose down + if: always() + run: docker compose --file deploy/dev-standalone.yml down diff --git a/deploy/dev-standalone.yml b/deploy/dev-standalone.yml new file mode 100644 index 0000000000..0cc33ab9d6 --- /dev/null +++ b/deploy/dev-standalone.yml @@ -0,0 +1,112 @@ +services: + dotcom: + build: + context: ../ + dockerfile: ./deploy/dotcom/dev/1/Dockerfile + env_file: + - ../.env + depends_on: + redis-cluster-init: + condition: service_started + environment: + - MIX_ENV=dev + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - MBTA_API_BASE_URL=${MBTA_API_BASE_URL} + - MBTA_API_KEY=${MBTA_API_KEY} + - PORT=4001 + - REDIS_HOST=10.0.0.11 + - REDIS_PORT=6379 + - WEBPACK_PORT=8092 + - WARM_CACHES=false + expose: + - 4001 + ports: + - 4001:4001 + - 8092:8092 + healthcheck: + test: curl --fail http://localhost:4001/_health || exit 1 + interval: 10s + retries: 5 + start_period: 180s + timeout: 10s + volumes: + - ../:/app + networks: + dotcom_network: + ipv4_address: 10.0.0.1 + redis-cluster-init: + image: redis:7.2.4 + command: redis-cli --cluster create 10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 10.0.0.14:6379 10.0.0.15:6379 10.0.0.16:6379 --cluster-replicas 1 --cluster-yes + depends_on: + redis-1: + condition: service_healthy + redis-2: + condition: service_healthy + redis-3: + condition: service_healthy + redis-4: + condition: service_healthy + redis-5: + condition: service_healthy + redis-6: + condition: service_healthy + networks: + dotcom_network: + ipv4_address: 10.0.0.10 + redis-1: &redis + build: + context: ../ + dockerfile: ./deploy/redis/Dockerfile + healthcheck: + test: [ "CMD", "redis-cli", "PING"] + timeout: 10s + interval: 3s + retries: 10 + environment: + - CLUSTER_ANNOUNCE_IP=10.0.0.11 + networks: + dotcom_network: + ipv4_address: 10.0.0.11 + redis-2: + <<: *redis + environment: + - CLUSTER_ANNOUNCE_IP=10.0.0.12 + networks: + dotcom_network: + ipv4_address: 10.0.0.12 + redis-3: + <<: *redis + environment: + - CLUSTER_ANNOUNCE_IP=10.0.0.13 + networks: + dotcom_network: + ipv4_address: 10.0.0.13 + redis-4: + <<: *redis + environment: + - CLUSTER_ANNOUNCE_IP=10.0.0.14 + networks: + dotcom_network: + ipv4_address: 10.0.0.14 + redis-5: + <<: *redis + environment: + - CLUSTER_ANNOUNCE_IP=10.0.0.15 + networks: + dotcom_network: + ipv4_address: 10.0.0.15 + redis-6: + <<: *redis + environment: + - CLUSTER_ANNOUNCE_IP=10.0.0.16 + networks: + dotcom_network: + ipv4_address: 10.0.0.16 +networks: + dotcom_network: + driver: bridge + ipam: + config: + - subnet: 10.0.0.0/24 + gateway: 10.0.0.254 diff --git a/deploy/dev.yml b/deploy/dev.yml index 9703089432..6beab132aa 100644 --- a/deploy/dev.yml +++ b/deploy/dev.yml @@ -33,10 +33,13 @@ services: - MIX_ENV=dev - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - MBTA_API_BASE_URL=${MBTA_API_BASE_URL} + - MBTA_API_KEY=${MBTA_API_KEY} - PORT=4002 - REDIS_HOST=10.0.0.11 - REDIS_PORT=6379 - WEBPACK_PORT=8092 + - WARM_CACHES=false expose: - 4002 ports: @@ -66,10 +69,13 @@ services: - MIX_ENV=dev - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - MBTA_API_BASE_URL=${MBTA_API_BASE_URL} + - MBTA_API_KEY=${MBTA_API_KEY} - PORT=4003 - REDIS_HOST=10.0.0.11 - REDIS_PORT=6379 - WEBPACK_PORT=8093 + - WARM_CACHES=false expose: - 4003 ports: diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index 187a1652c0..9a10556872 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -14,6 +14,8 @@ COPY assets/package.json ./assets/package.json RUN mix local.hex --force RUN mix local.rebar --force -RUN mix deps.get -RUN npm --prefix assets install --package-lock-only --ignore-scripts --no-save --audit false --fund false --loglevel verbose -CMD elixir --sname dotcom1 --cookie foobarbaz -S mix phx.server +CMD mix deps.get \ + && npm install --no-save \ + && mix phx.digest \ + && npm --prefix assets install --package-lock-only --ignore-scripts --no-save --audit false --fund false --loglevel verbose \ + && elixir --sname dotcom1 --cookie foobarbaz -S mix phx.server diff --git a/deploy/dotcom/dev/2/Dockerfile b/deploy/dotcom/dev/2/Dockerfile index 89fd8bd119..1eb0fb02ed 100644 --- a/deploy/dotcom/dev/2/Dockerfile +++ b/deploy/dotcom/dev/2/Dockerfile @@ -8,5 +8,5 @@ WORKDIR /app COPY mix.exs . COPY mix.lock . -RUN mix deps.get -CMD elixir --sname dotcom2 --cookie foobarbaz -S mix phx.server +CMD mix deps.get \ + && elixir --sname dotcom2 --cookie foobarbaz -S mix phx.server From 1b5a04393bd54a5b852a8f526a889011dca814af Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 6 Aug 2024 16:40:46 -0400 Subject: [PATCH 04/15] even simpler docker compose --- .github/workflows/tests-axe.yml | 3 +- deploy/dev-standalone.yml | 117 +++++++------------------------- 2 files changed, 27 insertions(+), 93 deletions(-) diff --git a/.github/workflows/tests-axe.yml b/.github/workflows/tests-axe.yml index dc95a48475..7a386762e2 100644 --- a/.github/workflows/tests-axe.yml +++ b/.github/workflows/tests-axe.yml @@ -41,9 +41,8 @@ jobs: aws-region: us-east-1 mask-aws-account-id: true - run: npm install --ignore-scripts - - run: cp .env.template .env # The docker compose expects an .env file - name: docker compose up - run: docker compose --file deploy/dev-standalone.yml up --build --detach --wait + run: docker compose --file deploy/dev-standalone.yml up --detach --wait - uses: docker://mcr.microsoft.com/playwright:v1.42.1-jammy with: args: npx playwright test axe diff --git a/deploy/dev-standalone.yml b/deploy/dev-standalone.yml index 0cc33ab9d6..705cb0b4db 100644 --- a/deploy/dev-standalone.yml +++ b/deploy/dev-standalone.yml @@ -1,112 +1,47 @@ services: + redis: + network_mode: host + image: grokzen/redis-cluster + container_name: redis + restart: on-failure + ports: + - 30001-30006:30001-30006 + environment: + - INITIAL_PORT=30001 + - REDIS_CLUSTER_IP=0.0.0.0 + - IP=0.0.0.0 + healthcheck: + test: ["CMD", "redis-cli", "-p", "30001", "ping"] + interval: 5s + timeout: 5s + retries: 5 + start_period: 5s dotcom: + network_mode: host + depends_on: + - redis build: context: ../ dockerfile: ./deploy/dotcom/dev/1/Dockerfile - env_file: - - ../.env - depends_on: - redis-cluster-init: - condition: service_started environment: - MIX_ENV=dev + - CMS_API_BASE_URL=https://live-mbta.pantheonsite.io + - OPEN_TRIP_PLANNER_URL=http://otp2-local.mbtace.com - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - MBTA_API_BASE_URL=${MBTA_API_BASE_URL} - MBTA_API_KEY=${MBTA_API_KEY} - PORT=4001 - - REDIS_HOST=10.0.0.11 - - REDIS_PORT=6379 - WEBPACK_PORT=8092 - WARM_CACHES=false + - REDIS_PORT=30001 expose: - 4001 - ports: - - 4001:4001 - - 8092:8092 healthcheck: test: curl --fail http://localhost:4001/_health || exit 1 - interval: 10s + interval: 15s retries: 5 - start_period: 180s - timeout: 10s + start_period: 100s + timeout: 30s volumes: - ../:/app - networks: - dotcom_network: - ipv4_address: 10.0.0.1 - redis-cluster-init: - image: redis:7.2.4 - command: redis-cli --cluster create 10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 10.0.0.14:6379 10.0.0.15:6379 10.0.0.16:6379 --cluster-replicas 1 --cluster-yes - depends_on: - redis-1: - condition: service_healthy - redis-2: - condition: service_healthy - redis-3: - condition: service_healthy - redis-4: - condition: service_healthy - redis-5: - condition: service_healthy - redis-6: - condition: service_healthy - networks: - dotcom_network: - ipv4_address: 10.0.0.10 - redis-1: &redis - build: - context: ../ - dockerfile: ./deploy/redis/Dockerfile - healthcheck: - test: [ "CMD", "redis-cli", "PING"] - timeout: 10s - interval: 3s - retries: 10 - environment: - - CLUSTER_ANNOUNCE_IP=10.0.0.11 - networks: - dotcom_network: - ipv4_address: 10.0.0.11 - redis-2: - <<: *redis - environment: - - CLUSTER_ANNOUNCE_IP=10.0.0.12 - networks: - dotcom_network: - ipv4_address: 10.0.0.12 - redis-3: - <<: *redis - environment: - - CLUSTER_ANNOUNCE_IP=10.0.0.13 - networks: - dotcom_network: - ipv4_address: 10.0.0.13 - redis-4: - <<: *redis - environment: - - CLUSTER_ANNOUNCE_IP=10.0.0.14 - networks: - dotcom_network: - ipv4_address: 10.0.0.14 - redis-5: - <<: *redis - environment: - - CLUSTER_ANNOUNCE_IP=10.0.0.15 - networks: - dotcom_network: - ipv4_address: 10.0.0.15 - redis-6: - <<: *redis - environment: - - CLUSTER_ANNOUNCE_IP=10.0.0.16 - networks: - dotcom_network: - ipv4_address: 10.0.0.16 -networks: - dotcom_network: - driver: bridge - ipam: - config: - - subnet: 10.0.0.0/24 - gateway: 10.0.0.254 From 562a72694e46a0ce79cd8f2bcead9ca7d764d634 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 6 Aug 2024 16:47:23 -0400 Subject: [PATCH 05/15] more timeout --- deploy/dev-standalone.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/deploy/dev-standalone.yml b/deploy/dev-standalone.yml index 705cb0b4db..71eb3f9076 100644 --- a/deploy/dev-standalone.yml +++ b/deploy/dev-standalone.yml @@ -1,6 +1,5 @@ services: redis: - network_mode: host image: grokzen/redis-cluster container_name: redis restart: on-failure @@ -17,7 +16,6 @@ services: retries: 5 start_period: 5s dotcom: - network_mode: host depends_on: - redis build: @@ -40,8 +38,8 @@ services: healthcheck: test: curl --fail http://localhost:4001/_health || exit 1 interval: 15s - retries: 5 - start_period: 100s - timeout: 30s + retries: 10 + start_period: 180s + timeout: 60s volumes: - ../:/app From 71749aec150f7c92302740f22cf4210a0e3e886d Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 6 Aug 2024 17:42:07 -0400 Subject: [PATCH 06/15] ports --- deploy/dev-standalone.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deploy/dev-standalone.yml b/deploy/dev-standalone.yml index 71eb3f9076..67ec14820b 100644 --- a/deploy/dev-standalone.yml +++ b/deploy/dev-standalone.yml @@ -35,6 +35,9 @@ services: - REDIS_PORT=30001 expose: - 4001 + ports: + - 4001:4001 + - 8092:8092 healthcheck: test: curl --fail http://localhost:4001/_health || exit 1 interval: 15s From 4e6ffcb1067698d2e8f17b808f35d7e80ec24a04 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 6 Aug 2024 17:56:19 -0400 Subject: [PATCH 07/15] expose the port --- deploy/dotcom/dev/1/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index 9a10556872..9cc0c83ec6 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -14,6 +14,8 @@ COPY assets/package.json ./assets/package.json RUN mix local.hex --force RUN mix local.rebar --force +EXPOSE 4001 + CMD mix deps.get \ && npm install --no-save \ && mix phx.digest \ From b931f09ac86ce1e236791297954313d10d77ee90 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 01:37:26 -0400 Subject: [PATCH 08/15] even simpler --- .github/workflows/tests-axe.yml | 15 ++--------- deploy/dotcom/dev/1/Dockerfile | 2 -- deploy/{dev-standalone.yml => local.yml} | 32 ++++++++++++++++-------- 3 files changed, 24 insertions(+), 25 deletions(-) rename deploy/{dev-standalone.yml => local.yml} (66%) diff --git a/.github/workflows/tests-axe.yml b/.github/workflows/tests-axe.yml index 7a386762e2..15a62c5954 100644 --- a/.github/workflows/tests-axe.yml +++ b/.github/workflows/tests-axe.yml @@ -40,15 +40,7 @@ jobs: role-to-assume: ${{ secrets.AWS_ROLE_ARN }} aws-region: us-east-1 mask-aws-account-id: true - - run: npm install --ignore-scripts - - name: docker compose up - run: docker compose --file deploy/dev-standalone.yml up --detach --wait - - uses: docker://mcr.microsoft.com/playwright:v1.42.1-jammy - with: - args: npx playwright test axe - env: - CI: true - HOME: /root + - run: docker compose --file deploy/local.yml run a11y-test - uses: actions/upload-artifact@v4 if: always() with: @@ -56,8 +48,5 @@ jobs: path: playwright-report retention-days: 30 - name: show docker container logs - run: docker compose --file deploy/dev-standalone.yml logs dotcom + run: docker compose --file deploy/local.yml logs if: ${{ failure() }} - - name: docker compose down - if: always() - run: docker compose --file deploy/dev-standalone.yml down diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index 9cc0c83ec6..2e17bbba1f 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -17,7 +17,5 @@ RUN mix local.rebar --force EXPOSE 4001 CMD mix deps.get \ - && npm install --no-save \ - && mix phx.digest \ && npm --prefix assets install --package-lock-only --ignore-scripts --no-save --audit false --fund false --loglevel verbose \ && elixir --sname dotcom1 --cookie foobarbaz -S mix phx.server diff --git a/deploy/dev-standalone.yml b/deploy/local.yml similarity index 66% rename from deploy/dev-standalone.yml rename to deploy/local.yml index 67ec14820b..12e49f7b98 100644 --- a/deploy/dev-standalone.yml +++ b/deploy/local.yml @@ -1,10 +1,7 @@ services: redis: image: grokzen/redis-cluster - container_name: redis - restart: on-failure - ports: - - 30001-30006:30001-30006 + network_mode: host environment: - INITIAL_PORT=30001 - REDIS_CLUSTER_IP=0.0.0.0 @@ -16,8 +13,10 @@ services: retries: 5 start_period: 5s dotcom: + network_mode: host depends_on: - - redis + redis: + condition: service_healthy build: context: ../ dockerfile: ./deploy/dotcom/dev/1/Dockerfile @@ -32,17 +31,30 @@ services: - PORT=4001 - WEBPACK_PORT=8092 - WARM_CACHES=false + - REDIS_HOST=localhost - REDIS_PORT=30001 expose: - 4001 - ports: - - 4001:4001 - - 8092:8092 healthcheck: test: curl --fail http://localhost:4001/_health || exit 1 - interval: 15s - retries: 10 + interval: 30s + retries: 20 start_period: 180s timeout: 60s volumes: - ../:/app + + a11y-test: + image: mcr.microsoft.com/playwright:v1.42.1-jammy + depends_on: + dotcom: + condition: service_healthy + volumes: + - ../:/app + working_dir: /app + entrypoint: /bin/sh + command: -c "npx playwright test axe" + network_mode: host + environment: + - CI=true + - PLAYWRIGHT_HTML_OPEN=never From 6c1e3d8dea47d9f0dbc6cbfe235ef96af3ebf959 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 09:51:38 -0400 Subject: [PATCH 09/15] even more timeout --- deploy/local.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/deploy/local.yml b/deploy/local.yml index 12e49f7b98..ea666c9e86 100644 --- a/deploy/local.yml +++ b/deploy/local.yml @@ -16,7 +16,7 @@ services: network_mode: host depends_on: redis: - condition: service_healthy + condition: service_started build: context: ../ dockerfile: ./deploy/dotcom/dev/1/Dockerfile @@ -37,15 +37,17 @@ services: - 4001 healthcheck: test: curl --fail http://localhost:4001/_health || exit 1 - interval: 30s + interval: 60s retries: 20 - start_period: 180s + start_period: 240s timeout: 60s volumes: - ../:/app a11y-test: image: mcr.microsoft.com/playwright:v1.42.1-jammy + healthcheck: + disable: true depends_on: dotcom: condition: service_healthy From a51650b5c7431226dfe335ea41d331fac991222c Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 10:12:27 -0400 Subject: [PATCH 10/15] missing webpack builds --- deploy/dotcom/dev/1/Dockerfile | 2 ++ deploy/local.yml | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index 2e17bbba1f..7d2abee1b3 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -8,8 +8,10 @@ WORKDIR /app COPY mix.exs . COPY mix.lock . +COPY config . COPY package.json . COPY assets/package.json ./assets/package.json +COPY assets/webpack.config* . RUN mix local.hex --force RUN mix local.rebar --force diff --git a/deploy/local.yml b/deploy/local.yml index ea666c9e86..91afa493fc 100644 --- a/deploy/local.yml +++ b/deploy/local.yml @@ -12,6 +12,8 @@ services: timeout: 5s retries: 5 start_period: 5s + volumes: + - ../:/app dotcom: network_mode: host depends_on: @@ -43,7 +45,6 @@ services: timeout: 60s volumes: - ../:/app - a11y-test: image: mcr.microsoft.com/playwright:v1.42.1-jammy healthcheck: From 0a1f2ac9f93d782d9f08b716c9c624f73544a44c Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 10:22:37 -0400 Subject: [PATCH 11/15] just copy it all --- deploy/dotcom/dev/1/Dockerfile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index 7d2abee1b3..9c1e9ed3f5 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -6,12 +6,7 @@ RUN apt-get install -y nodejs WORKDIR /app -COPY mix.exs . -COPY mix.lock . -COPY config . -COPY package.json . -COPY assets/package.json ./assets/package.json -COPY assets/webpack.config* . +COPY . . RUN mix local.hex --force RUN mix local.rebar --force From 874a3fc155005621d07d0dafda7bed033757d3af Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 10:29:11 -0400 Subject: [PATCH 12/15] catch build errors --- lib/dotcom/react/react.ex | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/dotcom/react/react.ex b/lib/dotcom/react/react.ex index f43faa3bbd..ad71f8edc4 100644 --- a/lib/dotcom/react/react.ex +++ b/lib/dotcom/react/react.ex @@ -77,13 +77,18 @@ defmodule Dotcom.React do def dev_build(nil, _), do: :ok def dev_build(path, cmd_fn) do - {_, 0} = - cmd_fn.( - "npm", - ["run", "webpack:build:react"], - cd: path - ) - - :ok + case cmd_fn.( + "npm", + ["run", "webpack:build:react"], + cd: path + ) do + {_, 0} -> + :ok + {output, _} -> + _ = + Logger.warning(fn -> "react_renderer build error #{inspect(output)}" end) + + :ok + end end end From 017f298b90938d4ee75871a4d47ee95618dcf3cd Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 11:18:35 -0400 Subject: [PATCH 13/15] add build --- deploy/dotcom/dev/1/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index 9c1e9ed3f5..df89984402 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -14,5 +14,6 @@ RUN mix local.rebar --force EXPOSE 4001 CMD mix deps.get \ - && npm --prefix assets install --package-lock-only --ignore-scripts --no-save --audit false --fund false --loglevel verbose \ + && npm ci \ + && npm --prefix assets run webpack:build:react \ && elixir --sname dotcom1 --cookie foobarbaz -S mix phx.server From ba68042df990597fbff5ba6dfd801c96cd2c5c60 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 12:00:01 -0400 Subject: [PATCH 14/15] another one --- deploy/dotcom/dev/1/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/dotcom/dev/1/Dockerfile b/deploy/dotcom/dev/1/Dockerfile index df89984402..623f04a885 100644 --- a/deploy/dotcom/dev/1/Dockerfile +++ b/deploy/dotcom/dev/1/Dockerfile @@ -16,4 +16,5 @@ EXPOSE 4001 CMD mix deps.get \ && npm ci \ && npm --prefix assets run webpack:build:react \ + && mix phx.digest \ && elixir --sname dotcom1 --cookie foobarbaz -S mix phx.server From 9086b57e7eb3d386c9f17dc0a4e9ecfa079bb8f8 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 7 Aug 2024 12:25:57 -0400 Subject: [PATCH 15/15] screenshot on fail --- playwright.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/playwright.config.js b/playwright.config.js index 6738c3b223..5df45e0d34 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -18,6 +18,7 @@ module.exports = defineConfig({ baseURL: process.env.HOST ? `https://${process.env.HOST}` : 'http://localhost:4001', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', + screenshot: "on" }, /* set the expect timeout to 30s */ expect: { timeout: 30000 },