diff --git a/README.md b/README.md index 9e7ca26..e413faa 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # axe-html-reporter -Creates an HTML report from axe results object with list of violations, passes and incomplete results. +Creates an HTML report from axe-core library AxeResults object listing violations, passes, incomplete and incompatible results. -Allows specifying `url`, `projectKey` and `outputDir`. +Allows specifying report creation options: `reportFileName`, `outputDir`, `projectKey` and `customSummary`. + +`customSummary` allows having html parameters. Please check [sample report output.](https://lpelypenko.github.io/axe-html-reporter/) @@ -16,8 +18,7 @@ npm i axe-html-reporter ### Example usage in TestCafe - -To run TestCafe tests with axe-core, install testcafe, axe-core and [@testcafe-community/axe](https://www.npmjs.com/package/@testcafe-community/axe): +To run TestCafe tests with axe-core, install testcafe, axe-core and [@testcafe-community/axe](https://www.npmjs.com/package/@testcafe-community/axe): ```shell script npm i -D axe-html-reporter testcafe axe-core @testcafe-community/axe @@ -27,15 +28,15 @@ For TestCafe example add the following clientScript in your `.testcaferc.json` c ```json { - "clientScripts":[{"module":"axe-core/axe.min.js"}] + "clientScripts": [{ "module": "axe-core/axe.min.js" }] } ``` -In the example bellow `fileName` is not passed. In this case html report with default name `accessibilityReport.html` will be created in `artifacts` directory. -See full TestCafe test example is bellow: +In the example bellow `fileName` is not passed. If `fileName` is not passed, HTML report will be created with default name `accessibilityReport.html` in `artifacts` directory. -```javascript +See full TestCafe test example is bellow: +```javascript import { runAxe } from '@testcafe-community/axe'; import { createHtmlReport } from 'axe-html-reporter'; @@ -43,19 +44,24 @@ fixture('TestCafe tests with Axe').page('http://example.com'); test('Automated accessibility testing', async (t) => { const axeContext = { exclude: [['select']] }; - const axeOptions = { rules: rulesMap() }; + const axeOptions = { + rules: { + 'object-alt': { enabled: true }, + 'role-img-alt': { enabled: true }, + 'input-image-alt': { enabled: true }, + 'image-alt': { enabled: true }, + }, + }; const { error, results } = await runAxe(axeContext, axeOptions); - await t.expect(error).eql(null, `axe check failed with an error: ${error.message}`); + await t.expect(error).notOk(`axe check failed with an error: ${error.message}`); // creates html report with the default file name `accessibilityReport.html` createHtmlReport({ - violations: results.violations, - passes: results.passes, - incomplete: results.incomplete, - url: results.url, - projectKey: 'EXAMPLE', + results, + options: { + projectKey: 'EXAMPLE', + }, }); }); - ``` Run TestCafe test: @@ -77,36 +83,26 @@ HTML report was saved into the following directory /Users/axe-demos/artifacts/ac ### Example usage in any JS framework ```javascript - import { axeHtmlReporter } from 'axe-html-reporter'; (() => { - const results = { violations: [], passes: [], incomplete: [], inapplicable: [], url: 'http://example.com' }; // creates html report with the default name `accessibilityReport.html` file - axeHtmlReporter({ - violations: results.violations, - passes: results.passes, - incomplete: results.incomplete, - inapplicable: results.inapplicable, - url: results.url - }); + axeHtmlReporter({ results: 'AxeResults' }); // full AxeResults object + // creates html report with the default name `accessibilityReport.html` file and all supported AxeResults values + axeHtmlReporter({ results: { violations: 'Result[]' } }); // passing only violations from axe.run output // creates html report with the default name `accessibilityReport.html` file and adds url and projectKey axeHtmlReporter({ - violations: results.violations, - passes: results.passes, - incomplete: results.incomplete, - projectKey: 'JIRA_PROJECT_KEY', - url: results.url, + results: 'AxeResults', + options: { projectKey: 'JIRA_PROJECT_KEY' }, }); - // creates html report with the name `exampleReport.html` in 'axe-reports' directory and adds url and projectKey to the header + // creates html report with the name `exampleReport.html` in 'axe-reports' directory and adds projectKey to the header axeHtmlReporter({ - violations: results.violations, - passes: results.passes, - incomplete: results.incomplete, - projectKey: 'JIRA_PROJECT_KEY', - outputDir: 'axe-reports', - url: results.url, - fileName: 'exampleReport.html', + results: 'AxeResults', + options: { + projectKey: 'JIRA_PROJECT_KEY', + outputDir: 'axe-reports', + fileName: 'exampleReport.html', + }, }); // creates html report with all optional parameters, saving the report into 'docs' directory with report file name 'index.html' const customSummary = `Test Case: Full page analysis @@ -116,15 +112,13 @@ import { axeHtmlReporter } from 'axe-html-reporter';
  • Analyze full page with all rules enabled
  • `; createHtmlReport({ - violations: axeRawViolations, - passes: axeRawPassed, - incomplete: [], - inapplicable: axeRawInapplicable, - projectKey: 'DEQUE', - url: 'https://dequeuniversity.com/demo/mars/', - customSummary, - outputDir: 'docs', - reportFileName: 'index.html' + results: 'AxeResults', + options: { + projectKey: 'DEQUE', + customSummary, + outputDir: 'docs', + reportFileName: 'index.html', + }, }); })(); ``` @@ -136,6 +130,6 @@ const { axeHtmlReporter } = require('axe-html-reporter'); (() => { // creates html report with the name `accessibilityReport.html` file - axeHtmlReporter({ violations: results.violations }); + axeHtmlReporter({ results: { violations: 'Result[]' } }); })(); ``` diff --git a/docs/index.html b/docs/index.html index e012e4d..3233680 100644 --- a/docs/index.html +++ b/docs/index.html @@ -61,7 +61,7 @@

    Page URL: - https://dequeuniversity.com/demo/mars/ + http://example.com/
    Test Case: Full page analysis
    Steps:
    @@ -71,8 +71,7 @@
    - -
    axe-core found 85 violations
    +
    axe-core found 6 violations
    @@ -87,46 +86,6 @@
    axe-core found 85 violations
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -134,63 +93,23 @@
    axe-core found 85 violations
    - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -203,67 +122,22 @@

    Failed

    -
    Buttons must have discernible text
    +
    <html> element must have a lang attribute
    Learn more
    -
    button-name
    +
    html-has-lang
    WCAG 2.0 Level A
    -

    Ensures buttons have discernible text

    -
    - critical -
    -
    -
    -
    1Buttons must have discernible textbutton-nameWCAG 2.0 Level Acritical1
    2Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AAserious11
    3IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level Aserious1
    4id attribute value must be uniqueduplicate-idWCAG 2.0 Level Aminor10
    5Frames must have title attributeframe-titleWCAG 2.0 Level Aserious2
    6 <html> element must have a lang attribute html-has-lang WCAG 2.0 Level A 1
    7Images must have alternate textimage-altWCAG 2.0 Level Acritical4
    8Form elements must have labelslabelWCAG 2.0 Level Acritical1
    92 Document must have one main landmark landmark-one-main Best practice moderate4
    10Ensures landmarks are uniquelandmark-uniqueBest practicemoderate1
    11Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level Aserious 1
    12Links must have discernible textlink-nameWCAG 2.0 Level Aserious8
    133 All page content must be contained by landmarks region Best practice moderate371
    144 Elements should not have tabindex greater than zero tabindex Best practice
    - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<button class="ui-datepicker-trigger" type="button"> -<!-- <img title="..." alt="..." src="/redesign/assets/demo-sites/mars/images/calendar.png"> --> -</button>".departure-date > .ui-datepicker-trigger:nth-child(4)"
    - - - -
    -
    -
    -
    Elements must have sufficient color contrast
    - Learn more -
    -
    -
    color-contrast
    -
    - WCAG 2.0 Level AA -
    -
    -
    -

    Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds

    +

    Ensures every HTML document has a lang attribute

    serious
    @@ -280,61 +154,8 @@
    1 - <h3>Be Bold...</h3> - ":root > h3" - - - 2 - <p>Step out of your comfort zone, and into a rocket with enough fuel to blast a Manhattan-sized crater if it explodes. But it won't. Probably.<br> -&nbsp; </p> - "#vap-plan > p:nth-child(3)" - - - 3 - <h3>Countdown...</h3> - ":root > h3" - - - 4 - <p>If you're serious about traveling to Mars - really serious - then <a href="mars2.html?a=last_will">prepare your last will and testament</a>, and book a trip! </p> - "#vap-book > p:nth-child(3)" - - - 5 - <h3>Blast Off!</h3> - ":root > h3" - - - 6 - <p>Expect violent turbulence, bone-crushing g-forces, muscle atrophy, and certain death (hey, everyone's death is certain at some point, right?).<br> -&nbsp; </p> - "#vap-travel > p:nth-child(3)" - - - 7 - <a class="" href="mars2.html?a=crater_adventure">10% off Crater Adventure</a> - ":root > a[href="mars2\.html\?a\=crater_adventure"]" - - - 8 - <a class="" href="mars2.html?a=ice_cream">Free Astronaut Ice Cream</a> - ":root > a[href="mars2\.html\?a\=ice_cream"]" - - - 9 - <p>Spend an extra 3 months in orbit around Mars in our newly-remodelled MarsPod and get a free package of freeze-wrapped dehydrated astronaut ice cream. <a class="link-arrow" href="mars2.html?a=ice_cream">Get your free dehydrated ice cream!</a> -</p> - "li:nth-child(2) > .deal-text > p" - - - 10 - <a class="link" href="mars2.html?a=low_price_guarantee">Lowest Price Guarantee</a> - "li:nth-child(3) > .deal-text > h3 > .link" - - - 11 - <a href="mars2.html?a=free_year">Book a free year on Mars</a> - ":root > a[href="mars2\.html\?a\=free_year"]" + <html> + "html" @@ -344,24 +165,24 @@
    -
    IDs of active elements must be unique
    +
    Document must have one main landmark
    Learn more
    -
    duplicate-id-active
    +
    landmark-one-main
    - WCAG 2.0 Level A + Best practice
    -

    Ensures every id attribute value of active elements is unique

    +

    Ensures the document has a main landmark

    - serious + moderate
    @@ -376,8 +197,8 @@
    1 - <a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a> - ".active" + <html> + "html" @@ -387,24 +208,24 @@
    -
    id attribute value must be unique
    +
    All page content must be contained by landmarks
    Learn more
    -
    duplicate-id
    +
    region
    - WCAG 2.0 Level A + Best practice
    -

    Ensures every id attribute value is unique

    +

    Ensures all page content is contained by landmarks

    - minor + moderate
    @@ -419,113 +240,13 @@
    1 - <div id="control-panel" class="container-fluid-full"> - ".loginnow > .container-fluid-full" - - - 2 - <nav id="left-control-nav" class="pull-left"> - ".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)" - - - 3 - <div id="search-bar" class="pull-left"> -<form id="search" action="/demo/mars/mars2" method="get"> -<input type="hidden" name="fn" value="Search"> -<input type="text" class="search" name="query" placeholder="search"> -<input type="submit" class="control-search"> -</form> + <div> + <h1>Example Domain</h1> + <p>This domain is for use in illustrative examples in documents. You may use this + domain in literature without prior coordination or asking for permission.</p> + <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> - ".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(2)" - - - 4 - <form id="search" action="/demo/mars/mars2" method="get"> -<input type="hidden" name="fn" value="Search"> -<input type="text" class="search" name="query" placeholder="search"> -<input type="submit" class="control-search"> -</form> - ":root > form[method="get"][action="\/demo\/mars\/mars2"]" - - - 5 - <nav id="right-control-nav" class="pull-right" style="display: inline;"> - ".loginnow > .container-fluid-full > .container > .span7.pull-right > .pull-right" - - - 6 - <div id="vap-section"> -<h1 style="color:#eee;">Destination Mars </h1> -<h2 style="color:#acbad0;">A trip to Mars starts in your imagination. Are you bold enough, brave enough, <strong>foolish enough?</strong> We are. You belong on Mars with fools like us. Most of us don't bite. Much.</h2></div> - "#left-column > div:nth-child(1)" - - - 7 - <input type="hidden" id="nCountries" name="nCountries"> - "#select-country > input[name="nCountries"][type="hidden"]" - - - 8 - <div id="passenger-select" class="widget-container middle"> - ".middle.widget-container:nth-child(13)" - - - 9 - <div id="passengers"> - ".middle.widget-container:nth-child(13) > .interior-container > div:nth-child(3)" - - - 10 - <div id="ui-datepicker-div" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div> - ".ui-datepicker.ui-helper-clearfix.ui-corner-all:nth-child(33)" - - - -
    -
    -
    -
    -
    -
    -
    Frames must have title attribute
    - Learn more -
    -
    -
    frame-title
    -
    - WCAG 2.0 Level A -
    -
    -
    -

    Ensures <iframe> and <frame> elements contain a non-empty title attribute

    -
    - serious -
    -
    -
    - - - - - - - - - - - - - - - - - - +
    #Source CodeSelector
    1<iframe width="365" height="205" name="player" id="player" src="https://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>"#player"
    2<iframe id="fafbba78" name="f2bc5e72d" scrolling="no" style="border: none; overflow: hidden; height: 62px; width: 292px;" class="fb_ltr" src="/assets/demo-sites/mars/js/likebox.html"></iframe>"#fafbba78""div"
    @@ -535,22 +256,22 @@
    -
    <html> element must have a lang attribute
    +
    Elements should not have tabindex greater than zero
    Learn more
    -
    html-has-lang
    +
    tabindex
    - WCAG 2.0 Level A + Best practice
    -

    Ensures every HTML document has a lang attribute

    +

    Ensures tabindex attribute values are not greater than 0

    serious
    @@ -567,619 +288,18 @@
    1 - <html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths"> - "html" - - - -
    -
    -
    -
    -
    -
    -
    Images must have alternate text
    - Learn more -
    -
    -
    image-alt
    -
    - WCAG 2.0 Level A -
    -
    -
    -

    Ensures <img> elements have alternate text or a role of none or presentation

    -
    - critical -
    -
    -
    - - - - - - - - - - - - - + + - - + + - - - - - - - - - -
    #Source CodeSelector
    1<img src="/assets/demo-sites/mars/js/seg" width="1" height="1">"img[src$="seg"]"<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="from0" name="from0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#from0"
    2<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\32 10"][height="\31 20"]"<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="to0" name="to0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#to0"
    3<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\32 10"][height="\31 20"]"
    4<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\32 10"][height="\31 20"]"
    -
    -
    -
    -
    -
    -
    -
    Form elements must have labels
    - Learn more -
    -
    -
    label
    -
    - WCAG 2.0 Level A -
    -
    -
    -

    Ensures every form element has a label

    -
    - critical -
    -
    -
    - - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    -
    -
    -
    -
    -
    -
    -
    Document must have one main landmark
    - Learn more -
    -
    -
    landmark-one-main
    -
    - Best practice -
    -
    -
    -

    Ensures the document has a main landmark

    -
    - moderate -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    2<html lang="en" dir="ltr" data-cast-api-enabled="true">"#player", "html"
    3<html lang="en" id="facebook" class="">"#fafbba78", "#facebook"
    4<html lang="en" class=" xl en">".twitter-follow-button", "html"
    -
    -
    -
    -
    -
    -
    -
    Ensures landmarks are unique
    - Learn more -
    -
    -
    landmark-unique
    -
    - Best practice -
    -
    -
    -

    Landmarks must have a unique role or role/label/title (i.e. accessible name) combination

    -
    - moderate -
    -
    -
    - - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    -
    -
    -
    -
    -
    -
    -
    Links must be distinguished from surrounding text in a way that does not rely on color
    - Learn more -
    -
    -
    link-in-text-block
    -
    - WCAG 2.0 Level A -
    -
    -
    -

    Links can be distinguished without relying on color

    -
    - serious -
    -
    -
    - - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<a href="mars2.html?a=last_will">prepare your last will and testament</a>"a[href="mars2\.html\?a\=last_will"]"
    -
    -
    -
    -
    -
    -
    -
    Links must have discernible text
    - Learn more -
    -
    -
    link-name
    -
    - WCAG 2.0 Level A -
    -
    -
    -

    Ensures links have discernible text

    -
    - serious -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<a class="link" href="demo/mars/#"><i class="icon-menu-home"></i> </a>".link[href$="mars\/\#"]"
    2<a href="mars2.html?a=crater_adventure"> -<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    3<a href="mars2.html?a=crater_adventure"> -<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    4<a href="mars2.html?a=crater_adventure"> -<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    5<a href="mars2.html?a="></a>":root > a[href="mars2\.html\?a\="]"
    6<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    7<a target="player" data-text="Why Mars died" class="fader first" href="http://www.youtube.com/embed/oC31pqk9sak?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="Why\ Mars\ died"]"
    8<a target="player" data-text="The world that never was" class="fader first" href="http://www.youtube.com/embed/JgMXPXdqJn8?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="The\ world\ that\ never\ was"]"
    -
    -
    -
    -
    -
    -
    -
    All page content must be contained by landmarks
    - Learn more -
    -
    -
    region
    -
    - Best practice -
    -
    -
    -

    Ensures all page content is contained by landmarks

    -
    - moderate -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #Source CodeSelector
    1<div style="width: 1px; height: 1px; display: inline;">"body > div:nth-child(1)"
    2<div id="purposeDisclaimer">This web page is for demonstration purposes, to show common accessibility errors.</div>"#purposeDisclaimer"
    3<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    4<input type="submit" class="control-search">":root > .control-search[type="submit"]"
    5<div class="span7 left-first pull-left" id="left-column">"#left-column"
    6<div id="widget-controls" class="widget-container head">"#widget-controls"
    7<h3>Book your Trip</h3>"#route-select > .interior-container > h3"
    8<div id="route-type-radio-group" class="">"#route-type-radio-group"
    9<div id="route-type">"#route-type"
    10<div id="pass-question-radio-group" class="">"#pass-question-radio-group"
    11<h3>Who Is Traveling?</h3>".middle.widget-container:nth-child(13) > .interior-container > h3"
    12<span class="wrapper"> -<span class="traveler-label">Traveler</span> -</span>"#passenger0 > .wrapper:nth-child(1)"
    13<span class="wrapper age-range"> -<select id="traveler0" class="traveler-type"> -<option value="0">Adult (26+)</option> -<option value="1">Youth (12-25)</option> -<option value="2">Child (4-11)</option> -<option value="3">Senior (60+)</option> -</select> -</span>"#passenger0 > .age-range.wrapper"
    14<div class="add-buttons" id="add-traveler">"#add-traveler"
    15<div id="booking-box-submit" class="widget-container footer">"#booking-box-submit"
    16<div class="interior-container">"#video-box > .interior-container"
    17<div id="social-bar" class="container-fluid-full">"#social-bar"
    18<h4>Book Your Trip</h4>"#footer-book > h4"
    19<ul>"#footer-book > ul"
    20<h4>Mars Shuttles</h4>"#footer-trains > h4"
    21<ul>"#footer-trains > ul"
    22<h4>Mars Tourist Passes</h4>"#footer-passes > h4"
    23<ul>"#footer-passes > ul"
    24<h4>Mars Adventures</h4>"#footer-plan > h4"
    25<ul>"#footer-plan > ul"
    26<h4>FAQs</h4>"#footer-faq > h4"
    27<ul>"#footer-faq > ul"
    28<h4>Connect With Us</h4>"#footer-connect > h4"
    29<ul>"#footer-connect > ul"
    30<div id="copyright" class="container">"#copyright"
    31<div id="player" style="width: 100%; height: 100%;">"#player", "#player"
    32<tr><td><span class="fsl fwb"><a href="../mars2.html" target="_blank">Mars Commuter Express</a></span></td></tr>"#fafbba78", "._8m > table > tbody > tr:nth-child(1)"
    33<div class="pluginButton pluginConnectButtonDisconnected" title=""><div><button type="submit"><i class="pluginButtonIcon img sp_like sx_like_thumb"></i>Like</button></div></div>"#fafbba78", ".pluginConnectButtonDisconnected"
    34<span id="u_0_2">378,121</span>"#fafbba78", "#u_0_2"
    35<div class="btn-o" contextmenu="menu"><a id="follow-button" target="_blank" class="btn" title="Follow MarsCommuter on Twitter" href="mars2.html"><i></i><span class="label" id="l">Follow @MarsTrip1</span></a></div>".twitter-follow-button", ".btn-o"
    36<img src="../images/f.gif" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src="\.\.\/images\/f\.gif"]"
    37<img src="jot" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src$="jot"]"
    -
    -
    -
    -
    -
    -
    -
    Elements should not have tabindex greater than zero
    - Learn more -
    -
    -
    tabindex
    -
    - Best practice -
    -
    -
    -

    Ensures tabindex attribute values are not greater than 0

    -
    - serious -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - + +
    #Source CodeSelector
    1<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="from0" name="from0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#from0"
    2<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="to0" name="to0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#to0"
    3<input size="10" id="deptDate0" name="deptDate0" placeholder="mm/dd/yyyy" value="" tabindex="3" class="hasDatepicker input-dept">"#deptDate0"<input size="10" id="deptDate0" name="deptDate0" placeholder="mm/dd/yyyy" value="" tabindex="3" class="hasDatepicker input-dept">"#deptDate0"
    @@ -1197,7 +317,7 @@
    aria-expanded="false" aria-controls="passes" > - axe returned 38 passed axe + axe returned 12 passed axe checks. Expand details on click @@ -1223,306 +343,664 @@
    1 - Elements must only use allowed ARIA attributes - aria-allowed-attr + aria-hidden='true' must not be present on the document body + aria-hidden-body WCAG 2.0 Level A - 10 + 1 2 - ARIA role must be appropriate for the element - aria-allowed-role + Page must have means to bypass repeated blocks + bypass + WCAG 2.0 Level A + 1 + + + + 3 + Elements must have sufficient color contrast + color-contrast + WCAG 2.0 Level AA + 3 + + + + 4 + Documents must have <title> element to aid in navigation + document-title + WCAG 2.0 Level A + 1 + + + + 5 + Headings must not be empty + empty-heading + Best practice + 1 + + + + 6 + Heading levels should only increase by one + heading-order + Best practice + 1 + + + + 7 + Hidden content on the page cannot be analyzed + hidden-content Best practice 14 - 3 - aria-hidden='true' must not be present on the document body - aria-hidden-body + 8 + Links must have discernible text + link-name WCAG 2.0 Level A 1 + + + 9 + Users should be able to zoom and scale the text up to 500% + meta-viewport-large + Best practice + 1 + + + + 10 + Zooming and scaling must not be disabled + meta-viewport + Best practice + 1 + + + + 11 + Page must contain a level-one heading + page-has-heading-one + Best practice + 1 + + + + 12 + All page content must be contained by landmarks + region + Best practice + 4 + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'incomplete' axe checks means?

    +

    + Incomplete 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. +

    +

    + Visit axe API Documentation + to learn more. +

    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'inapplicable' axe checks means?

    +

    + The inapplicable array lists all the rules for which no matching + elements were found on the page. +

    +

    + Visit axe API Documentation + to learn more. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + - - + - - + - - + + + + + + + + - - + + + + + + + + - - + - - + + + + + + + + - - + - - + + + + + + + + - - - - + + + - - - - + + + - - + + + + + + + + - - + - - - - + + + - - + - - - - + + + - - - - + + + - - - - + + + - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - + - - - - - - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - + - - - - - - + + + + - - - - - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + - - + + + + + + + + - - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + -
    #DescriptionAxe rule IDWCAG
    1accesskey attribute value must be uniqueaccesskeysBest practice
    2Active <area> elements must have alternate textarea-altWCAG 2.0 Level A
    3Elements must only use allowed ARIA attributesaria-allowed-attrWCAG 2.0 Level A
    4ARIA role must be appropriate for the elementaria-allowed-roleBest practice
    5 ARIA hidden element must not contain focusable elements aria-hidden-focus WCAG 2.0 Level A2
    56ARIA input fields must have an accessible namearia-input-field-nameWCAG 2.0 Level A
    7 Required ARIA attributes must be provided aria-required-attr WCAG 2.0 Level A13
    68 Certain ARIA roles must contain particular children aria-required-children WCAG 2.0 Level A13
    79 Certain ARIA roles must be contained by particular parents aria-required-parent WCAG 2.0 Level A13
    810Use aria-roledescription on elements with a semantic rolearia-roledescriptionWCAG 2.0 Level A
    11 ARIA roles used must conform to valid values aria-roles WCAG 2.0 Level A13
    912ARIA toggle fields have an accessible namearia-toggle-field-nameWCAG 2.0 Level A
    13 ARIA attributes must conform to valid values aria-valid-attr-value WCAG 2.0 Level A10
    1014 ARIA attributes must conform to valid names aria-valid-attr WCAG 2.0 Level A10
    1115<audio> elements must have a captions trackaudio-captionWCAG 2.0 Level A
    16 autocomplete attribute must be used correctly autocomplete-valid WCAG 2.1 Level AA3
    1217 Inline text spacing must be adjustable with custom stylesheets avoid-inline-spacing WCAG 2.1 Level AA8
    1318<blink> elements are deprecated and must not be usedblinkWCAG 2.0 Level A
    19 Buttons must have discernible text button-name WCAG 2.0 Level A12
    14Page must have means to bypass repeated blocksbypass20<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elementsdefinition-list WCAG 2.0 Level A1
    15Documents must have <title> element to aid in navigationdocument-title21<dt> and <dd> elements must be contained by a <dl>dlitem WCAG 2.0 Level A1
    1622IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level A
    23 IDs used in ARIA and labels must be unique duplicate-id-aria WCAG 2.0 Level A7
    1724 id attribute value must be unique duplicate-id WCAG 2.0 Level A20
    18Headings must not be emptyempty-heading25Elements in the focus order need a role appropriate for interactive contentfocus-order-semantics Best practice6
    1926 Form field should not have multiple label elements form-field-multiple-labels WCAG 2.0 Level A17
    20Heading levels should only increase by oneheading-order27Frames must be tested with axe-coreframe-tested Best practice6
    21Hidden content on the page cannot be analyzedhidden-content28Frames must have a unique title attributeframe-title-unique Best practice434
    22<html> element must have a lang attributehtml-has-lang29Frames must have title attributeframe-title WCAG 2.0 Level A1
    2330 <html> element must have a valid value for the lang attribute html-lang-valid WCAG 2.0 Level A1
    2431HTML elements with lang and xml:lang must have the same base languagehtml-xml-lang-mismatchWCAG 2.0 Level A
    32Images must have alternate textimage-altWCAG 2.0 Level A
    33Alternative text of images should not be repeated as textimage-redundant-altBest practice
    34Input buttons must have discernible textinput-button-nameWCAG 2.0 Level A
    35Image buttons must have alternate textinput-image-altWCAG 2.0 Level A
    36 Elements must have their visible text as part of their accessible name label-content-name-mismatch WCAG 2.1 Level A1
    2537 Form elements should have a visible label label-title-only Best practice17
    2638 Form elements must have labels label WCAG 2.0 Level A12
    27Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A139Banner landmark must not be contained in another landmarklandmark-banner-is-top-levelBest practice
    28Links must have discernible textlink-name40Aside must not be contained in another landmarklandmark-complementary-is-top-levelBest practice
    41Contentinfo landmark must not be contained in another landmarklandmark-contentinfo-is-top-levelBest practice
    42Main landmark must not be contained in another landmarklandmark-main-is-top-levelBest practice
    43Document must not have more than one banner landmarklandmark-no-duplicate-bannerBest practice
    44Document must not have more than one contentinfo landmarklandmark-no-duplicate-contentinfoBest practice
    45Document must not have more than one main landmarklandmark-no-duplicate-mainBest practice
    46Ensures landmarks are uniquelandmark-uniqueBest practice
    47Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-block WCAG 2.0 Level A5
    2948 <ul> and <ol> must only directly contain <li>, <script> or <template> elements list WCAG 2.0 Level A1
    3049 <li> elements must be contained in a <ul> or <ol> listitem WCAG 2.0 Level A3
    31Users should be able to zoom and scale the text up to 500%meta-viewport-largeBest practice150<marquee> elements are deprecated and must not be usedmarqueeWCAG 2.0 Level A
    32Zooming and scaling must not be disabledmeta-viewportBest practice151Timed refresh must not existmeta-refreshWCAG 2.0 Level A
    33Page must contain a level-one headingpage-has-heading-one52<object> elements must have alternate textobject-altWCAG 2.0 Level A
    53Bold, italic text and font-size are not used to style p elements as a headingp-as-headingWCAG 2.0 Level A
    54[role='img'] elements have an alternative textrole-img-altWCAG 2.0 Level A
    55scope attribute should be used correctlyscope-attr-valid Best practice1
    34All page content must be contained by landmarksregion56Ensure that scrollable region has keyboard accessscrollable-region-focusableWCAG 2.0 Level A
    57Server-side image maps must not be usedserver-side-image-mapWCAG 2.0 Level A
    58The skip-link target should exist and be focusableskip-link Best practice280
    3559svg elements with an img role have an alternative textsvg-img-altWCAG 2.0 Level A
    60 Elements should not have tabindex greater than zero tabindex Best practice5
    3661 The <caption> element should not contain the same text as the summary attribute table-duplicate-name Best practice1
    37Data or header cells should not be used to give caption to a data table.table-fake-caption62Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A
    63All non-empty td element in table larger than 3 by 3 must have an associated table headertd-has-headerWCAG 2.0 Level A
    64All cells in a table element that use the headers attribute must only refer to other cells of that same tabletd-headers-attrWCAG 2.0 Level A
    65All th elements and elements with role=columnheader/rowheader must have data cells they describeth-has-data-cellsWCAG 2.0 Level A
    66lang attribute must have a valid valuevalid-langWCAG 2.0 Level AA
    67<video> elements must have captionsvideo-caption WCAG 2.0 Level A1
    38All cells in a table element that use the headers attribute must only refer to other cells of that same tabletd-headers-attr68<video> or <audio> elements do not autoplay audiono-autoplay-audio WCAG 2.0 Level A1
    @@ -1530,335 +1008,541 @@
    -
    -
    -
    -
    - -
    -
    -
    -
    -

    What 'incomplete' axe checks means?

    -

    - Incomplete 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. -

    -

    - Visit axe API Documentation - to learn more. -

    -
    -
    -
    -
    -
    +
    -
    +
    -

    What 'inapplicable' axe checks means?

    -

    - The inapplicable array lists all the rules for which no matching - elements were found on the page. -

    -

    - Visit axe API Documentation - to learn more. -

    - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + + - - - - - - + + + + +
    #DescriptionAxe rule IDWCAG
    #Rule IDEnabled
    1accesskey attribute value must be uniqueaccesskeysBest practice
    1object-alttrue
    2Active <area> elements must have alternate textarea-altWCAG 2.0 Level A
    2role-img-alttrue
    3ARIA input fields must have an accessible namearia-input-field-nameWCAG 2.0 Level A
    3input-image-alttrue
    4image-alttrue
    5svg-img-alttrue
    6area-alttrue
    7audio-captiontrue
    8video-captiontrue
    9definition-listtrue
    10dlitemtrue
    11listitemtrue
    12listtrue
    13th-has-data-cellstrue
    14td-headers-attrtrue
    15td-has-headertrue
    16p-as-headingtrue
    17aria-required-parenttrue
    18aria-required-childrentrue
    19table-fake-captiontrue
    20css-orientation-lockfalse
    21autocomplete-validtrue
    22link-in-text-blocktrue
    23no-autoplay-audiotrue
    24color-contrasttrue
    25meta-viewporttrue
    26avoid-inline-spacingtrue
    27server-side-image-maptrue
    28meta-refreshtrue
    29blinktrue
    30marqueetrue
    31bypasstrue
    32frame-titletrue
    33document-titletrue
    34scrollable-region-focusabletrue
    35identical-links-same-purposefalse
    36label-content-name-mismatchtrue
    37html-has-langtrue
    38html-lang-validtrue
    39html-xml-lang-mismatchtrue
    40valid-langtrue
    41form-field-multiple-labelstrue
    42duplicate-id-activetrue
    43duplicate-idtrue
    44duplicate-id-ariatrue
    45aria-valid-attrtrue
    46aria-valid-attr-valuetrue
    47aria-input-field-nametrue
    48aria-rolestrue
    49aria-toggle-field-nametrue
    50aria-hidden-focustrue
    51aria-hidden-bodytrue
    52button-nametrue
    4Use aria-roledescription on elements with a semantic rolearia-roledescriptionWCAG 2.0 Level A
    53aria-allowed-attrtrue
    5ARIA toggle fields have an accessible namearia-toggle-field-nameWCAG 2.0 Level A
    54input-button-nametrue
    6<audio> elements must have a captions trackaudio-captionWCAG 2.0 Level A
    55aria-required-attrtrue
    7<blink> elements are deprecated and must not be usedblinkWCAG 2.0 Level A
    56aria-roledescriptiontrue
    8<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elementsdefinition-listWCAG 2.0 Level A
    57link-nametrue
    9<dt> and <dd> elements must be contained by a <dl>dlitemWCAG 2.0 Level A
    58labeltrue
    10Elements in the focus order need a role appropriate for interactive contentfocus-order-semanticsBest practice
    59accesskeystrue
    11HTML elements with lang and xml:lang must have the same base languagehtml-xml-lang-mismatchWCAG 2.0 Level A
    60regiontrue
    12Image buttons must have alternate textinput-image-altWCAG 2.0 Level A
    61aria-allowed-roletrue
    13Elements must have their visible text as part of their accessible namelabel-content-name-mismatchWCAG 2.1 Level A
    62landmark-banner-is-top-leveltrue
    14Banner landmark must not be contained in another landmarklandmark-banner-is-top-levelBest practice
    63landmark-complementary-is-top-leveltrue
    15Aside must not be contained in another landmarklandmark-complementary-is-top-levelBest practice
    64landmark-contentinfo-is-top-leveltrue
    16Contentinfo landmark must not be contained in another landmarklandmark-contentinfo-is-top-levelBest practice
    65focus-order-semanticstrue
    17Main landmark must not be contained in another landmarklandmark-main-is-top-levelBest practice
    66tabindextrue
    18Document must not have more than one banner landmarklandmark-no-duplicate-bannerBest practice
    67landmark-no-duplicate-maintrue
    19Document must not have more than one contentinfo landmarklandmark-no-duplicate-contentinfoBest practice
    68label-title-onlytrue
    20Document must not have more than one main landmarklandmark-no-duplicate-mainBest practice
    69frame-testedtrue
    21<marquee> elements are deprecated and must not be usedmarqueeWCAG 2.0 Level A
    70frame-title-uniquetrue
    22Timed refresh must not existmeta-refreshWCAG 2.0 Level A
    71heading-ordertrue
    23<object> elements must have alternate textobject-altWCAG 2.0 Level A
    72empty-headingtrue
    24Bold, italic text and font-size are not used to style p elements as a headingp-as-headingWCAG 2.0 Level A
    73hidden-contenttrue
    25[role='img'] elements have an alternative textrole-img-altWCAG 2.0 Level A
    74landmark-uniquetrue
    26scope attribute should be used correctlyscope-attr-validBest practice
    75landmark-main-is-top-leveltrue
    27Ensure that scrollable region has keyboard accessscrollable-region-focusableWCAG 2.0 Level A
    76page-has-heading-onetrue
    28Server-side image maps must not be usedserver-side-image-mapWCAG 2.0 Level A
    77landmark-one-maintrue
    29The skip-link target should exist and be focusableskip-linkBest practice
    78landmark-no-duplicate-bannertrue
    30svg elements with an img role have an alternative textsvg-img-altWCAG 2.0 Level A
    79landmark-no-duplicate-contentinfotrue
    31Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A
    80scope-attr-validtrue
    32All non-empty td element in table larger than 3 by 3 must have an associated table headertd-has-headerWCAG 2.0 Level A
    81image-redundant-alttrue
    33All th elements and elements with role=columnheader/rowheader must have data cells they describeth-has-data-cellsWCAG 2.0 Level A
    82table-duplicate-nametrue
    34lang attribute must have a valid valuevalid-langWCAG 2.0 Level AA
    83skip-linktrue
    35<video> or <audio> elements do not autoplay audiono-autoplay-audioWCAG 2.0 Level A
    84meta-viewport-largetrue
    diff --git a/package-lock.json b/package-lock.json index 51ebfd4..3a7de96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "axe-html-reporter", - "version": "1.1.0", + "version": "1.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1147d2b..cec64bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "axe-html-reporter", - "version": "1.1.0", + "version": "1.2.1", "description": "The module that allows you to create HTML Report from raw accessibility aXe result object", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/index.ts b/src/index.ts index 3b1ca95..58347b1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,21 +1,22 @@ import mustache from 'mustache'; -import { Result } from 'axe-core'; +import { AxeResults, Result } from 'axe-core'; import { loadTemplate } from './util/loadTemplate'; import { prepareReportData } from './util/prepareReportData'; +import { prepareAxeRules } from './util/prepareAxeRules'; import { saveHtmlReport } from './util/saveHtmlReport'; -export interface CreateReport { - violations: Result[]; - url: string; - passes?: Result[]; - incomplete?: Result[]; - inapplicable?: Result[]; +export interface Options { reportFileName?: string; outputDir?: string; projectKey?: string; customSummary?: string; } +export interface CreateReport { + results: Partial; + options?: Options; +} + export interface PreparedResults { violations: Result[]; passes?: Result[]; @@ -23,41 +24,44 @@ export interface PreparedResults { inapplicable?: Result[]; } -export function createHtmlReport({ - violations, - url, - passes, - incomplete, - inapplicable, - reportFileName, - outputDir, - projectKey, - customSummary, -}: CreateReport): void { - if (!violations || !url) { +export function createHtmlReport({ results, options }: CreateReport): void { + if (!results.violations) { throw new Error( - "violations and url parameters are required for HTML accessibility report. Example: createHtmlReport({violations: Result[], url: 'www.example.com'})" + "'violations' is required for HTML accessibility report. Example: createHtmlReport({ results : { violations: Result[] } })" ); } try { const template = loadTemplate(); - const reportData = prepareReportData({ violations, passes, incomplete, inapplicable }); + const preparedReportData = prepareReportData({ + violations: results.violations, + passes: results.passes, + incomplete: results.incomplete, + inapplicable: results.inapplicable, + }); const htmlContent = mustache.render(template, { - url, - violationsSummary: reportData.violationsSummary, - violations: reportData.violationsSummaryTable, - violationDetails: reportData.violationsDetails, - checksPassed: reportData.checksPassed, - checksIncomplete: reportData.checksIncomplete, - checksInapplicable: reportData.checksInapplicable, - hasPassed: passes !== undefined, - hasIncomplete: incomplete !== undefined, - hasInapplicable: inapplicable !== undefined, - incompleteTotal: reportData.checksIncomplete ? reportData.checksIncomplete.length : 0, - projectKey, - customSummary, + url: results.url, + violationsSummary: preparedReportData.violationsSummary, + violations: preparedReportData.violationsSummaryTable, + violationDetails: preparedReportData.violationsDetails, + checksPassed: preparedReportData.checksPassed, + checksIncomplete: preparedReportData.checksIncomplete, + checksInapplicable: preparedReportData.checksInapplicable, + hasPassed: Boolean(results.passes), + hasIncomplete: Boolean(results.incomplete), + hasInapplicable: Boolean(results.inapplicable), + incompleteTotal: preparedReportData.checksIncomplete + ? preparedReportData.checksIncomplete.length + : 0, + projectKey: options?.projectKey, + customSummary: options?.customSummary, + hasAxeRawResults: Boolean(results?.timestamp), + rules: prepareAxeRules(results?.toolOptions?.rules || {}), + }); + saveHtmlReport({ + htmlContent, + reportFileName: options?.reportFileName, + outputDir: options?.outputDir, }); - saveHtmlReport({ htmlContent, reportFileName, outputDir }); } catch (e) { console.warn(`HTML report was not created due to the error ${e.message}`); } diff --git a/src/util/prepareAxeRules.ts b/src/util/prepareAxeRules.ts new file mode 100644 index 0000000..8972282 --- /dev/null +++ b/src/util/prepareAxeRules.ts @@ -0,0 +1,12 @@ +import { RuleObject } from 'axe-core'; + +export interface ReformattedRulesObject { + index: number; + rule: string; + enabled: boolean; +} +export function prepareAxeRules(rules: RuleObject): ReformattedRulesObject[] { + return Object.keys(rules).map((id, index) => { + return { index: ++ index, rule: id, enabled: rules[id].enabled }; + }); +} diff --git a/src/util/prepareReportData.ts b/src/util/prepareReportData.ts index 4bc7b24..a6978f7 100644 --- a/src/util/prepareReportData.ts +++ b/src/util/prepareReportData.ts @@ -12,7 +12,7 @@ function simplifyAxeResultForSummary(results: Result[]): Summary[] { help, wcag: getWcagReference(tags), impact: impact || 'n/a', - nodes: nodes.length, + nodes: nodes.length })); } /** diff --git a/src/util/saveHtmlReport.ts b/src/util/saveHtmlReport.ts index 6f10b4b..8d4fdee 100644 --- a/src/util/saveHtmlReport.ts +++ b/src/util/saveHtmlReport.ts @@ -1,5 +1,7 @@ import fs from 'fs'; +export const defaultReportFileName = 'accessibilityReport.html'; + interface SaveReportOptions { htmlContent: string; reportFileName?: string; @@ -22,7 +24,7 @@ export function saveHtmlReport({ recursive: true, }); } - const reportFilePath = `${reportDirectory}/${reportFileName || 'accessibilityReport.html'}`; + const reportFilePath = `${reportDirectory}/${reportFileName || defaultReportFileName}`; fs.writeFileSync(reportFilePath, htmlContent); console.info(`HTML report was saved into the following directory ${reportFilePath}`); } catch (err) { diff --git a/src/util/template/pageTemplate.html b/src/util/template/pageTemplate.html index f41558e..45f895b 100644 --- a/src/util/template/pageTemplate.html +++ b/src/util/template/pageTemplate.html @@ -58,6 +58,7 @@

    AXE Accessibility Results{{#projectKey}} for {{projectKey}} project{{/projectKey}}

    + {{#url}}
    Page URL: @@ -67,7 +68,7 @@
    {{{customSummary}}} {{/customSummary}}
    - + {{/url}}
    {{{violationsSummary}}}
    {{#violationDetails.length}} @@ -324,6 +325,55 @@
    {{/hasInapplicable}} + {{#hasAxeRawResults}} +
    +
    +
    +
    + +
    +
    +
    +
    + {{#rules.length}} +
    + + + + + + + + + {{#rules}} + + + + + + + {{/rules}} +
    #Rule IDEnabled
    {{index}}{{rule}}{{enabled}}
    + {{/rules.length}} +
    +
    +
    +
    + {{/hasAxeRawResults}}
    diff --git a/temp/tcPassesViolationsIncomplete.html b/temp/tcPassesViolationsIncomplete.html new file mode 100644 index 0000000..823834c --- /dev/null +++ b/temp/tcPassesViolationsIncomplete.html @@ -0,0 +1,1612 @@ + + + + + + + + + + + + + + AXE Accessibility Results + + +
    +

    + AXE Accessibility Results +

    +
    + Page URL: + https://dequeuniversity.com/demo/mars/ + + +
    +
    axe-core found 85 violations
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGImpactCount
    1Buttons must have discernible textbutton-nameWCAG 2.0 Level Acritical1
    2Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AAserious11
    3IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level Aserious1
    4id attribute value must be uniqueduplicate-idWCAG 2.0 Level Aminor10
    5Frames must have title attributeframe-titleWCAG 2.0 Level Aserious2
    6<html> element must have a lang attributehtml-has-langWCAG 2.0 Level Aserious1
    7Images must have alternate textimage-altWCAG 2.0 Level Acritical4
    8Form elements must have labelslabelWCAG 2.0 Level Acritical1
    9Document must have one main landmarklandmark-one-mainBest practicemoderate4
    10Ensures landmarks are uniquelandmark-uniqueBest practicemoderate1
    11Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level Aserious1
    12Links must have discernible textlink-nameWCAG 2.0 Level Aserious8
    13All page content must be contained by landmarksregionBest practicemoderate37
    14Elements should not have tabindex greater than zerotabindexBest practiceserious3
    +

    Failed

    +
    +
    +
    +
    Buttons must have discernible text
    + Learn more +
    +
    +
    button-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures buttons have discernible text

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<button class="ui-datepicker-trigger" type="button"> +<!-- <img title="..." alt="..." src="/redesign/assets/demo-sites/mars/images/calendar.png"> --> +</button>".departure-date > .ui-datepicker-trigger:nth-child(4)"
    +
    +
    +
    +
    +
    +
    +
    Elements must have sufficient color contrast
    + Learn more +
    +
    +
    color-contrast
    +
    + WCAG 2.0 Level AA +
    +
    +
    +

    Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<h3>Be Bold...</h3>":root > h3"
    2<p>Step out of your comfort zone, and into a rocket with enough fuel to blast a Manhattan-sized crater if it explodes. But it won't. Probably.<br> +&nbsp; </p>"#vap-plan > p:nth-child(3)"
    3<h3>Countdown...</h3>":root > h3"
    4<p>If you're serious about traveling to Mars - really serious - then <a href="mars2.html?a=last_will">prepare your last will and testament</a>, and book a trip! </p>"#vap-book > p:nth-child(3)"
    5<h3>Blast Off!</h3>":root > h3"
    6<p>Expect violent turbulence, bone-crushing g-forces, muscle atrophy, and certain death (hey, everyone's death is certain at some point, right?).<br> +&nbsp; </p>"#vap-travel > p:nth-child(3)"
    7<a class="" href="mars2.html?a=crater_adventure">10% off Crater Adventure</a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    8<a class="" href="mars2.html?a=ice_cream">Free Astronaut Ice Cream</a>":root > a[href="mars2\.html\?a\=ice_cream"]"
    9<p>Spend an extra 3 months in orbit around Mars in our newly-remodelled MarsPod and get a free package of freeze-wrapped dehydrated astronaut ice cream. <a class="link-arrow" href="mars2.html?a=ice_cream">Get your free dehydrated ice cream!</a> +</p>"li:nth-child(2) > .deal-text > p"
    10<a class="link" href="mars2.html?a=low_price_guarantee">Lowest Price Guarantee</a>"li:nth-child(3) > .deal-text > h3 > .link"
    11<a href="mars2.html?a=free_year">Book a free year on Mars</a>":root > a[href="mars2\.html\?a\=free_year"]"
    +
    +
    +
    +
    +
    +
    +
    IDs of active elements must be unique
    + Learn more +
    +
    +
    duplicate-id-active
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every id attribute value of active elements is unique

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    +
    +
    +
    +
    +
    +
    +
    id attribute value must be unique
    + Learn more +
    +
    +
    duplicate-id
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every id attribute value is unique

    +
    + minor +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div id="control-panel" class="container-fluid-full">".loginnow > .container-fluid-full"
    2<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    3<div id="search-bar" class="pull-left"> +<form id="search" action="/demo/mars/mars2" method="get"> +<input type="hidden" name="fn" value="Search"> +<input type="text" class="search" name="query" placeholder="search"> +<input type="submit" class="control-search"> +</form> +</div>".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(2)"
    4<form id="search" action="/demo/mars/mars2" method="get"> +<input type="hidden" name="fn" value="Search"> +<input type="text" class="search" name="query" placeholder="search"> +<input type="submit" class="control-search"> +</form>":root > form[method="get"][action="\/demo\/mars\/mars2"]"
    5<nav id="right-control-nav" class="pull-right" style="display: inline;">".loginnow > .container-fluid-full > .container > .span7.pull-right > .pull-right"
    6<div id="vap-section"> +<h1 style="color:#eee;">Destination Mars </h1> +<h2 style="color:#acbad0;">A trip to Mars starts in your imagination. Are you bold enough, brave enough, <strong>foolish enough?</strong> We are. You belong on Mars with fools like us. Most of us don't bite. Much.</h2></div>"#left-column > div:nth-child(1)"
    7<input type="hidden" id="nCountries" name="nCountries">"#select-country > input[name="nCountries"][type="hidden"]"
    8<div id="passenger-select" class="widget-container middle">".middle.widget-container:nth-child(13)"
    9<div id="passengers">".middle.widget-container:nth-child(13) > .interior-container > div:nth-child(3)"
    10<div id="ui-datepicker-div" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>".ui-datepicker.ui-helper-clearfix.ui-corner-all:nth-child(33)"
    +
    +
    +
    +
    +
    +
    +
    Frames must have title attribute
    + Learn more +
    +
    +
    frame-title
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures <iframe> and <frame> elements contain a non-empty title attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<iframe width="365" height="205" name="player" id="player" src="https://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>"#player"
    2<iframe id="fafbba78" name="f2bc5e72d" scrolling="no" style="border: none; overflow: hidden; height: 62px; width: 292px;" class="fb_ltr" src="/assets/demo-sites/mars/js/likebox.html"></iframe>"#fafbba78"
    +
    +
    +
    +
    +
    +
    +
    <html> element must have a lang attribute
    + Learn more +
    +
    +
    html-has-lang
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every HTML document has a lang attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    +
    +
    +
    +
    +
    +
    +
    Images must have alternate text
    + Learn more +
    +
    +
    image-alt
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures <img> elements have alternate text or a role of none or presentation

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<img src="/assets/demo-sites/mars/js/seg" width="1" height="1">"img[src$="seg"]"
    2<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\32 10"][height="\31 20"]"
    3<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\32 10"][height="\31 20"]"
    4<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\32 10"][height="\31 20"]"
    +
    +
    +
    +
    +
    +
    +
    Form elements must have labels
    + Learn more +
    +
    +
    label
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every form element has a label

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    +
    +
    +
    +
    +
    +
    +
    Document must have one main landmark
    + Learn more +
    +
    +
    landmark-one-main
    +
    + Best practice +
    +
    +
    +

    Ensures the document has a main landmark

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    2<html lang="en" dir="ltr" data-cast-api-enabled="true">"#player", "html"
    3<html lang="en" id="facebook" class="">"#fafbba78", "#facebook"
    4<html lang="en" class=" xl en">".twitter-follow-button", "html"
    +
    +
    +
    +
    +
    +
    +
    Ensures landmarks are unique
    + Learn more +
    +
    +
    landmark-unique
    +
    + Best practice +
    +
    +
    +

    Landmarks must have a unique role or role/label/title (i.e. accessible name) combination

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    +
    +
    +
    +
    +
    +
    +
    Links must be distinguished from surrounding text in a way that does not rely on color
    + Learn more +
    +
    +
    link-in-text-block
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Links can be distinguished without relying on color

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a href="mars2.html?a=last_will">prepare your last will and testament</a>"a[href="mars2\.html\?a\=last_will"]"
    +
    +
    +
    +
    +
    +
    +
    Links must have discernible text
    + Learn more +
    +
    +
    link-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures links have discernible text

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a class="link" href="demo/mars/#"><i class="icon-menu-home"></i> </a>".link[href$="mars\/\#"]"
    2<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    3<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    4<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\.html\?a\=crater_adventure"]"
    5<a href="mars2.html?a="></a>":root > a[href="mars2\.html\?a\="]"
    6<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    7<a target="player" data-text="Why Mars died" class="fader first" href="http://www.youtube.com/embed/oC31pqk9sak?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="Why\ Mars\ died"]"
    8<a target="player" data-text="The world that never was" class="fader first" href="http://www.youtube.com/embed/JgMXPXdqJn8?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="The\ world\ that\ never\ was"]"
    +
    +
    +
    +
    +
    +
    +
    All page content must be contained by landmarks
    + Learn more +
    +
    +
    region
    +
    + Best practice +
    +
    +
    +

    Ensures all page content is contained by landmarks

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div style="width: 1px; height: 1px; display: inline;">"body > div:nth-child(1)"
    2<div id="purposeDisclaimer">This web page is for demonstration purposes, to show common accessibility errors.</div>"#purposeDisclaimer"
    3<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    4<input type="submit" class="control-search">":root > .control-search[type="submit"]"
    5<div class="span7 left-first pull-left" id="left-column">"#left-column"
    6<div id="widget-controls" class="widget-container head">"#widget-controls"
    7<h3>Book your Trip</h3>"#route-select > .interior-container > h3"
    8<div id="route-type-radio-group" class="">"#route-type-radio-group"
    9<div id="route-type">"#route-type"
    10<div id="pass-question-radio-group" class="">"#pass-question-radio-group"
    11<h3>Who Is Traveling?</h3>".middle.widget-container:nth-child(13) > .interior-container > h3"
    12<span class="wrapper"> +<span class="traveler-label">Traveler</span> +</span>"#passenger0 > .wrapper:nth-child(1)"
    13<span class="wrapper age-range"> +<select id="traveler0" class="traveler-type"> +<option value="0">Adult (26+)</option> +<option value="1">Youth (12-25)</option> +<option value="2">Child (4-11)</option> +<option value="3">Senior (60+)</option> +</select> +</span>"#passenger0 > .age-range.wrapper"
    14<div class="add-buttons" id="add-traveler">"#add-traveler"
    15<div id="booking-box-submit" class="widget-container footer">"#booking-box-submit"
    16<div class="interior-container">"#video-box > .interior-container"
    17<div id="social-bar" class="container-fluid-full">"#social-bar"
    18<h4>Book Your Trip</h4>"#footer-book > h4"
    19<ul>"#footer-book > ul"
    20<h4>Mars Shuttles</h4>"#footer-trains > h4"
    21<ul>"#footer-trains > ul"
    22<h4>Mars Tourist Passes</h4>"#footer-passes > h4"
    23<ul>"#footer-passes > ul"
    24<h4>Mars Adventures</h4>"#footer-plan > h4"
    25<ul>"#footer-plan > ul"
    26<h4>FAQs</h4>"#footer-faq > h4"
    27<ul>"#footer-faq > ul"
    28<h4>Connect With Us</h4>"#footer-connect > h4"
    29<ul>"#footer-connect > ul"
    30<div id="copyright" class="container">"#copyright"
    31<div id="player" style="width: 100%; height: 100%;">"#player", "#player"
    32<tr><td><span class="fsl fwb"><a href="../mars2.html" target="_blank">Mars Commuter Express</a></span></td></tr>"#fafbba78", "._8m > table > tbody > tr:nth-child(1)"
    33<div class="pluginButton pluginConnectButtonDisconnected" title=""><div><button type="submit"><i class="pluginButtonIcon img sp_like sx_like_thumb"></i>Like</button></div></div>"#fafbba78", ".pluginConnectButtonDisconnected"
    34<span id="u_0_2">378,121</span>"#fafbba78", "#u_0_2"
    35<div class="btn-o" contextmenu="menu"><a id="follow-button" target="_blank" class="btn" title="Follow MarsCommuter on Twitter" href="mars2.html"><i></i><span class="label" id="l">Follow @MarsTrip1</span></a></div>".twitter-follow-button", ".btn-o"
    36<img src="../images/f.gif" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src="\.\.\/images\/f\.gif"]"
    37<img src="jot" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src$="jot"]"
    +
    +
    +
    +
    +
    +
    +
    Elements should not have tabindex greater than zero
    + Learn more +
    +
    +
    tabindex
    +
    + Best practice +
    +
    +
    +

    Ensures tabindex attribute values are not greater than 0

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="from0" name="from0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#from0"
    2<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="to0" name="to0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#to0"
    3<input size="10" id="deptDate0" name="deptDate0" placeholder="mm/dd/yyyy" value="" tabindex="3" class="hasDatepicker input-dept">"#deptDate0"
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGNodes passed check
    1Elements must only use allowed ARIA attributesaria-allowed-attrWCAG 2.0 Level A10
    2ARIA role must be appropriate for the elementaria-allowed-roleBest practice14
    3aria-hidden='true' must not be present on the document bodyaria-hidden-bodyWCAG 2.0 Level A1
    4ARIA hidden element must not contain focusable elementsaria-hidden-focusWCAG 2.0 Level A2
    5Required ARIA attributes must be providedaria-required-attrWCAG 2.0 Level A13
    6Certain ARIA roles must contain particular childrenaria-required-childrenWCAG 2.0 Level A13
    7Certain ARIA roles must be contained by particular parentsaria-required-parentWCAG 2.0 Level A13
    8ARIA roles used must conform to valid valuesaria-rolesWCAG 2.0 Level A13
    9ARIA attributes must conform to valid valuesaria-valid-attr-valueWCAG 2.0 Level A10
    10ARIA attributes must conform to valid namesaria-valid-attrWCAG 2.0 Level A10
    11autocomplete attribute must be used correctlyautocomplete-validWCAG 2.1 Level AA3
    12Inline text spacing must be adjustable with custom stylesheetsavoid-inline-spacingWCAG 2.1 Level AA8
    13Buttons must have discernible textbutton-nameWCAG 2.0 Level A12
    14Page must have means to bypass repeated blocksbypassWCAG 2.0 Level A1
    15Documents must have <title> element to aid in navigationdocument-titleWCAG 2.0 Level A1
    16IDs used in ARIA and labels must be uniqueduplicate-id-ariaWCAG 2.0 Level A7
    17id attribute value must be uniqueduplicate-idWCAG 2.0 Level A20
    18Headings must not be emptyempty-headingBest practice6
    19Form field should not have multiple label elementsform-field-multiple-labelsWCAG 2.0 Level A17
    20Heading levels should only increase by oneheading-orderBest practice6
    21Hidden content on the page cannot be analyzedhidden-contentBest practice434
    22<html> element must have a lang attributehtml-has-langWCAG 2.0 Level A1
    23<html> element must have a valid value for the lang attributehtml-lang-validWCAG 2.0 Level A1
    24Elements must have their visible text as part of their accessible namelabel-content-name-mismatchWCAG 2.1 Level A1
    25Form elements should have a visible labellabel-title-onlyBest practice17
    26Form elements must have labelslabelWCAG 2.0 Level A12
    27Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A1
    28Links must have discernible textlink-nameWCAG 2.0 Level A5
    29<ul> and <ol> must only directly contain <li>, <script> or <template> elementslistWCAG 2.0 Level A1
    30<li> elements must be contained in a <ul> or <ol>listitemWCAG 2.0 Level A3
    31Users should be able to zoom and scale the text up to 500%meta-viewport-largeBest practice1
    32Zooming and scaling must not be disabledmeta-viewportBest practice1
    33Page must contain a level-one headingpage-has-heading-oneBest practice1
    34All page content must be contained by landmarksregionBest practice280
    35Elements should not have tabindex greater than zerotabindexBest practice5
    36The <caption> element should not contain the same text as the summary attributetable-duplicate-nameBest practice1
    37Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A1
    38All cells in a table element that use the headers attribute must only refer to other cells of that same tabletd-headers-attrWCAG 2.0 Level A1
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'incomplete' axe checks means?

    +

    + Incomplete 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. +

    +

    + Visit axe API Documentation + to learn more. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGNodes with incomplete check
    1Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AA132
    2Hidden content on the page cannot be analyzedhidden-contentBest practice60
    3Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A22
    4<video> elements must have captionsvideo-captionWCAG 2.0 Level A1
    +
    +
    +
    +
    +
    + + diff --git a/test/__snapshots__/index.test.ts.snap b/test/__snapshots__/index.test.ts.snap index ea687af..e3ccf8a 100644 --- a/test/__snapshots__/index.test.ts.snap +++ b/test/__snapshots__/index.test.ts.snap @@ -59,7 +59,7 @@ exports[`createHtmlReport() test All optional parameters present 1`] = `

    - AXE Accessibility Results + AXE Accessibility Results for DEQUE project

    -
    axe-core found 85 violations
    @@ -1189,244 +1188,3661 @@ exports[`createHtmlReport() test All optional parameters present 1`] = ` - - - -" -`; - -exports[`createHtmlReport() test Verify report is created only with violations because passes and incomplete are not passed 1`] = ` -" - - - - - - - - - - - - - AXE Accessibility Results - - -
    -

    - AXE Accessibility Results -

    -
    - Page URL: - https://dequeuniversity.com/demo/mars/ - - -
    - -
    axe-core found 85 violations
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #DescriptionAxe rule IDWCAGImpactCount
    1Buttons must have discernible textbutton-nameWCAG 2.0 Level Acritical1
    2Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AAserious11
    3IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level Aserious1
    4id attribute value must be uniqueduplicate-idWCAG 2.0 Level Aminor10
    5Frames must have title attributeframe-titleWCAG 2.0 Level Aserious2
    6<html> element must have a lang attributehtml-has-langWCAG 2.0 Level Aserious1
    7Images must have alternate textimage-altWCAG 2.0 Level Acritical4
    8Form elements must have labelslabelWCAG 2.0 Level Acritical1
    9Document must have one main landmarklandmark-one-mainBest practicemoderate4
    10Ensures landmarks are uniquelandmark-uniqueBest practicemoderate1
    11Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level Aserious1
    12Links must have discernible textlink-nameWCAG 2.0 Level Aserious8
    13All page content must be contained by landmarksregionBest practicemoderate37
    14Elements should not have tabindex greater than zerotabindexBest practiceserious3
    -

    Failed

    -
    -
    -
    -
    Buttons must have discernible text
    - Learn more -
    -
    -
    button-name
    -
    - WCAG 2.0 Level A -
    -
    -
    -

    Ensures buttons have discernible text

    -
    - critical -
    +
    +
    +
    +
    + +
    -
    - - - - - - - - - - - +
    +
    +
    #Source CodeSelector
    1
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGNodes passed check
    1Elements must only use allowed ARIA attributesaria-allowed-attrWCAG 2.0 Level A10
    2ARIA role must be appropriate for the elementaria-allowed-roleBest practice14
    3aria-hidden='true' must not be present on the document bodyaria-hidden-bodyWCAG 2.0 Level A1
    4ARIA hidden element must not contain focusable elementsaria-hidden-focusWCAG 2.0 Level A2
    5Required ARIA attributes must be providedaria-required-attrWCAG 2.0 Level A13
    6Certain ARIA roles must contain particular childrenaria-required-childrenWCAG 2.0 Level A13
    7Certain ARIA roles must be contained by particular parentsaria-required-parentWCAG 2.0 Level A13
    8ARIA roles used must conform to valid valuesaria-rolesWCAG 2.0 Level A13
    9ARIA attributes must conform to valid valuesaria-valid-attr-valueWCAG 2.0 Level A10
    10ARIA attributes must conform to valid namesaria-valid-attrWCAG 2.0 Level A10
    11autocomplete attribute must be used correctlyautocomplete-validWCAG 2.1 Level AA3
    12Inline text spacing must be adjustable with custom stylesheetsavoid-inline-spacingWCAG 2.1 Level AA8
    13Buttons must have discernible textbutton-nameWCAG 2.0 Level A12
    14Page must have means to bypass repeated blocksbypassWCAG 2.0 Level A1
    15Documents must have <title> element to aid in navigationdocument-titleWCAG 2.0 Level A1
    16IDs used in ARIA and labels must be uniqueduplicate-id-ariaWCAG 2.0 Level A7
    17id attribute value must be uniqueduplicate-idWCAG 2.0 Level A20
    18Headings must not be emptyempty-headingBest practice6
    19Form field should not have multiple label elementsform-field-multiple-labelsWCAG 2.0 Level A17
    20Heading levels should only increase by oneheading-orderBest practice6
    21Hidden content on the page cannot be analyzedhidden-contentBest practice434
    22<html> element must have a lang attributehtml-has-langWCAG 2.0 Level A1
    23<html> element must have a valid value for the lang attributehtml-lang-validWCAG 2.0 Level A1
    24Elements must have their visible text as part of their accessible namelabel-content-name-mismatchWCAG 2.1 Level A1
    25Form elements should have a visible labellabel-title-onlyBest practice17
    26Form elements must have labelslabelWCAG 2.0 Level A12
    27Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A1
    28Links must have discernible textlink-nameWCAG 2.0 Level A5
    29<ul> and <ol> must only directly contain <li>, <script> or <template> elementslistWCAG 2.0 Level A1
    30<li> elements must be contained in a <ul> or <ol>listitemWCAG 2.0 Level A3
    31Users should be able to zoom and scale the text up to 500%meta-viewport-largeBest practice1
    32Zooming and scaling must not be disabledmeta-viewportBest practice1
    33Page must contain a level-one headingpage-has-heading-oneBest practice1
    34All page content must be contained by landmarksregionBest practice280
    35Elements should not have tabindex greater than zerotabindexBest practice5
    36The <caption> element should not contain the same text as the summary attributetable-duplicate-nameBest practice1
    37Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A1
    38All cells in a table element that use the headers attribute must only refer to other cells of that same tabletd-headers-attrWCAG 2.0 Level A1
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'incomplete' axe checks means?

    +

    + Incomplete 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. +

    +

    + Visit axe API Documentation + to learn more. +

    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'inapplicable' axe checks means?

    +

    + The inapplicable array lists all the rules for which no matching + elements were found on the page. +

    +

    + Visit axe API Documentation + to learn more. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAG
    1accesskey attribute value must be uniqueaccesskeysBest practice
    2Active <area> elements must have alternate textarea-altWCAG 2.0 Level A
    3ARIA input fields must have an accessible namearia-input-field-nameWCAG 2.0 Level A
    4Use aria-roledescription on elements with a semantic rolearia-roledescriptionWCAG 2.0 Level A
    5ARIA toggle fields have an accessible namearia-toggle-field-nameWCAG 2.0 Level A
    6<audio> elements must have a captions trackaudio-captionWCAG 2.0 Level A
    7<blink> elements are deprecated and must not be usedblinkWCAG 2.0 Level A
    8<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elementsdefinition-listWCAG 2.0 Level A
    9<dt> and <dd> elements must be contained by a <dl>dlitemWCAG 2.0 Level A
    10Elements in the focus order need a role appropriate for interactive contentfocus-order-semanticsBest practice
    11HTML elements with lang and xml:lang must have the same base languagehtml-xml-lang-mismatchWCAG 2.0 Level A
    12Image buttons must have alternate textinput-image-altWCAG 2.0 Level A
    13Elements must have their visible text as part of their accessible namelabel-content-name-mismatchWCAG 2.1 Level A
    14Banner landmark must not be contained in another landmarklandmark-banner-is-top-levelBest practice
    15Aside must not be contained in another landmarklandmark-complementary-is-top-levelBest practice
    16Contentinfo landmark must not be contained in another landmarklandmark-contentinfo-is-top-levelBest practice
    17Main landmark must not be contained in another landmarklandmark-main-is-top-levelBest practice
    18Document must not have more than one banner landmarklandmark-no-duplicate-bannerBest practice
    19Document must not have more than one contentinfo landmarklandmark-no-duplicate-contentinfoBest practice
    20Document must not have more than one main landmarklandmark-no-duplicate-mainBest practice
    21<marquee> elements are deprecated and must not be usedmarqueeWCAG 2.0 Level A
    22Timed refresh must not existmeta-refreshWCAG 2.0 Level A
    23<object> elements must have alternate textobject-altWCAG 2.0 Level A
    24Bold, italic text and font-size are not used to style p elements as a headingp-as-headingWCAG 2.0 Level A
    25[role='img'] elements have an alternative textrole-img-altWCAG 2.0 Level A
    26scope attribute should be used correctlyscope-attr-validBest practice
    27Ensure that scrollable region has keyboard accessscrollable-region-focusableWCAG 2.0 Level A
    28Server-side image maps must not be usedserver-side-image-mapWCAG 2.0 Level A
    29The skip-link target should exist and be focusableskip-linkBest practice
    30svg elements with an img role have an alternative textsvg-img-altWCAG 2.0 Level A
    31Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A
    32All non-empty td element in table larger than 3 by 3 must have an associated table headertd-has-headerWCAG 2.0 Level A
    33All th elements and elements with role=columnheader/rowheader must have data cells they describeth-has-data-cellsWCAG 2.0 Level A
    34lang attribute must have a valid valuevalid-langWCAG 2.0 Level AA
    35<video> or <audio> elements do not autoplay audiono-autoplay-audioWCAG 2.0 Level A
    +
    +
    +
    +
    +
    + + +" +`; + +exports[`createHtmlReport() test AxeResults passed 1`] = ` +" + + + + + + + + + + + + + AXE Accessibility Results + + +
    +

    + AXE Accessibility Results for DEQUE project +

    +
    + Page URL: + http://example.com/ +
    + Test Case: Full page analysis +
    Steps:
    +
      +
    1. Open https://dequeuniversity.com/demo/mars/
    2. +
    3. Analyze full page with all rules enabled
    4. +
    +
    +
    +
    axe-core found 6 violations
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGImpactCount
    1<html> element must have a lang attributehtml-has-langWCAG 2.0 Level Aserious1
    2Document must have one main landmarklandmark-one-mainBest practicemoderate1
    3All page content must be contained by landmarksregionBest practicemoderate1
    4Elements should not have tabindex greater than zerotabindexBest practiceserious3
    +

    Failed

    +
    +
    +
    +
    <html> element must have a lang attribute
    + Learn more +
    +
    +
    html-has-lang
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every HTML document has a lang attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html>"html"
    +
    +
    +
    +
    +
    +
    +
    Document must have one main landmark
    + Learn more +
    +
    +
    landmark-one-main
    +
    + Best practice +
    +
    +
    +

    Ensures the document has a main landmark

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html>"html"
    +
    +
    +
    +
    +
    +
    +
    All page content must be contained by landmarks
    + Learn more +
    +
    +
    region
    +
    + Best practice +
    +
    +
    +

    Ensures all page content is contained by landmarks

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div> + <h1>Example Domain</h1> + <p>This domain is for use in illustrative examples in documents. You may use this + domain in literature without prior coordination or asking for permission.</p> + <p><a href="https://www.iana.org/domains/example">More information...</a></p> +</div>"div"
    +
    +
    +
    +
    +
    +
    +
    Elements should not have tabindex greater than zero
    + Learn more +
    +
    +
    tabindex
    +
    + Best practice +
    +
    +
    +

    Ensures tabindex attribute values are not greater than 0

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="from0" name="from0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#from0"
    2<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="to0" name="to0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#to0"
    3<input size="10" id="deptDate0" name="deptDate0" placeholder="mm/dd/yyyy" value="" tabindex="3" class="hasDatepicker input-dept">"#deptDate0"
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGNodes passed check
    1aria-hidden='true' must not be present on the document bodyaria-hidden-bodyWCAG 2.0 Level A1
    2Page must have means to bypass repeated blocksbypassWCAG 2.0 Level A1
    3Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AA3
    4Documents must have <title> element to aid in navigationdocument-titleWCAG 2.0 Level A1
    5Headings must not be emptyempty-headingBest practice1
    6Heading levels should only increase by oneheading-orderBest practice1
    7Hidden content on the page cannot be analyzedhidden-contentBest practice14
    8Links must have discernible textlink-nameWCAG 2.0 Level A1
    9Users should be able to zoom and scale the text up to 500%meta-viewport-largeBest practice1
    10Zooming and scaling must not be disabledmeta-viewportBest practice1
    11Page must contain a level-one headingpage-has-heading-oneBest practice1
    12All page content must be contained by landmarksregionBest practice4
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'incomplete' axe checks means?

    +

    + Incomplete 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. +

    +

    + Visit axe API Documentation + to learn more. +

    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'inapplicable' axe checks means?

    +

    + The inapplicable array lists all the rules for which no matching + elements were found on the page. +

    +

    + Visit axe API Documentation + to learn more. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAG
    1accesskey attribute value must be uniqueaccesskeysBest practice
    2Active <area> elements must have alternate textarea-altWCAG 2.0 Level A
    3Elements must only use allowed ARIA attributesaria-allowed-attrWCAG 2.0 Level A
    4ARIA role must be appropriate for the elementaria-allowed-roleBest practice
    5ARIA hidden element must not contain focusable elementsaria-hidden-focusWCAG 2.0 Level A
    6ARIA input fields must have an accessible namearia-input-field-nameWCAG 2.0 Level A
    7Required ARIA attributes must be providedaria-required-attrWCAG 2.0 Level A
    8Certain ARIA roles must contain particular childrenaria-required-childrenWCAG 2.0 Level A
    9Certain ARIA roles must be contained by particular parentsaria-required-parentWCAG 2.0 Level A
    10Use aria-roledescription on elements with a semantic rolearia-roledescriptionWCAG 2.0 Level A
    11ARIA roles used must conform to valid valuesaria-rolesWCAG 2.0 Level A
    12ARIA toggle fields have an accessible namearia-toggle-field-nameWCAG 2.0 Level A
    13ARIA attributes must conform to valid valuesaria-valid-attr-valueWCAG 2.0 Level A
    14ARIA attributes must conform to valid namesaria-valid-attrWCAG 2.0 Level A
    15<audio> elements must have a captions trackaudio-captionWCAG 2.0 Level A
    16autocomplete attribute must be used correctlyautocomplete-validWCAG 2.1 Level AA
    17Inline text spacing must be adjustable with custom stylesheetsavoid-inline-spacingWCAG 2.1 Level AA
    18<blink> elements are deprecated and must not be usedblinkWCAG 2.0 Level A
    19Buttons must have discernible textbutton-nameWCAG 2.0 Level A
    20<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elementsdefinition-listWCAG 2.0 Level A
    21<dt> and <dd> elements must be contained by a <dl>dlitemWCAG 2.0 Level A
    22IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level A
    23IDs used in ARIA and labels must be uniqueduplicate-id-ariaWCAG 2.0 Level A
    24id attribute value must be uniqueduplicate-idWCAG 2.0 Level A
    25Elements in the focus order need a role appropriate for interactive contentfocus-order-semanticsBest practice
    26Form field should not have multiple label elementsform-field-multiple-labelsWCAG 2.0 Level A
    27Frames must be tested with axe-coreframe-testedBest practice
    28Frames must have a unique title attributeframe-title-uniqueBest practice
    29Frames must have title attributeframe-titleWCAG 2.0 Level A
    30<html> element must have a valid value for the lang attributehtml-lang-validWCAG 2.0 Level A
    31HTML elements with lang and xml:lang must have the same base languagehtml-xml-lang-mismatchWCAG 2.0 Level A
    32Images must have alternate textimage-altWCAG 2.0 Level A
    33Alternative text of images should not be repeated as textimage-redundant-altBest practice
    34Input buttons must have discernible textinput-button-nameWCAG 2.0 Level A
    35Image buttons must have alternate textinput-image-altWCAG 2.0 Level A
    36Elements must have their visible text as part of their accessible namelabel-content-name-mismatchWCAG 2.1 Level A
    37Form elements should have a visible labellabel-title-onlyBest practice
    38Form elements must have labelslabelWCAG 2.0 Level A
    39Banner landmark must not be contained in another landmarklandmark-banner-is-top-levelBest practice
    40Aside must not be contained in another landmarklandmark-complementary-is-top-levelBest practice
    41Contentinfo landmark must not be contained in another landmarklandmark-contentinfo-is-top-levelBest practice
    42Main landmark must not be contained in another landmarklandmark-main-is-top-levelBest practice
    43Document must not have more than one banner landmarklandmark-no-duplicate-bannerBest practice
    44Document must not have more than one contentinfo landmarklandmark-no-duplicate-contentinfoBest practice
    45Document must not have more than one main landmarklandmark-no-duplicate-mainBest practice
    46Ensures landmarks are uniquelandmark-uniqueBest practice
    47Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A
    48<ul> and <ol> must only directly contain <li>, <script> or <template> elementslistWCAG 2.0 Level A
    49<li> elements must be contained in a <ul> or <ol>listitemWCAG 2.0 Level A
    50<marquee> elements are deprecated and must not be usedmarqueeWCAG 2.0 Level A
    51Timed refresh must not existmeta-refreshWCAG 2.0 Level A
    52<object> elements must have alternate textobject-altWCAG 2.0 Level A
    53Bold, italic text and font-size are not used to style p elements as a headingp-as-headingWCAG 2.0 Level A
    54[role='img'] elements have an alternative textrole-img-altWCAG 2.0 Level A
    55scope attribute should be used correctlyscope-attr-validBest practice
    56Ensure that scrollable region has keyboard accessscrollable-region-focusableWCAG 2.0 Level A
    57Server-side image maps must not be usedserver-side-image-mapWCAG 2.0 Level A
    58The skip-link target should exist and be focusableskip-linkBest practice
    59svg elements with an img role have an alternative textsvg-img-altWCAG 2.0 Level A
    60Elements should not have tabindex greater than zerotabindexBest practice
    61The <caption> element should not contain the same text as the summary attributetable-duplicate-nameBest practice
    62Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A
    63All non-empty td element in table larger than 3 by 3 must have an associated table headertd-has-headerWCAG 2.0 Level A
    64All cells in a table element that use the headers attribute must only refer to other cells of that same tabletd-headers-attrWCAG 2.0 Level A
    65All th elements and elements with role=columnheader/rowheader must have data cells they describeth-has-data-cellsWCAG 2.0 Level A
    66lang attribute must have a valid valuevalid-langWCAG 2.0 Level AA
    67<video> elements must have captionsvideo-captionWCAG 2.0 Level A
    68<video> or <audio> elements do not autoplay audiono-autoplay-audioWCAG 2.0 Level A
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Rule IDEnabled
    1object-alttrue
    2role-img-alttrue
    3input-image-alttrue
    4image-alttrue
    5svg-img-alttrue
    6area-alttrue
    7audio-captiontrue
    8video-captiontrue
    9definition-listtrue
    10dlitemtrue
    11listitemtrue
    12listtrue
    13th-has-data-cellstrue
    14td-headers-attrtrue
    15td-has-headertrue
    16p-as-headingtrue
    17aria-required-parenttrue
    18aria-required-childrentrue
    19table-fake-captiontrue
    20css-orientation-lockfalse
    21autocomplete-validtrue
    22link-in-text-blocktrue
    23no-autoplay-audiotrue
    24color-contrasttrue
    25meta-viewporttrue
    26avoid-inline-spacingtrue
    27server-side-image-maptrue
    28meta-refreshtrue
    29blinktrue
    30marqueetrue
    31bypasstrue
    32frame-titletrue
    33document-titletrue
    34scrollable-region-focusabletrue
    35identical-links-same-purposefalse
    36label-content-name-mismatchtrue
    37html-has-langtrue
    38html-lang-validtrue
    39html-xml-lang-mismatchtrue
    40valid-langtrue
    41form-field-multiple-labelstrue
    42duplicate-id-activetrue
    43duplicate-idtrue
    44duplicate-id-ariatrue
    45aria-valid-attrtrue
    46aria-valid-attr-valuetrue
    47aria-input-field-nametrue
    48aria-rolestrue
    49aria-toggle-field-nametrue
    50aria-hidden-focustrue
    51aria-hidden-bodytrue
    52button-nametrue
    53aria-allowed-attrtrue
    54input-button-nametrue
    55aria-required-attrtrue
    56aria-roledescriptiontrue
    57link-nametrue
    58labeltrue
    59accesskeystrue
    60regiontrue
    61aria-allowed-roletrue
    62landmark-banner-is-top-leveltrue
    63landmark-complementary-is-top-leveltrue
    64landmark-contentinfo-is-top-leveltrue
    65focus-order-semanticstrue
    66tabindextrue
    67landmark-no-duplicate-maintrue
    68label-title-onlytrue
    69frame-testedtrue
    70frame-title-uniquetrue
    71heading-ordertrue
    72empty-headingtrue
    73hidden-contenttrue
    74landmark-uniquetrue
    75landmark-main-is-top-leveltrue
    76page-has-heading-onetrue
    77landmark-one-maintrue
    78landmark-no-duplicate-bannertrue
    79landmark-no-duplicate-contentinfotrue
    80scope-attr-validtrue
    81image-redundant-alttrue
    82table-duplicate-nametrue
    83skip-linktrue
    84meta-viewport-largetrue
    +
    +
    +
    +
    +
    + + +" +`; + +exports[`createHtmlReport() test URL is not passed 1`] = ` +" + + + + + + + + + + + + + AXE Accessibility Results + + +
    +

    + AXE Accessibility Results +

    +
    axe-core found 85 violations
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGImpactCount
    1Buttons must have discernible textbutton-nameWCAG 2.0 Level Acritical1
    2Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AAserious11
    3IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level Aserious1
    4id attribute value must be uniqueduplicate-idWCAG 2.0 Level Aminor10
    5Frames must have title attributeframe-titleWCAG 2.0 Level Aserious2
    6<html> element must have a lang attributehtml-has-langWCAG 2.0 Level Aserious1
    7Images must have alternate textimage-altWCAG 2.0 Level Acritical4
    8Form elements must have labelslabelWCAG 2.0 Level Acritical1
    9Document must have one main landmarklandmark-one-mainBest practicemoderate4
    10Ensures landmarks are uniquelandmark-uniqueBest practicemoderate1
    11Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level Aserious1
    12Links must have discernible textlink-nameWCAG 2.0 Level Aserious8
    13All page content must be contained by landmarksregionBest practicemoderate37
    14Elements should not have tabindex greater than zerotabindexBest practiceserious3
    +

    Failed

    +
    +
    +
    +
    Buttons must have discernible text
    + Learn more +
    +
    +
    button-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures buttons have discernible text

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<button class="ui-datepicker-trigger" type="button"> +<!-- <img title="..." alt="..." src="/redesign/assets/demo-sites/mars/images/calendar.png"> --> +</button>".departure-date > .ui-datepicker-trigger:nth-child(4)"
    +
    +
    +
    +
    +
    +
    +
    Elements must have sufficient color contrast
    + Learn more +
    +
    +
    color-contrast
    +
    + WCAG 2.0 Level AA +
    +
    +
    +

    Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<h3>Be Bold...</h3>":root > h3"
    2<p>Step out of your comfort zone, and into a rocket with enough fuel to blast a Manhattan-sized crater if it explodes. But it won't. Probably.<br> +&nbsp; </p>"#vap-plan > p:nth-child(3)"
    3<h3>Countdown...</h3>":root > h3"
    4<p>If you're serious about traveling to Mars - really serious - then <a href="mars2.html?a=last_will">prepare your last will and testament</a>, and book a trip! </p>"#vap-book > p:nth-child(3)"
    5<h3>Blast Off!</h3>":root > h3"
    6<p>Expect violent turbulence, bone-crushing g-forces, muscle atrophy, and certain death (hey, everyone's death is certain at some point, right?).<br> +&nbsp; </p>"#vap-travel > p:nth-child(3)"
    7<a class="" href="mars2.html?a=crater_adventure">10% off Crater Adventure</a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    8<a class="" href="mars2.html?a=ice_cream">Free Astronaut Ice Cream</a>":root > a[href="mars2\\\\.html\\\\?a\\\\=ice_cream"]"
    9<p>Spend an extra 3 months in orbit around Mars in our newly-remodelled MarsPod and get a free package of freeze-wrapped dehydrated astronaut ice cream. <a class="link-arrow" href="mars2.html?a=ice_cream">Get your free dehydrated ice cream!</a> +</p>"li:nth-child(2) > .deal-text > p"
    10<a class="link" href="mars2.html?a=low_price_guarantee">Lowest Price Guarantee</a>"li:nth-child(3) > .deal-text > h3 > .link"
    11<a href="mars2.html?a=free_year">Book a free year on Mars</a>":root > a[href="mars2\\\\.html\\\\?a\\\\=free_year"]"
    +
    +
    +
    +
    +
    +
    +
    IDs of active elements must be unique
    + Learn more +
    +
    +
    duplicate-id-active
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every id attribute value of active elements is unique

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    +
    +
    +
    +
    +
    +
    +
    id attribute value must be unique
    + Learn more +
    +
    +
    duplicate-id
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every id attribute value is unique

    +
    + minor +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div id="control-panel" class="container-fluid-full">".loginnow > .container-fluid-full"
    2<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    3<div id="search-bar" class="pull-left"> +<form id="search" action="/demo/mars/mars2" method="get"> +<input type="hidden" name="fn" value="Search"> +<input type="text" class="search" name="query" placeholder="search"> +<input type="submit" class="control-search"> +</form> +</div>".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(2)"
    4<form id="search" action="/demo/mars/mars2" method="get"> +<input type="hidden" name="fn" value="Search"> +<input type="text" class="search" name="query" placeholder="search"> +<input type="submit" class="control-search"> +</form>":root > form[method="get"][action="\\\\/demo\\\\/mars\\\\/mars2"]"
    5<nav id="right-control-nav" class="pull-right" style="display: inline;">".loginnow > .container-fluid-full > .container > .span7.pull-right > .pull-right"
    6<div id="vap-section"> +<h1 style="color:#eee;">Destination Mars </h1> +<h2 style="color:#acbad0;">A trip to Mars starts in your imagination. Are you bold enough, brave enough, <strong>foolish enough?</strong> We are. You belong on Mars with fools like us. Most of us don't bite. Much.</h2></div>"#left-column > div:nth-child(1)"
    7<input type="hidden" id="nCountries" name="nCountries">"#select-country > input[name="nCountries"][type="hidden"]"
    8<div id="passenger-select" class="widget-container middle">".middle.widget-container:nth-child(13)"
    9<div id="passengers">".middle.widget-container:nth-child(13) > .interior-container > div:nth-child(3)"
    10<div id="ui-datepicker-div" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>".ui-datepicker.ui-helper-clearfix.ui-corner-all:nth-child(33)"
    +
    +
    +
    +
    +
    +
    +
    Frames must have title attribute
    + Learn more +
    +
    +
    frame-title
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures <iframe> and <frame> elements contain a non-empty title attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<iframe width="365" height="205" name="player" id="player" src="https://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>"#player"
    2<iframe id="fafbba78" name="f2bc5e72d" scrolling="no" style="border: none; overflow: hidden; height: 62px; width: 292px;" class="fb_ltr" src="/assets/demo-sites/mars/js/likebox.html"></iframe>"#fafbba78"
    +
    +
    +
    +
    +
    +
    +
    <html> element must have a lang attribute
    + Learn more +
    +
    +
    html-has-lang
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every HTML document has a lang attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    +
    +
    +
    +
    +
    +
    +
    Images must have alternate text
    + Learn more +
    +
    +
    image-alt
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures <img> elements have alternate text or a role of none or presentation

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<img src="/assets/demo-sites/mars/js/seg" width="1" height="1">"img[src$="seg"]"
    2<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\\\\32 10"][height="\\\\31 20"]"
    3<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\\\\32 10"][height="\\\\31 20"]"
    4<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\\\\32 10"][height="\\\\31 20"]"
    +
    +
    +
    +
    +
    +
    +
    Form elements must have labels
    + Learn more +
    +
    +
    label
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every form element has a label

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    +
    +
    +
    +
    +
    +
    +
    Document must have one main landmark
    + Learn more +
    +
    +
    landmark-one-main
    +
    + Best practice +
    +
    +
    +

    Ensures the document has a main landmark

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    2<html lang="en" dir="ltr" data-cast-api-enabled="true">"#player", "html"
    3<html lang="en" id="facebook" class="">"#fafbba78", "#facebook"
    4<html lang="en" class=" xl en">".twitter-follow-button", "html"
    +
    +
    +
    +
    +
    +
    +
    Ensures landmarks are unique
    + Learn more +
    +
    +
    landmark-unique
    +
    + Best practice +
    +
    +
    +

    Landmarks must have a unique role or role/label/title (i.e. accessible name) combination

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    +
    +
    +
    +
    +
    +
    +
    Links must be distinguished from surrounding text in a way that does not rely on color
    + Learn more +
    +
    +
    link-in-text-block
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Links can be distinguished without relying on color

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a href="mars2.html?a=last_will">prepare your last will and testament</a>"a[href="mars2\\\\.html\\\\?a\\\\=last_will"]"
    +
    +
    +
    +
    +
    +
    +
    Links must have discernible text
    + Learn more +
    +
    +
    link-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures links have discernible text

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a class="link" href="demo/mars/#"><i class="icon-menu-home"></i> </a>".link[href$="mars\\\\/\\\\#"]"
    2<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    3<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    4<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    5<a href="mars2.html?a="></a>":root > a[href="mars2\\\\.html\\\\?a\\\\="]"
    6<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    7<a target="player" data-text="Why Mars died" class="fader first" href="http://www.youtube.com/embed/oC31pqk9sak?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="Why\\\\ Mars\\\\ died"]"
    8<a target="player" data-text="The world that never was" class="fader first" href="http://www.youtube.com/embed/JgMXPXdqJn8?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="The\\\\ world\\\\ that\\\\ never\\\\ was"]"
    +
    +
    +
    +
    +
    +
    +
    All page content must be contained by landmarks
    + Learn more +
    +
    +
    region
    +
    + Best practice +
    +
    +
    +

    Ensures all page content is contained by landmarks

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div style="width: 1px; height: 1px; display: inline;">"body > div:nth-child(1)"
    2<div id="purposeDisclaimer">This web page is for demonstration purposes, to show common accessibility errors.</div>"#purposeDisclaimer"
    3<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    4<input type="submit" class="control-search">":root > .control-search[type="submit"]"
    5<div class="span7 left-first pull-left" id="left-column">"#left-column"
    6<div id="widget-controls" class="widget-container head">"#widget-controls"
    7<h3>Book your Trip</h3>"#route-select > .interior-container > h3"
    8<div id="route-type-radio-group" class="">"#route-type-radio-group"
    9<div id="route-type">"#route-type"
    10<div id="pass-question-radio-group" class="">"#pass-question-radio-group"
    11<h3>Who Is Traveling?</h3>".middle.widget-container:nth-child(13) > .interior-container > h3"
    12<span class="wrapper"> +<span class="traveler-label">Traveler</span> +</span>"#passenger0 > .wrapper:nth-child(1)"
    13<span class="wrapper age-range"> +<select id="traveler0" class="traveler-type"> +<option value="0">Adult (26+)</option> +<option value="1">Youth (12-25)</option> +<option value="2">Child (4-11)</option> +<option value="3">Senior (60+)</option> +</select> +</span>"#passenger0 > .age-range.wrapper"
    14<div class="add-buttons" id="add-traveler">"#add-traveler"
    15<div id="booking-box-submit" class="widget-container footer">"#booking-box-submit"
    16<div class="interior-container">"#video-box > .interior-container"
    17<div id="social-bar" class="container-fluid-full">"#social-bar"
    18<h4>Book Your Trip</h4>"#footer-book > h4"
    19<ul>"#footer-book > ul"
    20<h4>Mars Shuttles</h4>"#footer-trains > h4"
    21<ul>"#footer-trains > ul"
    22<h4>Mars Tourist Passes</h4>"#footer-passes > h4"
    23<ul>"#footer-passes > ul"
    24<h4>Mars Adventures</h4>"#footer-plan > h4"
    25<ul>"#footer-plan > ul"
    26<h4>FAQs</h4>"#footer-faq > h4"
    27<ul>"#footer-faq > ul"
    28<h4>Connect With Us</h4>"#footer-connect > h4"
    29<ul>"#footer-connect > ul"
    30<div id="copyright" class="container">"#copyright"
    31<div id="player" style="width: 100%; height: 100%;">"#player", "#player"
    32<tr><td><span class="fsl fwb"><a href="../mars2.html" target="_blank">Mars Commuter Express</a></span></td></tr>"#fafbba78", "._8m > table > tbody > tr:nth-child(1)"
    33<div class="pluginButton pluginConnectButtonDisconnected" title=""><div><button type="submit"><i class="pluginButtonIcon img sp_like sx_like_thumb"></i>Like</button></div></div>"#fafbba78", ".pluginConnectButtonDisconnected"
    34<span id="u_0_2">378,121</span>"#fafbba78", "#u_0_2"
    35<div class="btn-o" contextmenu="menu"><a id="follow-button" target="_blank" class="btn" title="Follow MarsCommuter on Twitter" href="mars2.html"><i></i><span class="label" id="l">Follow @MarsTrip1</span></a></div>".twitter-follow-button", ".btn-o"
    36<img src="../images/f.gif" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src="\\\\.\\\\.\\\\/images\\\\/f\\\\.gif"]"
    37<img src="jot" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src$="jot"]"
    +
    +
    +
    +
    +
    +
    +
    Elements should not have tabindex greater than zero
    + Learn more +
    +
    +
    tabindex
    +
    + Best practice +
    +
    +
    +

    Ensures tabindex attribute values are not greater than 0

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="from0" name="from0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#from0"
    2<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="to0" name="to0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#to0"
    3<input size="10" id="deptDate0" name="deptDate0" placeholder="mm/dd/yyyy" value="" tabindex="3" class="hasDatepicker input-dept">"#deptDate0"
    +
    +
    +
    +
    + + +" +`; + +exports[`createHtmlReport() test Verify report is created only with violations because passes and incomplete are not passed 1`] = ` +" + + + + + + + + + + + + + AXE Accessibility Results + + +
    +

    + AXE Accessibility Results +

    +
    + Page URL: + https://dequeuniversity.com/demo/mars/ + + +
    +
    axe-core found 85 violations
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGImpactCount
    1Buttons must have discernible textbutton-nameWCAG 2.0 Level Acritical1
    2Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AAserious11
    3IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level Aserious1
    4id attribute value must be uniqueduplicate-idWCAG 2.0 Level Aminor10
    5Frames must have title attributeframe-titleWCAG 2.0 Level Aserious2
    6<html> element must have a lang attributehtml-has-langWCAG 2.0 Level Aserious1
    7Images must have alternate textimage-altWCAG 2.0 Level Acritical4
    8Form elements must have labelslabelWCAG 2.0 Level Acritical1
    9Document must have one main landmarklandmark-one-mainBest practicemoderate4
    10Ensures landmarks are uniquelandmark-uniqueBest practicemoderate1
    11Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level Aserious1
    12Links must have discernible textlink-nameWCAG 2.0 Level Aserious8
    13All page content must be contained by landmarksregionBest practicemoderate37
    14Elements should not have tabindex greater than zerotabindexBest practiceserious3
    +

    Failed

    +
    +
    +
    +
    Buttons must have discernible text
    + Learn more +
    +
    +
    button-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures buttons have discernible text

    +
    + critical +
    +
    +
    + + + + + + + + + + + @@ -2458,7 +5874,6 @@ exports[`createHtmlReport() test Verify report is created with violations and cu -
    axe-core found 85 violations
    #Source CodeSelector
    1 <button class="ui-datepicker-trigger" type="button"> <!-- <img title="..." alt="..." src="/redesign/assets/demo-sites/mars/images/calendar.png"> --> </button>
    @@ -3647,7 +7062,6 @@ exports[`createHtmlReport() test Verify report is created with violations and pa -
    axe-core found 85 violations
    @@ -5180,7 +8594,6 @@ exports[`createHtmlReport() test Verify report is created with violations, passe -
    axe-core found 85 violations
    @@ -6797,7 +10210,6 @@ exports[`createHtmlReport() test Verify report is created with violations, passe -
    axe-core found 85 violations
    @@ -8414,7 +11826,6 @@ exports[`createHtmlReport() test Verify report with no violations, no passes, no -
    axe-core found 0 violations
    @@ -8599,7 +12010,6 @@ exports[`createHtmlReport() test Verify report with no violations, passes and in -
    axe-core found 0 violations
    @@ -8948,169 +12358,1278 @@ exports[`createHtmlReport() test Verify report with no violations, passes and in -
    -
    -
    -
    - -
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'incomplete' axe checks means?

    +

    + Incomplete 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. +

    +

    + Visit axe API Documentation + to learn more. +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGNodes with incomplete check
    1Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AA132
    2Hidden content on the page cannot be analyzedhidden-contentBest practice60
    3Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A22
    4<video> elements must have captionsvideo-captionWCAG 2.0 Level A1
    +
    +
    +
    +
    +
    + + +" +`; + +exports[`createHtmlReport() test Verify report with no violations, passes and incomplete with optional reportFileName, url and project key params 2`] = ` +" + + + + + + + + + + + + + AXE Accessibility Results + + +
    +

    + AXE Accessibility Results +

    +
    + Page URL: + https://dequeuniversity.com/demo/mars/ + + +
    +
    axe-core found 85 violations
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAGImpactCount
    1Buttons must have discernible textbutton-nameWCAG 2.0 Level Acritical1
    2Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AAserious11
    3IDs of active elements must be uniqueduplicate-id-activeWCAG 2.0 Level Aserious1
    4id attribute value must be uniqueduplicate-idWCAG 2.0 Level Aminor10
    5Frames must have title attributeframe-titleWCAG 2.0 Level Aserious2
    6<html> element must have a lang attributehtml-has-langWCAG 2.0 Level Aserious1
    7Images must have alternate textimage-altWCAG 2.0 Level Acritical4
    8Form elements must have labelslabelWCAG 2.0 Level Acritical1
    9Document must have one main landmarklandmark-one-mainBest practicemoderate4
    10Ensures landmarks are uniquelandmark-uniqueBest practicemoderate1
    11Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level Aserious1
    12Links must have discernible textlink-nameWCAG 2.0 Level Aserious8
    13All page content must be contained by landmarksregionBest practicemoderate37
    14Elements should not have tabindex greater than zerotabindexBest practiceserious3
    +

    Failed

    +
    +
    +
    +
    Buttons must have discernible text
    + Learn more +
    +
    +
    button-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures buttons have discernible text

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<button class="ui-datepicker-trigger" type="button"> +<!-- <img title="..." alt="..." src="/redesign/assets/demo-sites/mars/images/calendar.png"> --> +</button>".departure-date > .ui-datepicker-trigger:nth-child(4)"
    +
    +
    +
    +
    +
    +
    +
    Elements must have sufficient color contrast
    + Learn more +
    +
    +
    color-contrast
    +
    + WCAG 2.0 Level AA +
    +
    +
    +

    Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<h3>Be Bold...</h3>":root > h3"
    2<p>Step out of your comfort zone, and into a rocket with enough fuel to blast a Manhattan-sized crater if it explodes. But it won't. Probably.<br> +&nbsp; </p>"#vap-plan > p:nth-child(3)"
    3<h3>Countdown...</h3>":root > h3"
    4<p>If you're serious about traveling to Mars - really serious - then <a href="mars2.html?a=last_will">prepare your last will and testament</a>, and book a trip! </p>"#vap-book > p:nth-child(3)"
    5<h3>Blast Off!</h3>":root > h3"
    6<p>Expect violent turbulence, bone-crushing g-forces, muscle atrophy, and certain death (hey, everyone's death is certain at some point, right?).<br> +&nbsp; </p>"#vap-travel > p:nth-child(3)"
    7<a class="" href="mars2.html?a=crater_adventure">10% off Crater Adventure</a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    8<a class="" href="mars2.html?a=ice_cream">Free Astronaut Ice Cream</a>":root > a[href="mars2\\\\.html\\\\?a\\\\=ice_cream"]"
    9<p>Spend an extra 3 months in orbit around Mars in our newly-remodelled MarsPod and get a free package of freeze-wrapped dehydrated astronaut ice cream. <a class="link-arrow" href="mars2.html?a=ice_cream">Get your free dehydrated ice cream!</a> +</p>"li:nth-child(2) > .deal-text > p"
    10<a class="link" href="mars2.html?a=low_price_guarantee">Lowest Price Guarantee</a>"li:nth-child(3) > .deal-text > h3 > .link"
    11<a href="mars2.html?a=free_year">Book a free year on Mars</a>":root > a[href="mars2\\\\.html\\\\?a\\\\=free_year"]"
    +
    +
    +
    +
    +
    +
    +
    IDs of active elements must be unique
    + Learn more +
    +
    +
    duplicate-id-active
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every id attribute value of active elements is unique

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    +
    +
    +
    +
    +
    +
    +
    id attribute value must be unique
    + Learn more +
    +
    +
    duplicate-id
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every id attribute value is unique

    +
    + minor +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div id="control-panel" class="container-fluid-full">".loginnow > .container-fluid-full"
    2<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    3<div id="search-bar" class="pull-left"> +<form id="search" action="/demo/mars/mars2" method="get"> +<input type="hidden" name="fn" value="Search"> +<input type="text" class="search" name="query" placeholder="search"> +<input type="submit" class="control-search"> +</form> +</div>".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(2)"
    4<form id="search" action="/demo/mars/mars2" method="get"> +<input type="hidden" name="fn" value="Search"> +<input type="text" class="search" name="query" placeholder="search"> +<input type="submit" class="control-search"> +</form>":root > form[method="get"][action="\\\\/demo\\\\/mars\\\\/mars2"]"
    5<nav id="right-control-nav" class="pull-right" style="display: inline;">".loginnow > .container-fluid-full > .container > .span7.pull-right > .pull-right"
    6<div id="vap-section"> +<h1 style="color:#eee;">Destination Mars </h1> +<h2 style="color:#acbad0;">A trip to Mars starts in your imagination. Are you bold enough, brave enough, <strong>foolish enough?</strong> We are. You belong on Mars with fools like us. Most of us don't bite. Much.</h2></div>"#left-column > div:nth-child(1)"
    7<input type="hidden" id="nCountries" name="nCountries">"#select-country > input[name="nCountries"][type="hidden"]"
    8<div id="passenger-select" class="widget-container middle">".middle.widget-container:nth-child(13)"
    9<div id="passengers">".middle.widget-container:nth-child(13) > .interior-container > div:nth-child(3)"
    10<div id="ui-datepicker-div" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>".ui-datepicker.ui-helper-clearfix.ui-corner-all:nth-child(33)"
    +
    +
    +
    +
    +
    +
    +
    Frames must have title attribute
    + Learn more +
    +
    +
    frame-title
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures <iframe> and <frame> elements contain a non-empty title attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<iframe width="365" height="205" name="player" id="player" src="https://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>"#player"
    2<iframe id="fafbba78" name="f2bc5e72d" scrolling="no" style="border: none; overflow: hidden; height: 62px; width: 292px;" class="fb_ltr" src="/assets/demo-sites/mars/js/likebox.html"></iframe>"#fafbba78"
    +
    +
    +
    +
    +
    +
    +
    <html> element must have a lang attribute
    + Learn more +
    +
    +
    html-has-lang
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every HTML document has a lang attribute

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    +
    +
    +
    +
    +
    +
    +
    Images must have alternate text
    + Learn more +
    +
    +
    image-alt
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures <img> elements have alternate text or a role of none or presentation

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<img src="/assets/demo-sites/mars/js/seg" width="1" height="1">"img[src$="seg"]"
    2<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\\\\32 10"][height="\\\\31 20"]"
    3<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\\\\32 10"][height="\\\\31 20"]"
    4<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120">":root > img[width="\\\\32 10"][height="\\\\31 20"]"
    +
    +
    +
    +
    +
    +
    +
    Form elements must have labels
    + Learn more +
    +
    +
    label
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures every form element has a label

    +
    + critical +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    +
    +
    +
    +
    +
    +
    +
    Document must have one main landmark
    + Learn more +
    +
    +
    landmark-one-main
    +
    + Best practice +
    +
    +
    +

    Ensures the document has a main landmark

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<html class=" js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths">"html"
    2<html lang="en" dir="ltr" data-cast-api-enabled="true">"#player", "html"
    3<html lang="en" id="facebook" class="">"#fafbba78", "#facebook"
    4<html lang="en" class=" xl en">".twitter-follow-button", "html"
    +
    +
    +
    +
    +
    +
    +
    Ensures landmarks are unique
    + Learn more +
    +
    +
    landmark-unique
    +
    + Best practice +
    +
    +
    +

    Landmarks must have a unique role or role/label/title (i.e. accessible name) combination

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<nav id="left-control-nav" class="pull-left">".loginnow > .container-fluid-full > .container > .span5.pull-left.left-first > .pull-left:nth-child(1)"
    +
    +
    +
    +
    +
    +
    +
    Links must be distinguished from surrounding text in a way that does not rely on color
    + Learn more +
    +
    +
    link-in-text-block
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Links can be distinguished without relying on color

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a href="mars2.html?a=last_will">prepare your last will and testament</a>"a[href="mars2\\\\.html\\\\?a\\\\=last_will"]"
    +
    +
    +
    +
    +
    +
    +
    Links must have discernible text
    + Learn more +
    +
    +
    link-name
    +
    + WCAG 2.0 Level A +
    +
    +
    +

    Ensures links have discernible text

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<a class="link" href="demo/mars/#"><i class="icon-menu-home"></i> </a>".link[href$="mars\\\\/\\\\#"]"
    2<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    3<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    4<a href="mars2.html?a=crater_adventure"> +<img src="/assets/demo-sites/mars/images/mars-spaceman.jpg" class="" width="210" height="120"></a>":root > a[href="mars2\\\\.html\\\\?a\\\\=crater_adventure"]"
    5<a href="mars2.html?a="></a>":root > a[href="mars2\\\\.html\\\\?a\\\\="]"
    6<a target="player" data-text="Life was possible on Mars" class="fader first active" href="http://www.youtube.com/embed/OagLGti_hTE?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>".active"
    7<a target="player" data-text="Why Mars died" class="fader first" href="http://www.youtube.com/embed/oC31pqk9sak?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="Why\\\\ Mars\\\\ died"]"
    8<a target="player" data-text="The world that never was" class="fader first" href="http://www.youtube.com/embed/JgMXPXdqJn8?controls=1&amp;showinfo=1&amp;modestbranding=0&amp;wmode=opaque&amp;enablejsapi=1" id="default"></a>"a[data-text="The\\\\ world\\\\ that\\\\ never\\\\ was"]"
    +
    +
    +
    +
    +
    +
    +
    All page content must be contained by landmarks
    + Learn more +
    +
    +
    region
    +
    + Best practice +
    +
    +
    +

    Ensures all page content is contained by landmarks

    +
    + moderate +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<div style="width: 1px; height: 1px; display: inline;">"body > div:nth-child(1)"
    2<div id="purposeDisclaimer">This web page is for demonstration purposes, to show common accessibility errors.</div>"#purposeDisclaimer"
    3<input type="text" class="search" name="query" placeholder="search">":root > .search[name="query"][placeholder="search"]"
    4<input type="submit" class="control-search">":root > .control-search[type="submit"]"
    5<div class="span7 left-first pull-left" id="left-column">"#left-column"
    6<div id="widget-controls" class="widget-container head">"#widget-controls"
    7<h3>Book your Trip</h3>"#route-select > .interior-container > h3"
    8<div id="route-type-radio-group" class="">"#route-type-radio-group"
    9<div id="route-type">"#route-type"
    10<div id="pass-question-radio-group" class="">"#pass-question-radio-group"
    11<h3>Who Is Traveling?</h3>".middle.widget-container:nth-child(13) > .interior-container > h3"
    12<span class="wrapper"> +<span class="traveler-label">Traveler</span> +</span>"#passenger0 > .wrapper:nth-child(1)"
    13<span class="wrapper age-range"> +<select id="traveler0" class="traveler-type"> +<option value="0">Adult (26+)</option> +<option value="1">Youth (12-25)</option> +<option value="2">Child (4-11)</option> +<option value="3">Senior (60+)</option> +</select> +</span>"#passenger0 > .age-range.wrapper"
    14<div class="add-buttons" id="add-traveler">"#add-traveler"
    15<div id="booking-box-submit" class="widget-container footer">"#booking-box-submit"
    16<div class="interior-container">"#video-box > .interior-container"
    17<div id="social-bar" class="container-fluid-full">"#social-bar"
    18<h4>Book Your Trip</h4>"#footer-book > h4"
    19<ul>"#footer-book > ul"
    20<h4>Mars Shuttles</h4>"#footer-trains > h4"
    21<ul>"#footer-trains > ul"
    22<h4>Mars Tourist Passes</h4>"#footer-passes > h4"
    23<ul>"#footer-passes > ul"
    24<h4>Mars Adventures</h4>"#footer-plan > h4"
    25<ul>"#footer-plan > ul"
    26<h4>FAQs</h4>"#footer-faq > h4"
    27<ul>"#footer-faq > ul"
    28<h4>Connect With Us</h4>"#footer-connect > h4"
    29<ul>"#footer-connect > ul"
    30<div id="copyright" class="container">"#copyright"
    31<div id="player" style="width: 100%; height: 100%;">"#player", "#player"
    32<tr><td><span class="fsl fwb"><a href="../mars2.html" target="_blank">Mars Commuter Express</a></span></td></tr>"#fafbba78", "._8m > table > tbody > tr:nth-child(1)"
    33<div class="pluginButton pluginConnectButtonDisconnected" title=""><div><button type="submit"><i class="pluginButtonIcon img sp_like sx_like_thumb"></i>Like</button></div></div>"#fafbba78", ".pluginConnectButtonDisconnected"
    34<span id="u_0_2">378,121</span>"#fafbba78", "#u_0_2"
    35<div class="btn-o" contextmenu="menu"><a id="follow-button" target="_blank" class="btn" title="Follow MarsCommuter on Twitter" href="mars2.html"><i></i><span class="label" id="l">Follow @MarsTrip1</span></a></div>".twitter-follow-button", ".btn-o"
    36<img src="../images/f.gif" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src="\\\\.\\\\.\\\\/images\\\\/f\\\\.gif"]"
    37<img src="jot" alt="" style="position: absolute; height: 1px; width: 1px; top: -9999px; left: -9999px;">".twitter-follow-button", "img[src$="jot"]"
    +
    +
    +
    +
    +
    +
    +
    Elements should not have tabindex greater than zero
    + Learn more
    -
    -
    -

    What 'incomplete' axe checks means?

    -

    - Incomplete 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. -

    -

    - Visit axe API Documentation - to learn more. -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #DescriptionAxe rule IDWCAGNodes with incomplete check
    1Elements must have sufficient color contrastcolor-contrastWCAG 2.0 Level AA132
    2Hidden content on the page cannot be analyzedhidden-contentBest practice60
    3Links must be distinguished from surrounding text in a way that does not rely on colorlink-in-text-blockWCAG 2.0 Level A22
    4<video> elements must have captionsvideo-captionWCAG 2.0 Level A1
    -
    +
    +
    tabindex
    +
    + Best practice +
    -
    -
    -
    - - -" -`; - -exports[`createHtmlReport() test Verify report with no violations, passes and incomplete with optional reportFileName, url and project key params 2`] = ` -" - - - - - - - - - - - - - AXE Accessibility Results - - -
    -

    - AXE Accessibility Results for DEQUE project -

    -
    - Page URL: - https://dequeuniversity.com/demo/mars/ - - -
    - -
    axe-core found 0 violations
    - - - +
    +

    Ensures tabindex attribute values are not greater than 0

    +
    + serious +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Source CodeSelector
    1<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="from0" name="from0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#from0"
    2<input type="text" value="" class="city-input ac_input ui-autocomplete-input" autocomplete="off" id="to0" name="to0" tabindex="1" role="textbox" aria-autocomplete="list" aria-haspopup="true">"#to0"
    3<input size="10" id="deptDate0" name="deptDate0" placeholder="mm/dd/yyyy" value="" tabindex="3" class="hasDatepicker input-dept">"#deptDate0"
    +
    +
    +
    @@ -9539,6 +14058,301 @@ exports[`createHtmlReport() test Verify report with no violations, passes and in
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    What 'inapplicable' axe checks means?

    +

    + The inapplicable array lists all the rules for which no matching + elements were found on the page. +

    +

    + Visit axe API Documentation + to learn more. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #DescriptionAxe rule IDWCAG
    1accesskey attribute value must be uniqueaccesskeysBest practice
    2Active <area> elements must have alternate textarea-altWCAG 2.0 Level A
    3ARIA input fields must have an accessible namearia-input-field-nameWCAG 2.0 Level A
    4Use aria-roledescription on elements with a semantic rolearia-roledescriptionWCAG 2.0 Level A
    5ARIA toggle fields have an accessible namearia-toggle-field-nameWCAG 2.0 Level A
    6<audio> elements must have a captions trackaudio-captionWCAG 2.0 Level A
    7<blink> elements are deprecated and must not be usedblinkWCAG 2.0 Level A
    8<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elementsdefinition-listWCAG 2.0 Level A
    9<dt> and <dd> elements must be contained by a <dl>dlitemWCAG 2.0 Level A
    10Elements in the focus order need a role appropriate for interactive contentfocus-order-semanticsBest practice
    11HTML elements with lang and xml:lang must have the same base languagehtml-xml-lang-mismatchWCAG 2.0 Level A
    12Image buttons must have alternate textinput-image-altWCAG 2.0 Level A
    13Elements must have their visible text as part of their accessible namelabel-content-name-mismatchWCAG 2.1 Level A
    14Banner landmark must not be contained in another landmarklandmark-banner-is-top-levelBest practice
    15Aside must not be contained in another landmarklandmark-complementary-is-top-levelBest practice
    16Contentinfo landmark must not be contained in another landmarklandmark-contentinfo-is-top-levelBest practice
    17Main landmark must not be contained in another landmarklandmark-main-is-top-levelBest practice
    18Document must not have more than one banner landmarklandmark-no-duplicate-bannerBest practice
    19Document must not have more than one contentinfo landmarklandmark-no-duplicate-contentinfoBest practice
    20Document must not have more than one main landmarklandmark-no-duplicate-mainBest practice
    21<marquee> elements are deprecated and must not be usedmarqueeWCAG 2.0 Level A
    22Timed refresh must not existmeta-refreshWCAG 2.0 Level A
    23<object> elements must have alternate textobject-altWCAG 2.0 Level A
    24Bold, italic text and font-size are not used to style p elements as a headingp-as-headingWCAG 2.0 Level A
    25[role='img'] elements have an alternative textrole-img-altWCAG 2.0 Level A
    26scope attribute should be used correctlyscope-attr-validBest practice
    27Ensure that scrollable region has keyboard accessscrollable-region-focusableWCAG 2.0 Level A
    28Server-side image maps must not be usedserver-side-image-mapWCAG 2.0 Level A
    29The skip-link target should exist and be focusableskip-linkBest practice
    30svg elements with an img role have an alternative textsvg-img-altWCAG 2.0 Level A
    31Data or header cells should not be used to give caption to a data table.table-fake-captionWCAG 2.0 Level A
    32All non-empty td element in table larger than 3 by 3 must have an associated table headertd-has-headerWCAG 2.0 Level A
    33All th elements and elements with role=columnheader/rowheader must have data cells they describeth-has-data-cellsWCAG 2.0 Level A
    34lang attribute must have a valid valuevalid-langWCAG 2.0 Level AA
    35<video> or <audio> elements do not autoplay audiono-autoplay-audioWCAG 2.0 Level A
    +
    +
    +
    +
    diff --git a/test/index.test.ts b/test/index.test.ts index 33c87c0..e679453 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,138 +1,158 @@ import { createHtmlReport } from '../src'; +import { defaultReportFileName } from '../src/util/saveHtmlReport'; import fs from 'fs'; import path from 'path'; const axeRawViolations = require('./rawViolations.json'); const axeRawPassed = require('./rawPasses.json'); const axeRawIncomplete = require('./rawIncomplete.json'); const axeRawInapplicable = require('./rawInapplicable.json'); +const rawAxeResults = require('./rawAxeResults.json'); + +function getPathToCreatedReport(customFileName?: string, customOutputDir?: string) { + return path.resolve( + process.cwd(), + customOutputDir ? customOutputDir : 'artifacts', + customFileName ? customFileName : defaultReportFileName + ); +} describe('createHtmlReport() test', () => { it('Verify throwing an error if required parameters are not passed', async () => { expect(() => { - //@ts-ignore - createHtmlReport({ passes: [] }); + createHtmlReport({ + // @ts-ignore + results: { + passes: [], + }, + }); }).toThrow( - "violations and url parameters are required for HTML accessibility report. Example: createHtmlReport({violations: Result[], url: 'www.example.com'})" + "'violations' is required for HTML accessibility report. Example: createHtmlReport({ results : { violations: Result[] } })" ); }); + it('Verify report is created only with violations because passes and incomplete are not passed', async () => { createHtmlReport({ - violations: axeRawViolations, - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve( - process.cwd(), - 'artifacts', - 'accessibilityReport.html' - ); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', + results: { + violations: axeRawViolations, + url: 'https://dequeuniversity.com/demo/mars/', + }, }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + expect(fs.readFileSync(getPathToCreatedReport(), { encoding: 'utf8' })).toMatchSnapshot(); + }); + it('URL is not passed', async () => { + const reportFileName = 'urlIsNotPassed.html'; + createHtmlReport({ + results: { + violations: axeRawViolations, + }, + options: { reportFileName }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); it('Verify report is created with violations and passes', async () => { + const reportFileName = 'tcPassesAndViolations.html'; createHtmlReport({ - violations: axeRawViolations, - passes: axeRawPassed, - reportFileName: 'tcPassesAndViolations.html', - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve(process.cwd(), 'artifacts', 'tcPassesAndViolations.html'); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: axeRawViolations, + passes: axeRawPassed, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { reportFileName }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); it('Verify report is created with violations, passes and incomplete with optional reportFileName and outputDir params', async () => { + const reportFileName = 'tcPassesViolationsIncomplete.html'; + const outputDir = 'temp'; createHtmlReport({ - violations: axeRawViolations, - passes: axeRawPassed, - incomplete: axeRawIncomplete, - reportFileName: 'tcPassesViolationsIncomplete.html', - outputDir: 'temp', - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve(process.cwd(), 'temp', 'tcPassesViolationsIncomplete.html'); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: axeRawViolations, + passes: axeRawPassed, + incomplete: axeRawIncomplete, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { + reportFileName, + outputDir, + }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName, outputDir), { + encoding: 'utf8', + }) + ).toMatchSnapshot(); }); it('Verify report is created with violations, passes and incomplete with optional reportFileName, url and project key params', async () => { + const reportFileName = 'tcWithTheKey.html'; createHtmlReport({ - violations: axeRawViolations, - passes: axeRawPassed, - incomplete: axeRawIncomplete, - reportFileName: 'tcWithTheKey.html', - projectKey: 'DEQUE', - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve(process.cwd(), 'artifacts', 'tcWithTheKey.html'); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: axeRawViolations, + passes: axeRawPassed, + incomplete: axeRawIncomplete, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { + reportFileName, + projectKey: 'DEQUE', + }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); it('Verify report with no violations, passes and incomplete with optional reportFileName, url and project key params', async () => { + const reportFileName = 'tcAllPassed.html'; createHtmlReport({ - violations: [], - passes: axeRawPassed, - incomplete: axeRawIncomplete, - reportFileName: 'tcAllPassed.html', - projectKey: 'DEQUE', - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve(process.cwd(), 'artifacts', 'tcAllPassed.html'); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: [], + passes: axeRawPassed, + incomplete: axeRawIncomplete, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { reportFileName, projectKey: 'DEQUE' }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); it('Verify report with no violations, passes and incomplete with optional reportFileName, url and project key params', async () => { + const reportFileName = 'tcInapplicablePresent.html'; createHtmlReport({ - violations: axeRawViolations, - passes: axeRawPassed, - incomplete: axeRawIncomplete, - inapplicable: axeRawInapplicable, - reportFileName: 'tcInapplicablePresent.html', - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve(process.cwd(), 'artifacts', 'tcAllPassed.html'); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: axeRawViolations, + passes: axeRawPassed, + incomplete: axeRawIncomplete, + inapplicable: axeRawInapplicable, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { reportFileName }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); it('Verify report with no violations, no passes, no incomplete, no inapplicable', async () => { + const reportFileName = 'tcOnlyPasses.html'; createHtmlReport({ - violations: [], - passes: [], - incomplete: [], - inapplicable: [], - reportFileName: 'tcOnlyPasses.html', - url: 'https://dequeuniversity.com/demo/mars/', - }); - const pathToTheReport = path.resolve(process.cwd(), 'artifacts', 'tcOnlyPasses.html'); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: [], + passes: [], + incomplete: [], + inapplicable: [], + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { reportFileName }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); it('Verify report is created with violations and custom summary', async () => { + const reportFileName = 'tcIncludingCustomSummary.html'; const customSummary = `Test Case: Full page analysis
    Steps:
      @@ -140,52 +160,51 @@ describe('createHtmlReport() test', () => {
    1. Analyze full page with all rules enabled
    `; createHtmlReport({ - violations: axeRawViolations, - url: 'https://dequeuniversity.com/demo/mars/', - customSummary, - reportFileName: 'tcIncludingCustomSummary.html' - }); - const pathToTheReport = path.resolve( - process.cwd(), - 'artifacts', - 'tcIncludingCustomSummary.html' - ); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: axeRawViolations, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { reportFileName, customSummary }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { encoding: 'utf8' }) + ).toMatchSnapshot(); }); - - it('All optional parameters present', async () => { - const customSummary = `Test Case: Full page analysis + const customSummary = `Test Case: Full page analysis
    Steps:
    1. Open https://dequeuniversity.com/demo/mars/
    2. Analyze full page with all rules enabled
    `; + it('All optional parameters present', async () => { + const reportFileName = 'tsAllOptionalParametersPresent.html'; createHtmlReport({ - violations: axeRawViolations, - passes: axeRawPassed, - incomplete: [], - inapplicable: axeRawInapplicable, - projectKey: 'DEQUE', - url: 'https://dequeuniversity.com/demo/mars/', - customSummary, - outputDir: 'docs', - reportFileName: 'index.html' - }); - const pathToTheReport = path.resolve( - process.cwd(), - 'artifacts', - 'tcIncludingCustomSummary.html' - ); - const htmlFileContent = fs.readFileSync(pathToTheReport, { - encoding: 'utf8', - }); - // do not clean up to verify results manually - // validate - expect(htmlFileContent).toMatchSnapshot(); + results: { + violations: axeRawViolations, + passes: axeRawPassed, + incomplete: [], + inapplicable: axeRawInapplicable, + url: 'https://dequeuniversity.com/demo/mars/', + }, + options: { projectKey: 'DEQUE', customSummary, reportFileName }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName), { + encoding: 'utf8', + }) + ).toMatchSnapshot(); + }); + it('AxeResults passed', async () => { + const reportFileName = 'index.html'; + const outputDir = 'docs'; + createHtmlReport({ + results: rawAxeResults, + options: { projectKey: 'DEQUE', customSummary, outputDir, reportFileName }, + }); + expect( + fs.readFileSync(getPathToCreatedReport(reportFileName, outputDir), { + encoding: 'utf8', + }) + ).toMatchSnapshot(); }); }); diff --git a/test/rawAxeResults.json b/test/rawAxeResults.json new file mode 100644 index 0000000..5049f7d --- /dev/null +++ b/test/rawAxeResults.json @@ -0,0 +1,1530 @@ +{ + "testEngine": { "name": "axe-core", "version": "3.5.5" }, + "testRunner": { "name": "axe" }, + "testEnvironment": { + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", + "windowWidth": 1200, + "windowHeight": 798, + "orientationAngle": 0, + "orientationType": "landscape-primary" + }, + "timestamp": "2020-10-12T04:08:37.038Z", + "url": "http://example.com/", + "toolOptions": { + "rules": { + "object-alt": { "enabled": true }, + "role-img-alt": { "enabled": true }, + "input-image-alt": { "enabled": true }, + "image-alt": { "enabled": true }, + "svg-img-alt": { "enabled": true }, + "area-alt": { "enabled": true }, + "audio-caption": { "enabled": true }, + "video-caption": { "enabled": true }, + "definition-list": { "enabled": true }, + "dlitem": { "enabled": true }, + "listitem": { "enabled": true }, + "list": { "enabled": true }, + "th-has-data-cells": { "enabled": true }, + "td-headers-attr": { "enabled": true }, + "td-has-header": { "enabled": true }, + "p-as-heading": { "enabled": true }, + "aria-required-parent": { "enabled": true }, + "aria-required-children": { "enabled": true }, + "table-fake-caption": { "enabled": true }, + "css-orientation-lock": { "enabled": false }, + "autocomplete-valid": { "enabled": true }, + "link-in-text-block": { "enabled": true }, + "no-autoplay-audio": { "enabled": true }, + "color-contrast": { "enabled": true }, + "meta-viewport": { "enabled": true }, + "avoid-inline-spacing": { "enabled": true }, + "server-side-image-map": { "enabled": true }, + "meta-refresh": { "enabled": true }, + "blink": { "enabled": true }, + "marquee": { "enabled": true }, + "bypass": { "enabled": true }, + "frame-title": { "enabled": true }, + "document-title": { "enabled": true }, + "scrollable-region-focusable": { "enabled": true }, + "identical-links-same-purpose": { "enabled": false }, + "label-content-name-mismatch": { "enabled": true }, + "html-has-lang": { "enabled": true }, + "html-lang-valid": { "enabled": true }, + "html-xml-lang-mismatch": { "enabled": true }, + "valid-lang": { "enabled": true }, + "form-field-multiple-labels": { "enabled": true }, + "duplicate-id-active": { "enabled": true }, + "duplicate-id": { "enabled": true }, + "duplicate-id-aria": { "enabled": true }, + "aria-valid-attr": { "enabled": true }, + "aria-valid-attr-value": { "enabled": true }, + "aria-input-field-name": { "enabled": true }, + "aria-roles": { "enabled": true }, + "aria-toggle-field-name": { "enabled": true }, + "aria-hidden-focus": { "enabled": true }, + "aria-hidden-body": { "enabled": true }, + "button-name": { "enabled": true }, + "aria-allowed-attr": { "enabled": true }, + "input-button-name": { "enabled": true }, + "aria-required-attr": { "enabled": true }, + "aria-roledescription": { "enabled": true }, + "link-name": { "enabled": true }, + "label": { "enabled": true }, + "accesskeys": { "enabled": true }, + "region": { "enabled": true }, + "aria-allowed-role": { "enabled": true }, + "landmark-banner-is-top-level": { "enabled": true }, + "landmark-complementary-is-top-level": { "enabled": true }, + "landmark-contentinfo-is-top-level": { "enabled": true }, + "focus-order-semantics": { "enabled": true }, + "tabindex": { "enabled": true }, + "landmark-no-duplicate-main": { "enabled": true }, + "label-title-only": { "enabled": true }, + "frame-tested": { "enabled": true }, + "frame-title-unique": { "enabled": true }, + "heading-order": { "enabled": true }, + "empty-heading": { "enabled": true }, + "hidden-content": { "enabled": true }, + "landmark-unique": { "enabled": true }, + "landmark-main-is-top-level": { "enabled": true }, + "page-has-heading-one": { "enabled": true }, + "landmark-one-main": { "enabled": true }, + "landmark-no-duplicate-banner": { "enabled": true }, + "landmark-no-duplicate-contentinfo": { "enabled": true }, + "scope-attr-valid": { "enabled": true }, + "image-redundant-alt": { "enabled": true }, + "table-duplicate-name": { "enabled": true }, + "skip-link": { "enabled": true }, + "meta-viewport-large": { "enabled": true } + }, + "reporter": "v1" + }, + "violations": [ + { + "id": "html-has-lang", + "impact": "serious", + "tags": ["cat.language", "wcag2a", "wcag311"], + "description": "Ensures every HTML document has a lang attribute", + "help": " element must have a lang attribute", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/html-has-lang?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "has-lang", + "data": { "messageKey": "noLang" }, + "relatedNodes": [], + "impact": "serious", + "message": "The element does not have a lang attribute" + } + ], + "all": [], + "none": [], + "impact": "serious", + "html": "", + "target": ["html"], + "failureSummary": "Fix any of the following:\n The element does not have a lang attribute" + } + ] + }, + { + "id": "landmark-one-main", + "impact": "moderate", + "tags": ["cat.semantics", "best-practice"], + "description": "Ensures the document has a main landmark", + "help": "Document must have one main landmark", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/landmark-one-main?application=axeAPI", + "nodes": [ + { + "any": [], + "all": [ + { + "id": "page-has-main", + "data": null, + "relatedNodes": [], + "impact": "moderate", + "message": "Document does not have a main landmark" + } + ], + "none": [], + "impact": "moderate", + "html": "", + "target": ["html"], + "failureSummary": "Fix all of the following:\n Document does not have a main landmark" + } + ] + }, + { + "id": "region", + "impact": "moderate", + "tags": ["cat.keyboard", "best-practice"], + "description": "Ensures all page content is contained by landmarks", + "help": "All page content must be contained by landmarks", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/region?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "region", + "data": null, + "relatedNodes": [], + "impact": "moderate", + "message": "Some page content is not contained by landmarks" + } + ], + "all": [], + "none": [], + "impact": "moderate", + "html": "
    \n

    Example Domain

    \n

    This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.

    \n

    More information...

    \n
    ", + "target": ["div"], + "failureSummary": "Fix any of the following:\n Some page content is not contained by landmarks" + } + ] + }, + { + "id": "tabindex", + "impact": "serious", + "tags": ["cat.keyboard", "best-practice"], + "description": "Ensures tabindex attribute values are not greater than 0", + "help": "Elements should not have tabindex greater than zero", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/tabindex?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "tabindex", + "data": null, + "relatedNodes": [], + "impact": "serious", + "message": "Element has a tabindex greater than 0" + } + ], + "all": [], + "none": [], + "impact": "serious", + "html": "", + "target": ["#from0"], + "failureSummary": "Fix any of the following:\n Element has a tabindex greater than 0" + }, + { + "any": [ + { + "id": "tabindex", + "data": null, + "relatedNodes": [], + "impact": "serious", + "message": "Element has a tabindex greater than 0" + } + ], + "all": [], + "none": [], + "impact": "serious", + "html": "", + "target": ["#to0"], + "failureSummary": "Fix any of the following:\n Element has a tabindex greater than 0" + }, + { + "any": [ + { + "id": "tabindex", + "data": null, + "relatedNodes": [], + "impact": "serious", + "message": "Element has a tabindex greater than 0" + } + ], + "all": [], + "none": [], + "impact": "serious", + "html": "", + "target": ["#deptDate0"], + "failureSummary": "Fix any of the following:\n Element has a tabindex greater than 0" + } + ] + } + ], + "passes": [ + { + "id": "aria-hidden-body", + "impact": null, + "tags": ["cat.aria", "wcag2a", "wcag412"], + "description": "Ensures aria-hidden='true' is not present on the document body.", + "help": "aria-hidden='true' must not be present on the document body", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/aria-hidden-body?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "aria-hidden-body", + "data": null, + "relatedNodes": [], + "impact": "critical", + "message": "No aria-hidden attribute is present on document body" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "", + "target": ["body"] + } + ] + }, + { + "id": "bypass", + "impact": null, + "tags": ["cat.keyboard", "wcag2a", "wcag241", "section508", "section508.22.o"], + "description": "Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content", + "help": "Page must have means to bypass repeated blocks", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/bypass?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "header-present", + "data": null, + "relatedNodes": [], + "impact": "serious", + "message": "Page has a heading" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "", + "target": ["html"] + } + ] + }, + { + "id": "color-contrast", + "impact": null, + "tags": ["cat.color", "wcag2aa", "wcag143"], + "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds", + "help": "Elements must have sufficient color contrast", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/color-contrast?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "color-contrast", + "data": { + "fgColor": "#000000", + "bgColor": "#fdfdff", + "contrastRatio": 20.67, + "fontSize": "24.0pt (32px)", + "fontWeight": "bold", + "expectedContrastRatio": "3:1" + }, + "relatedNodes": [], + "impact": "serious", + "message": "Element has sufficient color contrast of 20.67" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "

    Example Domain

    ", + "target": ["h1"] + }, + { + "any": [ + { + "id": "color-contrast", + "data": { + "fgColor": "#000000", + "bgColor": "#fdfdff", + "contrastRatio": 20.67, + "fontSize": "12.0pt (16px)", + "fontWeight": "normal", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [], + "impact": "serious", + "message": "Element has sufficient color contrast of 20.67" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "

    This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.

    ", + "target": ["p:nth-child(2)"] + }, + { + "any": [ + { + "id": "color-contrast", + "data": { + "fgColor": "#38488f", + "bgColor": "#fdfdff", + "contrastRatio": 8.29, + "fontSize": "12.0pt (16px)", + "fontWeight": "normal", + "expectedContrastRatio": "4.5:1" + }, + "relatedNodes": [], + "impact": "serious", + "message": "Element has sufficient color contrast of 8.29" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "More information...", + "target": ["a"] + } + ] + }, + { + "id": "document-title", + "impact": null, + "tags": ["cat.text-alternatives", "wcag2a", "wcag242"], + "description": "Ensures each HTML document contains a non-empty element", + "help": "Documents must have <title> element to aid in navigation", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/document-title?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "doc-has-title", + "data": null, + "relatedNodes": [], + "impact": "serious", + "message": "Document has a non-empty <title> element" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "<html>", + "target": ["html"] + } + ] + }, + { + "id": "empty-heading", + "impact": null, + "tags": ["cat.name-role-value", "best-practice"], + "description": "Ensures headings have discernible text", + "help": "Headings must not be empty", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/empty-heading?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "has-visible-text", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "Element has text that is visible to screen readers" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "<h1>Example Domain</h1>", + "target": ["h1"] + } + ] + }, + { + "id": "heading-order", + "impact": null, + "tags": ["cat.semantics", "best-practice"], + "description": "Ensures the order of headings is semantically correct", + "help": "Heading levels should only increase by one", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/heading-order?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "heading-order", + "data": 1, + "relatedNodes": [], + "impact": "moderate", + "message": "Heading order valid" + } + ], + "all": [], + "none": [], + "impact": null, + "html": "<h1>Example Domain</h1>", + "target": ["h1"] + } + ] + }, + { + "id": "hidden-content", + "impact": null, + "tags": ["cat.structure", "experimental", "review-item", "best-practice"], + "description": "Informs users about hidden content.", + "help": "Hidden content on the page cannot be analyzed", + "helpUrl": "https://dequeuniversity.com/rules/axe/3.5/hidden-content?application=axeAPI", + "nodes": [ + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "<html>", + "target": ["html"] + }, + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "<head>", + "target": ["head"] + }, + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "<title>nc1XeDBns*TPbby41kI", + "target": ["title"] + }, + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "", + "target": ["meta[charset=\"utf-8\"]"] + }, + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "", + "target": ["meta[http-equiv=\"Content-type\"]"] + }, + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "", + "target": ["meta[name=\"viewport\"]"] + }, + { + "any": [ + { + "id": "hidden-content", + "data": null, + "relatedNodes": [], + "impact": "minor", + "message": "All content on the page has been analyzed." + } + ], + "all": [], + "none": [], + "impact": null, + "html": "