From b0d83efd8db12fdd2c145a9189da0f6196e11a64 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Tue, 9 Jan 2024 13:11:51 +0100 Subject: [PATCH 01/13] add reload action plugin --- src/MCT.js | 1 + src/plugins/plugins.js | 2 ++ src/plugins/reloadAction/ReloadAction.js | 37 ++++++++++++++++++++++++ src/plugins/reloadAction/plugin.js | 28 ++++++++++++++++++ src/ui/components/ObjectView.vue | 6 ++++ 5 files changed, 74 insertions(+) create mode 100644 src/plugins/reloadAction/ReloadAction.js create mode 100644 src/plugins/reloadAction/plugin.js diff --git a/src/MCT.js b/src/MCT.js index 35b4390d0b4..a10c1538241 100644 --- a/src/MCT.js +++ b/src/MCT.js @@ -251,6 +251,7 @@ export class MCT extends EventEmitter { this.install(this.plugins.FlexibleLayout()); this.install(this.plugins.GoToOriginalAction()); this.install(this.plugins.OpenInNewTabAction()); + this.install(this.plugins.ReloadAction()); this.install(this.plugins.WebPage()); this.install(this.plugins.Condition()); this.install(this.plugins.ConditionWidget()); diff --git a/src/plugins/plugins.js b/src/plugins/plugins.js index 1583fdfc39b..0410cb63341 100644 --- a/src/plugins/plugins.js +++ b/src/plugins/plugins.js @@ -65,6 +65,7 @@ import PerformanceIndicator from './performanceIndicator/plugin.js'; import CouchDBPlugin from './persistence/couch/plugin.js'; import PlanLayout from './plan/plugin.js'; import PlotPlugin from './plot/plugin.js'; +import ReloadAction from './reloadAction/plugin.js'; import RemoteClock from './remoteClock/plugin.js'; import StaticRootPlugin from './staticRootPlugin/plugin.js'; import SummaryWidget from './summaryWidget/plugin.js'; @@ -141,6 +142,7 @@ plugins.Filters = Filters; plugins.ObjectMigration = ObjectMigration; plugins.GoToOriginalAction = GoToOriginalAction; plugins.OpenInNewTabAction = OpenInNewTabAction; +plugins.ReloadAction = ReloadAction; plugins.ClearData = ClearData; plugins.WebPage = WebPagePlugin; plugins.Espresso = Espresso; diff --git a/src/plugins/reloadAction/ReloadAction.js b/src/plugins/reloadAction/ReloadAction.js new file mode 100644 index 00000000000..b165240d61b --- /dev/null +++ b/src/plugins/reloadAction/ReloadAction.js @@ -0,0 +1,37 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2023, 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. + *****************************************************************************/ +export default class ReloadAction { + constructor(openmct) { + this.name = 'Reload'; + this.key = 'reload'; + this.description = 'Reload this object and its children'; + this.group = 'action'; + this.priority = 10; + this.cssClass = 'icon-refresh'; + + this.openmct = openmct; + } + invoke(objectPath, view) { + console.debug('🎨 Reloading'); + this.openmct.objectViews.emit('reload'); + } +} diff --git a/src/plugins/reloadAction/plugin.js b/src/plugins/reloadAction/plugin.js new file mode 100644 index 00000000000..c9db76b89a1 --- /dev/null +++ b/src/plugins/reloadAction/plugin.js @@ -0,0 +1,28 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2023, 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. + *****************************************************************************/ +import ReloadAction from './ReloadAction.js'; + +export default function plugin() { + return function install(openmct) { + openmct.actions.register(new ReloadAction(openmct)); + }; +} diff --git a/src/ui/components/ObjectView.vue b/src/ui/components/ObjectView.vue index 1eea8d8a611..b61528b0fe2 100644 --- a/src/ui/components/ObjectView.vue +++ b/src/ui/components/ObjectView.vue @@ -184,6 +184,7 @@ export default { this.triggerUnsubscribeFromStaleness(this.domainObject); this.openmct.objectViews.off('clearData', this.clearData); + this.openmct.objectViews.off('reload', this.reload); if (this.contextActionEvent) { this.openmct.objectViews.off(this.contextActionEvent, this.performContextAction); } @@ -218,6 +219,10 @@ export default { this.clear(); this.updateView(true); }, + reload() { + this.clear(); + this.updateView(true); + }, triggerStalenessSubscribe(object) { if (this.openmct.telemetry.isTelemetryObject(object)) { this.subscribeToStaleness(object); @@ -316,6 +321,7 @@ export default { this.domainObject.identifier )}`; this.openmct.objectViews.on('clearData', this.clearData); + this.openmct.objectViews.on('reload', this.reload); this.openmct.objectViews.on(this.contextActionEvent, this.performContextAction); this.$nextTick(() => { From dfb72b8b269e2852b749f301fde7bf169b39c815 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Tue, 9 Jan 2024 13:34:36 +0100 Subject: [PATCH 02/13] checking for domain object before reloading --- src/plugins/reloadAction/ReloadAction.js | 4 ++-- src/ui/components/ObjectView.vue | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/plugins/reloadAction/ReloadAction.js b/src/plugins/reloadAction/ReloadAction.js index b165240d61b..ff86bff4f5d 100644 --- a/src/plugins/reloadAction/ReloadAction.js +++ b/src/plugins/reloadAction/ReloadAction.js @@ -31,7 +31,7 @@ export default class ReloadAction { this.openmct = openmct; } invoke(objectPath, view) { - console.debug('🎨 Reloading'); - this.openmct.objectViews.emit('reload'); + const domainObject = objectPath[0]; + this.openmct.objectViews.emit('reload', domainObject); } } diff --git a/src/ui/components/ObjectView.vue b/src/ui/components/ObjectView.vue index b61528b0fe2..f51282e8335 100644 --- a/src/ui/components/ObjectView.vue +++ b/src/ui/components/ObjectView.vue @@ -219,9 +219,16 @@ export default { this.clear(); this.updateView(true); }, - reload() { - this.clear(); - this.updateView(true); + reload(domainObjectToReload) { + console.debug(`Reloading object view for `, domainObjectToReload); + console.debug(`My object path is `, this.domainObject); + + // should maybe check object path here instead? + if (domainObjectToReload === this.domainObject) { + console.debug(`🍎 Reloading object view for `, domainObjectToReload); + this.clear(); + this.updateView(true); + } }, triggerStalenessSubscribe(object) { if (this.openmct.telemetry.isTelemetryObject(object)) { From 5ed43dd3309f337448ad453b9598205c84068078 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Tue, 9 Jan 2024 15:19:50 +0100 Subject: [PATCH 03/13] check if objects are equal before refreshing --- src/ui/components/ObjectView.vue | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/ui/components/ObjectView.vue b/src/ui/components/ObjectView.vue index f51282e8335..05d46da444e 100644 --- a/src/ui/components/ObjectView.vue +++ b/src/ui/components/ObjectView.vue @@ -33,6 +33,7 @@ import StyleRuleManager from '@/plugins/condition/StyleRuleManager'; import { STYLE_CONSTANTS } from '@/plugins/condition/utils/constants'; import stalenessMixin from '@/ui/mixins/staleness-mixin'; +import objectUtils from '../../api/objects/object-utils.js'; import VisibilityObserver from '../../utils/visibility/VisibilityObserver.js'; export default { @@ -220,12 +221,7 @@ export default { this.updateView(true); }, reload(domainObjectToReload) { - console.debug(`Reloading object view for `, domainObjectToReload); - console.debug(`My object path is `, this.domainObject); - - // should maybe check object path here instead? - if (domainObjectToReload === this.domainObject) { - console.debug(`🍎 Reloading object view for `, domainObjectToReload); + if (objectUtils.equals(domainObjectToReload, this.domainObject)) { this.clear(); this.updateView(true); } From cfd129c652be4e9b82c36a75623058f946afa426 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Tue, 9 Jan 2024 16:59:55 +0100 Subject: [PATCH 04/13] add test --- .../reloadAction/reloadAction.e2e.spec.js | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js diff --git a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js new file mode 100644 index 00000000000..78ef60a9f90 --- /dev/null +++ b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js @@ -0,0 +1,147 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2023, 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. + *****************************************************************************/ +import { + createDomainObjectWithDefaults, + expandEntireTree, + setRealTimeMode +} from '../../../../appActions.js'; +import { expect, test } from '../../../../pluginFixtures.js'; + +test.describe('Reload action', () => { + test.beforeEach(async ({ page }) => { + await page.goto('./', { waitUntil: 'domcontentloaded' }); + + const displayLayout = await createDomainObjectWithDefaults(page, { + type: 'Display Layout' + }); + + const alphaTable = await createDomainObjectWithDefaults(page, { + type: 'Telemetry Table', + name: 'Alpha Table' + }); + + const betaTable = await createDomainObjectWithDefaults(page, { + type: 'Telemetry Table', + name: 'Beta Table' + }); + + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: alphaTable.uuid, + customParameters: { + '[aria-label="Data Rate (hz)"]': '0.001' + } + }); + + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: betaTable.uuid, + customParameters: { + '[aria-label="Data Rate (hz)"]': '0.001' + } + }); + + await page.goto(displayLayout.url); + + // Expand all folders + await expandEntireTree(page); + + await page.locator('[title="Edit"]').click(); + + await page.dragAndDrop(`text='Alpha Table'`, '.l-layout__grid-holder', { + targetPosition: { x: 0, y: 0 } + }); + + await page.dragAndDrop(`text='Beta Table'`, '.l-layout__grid-holder', { + targetPosition: { x: 0, y: 250 } + }); + + await page.locator('button[title="Save"]').click(); + await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); + }); + + test('can reload display layout and its children', async ({ page }) => { + const beforeReloadAlphaTelemetryValue = await page + .locator('table.c-telemetry-table__body > tbody') + .first() + .locator('tr') + .first() + .locator('td') + .nth(3) + .getAttribute('title'); + const beforeReloadBetaTelemetryValue = await page + .locator('table.c-telemetry-table__body > tbody') + .last() + .locator('tr') + .first() + .locator('td') + .nth(3) + .getAttribute('title'); + // reload alpha + await page.getByTitle('View menu items').first().click(); + await page.getByRole('menuitem', { name: /Reload/ }).click(); + + const afterReloadAlphaTelemetryValue = await page + .locator('table.c-telemetry-table__body > tbody') + .first() + .locator('tr') + .first() + .locator('td') + .nth(3) + .getAttribute('title'); + const afterReloadBetaTelemetryValue = await page + .locator('table.c-telemetry-table__body > tbody') + .last() + .locator('tr') + .first() + .locator('td') + .nth(3) + .getAttribute('title'); + + expect(beforeReloadAlphaTelemetryValue).not.toEqual(afterReloadAlphaTelemetryValue); + expect(beforeReloadBetaTelemetryValue).toEqual(afterReloadBetaTelemetryValue); + + // now reload parent + await page.getByTitle('More actions').click(); + await page.getByRole('menuitem', { name: /Reload/ }).click(); + + const fullReloadAlphaTelemetryValue = await page + .locator('table.c-telemetry-table__body > tbody') + .first() + .locator('tr') + .first() + .locator('td') + .nth(3) + .getAttribute('title'); + const fullReloadBetaTelemetryValue = await page + .locator('table.c-telemetry-table__body > tbody') + .last() + .locator('tr') + .first() + .locator('td') + .nth(3) + .getAttribute('title'); + + expect(fullReloadAlphaTelemetryValue).not.toEqual(afterReloadAlphaTelemetryValue); + expect(fullReloadBetaTelemetryValue).not.toEqual(afterReloadBetaTelemetryValue); + }); +}); From 061f4f83da12780d66e6a053310277ca39ebaf95 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Tue, 9 Jan 2024 17:04:29 +0100 Subject: [PATCH 05/13] lint --- .../plugins/reloadAction/reloadAction.e2e.spec.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js index 78ef60a9f90..81f1987e18a 100644 --- a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js +++ b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js @@ -19,11 +19,7 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -import { - createDomainObjectWithDefaults, - expandEntireTree, - setRealTimeMode -} from '../../../../appActions.js'; +import { createDomainObjectWithDefaults, expandEntireTree } from '../../../../appActions.js'; import { expect, test } from '../../../../pluginFixtures.js'; test.describe('Reload action', () => { From e06312894b0eddb653dcf35a3bf21b821cc68ae4 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Wed, 10 Jan 2024 18:15:37 +0100 Subject: [PATCH 06/13] change to label --- .../functional/plugins/reloadAction/reloadAction.e2e.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js index 81f1987e18a..53b6e7400c8 100644 --- a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js +++ b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js @@ -61,7 +61,7 @@ test.describe('Reload action', () => { // Expand all folders await expandEntireTree(page); - await page.locator('[title="Edit"]').click(); + await page.getByLabel('Edit').click(); await page.dragAndDrop(`text='Alpha Table'`, '.l-layout__grid-holder', { targetPosition: { x: 0, y: 0 } From 5f2bcb50b9b639dfd71fb50a86afa912ffc9f35b Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 11 Jan 2024 10:29:32 +0100 Subject: [PATCH 07/13] ensure object styles are initialized --- src/ui/components/ObjectView.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/components/ObjectView.vue b/src/ui/components/ObjectView.vue index 6e56e209362..d5ab6c599ba 100644 --- a/src/ui/components/ObjectView.vue +++ b/src/ui/components/ObjectView.vue @@ -223,6 +223,7 @@ export default { reload(domainObjectToReload) { if (objectUtils.equals(domainObjectToReload, this.domainObject)) { this.clear(); + this.initObjectStyles(); this.updateView(true); } }, From f103afc77d5d72e145e9fe3d26b83c89b7d0a566 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 11 Jan 2024 10:43:29 +0100 Subject: [PATCH 08/13] resubscribe to staleness too --- src/ui/components/ObjectView.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/components/ObjectView.vue b/src/ui/components/ObjectView.vue index d5ab6c599ba..6644fb3ce05 100644 --- a/src/ui/components/ObjectView.vue +++ b/src/ui/components/ObjectView.vue @@ -222,9 +222,9 @@ export default { }, reload(domainObjectToReload) { if (objectUtils.equals(domainObjectToReload, this.domainObject)) { - this.clear(); - this.initObjectStyles(); this.updateView(true); + this.initObjectStyles(); + this.triggerStalenessSubscribe(this.domainObject); } }, triggerStalenessSubscribe(object) { From 89a824e1967e7bbd0e07abfad5bdd3affee45949 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 11 Jan 2024 11:23:11 +0100 Subject: [PATCH 09/13] add better labels for tabels --- .../reloadAction/reloadAction.e2e.spec.js | 42 ++++++------------- .../telemetryTable/components/TableCell.vue | 1 + .../components/TableComponent.vue | 1 + 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js index 53b6e7400c8..880777cacb3 100644 --- a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js +++ b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js @@ -77,40 +77,28 @@ test.describe('Reload action', () => { test('can reload display layout and its children', async ({ page }) => { const beforeReloadAlphaTelemetryValue = await page - .locator('table.c-telemetry-table__body > tbody') + .getByLabel('Alpha Table table content') + .getByLabel('wavelengths table cell') .first() - .locator('tr') - .first() - .locator('td') - .nth(3) .getAttribute('title'); const beforeReloadBetaTelemetryValue = await page - .locator('table.c-telemetry-table__body > tbody') - .last() - .locator('tr') + .getByLabel('Beta Table table content') + .getByLabel('wavelengths table cell') .first() - .locator('td') - .nth(3) .getAttribute('title'); // reload alpha await page.getByTitle('View menu items').first().click(); await page.getByRole('menuitem', { name: /Reload/ }).click(); const afterReloadAlphaTelemetryValue = await page - .locator('table.c-telemetry-table__body > tbody') - .first() - .locator('tr') + .getByLabel('Alpha Table table content') + .getByLabel('wavelengths table cell') .first() - .locator('td') - .nth(3) .getAttribute('title'); const afterReloadBetaTelemetryValue = await page - .locator('table.c-telemetry-table__body > tbody') - .last() - .locator('tr') + .getByLabel('Beta Table table content') + .getByLabel('wavelengths table cell') .first() - .locator('td') - .nth(3) .getAttribute('title'); expect(beforeReloadAlphaTelemetryValue).not.toEqual(afterReloadAlphaTelemetryValue); @@ -121,20 +109,14 @@ test.describe('Reload action', () => { await page.getByRole('menuitem', { name: /Reload/ }).click(); const fullReloadAlphaTelemetryValue = await page - .locator('table.c-telemetry-table__body > tbody') - .first() - .locator('tr') + .getByLabel('Alpha Table table content') + .getByLabel('wavelengths table cell') .first() - .locator('td') - .nth(3) .getAttribute('title'); const fullReloadBetaTelemetryValue = await page - .locator('table.c-telemetry-table__body > tbody') - .last() - .locator('tr') + .getByLabel('Beta Table table content') + .getByLabel('wavelengths table cell') .first() - .locator('td') - .nth(3) .getAttribute('title'); expect(fullReloadAlphaTelemetryValue).not.toEqual(afterReloadAlphaTelemetryValue); diff --git a/src/plugins/telemetryTable/components/TableCell.vue b/src/plugins/telemetryTable/components/TableCell.vue index 48fb850ffa3..9370d6fcdba 100644 --- a/src/plugins/telemetryTable/components/TableCell.vue +++ b/src/plugins/telemetryTable/components/TableCell.vue @@ -23,6 +23,7 @@ Date: Thu, 11 Jan 2024 11:33:11 +0100 Subject: [PATCH 10/13] ensure tab uses exact for label now due to table aria changes --- e2e/tests/performance/tabs.e2e.spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/e2e/tests/performance/tabs.e2e.spec.js b/e2e/tests/performance/tabs.e2e.spec.js index 9689be8a387..3db219f1dad 100644 --- a/e2e/tests/performance/tabs.e2e.spec.js +++ b/e2e/tests/performance/tabs.e2e.spec.js @@ -24,7 +24,7 @@ import { createDomainObjectWithDefaults, waitForPlotsToRender } from '../../appA import { expect, test } from '../../pluginFixtures.js'; test.describe('Tabs View', () => { - test('Renders tabbed elements nicely', async ({ page }) => { + test('Renders tabbed elements only when visible', async ({ page }) => { // Code to hook into the requestAnimationFrame function and log each call let animationCalls = []; await page.exposeFunction('logCall', (callCount) => { @@ -64,24 +64,24 @@ test.describe('Tabs View', () => { page.goto(tabsView.url); // select first tab - await page.getByLabel(`${table.name} tab`).click(); + await page.getByLabel(`${table.name} tab`, { exact: true }).click(); // ensure table header visible await expect(page.getByRole('searchbox', { name: 'message filter input' })).toBeVisible(); // select second tab - await page.getByLabel(`${notebook.name} tab`).click(); + await page.getByLabel(`${notebook.name} tab`, { exact: true }).click(); // expect notebook visible await expect(page.locator('.c-notebook__drag-area')).toBeVisible(); // select third tab - await page.getByLabel(`${sineWaveGenerator.name} tab`).click(); + await page.getByLabel(`${sineWaveGenerator.name} tab`, { exact: true }).click(); // ensure sine wave generator visible expect(await page.locator('.c-plot').isVisible()).toBe(true); // now select notebook and clear animation calls - await page.getByLabel(`${notebook.name} tab`).click(); + await page.getByLabel(`${notebook.name} tab`, { exact: true }).click(); animationCalls = []; // expect notebook visible await expect(page.locator('.c-notebook__drag-area')).toBeVisible(); @@ -89,7 +89,7 @@ test.describe('Tabs View', () => { // select sine wave generator and clear animation calls animationCalls = []; - await page.getByLabel(`${sineWaveGenerator.name} tab`).click(); + await page.getByLabel(`${sineWaveGenerator.name} tab`, { exact: true }).click(); // ensure sine wave generator visible await waitForPlotsToRender(page); From 1f34ab5d6fe6b9138035a022c11c5609274597f1 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 11 Jan 2024 12:11:06 +0100 Subject: [PATCH 11/13] fix table tests --- .../telemetryTable/telemetryTable.e2e.spec.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js b/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js index e28d12d196a..19e0e5c24ea 100644 --- a/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js +++ b/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js @@ -64,10 +64,9 @@ test.describe('Telemetry Table', () => { // Get the most recent telemetry date const latestTelemetryDate = await page - .locator('table.c-telemetry-table__body > tbody > tr') + .getByLabel('table content') + .getByLabel('utc table cell') .last() - .locator('td') - .nth(1) .getAttribute('title'); // Verify that it is <= our new end bound @@ -91,7 +90,7 @@ test.describe('Telemetry Table', () => { await page.getByRole('searchbox', { name: 'message filter input' }).click(); await page.getByRole('searchbox', { name: 'message filter input' }).fill('Roger'); - let cells = await page.getByRole('cell', { name: /Roger/ }).all(); + let cells = await page.getByRole('cell').getByText(/Roger/).all(); // ensure we've got more than one cell expect(cells.length).toBeGreaterThan(1); // ensure the text content of each cell contains the search term @@ -103,7 +102,10 @@ test.describe('Telemetry Table', () => { await page.getByRole('searchbox', { name: 'message filter input' }).click(); await page.getByRole('searchbox', { name: 'message filter input' }).fill('Dodger'); - cells = await page.getByRole('cell', { name: /Dodger/ }).all(); + cells = await page + .getByRole('cell') + .getByText(/Dodger/) + .all(); // ensure we've got more than one cell expect(cells.length).toBe(0); // ensure the text content of each cell contains the search term @@ -132,7 +134,7 @@ test.describe('Telemetry Table', () => { await page.getByRole('searchbox', { name: 'message filter input' }).click(); await page.getByRole('searchbox', { name: 'message filter input' }).fill('/[Rr]oger/'); - let cells = await page.getByRole('cell', { name: /Roger/ }).all(); + let cells = await page.getByRole('cell').getByText(/Roger/).all(); // ensure we've got more than one cell expect(cells.length).toBeGreaterThan(1); // ensure the text content of each cell contains the search term @@ -144,7 +146,10 @@ test.describe('Telemetry Table', () => { await page.getByRole('searchbox', { name: 'message filter input' }).click(); await page.getByRole('searchbox', { name: 'message filter input' }).fill('/[Dd]oger/'); - cells = await page.getByRole('cell', { name: /Dodger/ }).all(); + cells = await page + .getByRole('cell') + .getByText(/Dodger/) + .all(); // ensure we've got more than one cell expect(cells.length).toBe(0); // ensure the text content of each cell contains the search term From e64bafe3c787d9377d97a3baf830020194ee9946 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 11 Jan 2024 12:20:31 +0100 Subject: [PATCH 12/13] make tabs exact --- e2e/tests/functional/plugins/tabs/tabs.e2e.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/tests/functional/plugins/tabs/tabs.e2e.spec.js b/e2e/tests/functional/plugins/tabs/tabs.e2e.spec.js index 46e33330fed..373fe8fdd1c 100644 --- a/e2e/tests/functional/plugins/tabs/tabs.e2e.spec.js +++ b/e2e/tests/functional/plugins/tabs/tabs.e2e.spec.js @@ -50,7 +50,7 @@ test.describe('Tabs View', () => { page.goto(tabsView.url); // select first tab - await page.getByLabel(`${table.name} tab`).click(); + await page.getByLabel(`${table.name} tab`, { exact: true }).click(); // ensure table header visible await expect(page.getByRole('searchbox', { name: 'message filter input' })).toBeVisible(); @@ -58,7 +58,7 @@ test.describe('Tabs View', () => { await expect(page.locator('canvas')).toBeHidden(); // select second tab - await page.getByLabel(`${notebook.name} tab`).click(); + await page.getByLabel(`${notebook.name} tab`, { exact: true }).click(); // ensure notebook visible await expect(page.locator('.c-notebook__drag-area')).toBeVisible(); @@ -67,7 +67,7 @@ test.describe('Tabs View', () => { await expect(page.locator('canvas')).toBeHidden(); // select third tab - await page.getByLabel(`${sineWaveGenerator.name} tab`).click(); + await page.getByLabel(`${sineWaveGenerator.name} tab`, { exact: true }).click(); // expect sine wave generator visible await expect(page.locator('.c-plot')).toBeVisible(); @@ -78,7 +78,7 @@ test.describe('Tabs View', () => { await expect(page.locator('canvas').nth(1)).toBeVisible(); // now try to select the first tab again - await page.getByLabel(`${table.name} tab`).click(); + await page.getByLabel(`${table.name} tab`, { exact: true }).click(); // ensure table header visible await expect(page.getByRole('searchbox', { name: 'message filter input' })).toBeVisible(); From b8bae55c0261f90d0d8ea8b6f67004573eb3e1dd Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Tue, 16 Jan 2024 19:17:24 +0100 Subject: [PATCH 13/13] update conflicts --- .../functional/plugins/reloadAction/reloadAction.e2e.spec.js | 2 +- src/plugins/telemetryTable/components/TableCell.vue | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js index 880777cacb3..c64e19a007c 100644 --- a/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js +++ b/e2e/tests/functional/plugins/reloadAction/reloadAction.e2e.spec.js @@ -61,7 +61,7 @@ test.describe('Reload action', () => { // Expand all folders await expandEntireTree(page); - await page.getByLabel('Edit').click(); + await page.getByLabel('Edit Object', { exact: true }).click(); await page.dragAndDrop(`text='Alpha Table'`, '.l-layout__grid-holder', { targetPosition: { x: 0, y: 0 } diff --git a/src/plugins/telemetryTable/components/TableCell.vue b/src/plugins/telemetryTable/components/TableCell.vue index 502a13320e3..e30b64ce093 100644 --- a/src/plugins/telemetryTable/components/TableCell.vue +++ b/src/plugins/telemetryTable/components/TableCell.vue @@ -22,9 +22,8 @@