mirror of
https://github.com/nasa/openmct.git
synced 2025-01-18 02:39:56 +00:00
Fix stacked plot child selection (#6275)
* Fix selections for different scenarios * Ensure plot selection in stacked plots works when there are no selected or found annotations * Adds e2e test for stacked plot selection and fixes the old e2e test which was testing overlay plots instead. * Fix selection of plots while in Edit mode * Improve tests for stacked plots * refactor: remove unnecessary `await`s * a11y: move aria-label to StackedPlotItem * refactor(e2e): combine like tests, unique object names - Use unique object names in `text=` selectors - Combine like tests to reduce execution time - Use `getByRole` selectors where able * docs(e2e): add comments to test * fix: add class back for unit test selector --------- Co-authored-by: Scott Bell <scott@traclabs.com> Co-authored-by: Jesse Mazzella <jesse.d.mazzella@nasa.gov>
This commit is contained in:
parent
0f312a88bb
commit
be38c3e654
@ -29,29 +29,39 @@ const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
|
||||
test.describe('Stacked Plot', () => {
|
||||
let stackedPlot;
|
||||
let swgA;
|
||||
let swgB;
|
||||
let swgC;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
//Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
stackedPlot = await createDomainObjectWithDefaults(page, {
|
||||
type: "Stacked Plot"
|
||||
});
|
||||
|
||||
swgA = await createDomainObjectWithDefaults(page, {
|
||||
type: "Sine Wave Generator",
|
||||
parent: stackedPlot.uuid
|
||||
});
|
||||
swgB = await createDomainObjectWithDefaults(page, {
|
||||
type: "Sine Wave Generator",
|
||||
parent: stackedPlot.uuid
|
||||
});
|
||||
swgC = await createDomainObjectWithDefaults(page, {
|
||||
type: "Sine Wave Generator",
|
||||
parent: stackedPlot.uuid
|
||||
});
|
||||
});
|
||||
|
||||
test('Using the remove action removes the correct plot', async ({ page }) => {
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||
type: "Overlay Plot"
|
||||
});
|
||||
const swgAElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgA.name });
|
||||
const swgBElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgB.name });
|
||||
const swgCElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgC.name });
|
||||
|
||||
await page.goto(stackedPlot.url);
|
||||
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: "Sine Wave Generator",
|
||||
name: 'swg a',
|
||||
parent: overlayPlot.uuid
|
||||
});
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: "Sine Wave Generator",
|
||||
name: 'swg b',
|
||||
parent: overlayPlot.uuid
|
||||
});
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: "Sine Wave Generator",
|
||||
name: 'swg c',
|
||||
parent: overlayPlot.uuid
|
||||
});
|
||||
await page.goto(overlayPlot.url);
|
||||
await page.click('button[title="Edit"]');
|
||||
|
||||
// Expand the elements pool vertically
|
||||
@ -60,20 +70,70 @@ test.describe('Stacked Plot', () => {
|
||||
await page.mouse.move(0, 100);
|
||||
await page.mouse.up();
|
||||
|
||||
await page.locator('.js-elements-pool__tree >> text=swg b').click({ button: 'right' });
|
||||
await page.locator('li[role="menuitem"]:has-text("Remove")').click();
|
||||
await page.locator('.js-overlay .js-overlay__button >> text=OK').click();
|
||||
await swgBElementsPoolItem.click({ button: 'right' });
|
||||
await page.getByRole('menuitem').filter({ hasText: /Remove/ }).click();
|
||||
await page.getByRole('button').filter({ hasText: "OK" }).click();
|
||||
|
||||
// Wait until the number of elements in the elements pool has changed, and then confirm that the correct children were retained
|
||||
// await page.waitForFunction(() => {
|
||||
// return Array.from(document.querySelectorAll('.js-elements-pool__tree .js-elements-pool__item')).length === 2;
|
||||
// });
|
||||
// Wait until there are only two items in the elements pool (ie the remove action has completed)
|
||||
await expect(page.locator('.js-elements-pool__tree .js-elements-pool__item')).toHaveCount(2);
|
||||
await expect(page.locator('#inspector-elements-tree .js-elements-pool__item')).toHaveCount(2);
|
||||
|
||||
// Confirm that the elements pool contains the items we expect
|
||||
await expect(page.locator('.js-elements-pool__tree >> text=swg a')).toHaveCount(1);
|
||||
await expect(page.locator('.js-elements-pool__tree >> text=swg b')).toHaveCount(0);
|
||||
await expect(page.locator('.js-elements-pool__tree >> text=swg c')).toHaveCount(1);
|
||||
await expect(swgAElementsPoolItem).toHaveCount(1);
|
||||
await expect(swgBElementsPoolItem).toHaveCount(0);
|
||||
await expect(swgCElementsPoolItem).toHaveCount(1);
|
||||
});
|
||||
|
||||
test('Selecting a child plot while in browse and edit modes shows its properties in the inspector', async ({ page }) => {
|
||||
await page.goto(stackedPlot.url);
|
||||
|
||||
// Click on the 1st plot
|
||||
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"] canvas`).nth(1).click();
|
||||
|
||||
// Assert that the inspector shows the Y Axis properties for swgA
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
||||
await expect(page.getByRole('list', { name: "Y Axis Properties" }).locator("h2")).toContainText("Y Axis");
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgA.name);
|
||||
|
||||
// Click on the 2nd plot
|
||||
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"] canvas`).nth(1).click();
|
||||
|
||||
// Assert that the inspector shows the Y Axis properties for swgB
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
||||
await expect(page.getByRole('list', { name: "Y Axis Properties" }).locator("h2")).toContainText("Y Axis");
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgB.name);
|
||||
|
||||
// Click on the 3rd plot
|
||||
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"] canvas`).nth(1).click();
|
||||
|
||||
// Assert that the inspector shows the Y Axis properties for swgC
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
||||
await expect(page.getByRole('list', { name: "Y Axis Properties" }).locator("h2")).toContainText("Y Axis");
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgC.name);
|
||||
|
||||
// Go into edit mode
|
||||
await page.click('button[title="Edit"]');
|
||||
|
||||
// Click on canvas for the 1st plot
|
||||
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"]`).click();
|
||||
|
||||
// Assert that the inspector shows the Y Axis properties for swgA
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
||||
await expect(page.getByRole('list', { name: "Y Axis Properties" }).locator("h2")).toContainText("Y Axis");
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgA.name);
|
||||
|
||||
//Click on canvas for the 2nd plot
|
||||
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"]`).click();
|
||||
|
||||
// Assert that the inspector shows the Y Axis properties for swgB
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
||||
await expect(page.getByRole('list', { name: "Y Axis Properties" }).locator("h2")).toContainText("Y Axis");
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgB.name);
|
||||
|
||||
//Click on canvas for the 3rd plot
|
||||
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"]`).click();
|
||||
|
||||
// Assert that the inspector shows the Y Axis properties for swgC
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
||||
await expect(page.getByRole('list', { name: "Y Axis Properties" }).locator("h2")).toContainText("Y Axis");
|
||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgC.name);
|
||||
});
|
||||
});
|
||||
|
@ -1190,28 +1190,42 @@ export default {
|
||||
selectNearbyAnnotations(event) {
|
||||
// need to stop propagation right away to prevent selecting the plot itself
|
||||
event.stopPropagation();
|
||||
if (!this.annotationViewingAndEditingAllowed || this.annotationSelections.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nearbyAnnotations = this.gatherNearbyAnnotations();
|
||||
if (!nearbyAnnotations.length) {
|
||||
const emptySelection = this.createPathSelection();
|
||||
this.openmct.selection.select(emptySelection, true);
|
||||
// should show plot itself if we didn't find any annotations
|
||||
|
||||
if (this.annotationViewingAndEditingAllowed && this.annotationSelections.length) {
|
||||
//no annotations were found, but we are adding some now
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.annotationViewingAndEditingAllowed && nearbyAnnotations.length) {
|
||||
//show annotations if some were found
|
||||
const { targetDomainObjects, targetDetails } = this.prepareExistingAnnotationSelection(nearbyAnnotations);
|
||||
this.selectPlotAnnotations({
|
||||
targetDetails,
|
||||
targetDomainObjects,
|
||||
annotations: nearbyAnnotations
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const { targetDomainObjects, targetDetails } = this.prepareExistingAnnotationSelection(nearbyAnnotations);
|
||||
this.selectPlotAnnotations({
|
||||
targetDetails,
|
||||
targetDomainObjects,
|
||||
annotations: nearbyAnnotations
|
||||
});
|
||||
//Fall through to here if either there is no new selection add tags or no existing annotations were retrieved
|
||||
this.selectPlot();
|
||||
},
|
||||
selectPlot() {
|
||||
// should show plot itself if we didn't find any annotations
|
||||
const selection = this.createPathSelection();
|
||||
this.openmct.selection.select(selection, true);
|
||||
},
|
||||
createPathSelection() {
|
||||
let selection = [];
|
||||
selection.unshift({
|
||||
element: this.$el,
|
||||
context: {
|
||||
item: this.domainObject
|
||||
}
|
||||
});
|
||||
this.path.forEach((pathObject, index) => {
|
||||
selection.push({
|
||||
element: this.openmct.layout.$refs.browseObject.$el,
|
||||
|
@ -27,6 +27,7 @@
|
||||
<ul
|
||||
v-if="!isStackedPlotObject"
|
||||
class="c-tree"
|
||||
aria-label="Plot Series Properties"
|
||||
>
|
||||
<h2 title="Plot series display properties in this object">Plot Series</h2>
|
||||
<plot-options-item
|
||||
@ -43,6 +44,7 @@
|
||||
v-for="(yAxis, index) in yAxesWithSeries"
|
||||
:key="`yAxis-${index}`"
|
||||
class="l-inspector-part js-yaxis-properties"
|
||||
:aria-label="yAxesWithSeries.length > 1 ? `Y Axis ${yAxis.id} Properties` : 'Y Axis Properties'"
|
||||
>
|
||||
<h2 title="Y axis settings for this object">Y Axis {{ yAxesWithSeries.length > 1 ? yAxis.id : '' }}</h2>
|
||||
<li class="grid-row">
|
||||
|
@ -27,6 +27,7 @@
|
||||
<ul
|
||||
v-if="!isStackedPlotObject"
|
||||
class="c-tree"
|
||||
aria-label="Plot Series Properties"
|
||||
>
|
||||
<h2 title="Display properties for this object">Plot Series</h2>
|
||||
<li
|
||||
|
@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div v-if="loaded">
|
||||
<ul class="l-inspector-part">
|
||||
<ul
|
||||
class="l-inspector-part"
|
||||
:aria-label="id > 1 ? `Y Axis ${id} Properties` : 'Y Axis Properties'"
|
||||
>
|
||||
<h2>Y Axis {{ id > 1 ? id : '' }}</h2>
|
||||
<li class="grid-row">
|
||||
<div
|
||||
|
@ -20,7 +20,9 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div></div>
|
||||
<div
|
||||
:aria-label="`Stacked Plot Item ${childObject.name}`"
|
||||
></div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@ -102,13 +104,33 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.updateView();
|
||||
this.isEditing = this.openmct.editor.isEditing();
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.openmct.editor.off('isEditing', this.setEditState);
|
||||
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
if (this.component) {
|
||||
this.component.$destroy();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setEditState(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
|
||||
if (this.isEditing) {
|
||||
this.setSelection();
|
||||
} else {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateComponentProp(prop, value) {
|
||||
if (this.component) {
|
||||
this.component[prop] = value;
|
||||
@ -203,6 +225,10 @@ export default {
|
||||
@loadingUpdated="loadingUpdated"/>
|
||||
</div>`
|
||||
});
|
||||
|
||||
if (this.isEditing) {
|
||||
this.setSelection();
|
||||
}
|
||||
},
|
||||
onLockHighlightPointUpdated() {
|
||||
this.$emit('lockHighlightPoint', ...arguments);
|
||||
@ -226,6 +252,17 @@ export default {
|
||||
this.status = status;
|
||||
this.updateComponentProp('status', status);
|
||||
},
|
||||
setSelection() {
|
||||
let childContext = {};
|
||||
childContext.item = this.childObject;
|
||||
this.context = childContext;
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context);
|
||||
},
|
||||
getProps() {
|
||||
return {
|
||||
limitLineLabels: this.showLimitLineLabels,
|
||||
|
@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
<div aria-label="Inspector Views"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
Loading…
Reference in New Issue
Block a user