[Flexible Layouts] Flexible Layout styling fixes (#7319)

This commit is contained in:
Khalid Adil 2024-01-03 19:11:35 -06:00 committed by GitHub
parent 6f3bb5fc6f
commit 70de7363d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1222 additions and 58 deletions

View File

@ -491,7 +491,9 @@
"oger",
"lcovonly",
"gcov",
"WCAG"
"WCAG",
"stackedplot",
"Andale"
],
"dictionaries": ["npm", "softwareTerms", "node", "html", "css", "bash", "en_US"],
"ignorePaths": [

View File

@ -4,6 +4,10 @@
# Requires Git > 2.23
# See https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt
# vue-eslint update 2019
14a0f84c1bcd56886d7c9e4e6afa8f7d292734e5
# eslint changes 2022
d80b6923541704ab925abf0047cbbc58735c27e2
# Copyright year update 2022
4a9744e916d24122a81092f6b7950054048ba860
# Copyright year update 2023

View File

@ -25,4 +25,9 @@ snapshot:
/* Time Conductor Start Time */
.c-compact-tc__setting-value{
opacity: 0 !important;
}
}
/* Chart Area for Plots */
.gl-plot-chart-area{
opacity: 0 !important;
}

View File

@ -25,4 +25,8 @@ snapshot:
/* Time Conductor Start Time */
.c-compact-tc__setting-value{
opacity: 0 !important;
}
/* Chart Area for Plots */
.gl-plot-chart-area{
opacity: 0 !important;
}

104
e2e/helper/stylingUtils.js Normal file
View File

@ -0,0 +1,104 @@
/*****************************************************************************
* 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 { expect } from '../pluginFixtures.js';
/**
* Converts a hex color value to its RGB equivalent.
*
* @param {string} hex - The hex color value. i.e. '#5b0f00'
* @returns {string} The RGB equivalent of the hex color.
*/
function hexToRGB(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? `rgb(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)})`
: null;
}
/**
* Sets the background and text color of a given element.
*
* @param {import('@playwright/test').Page} page - The Playwright page object.
* @param {string} borderColorHex - The hex value of the border color to set, or 'No Style'.
* @param {string} backgroundColorHex - The hex value of the background color to set, or 'No Style'.
* @param {string} textColorHex - The hex value of the text color to set, or 'No Style'.
* @param {import('@playwright/test').Locator} locator - The Playwright locator for the element whose style is to be set.
*/
async function setStyles(page, borderColorHex, backgroundColorHex, textColorHex, locator) {
await locator.click(); // Assuming the locator is clickable and opens the style setting UI
await page.getByLabel('Set border color').click();
await page.getByLabel(borderColorHex).click();
await page.getByLabel('Set background color').click();
await page.getByLabel(backgroundColorHex).click();
await page.getByLabel('Set text color').click();
await page.getByLabel(textColorHex).click();
}
/**
* Checks if the styles of an element match the expected values.
*
* @param {string} expectedBorderColor - The expected border color in RGB format. Default is '#e6b8af' or 'rgb(230, 184, 175)'
* @param {string} expectedBackgroundColor - The expected background color in RGB format.
* @param {string} expectedTextColor - The expected text color in RGB format. Default is #aaaaaa or 'rgb(170, 170, 170)'
* @param {import('@playwright/test').Locator} locator - The Playwright locator for the element whose style is to be checked.
*/
async function checkStyles(
expectedBorderColor,
expectedBackgroundColor,
expectedTextColor,
locator
) {
const layoutStyles = await locator.evaluate((el) => {
return {
border: window.getComputedStyle(el).getPropertyValue('border-top-color'), //infer the left, right, and bottom
background: window.getComputedStyle(el).getPropertyValue('background-color'),
fontColor: window.getComputedStyle(el).getPropertyValue('color')
};
});
expect(layoutStyles.border).toContain(expectedBorderColor);
expect(layoutStyles.background).toContain(expectedBackgroundColor);
expect(layoutStyles.fontColor).toContain(expectedTextColor);
}
/**
* Checks if the font Styles of an element match the expected values.
*
* @param {string} expectedFontSize - The expected font size in '72px' format. Default is 'Default'
* @param {string} expectedFontWeight - The expected font Type. Format as '700' for bold. Default is 'Default'
* @param {string} expectedFontFamily - The expected font Type. Format as "\"Andale Mono\", sans-serif". Default is 'Default'
* @param {import('@playwright/test').Locator} locator - The Playwright locator for the element whose style is to be checked.
*/
async function checkFontStyles(expectedFontSize, expectedFontWeight, expectedFontFamily, locator) {
const layoutStyles = await locator.evaluate((el) => {
return {
fontSize: window.getComputedStyle(el).getPropertyValue('font-size'),
fontWeight: window.getComputedStyle(el).getPropertyValue('font-weight'),
fontFamily: window.getComputedStyle(el).getPropertyValue('font-family')
};
});
expect(layoutStyles.fontSize).toContain(expectedFontSize);
expect(layoutStyles.fontWeight).toContain(expectedFontWeight);
expect(layoutStyles.fontFamily).toContain(expectedFontFamily);
}
export { checkFontStyles, checkStyles, hexToRGB, setStyles };

