mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 21:53:08 +00:00
[e2e] More VIPER compatibility fixes (#5582)
This commit is contained in:
parent
22924f18fc
commit
fc3614dfbd
@ -148,6 +148,7 @@ Current list of test tags:
|
|||||||
- `@localStorage` - Captures or generates session storage to manipulate browser state. Useful for excluding in tests which require a persistent backend (i.e. CouchDB).
|
- `@localStorage` - Captures or generates session storage to manipulate browser state. Useful for excluding in tests which require a persistent backend (i.e. CouchDB).
|
||||||
- `@snapshot` - Uses Playwright's snapshot functionality to record a copy of the DOM for direct comparison. Must be run inside of the playwright container.
|
- `@snapshot` - Uses Playwright's snapshot functionality to record a copy of the DOM for direct comparison. Must be run inside of the playwright container.
|
||||||
- `@unstable` - A new test or test which is known to be flaky.
|
- `@unstable` - A new test or test which is known to be flaky.
|
||||||
|
- `@2p` - Indicates that multiple users are involved, or multiple tabs/pages are used. Useful for testing multi-user interactivity.
|
||||||
|
|
||||||
### Continuous Integration
|
### Continuous Integration
|
||||||
|
|
||||||
|
@ -37,11 +37,16 @@
|
|||||||
* @param {string | undefined} name
|
* @param {string | undefined} name
|
||||||
*/
|
*/
|
||||||
async function createDomainObjectWithDefaults(page, type, name) {
|
async function createDomainObjectWithDefaults(page, type, name) {
|
||||||
|
// Navigate to focus the 'My Items' folder, and hide the object tree
|
||||||
|
// This is necessary so that subsequent objects can be created without a parent
|
||||||
|
// TODO: Ideally this would navigate to a common `e2e` folder
|
||||||
|
await page.goto('./#/browse/mine?hideTree=true');
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
//Click the Create button
|
//Click the Create button
|
||||||
await page.click('button:has-text("Create")');
|
await page.click('button:has-text("Create")');
|
||||||
|
|
||||||
// Click the object specified by 'type'
|
// Click the object specified by 'type'
|
||||||
await page.click(`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) {
|
if (name) {
|
||||||
@ -52,9 +57,13 @@ async function createDomainObjectWithDefaults(page, type, name) {
|
|||||||
|
|
||||||
// Click OK button and wait for Navigate event
|
// Click OK button and wait for Navigate event
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation(),
|
||||||
page.click('text=OK')
|
page.click('[aria-label="Save"]'),
|
||||||
|
// Wait for Save Banner to appear
|
||||||
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
return name || `Unnamed ${type}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('./baseFixtures');
|
const { test, expect } = require('./baseFixtures');
|
||||||
const { createDomainObjectWithDefaults } = require('./appActions');
|
// const { createDomainObjectWithDefaults } = require('./appActions');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} ObjectCreateOptions
|
* @typedef {Object} ObjectCreateOptions
|
||||||
@ -36,12 +36,16 @@ const { createDomainObjectWithDefaults } = require('./appActions');
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* **NOTE: This feature is a work-in-progress and should not currently be used.**
|
||||||
|
*
|
||||||
* Used to create a new domain object as a part of getOrCreateDomainObject.
|
* Used to create a new domain object as a part of getOrCreateDomainObject.
|
||||||
* @type {Map<string, string>}
|
* @type {Map<string, string>}
|
||||||
*/
|
*/
|
||||||
const createdObjects = new Map();
|
// const createdObjects = new Map();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* **NOTE: This feature is a work-in-progress and should not currently be used.**
|
||||||
|
*
|
||||||
* This action will create a domain object for the test to reference and return the uuid. If an object
|
* This action will create a domain object for the test to reference and return the uuid. If an object
|
||||||
* of a given name already exists, it will return the uuid of that object to the test instead of creating
|
* of a given name already exists, it will return the uuid of that object to the test instead of creating
|
||||||
* a new file. The intent is to move object creation out of test suites which are not explicitly worried
|
* a new file. The intent is to move object creation out of test suites which are not explicitly worried
|
||||||
@ -50,27 +54,29 @@ const createdObjects = new Map();
|
|||||||
* @param {ObjectCreateOptions} options
|
* @param {ObjectCreateOptions} options
|
||||||
* @returns {Promise<string>} uuid of the domain object
|
* @returns {Promise<string>} uuid of the domain object
|
||||||
*/
|
*/
|
||||||
async function getOrCreateDomainObject(page, options) {
|
// async function getOrCreateDomainObject(page, options) {
|
||||||
const { type, name } = options;
|
// const { type, name } = options;
|
||||||
const objectName = name ? `${type}:${name}` : type;
|
// const objectName = name ? `${type}:${name}` : type;
|
||||||
|
|
||||||
if (createdObjects.has(objectName)) {
|
// if (createdObjects.has(objectName)) {
|
||||||
return createdObjects.get(objectName);
|
// return createdObjects.get(objectName);
|
||||||
}
|
// }
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, type, name);
|
// await createDomainObjectWithDefaults(page, type, name);
|
||||||
|
|
||||||
// Once object is created, get the uuid from the url
|
// // Once object is created, get the uuid from the url
|
||||||
const uuid = await page.evaluate(() => {
|
// const uuid = await page.evaluate(() => {
|
||||||
return window.location.href.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/)[0];
|
// return window.location.href.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/)[0];
|
||||||
});
|
// });
|
||||||
|
|
||||||
createdObjects.set(objectName, uuid);
|
// createdObjects.set(objectName, uuid);
|
||||||
|
|
||||||
return uuid;
|
// return uuid;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* **NOTE: This feature is a work-in-progress and should not currently be used.**
|
||||||
|
*
|
||||||
* If provided, these options will be used to get or create the desired domain object before
|
* If provided, these options will be used to get or create the desired domain object before
|
||||||
* any tests or test hooks have run.
|
* any tests or test hooks have run.
|
||||||
* The `uuid` of the `domainObject` will then be available to use within the scoped tests.
|
* The `uuid` of the `domainObject` will then be available to use within the scoped tests.
|
||||||
@ -87,7 +93,7 @@ async function getOrCreateDomainObject(page, options) {
|
|||||||
* ```
|
* ```
|
||||||
* @type {ObjectCreateOptions}
|
* @type {ObjectCreateOptions}
|
||||||
*/
|
*/
|
||||||
const objectCreateOptions = null;
|
// const objectCreateOptions = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the "My Items" folder in the domain object tree.
|
* The name of the "My Items" folder in the domain object tree.
|
||||||
@ -103,23 +109,23 @@ exports.test = test.extend({
|
|||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
// 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);
|
||||||
|
|
||||||
//Go to baseURL
|
// return;
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
// }
|
||||||
|
|
||||||
const uuid = await getOrCreateDomainObject(page, objectCreateOptions);
|
// //Go to baseURL
|
||||||
await use({ uuid });
|
// await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
}, { auto: true }]
|
|
||||||
|
// const uuid = await getOrCreateDomainObject(page, objectCreateOptions);
|
||||||
|
// await use({ uuid });
|
||||||
|
// }, { auto: true }]
|
||||||
});
|
});
|
||||||
exports.expect = expect;
|
exports.expect = expect;
|
||||||
|
41
e2e/tests/framework/appActions.e2e.spec.js
Normal file
41
e2e/tests/framework/appActions.e2e.spec.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const { test, expect } = require('../../baseFixtures.js');
|
||||||
|
const { createDomainObjectWithDefaults } = require('../../appActions.js');
|
||||||
|
|
||||||
|
test.describe('appActions tests', () => {
|
||||||
|
test('createDomainObjectsWithDefaults can create multiple objects in a row', async ({ page }) => {
|
||||||
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
await createDomainObjectWithDefaults(page, 'Timer', 'Timer Foo');
|
||||||
|
await createDomainObjectWithDefaults(page, 'Timer', 'Timer Bar');
|
||||||
|
await createDomainObjectWithDefaults(page, 'Timer', 'Timer Baz');
|
||||||
|
|
||||||
|
// Expand the tree
|
||||||
|
await page.click('.c-disclosure-triangle');
|
||||||
|
|
||||||
|
// Verify the objects were created
|
||||||
|
await expect(page.locator('a :text("Timer Foo")')).toBeVisible();
|
||||||
|
await expect(page.locator('a :text("Timer Bar")')).toBeVisible();
|
||||||
|
await expect(page.locator('a :text("Timer Baz")')).toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
@ -52,7 +52,7 @@ const { createDomainObjectWithDefaults } = require('../../appActions');
|
|||||||
|
|
||||||
// Structure: Try to keep a single describe block per logical groups of tests. If your test runtime exceeds 5 minutes or 500 lines, it's likely that it will need to be split.
|
// Structure: Try to keep a single describe block per logical groups of tests. If your test runtime exceeds 5 minutes or 500 lines, it's likely that it will need to be split.
|
||||||
// Annotations: Please use the @unstable tag so that our automation can pick it up as a part of our test promotion pipeline.
|
// Annotations: Please use the @unstable tag so that our automation can pick it up as a part of our test promotion pipeline.
|
||||||
test.describe('Renaming Timer Object @unstable', () => {
|
test.describe('Renaming Timer Object', () => {
|
||||||
//Create a testcase name which will be obvious when it fails in CI
|
//Create a testcase name which will be obvious when it fails in CI
|
||||||
test('Can create a new Timer object and rename it from actions Menu', async ({ page }) => {
|
test('Can create a new Timer object and rename it from actions Menu', async ({ page }) => {
|
||||||
//Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
//Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
||||||
@ -68,7 +68,6 @@ test.describe('Renaming Timer Object @unstable', () => {
|
|||||||
|
|
||||||
//Assert that the name has changed in the browser bar to the value we assigned above
|
//Assert that the name has changed in the browser bar to the value we assigned above
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText(newObjectName);
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(newObjectName);
|
||||||
|
|
||||||
});
|
});
|
||||||
test('An existing Timer object can be renamed twice', async ({ page }) => {
|
test('An existing Timer object can be renamed twice', async ({ page }) => {
|
||||||
//Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
//Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
||||||
|
@ -25,21 +25,22 @@ This test suite is dedicated to testing our use of our custom fixtures to verify
|
|||||||
that they are working as expected.
|
that they are working as expected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../pluginFixtures.js');
|
const { test } = require('../../pluginFixtures.js');
|
||||||
|
|
||||||
test.describe('pluginFixtures tests', () => {
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.use({ domainObjectName: 'Timer' });
|
test.describe.skip('pluginFixtures tests', () => {
|
||||||
let timerUUID;
|
// test.use({ domainObjectName: 'Timer' });
|
||||||
|
// let timerUUID;
|
||||||
|
|
||||||
test('Creates a timer object @framework @unstable', ({ domainObject }) => {
|
// test('Creates a timer object @framework @unstable', ({ domainObject }) => {
|
||||||
const { uuid } = domainObject;
|
// const { uuid } = domainObject;
|
||||||
const uuidRegexp = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/;
|
// const uuidRegexp = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/;
|
||||||
expect(uuid).toMatch(uuidRegexp);
|
// expect(uuid).toMatch(uuidRegexp);
|
||||||
timerUUID = uuid;
|
// timerUUID = uuid;
|
||||||
});
|
// });
|
||||||
|
|
||||||
test('Provides same uuid for subsequent uses of the same object @framework', ({ domainObject }) => {
|
// test('Provides same uuid for subsequent uses of the same object @framework', ({ domainObject }) => {
|
||||||
const { uuid } = domainObject;
|
// const { uuid } = domainObject;
|
||||||
expect(uuid).toEqual(timerUUID);
|
// expect(uuid).toEqual(timerUUID);
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -38,14 +38,14 @@ test.describe('Branding tests', () => {
|
|||||||
await expect(page.locator('.c-about__image')).toBeVisible();
|
await expect(page.locator('.c-about__image')).toBeVisible();
|
||||||
|
|
||||||
// Modify the Build information in 'about' Modal
|
// Modify the Build information in 'about' Modal
|
||||||
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info');
|
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
||||||
await expect(versionInformationLocator).toBeEnabled();
|
await expect(versionInformationLocator).toBeEnabled();
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Version: \d/);
|
await expect.soft(versionInformationLocator).toContainText(/Version: \d/);
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Build Date: ((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun))/);
|
await expect.soft(versionInformationLocator).toContainText(/Build Date: ((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun))/);
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Revision: \b[0-9a-f]{5,40}\b/);
|
await expect.soft(versionInformationLocator).toContainText(/Revision: \b[0-9a-f]{5,40}\b/);
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Branch: ./);
|
await expect.soft(versionInformationLocator).toContainText(/Branch: ./);
|
||||||
});
|
});
|
||||||
test('Verify Links in About Modal', async ({ page }) => {
|
test('Verify Links in About Modal @2p', async ({ page }) => {
|
||||||
// Go to baseURL
|
// Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ but only assume that example imagery is present.
|
|||||||
|
|
||||||
const { waitForAnimations } = require('../../../../baseFixtures');
|
const { waitForAnimations } = require('../../../../baseFixtures');
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
const backgroundImageSelector = '.c-imagery__main-image__background-image';
|
const backgroundImageSelector = '.c-imagery__main-image__background-image';
|
||||||
const panHotkey = process.platform === 'linux' ? ['Control', 'Alt'] : ['Alt'];
|
const panHotkey = process.platform === 'linux' ? ['Control', 'Alt'] : ['Alt'];
|
||||||
const expectedAltText = process.platform === 'linux' ? 'Ctrl+Alt drag to pan' : 'Alt drag to pan';
|
const expectedAltText = process.platform === 'linux' ? 'Ctrl+Alt drag to pan' : 'Alt drag to pan';
|
||||||
@ -39,26 +40,17 @@ test.describe('Example Imagery Object', () => {
|
|||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
//Click the Create button
|
// Create a default 'Example Imagery' object
|
||||||
await page.click('button:has-text("Create")');
|
createDomainObjectWithDefaults(page, 'Example Imagery');
|
||||||
|
|
||||||
// Click text=Example Imagery
|
|
||||||
await page.click('text=Example Imagery');
|
|
||||||
|
|
||||||
// Click text=OK
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation(),
|
||||||
page.click('text=OK'),
|
page.locator(backgroundImageSelector).hover({trial: true}),
|
||||||
//Wait for Save Banner to appear
|
// eslint-disable-next-line playwright/missing-playwright-await
|
||||||
page.waitForSelector('.c-message-banner__message')
|
expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery')
|
||||||
]);
|
]);
|
||||||
// Close Banner
|
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
|
||||||
|
|
||||||
//Wait until Save Banner is gone
|
// Verify that the created object is focused
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery');
|
|
||||||
await page.locator(backgroundImageSelector).hover({trial: true});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => {
|
test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => {
|
||||||
@ -208,7 +200,7 @@ test.describe('Example Imagery Object', () => {
|
|||||||
const pausePlayButton = page.locator('.c-button.pause-play');
|
const pausePlayButton = page.locator('.c-button.pause-play');
|
||||||
|
|
||||||
// open the time conductor drop down
|
// open the time conductor drop down
|
||||||
await page.locator('button:has-text("Fixed Timespan")').click();
|
await page.locator('.c-mode-button').click();
|
||||||
|
|
||||||
// Click local clock
|
// Click local clock
|
||||||
await page.locator('[data-testid="conductor-modeOption-realtime"]').click();
|
await page.locator('[data-testid="conductor-modeOption-realtime"]').click();
|
||||||
@ -532,7 +524,7 @@ test.describe('Example Imagery in Flexible layout', () => {
|
|||||||
await page.locator('.c-mode-button').click();
|
await page.locator('.c-mode-button').click();
|
||||||
|
|
||||||
// Select local clock mode
|
// Select local clock mode
|
||||||
await page.locator('[data-testid=conductor-modeOption-realtime]').click();
|
await page.locator('[data-testid=conductor-modeOption-realtime]').nth(0).click();
|
||||||
|
|
||||||
// Zoom in on next image
|
// Zoom in on next image
|
||||||
await mouseZoomIn(page);
|
await mouseZoomIn(page);
|
||||||
|
@ -25,25 +25,18 @@ This test suite is dedicated to tests which verify form functionality.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a notebook object and adds an entry.
|
* Creates a notebook object and adds an entry.
|
||||||
* @param {import('@playwright/test').Page} - page to load
|
* @param {import('@playwright/test').Page} - page to load
|
||||||
* @param {number} [iterations = 1] - the number of entries to create
|
* @param {number} [iterations = 1] - the number of entries to create
|
||||||
*/
|
*/
|
||||||
async function createNotebookAndEntry(page, myItemsFolderName, iterations = 1) {
|
async function createNotebookAndEntry(page, iterations = 1) {
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
// Click button:has-text("Create")
|
createDomainObjectWithDefaults(page, 'Notebook');
|
||||||
await page.locator('button:has-text("Create")').click();
|
|
||||||
await page.locator('[title="Create and save timestamped notes with embedded object snapshots."]').click();
|
|
||||||
// Click button:has-text("OK")
|
|
||||||
await Promise.all([
|
|
||||||
page.waitForNavigation(),
|
|
||||||
page.locator(`[name="mctForm"] >> text=${myItemsFolderName}`).click(),
|
|
||||||
page.locator('button:has-text("OK")').click()
|
|
||||||
]);
|
|
||||||
|
|
||||||
for (let iteration = 0; iteration < iterations; iteration++) {
|
for (let iteration = 0; iteration < iterations; iteration++) {
|
||||||
// Click text=To start a new entry, click here or drag and drop any object
|
// Click text=To start a new entry, click here or drag and drop any object
|
||||||
@ -52,7 +45,6 @@ async function createNotebookAndEntry(page, myItemsFolderName, 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}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,8 +52,8 @@ async function createNotebookAndEntry(page, myItemsFolderName, iterations = 1) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
* @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, myItemsFolderName, iterations = 1) {
|
async function createNotebookEntryAndTags(page, iterations = 1) {
|
||||||
await createNotebookAndEntry(page, myItemsFolderName, iterations);
|
await createNotebookAndEntry(page, iterations);
|
||||||
|
|
||||||
for (let iteration = 0; iteration < iterations; iteration++) {
|
for (let iteration = 0; iteration < iterations; iteration++) {
|
||||||
// Click text=To start a new entry, click here or drag and drop any object
|
// Click text=To start a new entry, click here or drag and drop any object
|
||||||
@ -81,11 +73,10 @@ async function createNotebookEntryAndTags(page, myItemsFolderName, iterations =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Tagging in Notebooks', () => {
|
test.describe('Tagging in Notebooks @addInit', () => {
|
||||||
test('Can load tags', async ({ page, openmctConfig }) => {
|
test('Can load tags', async ({ page }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
|
||||||
|
|
||||||
await createNotebookAndEntry(page, myItemsFolderName);
|
await createNotebookAndEntry(page);
|
||||||
// Click text=To start a new entry, click here or drag and drop any object
|
// Click text=To start a new entry, click here or drag and drop any object
|
||||||
await page.locator('button:has-text("Add Tag")').click();
|
await page.locator('button:has-text("Add Tag")').click();
|
||||||
|
|
||||||
@ -96,10 +87,8 @@ test.describe('Tagging in Notebooks', () => {
|
|||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Drilling");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Drilling");
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Driving");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Driving");
|
||||||
});
|
});
|
||||||
test('Can add tags', async ({ page, openmctConfig }) => {
|
test('Can add tags', async ({ page }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
await createNotebookEntryAndTags(page);
|
||||||
|
|
||||||
await createNotebookEntryAndTags(page, myItemsFolderName);
|
|
||||||
|
|
||||||
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Science");
|
||||||
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Driving");
|
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Driving");
|
||||||
@ -113,10 +102,8 @@ test.describe('Tagging in Notebooks', () => {
|
|||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).not.toContainText("Driving");
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Drilling");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Drilling");
|
||||||
});
|
});
|
||||||
test('Can search for tags', async ({ page, openmctConfig }) => {
|
test('Can search for tags', async ({ page }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
await createNotebookEntryAndTags(page);
|
||||||
|
|
||||||
await createNotebookEntryAndTags(page, myItemsFolderName);
|
|
||||||
// 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();
|
||||||
// Fill [aria-label="OpenMCT Search"] input[type="search"]
|
// Fill [aria-label="OpenMCT Search"] input[type="search"]
|
||||||
@ -139,10 +126,8 @@ test.describe('Tagging in Notebooks', () => {
|
|||||||
await expect(page.locator('[aria-label="Search Result"]')).not.toBeVisible();
|
await expect(page.locator('[aria-label="Search Result"]')).not.toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can delete tags', async ({ page, openmctConfig }) => {
|
test('Can delete tags', async ({ page }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
await createNotebookEntryAndTags(page);
|
||||||
|
|
||||||
await createNotebookEntryAndTags(page, myItemsFolderName);
|
|
||||||
await page.locator('[aria-label="Notebook Entries"]').click();
|
await page.locator('[aria-label="Notebook Entries"]').click();
|
||||||
// Delete Driving
|
// Delete Driving
|
||||||
await page.locator('text=Science Driving Add Tag >> button').nth(1).click();
|
await page.locator('text=Science Driving Add Tag >> button').nth(1).click();
|
||||||
@ -154,28 +139,14 @@ test.describe('Tagging in Notebooks', () => {
|
|||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText("Driving");
|
||||||
});
|
});
|
||||||
test('Tags persist across reload', async ({ page, openmctConfig }) => {
|
test('Tags persist across reload', async ({ page }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
|
||||||
|
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
// Create a clock object we can navigate to
|
await createDomainObjectWithDefaults(page, 'Clock');
|
||||||
await page.click('button:has-text("Create")');
|
|
||||||
|
|
||||||
// Click Clock
|
|
||||||
await page.click('text=Clock');
|
|
||||||
// Click button:has-text("OK")
|
|
||||||
await Promise.all([
|
|
||||||
page.waitForNavigation(),
|
|
||||||
page.locator(`[name="mctForm"] >> text=${myItemsFolderName}`).click(),
|
|
||||||
page.locator('button:has-text("OK")').click()
|
|
||||||
]);
|
|
||||||
|
|
||||||
await page.click('.c-disclosure-triangle');
|
|
||||||
|
|
||||||
const ITERATIONS = 4;
|
const ITERATIONS = 4;
|
||||||
await createNotebookEntryAndTags(page, myItemsFolderName, ITERATIONS);
|
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}`;
|
||||||
@ -183,6 +154,11 @@ test.describe('Tagging in Notebooks', () => {
|
|||||||
await expect(page.locator(entryLocator)).toContainText("Driving");
|
await expect(page.locator(entryLocator)).toContainText("Driving");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForNavigation(),
|
||||||
|
page.goto('./#/browse/mine?hideTree=false'),
|
||||||
|
page.click('.c-disclosure-triangle')
|
||||||
|
]);
|
||||||
// Click Unnamed Clock
|
// Click Unnamed Clock
|
||||||
await page.click('text="Unnamed Clock"');
|
await page.click('text="Unnamed Clock"');
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:01');
|
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:01');
|
||||||
|
|
||||||
// Verify url parameters persist after mode switch
|
// Verify url parameters persist after mode switch
|
||||||
await page.waitForNavigation();
|
await page.waitForNavigation({ waitUntil: 'networkidle' });
|
||||||
expect(page.url()).toContain(`startDelta=${startDelta}`);
|
expect(page.url()).toContain(`startDelta=${startDelta}`);
|
||||||
expect(page.url()).toContain(`endDelta=${endDelta}`);
|
expect(page.url()).toContain(`endDelta=${endDelta}`);
|
||||||
});
|
});
|
||||||
|
@ -21,14 +21,14 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { openObjectTreeContextMenu } = require('../../../../appActions');
|
const { openObjectTreeContextMenu, createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
|
|
||||||
const options = {
|
|
||||||
type: 'Timer'
|
|
||||||
};
|
|
||||||
|
|
||||||
test.describe('Timer', () => {
|
test.describe('Timer', () => {
|
||||||
test.use({ objectCreateOptions: options });
|
test.beforeEach(async ({ page }) => {
|
||||||
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
await createDomainObjectWithDefaults(page, 'timer');
|
||||||
|
});
|
||||||
|
|
||||||
test('Can perform actions on the Timer', async ({ page, openmctConfig }) => {
|
test('Can perform actions on the Timer', async ({ page, openmctConfig }) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
|
Loading…
Reference in New Issue
Block a user