Skip to content

Commit

Permalink
Merge branch 'master' into vipergc-415
Browse files Browse the repository at this point in the history
  • Loading branch information
davetsay authored Oct 8, 2024
2 parents dc7a07c + 83e4a12 commit 6269ecc
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 41 deletions.
16 changes: 8 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ executors:
- image: mcr.microsoft.com/playwright:v1.47.2-focal
environment:
NODE_ENV: development # Needed to ensure 'dist' folder created and devDependencies installed
PERCY_POSTINSTALL_BROWSER: "true" # Needed to store the percy browser in cache deps
PERCY_LOGLEVEL: "debug" # Enable DEBUG level logging for Percy (Issue: https://github.com/nasa/openmct/issues/5742)
PERCY_POSTINSTALL_BROWSER: 'true' # Needed to store the percy browser in cache deps
PERCY_LOGLEVEL: 'debug' # Enable DEBUG level logging for Percy (Issue: https://github.com/nasa/openmct/issues/5742)
PERCY_PARALLEL_TOTAL: 2
ubuntu:
machine:
image: ubuntu-2204:current
docker_layer_caching: true
commands:
build_and_install:
description: "All steps used to build and install."
description: 'All steps used to build and install.'
parameters:
node-version:
type: string
Expand All @@ -27,7 +27,7 @@ commands:
node-version: << parameters.node-version >>
- node/install-packages
generate_and_store_version_and_filesystem_artifacts:
description: "Track important packages and files"
description: 'Track important packages and files'
steps:
- run: |
[[ $EUID -ne 0 ]] && (sudo mkdir -p /tmp/artifacts && sudo chmod 777 /tmp/artifacts) || (mkdir -p /tmp/artifacts && chmod 777 /tmp/artifacts)
Expand Down Expand Up @@ -61,7 +61,7 @@ commands:
[[ $EUID -ne 0 ]] && sudo chmod +x codecov || chmod +x codecov
./codecov --help
generate_e2e_code_cov_report:
description: "Generate e2e code coverage artifacts and publish to codecov.io. Needed to that we can ignore the exit code status of the npm run test"
description: 'Generate e2e code coverage artifacts and publish to codecov.io. Needed to that we can ignore the exit code status of the npm run test'
parameters:
suite:
type: string
Expand Down Expand Up @@ -135,13 +135,13 @@ jobs:
suite: #ci or full
type: string
executor: pw-focal-development
parallelism: 7
parallelism: 8
steps:
- build_and_install:
node-version: lts/hydrogen
- when: #Only install chrome-beta when running the 'full' suite to save $$$
condition:
equal: ["full", <<parameters.suite>>]
equal: ['full', <<parameters.suite>>]
steps:
- run: npx playwright install chrome-beta
- run:
Expand Down Expand Up @@ -323,7 +323,7 @@ workflows:
- e2e-couchdb
triggers:
- schedule:
cron: "0 0 * * *"
cron: '0 0 * * *'
filters:
branches:
only:
Expand Down
51 changes: 51 additions & 0 deletions e2e/appActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,37 @@ async function createExampleTelemetryObject(page, parent = 'mine') {
};
}

/**
* Create a Stable State Telemetry Object (State Generator) for use in visual tests
* and tests against plotting telemetry (e.g. logPlot tests). This will change state every 2 seconds.
* @param {import('@playwright/test').Page} page
* @param {string | import('../src/api/objects/ObjectAPI').Identifier} [parent] the uuid or identifier of the parent object. Defaults to 'mine'
* @returns {Promise<CreatedObjectInfo>} An object containing information about the telemetry object.
*/
async function createStableStateTelemetry(page, parent = 'mine') {
const parentUrl = await getHashUrlToDomainObject(page, parent);

await page.goto(`${parentUrl}`);
const createdObject = await createDomainObjectWithDefaults(page, {
type: 'State Generator',
name: 'Stable State Generator'
});
// edit the state generator to have a 1 second update rate
await page.getByLabel('More actions').click();
await page.getByRole('menuitem', { name: 'Edit Properties...' }).click();
await page.getByLabel('State Duration (seconds)', { exact: true }).fill('2');
await page.getByLabel('Save').click();
// Wait until the URL is updated
const uuid = await getFocusedObjectUuid(page);
const url = await getHashUrlToDomainObject(page, uuid);

return {
name: createdObject.name,
uuid,
url
};
}

/**
* Navigates directly to a given object url, in fixed time mode, with the given start and end bounds. Note: does not set
* default view type.
Expand Down Expand Up @@ -629,13 +660,33 @@ async function getCanvasPixels(page, canvasSelector) {
);
}

/**
* Search for telemetry and link it to an object. objectName should come from the domainObject.name function.
* @param {import('@playwright/test').Page} page
* @param {string} parameterName
* @param {string} objectName
*/
async function linkParameterToObject(page, parameterName, objectName) {
await page.getByRole('searchbox', { name: 'Search Input' }).click();
await page.getByRole('searchbox', { name: 'Search Input' }).fill(parameterName);
await page.getByLabel('Object Results').getByText(parameterName).click();
await page.getByLabel('More actions').click();
await page.getByLabel('Create Link').click();
await page.getByLabel('Modal Overlay').getByLabel('Search Input').click();
await page.getByLabel('Modal Overlay').getByLabel('Search Input').fill(objectName);
await page.getByLabel('Modal Overlay').getByLabel(`Navigate to ${objectName}`).click();
await page.getByLabel('Save').click();
}

