mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 20:57:53 +00:00
[e2e] Update remaining tests and add missing comparison coverage (#7363)
This commit is contained in:
parent
6fd7b6f7a3
commit
6ce340cebd
@ -43,7 +43,6 @@
|
||||
"sharded",
|
||||
"perfromance",
|
||||
"MMOC",
|
||||
"deploysentinel",
|
||||
"codegen",
|
||||
"Unfortuantely",
|
||||
"viewports",
|
||||
|
3
.github/workflows/e2e-couchdb.yml
vendored
3
.github/workflows/e2e-couchdb.yml
vendored
@ -47,9 +47,8 @@ jobs:
|
||||
bash src/plugins/persistence/couch/setup-couchdb.sh
|
||||
bash src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh
|
||||
|
||||
- name: Run CouchDB Tests and publish to deploysentinel
|
||||
- name: Run CouchDB Tests
|
||||
env:
|
||||
DEPLOYSENTINEL_API_KEY: ${{ secrets.DEPLOYSENTINEL_API_KEY }}
|
||||
COMMIT_INFO_SHA: ${{github.event.pull_request.head.sha }}
|
||||
run: npm run test:e2e:couchdb
|
||||
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,6 +15,9 @@
|
||||
*.idea
|
||||
*.iml
|
||||
|
||||
# VSCode
|
||||
.vscode/settings.json
|
||||
|
||||
# Build output
|
||||
target
|
||||
dist
|
||||
|
@ -85,9 +85,8 @@ There are a few reasons that your GitHub PR could be failing beyond simple faile
|
||||
* Not all required checks are run per commit. You may need to manually trigger addition GitHub checks with a `pr:<label>` label added to your PR.
|
||||
|
||||
### Flaky tests
|
||||
There are two ways to know if a test on your branch is historically flaky:
|
||||
1. `deploysentinel`'s PR comment bot to give an accurate and historical view of e2e flakiness. Check your PR for a view of the test failures and flakes (with link to the failing test). Note: only a 7 day window of flake is available.
|
||||
2. (CircleCI's test insights feature)[https://circleci.com/blog/introducing-test-insights-with-flaky-test-detection/] collects historical data about the individual test results for both unit and e2e tests. Note: only a 14 day window of flake is available.
|
||||
|
||||
(CircleCI's test insights feature)[https://circleci.com/blog/introducing-test-insights-with-flaky-test-detection/] collects historical data about the individual test results for both unit and e2e tests. Note: only a 14 day window of flake is available.
|
||||
|
||||
### Local=Pass and CI=Fail
|
||||
Although rare, it is possible that your test can pass locally but fail in CI.
|
||||
|
@ -75,8 +75,7 @@ const config = {
|
||||
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
||||
}
|
||||
],
|
||||
['junit', { outputFile: '../test-results/results.xml' }],
|
||||
['@deploysentinel/playwright']
|
||||
['junit', { outputFile: '../test-results/results.xml' }]
|
||||
]
|
||||
};
|
||||
|
||||
|
@ -1,14 +1,9 @@
|
||||
// playwright.config.js
|
||||
// @ts-check
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { devices } from '@playwright/test';
|
||||
const MAX_FAILURES = 5;
|
||||
const NUM_WORKERS = 2;
|
||||
|
||||
/** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||
const config = {
|
||||
retries: 0, //Retries 2 times for a total of 3 runs. When running sharded and with max-failures=5, this should ensure that flake is managed without failing the full suite
|
||||
retries: 0, //Retries are not needed with watch mode
|
||||
testDir: 'tests',
|
||||
timeout: 60 * 1000,
|
||||
webServer: {
|
||||
@ -17,8 +12,7 @@ const config = {
|
||||
timeout: 200 * 1000,
|
||||
reuseExistingServer: true //This was originally disabled to prevent differences in local debugging vs. CI. However, it significantly speeds up local debugging.
|
||||
},
|
||||
maxFailures: MAX_FAILURES, //Limits failures to 5 to reduce CI Waste
|
||||
workers: NUM_WORKERS, //Limit to 2 for CircleCI Agent
|
||||
workers: '75%', //Limit to 75% of the CPU to support running with dev server
|
||||
use: {
|
||||
baseURL: 'http://localhost:8080/',
|
||||
headless: true,
|
||||
@ -45,8 +39,7 @@ const config = {
|
||||
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
||||
}
|
||||
],
|
||||
['junit', { outputFile: '../test-results/results.xml' }],
|
||||
['@deploysentinel/playwright']
|
||||
['junit', { outputFile: '../test-results/results.xml' }]
|
||||
]
|
||||
};
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -6,11 +6,11 @@
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "mct",
|
||||
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602540,\"created\":1732413600760,\"persisted\":1732413602540},\"20e7d5fe-9cf8-4099-8957-9453a8954c67\":{\"identifier\":{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},\"name\":\"Overlay Plot with Telemetry Object\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"configuration\":{\"series\":[]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with Telemetry Object\\nchrome\",\"modified\":1732413603960,\"location\":\"mine\",\"created\":1732413601820,\"persisted\":1732413603960},\"2db521a9-996d-4d04-a171-93f4c5c220af\":{\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"identifier\":{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"},\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":0,\"infinityValues\":false,\"staleness\":false},\"modified\":1732413602540,\"location\":\"mine\",\"created\":1732413602540,\"persisted\":1732413602540}}"
|
||||
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602460,\"created\":1732413600960,\"persisted\":1732413602460},\"e78ca721-fb5e-409b-bf6d-597c87cb716f\":{\"identifier\":{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},\"name\":\"Overlay Plot with Telemetry Object\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with Telemetry Object\\nchrome\",\"modified\":1732413603880,\"location\":\"mine\",\"created\":1732413601740,\"persisted\":1732413603880},\"c6100044-56be-44b3-acca-6b9fddfb3849\":{\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"identifier\":{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"},\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":0,\"infinityValues\":false,\"exceedFloat32\":false,\"staleness\":false},\"modified\":1732413602460,\"location\":\"mine\",\"created\":1732413602460,\"persisted\":1732413602460}}"
|
||||
},
|
||||
{
|
||||
"name": "mct-recent-objects",
|
||||
"value": "[{\"objectPath\":[{\"identifier\":{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"},\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":0,\"infinityValues\":false,\"staleness\":false},\"modified\":1732413602540,\"location\":\"mine\",\"created\":1732413602540,\"persisted\":1732413602540},{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602540,\"created\":1732413600760,\"persisted\":1732413602540},{\"identifier\":{\"key\":\"ROOT\",\"namespace\":\"\"},\"name\":\"Open MCT\",\"type\":\"root\",\"composition\":[{\"key\":\"mine\",\"namespace\":\"\"}]}],\"navigationPath\":\"/browse/mine/2db521a9-996d-4d04-a171-93f4c5c220af\",\"domainObject\":{\"identifier\":{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"},\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":0,\"infinityValues\":false,\"staleness\":false},\"modified\":1732413602540,\"location\":\"mine\",\"created\":1732413602540,\"persisted\":1732413602540}},{\"objectPath\":[{\"identifier\":{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},\"name\":\"Overlay Plot with Telemetry Object\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with Telemetry Object\\nchrome\",\"modified\":1732413603960,\"location\":\"mine\",\"created\":1732413601820,\"persisted\":1732413603960},{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602540,\"created\":1732413600760,\"persisted\":1732413602540},{\"identifier\":{\"key\":\"ROOT\",\"namespace\":\"\"},\"name\":\"Open MCT\",\"type\":\"root\",\"composition\":[{\"key\":\"mine\",\"namespace\":\"\"}]}],\"navigationPath\":\"/browse/mine/20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"domainObject\":{\"identifier\":{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},\"name\":\"Overlay Plot with Telemetry Object\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with Telemetry Object\\nchrome\",\"modified\":1732413603960,\"location\":\"mine\",\"created\":1732413601820,\"persisted\":1732413603960}},{\"objectPath\":[{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602540,\"created\":1732413600760,\"persisted\":1732413602540},{\"identifier\":{\"key\":\"ROOT\",\"namespace\":\"\"},\"name\":\"Open MCT\",\"type\":\"root\",\"composition\":[{\"key\":\"mine\",\"namespace\":\"\"}]}],\"navigationPath\":\"/browse/mine\",\"domainObject\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"20e7d5fe-9cf8-4099-8957-9453a8954c67\",\"namespace\":\"\"},{\"key\":\"2db521a9-996d-4d04-a171-93f4c5c220af\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602540,\"created\":1732413600760,\"persisted\":1732413602540}}]"
|
||||
"value": "[{\"objectPath\":[{\"identifier\":{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"},\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":0,\"infinityValues\":false,\"exceedFloat32\":false,\"staleness\":false},\"modified\":1732413602460,\"location\":\"mine\",\"created\":1732413602460,\"persisted\":1732413602460},{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602460,\"created\":1732413600960,\"persisted\":1732413602460},{\"identifier\":{\"key\":\"ROOT\",\"namespace\":\"\"},\"name\":\"Open MCT\",\"type\":\"root\",\"composition\":[{\"key\":\"mine\",\"namespace\":\"\"}]}],\"navigationPath\":\"/browse/mine/c6100044-56be-44b3-acca-6b9fddfb3849\",\"domainObject\":{\"identifier\":{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"},\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":0,\"infinityValues\":false,\"exceedFloat32\":false,\"staleness\":false},\"modified\":1732413602460,\"location\":\"mine\",\"created\":1732413602460,\"persisted\":1732413602460}},{\"objectPath\":[{\"identifier\":{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},\"name\":\"Overlay Plot with Telemetry Object\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with Telemetry Object\\nchrome\",\"modified\":1732413603880,\"location\":\"mine\",\"created\":1732413601740,\"persisted\":1732413603880},{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602460,\"created\":1732413600960,\"persisted\":1732413602460},{\"identifier\":{\"key\":\"ROOT\",\"namespace\":\"\"},\"name\":\"Open MCT\",\"type\":\"root\",\"composition\":[{\"key\":\"mine\",\"namespace\":\"\"}]}],\"navigationPath\":\"/browse/mine/e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"domainObject\":{\"identifier\":{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},\"name\":\"Overlay Plot with Telemetry Object\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with Telemetry Object\\nchrome\",\"modified\":1732413603880,\"location\":\"mine\",\"created\":1732413601740,\"persisted\":1732413603880}},{\"objectPath\":[{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602460,\"created\":1732413600960,\"persisted\":1732413602460},{\"identifier\":{\"key\":\"ROOT\",\"namespace\":\"\"},\"name\":\"Open MCT\",\"type\":\"root\",\"composition\":[{\"key\":\"mine\",\"namespace\":\"\"}]}],\"navigationPath\":\"/browse/mine\",\"domainObject\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"e78ca721-fb5e-409b-bf6d-597c87cb716f\",\"namespace\":\"\"},{\"key\":\"c6100044-56be-44b3-acca-6b9fddfb3849\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413602460,\"created\":1732413600960,\"persisted\":1732413602460}}]"
|
||||
},
|
||||
{
|
||||
"name": "mct-tree-expanded",
|
||||
|
@ -6,7 +6,7 @@
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "mct",
|
||||
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"98161570-a735-4a50-9c75-11b346ad3789\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413601340,\"created\":1732413600580,\"persisted\":1732413601340},\"98161570-a735-4a50-9c75-11b346ad3789\":{\"identifier\":{\"key\":\"98161570-a735-4a50-9c75-11b346ad3789\",\"namespace\":\"\"},\"name\":\"Overlay Plot with 5s Delay\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"477e60bb-4cba-4603-b4c9-2281ccf7e054\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"477e60bb-4cba-4603-b4c9-2281ccf7e054\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with 5s Delay\\nchrome\",\"modified\":1732413602660,\"location\":\"mine\",\"created\":1732413601340,\"persisted\":1732413602660},\"477e60bb-4cba-4603-b4c9-2281ccf7e054\":{\"identifier\":{\"key\":\"477e60bb-4cba-4603-b4c9-2281ccf7e054\",\"namespace\":\"\"},\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":5000,\"infinityValues\":false,\"staleness\":false},\"modified\":1732413602520,\"location\":\"98161570-a735-4a50-9c75-11b346ad3789\",\"created\":1732413602040,\"persisted\":1732413602520}}"
|
||||
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"67ca2e0a-b37e-4eda-86a4-ccdbb228bbc0\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"modified\":1732413601720,\"created\":1732413600920,\"persisted\":1732413601720},\"67ca2e0a-b37e-4eda-86a4-ccdbb228bbc0\":{\"identifier\":{\"key\":\"67ca2e0a-b37e-4eda-86a4-ccdbb228bbc0\",\"namespace\":\"\"},\"name\":\"Overlay Plot with 5s Delay\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"8f524b49-ad06-47f9-98e0-087b31a2f3e0\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"8f524b49-ad06-47f9-98e0-087b31a2f3e0\",\"namespace\":\"\"}}]},\"notes\":\"framework/generateLocalStorageData.e2e.spec.js\\nGenerate Visual Test Data @localStorage @generatedata\\nGenerate Overlay Plot with 5s Delay\\nchrome\",\"modified\":1732413603020,\"location\":\"mine\",\"created\":1732413601720,\"persisted\":1732413603020},\"8f524b49-ad06-47f9-98e0-087b31a2f3e0\":{\"identifier\":{\"key\":\"8f524b49-ad06-47f9-98e0-087b31a2f3e0\",\"namespace\":\"\"},\"name\":\"VIPER Rover Heading\",\"type\":\"generator\",\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":5000,\"infinityValues\":false,\"exceedFloat32\":false,\"staleness\":false},\"modified\":1732413602920,\"location\":\"67ca2e0a-b37e-4eda-86a4-ccdbb228bbc0\",\"created\":1732413602420,\"persisted\":1732413602920}}"
|
||||
},
|
||||
{
|
||||
"name": "mct-tree-expanded",
|
||||
|
File diff suppressed because one or more lines are too long
@ -155,7 +155,7 @@ test.describe('AppActions', () => {
|
||||
|
||||
await page.goto('./#/browse/mine');
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click the object specified by 'type'
|
||||
await page.click(`li[role='menuitem']:text("Clock")`);
|
||||
|
@ -53,29 +53,28 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
|
||||
});
|
||||
|
||||
test('Generate display layout with 2 child display layouts', async ({ page, context }) => {
|
||||
// Create Display Layout
|
||||
const parent = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Parent Display Layout'
|
||||
});
|
||||
const child1 = await createDomainObjectWithDefaults(page, {
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Child Layout 1',
|
||||
parent: parent.uuid
|
||||
});
|
||||
const child2 = await createDomainObjectWithDefaults(page, {
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Child Layout 2',
|
||||
parent: parent.uuid
|
||||
});
|
||||
|
||||
await page.goto(parent.url);
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel(`${child2.name} Layout Grid`).hover();
|
||||
await page.goto(parent.url, { waitUntil: 'domcontentloaded' });
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.getByLabel('Child Layout 2 Layout', { exact: true }).hover();
|
||||
await page.getByLabel('Move Sub-object Frame').nth(1).click();
|
||||
await page.getByLabel('X:').fill('30');
|
||||
|
||||
await page.getByLabel(`${child1.name} Layout Grid`).hover();
|
||||
await page.getByLabel('Child Layout 1 Layout', { exact: true }).hover();
|
||||
await page.getByLabel('Move Sub-object Frame').first().click();
|
||||
await page.getByLabel('Y:').fill('30');
|
||||
|
||||
@ -107,7 +106,7 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
|
||||
parent: parent.uuid
|
||||
});
|
||||
|
||||
await page.goto(parent.url);
|
||||
await page.goto(parent.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
//Save localStorage for future test execution
|
||||
await context.storageState({
|
||||
@ -134,7 +133,7 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
|
||||
await page.locator('button[title="More actions"]').click();
|
||||
|
||||
// Select 'Create Link' from dropdown
|
||||
await page.getByRole('menuitem', { name: ' Create Link' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Create Link' }).click();
|
||||
|
||||
// Search and Select for overlay Plot within Create Modal
|
||||
await page.getByRole('dialog').getByRole('searchbox', { name: 'Search Input' }).click();
|
||||
@ -206,8 +205,8 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
|
||||
const swgWith5sDelay = await createExampleTelemetryObject(page, overlayPlot.uuid);
|
||||
|
||||
await page.goto(swgWith5sDelay.url);
|
||||
await page.getByTitle('More actions').click();
|
||||
await page.getByRole('menuitem', { name: ' Edit Properties...' }).click();
|
||||
await page.getByLabel('More actions').click();
|
||||
await page.getByLabel('Edit Properties...').click();
|
||||
|
||||
//Edit Example Telemetry Object to include 5s loading Delay
|
||||
await page.locator('[aria-label="Loading Delay \\(ms\\)"]').fill('5000');
|
||||
@ -226,7 +225,7 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
|
||||
|
||||
// Clear Recently Viewed
|
||||
await page.getByRole('button', { name: 'Clear Recently Viewed' }).click();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
//Save localStorage for future test execution
|
||||
await context.storageState({
|
||||
path: fileURLToPath(
|
||||
|
@ -27,39 +27,33 @@ This test suite is dedicated to tests which verify branding related components.
|
||||
import { expect, test } from '../../baseFixtures.js';
|
||||
|
||||
test.describe('Branding tests', () => {
|
||||
test('About Modal launches with basic branding properties', async ({ page }) => {
|
||||
// Go to baseURL
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Click About button
|
||||
await page.click('.l-shell__app-logo');
|
||||
});
|
||||
test('About Modal launches with basic branding properties', async ({ page }) => {
|
||||
await page.getByLabel('About Modal').click();
|
||||
|
||||
// Verify that the NASA Logo Appears
|
||||
await expect(page.locator('.c-about__image')).toBeVisible();
|
||||
await expect(page.getByAltText('Open MCT Splash Logo')).toBeVisible();
|
||||
|
||||
// Modify the Build information in 'about' Modal
|
||||
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
||||
await expect(versionInformationLocator).toBeEnabled();
|
||||
await expect.soft(versionInformationLocator).toContainText(/Version: \d/);
|
||||
await expect.soft(page.getByLabel('Version Number')).toContainText(/Version: \d/);
|
||||
await expect
|
||||
.soft(versionInformationLocator)
|
||||
.soft(page.getByLabel('Build Date'))
|
||||
.toContainText(/Build Date: ((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun))/);
|
||||
await expect.soft(versionInformationLocator).toContainText(/Revision: \b[0-9a-f]{5,40}\b/);
|
||||
await expect.soft(versionInformationLocator).toContainText(/Branch: ./);
|
||||
await expect.soft(page.getByLabel('Revision')).toContainText(/Revision: \b[0-9a-f]{5,40}\b/);
|
||||
await expect.soft(page.getByLabel('Branch')).toContainText(/Branch: ./);
|
||||
});
|
||||
test('Verify Links in About Modal @2p', async ({ page }) => {
|
||||
// Go to baseURL
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Click About button
|
||||
await page.click('.l-shell__app-logo');
|
||||
await page.getByLabel('About Modal').click();
|
||||
|
||||
// Verify that clicking on the third party licenses information opens up another tab on licenses url
|
||||
const [page2] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.locator('text=click here for third party licensing information').click()
|
||||
page.getByText('click here for third party licensing information').click()
|
||||
]);
|
||||
await page2.waitForLoadState('networkidle'); //Avoids timing issues with juggler/firefox
|
||||
await page2.waitForLoadState('domcontentloaded'); //Avoids timing issues with juggler/firefox
|
||||
expect(page2.waitForURL('**/licenses**')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
@ -46,11 +46,16 @@ test.describe('Clear Data Action', () => {
|
||||
await expect(await page.locator('.c-thumb__image').count()).toBeGreaterThan(0);
|
||||
// Click the "Clear Data" menu action
|
||||
await page.getByTitle('More actions').click();
|
||||
const clearDataMenuItem = page.getByRole('menuitem', {
|
||||
name: 'Clear Data'
|
||||
});
|
||||
await expect(clearDataMenuItem).toBeEnabled();
|
||||
await clearDataMenuItem.click();
|
||||
await expect(
|
||||
page.getByRole('menuitem', {
|
||||
name: 'Clear Data for Object'
|
||||
})
|
||||
).toBeEnabled();
|
||||
await page
|
||||
.getByRole('menuitem', {
|
||||
name: 'Clear Data for Object'
|
||||
})
|
||||
.click();
|
||||
|
||||
// Verify that the background image is no longer visible
|
||||
await expect(page.locator(backgroundImageSelector)).toBeHidden();
|
||||
|
@ -38,7 +38,7 @@ test.describe('Sine Wave Generator', () => {
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click Sine Wave Generator
|
||||
await page.click('text=Sine Wave Generator');
|
||||
|
@ -41,8 +41,8 @@ test.describe('Form Validation Behavior', () => {
|
||||
//Go to baseURL
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('menuitem', { name: ' Folder' }).click();
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Folder' }).click();
|
||||
|
||||
// Fill in empty string into title and trigger validation with 'Tab'
|
||||
await page.click('text=Properties Title Notes >> input[type="text"]');
|
||||
@ -80,7 +80,7 @@ test.describe('Form File Input Behavior', () => {
|
||||
test('Can select a JSON file type', async ({ page }) => {
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await page.getByRole('button', { name: ' Create ' }).click();
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('menuitem', { name: 'JSON File Input Object' }).click();
|
||||
|
||||
await page.setInputFiles('#fileElem', jsonFilePath);
|
||||
@ -94,7 +94,7 @@ test.describe('Form File Input Behavior', () => {
|
||||
test('Can select an image file type', async ({ page }) => {
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await page.getByRole('button', { name: ' Create ' }).click();
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Image File Input Object' }).click();
|
||||
|
||||
await page.setInputFiles('#fileElem', imageFilePath);
|
||||
@ -121,7 +121,7 @@ test.describe('Persistence operations @addInit', () => {
|
||||
});
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
await page.click('text=Condition Set');
|
||||
|
||||
|
@ -107,7 +107,7 @@ test.describe('Notification Overlay', () => {
|
||||
await page.getByRole('button', { name: 'Close' }).click();
|
||||
|
||||
// On the Display Layout object, click on the "Edit" button
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await page.getByRole('button', { name: 'Edit Object' }).click();
|
||||
|
||||
// Click on the "Save" button
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
@ -69,7 +69,7 @@ test.describe('Gantt Chart', () => {
|
||||
.getByRole('dialog')
|
||||
.filter({ hasText: 'This action will replace the current Plan. Do you want to continue?' });
|
||||
await expect(replaceModal).toBeVisible();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'Ok', exact: true }).click();
|
||||
|
||||
await assertPlanActivities(page, testPlan2, ganttChart.url);
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ test.describe('Clock Generator CRUD Operations', () => {
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click Clock
|
||||
await page.getByRole('menuitem').first().click();
|
||||
|
@ -34,7 +34,6 @@ import {
|
||||
import { expect, test } from '../../../../pluginFixtures.js';
|
||||
|
||||
let conditionSetUrl;
|
||||
let getConditionSetIdentifierFromUrl;
|
||||
|
||||
test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
@ -42,7 +41,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
await page.locator('li[role="menuitem"]:has-text("Condition Set")').click();
|
||||
|
||||
@ -58,8 +57,6 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
||||
//Set object identifier from url
|
||||
conditionSetUrl = page.url();
|
||||
|
||||
getConditionSetIdentifierFromUrl = conditionSetUrl.split('/').pop().split('?')[0];
|
||||
console.debug(`getConditionSetIdentifierFromUrl: ${getConditionSetIdentifierFromUrl}`);
|
||||
await page.close();
|
||||
});
|
||||
|
||||
@ -234,7 +231,7 @@ test.describe('Basic Condition Set Use', () => {
|
||||
await page.goto(conditionSet.url);
|
||||
|
||||
// Change the object to edit mode
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Click Add Condition button
|
||||
await page.locator('#addCondition').click();
|
||||
@ -262,7 +259,7 @@ test.describe('Basic Condition Set Use', () => {
|
||||
await page.goto(conditionSet.url);
|
||||
|
||||
// Change the object to edit mode
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
page.click('button[title="Show selected item in tree"]');
|
||||
@ -299,7 +296,7 @@ test.describe('Basic Condition Set Use', () => {
|
||||
await page.getByTitle('Show selected item in tree').click();
|
||||
await page.goto(conditionSet.url);
|
||||
// Change the object to edit mode
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Create two conditions
|
||||
await page.locator('#addCondition').click();
|
||||
|
@ -47,7 +47,7 @@ test.describe('Display Layout Toolbar Actions @localStorage', () => {
|
||||
.filter({ hasText: 'Parent Display Layout Display Layout' })
|
||||
.first()
|
||||
.click();
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
});
|
||||
test.use({
|
||||
storageState: LOCALSTORAGE_PATH
|
||||
@ -133,7 +133,7 @@ test.describe('Display Layout', () => {
|
||||
name: 'Test Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -171,7 +171,7 @@ test.describe('Display Layout', () => {
|
||||
name: 'Test Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -213,7 +213,7 @@ test.describe('Display Layout', () => {
|
||||
name: 'Test Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -255,7 +255,7 @@ test.describe('Display Layout', () => {
|
||||
type: 'Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -301,7 +301,7 @@ test.describe('Display Layout', () => {
|
||||
type: 'Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -357,7 +357,7 @@ test.describe('Display Layout', () => {
|
||||
name: 'Test Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -449,7 +449,7 @@ async function removeLayoutObject(page, layoutObject) {
|
||||
// eslint-disable-next-line playwright/no-force-option
|
||||
.click({ force: true });
|
||||
await page.getByTitle('Delete the selected object').click();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +73,7 @@ test.describe('Flexible Layout', () => {
|
||||
}) => {
|
||||
await page.goto(flexibleLayout.url);
|
||||
// Edit Flexible Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
|
||||
@ -166,7 +166,7 @@ test.describe('Flexible Layout', () => {
|
||||
}) => {
|
||||
await page.goto(flexibleLayout.url);
|
||||
// Edit Flexible Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
|
||||
@ -197,7 +197,7 @@ test.describe('Flexible Layout', () => {
|
||||
});
|
||||
await page.goto(flexibleLayout.url);
|
||||
// Edit Flexible Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -234,7 +234,7 @@ test.describe('Flexible Layout', () => {
|
||||
|
||||
await page.goto(flexibleLayout.url);
|
||||
// Edit Flexible Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -276,7 +276,7 @@ test.describe('Flexible Layout Toolbar Actions @localStorage', () => {
|
||||
.filter({ hasText: 'Parent Flexible Layout Flexible Layout' })
|
||||
.first()
|
||||
.click();
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
});
|
||||
test('Add/Remove Container', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
@ -293,7 +293,7 @@ test.describe('Flexible Layout Toolbar Actions @localStorage', () => {
|
||||
await expect(page.getByRole('dialog', { name: 'Overlay' })).toHaveText(
|
||||
'This action will permanently delete this container from this Flexible Layout. Do you want to continue?'
|
||||
);
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
expect(await containerHandles.count()).toEqual(2);
|
||||
});
|
||||
test('Remove Frame', async ({ page }) => {
|
||||
@ -303,7 +303,7 @@ test.describe('Flexible Layout Toolbar Actions @localStorage', () => {
|
||||
await expect(page.getByRole('dialog', { name: 'Overlay' })).toHaveText(
|
||||
'This action will remove this frame from this Flexible Layout. Do you want to continue?'
|
||||
);
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
expect(await page.getByRole('group', { name: 'Frame' }).count()).toEqual(1);
|
||||
});
|
||||
test('Columns/Rows Layout Toggle', async ({ page }) => {
|
||||
|
@ -41,8 +41,6 @@ test.describe('Gauge', () => {
|
||||
test('Can add and remove telemetry sources @unstable', async ({ page }) => {
|
||||
// Create the gauge with defaults
|
||||
const gauge = await createDomainObjectWithDefaults(page, { type: 'Gauge' });
|
||||
const editButtonLocator = page.locator('button[title="Edit"]');
|
||||
const saveButtonLocator = page.locator('button[title="Save"]');
|
||||
|
||||
// Create a sine wave generator within the gauge
|
||||
const swg1 = await createDomainObjectWithDefaults(page, {
|
||||
@ -54,9 +52,9 @@ test.describe('Gauge', () => {
|
||||
// Navigate to the gauge and verify that
|
||||
// the SWG appears in the elements pool
|
||||
await page.goto(gauge.url);
|
||||
await editButtonLocator.click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeVisible();
|
||||
await saveButtonLocator.click();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
|
||||
// Create another sine wave generator within the gauge
|
||||
@ -79,10 +77,10 @@ test.describe('Gauge', () => {
|
||||
// Navigate to the gauge and verify that the new SWG
|
||||
// appears in the elements pool and the old one is gone
|
||||
await page.goto(gauge.url);
|
||||
await editButtonLocator.click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeHidden();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg2.name}`)).toBeVisible();
|
||||
await saveButtonLocator.click();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
// Right click on the new SWG in the elements pool and delete it
|
||||
await page.locator(`#inspector-elements-tree >> text=${swg2.name}`).click({
|
||||
@ -109,7 +107,7 @@ test.describe('Gauge', () => {
|
||||
description: 'https://github.com/nasa/openmct/issues/5356'
|
||||
});
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click the object specified by 'type'
|
||||
await page.click(`li[role='menuitem']:text("Gauge")`);
|
||||
|
@ -61,7 +61,7 @@ test.describe('Example Imagery Object', () => {
|
||||
await expect(page.locator('.c-hud')).toBeHidden();
|
||||
});
|
||||
|
||||
test('Can right click on image and open it in a new tab', async ({ page, context }) => {
|
||||
test('Can right click on image and open it in a new tab @2p', async ({ page, context }) => {
|
||||
// try to right click on image
|
||||
const backgroundImage = await page.locator(backgroundImageSelector);
|
||||
await backgroundImage.click({
|
||||
@ -397,7 +397,7 @@ test.describe('Example Imagery in Display Layout', () => {
|
||||
});
|
||||
|
||||
// Edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Click on example imagery to expose toolbar
|
||||
await page.locator('.c-so-view__header').click();
|
||||
@ -416,7 +416,7 @@ test.describe('Example Imagery in Display Layout', () => {
|
||||
test('Resizing the layout changes thumbnail visibility and size', async ({ page }) => {
|
||||
const thumbsWrapperLocator = page.locator('.c-imagery__thumbs-wrapper');
|
||||
// Edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Click on example imagery to expose toolbar
|
||||
await page.locator('.c-so-view__header').click();
|
||||
@ -493,7 +493,7 @@ test.describe('Example Imagery in Flexible layout', () => {
|
||||
|
||||
/* Create Sine Wave Generator with minimum Image Load Delay */
|
||||
// Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click text=Example Imagery
|
||||
await page.click('li[role="menuitem"]:has-text("Example Imagery")');
|
||||
@ -537,7 +537,7 @@ test.describe('Example Imagery in Tabs View', () => {
|
||||
|
||||
/* Create Sine Wave Generator with minimum Image Load Delay */
|
||||
// Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click text=Example Imagery
|
||||
await page.click('li[role="menuitem"]:has-text("Example Imagery")');
|
||||
@ -984,7 +984,7 @@ async function resetImageryPanAndZoom(page) {
|
||||
*/
|
||||
async function createImageryView(page) {
|
||||
// Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click text=Example Imagery
|
||||
await page.click('li[role="menuitem"]:has-text("Example Imagery")');
|
||||
|
@ -52,7 +52,7 @@ test.describe('Testing LAD table configuration', () => {
|
||||
});
|
||||
test('in edit mode, LAD Tables provide ability to hide columns', async ({ page }) => {
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.getByRole('tab', { name: 'LAD Table Configuration' }).click();
|
||||
|
||||
// make sure headers are visible initially
|
||||
@ -113,7 +113,7 @@ test.describe('Testing LAD table configuration', () => {
|
||||
await expect(page.getByRole('cell', { name: 'SEVERE' })).toBeVisible();
|
||||
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.getByRole('tab', { name: 'LAD Table Configuration' }).click();
|
||||
|
||||
// show timestamp column
|
||||
@ -141,7 +141,7 @@ test.describe('Testing LAD table configuration', () => {
|
||||
await expect(page.getByRole('cell', { name: 'SEVERE' })).toBeVisible();
|
||||
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.getByRole('tab', { name: 'LAD Table Configuration' }).click();
|
||||
|
||||
// show units, type, and WATCH columns
|
||||
@ -181,7 +181,7 @@ test.describe('Testing LAD table configuration', () => {
|
||||
await page.goto(ladTable.url);
|
||||
|
||||
// Edit LAD table
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.getByRole('tab', { name: 'LAD Table Configuration' }).click();
|
||||
|
||||
// make sure Sine Wave headers are visible initially too
|
||||
@ -198,10 +198,10 @@ test.describe('Testing LAD table configuration', () => {
|
||||
await page.getByLabel('Save').click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
|
||||
// Remove Sin Wave Generator
|
||||
// Remove Sine Wave Generator
|
||||
openObjectTreeContextMenu(page, sineWaveObject.url);
|
||||
await page.getByRole('menuitem', { name: /Remove/ }).click();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// Ensure Units & Limit columns are gone
|
||||
// as Event Generator don't have them
|
||||
@ -258,7 +258,7 @@ test.describe('Testing LAD table @unstable', () => {
|
||||
name: 'Test LAD Table'
|
||||
});
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
@ -286,7 +286,7 @@ test.describe('Testing LAD table @unstable', () => {
|
||||
name: 'Test LAD Table'
|
||||
});
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the 'My Items' folder in the left tree
|
||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
|
||||
|
@ -89,10 +89,15 @@ test.describe('Snapshot Container tests', () => {
|
||||
// name: "Dropped Overlay Plot"
|
||||
// });
|
||||
|
||||
await page.getByRole('button', { name: ' Snapshot ' }).click();
|
||||
await page.getByRole('menuitem', { name: ' Save to Notebook Snapshots' }).click();
|
||||
await page.getByLabel('Take a Notebook Snapshot').click();
|
||||
await page.getByRole('menuitem', { name: 'Save to Notebook Snapshots' }).click();
|
||||
await page.getByRole('button', { name: 'Show' }).click();
|
||||
});
|
||||
test('A snapshot can be Quick Viewed from Container with 3 dot action menu', async ({ page }) => {
|
||||
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More actions').click();
|
||||
await page.getByRole('menuitem', { name: 'Quick View' }).click();
|
||||
await expect(page.locator('.c-overlay__outer')).toBeVisible();
|
||||
});
|
||||
test.fixme('5 Snapshots can be added to a container', async ({ page }) => {});
|
||||
test.fixme(
|
||||
'5 Snapshots can be added to a container and Deleted with Delete All action',
|
||||
@ -117,11 +122,7 @@ test.describe('Snapshot Container tests', () => {
|
||||
//await expect(await page.locator)
|
||||
}
|
||||
);
|
||||
test('A snapshot can be Quick Viewed from Container with 3 dot action menu', async ({ page }) => {
|
||||
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More actions').click();
|
||||
await page.getByRole('menuitem', { name: 'Quick View' }).click();
|
||||
await expect(page.locator('.c-overlay__outer')).toBeVisible();
|
||||
});
|
||||
|
||||
test.fixme(
|
||||
'A snapshot can be Navigated To from Container with 3 dot action menu',
|
||||
async ({ page }) => {}
|
||||
|
@ -128,7 +128,7 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
||||
});
|
||||
|
||||
// Go back into edit mode for the display layout
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await page.getByRole('button', { name: 'Edit Object' }).click();
|
||||
|
||||
await page.getByRole('search').getByLabel('Search Input').click();
|
||||
await page.getByRole('search').getByLabel('Search Input').fill('Sc');
|
||||
|
@ -58,7 +58,7 @@ test.describe('Autoscale', () => {
|
||||
await testYTicks(page, ['-1.00', '-0.50', '0.00', '0.50', '1.00']);
|
||||
|
||||
// enter edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Config' }).click();
|
||||
await turnOffAutoscale(page);
|
||||
|
@ -183,7 +183,7 @@ async function testLogTicks(page) {
|
||||
*/
|
||||
async function enableEditMode(page) {
|
||||
// turn on edit mode
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await page.getByRole('button', { name: 'Edit Object' }).click();
|
||||
await expect(page.getByRole('button', { name: 'Save' })).toBeVisible();
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ test.describe('Overlay Plot', () => {
|
||||
expect(await page.locator('.c-plot-limit-line').count()).toBe(0);
|
||||
|
||||
// Enter edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
||||
await page.getByRole('tab', { name: 'Config' }).click();
|
||||
@ -114,7 +114,7 @@ test.describe('Overlay Plot', () => {
|
||||
await assertLimitLinesExistAndAreVisible(page);
|
||||
|
||||
// Enter edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
|
||||
@ -165,7 +165,7 @@ test.describe('Overlay Plot', () => {
|
||||
});
|
||||
|
||||
await page.goto(overlayPlot.url);
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
|
||||
@ -239,7 +239,7 @@ test.describe('Overlay Plot', () => {
|
||||
await page.goto(overlayPlot.url);
|
||||
// Wait for plot series data to load and be drawn
|
||||
await waitForPlotsToRender(page);
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
|
||||
|
@ -41,9 +41,6 @@ test.describe('Scatter Plot', () => {
|
||||
});
|
||||
|
||||
test('Can add and remove telemetry sources', async ({ page }) => {
|
||||
const editButton = page.locator('button[title="Edit"]');
|
||||
const saveButton = page.locator('button[title="Save"]');
|
||||
|
||||
// Create a sine wave generator within the scatter plot
|
||||
const swg1 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
@ -54,10 +51,10 @@ test.describe('Scatter Plot', () => {
|
||||
// Navigate to the scatter plot and verify that
|
||||
// the SWG appears in the elements pool
|
||||
await page.goto(scatterPlot.url);
|
||||
await editButton.click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeVisible();
|
||||
await saveButton.click();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
|
||||
// Create another sine wave generator within the scatter plot
|
||||
@ -80,13 +77,13 @@ test.describe('Scatter Plot', () => {
|
||||
// Navigate to the scatter plot and verify that the new SWG
|
||||
// appears in the elements pool and the old one is gone
|
||||
await page.goto(scatterPlot.url);
|
||||
await editButton.click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Click the "Elements" tab
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeHidden();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg2.name}`)).toBeVisible();
|
||||
await saveButton.click();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
// Right click on the new SWG in the elements pool and delete it
|
||||
await page.locator(`#inspector-elements-tree >> text=${swg2.name}`).click({
|
||||
|
@ -69,7 +69,7 @@ test.describe('Stacked Plot', () => {
|
||||
|
||||
await page.goto(stackedPlot.url);
|
||||
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
|
||||
@ -101,7 +101,7 @@ test.describe('Stacked Plot', () => {
|
||||
|
||||
await page.goto(stackedPlot.url);
|
||||
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Elements' }).click();
|
||||
|
||||
@ -187,7 +187,7 @@ test.describe('Stacked Plot', () => {
|
||||
).toContainText(swgC.name);
|
||||
|
||||
// Go into edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Config' }).click();
|
||||
|
||||
@ -231,8 +231,10 @@ test.describe('Stacked Plot', () => {
|
||||
test('the legend toggles between aggregate and per child', async ({ page }) => {
|
||||
await page.goto(stackedPlot.url);
|
||||
|
||||
await waitForPlotsToRender(page);
|
||||
|
||||
// Go into edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Config' }).click();
|
||||
|
||||
@ -245,10 +247,14 @@ test.describe('Stacked Plot', () => {
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
|
||||
await waitForPlotsToRender(page);
|
||||
|
||||
await assertAggregateLegendIsVisible(page);
|
||||
|
||||
await page.reload();
|
||||
|
||||
await waitForPlotsToRender(page);
|
||||
|
||||
await assertAggregateLegendIsVisible(page);
|
||||
});
|
||||
});
|
||||
|
@ -72,7 +72,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
@ -133,7 +133,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
@ -210,7 +210,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit stackedPlot
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
|
||||
@ -231,7 +231,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
@ -296,7 +296,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
@ -345,7 +345,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
@ -375,7 +375,7 @@ test.describe('Flexible Layout styling', () => {
|
||||
await page.reload({ waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
|
@ -74,7 +74,7 @@ test.describe('Stacked Plot styling', () => {
|
||||
// Directly navigate to the stacked plot
|
||||
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
|
||||
@ -165,7 +165,7 @@ test.describe('Stacked Plot styling', () => {
|
||||
});
|
||||
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
|
||||
|
@ -49,7 +49,7 @@ test.describe('Style Inspector Options', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// The overall Flex Layout or Stacked Plot itself MUST be style-able.
|
||||
await expect(page.getByRole('tab', { name: 'Styles' })).toBeVisible();
|
||||
|
@ -128,7 +128,10 @@ test.describe('Telemetry Table', () => {
|
||||
// focus the Telemetry Table
|
||||
page.goto(table.url);
|
||||
await page.getByRole('searchbox', { name: 'message filter input' }).hover();
|
||||
await page.getByLabel('Message filter header').getByRole('button', { name: '/R/' }).click();
|
||||
await page
|
||||
.getByLabel('Message filter header')
|
||||
.getByLabel('Click to enable regex: enter a string with slashes, like this: /regex_exp/')
|
||||
.click();
|
||||
await page.getByRole('searchbox', { name: 'message filter input' }).click();
|
||||
await page.getByRole('searchbox', { name: 'message filter input' }).fill('/[Rr]oger/');
|
||||
|
||||
|
@ -104,7 +104,7 @@ test.describe('Recent Objects', () => {
|
||||
button: 'right'
|
||||
});
|
||||
await page.getByRole('menuitem', { name: /Remove/ }).click();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// Verify that the folder and clock are no longer in the recent objects list
|
||||
await expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeHidden();
|
||||
@ -293,7 +293,7 @@ test.describe('Recent Objects', () => {
|
||||
await page.getByRole('button', { name: 'Clear Recently Viewed' }).click();
|
||||
|
||||
// Click on the "OK" button in the confirmation dialog
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// Assert that the list is empty
|
||||
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(0);
|
||||
@ -311,7 +311,7 @@ test.describe('Recent Objects', () => {
|
||||
await page.getByRole('button', { name: 'Clear Recently Viewed' }).click();
|
||||
|
||||
// Click on the "OK" button in the confirmation dialog
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// Assert that the list is empty
|
||||
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(0);
|
||||
|
@ -49,7 +49,7 @@ test.describe('Grand Search', () => {
|
||||
const createdObjects = await createObjectsForSearch(page);
|
||||
|
||||
// Go back into edit mode for the display layout
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await page.getByRole('button', { name: 'Edit Object' }).click();
|
||||
|
||||
await grandSearchInput.click();
|
||||
await grandSearchInput.fill('Cl');
|
||||
|
@ -42,7 +42,7 @@ test('Verify that the create button appears and that the Folder Domain Object is
|
||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Verify that Create Folder appears in the dropdown
|
||||
await expect(page.locator(':nth-match(:text("Folder"), 2)')).toBeEnabled();
|
||||
|
@ -96,7 +96,7 @@ test.describe('Verify tooltips', () => {
|
||||
name: 'Test LAD Table'
|
||||
});
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Add the Sine Wave Generator to the LAD table and save changes
|
||||
await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.c-lad-table-wrapper');
|
||||
@ -126,7 +126,7 @@ test.describe('Verify tooltips', () => {
|
||||
name: 'Test Overlay Plots'
|
||||
});
|
||||
// Edit Overlay Plot
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Add the Sine Wave Generator to the LAD table and save changes
|
||||
await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.gl-plot');
|
||||
@ -197,7 +197,7 @@ test.describe('Verify tooltips', () => {
|
||||
name: 'Test Overlay Plot'
|
||||
});
|
||||
// Edit Overlay Plot
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.gl-plot');
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
@ -208,7 +208,7 @@ test.describe('Verify tooltips', () => {
|
||||
name: 'Test Stacked Plot'
|
||||
});
|
||||
// Edit Stacked Plot
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.dragAndDrop(`text=${sineWaveObject2.name}`, '.c-plot--stacked.holder');
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
@ -219,7 +219,7 @@ test.describe('Verify tooltips', () => {
|
||||
name: 'Test Display Layout'
|
||||
});
|
||||
// Edit Display Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
await page.dragAndDrop("text='Test Overlay Plot'", '.l-layout__grid-holder', {
|
||||
targetPosition: { x: 0, y: 0 }
|
||||
@ -428,7 +428,7 @@ test.describe('Verify tooltips', () => {
|
||||
name: 'Test Time Strip'
|
||||
});
|
||||
// Edit Overlay Plot
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
await page.dragAndDrop(
|
||||
`text=${sineWaveObject1.name}`,
|
||||
'.c-object-view.is-object-type-time-strip'
|
||||
|
@ -26,10 +26,10 @@ Tests the branding associated with the default deployment. At least the about mo
|
||||
|
||||
import percySnapshot from '@percy/playwright';
|
||||
|
||||
import { expect, scanForA11yViolations, test } from '../../../avpFixtures.js';
|
||||
import { VISUAL_URL } from '../../../constants.js';
|
||||
import { expect, test } from '../../../pluginFixtures.js';
|
||||
|
||||
test.describe('Visual - Branding', () => {
|
||||
test.describe('Visual - Branding @a11y', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
//Go to baseURL and Hide Tree
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
@ -37,18 +37,22 @@ test.describe('Visual - Branding', () => {
|
||||
|
||||
test('Visual - About Modal', async ({ page, theme }) => {
|
||||
// Click About button
|
||||
await page.click('.l-shell__app-logo');
|
||||
await page.getByLabel('About Modal').click();
|
||||
|
||||
// Modify the Build information in 'about' to be consistent run-over-run
|
||||
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
||||
await expect(versionInformationLocator).toBeEnabled();
|
||||
await versionInformationLocator.evaluate(
|
||||
(node) =>
|
||||
(node.innerHTML =
|
||||
'<li>Version: visual-snapshot</li> <li>Build Date: Mon Nov 15 2021 08:07:51 GMT-0800 (Pacific Standard Time)</li> <li>Revision: 93049cdbc6c047697ca204893db9603b864b8c9f</li> <li>Branch: master</li>')
|
||||
);
|
||||
await expect(page.locator('id=versionInformation')).toBeEnabled();
|
||||
await page
|
||||
.locator('id=versionInformation')
|
||||
.evaluate(
|
||||
(node) =>
|
||||
(node.innerHTML =
|
||||
'<li>Version: visual-snapshot</li> <li>Build Date: Mon Nov 15 2021 08:07:51 GMT-0800 (Pacific Standard Time)</li> <li>Revision: 93049cdbc6c047697ca204893db9603b864b8c9f</li> <li>Branch: master</li>')
|
||||
);
|
||||
|
||||
// Take a snapshot of the About modal
|
||||
await percySnapshot(page, `About (theme: '${theme}')`);
|
||||
});
|
||||
});
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await scanForA11yViolations(page, testInfo.title);
|
||||
});
|
||||
|
56
e2e/tests/visual-a11y/components/header.visual.spec.js
Normal file
56
e2e/tests/visual-a11y/components/header.visual.spec.js
Normal file
@ -0,0 +1,56 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2024, 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Tests the branding associated with the default deployment. At least the about modal for now
|
||||
*/
|
||||
|
||||
import percySnapshot from '@percy/playwright';
|
||||
|
||||
import { scanForA11yViolations, test } from '../../../avpFixtures.js';
|
||||
import { VISUAL_URL } from '../../../constants.js';
|
||||
|
||||
//Declare the scope of the visual test
|
||||
const header = '.l-shell__head';
|
||||
|
||||
test.describe('Visual - Header @a11y', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
//Go to baseURL and Hide Tree
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
});
|
||||
|
||||
test('header sizing', async ({ page, theme }) => {
|
||||
// Click About button
|
||||
await percySnapshot(page, `Header default (theme: '${theme}')`, {
|
||||
scope: header
|
||||
});
|
||||
|
||||
await page.getByLabel('Click to collapse items').click();
|
||||
|
||||
await percySnapshot(page, `Header Collapsed (theme: '${theme}')`, {
|
||||
scope: header
|
||||
});
|
||||
});
|
||||
});
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await scanForA11yViolations(page, testInfo.title);
|
||||
});
|
@ -22,13 +22,13 @@
|
||||
|
||||
import percySnapshot from '@percy/playwright';
|
||||
|
||||
import { scanForA11yViolations, test } from '../../../avpFixtures.js';
|
||||
import { MISSION_TIME, VISUAL_URL } from '../../../constants.js';
|
||||
import { test } from '../../../pluginFixtures.js';
|
||||
|
||||
//Declare the scope of the visual test
|
||||
const inspectorPane = '.l-shell__pane-inspector';
|
||||
|
||||
test.describe('Visual - Controlled Clock', () => {
|
||||
test.describe('Visual - Inspector @ally', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
});
|
||||
@ -55,3 +55,6 @@ test.describe('Visual - Controlled Clock', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await scanForA11yViolations(page, testInfo.title);
|
||||
});
|
||||
|
@ -89,6 +89,9 @@ test.describe('Visual - Tree Pane', () => {
|
||||
await expandTreePaneItemByName(page, bar.name);
|
||||
await expandTreePaneItemByName(page, baz.name);
|
||||
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1 * 1000); //https://github.com/nasa/openmct/issues/7059
|
||||
|
||||
await percySnapshot(page, `Tree Pane w/ multiple levels expanded (theme: ${theme})`, {
|
||||
scope: treePane
|
||||
});
|
||||
|
@ -44,14 +44,15 @@ test.describe('Visual - Controlled Clock', () => {
|
||||
|
||||
test('Overlay Plot Loading Indicator @localStorage', async ({ page, theme }) => {
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
await page.locator('a').filter({ hasText: 'Overlay Plot with 5s Delay' }).click();
|
||||
await page
|
||||
.getByRole('gridcell', { hasText: 'Overlay Plot with 5s Delay Overlay Plot' })
|
||||
.click();
|
||||
//Ensure that we're on the Unnamed Overlay Plot object
|
||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText(
|
||||
'Overlay Plot with 5s Delay'
|
||||
);
|
||||
await expect(page.getByRole('main')).toContainText('Overlay Plot with 5s Delay');
|
||||
|
||||
//Wait for canvas to be rendered and stop animating, but plot should not be loaded. Cannot use waitForPlotsToRender
|
||||
await page.locator('canvas >> nth=1').hover({ trial: true });
|
||||
//Wait for canvas to be rendered and stop animating, but plot should not be loaded.
|
||||
//Cannot use waitForPlotsToRender due to clockOptions.
|
||||
await page.locator('#webglContext').hover({ trial: true });
|
||||
|
||||
//Take snapshot of Sine Wave Generator within Overlay Plot
|
||||
await percySnapshot(page, `SineWaveInOverlayPlot (theme: '${theme}')`);
|
||||
|
@ -39,7 +39,7 @@ test.describe('Visual - Default @a11y', () => {
|
||||
|
||||
test('Visual - Default Dashboard', async ({ page, theme }) => {
|
||||
// Verify that Create button is actionable
|
||||
await expect(page.locator('button:has-text("Create")')).toBeEnabled();
|
||||
await expect(page.getByRole('button', { name: 'Create' })).toBeEnabled();
|
||||
|
||||
// Take a snapshot of the Dashboard
|
||||
await percySnapshot(page, `Default Dashboard (theme: '${theme}')`);
|
||||
@ -66,27 +66,22 @@ test.describe('Visual - Default @a11y', () => {
|
||||
});
|
||||
|
||||
test('Visual - Sine Wave Generator Form', async ({ page, theme }) => {
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Click text=Sine Wave Generator
|
||||
await page.click('text=Sine Wave Generator');
|
||||
await page.getByRole('menuItem', { name: 'Sine Wave Generator' }).click();
|
||||
|
||||
await percySnapshot(page, `Default Sine Wave Generator Form (theme: '${theme}')`);
|
||||
|
||||
await page.locator('.field.control.l-input-sm input').first().click();
|
||||
await page.locator('.field.control.l-input-sm input').first().fill('');
|
||||
await page.getByLabel('Period').click();
|
||||
await page.getByLabel('Period').fill('');
|
||||
|
||||
// Validate red x mark
|
||||
await percySnapshot(page, `removed amplitude property value (theme: '${theme}')`);
|
||||
});
|
||||
|
||||
test('Visual - Display Layout Icon is correct in Create Menu', async ({ page, theme }) => {
|
||||
// Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Hover on Display Layout option.
|
||||
await page.locator('text=Display Layout').hover();
|
||||
await page.getByRole('menuItem', { name: 'Display Layout' }).hover({ trial: true });
|
||||
await percySnapshot(page, `Display Layout Create Menu (theme: '${theme}')`);
|
||||
});
|
||||
|
||||
|
@ -20,138 +20,77 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Defines playwright locators that can be used in tests.
|
||||
* @typedef {Object} LayoutLocators
|
||||
* @property {Object<string, import('@playwright/test').Locator>} LayoutLocator
|
||||
*/
|
||||
|
||||
import percySnapshot from '@percy/playwright';
|
||||
|
||||
import { createDomainObjectWithDefaults } from '../../appActions.js';
|
||||
import { VISUAL_URL } from '../../constants.js';
|
||||
import { test } from '../../pluginFixtures.js';
|
||||
const snapshotScope = '.l-shell__pane-main .l-pane__contents';
|
||||
|
||||
test.describe('Visual - Display Layout', () => {
|
||||
test('Resize Marquee surrounds selection', async ({ page, theme }) => {
|
||||
const baseline = await setupBaseline(page);
|
||||
const { child1LayoutLocator, child1LayoutObjectLocator } = baseline;
|
||||
test.beforeEach(async ({ page, theme }) => {
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await percySnapshot(page, `Resize nested layout selected (theme: '${theme}')`, {
|
||||
scope: snapshotScope
|
||||
const parentLayout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Parent Layout'
|
||||
});
|
||||
const child2Layout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Child Left Layout',
|
||||
parent: parentLayout.uuid
|
||||
});
|
||||
//Create this layout second so that it is on top for the position change
|
||||
const child1Layout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Child Right Layout',
|
||||
parent: parentLayout.uuid
|
||||
});
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: 'SWG 1',
|
||||
parent: child1Layout.uuid
|
||||
});
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: 'SWG 2',
|
||||
parent: child2Layout.uuid
|
||||
});
|
||||
|
||||
await child1LayoutLocator.click();
|
||||
await percySnapshot(page, `Resize new nested layout selected (theme: '${theme}')`, {
|
||||
scope: snapshotScope
|
||||
});
|
||||
await page.goto(parentLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
await page.getByRole('button', { name: 'Edit Object' }).click();
|
||||
|
||||
await child1LayoutObjectLocator.click();
|
||||
await percySnapshot(page, `Resize Object in nested layout selected (theme: '${theme}')`, {
|
||||
scope: snapshotScope
|
||||
});
|
||||
//Move the Child Right Layout to the Right. It should be on top of the Left Layout at this point.
|
||||
await page
|
||||
.getByLabel('Child Right Layout Layout', { exact: true })
|
||||
.getByLabel('Move Sub-object Frame')
|
||||
.click();
|
||||
await page.getByLabel('Move Sub-object Frame').nth(3).click(); //I'm not sure why this step is necessary
|
||||
await page.getByLabel('X:').click();
|
||||
await page.getByLabel('X:').fill('35');
|
||||
});
|
||||
|
||||
test('Parent layout of selection displays grid', async ({ page, theme }) => {
|
||||
const baseline = await setupBaseline(page);
|
||||
const { parentLayoutLocator, child1LayoutObjectLocator } = baseline;
|
||||
test('Resize Marquee surrounds selection', async ({ page, theme }) => {
|
||||
//This is where the beforeEach leaves off.
|
||||
await percySnapshot(page, `Last modified object selected (theme: '${theme}')`);
|
||||
|
||||
await percySnapshot(page, `Parent nested layout selected (theme: '${theme}')`, {
|
||||
scope: snapshotScope
|
||||
});
|
||||
await page.getByLabel('Child Left Layout Layout', { exact: true }).click();
|
||||
await percySnapshot(page, `Only Left Child Layout has Marque selection (theme: '${theme}')`);
|
||||
|
||||
await parentLayoutLocator.click();
|
||||
await percySnapshot(page, `Parent outer layout selected (theme: '${theme}')`, {
|
||||
scope: snapshotScope
|
||||
});
|
||||
await page.getByLabel('Child Right Layout Layout', { exact: true }).click();
|
||||
await percySnapshot(page, `Only Right Child Layout has Marque selection (theme: '${theme}')`);
|
||||
|
||||
await child1LayoutObjectLocator.click();
|
||||
await percySnapshot(page, `Parent Object in nested layout selected (theme: '${theme}')`, {
|
||||
scope: snapshotScope
|
||||
});
|
||||
//Only the sub-object in the Right Layout should be highlighted with a marquee
|
||||
await page
|
||||
.getByLabel('Child Right Layout Layout', { exact: true })
|
||||
.getByLabel('Move Sub-object Frame')
|
||||
.click();
|
||||
|
||||
await percySnapshot(
|
||||
page,
|
||||
`Selecting a sub-object from Right Layout selected (theme: '${theme}')`
|
||||
);
|
||||
|
||||
await page.getByLabel('Parent Layout Layout', { exact: true }).click();
|
||||
await percySnapshot(page, `Parent outer layout selected (theme: '${theme}')`);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets up a complex layout with nested layouts and provides the playwright locators
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @returns {LayoutLocators} locators of baseline complex display to be used in tests
|
||||
*/
|
||||
async function setupBaseline(page) {
|
||||
// Load Open MCT visual test baseline
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
// Open Tree
|
||||
await page.getByRole('button', { name: 'Browse' }).click();
|
||||
|
||||
const treePane = page.getByRole('tree', {
|
||||
name: 'Main Tree'
|
||||
});
|
||||
|
||||
const objectViewLocator = page.locator('.c-object-view');
|
||||
const parentLayoutLocator = objectViewLocator.first();
|
||||
const child1LayoutLocator = parentLayoutLocator.locator(objectViewLocator).first();
|
||||
const child1LayoutObjectLocator = child1LayoutLocator.locator('.l-layout__frame');
|
||||
const parentLayout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Parent Layout'
|
||||
});
|
||||
const child1Layout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Child 1 Layout'
|
||||
});
|
||||
const child2Layout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: 'Child 2 Layout'
|
||||
});
|
||||
const swg1 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: 'SWG 1'
|
||||
});
|
||||
const swg2 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: 'SWG 2'
|
||||
});
|
||||
const child1LayoutTreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(child1Layout.name)
|
||||
});
|
||||
const child2LayoutTreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(child2Layout.name)
|
||||
});
|
||||
const swg1TreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(swg1.name)
|
||||
});
|
||||
const swg2TreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(swg2.name)
|
||||
});
|
||||
|
||||
// Expand folder containing created objects
|
||||
await page.goto(parentLayout.url);
|
||||
await page.getByTitle('Show selected item in tree').click();
|
||||
|
||||
// Add swg1 to child1Layout
|
||||
await page.goto(child1Layout.url);
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await swg1TreeItem.dragTo(parentLayoutLocator, { targetPosition: { x: 0, y: 0 } });
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
|
||||
// Add swg1 to child1Layout
|
||||
await page.goto(child2Layout.url);
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await swg2TreeItem.dragTo(parentLayoutLocator, { targetPosition: { x: 0, y: 0 } });
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||
|
||||
// Add child1Layout and child2Layout to parentLayout
|
||||
await page.goto(parentLayout.url);
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await child1LayoutTreeItem.dragTo(parentLayoutLocator, { targetPosition: { x: 350, y: 0 } });
|
||||
await child2LayoutTreeItem.dragTo(parentLayoutLocator, { targetPosition: { x: 0, y: 0 } });
|
||||
|
||||
return {
|
||||
parentLayoutLocator,
|
||||
child1LayoutLocator,
|
||||
child1LayoutObjectLocator
|
||||
};
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import { VISUAL_URL } from '../../constants.js';
|
||||
import { expect, test } from '../../pluginFixtures.js';
|
||||
|
||||
test.describe('Visual - LAD Table', () => {
|
||||
/** @type {import('@playwright/test').Locator} */
|
||||
let ladTable;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
@ -46,9 +45,9 @@ test.describe('Visual - LAD Table', () => {
|
||||
});
|
||||
|
||||
//Modify SWG to create a really stable SWG
|
||||
await page.locator('button[title="More actions"]').click();
|
||||
await page.getByRole('button', { name: 'More actions' }).click();
|
||||
|
||||
await page.getByRole('menuitem', { name: ' Edit Properties...' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Edit Properties...' }).click();
|
||||
|
||||
//Forgive me, padre
|
||||
await page.getByRole('spinbutton', { name: 'Data Rate (hz)' }).fill('0');
|
||||
@ -57,18 +56,18 @@ test.describe('Visual - LAD Table', () => {
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
});
|
||||
test('Toggled column widths behave accordingly', async ({ page, theme }) => {
|
||||
await page.goto(ladTable.url);
|
||||
await page.goto(ladTable.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
await expect(page.locator('button[title="Expand Columns"]')).toBeVisible();
|
||||
await expect(page.getByLabel('Expand Columns')).toBeVisible();
|
||||
|
||||
await percySnapshot(
|
||||
page,
|
||||
`LAD Table w/ Sine Wave Generator columns autosized (theme: ${theme})`
|
||||
);
|
||||
|
||||
await page.locator('button[title="Expand Columns"]').click();
|
||||
await page.getByLabel('Expand Columns').click();
|
||||
|
||||
await expect(page.locator('button[title="Autosize Columns"]')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Autosize Columns' })).toBeVisible();
|
||||
|
||||
await percySnapshot(
|
||||
page,
|
||||
|
@ -26,43 +26,54 @@
|
||||
|
||||
import percySnapshot from '@percy/playwright';
|
||||
|
||||
import { createDomainObjectWithDefaults } from '../../appActions.js';
|
||||
import { createNotification } from '../../appActions.js';
|
||||
import { expect, scanForA11yViolations, test } from '../../avpFixtures.js';
|
||||
import { VISUAL_URL } from '../../constants.js';
|
||||
|
||||
test.describe("Visual - Check Notification Info Banner of 'Save successful' @a11y", () => {
|
||||
test.describe('Visual - Notifications @a11y', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
});
|
||||
|
||||
test("Create a clock, click on 'Save successful' banner and dismiss it", async ({
|
||||
page,
|
||||
theme
|
||||
}) => {
|
||||
// Create a clock domain object
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Clock',
|
||||
name: 'Default Clock'
|
||||
test('Alert Levels and Notification List Modal', async ({ page, theme }) => {
|
||||
await createNotification(page, {
|
||||
message: 'Test info notification',
|
||||
severity: 'info'
|
||||
});
|
||||
// Click on the div with role="alert" that has "Save successful" text
|
||||
await page.getByRole('alert').filter({ hasText: 'Save successful' }).click();
|
||||
// Verify there is a div with role="dialog"
|
||||
await expect(page.getByRole('dialog', { name: 'Overlay' })).toBeVisible();
|
||||
// Verify the div with role="dialog" contains text "Save successful"
|
||||
expect(await page.getByRole('dialog', { name: 'Overlay' }).innerText()).toContain(
|
||||
'Save successful'
|
||||
);
|
||||
await percySnapshot(page, `Notification banner shows Save successful (theme: '${theme}')`);
|
||||
// Verify there is a button with text "Dismiss"
|
||||
await expect(page.getByText('Dismiss', { exact: true })).toBeVisible();
|
||||
await percySnapshot(page, `Notification banner shows Dismiss (theme: '${theme}')`);
|
||||
// Click on button with text "Dismiss"
|
||||
await page.getByText('Dismiss', { exact: true }).click();
|
||||
// Verify there is no div with role="dialog"
|
||||
await expect(page.getByRole('dialog', { name: 'Overlay' })).toBeHidden();
|
||||
await percySnapshot(page, `Notification banner dismissed (theme: '${theme}')`);
|
||||
});
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await scanForA11yViolations(page, testInfo.title);
|
||||
await expect(page.getByText('Test info notification')).toBeVisible();
|
||||
await percySnapshot(page, `Info Notification banner shown (theme: '${theme}')`);
|
||||
await page.getByLabel('Dismiss').click();
|
||||
await page.getByRole('alert').waitFor({ state: 'detached' });
|
||||
await createNotification(page, {
|
||||
message: 'Test alert notification',
|
||||
severity: 'alert'
|
||||
});
|
||||
await expect(page.getByText('Test alert notification')).toBeVisible();
|
||||
await percySnapshot(page, `Alert Notification banner shown (theme: '${theme}')`);
|
||||
await page.getByLabel('Dismiss').click();
|
||||
await page.getByRole('alert').waitFor({ state: 'detached' });
|
||||
await createNotification(page, {
|
||||
message: 'Test error notification',
|
||||
severity: 'error'
|
||||
});
|
||||
await expect(page.getByText('Test error notification')).toBeVisible();
|
||||
await percySnapshot(page, `Error Notification banner shown (theme: '${theme}')`);
|
||||
await page.getByLabel('Dismiss').click();
|
||||
await page.getByRole('alert').waitFor({ state: 'detached' });
|
||||
|
||||
await page.getByLabel('Review 2 Notifications').click();
|
||||
await page.getByText('Test alert notification').waitFor();
|
||||
await percySnapshot(page, `Notification List Modal with alert and error (theme: '${theme}')`);
|
||||
|
||||
// Skipping due to https://github.com/nasa/openmct/issues/6820
|
||||
// await page.getByLabel('Dismiss notification of Test alert notification').click();
|
||||
// await page.getByText('Test alert notification').waitFor({ state: 'detached' });
|
||||
// await percySnapshot(page, `Notification Modal with error only (theme: '${theme}')`);
|
||||
|
||||
await page.getByRole('button', { name: 'Clear All Notifications', exact: true }).click();
|
||||
await percySnapshot(page, `Notification Modal after Clear All (theme: '${theme}')`);
|
||||
});
|
||||
});
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await scanForA11yViolations(page, testInfo.title);
|
||||
});
|
||||
|
@ -64,7 +64,7 @@ test.describe('Grand Search @a11y', () => {
|
||||
await percySnapshot(page, `Searching for Object (theme: '${theme}')`);
|
||||
|
||||
// Enter Edit mode on the Display Layout
|
||||
await page.getByRole('button', { name: 'Edit' }).click();
|
||||
await page.getByRole('button', { name: 'Edit Object' }).click();
|
||||
|
||||
// Navigate to the object while in edit mode on the display layout
|
||||
await page.getByRole('searchbox', { name: 'Search Input' }).click();
|
||||
|
@ -68,7 +68,7 @@ test.describe('Flexible Layout styling @a11y', () => {
|
||||
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
@ -146,7 +146,7 @@ test.describe('Stacked Plot styling @a11y', () => {
|
||||
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Edit Flexible Layout
|
||||
await page.getByLabel('Edit').click();
|
||||
await page.getByLabel('Edit Object').click();
|
||||
|
||||
// Select styles tab
|
||||
await page.getByRole('tab', { name: 'Styles' }).click();
|
||||
|
78
e2e/tests/visual-a11y/telemetryViews.visual.spec.js
Normal file
78
e2e/tests/visual-a11y/telemetryViews.visual.spec.js
Normal file
@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2024, 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.
|
||||
*****************************************************************************/
|
||||
|
||||
import percySnapshot from '@percy/playwright';
|
||||
|
||||
import { createDomainObjectWithDefaults } from '../../appActions.js';
|
||||
import { VISUAL_URL } from '../../constants.js';
|
||||
import { expect, test } from '../../pluginFixtures.js';
|
||||
|
||||
test.describe('Visual - Telemetry Views', () => {
|
||||
let telemetry;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(VISUAL_URL, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
// Create SWG inside of LAD Table
|
||||
telemetry = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: 'SWG4'
|
||||
});
|
||||
|
||||
//Modify SWG to create a really stable SWG
|
||||
await page.getByRole('button', { name: 'More actions' }).click();
|
||||
|
||||
await page.getByRole('menuitem', { name: 'Edit Properties...' }).click();
|
||||
|
||||
//Forgive me, padre
|
||||
await page.getByRole('spinbutton', { name: 'Data Rate (hz)' }).fill('0');
|
||||
await page.getByRole('spinbutton', { name: 'Period' }).fill('0');
|
||||
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
});
|
||||
test('Telemetry Table toggled column widths behave accordingly', async ({ page, theme }) => {
|
||||
await page.goto(telemetry.url, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
//Click this button to see telemetry display options
|
||||
await page.getByRole('button', { name: 'Plot' }).click();
|
||||
await page.getByLabel('Telemetry Table').click();
|
||||
|
||||
//Get Table View in place
|
||||
expect(await page.getByLabel('Expand Columns')).toBeInViewport();
|
||||
|
||||
await percySnapshot(page, `Default Telemetry Table View (theme: ${theme})`);
|
||||
|
||||
await page.getByLabel('Expand Columns').click();
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Autosize Columns' })).toBeVisible();
|
||||
|
||||
await percySnapshot(page, `Default Telemetry Table columns expanded (theme: ${theme})`);
|
||||
|
||||
await page.getByLabel('More actions').click();
|
||||
|
||||
await percySnapshot(page, `Telemetry View Actions Menu expanded (theme: ${theme})`);
|
||||
|
||||
await page.getByRole('menuitem', { name: 'Pause' }).click();
|
||||
|
||||
await percySnapshot(page, `Telemetry View Paused (theme: ${theme})`);
|
||||
});
|
||||
});
|
@ -8,7 +8,6 @@
|
||||
"@axe-core/playwright": "4.8.2",
|
||||
"@babel/eslint-parser": "7.23.3",
|
||||
"@braintree/sanitize-url": "6.0.4",
|
||||
"@deploysentinel/playwright": "0.3.4",
|
||||
"@percy/cli": "1.27.4",
|
||||
"@percy/playwright": "1.0.4",
|
||||
"@playwright/test": "1.39.0",
|
||||
|
@ -29,6 +29,7 @@
|
||||
:key="action.name"
|
||||
role="menuitem"
|
||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||
:aria-label="action.name"
|
||||
:title="action.description"
|
||||
@click="action.onItemClicked"
|
||||
>
|
||||
@ -51,6 +52,7 @@
|
||||
:key="action.name"
|
||||
role="menuitem"
|
||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||
:aria-label="action.name"
|
||||
:title="action.description"
|
||||
@click="action.onItemClicked"
|
||||
>
|
||||
|
@ -62,6 +62,7 @@
|
||||
:key="action.name"
|
||||
role="menuitem"
|
||||
:class="action.cssClass"
|
||||
:aria-label="action.name"
|
||||
:title="action.description"
|
||||
@click="action.onItemClicked"
|
||||
@mouseover="toggleItemDescription(action)"
|
||||
|
@ -37,12 +37,13 @@
|
||||
<ul v-for="column in columns" class="l-autoflow-col" :style="{ width: width + 'px' }">
|
||||
<li v-for="row in column" class="l-autoflow-row">
|
||||
<span
|
||||
:aria-label="row.value"
|
||||
:title="row.value"
|
||||
:data-value="row.value"
|
||||
:class="'l-autoflow-item r l-obj-val-format ' + row.classes"
|
||||
>{{row.value}}</span
|
||||
>
|
||||
<span :title="row.name" class="l-autoflow-item l">{{row.name}}</span>
|
||||
<span :aria-label="row.name" :title="row.name" class="l-autoflow-item l">{{row.name}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -41,7 +41,11 @@
|
||||
@mouseover.ctrl="showToolTip"
|
||||
@mouseleave="hideToolTip"
|
||||
>
|
||||
<div class="is-status__indicator" :title="`This item is ${status}`"></div>
|
||||
<div
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></div>
|
||||
<div v-if="showLabel" class="c-telemetry-view__label">
|
||||
<div class="c-telemetry-view__label-text">
|
||||
{{ domainObject.name }}
|
||||
@ -50,6 +54,7 @@
|
||||
|
||||
<div
|
||||
v-if="showValue"
|
||||
:aria-label="fieldName"
|
||||
:title="fieldName"
|
||||
class="c-telemetry-view__value"
|
||||
:class="[telemetryClass]"
|
||||
|
@ -28,6 +28,7 @@
|
||||
<div class="c-fault-mgmt-item">
|
||||
<div
|
||||
class="c-fault-mgmt__list-severity"
|
||||
:aria-label="fault.severity"
|
||||
:title="fault.severity"
|
||||
:class="['is-severity-' + severity]"
|
||||
></div>
|
||||
|
@ -42,14 +42,22 @@
|
||||
<div class="c-grid-item__details">
|
||||
<!-- Name and metadata -->
|
||||
<div class="c-grid-item__name" :title="item.model.name">{{ item.model.name }}</div>
|
||||
<div class="c-grid-item__metadata" :title="item.type.name">
|
||||
<div class="c-grid-item__metadata" :aria-label="item.type.name" :title="item.type.name">
|
||||
<span class="c-grid-item__metadata__type">{{ item.type.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-grid-item__controls">
|
||||
<div class="is-status__indicator" :title="`This item is ${status}`"></div>
|
||||
<div
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></div>
|
||||
<div class="icon-people" title="Shared"></div>
|
||||
<button class="c-icon-button icon-info c-info-button" title="More Info"></button>
|
||||
<button
|
||||
class="c-icon-button icon-info c-info-button"
|
||||
aria-label="More Info"
|
||||
title="More Info"
|
||||
></button>
|
||||
<div class="icon-pointer-right c-pointer-icon"></div>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -20,12 +20,13 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div class="l-grid-view">
|
||||
<div class="l-grid-view" role="grid">
|
||||
<grid-item
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:item="item"
|
||||
:object-path="item.objectPath"
|
||||
role="gridcell"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -34,7 +34,11 @@
|
||||
class="c-object-label__type-icon c-list-item__name__type-icon"
|
||||
:class="item.type.cssClass"
|
||||
>
|
||||
<span class="is-status__indicator" :title="`This item is ${status}`"></span>
|
||||
<span
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></span>
|
||||
</div>
|
||||
<div class="c-object-label__name c-list-item__name__name">{{ item.model.name }}</div>
|
||||
</a>
|
||||
|
@ -24,6 +24,7 @@
|
||||
ref="gaugeWrapper"
|
||||
class="c-gauge__wrapper js-gauge-wrapper"
|
||||
:class="gaugeClasses"
|
||||
:aria-label="gaugeTitle"
|
||||
:title="gaugeTitle"
|
||||
>
|
||||
<template v-if="typeDial">
|
||||
|
@ -26,11 +26,20 @@
|
||||
role="toolbar"
|
||||
aria-label="Image controls"
|
||||
>
|
||||
<imagery-view-menu-switcher :icon-class="'icon-brightness'" :title="'Brightness and contrast'">
|
||||
<imagery-view-menu-switcher
|
||||
:icon-class="'icon-brightness'"
|
||||
:aria-label="'Brightness and contrast'"
|
||||
:title="'Brightness and contrast'"
|
||||
>
|
||||
<filter-settings @filter-changed="updateFilterValues" />
|
||||
</imagery-view-menu-switcher>
|
||||
|
||||
<imagery-view-menu-switcher v-if="layers.length" :icon-class="'icon-layers'" :title="'Layers'">
|
||||
<imagery-view-menu-switcher
|
||||
v-if="layers.length"
|
||||
icon-class="icon-layers"
|
||||
aria-label="Layers"
|
||||
title="Layers"
|
||||
>
|
||||
<layer-settings :layers="layers" @toggle-layer-visibility="toggleLayerVisibility" />
|
||||
</imagery-view-menu-switcher>
|
||||
|
||||
@ -47,6 +56,7 @@
|
||||
<imagery-view-menu-switcher
|
||||
class="--show-if-less-than-220"
|
||||
:icon-class="'icon-magnify'"
|
||||
:aria-label="'Zoom settings'"
|
||||
:title="'Zoom settings'"
|
||||
>
|
||||
<zoom-settings
|
||||
|
@ -28,6 +28,7 @@
|
||||
selected: selected,
|
||||
'real-time': realTime
|
||||
}"
|
||||
:aria-label="image.formattedTime"
|
||||
:title="image.formattedTime"
|
||||
@click="handleClick"
|
||||
>
|
||||
|
@ -25,6 +25,7 @@
|
||||
:id="id"
|
||||
class="c-button c-button--menu c-switcher-menu__button"
|
||||
:class="iconClass"
|
||||
:aria-label="title"
|
||||
:title="title"
|
||||
@click="toggleMenu"
|
||||
/>
|
||||
|
@ -23,7 +23,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="c-style c-style--saved has-local-controls c-toolbar">
|
||||
<div class="c-style__controls" :title="description" @click="selectStyle()">
|
||||
<div
|
||||
class="c-style__controls"
|
||||
:aria-label="description"
|
||||
:title="description"
|
||||
@click="selectStyle()"
|
||||
>
|
||||
<div class="c-style-thumb" :style="thumbStyle">
|
||||
<span
|
||||
class="c-style-thumb__text u-style-receiver js-style-receiver"
|
||||
|
@ -23,6 +23,7 @@
|
||||
<div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left">
|
||||
<button
|
||||
class="c-icon-button c-button--menu icon-camera"
|
||||
aria-label="Take a Notebook Snapshot"
|
||||
title="Take a Notebook Snapshot"
|
||||
@click.stop.prevent="showMenu"
|
||||
>
|
||||
|
@ -37,6 +37,7 @@
|
||||
<div
|
||||
v-for="entry in statusCountViewModel"
|
||||
:key="entry.status.key"
|
||||
:aria-label="entry.status.label"
|
||||
:title="entry.status.label"
|
||||
class="c-status-poll-report__count"
|
||||
:style="[
|
||||
|
@ -30,6 +30,7 @@
|
||||
:style="{
|
||||
left: (100 * (tick.value - min)) / interval + '%'
|
||||
}"
|
||||
:aria-label="tick.fullText || tick.text"
|
||||
:title="tick.fullText || tick.text"
|
||||
>
|
||||
{{ tick.text }}
|
||||
@ -41,6 +42,7 @@
|
||||
:key="'tick-top' + i"
|
||||
class="gl-plot-tick gl-plot-y-tick-label"
|
||||
:style="{ top: (100 * (max - tick.value)) / interval + '%' }"
|
||||
:aria-label="tick.fullText || tick.text"
|
||||
:title="tick.fullText || tick.text"
|
||||
style="margin-top: -0.5em; direction: ltr"
|
||||
>
|
||||
|
@ -22,9 +22,9 @@
|
||||
|
||||
<template>
|
||||
<div ref="chart" class="gl-plot-chart-area">
|
||||
<canvas :style="canvasStyle" class="js-overlay-canvas"></canvas>
|
||||
<canvas :style="canvasStyle" class="js-main-canvas"></canvas>
|
||||
<div ref="limitArea" class="js-limit-area">
|
||||
<canvas id="2dContext" :style="canvasStyle" class="js-overlay-canvas" role="img"></canvas>
|
||||
<canvas id="webglContext" :style="canvasStyle" class="js-main-canvas" role="img"></canvas>
|
||||
<div ref="limitArea" class="js-limit-area" aria-hidden="true">
|
||||
<limit-label
|
||||
v-for="(limitLabel, index) in visibleLimitLabels"
|
||||
:key="index"
|
||||
|
@ -54,7 +54,11 @@
|
||||
:class="[tab.status ? `is-status--${tab.status}` : '']"
|
||||
>
|
||||
<div class="c-object-label__type-icon" :class="tab.type.definition.cssClass">
|
||||
<span class="is-status__indicator" :title="`This item is ${tab.status}`"></span>
|
||||
<span
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${tab.status}`"
|
||||
:title="`This item is ${tab.status}`"
|
||||
></span>
|
||||
</div>
|
||||
<span class="c-button__label c-object-label__name">{{ tab.domainObject.name }}</span>
|
||||
</div>
|
||||
|
@ -22,6 +22,7 @@
|
||||
<template>
|
||||
<td
|
||||
ref="tableCell"
|
||||
:aria-label="formattedValue"
|
||||
:title="formattedValue"
|
||||
@click="selectCell($event.currentTarget, columnKey)"
|
||||
@mouseover.ctrl="showToolTip"
|
||||
|
@ -21,11 +21,12 @@
|
||||
-->
|
||||
<template>
|
||||
<div ref="root" class="c-table-wrapper" :class="tableClasses">
|
||||
<div v-if="enableLegacyToolbar" class="c-table-control-bar c-control-bar">
|
||||
<div v-if="enableLegacyToolbar" class="c-table-control-bar c-control-bar" role="menubar">
|
||||
<button
|
||||
v-if="allowExport"
|
||||
v-show="!markedRows.length"
|
||||
class="c-button icon-download labeled"
|
||||
aria-label="Export this view's data"
|
||||
title="Export this view's data"
|
||||
@click="exportAllDataAsCSV()"
|
||||
>
|
||||
@ -35,6 +36,7 @@
|
||||
v-if="allowExport"
|
||||
v-show="markedRows.length"
|
||||
class="c-button icon-download labeled"
|
||||
aria-label="Export marked rows as CSV"
|
||||
title="Export marked rows as CSV"
|
||||
@click="exportMarkedDataAsCSV()"
|
||||
>
|
||||
@ -43,6 +45,7 @@
|
||||
<button
|
||||
v-show="markedRows.length"
|
||||
class="c-button icon-x labeled"
|
||||
aria-label="Unmark all rows"
|
||||
title="Unmark all rows"
|
||||
@click="unmarkAllRows()"
|
||||
>
|
||||
@ -51,6 +54,7 @@
|
||||
<div v-if="marking.enable" class="c-separator"></div>
|
||||
<button
|
||||
v-if="marking.enable"
|
||||
:aria-label="paused ? 'Continue real-time data flow' : 'Pause real-time data flow'"
|
||||
class="c-button icon-pause pause-play labeled"
|
||||
:class="paused ? 'icon-play is-paused' : 'icon-pause'"
|
||||
:title="paused ? 'Continue real-time data flow' : 'Pause real-time data flow'"
|
||||
@ -62,10 +66,11 @@
|
||||
</button>
|
||||
|
||||
<template v-if="!isEditing">
|
||||
<div class="c-separator"></div>
|
||||
<div class="c-separator" role="separator"></div>
|
||||
<button
|
||||
v-if="isAutosizeEnabled"
|
||||
class="c-button icon-arrows-right-left labeled"
|
||||
aria-label="Increase column widths to fit currently available data."
|
||||
title="Increase column widths to fit currently available data."
|
||||
@click="recalculateColumnWidths"
|
||||
>
|
||||
@ -73,6 +78,7 @@
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
aria-label="Automatically size columns to fit the table into the available space."
|
||||
class="c-button icon-expand labeled"
|
||||
title="Automatically size columns to fit the table into the available space."
|
||||
@click="autosizeColumns"
|
||||
@ -104,6 +110,7 @@
|
||||
<button
|
||||
:class="{ 'hide-nice': !markedRows.length }"
|
||||
class="c-icon-button icon-x labeled"
|
||||
aria-label="Deselect All"
|
||||
title="Deselect All"
|
||||
@click="unmarkAllRows()"
|
||||
>
|
||||
@ -191,6 +198,7 @@
|
||||
<button
|
||||
class="c-search__use-regex"
|
||||
:class="{ 'is-active': enableRegexSearch[key] }"
|
||||
aria-label="Click to enable regex: enter a string with slashes, like this: /regex_exp/"
|
||||
title="Click to enable regex: enter a string with slashes, like this: /regex_exp/"
|
||||
@click="toggleRegex(key)"
|
||||
>
|
||||
|
@ -25,6 +25,7 @@
|
||||
v-if="filterNames.length > 0"
|
||||
class="c-table-indicator__filter c-table-indicator__elem c-filter-indication"
|
||||
:class="{ 'c-filter-indication--mixed': hasMixedFilters }"
|
||||
:aria-label="title"
|
||||
:title="title"
|
||||
>
|
||||
<span class="c-filter-indication__mixed">{{ label }}</span>
|
||||
@ -35,6 +36,7 @@
|
||||
|
||||
<div class="c-table-indicator__counts">
|
||||
<span
|
||||
:aria-label="totalRows + ' rows visible after any filtering'"
|
||||
:title="totalRows + ' rows visible after any filtering'"
|
||||
class="c-table-indicator__elem c-table-indicator__row-count"
|
||||
>
|
||||
@ -44,6 +46,7 @@
|
||||
<span
|
||||
v-if="markedRows"
|
||||
class="c-table-indicator__elem c-table-indicator__marked-count"
|
||||
:aria-label="markedRows + ' rows selected'"
|
||||
:title="markedRows + ' rows selected'"
|
||||
>
|
||||
{{ markedRows }} Marked
|
||||
|
@ -31,6 +31,7 @@
|
||||
<div
|
||||
v-if="!compact"
|
||||
class="c-compact-tc__setting-value icon-minus u-fade-truncate--lg --no-sep"
|
||||
:aria-label="`Start offset: ${offsets.start}`"
|
||||
:title="`Start offset: ${offsets.start}`"
|
||||
>
|
||||
{{ offsets.start }}
|
||||
@ -40,12 +41,14 @@
|
||||
v-if="!compact"
|
||||
class="c-compact-tc__setting-value icon-plus u-fade-truncate--lg"
|
||||
:class="{ '--no-sep': compact }"
|
||||
:aria-label="`End offset: ${offsets.end}`"
|
||||
:title="`End offset: ${offsets.end}`"
|
||||
>
|
||||
{{ offsets.end }}
|
||||
</div>
|
||||
<div
|
||||
class="c-compact-tc__setting-value icon-clock c-compact-tc__current-update u-fade-truncate--lg --no-sep"
|
||||
aria-label="Last update"
|
||||
title="Last update"
|
||||
>
|
||||
{{ formattedCurrentValue }}
|
||||
|
@ -37,6 +37,7 @@
|
||||
<div
|
||||
v-else
|
||||
class="c-compact-tc__setting-value__elem"
|
||||
:aria-label="`Time system: ${selectedTimeSystem.name}`"
|
||||
:title="`Time system: ${selectedTimeSystem.name}`"
|
||||
>
|
||||
{{ selectedTimeSystem.name }}
|
||||
|
@ -22,7 +22,7 @@
|
||||
<template>
|
||||
<div class="grid-row grid-row--pad-label-for-button">
|
||||
<template v-if="canEdit">
|
||||
<div class="grid-cell label" :title="editTitle">{{ shortLabel }}</div>
|
||||
<div class="grid-cell label" :aria-label="editTitle" :title="editTitle">{{ shortLabel }}</div>
|
||||
<div class="grid-cell value">
|
||||
<div class="c-click-swatch c-click-swatch--menu" @click="toggleSwatch()">
|
||||
<span class="c-color-swatch" :style="{ background: currentColor }"> </span>
|
||||
@ -44,7 +44,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="grid-cell label" :title="viewTitle">{{ shortLabel }}</div>
|
||||
<div class="grid-cell label" :aria-label="viewTitle" :title="viewTitle">{{ shortLabel }}</div>
|
||||
<div class="grid-cell value">
|
||||
<span
|
||||
class="c-color-swatch"
|
||||
|
@ -26,6 +26,7 @@
|
||||
:key="itemValue.key"
|
||||
class="c-list-item__value js-list-item__value"
|
||||
:class="['--' + itemValue.key]"
|
||||
:aria-label="itemValue.text"
|
||||
:title="itemValue.text"
|
||||
>
|
||||
{{ itemValue.text }}
|
||||
|
@ -29,6 +29,7 @@
|
||||
:key="headerItem.property"
|
||||
:direction="sortBy === headerItem.property ? ascending : headerItem.defaultDirection"
|
||||
:is-sortable="headerItem.isSortable"
|
||||
:aria-label="headerItem.name"
|
||||
:title="headerItem.name"
|
||||
:property="headerItem.property"
|
||||
:current-sort="sortBy"
|
||||
|
@ -36,7 +36,11 @@
|
||||
<div class="c-so-view__header">
|
||||
<div class="c-object-label" :class="[statusClass]">
|
||||
<div class="c-object-label__type-icon" :class="cssClass">
|
||||
<span class="is-status__indicator" :title="`This item is ${status}`"></span>
|
||||
<span
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></span>
|
||||
</div>
|
||||
<div
|
||||
ref="objectName"
|
||||
@ -78,6 +82,7 @@
|
||||
</div>
|
||||
<button
|
||||
class="c-icon-button icon-3-dots c-so-view__frame-controls__more"
|
||||
aria-label="View menu items"
|
||||
title="View menu items"
|
||||
@click.prevent.stop="showMenuItems($event)"
|
||||
></button>
|
||||
|
@ -29,7 +29,11 @@
|
||||
@click="navigateOrPreview"
|
||||
>
|
||||
<div class="c-tree__item__type-icon c-object-label__type-icon" :class="typeClass">
|
||||
<span class="is-status__indicator" :title="`This item is ${status}`"></span>
|
||||
<span
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></span>
|
||||
</div>
|
||||
<div
|
||||
ref="objectLabel"
|
||||
|
@ -35,7 +35,12 @@
|
||||
:style="gridRowSpan"
|
||||
>
|
||||
<div v-if="iconClass" class="c-object-label__type-icon" :class="iconClass">
|
||||
<span v-if="status" class="is-status__indicator" :title="`This item is ${status}`"></span>
|
||||
<span
|
||||
v-if="status"
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="c-object-label__name">
|
||||
|
@ -24,7 +24,11 @@
|
||||
<div class="c-inspector__header">
|
||||
<div v-if="!multiSelect" class="c-inspector__selected c-object-label" :class="[statusClass]">
|
||||
<div class="c-object-label__type-icon" :class="typeCssClass">
|
||||
<span class="is-status__indicator" :title="`This item is ${status}`"></span>
|
||||
<span
|
||||
class="is-status__indicator"
|
||||
:aria-label="`This item is ${status}`"
|
||||
:title="`This item is ${status}`"
|
||||
></span>
|
||||
</div>
|
||||
<span v-if="!singleSelectNonObject" class="c-inspector__selected c-object-label__name">{{
|
||||
item.name
|
||||
|
@ -22,7 +22,7 @@
|
||||
<template>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div class="c-about c-about--splash">
|
||||
<div class="c-about__image c-splash-image"></div>
|
||||
<div class="c-about__image c-splash-image" role="img" alt="Open MCT Splash Logo"></div>
|
||||
<div class="c-about__text s-text">
|
||||
<div
|
||||
v-if="branding.aboutHtml"
|
||||
@ -40,7 +40,10 @@
|
||||
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
|
||||
<a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0"
|
||||
<a
|
||||
target="_blank"
|
||||
href="http://www.apache.org/licenses/LICENSE-2.0"
|
||||
rel="noopener noreferrer"
|
||||
>http://www.apache.org/licenses/LICENSE-2.0</a
|
||||
>.
|
||||
</p>
|
||||
@ -57,11 +60,11 @@
|
||||
</p>
|
||||
</div>
|
||||
<h2>Version Information</h2>
|
||||
<ul class="t-info l-info s-info">
|
||||
<li>Version: {{ buildInfo.version || 'Unknown' }}</li>
|
||||
<li>Build Date: {{ buildInfo.buildDate || 'Unknown' }}</li>
|
||||
<li>Revision: {{ buildInfo.revision || 'Unknown' }}</li>
|
||||
<li>Branch: {{ buildInfo.branch || 'Unknown' }}</li>
|
||||
<ul id="versionInformation" class="t-info l-info s-info">
|
||||
<li aria-label="Version Number">Version: {{ buildInfo.version || 'Unknown' }}</li>
|
||||
<li aria-label="Build Date">Build Date: {{ buildInfo.buildDate || 'Unknown' }}</li>
|
||||
<li aria-label="Revision">Revision: {{ buildInfo.revision || 'Unknown' }}</li>
|
||||
<li aria-label="Branch">Branch: {{ buildInfo.branch || 'Unknown' }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,6 +45,7 @@
|
||||
? 'l-shell__head__collapse-button--collapse'
|
||||
: 'l-shell__head__collapse-button--expand'
|
||||
"
|
||||
:aria-label="`Click to ${headExpanded ? 'collapse' : 'expand'} items`"
|
||||
:title="`Click to ${headExpanded ? 'collapse' : 'expand'} items`"
|
||||
@click="toggleShellHead"
|
||||
></button>
|
||||
@ -61,6 +62,7 @@
|
||||
'c-icon-button c-icon-button--major',
|
||||
fullScreen ? 'icon-fullscreen-collapse' : 'icon-fullscreen-expand'
|
||||
]"
|
||||
:aria-label="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
|
||||
:title="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
|
||||
@click="fullScreenToggle"
|
||||
></button>
|
||||
|
@ -20,7 +20,13 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div ref="aboutLogo" class="l-shell__app-logo" @click="launchAbout"></div>
|
||||
<div
|
||||
ref="aboutLogo"
|
||||
class="l-shell__app-logo"
|
||||
role="button"
|
||||
aria-label="About Modal"
|
||||
@click="launchAbout"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -71,6 +71,7 @@
|
||||
v-for="(item, index) in statusBarItems"
|
||||
:key="index"
|
||||
class="c-button"
|
||||
:aria-label="item.name"
|
||||
:title="item.name"
|
||||
:class="item.cssClass"
|
||||
@click="item.onItemClicked"
|
||||
@ -78,6 +79,7 @@
|
||||
|
||||
<button
|
||||
v-if="isViewEditable & !isEditing"
|
||||
:aria-label="lockedOrUnlockedTitle"
|
||||
:title="lockedOrUnlockedTitle"
|
||||
:class="{
|
||||
'c-button icon-lock': domainObject.locked,
|
||||
@ -89,8 +91,8 @@
|
||||
<button
|
||||
v-if="isViewEditable && !isEditing && !domainObject.locked"
|
||||
class="l-browse-bar__actions__edit c-button c-button--major icon-pencil"
|
||||
title="Edit"
|
||||
aria-label="Edit"
|
||||
title="Edit Object"
|
||||
aria-label="Edit Object"
|
||||
@click="edit()"
|
||||
></button>
|
||||
|
||||
@ -123,6 +125,7 @@
|
||||
<button
|
||||
v-if="isEditing"
|
||||
class="l-browse-bar__actions c-button icon-x"
|
||||
aria-label="Cancel Editing"
|
||||
title="Cancel Editing"
|
||||
@click="promptUserandCancelEditing()"
|
||||
></button>
|
||||
|
Loading…
Reference in New Issue
Block a user