mirror of
https://github.com/nasa/openmct.git
synced 2025-06-18 15:18:12 +00:00
[e2e] Refactor and document our extension of existing Playwright API and RFE features (#5537)
This commit is contained in:
186
e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js
Normal file
186
e2e/tests/functional/plugins/plot/autoscale.e2e.spec.js
Normal file
@ -0,0 +1,186 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Testsuite for plot autoscale.
|
||||
*/
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
test.use({
|
||||
viewport: {
|
||||
width: 1280,
|
||||
height: 720
|
||||
}
|
||||
});
|
||||
|
||||
test.describe('ExportAsJSON', () => {
|
||||
test('User can set autoscale with a valid range @snapshot', async ({ page, openmctConfig }) => {
|
||||
const { myItemsFolderName } = openmctConfig;
|
||||
|
||||
//This is necessary due to the size of the test suite.
|
||||
test.slow();
|
||||
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
|
||||
await setTimeRange(page);
|
||||
|
||||
await createSinewaveOverlayPlot(page, myItemsFolderName);
|
||||
|
||||
await testYTicks(page, ['-1.00', '-0.50', '0.00', '0.50', '1.00']);
|
||||
|
||||
await turnOffAutoscale(page);
|
||||
|
||||
// Make sure that after turning off autoscale, the user selected range values start at the same values the plot had prior.
|
||||
await testYTicks(page, ['-1.00', '-0.50', '0.00', '0.50', '1.00']);
|
||||
|
||||
const canvas = page.locator('canvas').nth(1);
|
||||
|
||||
await canvas.hover({trial: true});
|
||||
|
||||
expect(await canvas.screenshot()).toMatchSnapshot('autoscale-canvas-prepan');
|
||||
|
||||
//Alt Drag Start
|
||||
await page.keyboard.down('Alt');
|
||||
|
||||
await canvas.dragTo(canvas, {
|
||||
sourcePosition: {
|
||||
x: 200,
|
||||
y: 200
|
||||
},
|
||||
targetPosition: {
|
||||
x: 400,
|
||||
y: 400
|
||||
}
|
||||
});
|
||||
|
||||
//Alt Drag End
|
||||
await page.keyboard.up('Alt');
|
||||
|
||||
// Ensure the drag worked.
|
||||
await testYTicks(page, ['0.00', '0.50', '1.00', '1.50', '2.00']);
|
||||
|
||||
await canvas.hover({trial: true});
|
||||
|
||||
expect(await canvas.screenshot()).toMatchSnapshot('autoscale-canvas-panned');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {string} start
|
||||
* @param {string} end
|
||||
*/
|
||||
async function setTimeRange(page, start = '2022-03-29 22:00:00.000Z', end = '2022-03-29 22:00:30.000Z') {
|
||||
// Set a specific time range for consistency, otherwise it will change
|
||||
// on every test to a range based on the current time.
|
||||
|
||||
const timeInputs = page.locator('input.c-input--datetime');
|
||||
await timeInputs.first().click();
|
||||
await timeInputs.first().fill(start);
|
||||
|
||||
await timeInputs.nth(1).click();
|
||||
await timeInputs.nth(1).fill(end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {string} myItemsFolderName
|
||||
*/
|
||||
async function createSinewaveOverlayPlot(page, myItemsFolderName) {
|
||||
// click create button
|
||||
await page.locator('button:has-text("Create")').click();
|
||||
|
||||
// add overlay plot with defaults
|
||||
await page.locator('li:has-text("Overlay Plot")').click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear1
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// save (exit edit mode)
|
||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
|
||||
// click create button
|
||||
await page.locator('button:has-text("Create")').click();
|
||||
|
||||
// add sine wave generator with defaults
|
||||
await page.locator('li:has-text("Sine Wave Generator")').click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear1
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// focus the overlay plot
|
||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=Unnamed Overlay Plot').first().click()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function turnOffAutoscale(page) {
|
||||
// enter edit mode
|
||||
await page.locator('text=Unnamed Overlay Plot Snapshot >> button').nth(3).click();
|
||||
|
||||
// uncheck autoscale
|
||||
await page.locator('text=Y Axis Label Log mode Auto scale Padding >> input[type="checkbox"] >> nth=1').uncheck();
|
||||
|
||||
// save
|
||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
||||
await Promise.all([
|
||||
page.locator('text=Save and Finish Editing').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function testYTicks(page, values) {
|
||||
const yTicks = page.locator('.gl-plot-y-tick-label');
|
||||
await page.locator('canvas >> nth=1').hover();
|
||||
let promises = [yTicks.count().then(c => expect(c).toBe(values.length))];
|
||||
|
||||
for (let i = 0, l = values.length; i < l; i += 1) {
|
||||
promises.push(expect(yTicks.nth(i)).toHaveText(values[i])); // eslint-disable-line
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
301
e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
Normal file
301
e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
Normal file
@ -0,0 +1,301 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Tests to verify log plot functionality. Note this test suite if very much under active development and should not
|
||||
necessarily be used for reference when writing new tests in this area.
|
||||
*/
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
test.describe('Log plot tests', () => {
|
||||
test('Log Plot ticks are functionally correct in regular and log mode and after refresh', async ({ page, openmctConfig }) => {
|
||||
const { myItemsFolderName } = openmctConfig;
|
||||
|
||||
//Test.slow decorator is currently broken. Needs to be fixed in https://github.com/nasa/openmct/issues/5374
|
||||
test.slow();
|
||||
|
||||
await makeOverlayPlot(page, myItemsFolderName);
|
||||
await testRegularTicks(page);
|
||||
await enableEditMode(page);
|
||||
await enableLogMode(page);
|
||||
await testLogTicks(page);
|
||||
await disableLogMode(page);
|
||||
await testRegularTicks(page);
|
||||
await enableLogMode(page);
|
||||
await testLogTicks(page);
|
||||
await saveOverlayPlot(page);
|
||||
await testLogTicks(page);
|
||||
});
|
||||
|
||||
// Leaving test as 'TODO' for now.
|
||||
// NOTE: Not eligible for community contributions.
|
||||
test.fixme('Verify that log mode option is reflected in import/export JSON', async ({ page, openmctConfig }) => {
|
||||
const { myItemsFolderName } = openmctConfig;
|
||||
|
||||
await makeOverlayPlot(page, myItemsFolderName);
|
||||
await enableEditMode(page);
|
||||
await enableLogMode(page);
|
||||
await saveOverlayPlot(page);
|
||||
|
||||
// TODO ...export, delete the overlay, then import it...
|
||||
|
||||
//await testLogTicks(page);
|
||||
|
||||
// TODO, the plot is slightly at different position that in the other test, so this fails.
|
||||
// ...We can fix it by copying all steps from the first test...
|
||||
// await testLogPlotPixels(page);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Makes an overlay plot with a sine wave generator and clicks on the overlay plot in the sidebar so it is the active thing displayed.
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {string} myItemsFolderName
|
||||
*/
|
||||
async function makeOverlayPlot(page, myItemsFolderName) {
|
||||
// fresh page with time range from 2022-03-29 22:00:00.000Z to 2022-03-29 22:00:30.000Z
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
|
||||
// Set a specific time range for consistency, otherwise it will change
|
||||
// on every test to a range based on the current time.
|
||||
|
||||
const timeInputs = page.locator('input.c-input--datetime');
|
||||
await timeInputs.first().click();
|
||||
await timeInputs.first().fill('2022-03-29 22:00:00.000Z');
|
||||
|
||||
await timeInputs.nth(1).click();
|
||||
await timeInputs.nth(1).fill('2022-03-29 22:00:30.000Z');
|
||||
|
||||
// create overlay plot
|
||||
|
||||
await page.locator('button.c-create-button').click();
|
||||
await page.locator('li:has-text("Overlay Plot")').click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// save the overlay plot
|
||||
|
||||
await saveOverlayPlot(page);
|
||||
|
||||
// create a sinewave generator
|
||||
|
||||
await page.locator('button.c-create-button').click();
|
||||
await page.locator('li:has-text("Sine Wave Generator")').click();
|
||||
|
||||
// set amplitude to 6, offset 4, period 2
|
||||
|
||||
await page.locator('div:nth-child(5) .c-form-row__controls .form-control .field input').click();
|
||||
await page.locator('div:nth-child(5) .c-form-row__controls .form-control .field input').fill('6');
|
||||
|
||||
await page.locator('div:nth-child(6) .c-form-row__controls .form-control .field input').click();
|
||||
await page.locator('div:nth-child(6) .c-form-row__controls .form-control .field input').fill('4');
|
||||
|
||||
await page.locator('div:nth-child(7) .c-form-row__controls .form-control .field input').click();
|
||||
await page.locator('div:nth-child(7) .c-form-row__controls .form-control .field input').fill('2');
|
||||
|
||||
// Click OK to make generator
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// click on overlay plot
|
||||
|
||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=Unnamed Overlay Plot').first().click()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function testRegularTicks(page) {
|
||||
const yTicks = await page.locator('.gl-plot-y-tick-label');
|
||||
expect(await yTicks.count()).toBe(7);
|
||||
await expect(yTicks.nth(0)).toHaveText('-2');
|
||||
await expect(yTicks.nth(1)).toHaveText('0');
|
||||
await expect(yTicks.nth(2)).toHaveText('2');
|
||||
await expect(yTicks.nth(3)).toHaveText('4');
|
||||
await expect(yTicks.nth(4)).toHaveText('6');
|
||||
await expect(yTicks.nth(5)).toHaveText('8');
|
||||
await expect(yTicks.nth(6)).toHaveText('10');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function testLogTicks(page) {
|
||||
const yTicks = await page.locator('.gl-plot-y-tick-label');
|
||||
expect(await yTicks.count()).toBe(28);
|
||||
await expect(yTicks.nth(0)).toHaveText('-2.98');
|
||||
await expect(yTicks.nth(1)).toHaveText('-2.50');
|
||||
await expect(yTicks.nth(2)).toHaveText('-2.00');
|
||||
await expect(yTicks.nth(3)).toHaveText('-1.51');
|
||||
await expect(yTicks.nth(4)).toHaveText('-1.20');
|
||||
await expect(yTicks.nth(5)).toHaveText('-1.00');
|
||||
await expect(yTicks.nth(6)).toHaveText('-0.80');
|
||||
await expect(yTicks.nth(7)).toHaveText('-0.58');
|
||||
await expect(yTicks.nth(8)).toHaveText('-0.40');
|
||||
await expect(yTicks.nth(9)).toHaveText('-0.20');
|
||||
await expect(yTicks.nth(10)).toHaveText('-0.00');
|
||||
await expect(yTicks.nth(11)).toHaveText('0.20');
|
||||
await expect(yTicks.nth(12)).toHaveText('0.40');
|
||||
await expect(yTicks.nth(13)).toHaveText('0.58');
|
||||
await expect(yTicks.nth(14)).toHaveText('0.80');
|
||||
await expect(yTicks.nth(15)).toHaveText('1.00');
|
||||
await expect(yTicks.nth(16)).toHaveText('1.20');
|
||||
await expect(yTicks.nth(17)).toHaveText('1.51');
|
||||
await expect(yTicks.nth(18)).toHaveText('2.00');
|
||||
await expect(yTicks.nth(19)).toHaveText('2.50');
|
||||
await expect(yTicks.nth(20)).toHaveText('2.98');
|
||||
await expect(yTicks.nth(21)).toHaveText('3.50');
|
||||
await expect(yTicks.nth(22)).toHaveText('4.00');
|
||||
await expect(yTicks.nth(23)).toHaveText('4.50');
|
||||
await expect(yTicks.nth(24)).toHaveText('5.31');
|
||||
await expect(yTicks.nth(25)).toHaveText('7.00');
|
||||
await expect(yTicks.nth(26)).toHaveText('8.00');
|
||||
await expect(yTicks.nth(27)).toHaveText('9.00');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function enableEditMode(page) {
|
||||
// turn on edit mode
|
||||
await page.locator('text=Unnamed Overlay Plot Snapshot >> button').nth(3).click();
|
||||
await expect(await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1)).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function enableLogMode(page) {
|
||||
// turn on log mode
|
||||
await page.locator('text=Y Axis Label Log mode Auto scale Padding >> input[type="checkbox"]').first().check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function disableLogMode(page) {
|
||||
// turn off log mode
|
||||
await page.locator('text=Y Axis Label Log mode Auto scale Padding >> input[type="checkbox"]').first().uncheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function saveOverlayPlot(page) {
|
||||
// save overlay plot
|
||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
||||
|
||||
await Promise.all([
|
||||
page.locator('text=Save and Finish Editing').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
// FIXME: Remove this eslint exception once implemented
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async function testLogPlotPixels(page) {
|
||||
const pixelsMatch = await page.evaluate(async () => {
|
||||
// TODO get canvas pixels at a few locations to make sure they're the correct color, to test that the plot comes out as expected.
|
||||
|
||||
await new Promise((r) => setTimeout(r, 5 * 1000));
|
||||
|
||||
// These are some pixels that should be blue points in the log plot.
|
||||
// If the plot changes shape to an unexpected shape, this will
|
||||
// likely fail, which is what we want.
|
||||
//
|
||||
// I found these pixels by pausing playwright in debug mode at this
|
||||
// point, and using similar code as below to output the pixel data, then
|
||||
// I logged those pixels here.
|
||||
const expectedBluePixels = [
|
||||
// TODO these pixel sets only work with the first test, but not the second test.
|
||||
|
||||
// [60, 35],
|
||||
// [121, 125],
|
||||
// [156, 377],
|
||||
// [264, 73],
|
||||
// [372, 186],
|
||||
// [576, 73],
|
||||
// [659, 439],
|
||||
// [675, 423]
|
||||
|
||||
[60, 35],
|
||||
[120, 125],
|
||||
[156, 375],
|
||||
[264, 73],
|
||||
[372, 185],
|
||||
[575, 72],
|
||||
[659, 437],
|
||||
[675, 421]
|
||||
];
|
||||
|
||||
// The first canvas in the DOM is the one that has the plot point
|
||||
// icons (canvas 2d), which is the one we are testing. The second
|
||||
// one in the DOM is the WebGL canvas with the line. (Why aren't
|
||||
// they both WebGL?)
|
||||
const canvas = document.querySelector('canvas');
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
for (const pixel of expectedBluePixels) {
|
||||
// XXX Possible optimization: call getImageData only once with
|
||||
// area including all pixels to be tested.
|
||||
const data = ctx.getImageData(pixel[0], pixel[1], 1, 1).data;
|
||||
|
||||
// #43b0ffff <-- openmct cyanish-blue with 100% opacity
|
||||
// if (data[0] !== 0x43 || data[1] !== 0xb0 || data[2] !== 0xff || data[3] !== 0xff) {
|
||||
if (data[0] === 0 && data[1] === 0 && data[2] === 0 && data[3] === 0) {
|
||||
// If any pixel is empty, it means we didn't hit a plot point.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
expect(pixelsMatch).toBe(true);
|
||||
}
|
156
e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js
Normal file
156
e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js
Normal file
@ -0,0 +1,156 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Tests to verify log plot functionality when objects are missing
|
||||
*/
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
|
||||
test.describe('Handle missing object for plots', () => {
|
||||
test('Displays empty div for missing stacked plot item @unstable', async ({ page, browserName, openmctConfig }) => {
|
||||
const { myItemsFolderName } = openmctConfig;
|
||||
|
||||
test.fixme(browserName === 'firefox', 'Firefox failing due to console events being missed');
|
||||
const errorLogs = [];
|
||||
|
||||
page.on("console", (message) => {
|
||||
if (message.type() === 'warning' && message.text().includes('Missing domain object')) {
|
||||
errorLogs.push(message.text());
|
||||
}
|
||||
});
|
||||
|
||||
//Make stacked plot
|
||||
await makeStackedPlot(page, myItemsFolderName);
|
||||
|
||||
//Gets local storage and deletes the last sine wave generator in the stacked plot
|
||||
const localStorage = await page.evaluate(() => window.localStorage);
|
||||
const parsedData = JSON.parse(localStorage.mct);
|
||||
const keys = Object.keys(parsedData);
|
||||
const lastKey = keys[keys.length - 1];
|
||||
|
||||
delete parsedData[lastKey];
|
||||
|
||||
//Sets local storage with missing object
|
||||
await page.evaluate(
|
||||
`window.localStorage.setItem('mct', '${JSON.stringify(parsedData)}')`
|
||||
);
|
||||
|
||||
//Reloads page and clicks on stacked plot
|
||||
await Promise.all([
|
||||
page.reload(),
|
||||
page.waitForLoadState('networkidle')
|
||||
]);
|
||||
|
||||
//Verify Main section is there on load
|
||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Stacked Plot');
|
||||
|
||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=Unnamed Stacked Plot').first().click()
|
||||
]);
|
||||
|
||||
//Check that there is only one stacked item plot with a plot, the missing one will be empty
|
||||
await expect(page.locator(".c-plot--stacked-container:has(.gl-plot)")).toHaveCount(1);
|
||||
//Verify that console.warn is thrown
|
||||
expect(errorLogs).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* This is used the create a stacked plot object
|
||||
* @private
|
||||
*/
|
||||
async function makeStackedPlot(page, myItemsFolderName) {
|
||||
// fresh page with time range from 2022-03-29 22:00:00.000Z to 2022-03-29 22:00:30.000Z
|
||||
await page.goto('./', { waitUntil: 'networkidle' });
|
||||
|
||||
// create stacked plot
|
||||
await page.locator('button.c-create-button').click();
|
||||
await page.locator('li:has-text("Stacked Plot")').click();
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
|
||||
// save the stacked plot
|
||||
await saveStackedPlot(page);
|
||||
|
||||
// create a sinewave generator
|
||||
await createSineWaveGenerator(page);
|
||||
|
||||
// click on stacked plot
|
||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=Unnamed Stacked Plot').first().click()
|
||||
]);
|
||||
|
||||
// create a second sinewave generator
|
||||
await createSineWaveGenerator(page);
|
||||
|
||||
// click on stacked plot
|
||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=Unnamed Stacked Plot').first().click()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to save a stacked plot object
|
||||
* @private
|
||||
*/
|
||||
async function saveStackedPlot(page) {
|
||||
// save stacked plot
|
||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
||||
|
||||
await Promise.all([
|
||||
page.locator('text=Save and Finish Editing').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to create a sine wave generator object
|
||||
* @private
|
||||
*/
|
||||
async function createSineWaveGenerator(page) {
|
||||
//Create sine wave generator
|
||||
await page.locator('button.c-create-button').click();
|
||||
await page.locator('li:has-text("Sine Wave Generator")').click();
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
}
|
Reference in New Issue
Block a user