export {
createDomainObjectWithDefaults,
createExampleTelemetryObject,
createNotification,
createPlanFromJSON,
createStableStateTelemetry,
expandEntireTree,
getCanvasPixels,
linkParameterToObject,
navigateToObjectWithFixedTimeBounds,
navigateToObjectWithRealTime,
setEndOffset,
Expand Down
21 changes: 21 additions & 0 deletions e2e/tests/framework/appActions.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ import {
createExampleTelemetryObject,
createNotification,
createPlanFromJSON,
createStableStateTelemetry,
expandEntireTree,
getCanvasPixels,
linkParameterToObject,
navigateToObjectWithFixedTimeBounds,
navigateToObjectWithRealTime,
setEndOffset,
Expand Down Expand Up @@ -339,4 +341,23 @@ test.describe('AppActions @framework', () => {
// Expect this step to fail
await waitForPlotsToRender(page, { timeout: 1000 });
});
test('createStableStateTelemetry', async ({ page }) => {
const stableStateTelemetry = await createStableStateTelemetry(page);
expect(stableStateTelemetry.name).toBe('Stable State Generator');
expect(stableStateTelemetry.url).toBe(`./#/browse/mine/${stableStateTelemetry.uuid}`);
expect(stableStateTelemetry.uuid).toBeDefined();
});
test('linkParameterToObject', async ({ page }) => {
const displayLayout = await createDomainObjectWithDefaults(page, {
type: 'Display Layout',
name: 'Test Display Layout'
});
const exampleTelemetry = await createExampleTelemetryObject(page);

await linkParameterToObject(page, exampleTelemetry.name, displayLayout.name);
await page.goto(displayLayout.url);
await expect(page.getByRole('main').getByText('Test Display Layout')).toBeVisible();
await expandEntireTree(page);
await expect(page.getByLabel('Navigate to VIPER Rover').first()).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
This test suite is dedicated to tests which verify the basic operations surrounding conditionSets and styling
*/

import { createDomainObjectWithDefaults, setRealTimeMode } from '../../../../appActions.js';
import {
createDomainObjectWithDefaults,
linkParameterToObject,
setRealTimeMode
} from '../../../../appActions.js';
import { MISSION_TIME } from '../../../../constants.js';
import { expect, test } from '../../../../pluginFixtures.js';

Expand Down Expand Up @@ -92,7 +96,7 @@ test.describe('Conditionally Styling, using a Condition Set', () => {
await page.getByLabel('Save').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();

await searchAndLinkParameterToObject(page, stateGenerator.name, displayLayout.name);
await linkParameterToObject(page, stateGenerator.name, displayLayout.name);

//Add a box to the display layout
await page.goto(displayLayout.url, { waitUntil: 'domcontentloaded' });
Expand Down Expand Up @@ -157,21 +161,3 @@ async function waitForStyleChange(element, expectedStyle, timeout = 0) {
expect(style).toBe(expectedStyle);
}).toPass({ timeout: 1000 }); // timeout allows for the style to be applied
}

/**
* Search for telemetry and link it to an object. objectName should come from the domainObject.name function.
* @param {import('@playwright/test').Page} page
* @param {string} parameterName
* @param {string} objectName
*/
async function searchAndLinkParameterToObject(page, parameterName, objectName) {
await page.getByRole('searchbox', { name: 'Search Input' }).click();
await page.getByRole('searchbox', { name: 'Search Input' }).fill(parameterName);
await page.getByLabel('Object Results').getByText(parameterName).click();
await page.getByLabel('More actions').click();
await page.getByLabel('Create Link').click();
await page.getByLabel('Modal Overlay').getByLabel('Search Input').click();
await page.getByLabel('Modal Overlay').getByLabel('Search Input').fill(objectName);
await page.getByLabel('Modal Overlay').getByLabel(`Navigate to ${objectName}`).click();
await page.getByLabel('Save').click();
}
23 changes: 12 additions & 11 deletions e2e/tests/visual-a11y/displayLayout.visual.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@

import percySnapshot from '@percy/playwright';

import { createDomainObjectWithDefaults } from '../../appActions.js';
import {
createDomainObjectWithDefaults,
createStableStateTelemetry,
linkParameterToObject
} from '../../appActions.js';
import { MISSION_TIME, VISUAL_FIXED_URL } from '../../constants.js';
import { test } from '../../pluginFixtures.js';

Expand All @@ -47,16 +51,13 @@ test.describe('Visual - Display Layout @clock', () => {
name: 'Child Right Layout',
parent: parentLayout.uuid
});
await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: 'SWG 1',
parent: child1Layout.uuid
});
await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: 'SWG 2',
parent: child2Layout.uuid
});

const stableStateTelemetry = await createStableStateTelemetry(page);
await linkParameterToObject(page, stableStateTelemetry.name, child1Layout.name);
await linkParameterToObject(page, stableStateTelemetry.name, child2Layout.name);

// Pause the clock at a time where the telemetry is stable 20 minutes in the future
await page.clock.pauseAt(new Date(MISSION_TIME + 1200000));

await page.goto(parentLayout.url, { waitUntil: 'domcontentloaded' });
await page.getByRole('button', { name: 'Edit Object' }).click();
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/telemetryTable/collections/TableRowCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@ export default class TableRowCollection extends EventEmitter {
}

insertOrUpdateRows(rowsToAdd, addToBeginning) {
rowsToAdd.forEach((row) => {
rowsToAdd.forEach((row, addRowsIndex) => {
const index = this.getInPlaceUpdateIndex(row);
if (index > -1) {
this.updateRowInPlace(row, index);
} else {
if (addToBeginning) {
this.rows.unshift(row);
this.rows.splice(addRowsIndex, 0, row);
} else {
this.rows.push(row);
}
Expand Down

0 comments on commit 6269ecc

Please sign in to comment.