Use Composition API to add/remove from composition (#5941)
* Use composition API in RemoveAction
* refactor: ScatterPlotView to use composition API
* fix: initialize transaction to null and reset
* fix: remove seriesKey and correct found condition
* refactor: Gauge to use composition API
* refactor: DisplayLayout to use composition API
* test: RemoveAction starts and ends transactions
* test: add ScatterPlot add/remove telemetry test
* test: fix e2e test and add annotation
* test: remove unnecessary awaits
* test: make some displayLayout tests stable
* test{displayLayout}: navigate to objects via url
* test(gauge): add test for add/remove telemetry
* fix(#3117): init layoutItems within transaction
* refactor: add clearSelection() method
* test: remove unstable tag
* fix(#3117): init frames and use transactions
- fixes #3117 for flexible layouts by syncing frames and composition
- also uses transactions now to avoid race condition
* test(flexibleLayout): removing items via context menu
- add test for removing items via context menu while focusing the layout
- add test for removing items via context menu while not focusing the layout
* fix(e2e): use pluginFixtures
* refactor(e2e): improve selectors
* refactor: use async/await for saving transactions
* docs(e2e): fix comments
* test: use soft expects
Co-authored-by: Jamie V <jamie.j.vigliotta@nasa.gov>
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults, setStartOffset, setFixedTimeMode, setRealTimeMode } = require('../../../../appActions');
|
||||
|
||||
test.describe('Testing Display Layout @unstable', () => {
|
||||
test.describe('Display Layout', () => {
|
||||
let sineWaveObject;
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
@@ -55,12 +55,12 @@ test.describe('Testing Display Layout @unstable', () => {
|
||||
// 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 formattedTelemetryValue = getTelemValuePromise;
|
||||
const displayLayoutValuePromise = await page.waitForSelector(`text="${formattedTelemetryValue}"`);
|
||||
const displayLayoutValue = await displayLayoutValuePromise.textContent();
|
||||
const trimmedDisplayValue = displayLayoutValue.trim();
|
||||
|
||||
await expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
||||
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
|
||||
@@ -86,12 +86,12 @@ test.describe('Testing Display Layout @unstable', () => {
|
||||
|
||||
// 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 formattedTelemetryValue = getTelemValuePromise;
|
||||
const displayLayoutValuePromise = await page.waitForSelector(`text="${formattedTelemetryValue}"`);
|
||||
const displayLayoutValue = await displayLayoutValuePromise.textContent();
|
||||
const trimmedDisplayValue = displayLayoutValue.trim();
|
||||
|
||||
await expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
||||
expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
||||
});
|
||||
test('items in a display layout can be removed with object tree context menu when viewing the display layout', async ({ page }) => {
|
||||
// Create a Display Layout
|
||||
@@ -121,11 +121,15 @@ test.describe('Testing Display Layout @unstable', () => {
|
||||
|
||||
// delete
|
||||
|
||||
expect.soft(await page.locator('.l-layout .l-layout__frame').count()).toEqual(0);
|
||||
expect(await page.locator('.l-layout .l-layout__frame').count()).toEqual(0);
|
||||
});
|
||||
test('items in a display layout can be removed with object tree context menu when viewing another item', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/3117'
|
||||
});
|
||||
// Create a Display Layout
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
const displayLayout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Display Layout',
|
||||
name: "Test Display Layout"
|
||||
});
|
||||
@@ -144,18 +148,18 @@ test.describe('Testing Display Layout @unstable', () => {
|
||||
// Expand the Display Layout so we can remove the sine wave generator
|
||||
await page.locator('.c-tree__item.is-navigated-object .c-disclosure-triangle').click();
|
||||
|
||||
// Click the original Sine Wave Generator to navigate away from the Display Layout
|
||||
await page.locator('.c-tree__item .c-tree__item__name:text("Test Sine Wave Generator")').click();
|
||||
// Go to the original Sine Wave Generator to navigate away from the Display Layout
|
||||
await page.goto(sineWaveObject.url);
|
||||
|
||||
// Bring up context menu and remove
|
||||
await page.locator('.c-tree__item.is-alias .c-tree__item__name:text("Test Sine Wave Generator")').click({ button: 'right' });
|
||||
await page.locator('text=Remove').click();
|
||||
await page.locator('li[role="menuitem"]:has-text("Remove")').click();
|
||||
await page.locator('button:has-text("OK")').click();
|
||||
|
||||
// navigate back to the display layout to confirm it has been removed
|
||||
await page.locator('.c-tree__item .c-tree__item__name:text("Test Display Layout")').click();
|
||||
await page.goto(displayLayout.url);
|
||||
|
||||
expect.soft(await page.locator('.l-layout .l-layout__frame').count()).toEqual(0);
|
||||
expect(await page.locator('.l-layout .l-layout__frame').count()).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -23,12 +23,13 @@
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
|
||||
test.describe('Testing Flexible Layout @unstable', () => {
|
||||
test.describe('Flexible Layout', () => {
|
||||
let sineWaveObject;
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
|
||||
// Create Sine Wave Generator
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
sineWaveObject = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: "Test Sine Wave Generator"
|
||||
});
|
||||
@@ -54,13 +55,81 @@ test.describe('Testing Flexible Layout @unstable', () => {
|
||||
await page.dragAndDrop('text=Test Sine Wave Generator', '.c-fl__container.is-empty');
|
||||
await page.dragAndDrop('text=Test Clock', '.c-fl__container.is-empty');
|
||||
// Check that panes can be dragged while Flexible Layout is in Edit mode
|
||||
let dragWrapper = await page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||
let dragWrapper = page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||
await expect(dragWrapper).toHaveAttribute('draggable', 'true');
|
||||
// Save Flexible Layout
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
// Check that panes are not draggable while Flexible Layout is in Browse mode
|
||||
dragWrapper = await page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||
dragWrapper = page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||
await expect(dragWrapper).toHaveAttribute('draggable', 'false');
|
||||
});
|
||||
test('items in a flexible layout can be removed with object tree context menu when viewing the flexible layout', async ({ page }) => {
|
||||
// Create a Display Layout
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Flexible Layout',
|
||||
name: "Test Flexible Layout"
|
||||
});
|
||||
// Edit Flexible 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').first().click();
|
||||
// Add the Sine Wave Generator to the Flexible Layout and save changes
|
||||
await page.dragAndDrop('text=Test Sine Wave Generator', '.c-fl__container.is-empty');
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
|
||||
expect.soft(await page.locator('.c-fl-container__frame').count()).toEqual(1);
|
||||
|
||||
// Expand the Flexible Layout so we can remove the sine wave generator
|
||||
await page.locator('.c-tree__item.is-navigated-object .c-disclosure-triangle').click();
|
||||
|
||||
// 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('li[role="menuitem"]:has-text("Remove")').click();
|
||||
await page.locator('button:has-text("OK")').click();
|
||||
|
||||
// Verify that the item has been removed from the layout
|
||||
expect(await page.locator('.c-fl-container__frame').count()).toEqual(0);
|
||||
});
|
||||
test('items in a flexible layout can be removed with object tree context menu when viewing another item', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/3117'
|
||||
});
|
||||
// Create a Flexible Layout
|
||||
const flexibleLayout = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Flexible Layout',
|
||||
name: "Test Flexible Layout"
|
||||
});
|
||||
// Edit Flexible 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 Flexible Layout and save changes
|
||||
await page.dragAndDrop('text=Test Sine Wave Generator', '.c-fl__container.is-empty');
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
|
||||
expect.soft(await page.locator('.c-fl-container__frame').count()).toEqual(1);
|
||||
|
||||
// Expand the Flexible Layout so we can remove the sine wave generator
|
||||
await page.locator('.c-tree__item.is-navigated-object .c-disclosure-triangle').click();
|
||||
|
||||
// Go to the original Sine Wave Generator to navigate away from the Flexible Layout
|
||||
await page.goto(sineWaveObject.url);
|
||||
|
||||
// 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('li[role="menuitem"]:has-text("Remove")').click();
|
||||
await page.locator('button:has-text("OK")').click();
|
||||
|
||||
// navigate back to the display layout to confirm it has been removed
|
||||
await page.goto(flexibleLayout.url);
|
||||
|
||||
// Verify that the item has been removed from the layout
|
||||
expect(await page.locator('.c-fl-container__frame').count()).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
93
e2e/tests/functional/plugins/gauge/gauge.e2e.spec.js
Normal file
93
e2e/tests/functional/plugins/gauge/gauge.e2e.spec.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* This test suite is dedicated to testing the Gauge component.
|
||||
*/
|
||||
|
||||
const { test, expect } = require('../../../../baseFixtures');
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
const uuid = require('uuid').v4;
|
||||
|
||||
test.describe('Gauge', () => {
|
||||
let gauge;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
|
||||
// Create the gauge
|
||||
gauge = await createDomainObjectWithDefaults(page, { type: 'Gauge' });
|
||||
});
|
||||
|
||||
test('Can add and remove telemetry sources @unstable', async ({ page }) => {
|
||||
const editButtonLocator = page.locator('button[title="Edit"]');
|
||||
const saveButtonLocator = page.locator('button[title="Save"]');
|
||||
|
||||
// Create a sine wave generator within the gauge
|
||||
const swg1 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: `swg-${uuid()}`,
|
||||
parent: gauge.uuid
|
||||
});
|
||||
|
||||
// Navigate to the gauge and verify that
|
||||
// the SWG appears in the elements pool
|
||||
await page.goto(gauge.url);
|
||||
await editButtonLocator.click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeVisible();
|
||||
await saveButtonLocator.click();
|
||||
await page.locator('li[title="Save and Finish Editing"]').click();
|
||||
|
||||
// Create another sine wave generator within the gauge
|
||||
const swg2 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: `swg-${uuid()}`,
|
||||
parent: gauge.uuid
|
||||
});
|
||||
|
||||
// Verify that the 'Replace telemetry source' modal appears and accept it
|
||||
await expect.soft(page.locator('text=This action will replace the current telemetry source. Do you want to continue?')).toBeVisible();
|
||||
await page.click('text=Ok');
|
||||
|
||||
// Navigate to the gauge and verify that the new SWG
|
||||
// appears in the elements pool and the old one is gone
|
||||
await page.goto(gauge.url);
|
||||
await editButtonLocator.click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeHidden();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg2.name}`)).toBeVisible();
|
||||
await saveButtonLocator.click();
|
||||
|
||||
// Right click on the new SWG in the elements pool and delete it
|
||||
await page.locator(`#inspector-elements-tree >> text=${swg2.name}`).click({
|
||||
button: 'right'
|
||||
});
|
||||
await page.locator('li[title="Remove this object from its containing object."]').click();
|
||||
|
||||
// Verify that the 'Remove object' confirmation modal appears and accept it
|
||||
await expect.soft(page.locator('text=Warning! This action will remove this object. Are you sure you want to continue?')).toBeVisible();
|
||||
await page.click('text=Ok');
|
||||
|
||||
// Verify that the elements pool shows no elements
|
||||
await expect(page.locator('text="No contained elements"')).toBeVisible();
|
||||
});
|
||||
});
|
||||
93
e2e/tests/functional/plugins/plot/scatterPlot.e2e.spec.js
Normal file
93
e2e/tests/functional/plugins/plot/scatterPlot.e2e.spec.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* This test suite is dedicated to testing the Scatter Plot component.
|
||||
*/
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
const uuid = require('uuid').v4;
|
||||
|
||||
test.describe('Scatter Plot', () => {
|
||||
let scatterPlot;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
|
||||
// Create the Scatter Plot
|
||||
scatterPlot = await createDomainObjectWithDefaults(page, { type: 'Scatter Plot' });
|
||||
});
|
||||
|
||||
test('Can add and remove telemetry sources', async ({ page }) => {
|
||||
const editButtonLocator = page.locator('button[title="Edit"]');
|
||||
const saveButtonLocator = page.locator('button[title="Save"]');
|
||||
|
||||
// Create a sine wave generator within the scatter plot
|
||||
const swg1 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: `swg-${uuid()}`,
|
||||
parent: scatterPlot.uuid
|
||||
});
|
||||
|
||||
// Navigate to the scatter plot and verify that
|
||||
// the SWG appears in the elements pool
|
||||
await page.goto(scatterPlot.url);
|
||||
await editButtonLocator.click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeVisible();
|
||||
await saveButtonLocator.click();
|
||||
await page.locator('li[title="Save and Finish Editing"]').click();
|
||||
|
||||
// Create another sine wave generator within the scatter plot
|
||||
const swg2 = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Sine Wave Generator',
|
||||
name: `swg-${uuid()}`,
|
||||
parent: scatterPlot.uuid
|
||||
});
|
||||
|
||||
// Verify that the 'Replace telemetry source' modal appears and accept it
|
||||
await expect.soft(page.locator('text=This action will replace the current telemetry source. Do you want to continue?')).toBeVisible();
|
||||
await page.click('text=Ok');
|
||||
|
||||
// Navigate to the scatter plot and verify that the new SWG
|
||||
// appears in the elements pool and the old one is gone
|
||||
await page.goto(scatterPlot.url);
|
||||
await editButtonLocator.click();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg1.name}`)).toBeHidden();
|
||||
await expect.soft(page.locator(`#inspector-elements-tree >> text=${swg2.name}`)).toBeVisible();
|
||||
await saveButtonLocator.click();
|
||||
|
||||
// Right click on the new SWG in the elements pool and delete it
|
||||
await page.locator(`#inspector-elements-tree >> text=${swg2.name}`).click({
|
||||
button: 'right'
|
||||
});
|
||||
await page.locator('li[title="Remove this object from its containing object."]').click();
|
||||
|
||||
// Verify that the 'Remove object' confirmation modal appears and accept it
|
||||
await expect.soft(page.locator('text=Warning! This action will remove this object. Are you sure you want to continue?')).toBeVisible();
|
||||
await page.click('text=Ok');
|
||||
|
||||
// Verify that the elements pool shows no elements
|
||||
await expect(page.locator('text="No contained elements"')).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user