Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nasa/openmct.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Mazzella <ozyx@users.noreply.github.com>2022-11-08 02:50:33 +0300
committerGitHub <noreply@github.com>2022-11-08 02:50:33 +0300
commitd545124942c67536d52f762e12a699b67ea51c0f (patch)
treef6131166cd118b4d1c22b49cd6363db0029382bb
parent6abdbfdff03e6900387ee7ed68c5e52db2ee8c72 (diff)
test(e2e): unique names for created objects by default (#5945)
* feat(e2e): default unique names for new objects * refactor(e2e): reference generated object names - Fixes the tests that were locating "Unnamed <object_type>" to use the generated unique names * feat(e2e): add testInfo into domainObject notes - adds info about the currently running test and its project to notes * fix(e2e): fix selector for notes section * feat: ARIA: menu role for menus and SuperMenus - Implements the [ARIA: menu role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/roles/menu_role) for Menus and SuperMenus, * refactor(e2e): use role selectors for menu items * refactor(e2e): better selectors for "OK" button * refactor(e2e): better selectors for menu items * refactor(e2e): improve selector * refactor(e2e): update test to use appActions * refactor(e2e): update test to use object name * refactor(e2e): improve selectors for menu items * test(e2e): fix search test * refactor(e2e): update more plain 'text=' selectors * fix: resolve codeQL error - remove superfluous argument * refactor(e2e): move testNotes to `pluginFixtures` and update imports * refactor(e2e): remove unused fixture from test * refactor: add dynamic id to form textareas * refactor(e2e): improve notes textarea selector * refactor(e2e): remove unused fixture
-rw-r--r--e2e/appActions.js22
-rw-r--r--e2e/helper/notebookUtils.js31
-rw-r--r--e2e/pluginFixtures.js27
-rw-r--r--e2e/tests/framework/appActions.e2e.spec.js14
-rw-r--r--e2e/tests/framework/exampleTemplate.e2e.spec.js4
-rw-r--r--e2e/tests/framework/generateVisualTestData.e2e.spec.js6
-rw-r--r--e2e/tests/functional/couchdb.e2e.spec.js2
-rw-r--r--e2e/tests/functional/example/eventGenerator.e2e.spec.js2
-rw-r--r--e2e/tests/functional/example/generator/sineWaveLimitProvider.e2e.spec.js2
-rw-r--r--e2e/tests/functional/forms.e2e.spec.js6
-rw-r--r--e2e/tests/functional/moveAndLinkObjects.e2e.spec.js12
-rw-r--r--e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js10
-rw-r--r--e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js6
-rw-r--r--e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js16
-rw-r--r--e2e/tests/functional/plugins/notebook/notebook.e2e.spec.js2
-rw-r--r--e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js2
-rw-r--r--e2e/tests/functional/plugins/notebook/restrictedNotebook.e2e.spec.js19
-rw-r--r--e2e/tests/functional/plugins/notebook/tags.e2e.spec.js25
-rw-r--r--e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js8
-rw-r--r--e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js8
-rw-r--r--e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js8
-rw-r--r--e2e/tests/functional/plugins/plot/plotLegendSwatch.e2e.spec.js8
-rw-r--r--e2e/tests/functional/plugins/plot/plotRendering.e2e.spec.js2
-rw-r--r--e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js2
-rw-r--r--e2e/tests/functional/plugins/timer/timer.e2e.spec.js2
-rw-r--r--e2e/tests/functional/search.e2e.spec.js119
-rw-r--r--e2e/tests/performance/imagery.perf.spec.js2
-rw-r--r--src/api/forms/components/controls/TextAreaField.vue1
-rw-r--r--src/api/menu/components/Menu.vue57
-rw-r--r--src/api/menu/components/SuperMenu.vue53
30 files changed, 239 insertions, 239 deletions
diff --git a/e2e/appActions.js b/e2e/appActions.js
index 7b84080bb..bc1b1a212 100644
--- a/e2e/appActions.js
+++ b/e2e/appActions.js
@@ -46,6 +46,7 @@
*/
const Buffer = require('buffer').Buffer;
+const genUuid = require('uuid').v4;
/**
* This common function creates a domain object with the default options. It is the preferred way of creating objects
@@ -56,6 +57,10 @@ const Buffer = require('buffer').Buffer;
* @returns {Promise<CreatedObjectInfo>} An object containing information about the newly created domain object.
*/
async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine' }) {
+ if (!name) {
+ name = `${type}:${genUuid()}`;
+ }
+
const parentUrl = await getHashUrlToDomainObject(page, parent);
// Navigate to the parent object. This is necessary to create the object
@@ -70,11 +75,14 @@ async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine
await page.click(`li:text("${type}")`);
// Modify the name input field of the domain object to accept 'name'
- if (name) {
- const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
- await nameInput.fill("");
- await nameInput.fill(name);
- }
+ const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
+ await nameInput.fill("");
+ await nameInput.fill(name);
+
+ // Fill the "Notes" section with information about the
+ // currently running test and its project.
+ const notesInput = page.locator('form[name="mctForm"] #notes-textarea');
+ await notesInput.fill(page.testNotes);
// Click OK button and wait for Navigate event
await Promise.all([
@@ -96,8 +104,8 @@ async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine
}
return {
- name: name || `Unnamed ${type}`,
- uuid: uuid,
+ name,
+ uuid,
url: objectUrl
};
}
diff --git a/e2e/helper/notebookUtils.js b/e2e/helper/notebookUtils.js
index 5fdd97363..4a26fcd09 100644
--- a/e2e/helper/notebookUtils.js
+++ b/e2e/helper/notebookUtils.js
@@ -20,6 +20,8 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
+const { createDomainObjectWithDefaults } = require('../appActions');
+
const NOTEBOOK_DROP_AREA = '.c-notebook__drag-area';
/**
@@ -38,24 +40,17 @@ async function enterTextEntry(page, text) {
/**
* @param {import('@playwright/test').Page} page
*/
-async function dragAndDropEmbed(page, myItemsFolderName) {
- // Click button:has-text("Create")
- await page.locator('button:has-text("Create")').click();
- // Click li:has-text("Sine Wave Generator")
- await page.locator('li:has-text("Sine Wave Generator")').click();
- // Click form[name="mctForm"] >> text=My Items
- await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).click();
- // Click text=OK
- await page.locator('text=OK').click();
- // Click text=Open MCT My Items >> span >> nth=3
- await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
- // Click text=Unnamed CUSTOM_NAME
- await Promise.all([
- page.waitForNavigation(),
- page.locator('text=Unnamed CUSTOM_NAME').click()
- ]);
-
- await page.dragAndDrop('text=UNNAMED SINE WAVE GENERATOR', NOTEBOOK_DROP_AREA);
+async function dragAndDropEmbed(page, notebookObject) {
+ // Create example telemetry object
+ const swg = await createDomainObjectWithDefaults(page, {
+ type: "Sine Wave Generator"
+ });
+ // Navigate to notebook
+ await page.goto(notebookObject.url);
+ // Expand the tree to reveal the notebook
+ await page.click('button[title="Show selected item in tree"]');
+ // Drag and drop the SWG into the notebook
+ await page.dragAndDrop(`text=${swg.name}`, NOTEBOOK_DROP_AREA);
}
// eslint-disable-next-line no-undef
diff --git a/e2e/pluginFixtures.js b/e2e/pluginFixtures.js
index a3250054d..90d9a3a25 100644
--- a/e2e/pluginFixtures.js
+++ b/e2e/pluginFixtures.js
@@ -126,13 +126,21 @@ exports.test = test.extend({
// This should follow in the Project's configuration. Can be set to 'snow' in playwright config.js
theme: [theme, { option: true }],
// eslint-disable-next-line no-shadow
- page: async ({ page, theme }, use) => {
+ page: async ({ page, theme }, use, testInfo) => {
// eslint-disable-next-line playwright/no-conditional-in-test
if (theme === 'snow') {
//inject snow theme
await page.addInitScript({ path: path.join(__dirname, './helper', './useSnowTheme.js') });
}
+ // Attach info about the currently running test and its project.
+ // This will be used by appActions to fill in the created
+ // domain object's notes.
+ page.testNotes = [
+ `${testInfo.titlePath.join('\n')}`,
+ `${testInfo.project.name}`
+ ].join('\n');
+
await use(page);
},
myItemsFolderName: [myItemsFolderName, { option: true }],
@@ -140,22 +148,5 @@ exports.test = test.extend({
openmctConfig: async ({ myItemsFolderName }, use) => {
await use({ myItemsFolderName });
}
- // objectCreateOptions: [objectCreateOptions, {option: true}],
- // eslint-disable-next-line no-shadow
- // domainObject: [async ({ page, objectCreateOptions }, use) => {
- // // FIXME: This is a false-positive caused by a bug in the eslint-plugin-playwright rule.
- // // eslint-disable-next-line playwright/no-conditional-in-test
- // if (objectCreateOptions === null) {
- // await use(page);
-
- // return;
- // }
-
- // //Go to baseURL
- // await page.goto('./', { waitUntil: 'networkidle' });
-
- // const uuid = await getOrCreateDomainObject(page, objectCreateOptions);
- // await use({ uuid });
- // }, { auto: true }]
});
exports.expect = expect;
diff --git a/e2e/tests/framework/appActions.e2e.spec.js b/e2e/tests/framework/appActions.e2e.spec.js
index 3a95000ba..cb8772e27 100644
--- a/e2e/tests/framework/appActions.e2e.spec.js
+++ b/e2e/tests/framework/appActions.e2e.spec.js
@@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
-const { test, expect } = require('../../baseFixtures.js');
+const { test, expect } = require('../../pluginFixtures.js');
const { createDomainObjectWithDefaults } = require('../../appActions.js');
test.describe('AppActions', () => {
@@ -50,11 +50,11 @@ test.describe('AppActions', () => {
});
await page.goto(timer1.url, { waitUntil: 'networkidle' });
- await expect(page.locator('.l-browse-bar__object-name')).toHaveText('Timer Foo');
+ await expect(page.locator('.l-browse-bar__object-name')).toHaveText(timer1.name);
await page.goto(timer2.url, { waitUntil: 'networkidle' });
- await expect(page.locator('.l-browse-bar__object-name')).toHaveText('Timer Bar');
+ await expect(page.locator('.l-browse-bar__object-name')).toHaveText(timer2.name);
await page.goto(timer3.url, { waitUntil: 'networkidle' });
- await expect(page.locator('.l-browse-bar__object-name')).toHaveText('Timer Baz');
+ await expect(page.locator('.l-browse-bar__object-name')).toHaveText(timer3.name);
});
await test.step('Create multiple nested objects in a row', async () => {
@@ -74,11 +74,11 @@ test.describe('AppActions', () => {
parent: folder2.uuid
});
await page.goto(folder1.url, { waitUntil: 'networkidle' });
- await expect(page.locator('.l-browse-bar__object-name')).toHaveText('Folder Foo');
+ await expect(page.locator('.l-browse-bar__object-name')).toHaveText(folder1.name);
await page.goto(folder2.url, { waitUntil: 'networkidle' });
- await expect(page.locator('.l-browse-bar__object-name')).toHaveText('Folder Bar');
+ await expect(page.locator('.l-browse-bar__object-name')).toHaveText(folder2.name);
await page.goto(folder3.url, { waitUntil: 'networkidle' });
- await expect(page.locator('.l-browse-bar__object-name')).toHaveText('Folder Baz');
+ await expect(page.locator('.l-browse-bar__object-name')).toHaveText(folder3.name);
expect(folder1.url).toBe(`${e2eFolder.url}/${folder1.uuid}`);
expect(folder2.url).toBe(`${e2eFolder.url}/${folder1.uuid}/${folder2.uuid}`);
diff --git a/e2e/tests/framework/exampleTemplate.e2e.spec.js b/e2e/tests/framework/exampleTemplate.e2e.spec.js
index 1b8ac4490..d042bebdc 100644
--- a/e2e/tests/framework/exampleTemplate.e2e.spec.js
+++ b/e2e/tests/framework/exampleTemplate.e2e.spec.js
@@ -45,7 +45,7 @@
*/
// Structure: Some standard Imports. Please update the required pathing.
-const { test, expect } = require('../../baseFixtures');
+const { test, expect } = require('../../pluginFixtures');
const { createDomainObjectWithDefaults } = require('../../appActions');
/**
@@ -144,5 +144,5 @@ async function renameTimerFrom3DotMenu(page, timerUrl, newNameForTimer) {
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(newNameForTimer);
// Click Ok button to Save
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
}
diff --git a/e2e/tests/framework/generateVisualTestData.e2e.spec.js b/e2e/tests/framework/generateVisualTestData.e2e.spec.js
index 7cb37719f..3d304982d 100644
--- a/e2e/tests/framework/generateVisualTestData.e2e.spec.js
+++ b/e2e/tests/framework/generateVisualTestData.e2e.spec.js
@@ -43,14 +43,14 @@ test('Generate Visual Test Data @localStorage', async ({ page, context }) => {
await page.locator('button:has-text("Create")').click();
// add sine wave generator with defaults
- await page.locator('li:has-text("Sine Wave Generator")').click();
+ await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
//Add a 5000 ms Delay
await page.locator('[aria-label="Loading Delay \\(ms\\)"]').fill('5000');
await Promise.all([
page.waitForNavigation(),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
@@ -58,7 +58,7 @@ test('Generate Visual Test Data @localStorage', async ({ page, context }) => {
// focus the overlay plot
await page.goto(overlayPlot.url);
- await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
+ await expect(page.locator('.l-browse-bar__object-name')).toContainText(overlayPlot.name);
//Save localStorage for future test execution
await context.storageState({ path: './e2e/test-data/VisualTestData_storage.json' });
});
diff --git a/e2e/tests/functional/couchdb.e2e.spec.js b/e2e/tests/functional/couchdb.e2e.spec.js
index b3c2fd918..9641dbc13 100644
--- a/e2e/tests/functional/couchdb.e2e.spec.js
+++ b/e2e/tests/functional/couchdb.e2e.spec.js
@@ -25,7 +25,7 @@
*
*/
-const { test, expect } = require('../../baseFixtures');
+const { test, expect } = require('../../pluginFixtures');
test.describe("CouchDB Status Indicator @couchdb", () => {
test.use({ failOnConsoleError: false });
diff --git a/e2e/tests/functional/example/eventGenerator.e2e.spec.js b/e2e/tests/functional/example/eventGenerator.e2e.spec.js
index 0db74c480..2dd7d5061 100644
--- a/e2e/tests/functional/example/eventGenerator.e2e.spec.js
+++ b/e2e/tests/functional/example/eventGenerator.e2e.spec.js
@@ -24,7 +24,7 @@
This test suite is dedicated to tests which verify the basic operations surrounding the example event generator.
*/
-const { test, expect } = require('../../../baseFixtures');
+const { test, expect } = require('../../../pluginFixtures');
const { createDomainObjectWithDefaults } = require('../../../appActions');
test.describe('Example Event Generator CRUD Operations', () => {
diff --git a/e2e/tests/functional/example/generator/sineWaveLimitProvider.e2e.spec.js b/e2e/tests/functional/example/generator/sineWaveLimitProvider.e2e.spec.js
index 767540692..ac6f36e3b 100644
--- a/e2e/tests/functional/example/generator/sineWaveLimitProvider.e2e.spec.js
+++ b/e2e/tests/functional/example/generator/sineWaveLimitProvider.e2e.spec.js
@@ -96,7 +96,7 @@ test.describe('Sine Wave Generator', () => {
//Click text=OK
await Promise.all([
page.waitForNavigation(),
- page.click('text=OK')
+ page.click('button:has-text("OK")')
]);
// Verify that the Sine Wave Generator is displayed and correct
diff --git a/e2e/tests/functional/forms.e2e.spec.js b/e2e/tests/functional/forms.e2e.spec.js
index 9da49274a..b76021be1 100644
--- a/e2e/tests/functional/forms.e2e.spec.js
+++ b/e2e/tests/functional/forms.e2e.spec.js
@@ -43,7 +43,7 @@ test.describe('Form Validation Behavior', () => {
await page.press('text=Properties Title Notes >> input[type="text"]', 'Tab');
//Required Field Form Validation
- await expect(page.locator('text=OK')).toBeDisabled();
+ await expect(page.locator('button:has-text("OK")')).toBeDisabled();
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/invalid/);
//Correct Form Validation for missing title and trigger validation with 'Tab'
@@ -52,13 +52,13 @@ test.describe('Form Validation Behavior', () => {
await page.press('text=Properties Title Notes >> input[type="text"]', 'Tab');
//Required Field Form Validation is corrected
- await expect(page.locator('text=OK')).toBeEnabled();
+ await expect(page.locator('button:has-text("OK")')).toBeEnabled();
await expect(page.locator('.c-form-row__state-indicator').first()).not.toHaveClass(/invalid/);
//Finish Creating Domain Object
await Promise.all([
page.waitForNavigation(),
- page.click('text=OK')
+ page.click('button:has-text("OK")')
]);
//Verify that the Domain Object has been created with the corrected title property
diff --git a/e2e/tests/functional/moveAndLinkObjects.e2e.spec.js b/e2e/tests/functional/moveAndLinkObjects.e2e.spec.js
index 78f20cb65..680403267 100644
--- a/e2e/tests/functional/moveAndLinkObjects.e2e.spec.js
+++ b/e2e/tests/functional/moveAndLinkObjects.e2e.spec.js
@@ -81,7 +81,7 @@ test.describe('Move & link item tests', () => {
await page.locator('li.icon-move').click();
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).click();
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
// Expect that Child Folder is in My Items, the root folder
expect(page.locator(`text=${myItemsFolderName} >> nth=0:has(text=Child Folder)`)).toBeTruthy();
@@ -95,11 +95,11 @@ test.describe('Move & link item tests', () => {
// Create Telemetry Table
let telemetryTable = 'Test Telemetry Table';
await page.locator('button:has-text("Create")').click();
- await page.locator('li:has-text("Telemetry Table")').click();
+ await page.locator('li[role="menuitem"]:has-text("Telemetry Table")').click();
await page.locator('text=Properties Title Notes >> input[type="text"]').click();
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(telemetryTable);
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
// Finish editing and save Telemetry Table
await page.locator('.c-button--menu.c-button--major.icon-save').click();
@@ -108,7 +108,7 @@ test.describe('Move & link item tests', () => {
// Create New Folder Basic Domain Object
let folder = 'Test Folder';
await page.locator('button:has-text("Create")').click();
- await page.locator('li:has-text("Folder")').click();
+ await page.locator('li[role="menuitem"]:has-text("Folder")').click();
await page.locator('text=Properties Title Notes >> input[type="text"]').click();
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(folder);
@@ -120,7 +120,7 @@ test.describe('Move & link item tests', () => {
// Continue test regardless of assertion and create it in My Items
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).click();
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
// Open My Items
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
@@ -196,7 +196,7 @@ test.describe('Move & link item tests', () => {
await page.locator('li.icon-link').click();
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).click();
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
// Expect that Child Folder is in My Items, the root folder
expect(page.locator(`text=${myItemsFolderName} >> nth=0:has(text=Child Folder)`)).toBeTruthy();
diff --git a/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js b/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js
index f3f9826ae..0cb927466 100644
--- a/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js
+++ b/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js
@@ -40,11 +40,11 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
await page.goto('./', { waitUntil: 'networkidle' });
await page.click('button:has-text("Create")');
- await page.locator('li:has-text("Condition Set")').click();
+ await page.locator('li[role="menuitem"]:has-text("Condition Set")').click();
await Promise.all([
page.waitForNavigation(),
- page.click('text=OK')
+ page.click('button:has-text("OK")')
]);
//Save localStorage for future test execution
@@ -163,9 +163,9 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
// Click hamburger button
await page.locator('[title="More options"]').click();
- // Click text=Remove
- await page.locator('text=Remove').click();
- await page.locator('text=OK').click();
+ // Click 'Remove' and press OK
+ await page.locator('li[role="menuitem"]:has-text("Remove")').click();
+ await page.locator('button:has-text("OK")').click();
//Expect Unnamed Condition Set to be removed in Main View
const numberOfConditionSetsAtEnd = await page.locator('a:has-text("Unnamed Condition Set Condition Set")').count();
diff --git a/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js b/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js
index 3d6456e2e..a9c5e5670 100644
--- a/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js
+++ b/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js
@@ -116,8 +116,8 @@ test.describe('Testing Display Layout @unstable', () => {
// Bring up context menu and remove
await page.locator('.c-tree__item.is-alias .c-tree__item__name:text("Test Sine Wave Generator")').first().click({ button: 'right' });
- await page.locator('text=Remove').click();
- await page.locator('text=OK').click();
+ await page.locator('li[role="menuitem"]:has-text("Remove")').click();
+ await page.locator('button:has-text("OK")').click();
// delete
@@ -150,7 +150,7 @@ test.describe('Testing Display Layout @unstable', () => {
// Bring up context menu and remove
await page.locator('.c-tree__item.is-alias .c-tree__item__name:text("Test Sine Wave Generator")').click({ button: 'right' });
await page.locator('text=Remove').click();
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
// navigate back to the display layout to confirm it has been removed
await page.locator('.c-tree__item .c-tree__item__name:text("Test Display Layout")').click();
diff --git a/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js b/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js
index f399daee0..d8ecbf962 100644
--- a/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js
+++ b/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js
@@ -40,10 +40,10 @@ test.describe('Example Imagery Object', () => {
await page.goto('./', { waitUntil: 'networkidle' });
// Create a default 'Example Imagery' object
- await createDomainObjectWithDefaults(page, { type: 'Example Imagery' });
+ const exampleImagery = await createDomainObjectWithDefaults(page, { type: 'Example Imagery' });
// Verify that the created object is focused
- await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery');
+ await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
await page.locator(backgroundImageSelector).hover({trial: true});
});
@@ -188,7 +188,7 @@ test.describe('Example Imagery in Display Layout', () => {
await page.click('button:has-text("Create")');
// Click text=Example Imagery
- await page.click('text=Example Imagery');
+ await page.click('li[role="menuitem"]:has-text("Example Imagery")');
// Clear and set Image load delay to minimum value
await page.locator('input[type="number"]').fill('');
@@ -197,7 +197,7 @@ test.describe('Example Imagery in Display Layout', () => {
// Click text=OK
await Promise.all([
page.waitForNavigation({waitUntil: 'networkidle'}),
- page.click('text=OK'),
+ page.click('button:has-text("OK")'),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
@@ -275,7 +275,7 @@ test.describe('Example Imagery in Flexible layout', () => {
await page.click('button:has-text("Create")');
// Click text=Example Imagery
- await page.click('text=Example Imagery');
+ await page.click('li[role="menuitem"]:has-text("Example Imagery")');
// Clear and set Image load delay to minimum value
await page.locator('input[type="number"]').fill('');
@@ -284,7 +284,7 @@ test.describe('Example Imagery in Flexible layout', () => {
// Click text=OK
await Promise.all([
page.waitForNavigation({waitUntil: 'networkidle'}),
- page.click('text=OK'),
+ page.click('button:has-text("OK")'),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
@@ -317,7 +317,7 @@ test.describe('Example Imagery in Tabs View', () => {
await page.click('button:has-text("Create")');
// Click text=Example Imagery
- await page.click('text=Example Imagery');
+ await page.click('li[role="menuitem"]:has-text("Example Imagery")');
// Clear and set Image load delay to minimum value
await page.locator('input[type="number"]').fill('');
@@ -326,7 +326,7 @@ test.describe('Example Imagery in Tabs View', () => {
// Click text=OK
await Promise.all([
page.waitForNavigation({waitUntil: 'networkidle'}),
- page.click('text=OK'),
+ page.click('button:has-text("OK")'),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
diff --git a/e2e/tests/functional/plugins/notebook/notebook.e2e.spec.js b/e2e/tests/functional/plugins/notebook/notebook.e2e.spec.js
index 58e3e0f38..f44140fe4 100644
--- a/e2e/tests/functional/plugins/notebook/notebook.e2e.spec.js
+++ b/e2e/tests/functional/plugins/notebook/notebook.e2e.spec.js
@@ -26,7 +26,7 @@ This test suite is dedicated to tests which verify the basic operations surround
// FIXME: Remove this eslint exception once tests are implemented
// eslint-disable-next-line no-unused-vars
-const { test, expect } = require('../../../../baseFixtures');
+const { test, expect } = require('../../../../pluginFixtures');
const { expandTreePaneItemByName, createDomainObjectWithDefaults } = require('../../../../appActions');
const nbUtils = require('../../../../helper/notebookUtils');
diff --git a/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js b/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js
index 97f5ab3c6..87a352797 100644
--- a/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js
+++ b/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js
@@ -24,7 +24,7 @@
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks with CouchDB.
*/
-const { test, expect } = require('../../../../baseFixtures');
+const { test, expect } = require('../../../../pluginFixtures');
const { createDomainObjectWithDefaults } = require('../../../../appActions');
test.describe('Notebook Tests with CouchDB @couchdb', () => {
diff --git a/e2e/tests/functional/plugins/notebook/restrictedNotebook.e2e.spec.js b/e2e/tests/functional/plugins/notebook/restrictedNotebook.e2e.spec.js
index 8594f5866..6a51238fd 100644
--- a/e2e/tests/functional/plugins/notebook/restrictedNotebook.e2e.spec.js
+++ b/e2e/tests/functional/plugins/notebook/restrictedNotebook.e2e.spec.js
@@ -36,27 +36,27 @@ test.describe('Restricted Notebook', () => {
});
test('Can be renamed @addInit', async ({ page }) => {
- await expect(page.locator('.l-browse-bar__object-name')).toContainText(`Unnamed ${CUSTOM_NAME}`);
+ await expect(page.locator('.l-browse-bar__object-name')).toContainText(`${notebook.name}`);
});
- test('Can be deleted if there are no locked pages @addInit', async ({ page, openmctConfig }) => {
+ test('Can be deleted if there are no locked pages @addInit', async ({ page }) => {
await openObjectTreeContextMenu(page, notebook.url);
const menuOptions = page.locator('.c-menu ul');
await expect.soft(menuOptions).toContainText('Remove');
- const restrictedNotebookTreeObject = page.locator(`a:has-text("Unnamed ${CUSTOM_NAME}")`);
+ const restrictedNotebookTreeObject = page.locator(`a:has-text("${notebook.name}")`);
// notebook tree object exists
expect.soft(await restrictedNotebookTreeObject.count()).toEqual(1);
// Click Remove Text
- await page.locator('text=Remove').click();
+ await page.locator('li[role="menuitem"]:has-text("Remove")').click();
// Click 'OK' on confirmation window and wait for save banner to appear
await Promise.all([
page.waitForNavigation(),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
page.waitForSelector('.c-message-banner__message')
]);
@@ -134,7 +134,7 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
// Click text=Ok
await Promise.all([
page.waitForNavigation(),
- page.locator('text=Ok').click()
+ page.locator('button:has-text("OK")').click()
]);
// deleted page, should no longer exist
@@ -145,10 +145,9 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
test.describe('Restricted Notebook with a page locked and with an embed @addInit', () => {
- test.beforeEach(async ({ page, openmctConfig }) => {
- const { myItemsFolderName } = openmctConfig;
- await startAndAddRestrictedNotebookObject(page);
- await nbUtils.dragAndDropEmbed(page, myItemsFolderName);
+ test.beforeEach(async ({ page }) => {
+ const notebook = await startAndAddRestrictedNotebookObject(page);
+ await nbUtils.dragAndDropEmbed(page, notebook);
});
test('Allows embeds to be deleted if page unlocked @addInit', async ({ page }) => {
diff --git a/e2e/tests/functional/plugins/notebook/tags.e2e.spec.js b/e2e/tests/functional/plugins/notebook/tags.e2e.spec.js
index 792117b3e..a8a3dd239 100644
--- a/e2e/tests/functional/plugins/notebook/tags.e2e.spec.js
+++ b/e2e/tests/functional/plugins/notebook/tags.e2e.spec.js
@@ -36,7 +36,7 @@ async function createNotebookAndEntry(page, iterations = 1) {
//Go to baseURL
await page.goto('./', { waitUntil: 'networkidle' });
- createDomainObjectWithDefaults(page, { type: 'Notebook' });
+ const notebook = createDomainObjectWithDefaults(page, { type: 'Notebook' });
for (let iteration = 0; iteration < iterations; iteration++) {
// Create an entry
@@ -45,6 +45,8 @@ async function createNotebookAndEntry(page, iterations = 1) {
await page.locator(entryLocator).click();
await page.locator(entryLocator).fill(`Entry ${iteration}`);
}
+
+ return notebook;
}
/**
@@ -53,7 +55,7 @@ async function createNotebookAndEntry(page, iterations = 1) {
* @param {number} [iterations = 1] - the number of entries (and tags) to create
*/
async function createNotebookEntryAndTags(page, iterations = 1) {
- await createNotebookAndEntry(page, iterations);
+ const notebook = await createNotebookAndEntry(page, iterations);
for (let iteration = 0; iteration < iterations; iteration++) {
// Hover and click "Add Tag" button
@@ -75,6 +77,8 @@ async function createNotebookEntryAndTags(page, iterations = 1) {
// Select the "Science" tag
await page.locator('[aria-label="Autocomplete Options"] >> text=Science').click();
}
+
+ return notebook;
}
test.describe('Tagging in Notebooks @addInit', () => {
@@ -173,10 +177,10 @@ test.describe('Tagging in Notebooks @addInit', () => {
//Go to baseURL
await page.goto('./', { waitUntil: 'networkidle' });
- await createDomainObjectWithDefaults(page, { type: 'Clock' });
+ const clock = await createDomainObjectWithDefaults(page, { type: 'Clock' });
const ITERATIONS = 4;
- await createNotebookEntryAndTags(page, ITERATIONS);
+ const notebook = await createNotebookEntryAndTags(page, ITERATIONS);
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
@@ -189,11 +193,11 @@ test.describe('Tagging in Notebooks @addInit', () => {
page.goto('./#/browse/mine?hideTree=false'),
page.click('.c-disclosure-triangle')
]);
- // Click Unnamed Clock
- await page.click('text="Unnamed Clock"');
+ // Click Clock
+ await page.click(`text=${clock.name}`);
- // Click Unnamed Notebook
- await page.click('text="Unnamed Notebook"');
+ // Click Notebook
+ await page.click(`text=${notebook.name}`);
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
@@ -207,14 +211,13 @@ test.describe('Tagging in Notebooks @addInit', () => {
page.waitForLoadState('networkidle')
]);
- // Click Unnamed Notebook
- await page.click('text="Unnamed Notebook"');
+ // Click Notebook
+ await page.click(`text="${notebook.name}"`);
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
await expect(page.locator(entryLocator)).toContainText("Science");
await expect(page.locator(entryLocator)).toContainText("Driving");
}
-
});
});
diff --git a/e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js b/e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js
index 81640b95c..a61525419 100644
--- a/e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js
+++ b/e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js
@@ -110,10 +110,10 @@ async function createSinewaveOverlayPlot(page, myItemsFolderName) {
await page.locator('button:has-text("Create")').click();
// add overlay plot with defaults
- await page.locator('li:has-text("Overlay Plot")').click();
+ await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
await Promise.all([
page.waitForNavigation(),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear1
page.waitForSelector('.c-message-banner__message')
]);
@@ -129,10 +129,10 @@ async function createSinewaveOverlayPlot(page, myItemsFolderName) {
await page.locator('button:has-text("Create")').click();
// add sine wave generator with defaults
- await page.locator('li:has-text("Sine Wave Generator")').click();
+ await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
await Promise.all([
page.waitForNavigation(),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear1
page.waitForSelector('.c-message-banner__message')
]);
diff --git a/e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js b/e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
index c76bf82cc..fa6b43eec 100644
--- a/e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
+++ b/e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
@@ -88,10 +88,10 @@ async function makeOverlayPlot(page, myItemsFolderName) {
// create overlay plot
await page.locator('button.c-create-button').click();
- await page.locator('li:has-text("Overlay Plot")').click();
+ await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle'}),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
@@ -106,7 +106,7 @@ async function makeOverlayPlot(page, myItemsFolderName) {
// create a sinewave generator
await page.locator('button.c-create-button').click();
- await page.locator('li:has-text("Sine Wave Generator")').click();
+ await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
// set amplitude to 6, offset 4, period 2
@@ -123,7 +123,7 @@ async function makeOverlayPlot(page, myItemsFolderName) {
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle'}),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
diff --git a/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js b/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js
index 0e1eec5c7..a6bdd622e 100644
--- a/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js
+++ b/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js
@@ -88,11 +88,11 @@ async function makeStackedPlot(page, myItemsFolderName) {
// create stacked plot
await page.locator('button.c-create-button').click();
- await page.locator('li:has-text("Stacked Plot")').click();
+ await page.locator('li[role="menuitem"]:has-text("Stacked Plot")').click();
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle'}),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
@@ -146,11 +146,11 @@ async function saveStackedPlot(page) {
async function createSineWaveGenerator(page) {
//Create sine wave generator
await page.locator('button.c-create-button').click();
- await page.locator('li:has-text("Sine Wave Generator")').click();
+ await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle'}),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
diff --git a/e2e/tests/functional/plugins/plot/plotLegendSwatch.e2e.spec.js b/e2e/tests/functional/plugins/plot/plotLegendSwatch.e2e.spec.js
index 25a5e348d..86381f3a8 100644
--- a/e2e/tests/functional/plugins/plot/plotLegendSwatch.e2e.spec.js
+++ b/e2e/tests/functional/plugins/plot/plotLegendSwatch.e2e.spec.js
@@ -68,10 +68,10 @@ async function makeOverlayPlot(page) {
// create overlay plot
await page.locator('button.c-create-button').click();
- await page.locator('li:has-text("Overlay Plot")').click();
+ await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle'}),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
@@ -86,13 +86,13 @@ async function makeOverlayPlot(page) {
// create a sinewave generator
await page.locator('button.c-create-button').click();
- await page.locator('li:has-text("Sine Wave Generator")').click();
+ await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
// Click OK to make generator
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle'}),
- page.locator('text=OK').click(),
+ page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);
diff --git a/e2e/tests/functional/plugins/plot/plotRendering.e2e.spec.js b/e2e/tests/functional/plugins/plot/plotRendering.e2e.spec.js
index 30e863322..2979a9a3b 100644
--- a/e2e/tests/functional/plugins/plot/plotRendering.e2e.spec.js
+++ b/e2e/tests/functional/plugins/plot/plotRendering.e2e.spec.js
@@ -25,7 +25,7 @@
*
*/
-const { test, expect } = require('../../../../baseFixtures');
+const { test, expect } = require('../../../../pluginFixtures');
const { createDomainObjectWithDefaults } = require('../../../../appActions');
test.describe('Plot Integrity Testing @unstable', () => {
diff --git a/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js b/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js
index 645c4fc91..14494b5d9 100644
--- a/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js
+++ b/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js
@@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
-const { test, expect } = require('../../../../baseFixtures');
+const { test, expect } = require('../../../../pluginFixtures');
const { setFixedTimeMode, setRealTimeMode, setStartOffset, setEndOffset } = require('../../../../appActions');
test.describe('Time conductor operations', () => {
diff --git a/e2e/tests/functional/plugins/timer/timer.e2e.spec.js b/e2e/tests/functional/plugins/timer/timer.e2e.spec.js
index 16c6b5def..9269c0cac 100644
--- a/e2e/tests/functional/plugins/timer/timer.e2e.spec.js
+++ b/e2e/tests/functional/plugins/timer/timer.e2e.spec.js
@@ -30,7 +30,7 @@ test.describe('Timer', () => {
timer = await createDomainObjectWithDefaults(page, { type: 'timer' });
});
- test('Can perform actions on the Timer', async ({ page, openmctConfig }) => {
+ test('Can perform actions on the Timer', async ({ page }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/4313'
diff --git a/e2e/tests/functional/search.e2e.spec.js b/e2e/tests/functional/search.e2e.spec.js
index a94459969..2aa411656 100644
--- a/e2e/tests/functional/search.e2e.spec.js
+++ b/e2e/tests/functional/search.e2e.spec.js
@@ -31,7 +31,7 @@ test.describe('Grand Search', () => {
test('Can search for objects, and subsequent search dropdown behaves properly', async ({ page, openmctConfig }) => {
const { myItemsFolderName } = openmctConfig;
- await createObjectsForSearch(page, myItemsFolderName);
+ const createdObjects = await createObjectsForSearch(page);
// Click [aria-label="OpenMCT Search"] input[type="search"]
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
@@ -41,8 +41,8 @@ test.describe('Grand Search', () => {
await expect(page.locator('[aria-label="Search Result"] >> nth=1')).toContainText(`Clock B ${myItemsFolderName} Red Folder Blue Folder`);
await expect(page.locator('[aria-label="Search Result"] >> nth=2')).toContainText(`Clock C ${myItemsFolderName} Red Folder Blue Folder`);
await expect(page.locator('[aria-label="Search Result"] >> nth=3')).toContainText(`Clock D ${myItemsFolderName} Red Folder Blue Folder`);
- // Click text=Elements >> nth=0
- await page.locator('text=Elements').first().click();
+ // Click the Elements pool to dismiss the search menu
+ await page.locator('.l-pane__label:has-text("Elements")').click();
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').click();
@@ -77,7 +77,7 @@ test.describe('Grand Search', () => {
await expect(page.locator('.is-object-type-clock')).toBeVisible();
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').fill('Disp');
- await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText('Unnamed Display Layout');
+ await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(createdObjects.displayLayout.name);
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).not.toContainText('Folder');
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Clock C');
@@ -185,7 +185,7 @@ async function createFolderObject(page, folderName) {
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(folderName);
// Create folder object
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
}
async function waitForSearchCompletion(page) {
@@ -197,75 +197,56 @@ async function waitForSearchCompletion(page) {
* Creates some domain objects for searching
* @param {import('@playwright/test').Page} page
*/
-async function createObjectsForSearch(page, myItemsFolderName) {
+async function createObjectsForSearch(page) {
//Go to baseURL
await page.goto('./', { waitUntil: 'networkidle' });
- await page.locator('button:has-text("Create")').click();
- await page.locator('li:has-text("Folder") >> nth=1').click();
- await Promise.all([
- page.waitForNavigation(),
- await page.locator('text=Properties Title Notes >> input[type="text"]').fill('Red Folder'),
- await page.locator(`text=Save In Open MCT ${myItemsFolderName} >> span`).nth(3).click(),
- page.locator('button:has-text("OK")').click()
- ]);
-
- await page.locator('button:has-text("Create")').click();
- await page.locator('li:has-text("Folder") >> nth=2').click();
- await Promise.all([
- page.waitForNavigation(),
- await page.locator('text=Properties Title Notes >> input[type="text"]').fill('Blue Folder'),
- await page.locator('form[name="mctForm"] >> text=Red Folder').click(),
- page.locator('button:has-text("OK")').click()
- ]);
+ const redFolder = await createDomainObjectWithDefaults(page, {
+ type: 'Folder',
+ name: 'Red Folder'
+ });
- await page.locator('button:has-text("Create")').click();
- await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
- await Promise.all([
- page.waitForNavigation(),
- await page.locator('text=Properties Title Notes >> input[type="text"] >> nth=0').fill('Clock A'),
- await page.locator('form[name="mctForm"] >> text=Blue Folder').click(),
- page.locator('button:has-text("OK")').click()
- ]);
+ const blueFolder = await createDomainObjectWithDefaults(page, {
+ type: 'Folder',
+ name: 'Blue Folder',
+ parent: redFolder.uuid
+ });
- await page.locator('button:has-text("Create")').click();
- await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
- await Promise.all([
- page.waitForNavigation(),
- await page.locator('text=Properties Title Notes >> input[type="text"] >> nth=0').fill('Clock B'),
- await page.locator('form[name="mctForm"] >> text=Blue Folder').click(),
- page.locator('button:has-text("OK")').click()
- ]);
+ const clockA = await createDomainObjectWithDefaults(page, {
+ type: 'Clock',
+ name: 'Clock A',
+ parent: blueFolder.uuid
+ });
+ const clockB = await createDomainObjectWithDefaults(page, {
+ type: 'Clock',
+ name: 'Clock B',
+ parent: blueFolder.uuid
+ });
+ const clockC = await createDomainObjectWithDefaults(page, {
+ type: 'Clock',
+ name: 'Clock C',
+ parent: blueFolder.uuid
+ });
+ const clockD = await createDomainObjectWithDefaults(page, {
+ type: 'Clock',
+ name: 'Clock D',
+ parent: blueFolder.uuid
+ });
- await page.locator('button:has-text("Create")').click();
- await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
- await Promise.all([
- page.waitForNavigation(),
- await page.locator('text=Properties Title Notes >> input[type="text"] >> nth=0').fill('Clock C'),
- await page.locator('form[name="mctForm"] >> text=Blue Folder').click(),
- page.locator('button:has-text("OK")').click()
- ]);
+ const displayLayout = await createDomainObjectWithDefaults(page, {
+ type: 'Display Layout'
+ });
- await page.locator('button:has-text("Create")').click();
- await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
- await Promise.all([
- page.waitForNavigation(),
- await page.locator('text=Properties Title Notes >> input[type="text"] >> nth=0').fill('Clock D'),
- await page.locator('form[name="mctForm"] >> text=Blue Folder').click(),
- page.locator('button:has-text("OK")').click()
- ]);
-
- await Promise.all([
- page.waitForNavigation(),
- page.locator(`a:has-text("${myItemsFolderName}") >> nth=0`).click()
- ]);
- // Click button:has-text("Create")
- await page.locator('button:has-text("Create")').click();
- // Click li:has-text("Notebook")
- await page.locator('li:has-text("Display Layout")').click();
- // Click button:has-text("OK")
- await Promise.all([
- page.waitForNavigation(),
- page.locator('button:has-text("OK")').click()
- ]);
+ // Go back into edit mode for the display layout
+ await page.locator('button[title="Edit"]').click();
+
+ return {
+ redFolder,
+ blueFolder,
+ clockA,
+ clockB,
+ clockC,
+ clockD,
+ displayLayout
+ };
}
diff --git a/e2e/tests/performance/imagery.perf.spec.js b/e2e/tests/performance/imagery.perf.spec.js
index 396f249af..0cbe35bb8 100644
--- a/e2e/tests/performance/imagery.perf.spec.js
+++ b/e2e/tests/performance/imagery.perf.spec.js
@@ -53,7 +53,7 @@ test.describe('Performance tests', () => {
await page.setInputFiles('#fileElem', filePath);
// Click text=OK
- await page.locator('text=OK').click();
+ await page.locator('button:has-text("OK")').click();
await expect(page.locator('a:has-text("Performance Display Layout Display Layout")')).toBeVisible();
diff --git a/src/api/forms/components/controls/TextAreaField.vue b/src/api/forms/components/controls/TextAreaField.vue
index 834940b34..25e3c219f 100644
--- a/src/api/forms/components/controls/TextAreaField.vue
+++ b/src/api/forms/components/controls/TextAreaField.vue
@@ -27,6 +27,7 @@
:class="model.cssClass"
>
<textarea
+ :id="`${model.key}-textarea`"
v-model="field"
type="text"
:size="model.size"
diff --git a/src/api/menu/components/Menu.vue b/src/api/menu/components/Menu.vue
index 23a11f19b..051a4b538 100644
--- a/src/api/menu/components/Menu.vue
+++ b/src/api/menu/components/Menu.vue
@@ -3,39 +3,52 @@
class="c-menu"
:class="options.menuClass"
>
- <ul v-if="options.actions.length && options.actions[0].length">
+ <ul
+ v-if="options.actions.length && options.actions[0].length"
+ role="menu"
+ >
<template
v-for="(actionGroups, index) in options.actions"
>
- <li
- v-for="action in actionGroups"
- :key="action.name"
- :class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
- :title="action.description"
- :data-testid="action.testId || false"
- @click="action.onItemClicked"
- >
- {{ action.name }}
- </li>
<div
- v-if="index !== options.actions.length - 1"
- :key="index"
- class="c-menu__section-separator"
- >
- </div>
- <li
- v-if="actionGroups.length === 0"
:key="index"
+ role="group"
>
- No actions defined.
- </li>
- </template>
+ <li
+ v-for="action in actionGroups"
+ :key="action.name"
+ role="menuitem"
+ :class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
+ :title="action.description"
+ :data-testid="action.testId || false"
+ @click="action.onItemClicked"
+ >
+ {{ action.name }}
+ </li>
+ <div
+ v-if="index !== options.actions.length - 1"
+ :key="index"
+ role="separator"
+ class="c-menu__section-separator"
+ >
+ </div>
+ <li
+ v-if="actionGroups.length === 0"
+ :key="index"
+ >
+ No actions defined.
+ </li>
+ </div></template>
</ul>
- <ul v-else>
+ <ul
+ v-else
+ role="menu"
+ >
<li
v-for="action in options.actions"
:key="action.name"
+ role="menuitem"
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
:title="action.description"
:data-testid="action.testId || false"
diff --git a/src/api/menu/components/SuperMenu.vue b/src/api/menu/components/SuperMenu.vue
index 7b66c68b6..70db21b93 100644
--- a/src/api/menu/components/SuperMenu.vue
+++ b/src/api/menu/components/SuperMenu.vue
@@ -5,45 +5,54 @@
>
<ul
v-if="options.actions.length && options.actions[0].length"
+ role="menu"
class="c-super-menu__menu"
>
<template
v-for="(actionGroups, index) in options.actions"
>
- <li
- v-for="action in actionGroups"
- :key="action.name"
- :class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
- :title="action.description"
- :data-testid="action.testId || false"
- @click="action.onItemClicked"
- @mouseover="toggleItemDescription(action)"
- @mouseleave="toggleItemDescription()"
- >
- {{ action.name }}
- </li>
<div
- v-if="index !== options.actions.length - 1"
- :key="index"
- class="c-menu__section-separator"
- >
- </div>
- <li
- v-if="actionGroups.length === 0"
:key="index"
+ role="group"
>
- No actions defined.
- </li>
- </template>
+ <li
+ v-for="action in actionGroups"
+ :key="action.name"
+ role="menuitem"
+ :class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
+ :title="action.description"
+ :data-testid="action.testId || false"
+ @click="action.onItemClicked"
+ @mouseover="toggleItemDescription(action)"
+ @mouseleave="toggleItemDescription()"
+ >
+ {{ action.name }}
+ </li>
+ <div
+ v-if="index !== options.actions.length - 1"
+ :key="index"
+ role="separator"
+ class="c-menu__section-separator"
+ >
+ </div>
+ <li
+ v-if="actionGroups.length === 0"
+ :key="index"
+ >
+ No actions defined.
+ </li>
+ </div></template>
</ul>
<ul
v-else
class="c-super-menu__menu"
+ role="menu"
>
<li
v-for="action in options.actions"
:key="action.name"
+ role="menuitem"
:class="action.cssClass"
:title="action.description"
:data-testid="action.testId || false"