diff --git a/.circleci/config.yml b/.circleci/config.yml
index 0f0c594937..1388bf5352 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -219,7 +219,7 @@ jobs:
equal: [42, 42] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
steps:
- generate_and_store_version_and_filesystem_artifacts
- visual-test:
+ visual-a11y-tests:
parameters:
suite:
type: string # ci or full
@@ -253,7 +253,7 @@ workflows:
suite: stable
- mem-test
- perf-test
- - visual-test:
+ - visual-a11y-tests:
name: visual-test-ci
suite: ci
@@ -272,7 +272,7 @@ workflows:
suite: full
- mem-test
- perf-test
- - visual-test:
+ - visual-a11y-tests:
name: visual-test-nightly
suite: full
- e2e-couchdb
diff --git a/.cspell.json b/.cspell.json
index f29d189016..024e09d178 100644
--- a/.cspell.json
+++ b/.cspell.json
@@ -490,7 +490,8 @@
"Blockquotes",
"oger",
"lcovonly",
- "gcov"
+ "gcov",
+ "WCAG"
],
"dictionaries": ["npm", "softwareTerms", "node", "html", "css", "bash", "en_US"],
"ignorePaths": [
diff --git a/e2e/.percy.ci.yml b/e2e/.percy.ci.yml
index 29527e79e4..e15de3f810 100644
--- a/e2e/.percy.ci.yml
+++ b/e2e/.percy.ci.yml
@@ -21,4 +21,8 @@ snapshot:
/* Embedded timestamp in notebooks */
.c-ne__embed__time{
opacity: 0 !important;
+ }
+ /* Time Conductor Start Time */
+ .c-compact-tc__setting-value{
+ opacity: 0 !important;
}
\ No newline at end of file
diff --git a/e2e/.percy.nightly.yml b/e2e/.percy.nightly.yml
index 704913bb05..7f9d8ec813 100644
--- a/e2e/.percy.nightly.yml
+++ b/e2e/.percy.nightly.yml
@@ -21,4 +21,8 @@ snapshot:
/* Embedded timestamp in notebooks */
.c-ne__embed__time{
opacity: 0 !important;
+ }
+ /* Time Conductor Start Time */
+ .c-compact-tc__setting-value{
+ opacity: 0 !important;
}
\ No newline at end of file
diff --git a/e2e/README.md b/e2e/README.md
index 95c6343409..0917579b56 100644
--- a/e2e/README.md
+++ b/e2e/README.md
@@ -51,11 +51,13 @@ Next, you should walk through our implementation of Playwright in Open MCT:
## Types of e2e Testing
-e2e testing describes the layer at which a test is performed without prescribing the assertions which are made. Generally, when writing an e2e test, we have three choices to make on an assertion strategy:
+e2e testing describes the layer at which a test is performed without prescribing the assertions which are made. Generally, when writing an e2e test, we have five choices to make on an assertion strategy:
1. Functional - Verifies the functional correctness of the application. Sometimes interchanged with e2e or regression testing.
2. Visual - Verifies the "look and feel" of the application and can only detect _undesirable changes when compared to a previous baseline_.
3. Snapshot - Similar to Visual in that it captures the "look" of the application and can only detect _undesirable changes when compared to a previous baseline_. **Generally not preferred due to advanced setup necessary.**
+4. Accessibility - Verifies that the application meets the accessibility standards defined by the [WCAG organization](https://www.w3.org/WAI/standards-guidelines/wcag/).
+5. Performance - Verifies that application provides a performant experience. Like Snapshot testing, these tests are generally not recommended due to their difficulty in providing a consistent result.
When choosing between the different testing strategies, think only about the assertion that is made at the end of the series of test steps. "I want to verify that the Timer plugin functions correctly" vs "I want to verify that the Timer plugin does not look different than originally designed".
@@ -132,6 +134,35 @@ npm install
npm run test:e2e:updatesnapshots
```
+## Automated Accessibility (a11y) Testing
+
+Open MCT incorporates accessibility testing through two primary methods to ensure its compliance with accessibility standards:
+
+1. **Usage of Playwright's Locator Strategy**: Open MCT utilizes Playwright's locator strategy, specifically the [page.getByRole('') function](https://playwright.dev/docs/api/class-framelocator#frame-locator-get-by-role), to ensure that web elements are accessible via assistive technologies. This approach focuses on the accessibility of elements rather than full adherence to a11y guidelines, which is covered in the second method.
+
+2. **Enforcing a11y Guidelines with Playwright Axe Plugin**: To rigorously enforce a11y guideline compliance, Open MCT employs the [playwright axe plugin](https://playwright.dev/docs/accessibility-testing). This is achieved through the `scanForA11yViolations` function within the visual testing suite. This method not only benefits from the existing coverage of the visual tests but also targets specific a11y issues, such as `color-contrast` violations, which are particularly pertinent in the context of visual testing.
+
+### a11y Standards (WCAG and Section 508)
+
+Playwright axe supports a wide range of [WCAG Standards](https://playwright.dev/docs/accessibility-testing#scanning-for-wcag-violations) to test against. Open MCT is testing against the [Section 508](https://www.section508.gov/test/testing-overview/) accessibility guidelines with the intent to support higher standards over time. As of 2024, Section508 requirements now map completely to WCAG 2.0 AA. In the future, Section 508 requirements may map to WCAG 2.1 AA.
+
+### Reading an a11y test failure
+
+When an a11y test fails, the result must be interpreted in the html test report or the a11y report json artifact stored in the `/test-results/` folder. The json structure should be parsed for `"violations"` by `"id"` and identified `"target"`. Example provided for the 'color-contrast-enhanced' violation.
+
+```json
+ "violations":
+ {
+ "id": "color-contrast-enhanced",
+ "impact": "serious",
+ "html": "0 Snapshots ",
+ "target": [
+ ".s-status-off > .label.c-indicator__label"
+ ],
+ "failureSummary": "Fix any of the following:\n Element has insufficient color contrast of 6.51 (foreground color: #aaaaaa, background color: #262626, font size: 8.1pt (10.8px), font weight: normal). Expected contrast ratio of 7:1"
+ }
+```
+
## Performance Testing
The open source performance tests function in three ways which match their naming and folder structure:
@@ -142,6 +173,8 @@ The open source performance tests function in three ways which match their namin
These tests are expected to become blocking and gating with assertions as we extend the capabilities of Playwright.
+In addition to the explicit definition of performance tests, we also ensure that our test timeout timing is "tight" to catch performance regressions detectable by action timeouts. i.e. [Notebooks load much slower than they used to #6459](https://github.com/nasa/openmct/issues/6459)
+
## Test Architecture and CI
### Architecture
@@ -161,8 +194,8 @@ Our file structure follows the type of type of testing being excercised at the e
|`./tests/performance/` | Performance tests which should be run on every commit.|
|`./tests/performance/contract/` | A subset of performance tests which are designed to provide a contract between the open source tests which are run on every commit and the downstream tests which are run post merge and with other frameworks.|
|`./tests/performance/memory` | A subset of performance tests which are designed to test for memory leaks.|
-|`./tests/visual/` | Visual tests.|
-|`./tests/visual/component/` | Visual tests which are only run against a single component.|
+|`./tests/visual-a11y/` | Visual tests and accessibility tests.|
+|`./tests/visual-a11y/component/` | Visual and accessibility tests which are only run against a single component.|
|`./appActions.js` | Contains common methods which can be leveraged by test case authors to quickly move through the application when writing new tests.|
|`./baseFixture.js` | Contains base fixtures which only extend default `@playwright/test` functionality. The expectation is that these fixtures will be removed as the native Playwright API improves|
@@ -180,7 +213,7 @@ Open MCT is leveraging the [config file](https://playwright.dev/docs/test-config
|`./playwright-local.config.js` | Used when running locally|
|`./playwright-performance.config.js` | Used when running performance tests in CI or locally|
|`./playwright-performance-devmode.config.js` | Used when running performance tests in CI or locally|
-|`./playwright-visual.config.js` | Used to run the visual tests in CI or locally|
+|`./playwright-visual-a11y.config.js` | Used to run the visual and a11y tests in CI or locally|
#### Test Tags
@@ -191,6 +224,7 @@ Current list of test tags:
|Test Tag|Description|
|:-:|-|
|`@ipad` | Test case or test suite is compatible with Playwright's iPad support and Open MCT's read-only mobile view (i.e. no create button).|
+|`@a11y` | Test case or test suite to execute playwright-axe accessibility checks and generate a11y reports.|
|`@gds` | Denotes a GDS Test Case used in the VIPER Mission.|
|`@addInit` | Initializes the browser with an injected and artificial state. Useful for loading non-default plugins. Likely will not work outside of `npm start`.|
|`@localStorage` | Captures or generates session storage to manipulate browser state. Useful for excluding in tests which require a persistent backend (i.e. CouchDB). See [note](#utilizing-localstorage)|
@@ -216,7 +250,7 @@ CircleCI
- Stable e2e tests against ubuntu and chrome
- Performance tests against ubuntu and chrome
- e2e tests are linted
-- Visual tests are run in a single resolution on the default `espresso` theme
+- Visual and a11y tests are run in a single resolution on the default `espresso` theme
#### 2. Per-Merge Testing
@@ -232,7 +266,7 @@ Nightly Testing in Circle CI
- Full e2e suite against ubuntu and chrome, firefox, and an MMOC resolution profile
- Performance tests against ubuntu and chrome
- CouchDB suite
-- Visual Tests are run in the full profile
+- Visual and a11y Tests are run in the full profile
Github Actions / Workflow
@@ -405,7 +439,7 @@ By adhering to this principle, we can create tests that are both robust and refl
5. **Hide the Tree and Inspector**: Generally, your test will not require comparisons involving the tree and inspector. These aspects are covered in component-specific tests (explained below). To exclude them from the comparison by default, navigate to the root of the main view with the tree and inspector hidden:
- `await page.goto('./#/browse/mine?hideTree=true&hideInspector=true')`
-6. **Component-Specific Tests**: If you wish to focus on a particular component, use the `/visual/component/` folder and limit the scope of the comparison to that component. For instance:
+6. **Component-Specific Tests**: If you wish to focus on a particular component, use the `/visual-a11y/component/` folder and limit the scope of the comparison to that component. For instance:
```js
await percySnapshot(page, `Tree Pane w/ single level expanded (theme: ${theme})`, {
scope: treePane
diff --git a/e2e/avpFixtures.js b/e2e/avpFixtures.js
new file mode 100644
index 0000000000..fb99b94347
--- /dev/null
+++ b/e2e/avpFixtures.js
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2023, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+/**
+ * avpFixtures.js
+ *
+ * @file This module provides custom fixtures specifically tailored for Accessibility, Visual, and Performance (AVP) tests.
+ * These fixtures extend the base functionality of the Playwright fixtures and appActions, and are designed to be
+ * generalized across all plugins. They offer functionalities like scanning for accessibility violations, integrating
+ * with axe-core, and more.
+ *
+ * IMPORTANT NOTE: This fixture file is not intended to be extended further by other fixtures. If you find yourself
+ * needing to do so, please consult the documentation and consider creating a specialized fixture or modifying the
+ * existing ones.
+ */
+
+const fs = require('fs');
+const path = require('path');
+const { test, expect } = require('./pluginFixtures');
+const AxeBuilder = require('@axe-core/playwright').default;
+
+// Constants for repeated values
+const TEST_RESULTS_DIR = './test-results';
+
+/**
+ * Scans for accessibility violations on a page and writes a report to disk if violations are found.
+ * Automatically asserts that no violations should be present.
+ *
+ * @typedef {object} GenerateReportOptions
+ * @property {string} [reportName] - The name for the report file.
+ *
+ * @param {import('playwright').Page} page - The page object from Playwright.
+ * @param {string} testCaseName - The name of the test case.
+ * @param {GenerateReportOptions} [options={}] - The options for the report generation.
+ *
+ * @returns {Promise