mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
fix: use loadDelay
generator setting in subscriptions as well (#6918)
* refactor: use `getBounds()` instead of `bounds()` * fix: use `loadDelay` in generator subscription * refactor: fix up e2e test * fix: remove `.only()` * refactor: lint * Start to fix up conditionSet test with comments * test: edit conditionSet to add delay value * test: tests the case where telemetry is available * fix: remove `.only()` * test: add comments, clarify assertion * refactor: lint:fix * test: fix conditionSet default condition name test * test: add assertions to stabilize tags tests --------- Co-authored-by: Scott Bell <scott@traclabs.com> Co-authored-by: John Hill <john.c.hill@nasa.gov>
This commit is contained in:
parent
f3b819a786
commit
57743e5918
@ -27,7 +27,10 @@ demonstrate some playwright for test developers. This pattern should not be re-u
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures.js');
|
const { test, expect } = require('../../../../pluginFixtures.js');
|
||||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
const {
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
createExampleTelemetryObject
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
let conditionSetUrl;
|
let conditionSetUrl;
|
||||||
let getConditionSetIdentifierFromUrl;
|
let getConditionSetIdentifierFromUrl;
|
||||||
@ -205,23 +208,31 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Basic Condition Set Use', () => {
|
test.describe('Basic Condition Set Use', () => {
|
||||||
|
let conditionSet;
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// Open a browser, navigate to the main page, and wait until all network events to resolve
|
// Open a browser, navigate to the main page, and wait until all network events to resolve
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
});
|
|
||||||
test('Can add a condition', async ({ page }) => {
|
|
||||||
// Create a new condition set
|
// Create a new condition set
|
||||||
await createDomainObjectWithDefaults(page, {
|
conditionSet = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Condition Set',
|
type: 'Condition Set',
|
||||||
name: 'Test Condition Set'
|
name: 'Test Condition Set'
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
test('Creating a condition defaults the condition name to "Unnamed Condition"', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
|
await page.goto(conditionSet.url);
|
||||||
|
|
||||||
// Change the object to edit mode
|
// Change the object to edit mode
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
|
|
||||||
// Click Add Condition button
|
// Click Add Condition button
|
||||||
await page.locator('#addCondition').click();
|
await page.locator('#addCondition').click();
|
||||||
// Check that the new Unnamed Condition section appears
|
// Check that the new Unnamed Condition section appears
|
||||||
const numOfUnnamedConditions = await page.locator('text=Unnamed Condition').count();
|
const numOfUnnamedConditions = await page
|
||||||
|
.locator('.c-condition__name', { hasText: 'Unnamed Condition' })
|
||||||
|
.count();
|
||||||
expect(numOfUnnamedConditions).toEqual(1);
|
expect(numOfUnnamedConditions).toEqual(1);
|
||||||
});
|
});
|
||||||
test('ConditionSet should display appropriate view options', async ({ page }) => {
|
test('ConditionSet should display appropriate view options', async ({ page }) => {
|
||||||
@ -238,16 +249,13 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
name: 'Beta Sine Wave Generator'
|
name: 'Beta Sine Wave Generator'
|
||||||
});
|
});
|
||||||
const conditionSet1 = await createDomainObjectWithDefaults(page, {
|
|
||||||
type: 'Condition Set',
|
await page.goto(conditionSet.url);
|
||||||
name: 'Test Condition Set'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Change the object to edit mode
|
// Change the object to edit mode
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
|
|
||||||
// Expand the 'My Items' folder in the left tree
|
// Expand the 'My Items' folder in the left tree
|
||||||
await page.goto(conditionSet1.url);
|
|
||||||
page.click('button[title="Show selected item in tree"]');
|
page.click('button[title="Show selected item in tree"]');
|
||||||
// Add the Alpha & Beta Sine Wave Generator to the Condition Set and save changes
|
// Add the Alpha & Beta Sine Wave Generator to the Condition Set and save changes
|
||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
@ -264,9 +272,9 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
await alphaGeneratorTreeItem.dragTo(conditionCollection);
|
await alphaGeneratorTreeItem.dragTo(conditionCollection);
|
||||||
await betaGeneratorTreeItem.dragTo(conditionCollection);
|
await betaGeneratorTreeItem.dragTo(conditionCollection);
|
||||||
|
|
||||||
const saveButtonLocator = page.locator('button[title="Save"]');
|
await page.locator('button[title="Save"]').click();
|
||||||
await saveButtonLocator.click();
|
|
||||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||||
|
|
||||||
await page.click('button[title="Change the current view"]');
|
await page.click('button[title="Change the current view"]');
|
||||||
|
|
||||||
await expect(page.getByRole('menuitem', { name: /Lad Table/ })).toBeHidden();
|
await expect(page.getByRole('menuitem', { name: /Lad Table/ })).toBeHidden();
|
||||||
@ -274,95 +282,89 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
await expect(page.getByRole('menuitem', { name: /Plot/ })).toBeVisible();
|
await expect(page.getByRole('menuitem', { name: /Plot/ })).toBeVisible();
|
||||||
await expect(page.getByRole('menuitem', { name: /Telemetry Table/ })).toBeVisible();
|
await expect(page.getByRole('menuitem', { name: /Telemetry Table/ })).toBeVisible();
|
||||||
});
|
});
|
||||||
test('ConditionSet should output blank instead of the default value', async ({ page }) => {
|
test('ConditionSet has correct outputs when telemetry is and is not available', async ({
|
||||||
//Navigate to baseURL
|
page
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
}) => {
|
||||||
|
const exampleTelemetry = await createExampleTelemetryObject(page);
|
||||||
|
|
||||||
//Click the Create button
|
await page.getByTitle('Show selected item in tree').click();
|
||||||
await page.click('button:has-text("Create")');
|
await page.goto(conditionSet.url);
|
||||||
|
|
||||||
// Click the object specified by 'type'
|
|
||||||
await page.click(`li[role='menuitem']:text("Sine Wave Generator")`);
|
|
||||||
await page.getByRole('spinbutton', { name: 'Loading Delay (ms)' }).fill('8000');
|
|
||||||
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
|
||||||
await nameInput.fill('Delayed Sine Wave Generator');
|
|
||||||
|
|
||||||
// Click OK button and wait for Navigate event
|
|
||||||
await Promise.all([
|
|
||||||
page.waitForLoadState(),
|
|
||||||
page.click('[aria-label="Save"]'),
|
|
||||||
// Wait for Save Banner to appear
|
|
||||||
page.waitForSelector('.c-message-banner__message')
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Create a new condition set
|
|
||||||
await createDomainObjectWithDefaults(page, {
|
|
||||||
type: 'Condition Set',
|
|
||||||
name: 'Test Blank Output of Condition Set'
|
|
||||||
});
|
|
||||||
// Change the object to edit mode
|
// Change the object to edit mode
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
|
|
||||||
// Click Add Condition button twice
|
// Create two conditions
|
||||||
await page.locator('#addCondition').click();
|
await page.locator('#addCondition').click();
|
||||||
await page.locator('#addCondition').click();
|
await page.locator('#addCondition').click();
|
||||||
await page.locator('#conditionCollection').getByRole('textbox').nth(0).fill('First Condition');
|
await page.locator('#conditionCollection').getByRole('textbox').nth(0).fill('First Condition');
|
||||||
await page.locator('#conditionCollection').getByRole('textbox').nth(1).fill('Second Condition');
|
await page.locator('#conditionCollection').getByRole('textbox').nth(1).fill('Second Condition');
|
||||||
|
|
||||||
// Expand the 'My Items' folder in the left tree
|
// Add Telemetry to ConditionSet
|
||||||
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
|
const sineWaveGeneratorTreeItem = page
|
||||||
// Add the Sine Wave Generator to the Condition Set and save changes
|
.getByRole('tree', {
|
||||||
const treePane = page.getByRole('tree', {
|
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
|
})
|
||||||
|
.getByRole('treeitem', {
|
||||||
|
name: exampleTelemetry.name
|
||||||
});
|
});
|
||||||
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
|
const conditionCollection = page.locator('#conditionCollection');
|
||||||
name: 'Delayed Sine Wave Generator'
|
|
||||||
});
|
|
||||||
const conditionCollection = await page.locator('#conditionCollection');
|
|
||||||
|
|
||||||
await sineWaveGeneratorTreeItem.dragTo(conditionCollection);
|
await sineWaveGeneratorTreeItem.dragTo(conditionCollection);
|
||||||
|
|
||||||
const firstCriterionTelemetry = await page.locator(
|
// Modify First Criterion
|
||||||
|
const firstCriterionTelemetry = page.locator(
|
||||||
'[aria-label="Criterion Telemetry Selection"] >> nth=0'
|
'[aria-label="Criterion Telemetry Selection"] >> nth=0'
|
||||||
);
|
);
|
||||||
firstCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' });
|
firstCriterionTelemetry.selectOption({ label: exampleTelemetry.name });
|
||||||
|
const firstCriterionMetadata = page.locator(
|
||||||
const secondCriterionTelemetry = await page.locator(
|
|
||||||
'[aria-label="Criterion Telemetry Selection"] >> nth=1'
|
|
||||||
);
|
|
||||||
secondCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' });
|
|
||||||
|
|
||||||
const firstCriterionMetadata = await page.locator(
|
|
||||||
'[aria-label="Criterion Metadata Selection"] >> nth=0'
|
'[aria-label="Criterion Metadata Selection"] >> nth=0'
|
||||||
);
|
);
|
||||||
firstCriterionMetadata.selectOption({ label: 'Sine' });
|
firstCriterionMetadata.selectOption({ label: 'Sine' });
|
||||||
|
const firstCriterionComparison = page.locator(
|
||||||
|
'[aria-label="Criterion Comparison Selection"] >> nth=0'
|
||||||
|
);
|
||||||
|
firstCriterionComparison.selectOption({ label: 'is greater than or equal to' });
|
||||||
|
const firstCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=0');
|
||||||
|
await firstCriterionInput.fill('0');
|
||||||
|
|
||||||
const secondCriterionMetadata = await page.locator(
|
// Modify First Criterion
|
||||||
|
const secondCriterionTelemetry = page.locator(
|
||||||
|
'[aria-label="Criterion Telemetry Selection"] >> nth=1'
|
||||||
|
);
|
||||||
|
secondCriterionTelemetry.selectOption({ label: exampleTelemetry.name });
|
||||||
|
|
||||||
|
const secondCriterionMetadata = page.locator(
|
||||||
'[aria-label="Criterion Metadata Selection"] >> nth=1'
|
'[aria-label="Criterion Metadata Selection"] >> nth=1'
|
||||||
);
|
);
|
||||||
secondCriterionMetadata.selectOption({ label: 'Sine' });
|
secondCriterionMetadata.selectOption({ label: 'Sine' });
|
||||||
|
|
||||||
const firstCriterionComparison = await page.locator(
|
const secondCriterionComparison = page.locator(
|
||||||
'[aria-label="Criterion Comparison Selection"] >> nth=0'
|
|
||||||
);
|
|
||||||
firstCriterionComparison.selectOption({ label: 'is greater than or equal to' });
|
|
||||||
|
|
||||||
const secondCriterionComparison = await page.locator(
|
|
||||||
'[aria-label="Criterion Comparison Selection"] >> nth=1'
|
'[aria-label="Criterion Comparison Selection"] >> nth=1'
|
||||||
);
|
);
|
||||||
secondCriterionComparison.selectOption({ label: 'is less than' });
|
secondCriterionComparison.selectOption({ label: 'is less than' });
|
||||||
|
|
||||||
const firstCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=0');
|
const secondCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=1');
|
||||||
await firstCriterionInput.fill('0');
|
|
||||||
|
|
||||||
const secondCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=1');
|
|
||||||
await secondCriterionInput.fill('0');
|
await secondCriterionInput.fill('0');
|
||||||
|
|
||||||
const saveButtonLocator = page.locator('button[title="Save"]');
|
// Save ConditionSet
|
||||||
await saveButtonLocator.click();
|
await page.locator('button[title="Save"]').click();
|
||||||
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||||
|
|
||||||
const outputValue = await page.locator('[aria-label="Current Output Value"]');
|
// Validate that the condition set is evaluating and outputting
|
||||||
|
// the correct value when the underlying telemetry subscription is active.
|
||||||
|
let outputValue = page.locator('[aria-label="Current Output Value"]');
|
||||||
|
await expect(outputValue).toHaveText('false');
|
||||||
|
|
||||||
|
await page.goto(exampleTelemetry.url);
|
||||||
|
|
||||||
|
// 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.getByRole('menuitem', { name: 'Edit Properties...' }).click();
|
||||||
|
await page.getByRole('spinbutton', { name: 'Loading Delay (ms)' }).fill('8000');
|
||||||
|
await page.getByLabel('Save').click();
|
||||||
|
|
||||||
|
// Expect that the output value is blank or '---' if the
|
||||||
|
// underlying telemetry subscription is not active.
|
||||||
|
await page.goto(conditionSet.url);
|
||||||
await expect(outputValue).toHaveText('---');
|
await expect(outputValue).toHaveText('---');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -29,7 +29,8 @@ const {
|
|||||||
createDomainObjectWithDefaults,
|
createDomainObjectWithDefaults,
|
||||||
setRealTimeMode,
|
setRealTimeMode,
|
||||||
setFixedTimeMode,
|
setFixedTimeMode,
|
||||||
waitForPlotsToRender
|
waitForPlotsToRender,
|
||||||
|
selectInspectorTab
|
||||||
} = require('../../../../appActions');
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Plot Tagging', () => {
|
test.describe('Plot Tagging', () => {
|
||||||
@ -146,7 +147,10 @@ test.describe('Plot Tagging', () => {
|
|||||||
// wait for plots to load
|
// wait for plots to load
|
||||||
await waitForPlotsToRender(page);
|
await waitForPlotsToRender(page);
|
||||||
|
|
||||||
await page.getByText('Annotations').click();
|
await expect(page.getByRole('tab', { name: 'Annotations' })).not.toHaveClass(/is-current/);
|
||||||
|
await selectInspectorTab(page, 'Annotations');
|
||||||
|
await expect(page.getByRole('tab', { name: 'Annotations' })).toHaveClass(/is-current/);
|
||||||
|
|
||||||
await expect(page.getByText('No tags to display for this item')).toBeVisible();
|
await expect(page.getByText('No tags to display for this item')).toBeVisible();
|
||||||
|
|
||||||
const canvas = page.locator('canvas').nth(1);
|
const canvas = page.locator('canvas').nth(1);
|
||||||
|
@ -88,10 +88,10 @@ define(['uuid'], function ({ v4: uuid }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
WorkerInterface.prototype.subscribe = function (request, cb) {
|
WorkerInterface.prototype.subscribe = function (request, cb) {
|
||||||
const id = request.id;
|
const { id, loadDelay } = request;
|
||||||
const messageId = this.dispatch('subscribe', request, (message) => {
|
const messageId = this.dispatch('subscribe', request, (message) => {
|
||||||
if (!this.staleTelemetryIds[id]) {
|
if (!this.staleTelemetryIds[id]) {
|
||||||
cb(message.data);
|
setTimeout(() => cb(message.data), Math.max(loadDelay, 0));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shouldEvaluateNewTelemetry(currentTimestamp) {
|
shouldEvaluateNewTelemetry(currentTimestamp) {
|
||||||
return this.openmct.time.bounds().end >= currentTimestamp;
|
return this.openmct.time.getBounds().end >= currentTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
telemetryReceived(endpoint, datum) {
|
telemetryReceived(endpoint, datum) {
|
||||||
|
Loading…
Reference in New Issue
Block a user