Skip to content

Mct7367-tests #7387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
68edf79
refactor(ExportAsJSONAction): use private methods
ozyx Jan 10, 2024
b07a73e
refactor: remove unnecessary webpack alias
ozyx Jan 10, 2024
a0b71f4
refactor: lint
ozyx Jan 10, 2024
95ac152
fix: tests for `ExportAsJSONAction`
ozyx Jan 11, 2024
44fac67
test: stabilize `InspectorStylesSpec` tests
ozyx Jan 11, 2024
81b6b97
docs: fix jsdocs
ozyx Jan 11, 2024
9a1437a
chore: remove dead / redundant code
ozyx Jan 11, 2024
4f8403a
refactor(LocalStorageObjectProvider): use `getItem()` and `setItem()`
ozyx Jan 12, 2024
7378351
refactor(ExportAsJSONAction): use `Promise.all` where applicable
ozyx Jan 12, 2024
201deea
refactor(MenuAPI): one-liner
ozyx Jan 12, 2024
9f85a0b
feat: add percentage ProgressBar to ExportAsJSONAction
ozyx Jan 12, 2024
975ef25
fix(ProgressBar.vue): v-if conditionals
ozyx Jan 12, 2024
3a0c975
test(fix): update mockLocalStorage
ozyx Jan 12, 2024
24b80e3
test: fix locators
ozyx Jan 17, 2024
b88c849
test: remove unneeded awaits
ozyx Jan 17, 2024
d5b02b0
fix: example imagery urls (moved after NASA wordpress migration)
ozyx Jan 17, 2024
0de6640
Revert "refactor(LocalStorageObjectProvider): use `getItem()` and `se…
ozyx Jan 17, 2024
cb3d408
test(e2e): fix logPlot test
ozyx Jan 18, 2024
ef64b0d
Revert "Revert "refactor(LocalStorageObjectProvider): use `getItem()`…
ozyx Jan 18, 2024
b47ceff
test(e2e): remove waitForNavigations
ozyx Jan 18, 2024
fecd1ae
driveby and fixes
unlikelyzero Jan 18, 2024
590e2ea
aria improvement
unlikelyzero Jan 18, 2024
31bb25d
getting tests back oline
unlikelyzero Jan 18, 2024
c05e22d
more tests
unlikelyzero Jan 18, 2024
84caca1
Merge branch 'master' of https://github.com/nasa/openmct into mct7367…
unlikelyzero Jan 18, 2024
4901bf7
add last test
unlikelyzero Jan 18, 2024
0e9b667
Merge branch 'master' of https://github.com/nasa/openmct into mct7367…
unlikelyzero Jan 19, 2024
c26f124
Add a11y
unlikelyzero Jan 23, 2024
496b6c6
lint
unlikelyzero Jan 23, 2024
615face
lint
unlikelyzero Jan 23, 2024
406a94d
driveby
unlikelyzero Jan 23, 2024
7a4ee18
review comments
unlikelyzero Jan 23, 2024
16dd00c
driveby rename
unlikelyzero Jan 23, 2024
94b690a
fix selectors and break up test suites
unlikelyzero Jan 23, 2024
af95399
add test for snapshot in header
unlikelyzero Jan 23, 2024
ab01db9
last lint fixes
unlikelyzero Jan 23, 2024
f235d50
stable
unlikelyzero Jan 23, 2024
84597e8
comment
unlikelyzero Jan 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions .webpack/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,23 @@ This is the OpenMCT common webpack file. It is imported by the other three webpa
There are separate npm scripts to use these configurations, though simply running `npm install`
will use the default production configuration.
*/
import path from 'node:path';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import webpack from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import fs from 'node:fs';
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import CopyWebpackPlugin from 'copy-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { VueLoaderPlugin } from 'vue-loader';
import webpack from 'webpack';
let gitRevision = 'error-retrieving-revision';
let gitBranch = 'error-retrieving-branch';

const packageDefinition = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));

