dequelabs / axe-core-npm

Mozilla Public License 2.0
592 stars 67 forks source link

With Playwright: WCAG AA color contrast violations reported for black text on white background #952

Closed CorinaMurg closed 7 months ago

CorinaMurg commented 9 months ago

Product

playwright

Product Version

@playwright/test": "^1.40.0"

Latest Version

Issue Description

Expectation

Expected no color contrast violations for elements with this class, given the high contrast between text and background: text color is black (#000) and background is white (#fff).

CSS

.sample-project--description {
    background-color: #fff;
    color: #000;
    font-size: 1.2rem;
    font-weight: 400;
    margin-top: 0;
}

Actual

+ "failureSummary": "Fix any of the following:
+    Element has insufficient color contrast of 2.61 
       (foreground color: #a0a0a0,  // NOTE: DIFFERENT FROM THE COLOR IN CSS BLOCK
       background color: #ffffff, 
       font size: 14.4pt (19.2px), 
       font weight: normal). 
       Expected contrast ratio of 4.5:1",
 +   "html": "<p class=\"sample-project--description\">
                    React, Typescript
              </p>",
 +    "impact": "serious",
 +    "none": Array [],
 +    "target": Array [
 +    ".my-portfolio-site > .sample-project > .sample-project--description",
 +         ],

How to Reproduce

Site: https://corinamurg.netlify.app/

Test

import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test('should not have any automatically detectable WCAG AA violations', async ({ page }) => {
    await page.goto('https://corinamurg.netlify.app/');

    const accessibilityScanResults = await new AxeBuilder({ page })
        .withTags(['wcag2aa', 'wcag21aa'])
        .analyze();

    expect(accessibilityScanResults.violations).toEqual([]);
});

Additional context

Other elements on the page also fail the AA test, but when I run the AAA test, there are no violations found about these elements.

Zidious commented 9 months ago

Hey @CorinaMurg,

Happy Friday!

Our AxeBuilderanalyze() runs as soon as the DOM is ready. It looks like you have some CSS fade-in transitions/animations that happen on the page after the DOM has rendered. Playwright have a feature request for a new helper function waitForTransition() which could be possibly be used to wait for a particular element/elements to finish transitioning/animating.

A workaround you could add would look something like:

const { chromium } = require("playwright");
const { AxeBuilder } = require("@axe-core/playwright");

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto("https://corinamurg.netlify.app/");

  // Wait for all the pages transitions/animations to complete before running accessibility checks
  // await page.waitForTimeout(2000);
  // OR
  const mainElement = page.locator("#main");
    await mainElement.evaluate((e) =>
     Promise.all(e.getAnimations({ subtree: true }).map((a) => a.finished))
  );

  const results = await new AxeBuilder({ page }).analyze();
  console.log(`Number of violations: ${results.violations.length}`);

  await browser.close();
})();
CorinaMurg commented 9 months ago

Hi @Zidious,

I thought I turned over every stone trying to fix it, but the animations were definitely not on my radar. You made my day! Thank you so much.

Have a great weekend!

straker commented 7 months ago

Closing as issue seems to have been resolved. Please let us know if that is not the case.

padmavemulapati commented 6 months ago

Verified with the latest build- 4.8.5, with the test code below, not getting any color-contrast issues

const { chromium } = require("playwright");
const { AxeBuilder } = require("@axe-core/playwright");

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto("https://corinamurg.netlify.app/");

  // Wait for all the pages transitions/animations to complete before running accessibility checks
  // await page.waitForTimeout(2000);
  // OR
  const mainElement = page.locator("#main");
    await mainElement.evaluate((e) =>
     Promise.all(e.getAnimations({ subtree: true }).map((a) => a.finished))
  );

  const results = await new AxeBuilder({ page }).analyze();
  console.log(`Number of violations: ${results.violations.length}`);

  await browser.close();
})();

Image

Environment:

Label Value
Product axe-core-npm/Playwright
Version 4.8.5
Playwright-Version 1.41.2
OS-Details MAC- Intel Core i7 - 11.6.8 && Windows 11
BrowserDetails Chrome Version 122.0.6261.112 && Firefox 123.0.1