mirror of
https://github.com/nasa/openmct.git
synced 2025-06-15 05:38:12 +00:00
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
This commit is contained in:
@ -46,6 +46,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Buffer = require('buffer').Buffer;
|
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
|
* 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.
|
* @returns {Promise<CreatedObjectInfo>} An object containing information about the newly created domain object.
|
||||||
*/
|
*/
|
||||||
async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine' }) {
|
async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine' }) {
|
||||||
|
if (!name) {
|
||||||
|
name = `${type}:${genUuid()}`;
|
||||||
|
}
|
||||||
|
|
||||||
const parentUrl = await getHashUrlToDomainObject(page, parent);
|
const parentUrl = await getHashUrlToDomainObject(page, parent);
|
||||||
|
|
||||||
// Navigate to the parent object. This is necessary to create the object
|
// 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}")`);
|
await page.click(`li:text("${type}")`);
|
||||||
|
|
||||||
// Modify the name input field of the domain object to accept 'name'
|
// 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"]');
|
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
||||||
await nameInput.fill("");
|
await nameInput.fill("");
|
||||||
await nameInput.fill(name);
|
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
|
// Click OK button and wait for Navigate event
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -96,8 +104,8 @@ async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: name || `Unnamed ${type}`,
|
name,
|
||||||
uuid: uuid,
|
uuid,
|
||||||
url: objectUrl
|
url: objectUrl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const { createDomainObjectWithDefaults } = require('../appActions');
|
||||||
|
|
||||||
const NOTEBOOK_DROP_AREA = '.c-notebook__drag-area';
|
const NOTEBOOK_DROP_AREA = '.c-notebook__drag-area';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,24 +40,17 @@ async function enterTextEntry(page, text) {
|
|||||||
/**
|
/**
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function dragAndDropEmbed(page, myItemsFolderName) {
|
async function dragAndDropEmbed(page, notebookObject) {
|
||||||
// Click button:has-text("Create")
|
// Create example telemetry object
|
||||||
await page.locator('button:has-text("Create")').click();
|
const swg = await createDomainObjectWithDefaults(page, {
|
||||||
// Click li:has-text("Sine Wave Generator")
|
type: "Sine Wave Generator"
|
||||||
await page.locator('li:has-text("Sine Wave Generator")').click();
|
});
|
||||||
// Click form[name="mctForm"] >> text=My Items
|
// Navigate to notebook
|
||||||
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).click();
|
await page.goto(notebookObject.url);
|
||||||
// Click text=OK
|
// Expand the tree to reveal the notebook
|
||||||
await page.locator('text=OK').click();
|
await page.click('button[title="Show selected item in tree"]');
|
||||||
// Click text=Open MCT My Items >> span >> nth=3
|
// Drag and drop the SWG into the notebook
|
||||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
await page.dragAndDrop(`text=${swg.name}`, NOTEBOOK_DROP_AREA);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
|
@ -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
|
// This should follow in the Project's configuration. Can be set to 'snow' in playwright config.js
|
||||||
theme: [theme, { option: true }],
|
theme: [theme, { option: true }],
|
||||||
// eslint-disable-next-line no-shadow
|
// 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
|
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||||
if (theme === 'snow') {
|
if (theme === 'snow') {
|
||||||
//inject snow theme
|
//inject snow theme
|
||||||
await page.addInitScript({ path: path.join(__dirname, './helper', './useSnowTheme.js') });
|
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);
|
await use(page);
|
||||||
},
|
},
|
||||||
myItemsFolderName: [myItemsFolderName, { option: true }],
|
myItemsFolderName: [myItemsFolderName, { option: true }],
|
||||||
@ -140,22 +148,5 @@ exports.test = test.extend({
|
|||||||
openmctConfig: async ({ myItemsFolderName }, use) => {
|
openmctConfig: async ({ myItemsFolderName }, use) => {
|
||||||
await use({ myItemsFolderName });
|
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;
|
exports.expect = expect;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* 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');
|
const { createDomainObjectWithDefaults } = require('../../appActions.js');
|
||||||
|
|
||||||
test.describe('AppActions', () => {
|
test.describe('AppActions', () => {
|
||||||
@ -50,11 +50,11 @@ test.describe('AppActions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await page.goto(timer1.url, { waitUntil: 'networkidle' });
|
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 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 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 () => {
|
await test.step('Create multiple nested objects in a row', async () => {
|
||||||
@ -74,11 +74,11 @@ test.describe('AppActions', () => {
|
|||||||
parent: folder2.uuid
|
parent: folder2.uuid
|
||||||
});
|
});
|
||||||
await page.goto(folder1.url, { waitUntil: 'networkidle' });
|
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 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 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(folder1.url).toBe(`${e2eFolder.url}/${folder1.uuid}`);
|
||||||
expect(folder2.url).toBe(`${e2eFolder.url}/${folder1.uuid}/${folder2.uuid}`);
|
expect(folder2.url).toBe(`${e2eFolder.url}/${folder1.uuid}/${folder2.uuid}`);
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Structure: Some standard Imports. Please update the required pathing.
|
// Structure: Some standard Imports. Please update the required pathing.
|
||||||
const { test, expect } = require('../../baseFixtures');
|
const { test, expect } = require('../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults } = require('../../appActions');
|
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);
|
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(newNameForTimer);
|
||||||
|
|
||||||
// Click Ok button to Save
|
// Click Ok button to Save
|
||||||
await page.locator('text=OK').click();
|
await page.locator('button:has-text("OK")').click();
|
||||||
}
|
}
|
||||||
|
@ -43,14 +43,14 @@ test('Generate Visual Test Data @localStorage', async ({ page, context }) => {
|
|||||||
await page.locator('button:has-text("Create")').click();
|
await page.locator('button:has-text("Create")').click();
|
||||||
|
|
||||||
// add sine wave generator with defaults
|
// 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
|
//Add a 5000 ms Delay
|
||||||
await page.locator('[aria-label="Loading Delay \\(ms\\)"]').fill('5000');
|
await page.locator('[aria-label="Loading Delay \\(ms\\)"]').fill('5000');
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -58,7 +58,7 @@ test('Generate Visual Test Data @localStorage', async ({ page, context }) => {
|
|||||||
// focus the overlay plot
|
// focus the overlay plot
|
||||||
await page.goto(overlayPlot.url);
|
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
|
//Save localStorage for future test execution
|
||||||
await context.storageState({ path: './e2e/test-data/VisualTestData_storage.json' });
|
await context.storageState({ path: './e2e/test-data/VisualTestData_storage.json' });
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../baseFixtures');
|
const { test, expect } = require('../../pluginFixtures');
|
||||||
|
|
||||||
test.describe("CouchDB Status Indicator @couchdb", () => {
|
test.describe("CouchDB Status Indicator @couchdb", () => {
|
||||||
test.use({ failOnConsoleError: false });
|
test.use({ failOnConsoleError: false });
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
This test suite is dedicated to tests which verify the basic operations surrounding the example event generator.
|
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');
|
const { createDomainObjectWithDefaults } = require('../../../appActions');
|
||||||
|
|
||||||
test.describe('Example Event Generator CRUD Operations', () => {
|
test.describe('Example Event Generator CRUD Operations', () => {
|
||||||
|
@ -96,7 +96,7 @@ test.describe('Sine Wave Generator', () => {
|
|||||||
//Click text=OK
|
//Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.click('text=OK')
|
page.click('button:has-text("OK")')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Verify that the Sine Wave Generator is displayed and correct
|
// Verify that the Sine Wave Generator is displayed and correct
|
||||||
|
@ -43,7 +43,7 @@ test.describe('Form Validation Behavior', () => {
|
|||||||
await page.press('text=Properties Title Notes >> input[type="text"]', 'Tab');
|
await page.press('text=Properties Title Notes >> input[type="text"]', 'Tab');
|
||||||
|
|
||||||
//Required Field Form Validation
|
//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/);
|
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/invalid/);
|
||||||
|
|
||||||
//Correct Form Validation for missing title and trigger validation with 'Tab'
|
//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');
|
await page.press('text=Properties Title Notes >> input[type="text"]', 'Tab');
|
||||||
|
|
||||||
//Required Field Form Validation is corrected
|
//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/);
|
await expect(page.locator('.c-form-row__state-indicator').first()).not.toHaveClass(/invalid/);
|
||||||
|
|
||||||
//Finish Creating Domain Object
|
//Finish Creating Domain Object
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
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
|
//Verify that the Domain Object has been created with the corrected title property
|
||||||
|
@ -81,7 +81,7 @@ test.describe('Move & link item tests', () => {
|
|||||||
await page.locator('li.icon-move').click();
|
await page.locator('li.icon-move').click();
|
||||||
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).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 that Child Folder is in My Items, the root folder
|
||||||
expect(page.locator(`text=${myItemsFolderName} >> nth=0:has(text=Child Folder)`)).toBeTruthy();
|
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
|
// Create Telemetry Table
|
||||||
let telemetryTable = 'Test Telemetry Table';
|
let telemetryTable = 'Test Telemetry Table';
|
||||||
await page.locator('button:has-text("Create")').click();
|
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"]').click();
|
||||||
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(telemetryTable);
|
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
|
// Finish editing and save Telemetry Table
|
||||||
await page.locator('.c-button--menu.c-button--major.icon-save').click();
|
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
|
// Create New Folder Basic Domain Object
|
||||||
let folder = 'Test Folder';
|
let folder = 'Test Folder';
|
||||||
await page.locator('button:has-text("Create")').click();
|
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"]').click();
|
||||||
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(folder);
|
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
|
// Continue test regardless of assertion and create it in My Items
|
||||||
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).click();
|
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
|
// Open My Items
|
||||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
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('li.icon-link').click();
|
||||||
await page.locator(`form[name="mctForm"] >> text=${myItemsFolderName}`).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 that Child Folder is in My Items, the root folder
|
||||||
expect(page.locator(`text=${myItemsFolderName} >> nth=0:has(text=Child Folder)`)).toBeTruthy();
|
expect(page.locator(`text=${myItemsFolderName} >> nth=0:has(text=Child Folder)`)).toBeTruthy();
|
||||||
|
@ -40,11 +40,11 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
await page.click('button:has-text("Create")');
|
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([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.click('text=OK')
|
page.click('button:has-text("OK")')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//Save localStorage for future test execution
|
//Save localStorage for future test execution
|
||||||
@ -163,9 +163,9 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
// Click hamburger button
|
// Click hamburger button
|
||||||
await page.locator('[title="More options"]').click();
|
await page.locator('[title="More options"]').click();
|
||||||
|
|
||||||
// Click text=Remove
|
// Click 'Remove' and press OK
|
||||||
await page.locator('text=Remove').click();
|
await page.locator('li[role="menuitem"]:has-text("Remove")').click();
|
||||||
await page.locator('text=OK').click();
|
await page.locator('button:has-text("OK")').click();
|
||||||
|
|
||||||
//Expect Unnamed Condition Set to be removed in Main View
|
//Expect Unnamed Condition Set to be removed in Main View
|
||||||
const numberOfConditionSetsAtEnd = await page.locator('a:has-text("Unnamed Condition Set Condition Set")').count();
|
const numberOfConditionSetsAtEnd = await page.locator('a:has-text("Unnamed Condition Set Condition Set")').count();
|
||||||
|
@ -116,8 +116,8 @@ test.describe('Testing Display Layout @unstable', () => {
|
|||||||
|
|
||||||
// Bring up context menu and remove
|
// 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('.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('li[role="menuitem"]:has-text("Remove")').click();
|
||||||
await page.locator('text=OK').click();
|
await page.locator('button:has-text("OK")').click();
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ test.describe('Testing Display Layout @unstable', () => {
|
|||||||
// Bring up context menu and remove
|
// 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('.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=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
|
// 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();
|
await page.locator('.c-tree__item .c-tree__item__name:text("Test Display Layout")').click();
|
||||||
|
@ -40,10 +40,10 @@ test.describe('Example Imagery Object', () => {
|
|||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
// Create a default 'Example Imagery' object
|
// 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
|
// 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});
|
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")');
|
await page.click('button:has-text("Create")');
|
||||||
|
|
||||||
// Click text=Example Imagery
|
// 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
|
// Clear and set Image load delay to minimum value
|
||||||
await page.locator('input[type="number"]').fill('');
|
await page.locator('input[type="number"]').fill('');
|
||||||
@ -197,7 +197,7 @@ test.describe('Example Imagery in Display Layout', () => {
|
|||||||
// Click text=OK
|
// Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation({waitUntil: 'networkidle'}),
|
||||||
page.click('text=OK'),
|
page.click('button:has-text("OK")'),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -275,7 +275,7 @@ test.describe('Example Imagery in Flexible layout', () => {
|
|||||||
await page.click('button:has-text("Create")');
|
await page.click('button:has-text("Create")');
|
||||||
|
|
||||||
// Click text=Example Imagery
|
// 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
|
// Clear and set Image load delay to minimum value
|
||||||
await page.locator('input[type="number"]').fill('');
|
await page.locator('input[type="number"]').fill('');
|
||||||
@ -284,7 +284,7 @@ test.describe('Example Imagery in Flexible layout', () => {
|
|||||||
// Click text=OK
|
// Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation({waitUntil: 'networkidle'}),
|
||||||
page.click('text=OK'),
|
page.click('button:has-text("OK")'),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -317,7 +317,7 @@ test.describe('Example Imagery in Tabs View', () => {
|
|||||||
await page.click('button:has-text("Create")');
|
await page.click('button:has-text("Create")');
|
||||||
|
|
||||||
// Click text=Example Imagery
|
// 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
|
// Clear and set Image load delay to minimum value
|
||||||
await page.locator('input[type="number"]').fill('');
|
await page.locator('input[type="number"]').fill('');
|
||||||
@ -326,7 +326,7 @@ test.describe('Example Imagery in Tabs View', () => {
|
|||||||
// Click text=OK
|
// Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation({waitUntil: 'networkidle'}),
|
||||||
page.click('text=OK'),
|
page.click('button:has-text("OK")'),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
@ -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
|
// FIXME: Remove this eslint exception once tests are implemented
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { test, expect } = require('../../../../baseFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { expandTreePaneItemByName, createDomainObjectWithDefaults } = require('../../../../appActions');
|
const { expandTreePaneItemByName, createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
const nbUtils = require('../../../../helper/notebookUtils');
|
const nbUtils = require('../../../../helper/notebookUtils');
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks with CouchDB.
|
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');
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Notebook Tests with CouchDB @couchdb', () => {
|
test.describe('Notebook Tests with CouchDB @couchdb', () => {
|
||||||
|
@ -36,27 +36,27 @@ test.describe('Restricted Notebook', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Can be renamed @addInit', async ({ page }) => {
|
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);
|
await openObjectTreeContextMenu(page, notebook.url);
|
||||||
|
|
||||||
const menuOptions = page.locator('.c-menu ul');
|
const menuOptions = page.locator('.c-menu ul');
|
||||||
await expect.soft(menuOptions).toContainText('Remove');
|
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
|
// notebook tree object exists
|
||||||
expect.soft(await restrictedNotebookTreeObject.count()).toEqual(1);
|
expect.soft(await restrictedNotebookTreeObject.count()).toEqual(1);
|
||||||
|
|
||||||
// Click Remove Text
|
// 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
|
// Click 'OK' on confirmation window and wait for save banner to appear
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
page.waitForSelector('.c-message-banner__message')
|
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
|
// Click text=Ok
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('text=Ok').click()
|
page.locator('button:has-text("OK")').click()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// deleted page, should no longer exist
|
// 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.describe('Restricted Notebook with a page locked and with an embed @addInit', () => {
|
||||||
|
|
||||||
test.beforeEach(async ({ page, openmctConfig }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const notebook = await startAndAddRestrictedNotebookObject(page);
|
||||||
await startAndAddRestrictedNotebookObject(page);
|
await nbUtils.dragAndDropEmbed(page, notebook);
|
||||||
await nbUtils.dragAndDropEmbed(page, myItemsFolderName);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Allows embeds to be deleted if page unlocked @addInit', async ({ page }) => {
|
test('Allows embeds to be deleted if page unlocked @addInit', async ({ page }) => {
|
||||||
|
@ -36,7 +36,7 @@ async function createNotebookAndEntry(page, iterations = 1) {
|
|||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
createDomainObjectWithDefaults(page, { type: 'Notebook' });
|
const notebook = createDomainObjectWithDefaults(page, { type: 'Notebook' });
|
||||||
|
|
||||||
for (let iteration = 0; iteration < iterations; iteration++) {
|
for (let iteration = 0; iteration < iterations; iteration++) {
|
||||||
// Create an entry
|
// Create an entry
|
||||||
@ -45,6 +45,8 @@ async function createNotebookAndEntry(page, iterations = 1) {
|
|||||||
await page.locator(entryLocator).click();
|
await page.locator(entryLocator).click();
|
||||||
await page.locator(entryLocator).fill(`Entry ${iteration}`);
|
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
|
* @param {number} [iterations = 1] - the number of entries (and tags) to create
|
||||||
*/
|
*/
|
||||||
async function createNotebookEntryAndTags(page, iterations = 1) {
|
async function createNotebookEntryAndTags(page, iterations = 1) {
|
||||||
await createNotebookAndEntry(page, iterations);
|
const notebook = await createNotebookAndEntry(page, iterations);
|
||||||
|
|
||||||
for (let iteration = 0; iteration < iterations; iteration++) {
|
for (let iteration = 0; iteration < iterations; iteration++) {
|
||||||
// Hover and click "Add Tag" button
|
// Hover and click "Add Tag" button
|
||||||
@ -75,6 +77,8 @@ async function createNotebookEntryAndTags(page, iterations = 1) {
|
|||||||
// Select the "Science" tag
|
// Select the "Science" tag
|
||||||
await page.locator('[aria-label="Autocomplete Options"] >> text=Science').click();
|
await page.locator('[aria-label="Autocomplete Options"] >> text=Science').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return notebook;
|
||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Tagging in Notebooks @addInit', () => {
|
test.describe('Tagging in Notebooks @addInit', () => {
|
||||||
@ -173,10 +177,10 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, { type: 'Clock' });
|
const clock = await createDomainObjectWithDefaults(page, { type: 'Clock' });
|
||||||
|
|
||||||
const ITERATIONS = 4;
|
const ITERATIONS = 4;
|
||||||
await createNotebookEntryAndTags(page, ITERATIONS);
|
const notebook = await createNotebookEntryAndTags(page, ITERATIONS);
|
||||||
|
|
||||||
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${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.goto('./#/browse/mine?hideTree=false'),
|
||||||
page.click('.c-disclosure-triangle')
|
page.click('.c-disclosure-triangle')
|
||||||
]);
|
]);
|
||||||
// Click Unnamed Clock
|
// Click Clock
|
||||||
await page.click('text="Unnamed Clock"');
|
await page.click(`text=${clock.name}`);
|
||||||
|
|
||||||
// Click Unnamed Notebook
|
// Click Notebook
|
||||||
await page.click('text="Unnamed Notebook"');
|
await page.click(`text=${notebook.name}`);
|
||||||
|
|
||||||
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
||||||
@ -207,14 +211,13 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
page.waitForLoadState('networkidle')
|
page.waitForLoadState('networkidle')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Click Unnamed Notebook
|
// Click Notebook
|
||||||
await page.click('text="Unnamed Notebook"');
|
await page.click(`text="${notebook.name}"`);
|
||||||
|
|
||||||
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
||||||
await expect(page.locator(entryLocator)).toContainText("Science");
|
await expect(page.locator(entryLocator)).toContainText("Science");
|
||||||
await expect(page.locator(entryLocator)).toContainText("Driving");
|
await expect(page.locator(entryLocator)).toContainText("Driving");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -110,10 +110,10 @@ async function createSinewaveOverlayPlot(page, myItemsFolderName) {
|
|||||||
await page.locator('button:has-text("Create")').click();
|
await page.locator('button:has-text("Create")').click();
|
||||||
|
|
||||||
// add overlay plot with defaults
|
// 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([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear1
|
//Wait for Save Banner to appear1
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -129,10 +129,10 @@ async function createSinewaveOverlayPlot(page, myItemsFolderName) {
|
|||||||
await page.locator('button:has-text("Create")').click();
|
await page.locator('button:has-text("Create")').click();
|
||||||
|
|
||||||
// add sine wave generator with defaults
|
// 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([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear1
|
//Wait for Save Banner to appear1
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
@ -88,10 +88,10 @@ async function makeOverlayPlot(page, myItemsFolderName) {
|
|||||||
// create overlay plot
|
// create overlay plot
|
||||||
|
|
||||||
await page.locator('button.c-create-button').click();
|
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([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -106,7 +106,7 @@ async function makeOverlayPlot(page, myItemsFolderName) {
|
|||||||
// create a sinewave generator
|
// create a sinewave generator
|
||||||
|
|
||||||
await page.locator('button.c-create-button').click();
|
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
|
// set amplitude to 6, offset 4, period 2
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ async function makeOverlayPlot(page, myItemsFolderName) {
|
|||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
@ -88,11 +88,11 @@ async function makeStackedPlot(page, myItemsFolderName) {
|
|||||||
|
|
||||||
// create stacked plot
|
// create stacked plot
|
||||||
await page.locator('button.c-create-button').click();
|
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([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -146,11 +146,11 @@ async function saveStackedPlot(page) {
|
|||||||
async function createSineWaveGenerator(page) {
|
async function createSineWaveGenerator(page) {
|
||||||
//Create sine wave generator
|
//Create sine wave generator
|
||||||
await page.locator('button.c-create-button').click();
|
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([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
@ -68,10 +68,10 @@ async function makeOverlayPlot(page) {
|
|||||||
// create overlay plot
|
// create overlay plot
|
||||||
|
|
||||||
await page.locator('button.c-create-button').click();
|
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([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
@ -86,13 +86,13 @@ async function makeOverlayPlot(page) {
|
|||||||
// create a sinewave generator
|
// create a sinewave generator
|
||||||
|
|
||||||
await page.locator('button.c-create-button').click();
|
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
|
// Click OK to make generator
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||||
page.locator('text=OK').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../baseFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Plot Integrity Testing @unstable', () => {
|
test.describe('Plot Integrity Testing @unstable', () => {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* 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');
|
const { setFixedTimeMode, setRealTimeMode, setStartOffset, setEndOffset } = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Time conductor operations', () => {
|
test.describe('Time conductor operations', () => {
|
||||||
|
@ -30,7 +30,7 @@ test.describe('Timer', () => {
|
|||||||
timer = await createDomainObjectWithDefaults(page, { type: '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({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/4313'
|
description: 'https://github.com/nasa/openmct/issues/4313'
|
||||||
|
@ -31,7 +31,7 @@ test.describe('Grand Search', () => {
|
|||||||
test('Can search for objects, and subsequent search dropdown behaves properly', async ({ page, openmctConfig }) => {
|
test('Can search for objects, and subsequent search dropdown behaves properly', async ({ page, openmctConfig }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
await createObjectsForSearch(page, myItemsFolderName);
|
const createdObjects = await createObjectsForSearch(page);
|
||||||
|
|
||||||
// Click [aria-label="OpenMCT Search"] input[type="search"]
|
// Click [aria-label="OpenMCT Search"] input[type="search"]
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
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=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=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`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=3')).toContainText(`Clock D ${myItemsFolderName} Red Folder Blue Folder`);
|
||||||
// Click text=Elements >> nth=0
|
// Click the Elements pool to dismiss the search menu
|
||||||
await page.locator('text=Elements').first().click();
|
await page.locator('.l-pane__label:has-text("Elements")').click();
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').click();
|
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 expect(page.locator('.is-object-type-clock')).toBeVisible();
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').fill('Disp');
|
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 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');
|
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);
|
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(folderName);
|
||||||
|
|
||||||
// Create folder object
|
// Create folder object
|
||||||
await page.locator('text=OK').click();
|
await page.locator('button:has-text("OK")').click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function waitForSearchCompletion(page) {
|
async function waitForSearchCompletion(page) {
|
||||||
@ -197,75 +197,56 @@ async function waitForSearchCompletion(page) {
|
|||||||
* Creates some domain objects for searching
|
* Creates some domain objects for searching
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function createObjectsForSearch(page, myItemsFolderName) {
|
async function createObjectsForSearch(page) {
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
await page.locator('button:has-text("Create")').click();
|
const redFolder = await createDomainObjectWithDefaults(page, {
|
||||||
await page.locator('li:has-text("Folder") >> nth=1').click();
|
type: 'Folder',
|
||||||
await Promise.all([
|
name: 'Red Folder'
|
||||||
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();
|
const blueFolder = await createDomainObjectWithDefaults(page, {
|
||||||
await page.locator('li:has-text("Folder") >> nth=2').click();
|
type: 'Folder',
|
||||||
await Promise.all([
|
name: 'Blue Folder',
|
||||||
page.waitForNavigation(),
|
parent: redFolder.uuid
|
||||||
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()
|
|
||||||
]);
|
|
||||||
|
|
||||||
await page.locator('button:has-text("Create")').click();
|
const clockA = await createDomainObjectWithDefaults(page, {
|
||||||
await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
|
type: 'Clock',
|
||||||
await Promise.all([
|
name: 'Clock A',
|
||||||
page.waitForNavigation(),
|
parent: blueFolder.uuid
|
||||||
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(),
|
const clockB = await createDomainObjectWithDefaults(page, {
|
||||||
page.locator('button:has-text("OK")').click()
|
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();
|
const displayLayout = await createDomainObjectWithDefaults(page, {
|
||||||
await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
|
type: 'Display Layout'
|
||||||
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()
|
|
||||||
]);
|
|
||||||
|
|
||||||
await page.locator('button:has-text("Create")').click();
|
// Go back into edit mode for the display layout
|
||||||
await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
|
await page.locator('button[title="Edit"]').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()
|
|
||||||
]);
|
|
||||||
|
|
||||||
await page.locator('button:has-text("Create")').click();
|
return {
|
||||||
await page.locator('li[title="A digital clock that uses system time and supports a variety of display formats and timezones."]').click();
|
redFolder,
|
||||||
await Promise.all([
|
blueFolder,
|
||||||
page.waitForNavigation(),
|
clockA,
|
||||||
await page.locator('text=Properties Title Notes >> input[type="text"] >> nth=0').fill('Clock D'),
|
clockB,
|
||||||
await page.locator('form[name="mctForm"] >> text=Blue Folder').click(),
|
clockC,
|
||||||
page.locator('button:has-text("OK")').click()
|
clockD,
|
||||||
]);
|
displayLayout
|
||||||
|
};
|
||||||
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()
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ test.describe('Performance tests', () => {
|
|||||||
await page.setInputFiles('#fileElem', filePath);
|
await page.setInputFiles('#fileElem', filePath);
|
||||||
|
|
||||||
// Click text=OK
|
// 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();
|
await expect(page.locator('a:has-text("Performance Display Layout Display Layout")')).toBeVisible();
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
:class="model.cssClass"
|
:class="model.cssClass"
|
||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
|
:id="`${model.key}-textarea`"
|
||||||
v-model="field"
|
v-model="field"
|
||||||
type="text"
|
type="text"
|
||||||
:size="model.size"
|
:size="model.size"
|
||||||
|
@ -3,13 +3,21 @@
|
|||||||
class="c-menu"
|
class="c-menu"
|
||||||
:class="options.menuClass"
|
: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
|
<template
|
||||||
v-for="(actionGroups, index) in options.actions"
|
v-for="(actionGroups, index) in options.actions"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:key="index"
|
||||||
|
role="group"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-for="action in actionGroups"
|
v-for="action in actionGroups"
|
||||||
:key="action.name"
|
:key="action.name"
|
||||||
|
role="menuitem"
|
||||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||||
:title="action.description"
|
:title="action.description"
|
||||||
:data-testid="action.testId || false"
|
:data-testid="action.testId || false"
|
||||||
@ -20,6 +28,7 @@
|
|||||||
<div
|
<div
|
||||||
v-if="index !== options.actions.length - 1"
|
v-if="index !== options.actions.length - 1"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
role="separator"
|
||||||
class="c-menu__section-separator"
|
class="c-menu__section-separator"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -29,13 +38,17 @@
|
|||||||
>
|
>
|
||||||
No actions defined.
|
No actions defined.
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</div></template>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul v-else>
|
<ul
|
||||||
|
v-else
|
||||||
|
role="menu"
|
||||||
|
>
|
||||||
<li
|
<li
|
||||||
v-for="action in options.actions"
|
v-for="action in options.actions"
|
||||||
:key="action.name"
|
:key="action.name"
|
||||||
|
role="menuitem"
|
||||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||||
:title="action.description"
|
:title="action.description"
|
||||||
:data-testid="action.testId || false"
|
:data-testid="action.testId || false"
|
||||||
|
@ -5,14 +5,20 @@
|
|||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
v-if="options.actions.length && options.actions[0].length"
|
v-if="options.actions.length && options.actions[0].length"
|
||||||
|
role="menu"
|
||||||
class="c-super-menu__menu"
|
class="c-super-menu__menu"
|
||||||
>
|
>
|
||||||
<template
|
<template
|
||||||
v-for="(actionGroups, index) in options.actions"
|
v-for="(actionGroups, index) in options.actions"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:key="index"
|
||||||
|
role="group"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-for="action in actionGroups"
|
v-for="action in actionGroups"
|
||||||
:key="action.name"
|
:key="action.name"
|
||||||
|
role="menuitem"
|
||||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||||
:title="action.description"
|
:title="action.description"
|
||||||
:data-testid="action.testId || false"
|
:data-testid="action.testId || false"
|
||||||
@ -25,6 +31,7 @@
|
|||||||
<div
|
<div
|
||||||
v-if="index !== options.actions.length - 1"
|
v-if="index !== options.actions.length - 1"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
role="separator"
|
||||||
class="c-menu__section-separator"
|
class="c-menu__section-separator"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -34,16 +41,18 @@
|
|||||||
>
|
>
|
||||||
No actions defined.
|
No actions defined.
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</div></template>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
v-else
|
v-else
|
||||||
class="c-super-menu__menu"
|
class="c-super-menu__menu"
|
||||||
|
role="menu"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-for="action in options.actions"
|
v-for="action in options.actions"
|
||||||
:key="action.name"
|
:key="action.name"
|
||||||
|
role="menuitem"
|
||||||
:class="action.cssClass"
|
:class="action.cssClass"
|
||||||
:title="action.description"
|
:title="action.description"
|
||||||
:data-testid="action.testId || false"
|
:data-testid="action.testId || false"
|
||||||
|
Reference in New Issue
Block a user