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

github.com/nasa/openmct.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Bell <scott@traclabs.com>2022-08-08 23:34:32 +0300
committerGitHub <noreply@github.com>2022-08-08 23:34:32 +0300
commitcaecdd60a884b801c72ed8f813c99b50ac608d61 (patch)
tree07c1841737735a85e3ed375d2e3b406ec8878ebb
parentdd4b27ada77a17b01314c9ee39b8716f182092e5 (diff)
parentc6c58af12cea8441911b8df6d053c8a78dfee8df (diff)
Merge branch 'release/2.0.7' into 5615-infinite-loop-in-some-search-cases5615-infinite-loop-in-some-search-cases
-rw-r--r--e2e/appActions.js93
-rw-r--r--e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js122
-rw-r--r--e2e/tests/functional/plugins/lad/lad.e2e.spec.js120
-rw-r--r--e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js86
4 files changed, 334 insertions, 87 deletions
diff --git a/e2e/appActions.js b/e2e/appActions.js
index d0504ff0b..e4fbf7589 100644
--- a/e2e/appActions.js
+++ b/e2e/appActions.js
@@ -83,7 +83,7 @@ async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine
]);
// Wait until the URL is updated
- await page.waitForNavigation('networkidle');
+ await page.waitForURL(`**/${parent}/*`);
const uuid = await getFocusedObjectUuid(page);
const objectUrl = await getHashUrlToDomainObject(page, uuid);
@@ -175,10 +175,99 @@ async function _isInEditMode(page, identifier) {
return await page.evaluate((objectIdentifier) => window.openmct.objects.isTransactionActive(objectIdentifier), identifier);
}
+/**
+ * Set the time conductor mode to either fixed timespan or realtime mode.
+ * @param {import('@playwright/test').Page} page
+ * @param {boolean} [isFixedTimespan=true] true for fixed timespan mode, false for realtime mode; default is true
+ */
+async function setTimeConductorMode(page, isFixedTimespan = true) {
+ // Click 'mode' button
+ await page.locator('.c-mode-button').click();
+
+ // Switch time conductor mode
+ if (isFixedTimespan) {
+ await page.locator('data-testid=conductor-modeOption-fixed').click();
+ } else {
+ await page.locator('data-testid=conductor-modeOption-realtime').click();
+ }
+}
+
+/**
+ * Set the time conductor to fixed timespan mode
+ * @param {import('@playwright/test').Page} page
+ */
+async function setFixedTimeMode(page) {
+ await setTimeConductorMode(page, true);
+}
+
+/**
+ * Set the time conductor to realtime mode
+ * @param {import('@playwright/test').Page} page
+ */
+async function setRealTimeMode(page) {
+ await setTimeConductorMode(page, false);
+}
+
+/**
+ * @typedef {Object} OffsetValues
+ * @property {string | undefined} hours
+ * @property {string | undefined} mins
+ * @property {string | undefined} secs
+ */
+
+/**
+ * Set the values (hours, mins, secs) for the TimeConductor offsets when in realtime mode
+ * @param {import('@playwright/test').Page} page
+ * @param {OffsetValues} offset
+ * @param {import('@playwright/test').Locator} offsetButton
+ */
+async function setTimeConductorOffset(page, {hours, mins, secs}, offsetButton) {
+ await offsetButton.click();
+
+ if (hours) {
+ await page.fill('.pr-time-controls__hrs', hours);
+ }
+
+ if (mins) {
+ await page.fill('.pr-time-controls__mins', mins);
+ }
+
+ if (secs) {
+ await page.fill('.pr-time-controls__secs', secs);
+ }
+
+ // Click the check button
+ await page.locator('.pr-time__buttons .icon-check').click();
+}
+
+/**
+ * Set the values (hours, mins, secs) for the start time offset when in realtime mode
+ * @param {import('@playwright/test').Page} page
+ * @param {OffsetValues} offset
+ */
+async function setStartOffset(page, offset) {
+ const startOffsetButton = page.locator('data-testid=conductor-start-offset-button');
+ await setTimeConductorOffset(page, offset, startOffsetButton);
+}
+
+/**
+ * Set the values (hours, mins, secs) for the end time offset when in realtime mode
+ * @param {import('@playwright/test').Page} page
+ * @param {OffsetValues} offset
+ */
+async function setEndOffset(page, offset) {
+ const endOffsetButton = page.locator('data-testid=conductor-end-offset-button');
+ await setTimeConductorOffset(page, offset, endOffsetButton);
+}
+
// eslint-disable-next-line no-undef
module.exports = {
createDomainObjectWithDefaults,
openObjectTreeContextMenu,
getHashUrlToDomainObject,
- getFocusedObjectUuid
+ getFocusedObjectUuid,
+ setFixedTimeMode,
+ setRealTimeMode,
+ setStartOffset,
+ setEndOffset
};
diff --git a/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js b/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js
new file mode 100644
index 000000000..83090fc0e
--- /dev/null
+++ b/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * 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('../../../../pluginFixtures');
+const { createDomainObjectWithDefaults, setStartOffset, setFixedTimeMode, setRealTimeMode } = require('../../../../appActions');
+
+test.describe('Testing Display Layout @unstable', () => {
+ let sineWaveObject;
+ test.beforeEach(async ({ page }) => {
+ await page.goto('./', { waitUntil: 'networkidle' });
+ await setRealTimeMode(page);
+
+ // Create Sine Wave Generator
+ sineWaveObject = await createDomainObjectWithDefaults(page, {
+ type: 'Sine Wave Generator',
+ name: "Test Sine Wave Generator"
+ });
+ });
+ test('alpha-numeric widget telemetry value exactly matches latest telemetry value received in real time', async ({ page }) => {
+ // Create a Display Layout
+ await createDomainObjectWithDefaults(page, {
+ type: 'Display Layout',
+ name: "Test Display Layout"
+ });
+ // Edit Display Layout
+ await page.locator('[title="Edit"]').click();
+
+ // Expand the 'My Items' folder in the left tree
+ await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
+ // Add the Sine Wave Generator to the Display Layout and save changes
+ await page.dragAndDrop('text=Test Sine Wave Generator', '.l-layout__grid-holder');
+ await page.locator('button[title="Save"]').click();
+ await page.locator('text=Save and Finish Editing').click();
+
+ // Subscribe to the Sine Wave Generator data
+ // On getting data, check if the value found in the Display Layout is the most recent value
+ // from the Sine Wave Generator
+ const getTelemValuePromise = await subscribeToTelemetry(page, sineWaveObject.uuid);
+ const formattedTelemetryValue = await getTelemValuePromise;
+ const displayLayoutValuePromise = await page.waitForSelector(`text="${formattedTelemetryValue}"`);
+ const displayLayoutValue = await displayLayoutValuePromise.textContent();
+ const trimmedDisplayValue = displayLayoutValue.trim();
+
+ await expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
+ });
+ test('alpha-numeric widget telemetry value exactly matches latest telemetry value received in fixed time', async ({ page }) => {
+ // Create a Display Layout
+ await createDomainObjectWithDefaults(page, {
+ type: 'Display Layout',
+ name: "Test Display Layout"
+ });
+ // Edit Display Layout
+ await page.locator('[title="Edit"]').click();
+
+ // Expand the 'My Items' folder in the left tree
+ await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
+ // Add the Sine Wave Generator to the Display Layout and save changes
+ await page.dragAndDrop('text=Test Sine Wave Generator', '.l-layout__grid-holder');
+ await page.locator('button[title="Save"]').click();
+ await page.locator('text=Save and Finish Editing').click();
+
+ // Subscribe to the Sine Wave Generator data
+ const getTelemValuePromise = await subscribeToTelemetry(page, sineWaveObject.uuid);
+ // Set an offset of 1 minute and then change the time mode to fixed to set a 1 minute historical window
+ await setStartOffset(page, { mins: '1' });
+ await setFixedTimeMode(page);
+
+ // On getting data, check if the value found in the Display Layout is the most recent value
+ // from the Sine Wave Generator
+ const formattedTelemetryValue = await getTelemValuePromise;
+ const displayLayoutValuePromise = await page.waitForSelector(`text="${formattedTelemetryValue}"`);
+ const displayLayoutValue = await displayLayoutValuePromise.textContent();
+ const trimmedDisplayValue = displayLayoutValue.trim();
+
+ await expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
+ });
+});
+
+/**
+ * Util for subscribing to a telemetry object by object identifier
+ * Limitations: Currently only works to return telemetry once to the node scope
+ * To Do: See if there's a way to await this multiple times to allow for multiple
+ * values to be returned over time
+ * @param {import('@playwright/test').Page} page
+ * @param {string} objectIdentifier identifier for object
+ * @returns {Promise<string>} the formatted sin telemetry value
+ */
+async function subscribeToTelemetry(page, objectIdentifier) {
+ const getTelemValuePromise = new Promise(resolve => page.exposeFunction('getTelemValue', resolve));
+
+ await page.evaluate(async (telemetryIdentifier) => {
+ const telemetryObject = await window.openmct.objects.get(telemetryIdentifier);
+ const metadata = window.openmct.telemetry.getMetadata(telemetryObject);
+ const formats = await window.openmct.telemetry.getFormatMap(metadata);
+ window.openmct.telemetry.subscribe(telemetryObject, (obj) => {
+ const sinVal = obj.sin;
+ const formattedSinVal = formats.sin.format(sinVal);
+ window.getTelemValue(formattedSinVal);
+ });
+ }, objectIdentifier);
+
+ return getTelemValuePromise;
+}
diff --git a/e2e/tests/functional/plugins/lad/lad.e2e.spec.js b/e2e/tests/functional/plugins/lad/lad.e2e.spec.js
new file mode 100644
index 000000000..4ec084c1b
--- /dev/null
+++ b/e2e/tests/functional/plugins/lad/lad.e2e.spec.js
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * 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('../../../../pluginFixtures');
+const { createDomainObjectWithDefaults, setStartOffset, setFixedTimeMode, setRealTimeMode } = require('../../../../appActions');
+
+test.describe('Testing LAD table @unstable', () => {
+ let sineWaveObject;
+ test.beforeEach(async ({ page }) => {
+ await page.goto('./', { waitUntil: 'networkidle' });
+ await setRealTimeMode(page);
+
+ // Create Sine Wave Generator
+ sineWaveObject = await createDomainObjectWithDefaults(page, {
+ type: 'Sine Wave Generator',
+ name: "Test Sine Wave Generator"
+ });
+ });
+ test('telemetry value exactly matches latest telemetry value received in real time', async ({ page }) => {
+ // Create LAD table
+ await createDomainObjectWithDefaults(page, {
+ type: 'LAD Table',
+ name: "Test LAD Table"
+ });
+ // Edit LAD table
+ await page.locator('[title="Edit"]').click();
+
+ // Expand the 'My Items' folder in the left tree
+ await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
+ // Add the Sine Wave Generator to the LAD table and save changes
+ await page.dragAndDrop('text=Test Sine Wave Generator', '.c-lad-table-wrapper');
+ await page.locator('button[title="Save"]').click();
+ await page.locator('text=Save and Finish Editing').click();
+
+ // Subscribe to the Sine Wave Generator data
+ // On getting data, check if the value found in the LAD table is the most recent value
+ // from the Sine Wave Generator
+ const getTelemValuePromise = await subscribeToTelemetry(page, sineWaveObject.uuid);
+ const subscribeTelemValue = await getTelemValuePromise;
+ const ladTableValuePromise = await page.waitForSelector(`text="${subscribeTelemValue}"`);
+ const ladTableValue = await ladTableValuePromise.textContent();
+
+ expect(ladTableValue).toBe(subscribeTelemValue);
+ });
+ test('telemetry value exactly matches latest telemetry value received in fixed time', async ({ page }) => {
+ // Create LAD table
+ await createDomainObjectWithDefaults(page, {
+ type: 'LAD Table',
+ name: "Test LAD Table"
+ });
+ // Edit LAD table
+ await page.locator('[title="Edit"]').click();
+
+ // Expand the 'My Items' folder in the left tree
+ await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
+ // Add the Sine Wave Generator to the LAD table and save changes
+ await page.dragAndDrop('text=Test Sine Wave Generator', '.c-lad-table-wrapper');
+ await page.locator('button[title="Save"]').click();
+ await page.locator('text=Save and Finish Editing').click();
+
+ // Subscribe to the Sine Wave Generator data
+ const getTelemValuePromise = await subscribeToTelemetry(page, sineWaveObject.uuid);
+ // Set an offset of 1 minute and then change the time mode to fixed to set a 1 minute historical window
+ await setStartOffset(page, { mins: '1' });
+ await setFixedTimeMode(page);
+
+ // On getting data, check if the value found in the LAD table is the most recent value
+ // from the Sine Wave Generator
+ const subscribeTelemValue = await getTelemValuePromise;
+ const ladTableValuePromise = await page.waitForSelector(`text="${subscribeTelemValue}"`);
+ const ladTableValue = await ladTableValuePromise.textContent();
+
+ expect(ladTableValue).toBe(subscribeTelemValue);
+ });
+});
+
+/**
+ * Util for subscribing to a telemetry object by object identifier
+ * Limitations: Currently only works to return telemetry once to the node scope
+ * To Do: See if there's a way to await this multiple times to allow for multiple
+ * values to be returned over time
+ * @param {import('@playwright/test').Page} page
+ * @param {string} objectIdentifier identifier for object
+ * @returns {Promise<string>} the formatted sin telemetry value
+ */
+async function subscribeToTelemetry(page, objectIdentifier) {
+ const getTelemValuePromise = new Promise(resolve => page.exposeFunction('getTelemValue', resolve));
+
+ await page.evaluate(async (telemetryIdentifier) => {
+ const telemetryObject = await window.openmct.objects.get(telemetryIdentifier);
+ const metadata = window.openmct.telemetry.getMetadata(telemetryObject);
+ const formats = await window.openmct.telemetry.getFormatMap(metadata);
+ window.openmct.telemetry.subscribe(telemetryObject, (obj) => {
+ const sinVal = obj.sin;
+ const formattedSinVal = formats.sin.format(sinVal);
+ window.getTelemValue(formattedSinVal);
+ });
+ }, objectIdentifier);
+
+ return getTelemValuePromise;
+}
diff --git a/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js b/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js
index 8d764526b..59d317170 100644
--- a/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js
+++ b/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js
@@ -21,6 +21,7 @@
*****************************************************************************/
const { test, expect } = require('../../../../baseFixtures');
+const { setFixedTimeMode, setRealTimeMode, setStartOffset, setEndOffset } = require('../../../../appActions');
test.describe('Time conductor operations', () => {
test('validate start time does not exceeds end time', async ({ page }) => {
@@ -147,88 +148,3 @@ test.describe('Time conductor input fields real-time mode', () => {
expect(page.url()).toContain(`endDelta=${endDelta}`);
});
});
-
-/**
- * @typedef {Object} OffsetValues
- * @property {string | undefined} hours
- * @property {string | undefined} mins
- * @property {string | undefined} secs
- */
-
-/**
- * Set the values (hours, mins, secs) for the start time offset when in realtime mode
- * @param {import('@playwright/test').Page} page
- * @param {OffsetValues} offset
- */
-async function setStartOffset(page, offset) {
- const startOffsetButton = page.locator('data-testid=conductor-start-offset-button');
- await setTimeConductorOffset(page, offset, startOffsetButton);
-}
-
-/**
- * Set the values (hours, mins, secs) for the end time offset when in realtime mode
- * @param {import('@playwright/test').Page} page
- * @param {OffsetValues} offset
- */
-async function setEndOffset(page, offset) {
- const endOffsetButton = page.locator('data-testid=conductor-end-offset-button');
- await setTimeConductorOffset(page, offset, endOffsetButton);
-}
-
-/**
- * Set the time conductor to fixed timespan mode
- * @param {import('@playwright/test').Page} page
- */
-async function setFixedTimeMode(page) {
- await setTimeConductorMode(page, true);
-}
-
-/**
- * Set the time conductor to realtime mode
- * @param {import('@playwright/test').Page} page
- */
-async function setRealTimeMode(page) {
- await setTimeConductorMode(page, false);
-}
-
-/**
- * Set the values (hours, mins, secs) for the TimeConductor offsets when in realtime mode
- * @param {import('@playwright/test').Page} page
- * @param {OffsetValues} offset
- * @param {import('@playwright/test').Locator} offsetButton
- */
-async function setTimeConductorOffset(page, {hours, mins, secs}, offsetButton) {
- await offsetButton.click();
-
- if (hours) {
- await page.fill('.pr-time-controls__hrs', hours);
- }
-
- if (mins) {
- await page.fill('.pr-time-controls__mins', mins);
- }
-
- if (secs) {
- await page.fill('.pr-time-controls__secs', secs);
- }
-
- // Click the check button
- await page.locator('.icon-check').click();
-}
-
-/**
- * Set the time conductor mode to either fixed timespan or realtime mode.
- * @param {import('@playwright/test').Page} page
- * @param {boolean} [isFixedTimespan=true] true for fixed timespan mode, false for realtime mode; default is true
- */
-async function setTimeConductorMode(page, isFixedTimespan = true) {
- // Click 'mode' button
- await page.locator('.c-mode-button').click();
-
- // Switch time conductor mode
- if (isFixedTimespan) {
- await page.locator('data-testid=conductor-modeOption-fixed').click();
- } else {
- await page.locator('data-testid=conductor-modeOption-realtime').click();
- }
-}