View File

@ -164,7 +164,7 @@ async function renameTimerFrom3DotMenu(page, timerUrl, newNameForTimer) {
await page.goto(timerUrl);
// Click on 3 Dot Menu
await page.locator('button[title="More options"]').click();
await page.locator('button[title="More actions"]').click();
// Click text=Edit Properties...
await page.locator('text=Edit Properties...').click();

View File

@ -131,7 +131,7 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
const exampleTelemetry = await createExampleTelemetryObject(page);
// Make Link from Telemetry Object to Overlay Plot
await page.locator('button[title="More options"]').click();
await page.locator('button[title="More actions"]').click();
// Select 'Create Link' from dropdown
await page.getByRole('menuitem', { name: ' Create Link' }).click();
@ -206,7 +206,7 @@ test.describe('Generate Visual Test Data @localStorage @generatedata', () => {
const swgWith5sDelay = await createExampleTelemetryObject(page, overlayPlot.uuid);
await page.goto(swgWith5sDelay.url);
await page.getByTitle('More options').click();
await page.getByTitle('More actions').click();
await page.getByRole('menuitem', { name: ' Edit Properties...' }).click();
//Edit Example Telemetry Object to include 5s loading Delay

View File

@ -45,7 +45,7 @@ test.describe('Clear Data Action', () => {
test('works as expected with Example Imagery', async ({ page }) => {
await expect(await page.locator('.c-thumb__image').count()).toBeGreaterThan(0);
// Click the "Clear Data" menu action
await page.getByTitle('More options').click();
await page.getByTitle('More actions').click();
const clearDataMenuItem = page.getByRole('menuitem', {
name: 'Clear Data'
});

View File

@ -158,7 +158,7 @@ test.describe('Persistence operations @couchdb', () => {
});
// Open the edit form for the clock object
await page.click('button[title="More options"]');
await page.click('button[title="More actions"]');
await page.click('li[title="Edit properties of this object."]');
// Modify the display format from default 12hr -> 24hr and click 'Save'

View File

@ -196,7 +196,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
.first()
.click();
// Click hamburger button
await page.locator('[title="More options"]').click();
await page.locator('[title="More actions"]').click();
// Click 'Remove' and press OK
await page.locator('li[role="menuitem"]:has-text("Remove")').click();
@ -366,7 +366,7 @@ test.describe('Basic Condition Set Use', () => {
// Edit SWG to add 8 second loading delay to simulate the case
// where telemetry is not available.
await page.getByTitle('More options').click();
await page.getByTitle('More actions').click();
await page.getByRole('menuitem', { name: 'Edit Properties...' }).click();
await page.getByRole('spinbutton', { name: 'Loading Delay (ms)' }).fill('8000');
await page.getByLabel('Save').click();

View File

@ -283,16 +283,18 @@ test.describe('Flexible Layout Toolbar Actions @localStorage', () => {
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/7234'
});
expect(await page.getByRole('group', { name: 'Container' }).count()).toEqual(2);
await page.getByRole('group', { name: 'Container' }).nth(1).click();
const containerHandles = page.getByRole('columnheader', { name: 'Handle' });
expect(await containerHandles.count()).toEqual(2);
await page.getByRole('columnheader', { name: 'Container Handle 1' }).click();
await page.getByTitle('Add Container').click();
expect(await page.getByRole('group', { name: 'Container' }).count()).toEqual(3);
expect(await containerHandles.count()).toEqual(3);
await page.getByTitle('Remove Container').click();
await expect(page.getByRole('dialog')).toHaveText(
'This action will permanently delete this container from this Flexible Layout. Do you want to continue?'
);
await page.getByRole('button', { name: 'OK' }).click();
expect(await page.getByRole('group', { name: 'Container' }).count()).toEqual(2);
expect(await containerHandles.count()).toEqual(2);
});
test('Remove Frame', async ({ page }) => {
expect(await page.getByRole('group', { name: 'Frame' }).count()).toEqual(2);
@ -305,11 +307,12 @@ test.describe('Flexible Layout Toolbar Actions @localStorage', () => {
expect(await page.getByRole('group', { name: 'Frame' }).count()).toEqual(1);
});
test('Columns/Rows Layout Toggle', async ({ page }) => {
await page.getByRole('group', { name: 'Container' }).nth(1).click();
expect(await page.locator('.c-fl--rows').count()).toEqual(0);
await page.getByRole('columnheader', { name: 'Container Handle 1' }).click();
const flexRows = page.getByLabel('Flexible Layout Row');
expect(await flexRows.count()).toEqual(0);
await page.getByTitle('Columns layout').click();
expect(await page.locator('.c-fl--rows').count()).toEqual(1);
expect(await flexRows.count()).toEqual(1);
await page.getByTitle('Rows layout').click();
expect(await page.locator('.c-fl--rows').count()).toEqual(0);
expect(await flexRows.count()).toEqual(0);
});
});

View File

@ -128,7 +128,7 @@ test.describe('Gauge', () => {
// Create the gauge with defaults
await createDomainObjectWithDefaults(page, { type: 'Gauge' });
await page.click('button[title="More options"]');
await page.click('button[title="More actions"]');
await page.click('li[role="menuitem"]:has-text("Edit Properties")');
// FIXME: We need better selectors for these custom form controls
const displayCurrentValueSwitch = page.locator('.c-toggle-switch__slider >> nth=0');
@ -148,7 +148,7 @@ test.describe('Gauge', () => {
const swgWith5sDelay = await createExampleTelemetryObject(page, gauge.uuid);
await page.goto(swgWith5sDelay.url);
await page.getByTitle('More options').click();
await page.getByTitle('More actions').click();
await page.getByRole('menuitem', { name: /Edit Properties.../ }).click();
//Edit Example Telemetry Object to include 5s loading Delay

View File

@ -247,7 +247,7 @@ test.describe('Notebook export tests', () => {
test('can export notebook as text', async ({ page }) => {
await nbUtils.enterTextEntry(page, `Foo bar entry`);
// Click on 3 Dot Menu
await page.locator('button[title="More options"]').click();
await page.locator('button[title="More actions"]').click();
const downloadPromise = page.waitForEvent('download');
await page.getByRole('menuitem', { name: /Export Notebook as Text/ }).click();

View File

@ -105,7 +105,7 @@ test.describe('Snapshot Container tests', () => {
test.fixme(
'A snapshot can be Viewed, Annotated, display deleted, and saved from Container with 3 dot action menu',
async ({ page }) => {
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More actions').click();
await page.getByRole('menuitem', { name: ' View Snapshot' }).click();
await expect(page.locator('.c-overlay__outer')).toBeVisible();
await page.getByTitle('Annotate').click();
@ -118,7 +118,7 @@ test.describe('Snapshot Container tests', () => {
}
);
test('A snapshot can be Quick Viewed from Container with 3 dot action menu', async ({ page }) => {
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More actions').click();
await page.getByRole('menuitem', { name: 'Quick View' }).click();
await expect(page.locator('.c-overlay__outer')).toBeVisible();
});
@ -212,7 +212,7 @@ test.describe('Snapshot image tests', () => {
// expect two embedded images now
expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(2);
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More actions').click();
await page.getByRole('menuitem', { name: /Remove This Embed/ }).click();
await page.getByRole('button', { name: 'Ok', exact: true }).click();

View File

@ -152,18 +152,18 @@ test.describe('Restricted Notebook with a page locked and with an embed @addInit
test('Allows embeds to be deleted if page unlocked @addInit', async ({ page }) => {
// Click embed popup menu
await page.locator('.c-ne__embed__name .c-icon-button').click();
await page.getByLabel('Notebook Entry').getByLabel('More actions').click();
const embedMenu = page.locator('body >> .c-menu');
const embedMenu = page.getByLabel('Super Menu');
await expect(embedMenu).toContainText('Remove This Embed');
});
test('Disallows embeds to be deleted if page locked @addInit', async ({ page }) => {
await lockPage(page);
// Click embed popup menu
await page.locator('.c-ne__embed__name .c-icon-button').click();
await page.getByLabel('Notebook Entry').getByLabel('More actions').click();
const embedMenu = page.locator('body >> .c-menu');
const embedMenu = page.getByLabel('Super Menu');
await expect(embedMenu).not.toContainText('Remove This Embed');
});
});
@ -176,7 +176,7 @@ test.describe('can export restricted notebook as text', () => {
test('basic functionality ', async ({ page }) => {
await enterTextEntry(page, `Foo bar entry`);
// Click on 3 Dot Menu
await page.locator('button[title="More options"]').click();
await page.locator('button[title="More actions"]').click();
const downloadPromise = page.waitForEvent('download');
await page.getByRole('menuitem', { name: /Export Notebook as Text/ }).click();

View File

@ -167,7 +167,7 @@ test.describe('Tagging in Notebooks @addInit', () => {
test('Can delete objects with tags and neither return in search', async ({ page }) => {
await createNotebookEntryAndTags(page);
// Delete Notebook
await page.locator('button[title="More options"]').click();
await page.locator('button[title="More actions"]').click();
await page.locator('li[title="Remove this object from its containing object."]').click();
await page.locator('button:has-text("OK")').click();
await page.goto('./', { waitUntil: 'domcontentloaded' });

View File

@ -73,7 +73,7 @@ test.describe('Plot Rendering', () => {
async function editSineWaveToUseInfinityOption(page, sineWaveGeneratorObject) {
await page.goto(sineWaveGeneratorObject.url);
// Edit SWG properties to include infinity values
await page.locator('[title="More options"]').click();
await page.locator('[title="More actions"]').click();
await page.locator('[title="Edit properties of this object."]').click();
await page
.getByRole('switch', {

View File

@ -0,0 +1,48 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/**
* This test is dedicated to test conditional styling
*/
import { test } from '../../../../pluginFixtures.js';
test.describe('Conditional Styling', () => {
test.fixme(
'Conditional Styling can be applied to Flex Layout and its children',
async ({ page }) => {
//test
}
);
test.fixme(
'Conditional Styling can be applied to Overlay Plot and its children',
async ({ page }) => {
//test
}
);
test.fixme(
'Conditional Styling changes the styling of the object the condition changes state',
async ({ page }) => {
//test
}
);
});

View File

@ -0,0 +1,414 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/**
* This test is dedicated to test styling of flex layouts
*/
import { createDomainObjectWithDefaults } from '../../../../appActions.js';
import { checkStyles, hexToRGB, setStyles } from '../../../../helper/stylingUtils.js';
import { test } from '../../../../pluginFixtures.js';
const setBorderColor = '#ff00ff';
const setBackgroundColor = '#5b0f00';
const setTextColor = '#e6b8af';
const defaultFrameBorderColor = '#e6b8af'; //default border color
const defaultBorderTargetColor = '#aaaaaa';
const defaultTextColor = '#aaaaaa'; // default text color
const inheritedColor = '#aaaaaa'; // inherited from the body style
const pukeGreen = '#6aa84f'; //Ugliest green known to man
const NO_STYLE_RGBA = 'rgba(0, 0, 0, 0)'; //default background color value
test.describe('Flexible Layout styling', () => {
let stackedPlot;
let flexibleLayout;
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });
// Create a Flexible Layout and attach to the Stacked Plot
flexibleLayout = await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout',
name: 'Flexible Layout'
});
// Create a Stacked Plot and attach to the Flexible Layout
stackedPlot = await createDomainObjectWithDefaults(page, {
type: 'Stacked Plot',
name: 'StackedPlot1',
parent: flexibleLayout.uuid
});
// Create a Stacked Plot and attach to the Flexible Layout
await createDomainObjectWithDefaults(page, {
type: 'Stacked Plot',
name: 'StackedPlot2',
parent: flexibleLayout.uuid
});
});
test('styling the flexible layout properly applies the styles to flex layout', async ({
page
}) => {
// Directly navigate to the flexible layout
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// Select styles tab
await page.getByRole('tab', { name: 'Styles' }).click();
// Set styles using setStyles function
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('Flexible Layout Column')
);
// Flex Layout Column matches set styles
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Flexible Layout Column')
);
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Reload page
await page.reload({ waitUntil: 'domcontentloaded' });
// Check styles of overall Flex Layout
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Flexible Layout Column')
);
// Check styles on StackedPlot1. Note: https://github.com/nasa/openmct/issues/7337
await checkStyles(
hexToRGB(defaultFrameBorderColor),
NO_STYLE_RGBA,
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2. Note: https://github.com/nasa/openmct/issues/7337
await checkStyles(
hexToRGB(defaultFrameBorderColor),
NO_STYLE_RGBA,
hexToRGB(setTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
});
test('styling a child object of the flexible layout properly applies that style to only that child', async ({
page
}) => {
// Directly navigate to the flexible layout
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// Select styles tab
await page.getByRole('tab', { name: 'Styles' }).click();
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
// Set styles using setStyles function on StackedPlot1 but not StackedPlot2
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('StackedPlot1 Frame')
);
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Reload page and verify that styles persist
await page.reload({ waitUntil: 'domcontentloaded' });
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
});
test('if an overall style has been applied to the parent layout or plot, the individual styling should be able to coexist with that', async ({
page
}) => {
//Navigate to stackedPlot
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
// Edit stackedPlot
await page.getByLabel('Edit').click();
await page.getByRole('tab', { name: 'Styles' }).click();
// Set styles using setStyles function on StackedPlot1 but not StackedPlot2
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('Stacked Plot Style Target').locator('div')
);
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Directly navigate to the flexible layout
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// Select styles tab
await page.getByRole('tab', { name: 'Styles' }).click();
// Check styles on StackedPlot1 to match the set colors
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2 to verify they are the default
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
// Set styles using setStyles function on StackedPlot2
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('StackedPlot2 Frame')
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Reload page and verify that styles persist
await page.reload({ waitUntil: 'domcontentloaded' });
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
// Directly navigate to the flexible layout
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// Select styles tab
await page.getByRole('tab', { name: 'Styles' }).click();
// Set Flex Layout Column to puke green
await setStyles(
page,
pukeGreen,
pukeGreen,
pukeGreen,
page.getByLabel('Flexible Layout Column')
);
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Flex Layout Column matches set styles
await checkStyles(
hexToRGB(pukeGreen),
hexToRGB(pukeGreen),
hexToRGB(pukeGreen),
page.getByLabel('Flexible Layout Column')
);
// Check styles on StackedPlot1 matches previously set colors
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Check styles on StackedPlot2 matches previous set colors
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot2 Frame').getByLabel('Stacked Plot Style Target')
);
});
test('when the "no style" option is selected, background and text should be reset to inherited styles', async ({
page
}) => {
// Directly navigate to the flexible layout
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// Select styles tab
await page.getByRole('tab', { name: 'Styles' }).click();
// Set styles using setStyles function
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('StackedPlot1 Frame')
);
// Check styles using checkStyles function
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Reload page and set Styles to 'None'
await page.reload({ waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// Select styles tab
await page.getByRole('tab', { name: 'Styles' }).click();
//Select the 'No Style' option
await setStyles(
page,
'No Style',
'No Style',
'No Style',
page.getByLabel('StackedPlot1 Frame')
);
// Check styles using checkStyles function
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(inheritedColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
// Save Flexible Layout
await page.locator('button[title="Save"]').click();
await page.locator('text=Save and Finish Editing').click();
// Reload page and verify that styles persist
await page.reload({ waitUntil: 'domcontentloaded' });
// Check styles using checkStyles function
await checkStyles(
hexToRGB(defaultBorderTargetColor),
NO_STYLE_RGBA,
hexToRGB(inheritedColor),
page.getByLabel('StackedPlot1 Frame').getByLabel('Stacked Plot Style Target')
);
});
});

View File

@ -0,0 +1,246 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/**
* This test is dedicated to test styling of stacked plots
*/
import { createDomainObjectWithDefaults } from '../../../../appActions.js';
import {
checkFontStyles,
checkStyles,
hexToRGB,
setStyles
} from '../../../../helper/stylingUtils.js';
import { test } from '../../../../pluginFixtures.js';
const setBorderColor = '#ff00ff';
const setBackgroundColor = '#5b0f00';
const setTextColor = '#e6b8af';
const defaultTextColor = '#aaaaaa'; // default text color
const NO_STYLE_RGBA = 'rgba(0, 0, 0, 0)'; //default background color value
const setFontSize = '72px';
const setFontWeight = '700'; //bold for monospace bold
// eslint-disable-next-line prettier/prettier
const setFontFamily = "\"Andale Mono\", sans-serif";
test.describe('Stacked Plot styling', () => {
let stackedPlot;
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });
// Create a Stacked Plot
stackedPlot = await createDomainObjectWithDefaults(page, {
type: 'Stacked Plot',
name: 'StackedPlot1'
});
// Create two SWGs and attach them to the Stacked Plot
await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: 'Sine Wave Generator 1',
parent: stackedPlot.uuid
});
await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: 'Sine Wave Generator 2',
parent: stackedPlot.uuid
});
});
test('styling the overlay plot properly applies the styles to all containers', async ({
page
}) => {
// Directly navigate to the stacked plot
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
await page.getByLabel('Edit').click();
await page.getByRole('tab', { name: 'Styles' }).click();
//Set styles on overall stacked plot
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByRole('tab', { name: 'Styles' }) //Workaround for https://github.com/nasa/openmct/issues/7229
);
//Set Font Size to 72
await page.getByLabel('Set Font Size').click();
await page.getByRole('menuitem', { name: '72px' }).click();
//Set Font Type to Monospace Bold. See setFontWeight and setFontFamily variables
await page.getByLabel('Set Font Type').click();
await page.getByRole('menuitem', { name: 'Monospace Bold' }).click();
//Check styles of stacked plot
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Style Target')
);
//Check font styles of stacked plot
await checkFontStyles(
setFontSize,
setFontWeight,
setFontFamily,
page.getByLabel('Stacked Plot Style Target')
);
//Save
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Reload page
await page.reload({ waitUntil: 'domcontentloaded' });
//Verify styles are correct after reload
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Style Target')
);
await checkFontStyles(
setFontSize,
setFontWeight,
setFontFamily,
page.getByLabel('Stacked Plot Style Target')
);
//Verify that stacked Plot Items inherit only text properties
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
await checkFontStyles(
setFontSize,
setFontWeight,
setFontFamily,
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
});
test.fixme(
'styling a child object of the flexible layout properly applies that style to only that child',
async ({ page }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/7338'
});
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
await page.getByLabel('Edit').click();
await page.getByRole('tab', { name: 'Styles' }).click();
//Check default styles for SWG1 and SWG2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
// Set styles using setStyles function on StackedPlot1 but not StackedPlot2
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
//Set Font Styles on SWG1 but not SWG2
await page.getByLabel('Stacked Plot Item Sine Wave Generator 1').click();
//Set Font Size to 72
await page.getByLabel('Set Font Size').click();
await page.getByRole('menuitem', { name: '72px' }).click();
//Set Font Type to Monospace Bold. See setFontWeight and setFontFamily variables
await page.getByLabel('Set Font Type').click();
await page.getByRole('menuitem', { name: 'Monospace Bold' }).click();
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
// Check styles on StackedPlot2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
// Reload page and verify that styles persist
await page.reload({ waitUntil: 'domcontentloaded' });
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
// Check styles on StackedPlot2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
}
);
});

View File

@ -0,0 +1,90 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/**
* This test is dedicated to test styling changes in the inspector tool
*/
import { createDomainObjectWithDefaults } from '../../../../appActions.js';
import { expect, test } from '../../../../pluginFixtures.js';
test.describe('Style Inspector Options', () => {
let flexibleLayout;
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });
// Create a Flexible Layout and attach to the Stacked Plot
flexibleLayout = await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout',
name: 'Flexible Layout'
});
// Create a Stacked Plot and attach to the Flexible Layout
await createDomainObjectWithDefaults(page, {
type: 'Stacked Plot',
name: 'Stacked Plot',
parent: flexibleLayout.uuid
});
});
test('styles button only appears when appropriate component selected', async ({ page }) => {
await page.goto(flexibleLayout.url, { waitUntil: 'domcontentloaded' });
// Edit Flexible Layout
await page.getByLabel('Edit').click();
// The overall Flex Layout or Stacked Plot itself MUST be style-able.
await expect(page.getByRole('tab', { name: 'Styles' })).toBeVisible();
// Select flexible layout column
await page.getByLabel('Container Handle 1').click();
// Flex Layout containers should NOT be style-able.
await expect(page.getByRole('tab', { name: 'Styles' })).toBeHidden();
// Select Flex Layout Column
await page.getByLabel('Flexible Layout Column').click();
// The overall Flex Layout or Stacked Plot itself MUST be style-able.
await expect(page.getByRole('tab', { name: 'Styles' })).toBeVisible();
// Select Stacked Layout Column
await page.getByLabel('Stacked Plot Frame').click();
// The overall Flex Layout or Stacked Plot itself MUST be style-able.
await expect(page.getByRole('tab', { name: 'Styles' })).toBeVisible();
});
});
test.describe('Saved Styles', () => {
test.fixme('historical styles appear as an option once used', async ({ page }) => {
//test
});
test.fixme('at least 5 saved styles appear in the saved styles list', async ({ page }) => {
//test
});
test.fixme('Saved Styles can be deleted once used', async ({ page }) => {
//test
});
test.fixme('can apply a saved style to the currently selected target', async ({ page }) => {
//test
});
});

View File

@ -85,7 +85,7 @@ test.describe('Timer with target date', () => {
test('Can count down to a target date', async ({ page }) => {
// Set the target date to 2024-11-24 03:30:00
await page.getByTitle('More options').click();
await page.getByTitle('More actions').click();
await page.getByRole('menuitem', { name: /Edit Properties.../ }).click();
await page.getByPlaceholder('YYYY-MM-DD').fill('2024-11-24');
await page.locator('input[name="hour"]').fill('3');
@ -108,7 +108,7 @@ test.describe('Timer with target date', () => {
test('Can count up from a target date', async ({ page }) => {
// Set the target date to 2020-11-23 03:30:00
await page.getByTitle('More options').click();
await page.getByTitle('More actions').click();
await page.getByRole('menuitem', { name: /Edit Properties.../ }).click();
await page.getByPlaceholder('YYYY-MM-DD').fill('2020-11-23');
await page.locator('input[name="hour"]').fill('3');
@ -159,7 +159,7 @@ async function triggerTimerContextMenuAction(page, timerUrl, action) {
*/
async function triggerTimer3dotMenuAction(page, action) {
const menuAction = `.c-menu ul li >> text="${action}"`;
const threeDotMenuButton = 'button[title="More options"]';
const threeDotMenuButton = 'button[title="More actions"]';
let isActionAvailable = false;
let iterations = 0;
// Dismiss/open the 3dot menu until the action is available

View File

@ -46,7 +46,7 @@ test.describe('Visual - LAD Table', () => {
});
//Modify SWG to create a really stable SWG
await page.locator('button[title="More options"]').click();
await page.locator('button[title="More actions"]').click();
await page.getByRole('menuitem', { name: ' Edit Properties...' }).click();

View File

@ -0,0 +1,194 @@
/*****************************************************************************
* 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.