try {
gitRevision = execSync('git rev-parse HEAD').toString().trim();
gitBranch = execSync('git rev-parse --abbrev-ref HEAD')
.toString()
.trim();
gitBranch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
} catch (err) {
console.warn(err);
}
Expand Down Expand Up @@ -67,7 +65,6 @@ const config = {
alias: {
'@': path.join(projectRootDir, 'src'),
legacyRegistry: path.join(projectRootDir, 'src/legacyRegistry'),
saveAs: 'file-saver/src/FileSaver.js',
csv: 'comma-separated-values',
EventEmitter: 'eventemitter3',
bourbon: 'bourbon.scss',
Expand Down
4 changes: 2 additions & 2 deletions e2e/appActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ async function navigateToObjectWithFixedTimeBounds(page, url, start, end) {
* @param {string} url the url to the object
*/
async function openObjectTreeContextMenu(page, url) {
await page.goto(url);
await page.click('button[title="Show selected item in tree"]');
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.getByLabel('Show selected item in tree').click();
await page.locator('.is-navigated-object').click({
button: 'right'
});
Expand Down
2 changes: 1 addition & 1 deletion e2e/helper/notebookUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async function dragAndDropEmbed(page, notebookObject) {
// Navigate to notebook
await page.goto(notebookObject.url);
// Expand the tree to reveal the notebook
await page.click('button[title="Show selected item in tree"]');
await page.getByLabel('Show selected item in tree').click();
// Drag and drop the SWG into the notebook
await page.dragAndDrop(`text=${swg.name}`, NOTEBOOK_DROP_AREA);
await commitEntry(page);
Expand Down
12 changes: 11 additions & 1 deletion e2e/tests/framework/appActions.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import {
createDomainObjectWithDefaults,
createNotification,
expandEntireTree
expandEntireTree,
openObjectTreeContextMenu
} from '../../appActions.js';
import { expect, test } from '../../pluginFixtures.js';

Expand Down Expand Up @@ -166,4 +167,13 @@ test.describe('AppActions', () => {
const locatorTreeCollapsedItems = locatorTree.locator('role=treeitem[expanded=false]');
expect(await locatorTreeCollapsedItems.count()).toBe(0);
});
test('openObjectTreeContextMenu', async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });

const folder = await createDomainObjectWithDefaults(page, {
type: 'Folder'
});
await openObjectTreeContextMenu(page, folder.url);
await expect(page.getByLabel('Menu')).toBeVisible();
});
});
4 changes: 2 additions & 2 deletions e2e/tests/functional/clearDataAction.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ test.describe('Clear Data Action', () => {
await expect(page.locator(backgroundImageSelector)).toBeVisible();
});
test('works as expected with Example Imagery', async ({ page }) => {
await expect(await page.locator('.c-thumb__image').count()).toBeGreaterThan(0);
expect(await page.locator('.c-thumb__image').count()).toBeGreaterThan(0);
// Click the "Clear Data" menu action
await page.getByTitle('More actions').click();
await expect(
Expand All @@ -59,6 +59,6 @@ test.describe('Clear Data Action', () => {

// Verify that the background image is no longer visible
await expect(page.locator(backgroundImageSelector)).toBeHidden();
await expect(await page.locator('.c-thumb__image').count()).toBe(0);
expect(await page.locator('.c-thumb__image').count()).toBe(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,140 @@
This test suite is dedicated to tests which verify the basic operations surrounding exportAsJSON.
*/

// FIXME: Remove this eslint exception once tests are implemented
// eslint-disable-next-line no-unused-vars
import fs from 'fs/promises';

import {
createDomainObjectWithDefaults,
openObjectTreeContextMenu
} from '../../../../appActions.js';
import { expect, test } from '../../../../baseFixtures.js';

test.describe('ExportAsJSON', () => {
test.fixme(
'Create a basic object and verify that it can be exported as JSON from Tree',
async ({ page }) => {
//Create domain object
//Save Domain Object
//Verify that the newly created domain object can be exported as JSON from the Tree
}
);
test.fixme(
'Create a basic object and verify that it can be exported as JSON from 3 dot menu',
async ({ page }) => {
//Create domain object
//Save Domain Object
//Verify that the newly created domain object can be exported as JSON from the 3 dot menu
}
);
test.fixme('Verify that a nested Object can be exported as JSON', async ({ page }) => {
// Create 2 objects with hierarchy
// Export as JSON
// Verify Hierarchy
let folder;
test.beforeEach(async ({ page }) => {
// Go to baseURL
await page.goto('./', { waitUntil: 'networkidle' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

networkidle?

// Perform actions to create the domain object
folder = await createDomainObjectWithDefaults(page, {
type: 'Folder',
name: 'e2e folder'
});
});
test('Create a basic object and verify that it can be exported as JSON from Tree', async ({
page
}) => {
// Navigate to the page
await page.goto(folder.url);

// Open context menu and initiate download
await openObjectTreeContextMenu(page, folder.url);
const [download] = await Promise.all([
page.waitForEvent('download'), // Waits for the download event
page.getByLabel('Export as JSON').click() // Triggers the download
]);

// Wait for the download process to complete
const path = await download.path();

// Read the contents of the downloaded file using readFile from fs/promises
const fileContents = await fs.readFile(path, 'utf8');
const jsonData = JSON.parse(fileContents);

// Use the function to retrieve the key
const key = getFirstKeyFromOpenMctJson(jsonData);

// Verify the contents of the JSON file
expect(jsonData.openmct[key]).toHaveProperty('name', 'e2e folder');
expect(jsonData.openmct[key]).toHaveProperty('type', 'folder');
});
test('Create a basic object and verify that it can be exported as JSON from 3 dot menu', async ({
page
}) => {
// Navigate to the page
await page.goto(folder.url);
//3 dot menu
await page.getByLabel('More actions').click();
// Open context menu and initiate download
const [download] = await Promise.all([
page.waitForEvent('download'), // Waits for the download event
page.getByLabel('Export as JSON').click() // Triggers the download
]);

// Read the contents of the downloaded file using readFile from fs/promises
const fileContents = await fs.readFile(await download.path(), 'utf8');
const jsonData = JSON.parse(fileContents);

// Use the function to retrieve the key
const key = getFirstKeyFromOpenMctJson(jsonData);

// Verify the contents of the JSON file
expect(jsonData.openmct[key]).toHaveProperty('name', 'e2e folder');
expect(jsonData.openmct[key]).toHaveProperty('type', 'folder');
});
test('Verify that a nested Object can be exported as JSON', async ({ page }) => {
const timer = await createDomainObjectWithDefaults(page, {
type: 'Timer',
name: 'timer',
parent: folder.uuid
});
// Navigate to the page
await page.goto(timer.url);

//do this against parent folder.url, NOT timer.url child
await openObjectTreeContextMenu(page, folder.url);
// Open context menu and initiate download
const [download] = await Promise.all([
page.waitForEvent('download'), // Waits for the download event
page.getByLabel('Export as JSON').click() // Triggers the download
]);

// Read the contents of the downloaded file
const fileContents = await fs.readFile(await download.path(), 'utf8');
const jsonData = JSON.parse(fileContents);

// Retrieve the keys for folder and timer
const folderKey = getFirstKeyFromOpenMctJson(jsonData);
const timerKey = jsonData.openmct[folderKey].composition[0].key;

// Verify the folder properties
expect(jsonData.openmct[folderKey]).toHaveProperty('name', 'e2e folder');
expect(jsonData.openmct[folderKey]).toHaveProperty('type', 'folder');

// Verify the timer properties
expect(jsonData.openmct[timerKey]).toHaveProperty('name', 'timer');
expect(jsonData.openmct[timerKey]).toHaveProperty('type', 'timer');

// Verify the composition of the folder includes the timer
expect(jsonData.openmct[folderKey].composition).toEqual(
expect.arrayContaining([expect.objectContaining({ key: timerKey })])
);
});
});
test.describe('ExportAsJSON Disabled Actions', () => {
test.fixme(
'Verify that the ExportAsJSON dropdown does not appear for the item X',
async ({ page }) => {
// Other than non-persistable objects
}
);
});

/**
* Retrieves the first key from the 'openmct' property of the provided JSON object.
*
* @param {Object} jsonData - The JSON object containing the 'openmct' property.
* @returns {string} The first key found in the 'openmct' object.
* @throws {Error} If no keys are found in the 'openmct' object.
*/
function getFirstKeyFromOpenMctJson(jsonData) {
if (!jsonData.openmct) {
throw new Error("The provided JSON object does not have an 'openmct' property.");
}

const keys = Object.keys(jsonData.openmct);
if (keys.length === 0) {
throw new Error('No keys found in the openmct object');
}

return keys[0];
}
39 changes: 13 additions & 26 deletions e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,53 +95,40 @@ async function makeOverlayPlot(page, myItemsFolderName) {

await page.locator('button.c-create-button').click();
await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
// Click OK button and wait for Navigate event
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle' }),
page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForLoadState(),
await page.getByRole('button', { name: 'Save' }).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[role="menuitem"]: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');
// set amplitude to 6, offset 4, data rate 2 hz

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 page.getByLabel('Amplitude').fill('6');
await page.getByLabel('Offset').fill('4');
await page.getByLabel('Data Rate (hz)').fill('2');

// Click OK button and wait for Navigate event
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle' }),
page.locator('button:has-text("OK")').click(),
//Wait for Save Banner to appear
page.waitForLoadState(),
await page.getByRole('button', { name: 'Save' }).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.waitForLoadState(),
page.locator('text=Unnamed Overlay Plot').first().click()
]);
}
Expand Down
36 changes: 18 additions & 18 deletions example/imagery/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@
*****************************************************************************/

const DEFAULT_IMAGE_SAMPLES = [
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18731.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18732.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18733.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18734.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18735.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18736.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18737.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18738.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18739.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18740.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18741.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18742.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18743.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18744.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18745.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18746.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18747.jpg',
'https://www.hq.nasa.gov/alsj/a16/AS16-117-18748.jpg'
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18731.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18732.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18733.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18734.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18735.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18736.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18737.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18738.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18739.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18740.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18741.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18742.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18743.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18744.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18745.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18746.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18747.jpg',
'https://www.nasa.gov/wp-content/uploads/static/history/alsj/a16/AS16-117-18748.jpg'
];
const DEFAULT_IMAGE_LOAD_DELAY_IN_MILLISECONDS = 20000;
const MIN_IMAGE_LOAD_DELAY_IN_MILLISECONDS = 5000;
Expand Down
4 changes: 1 addition & 3 deletions src/api/menu/MenuAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ class MenuAPI {
if (isActionGroup) {
action = this.actionsToMenuItems(action, objectPath, view);
} else {
action.onItemClicked = () => {
action.invoke(objectPath, view);
};
action.onItemClicked = () => action.invoke(objectPath, view);
}

return action;
Expand Down
Loading