Skip to content

Commit 4935d5e

Browse files
jvigliottakhalidadilakhenryshefalijoshi
authored
Feature/historical conditions (#8148)
* adding telemetry collections to condition manager * handling telemetry collection data not datum * adding from maaster * addressing PR comments * update unit test to work with telemetry collections * fixing tests * removing unnecessary addition * removing focused describe * removing focused it * fix weird test bleed * Add realtime output of telemetry data in conditionals and add support for historical conditional telemetry queries to allow for plotting * Cleanup and add missing files * Fix issue with missing data * Update emitted values * Addressing feedback * Creating a const for telemetry value * Cleanup * Pass through plot options * Cleanup * Fix problem introduced with const * Add back initialize on mount * Compensate for missing data at certain timestamps * Rename file * Rename file * Update metadata provider * Update condition set metadata * Fix zero issue * Try removing the default format for better data inspection * pulled over changes that were made after copying whole repo in a dump * pulling over from file dump * remove debug * handle "none" output situations * removing telemetry when output condition is "none" * adding license info * one last tweak to get none to work correctly without messin up other stuff * WIP tests * make sure unit exists * WIP * WIP * adding timesystem accounting * WIP * remove unused method * handling dupes from historical/subscription, correct formatting before evaluating conditions * update tests to new output format * updating to reflect column name change * update to match new path style for telemetry options * more robust handling of new condition inspector view "canView" method * update for paths in condition telemetry dropdown, add config tab to inspector tests * updating for new paths in telemetry selection dropdwns * lint * remove unused method * add keystring to telem objcts so its easy to grab * dont use index * remove unused method * removed debug logs * use predefined priority constants * remove debug * lint * fix process buffer and remove fit on test * added missing await * remove unused arg * using a set instead of two arrays * using a set instead of two arrays, normalize id * add a guard if unsubscribe path is called with no telemetryobject * explicitly import isEqual instead of random global use * Updates to work with new changes introduced for conditionsets, merged both intended changes/fixes * lint * correcting case * handling removing output telemetry when condition set is being viewed and when not being viewed, but on load * handle removed telemetry correctly for conditions that use it * deleting instead of null settting to avoid issues on last unsub * lint --------- Co-authored-by: Khalid Adil <khalidadil29@gmail.com> Co-authored-by: Andrew Henry <akhenry@gmail.com> Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
1 parent 09ad12b commit 4935d5e

27 files changed

Lines changed: 1308 additions & 290 deletions

.webpack/webpack.common.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ const config = {
5353
compsMathWorker: './src/plugins/comps/CompsMathWorker.js',
5454
espressoTheme: './src/plugins/themes/espresso-theme.scss',
5555
snowTheme: './src/plugins/themes/snow-theme.scss',
56-
darkmatterTheme: './src/plugins/themes/darkmatter-theme.scss'
56+
darkmatterTheme: './src/plugins/themes/darkmatter-theme.scss',
57+
historicalTelemetryWorker: './src/plugins/condition/historicalTelemetryWorker.js',
5758
},
5859
output: {
5960
globalObject: 'this',

e2e/appActions.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,22 @@ async function createDomainObjectWithDefaults(
132132
};
133133
}
134134

135+
/**
136+
* Retrieves the properties of an OpenMCT domain object by its identifier.
137+
*
138+
* @param {import('@playwright/test').Page} page - The Playwright page object.
139+
* @param {string | identifier - The identifier or UUID of the domain object.
140+
* @returns {Promise<Object>} An object containing the properties of the domain object.
141+
*/
142+
async function getDomainObject(page, identifier) {
143+
const domainObject = await page.evaluate(async (objIdentifier) => {
144+
const object = await window.openmct.objects.get(objIdentifier);
145+
return object;
146+
}, identifier);
147+
148+
return domainObject;
149+
}
150+
135151
/**
136152
* Generate a notification with the given options.
137153
* @param {import('@playwright/test').Page} page
@@ -884,6 +900,7 @@ export {
884900
expandInspectorPane,
885901
expandTreePane,
886902
getCanvasPixels,
903+
getDomainObject,
887904
getNextSineValueFromSWG,
888905
linkParameterToObject,
889906
navigateToObjectWithFixedTimeBounds,

e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js

Lines changed: 67 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import { fileURLToPath } from 'url';
2929

3030
import {
3131
createDomainObjectWithDefaults,
32-
createExampleTelemetryObject
32+
createExampleTelemetryObject,
33+
getDomainObject
3334
} from '../../../../appActions.js';
3435
import { expect, test } from '../../../../pluginFixtures.js';
3536

@@ -292,7 +293,7 @@ test.describe('Basic Condition Set Use', () => {
292293
).toBeVisible();
293294
await page.getByLabel('Open the View Switcher Menu').click();
294295
await page.getByLabel('Telemetry Table').click();
295-
await expect(page.getByRole('searchbox', { name: 'output filter input' })).toBeVisible();
296+
await expect(page.getByRole('searchbox', { name: 'value filter input' })).toBeVisible();
296297
await page.getByLabel('Open the View Switcher Menu').click();
297298
await page.getByLabel('Conditions View').click();
298299
await expect(page.getByText('Current Output')).toBeVisible();
@@ -324,40 +325,23 @@ test.describe('Basic Condition Set Use', () => {
324325
const conditionCollection = page.locator('#conditionCollection');
325326
await sineWaveGeneratorTreeItem.dragTo(conditionCollection);
326327

327-
// Modify First Criterion
328-
const firstCriterionTelemetry = page.locator(
329-
'[aria-label="Criterion Telemetry Selection"] >> nth=0'
330-
);
331-
firstCriterionTelemetry.selectOption({ label: exampleTelemetry.name });
332-
const firstCriterionMetadata = page.locator(
333-
'[aria-label="Criterion Metadata Selection"] >> nth=0'
334-
);
335-
firstCriterionMetadata.selectOption({ label: 'Sine' });
336-
const firstCriterionComparison = page.locator(
337-
'[aria-label="Criterion Comparison Selection"] >> nth=0'
338-
);
339-
firstCriterionComparison.selectOption({ label: 'is greater than or equal to' });
340-
const firstCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=0');
341-
await firstCriterionInput.fill('0');
342-
343-
// Modify First Criterion
344-
const secondCriterionTelemetry = page.locator(
345-
'[aria-label="Criterion Telemetry Selection"] >> nth=1'
346-
);
347-
secondCriterionTelemetry.selectOption({ label: exampleTelemetry.name });
348-
349-
const secondCriterionMetadata = page.locator(
350-
'[aria-label="Criterion Metadata Selection"] >> nth=1'
351-
);
352-
secondCriterionMetadata.selectOption({ label: 'Sine' });
353-
354-
const secondCriterionComparison = page.locator(
355-
'[aria-label="Criterion Comparison Selection"] >> nth=1'
356-
);
357-
secondCriterionComparison.selectOption({ label: 'is less than' });
358-
359-
const secondCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=1');
360-
await secondCriterionInput.fill('0');
328+
// Modify First Criterion - use value selectors (labels show path e.g. "My Items/Name")
329+
await page.getByLabel('Criterion Telemetry Selection').first().selectOption({ value: 'all' });
330+
await page.getByLabel('Criterion Metadata Selection').first().selectOption({ value: 'sin' });
331+
await page
332+
.locator('select[aria-label="Criterion Comparison Selection"]')
333+
.first()
334+
.selectOption({ value: 'greaterThanOrEq' });
335+
await page.getByLabel('Criterion Input').first().fill('0');
336+
337+
// Modify Second Criterion
338+
await page.getByLabel('Criterion Telemetry Selection').nth(1).selectOption({ value: 'all' });
339+
await page.getByLabel('Criterion Metadata Selection').nth(1).selectOption({ value: 'sin' });
340+
await page
341+
.locator('select[aria-label="Criterion Comparison Selection"]')
342+
.nth(1)
343+
.selectOption({ value: 'lessThan' });
344+
await page.getByLabel('Criterion Input').nth(1).fill('0');
361345

362346
// Save ConditionSet
363347
await page.locator('button[title="Save"]').click();
@@ -408,51 +392,29 @@ test.describe('Basic Condition Set Use', () => {
408392
const conditionCollection = page.locator('#conditionCollection');
409393
await sineWaveGeneratorTreeItem.dragTo(conditionCollection);
410394

411-
// Modify First Criterion
412-
const firstCriterionTelemetry = page.locator(
413-
'[aria-label="Criterion Telemetry Selection"] >> nth=0'
414-
);
415-
firstCriterionTelemetry.selectOption({ label: exampleTelemetry.name });
416-
const firstCriterionMetadata = page.locator(
417-
'[aria-label="Criterion Metadata Selection"] >> nth=0'
418-
);
419-
firstCriterionMetadata.selectOption({ label: 'Sine' });
420-
const firstCriterionComparison = page.locator(
421-
'[aria-label="Criterion Comparison Selection"] >> nth=0'
422-
);
423-
firstCriterionComparison.selectOption({ label: 'is greater than or equal to' });
424-
const firstCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=0');
425-
await firstCriterionInput.fill('0');
395+
// Modify First Criterion - use value selectors (labels show path e.g. "My Items/Name")
396+
await page.getByLabel('Criterion Telemetry Selection').first().selectOption({ value: 'all' });
397+
await page.getByLabel('Criterion Metadata Selection').first().selectOption({ value: 'sin' });
398+
await page
399+
.locator('select[aria-label="Criterion Comparison Selection"]')
400+
.first()
401+
.selectOption({ value: 'greaterThanOrEq' });
402+
await page.getByLabel('Criterion Input').first().fill('0');
426403

427404
// Modify Second Criterion
428-
const secondCriterionTelemetry = page.locator(
429-
'[aria-label="Criterion Telemetry Selection"] >> nth=1'
430-
);
431-
await secondCriterionTelemetry.selectOption({ label: exampleTelemetry.name });
432-
433-
const secondCriterionMetadata = page.locator(
434-
'[aria-label="Criterion Metadata Selection"] >> nth=1'
435-
);
436-
await secondCriterionMetadata.selectOption({ label: 'Sine' });
437-
438-
const secondCriterionComparison = page.locator(
439-
'[aria-label="Criterion Comparison Selection"] >> nth=1'
440-
);
441-
await secondCriterionComparison.selectOption({ label: 'is less than' });
442-
443-
const secondCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=1');
444-
await secondCriterionInput.fill('0');
405+
await page.getByLabel('Criterion Telemetry Selection').nth(1).selectOption({ value: 'all' });
406+
await page.getByLabel('Criterion Metadata Selection').nth(1).selectOption({ value: 'sin' });
407+
await page
408+
.locator('select[aria-label="Criterion Comparison Selection"]')
409+
.nth(1)
410+
.selectOption({ value: 'lessThan' });
411+
await page.getByLabel('Criterion Input').nth(1).fill('0');
445412

446-
// Enable test data
413+
// Enable test data - use index (option 1 is first telemetry after "- Select Telemetry -")
447414
await page.getByLabel('Apply Test Data').nth(1).click();
448-
const testDataTelemetry = page.locator('[aria-label="Test Data Telemetry Selection"] >> nth=0');
449-
await testDataTelemetry.selectOption({ label: exampleTelemetry.name });
450-
451-
const testDataMetadata = page.locator('[aria-label="Test Data Metadata Selection"] >> nth=0');
452-
await testDataMetadata.selectOption({ label: 'Sine' });
453-
454-
const testInput = page.locator('[aria-label="Test Data Input"] >> nth=0');
455-
await testInput.fill('0');
415+
await page.getByLabel('Test Data Telemetry Selection').first().selectOption({ index: 1 });
416+
await page.getByLabel('Test Data Metadata Selection').first().selectOption({ value: 'sin' });
417+
await page.getByLabel('Test Data Input').first().fill('0');
456418

457419
// Validate that the condition set is evaluating and outputting
458420
// the correct value when the underlying telemetry subscription is active.
@@ -468,6 +430,34 @@ test.describe('Basic Condition Set Use', () => {
468430
description: 'https://github.com/nasa/openmct/issues/7484'
469431
});
470432
});
433+
434+
test('should toggle shouldFetchHistorical property in inspector', async ({ page }) => {
435+
await page.goto(conditionSet.url);
436+
await page.getByLabel('Edit Object').click();
437+
await page.getByRole('tab', { name: 'Config' }).click();
438+
let toggleSwitch = page.getByLabel('condition-historical-toggle');
439+
const initialState = await toggleSwitch.isChecked();
440+
expect(initialState).toBe(false);
441+
442+
await toggleSwitch.click();
443+
let toggledState = await toggleSwitch.isChecked();
444+
expect(toggledState).toBe(true);
445+
await page.click('button[title="Save"]');
446+
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
447+
let conditionSetObject = await getDomainObject(page, conditionSet.uuid);
448+
expect(conditionSetObject.configuration.shouldFetchHistorical).toBe(true);
449+
450+
await page.getByLabel('Edit Object').click();
451+
await page.getByRole('tab', { name: 'Config' }).click();
452+
toggleSwitch = page.getByLabel('condition-historical-toggle');
453+
await toggleSwitch.click();
454+
toggledState = await toggleSwitch.isChecked();
455+
expect(toggledState).toBe(false);
456+
await page.click('button[title="Save"]');
457+
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
458+
conditionSetObject = await getDomainObject(page, conditionSet.uuid);
459+
expect(conditionSetObject.configuration.shouldFetchHistorical).toBe(false);
460+
});
471461
});
472462

473463
test.describe('Condition Set Composition', () => {

0 commit comments

Comments
 (0)