From 57743e59183937d9dc358b8969745655805cb239 Mon Sep 17 00:00:00 2001 From: Jesse Mazzella Date: Mon, 14 Aug 2023 12:04:01 -0700 Subject: [PATCH] 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 Co-authored-by: John Hill --- .../conditionSet/conditionSet.e2e.spec.js | 146 +++++++++--------- .../plugins/plot/tagging.e2e.spec.js | 8 +- example/generator/WorkerInterface.js | 4 +- src/plugins/condition/ConditionManager.js | 2 +- 4 files changed, 83 insertions(+), 77 deletions(-) diff --git a/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js b/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js index 1bfe2e9ac4..1452d3164c 100644 --- a/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js +++ b/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js @@ -27,7 +27,10 @@ demonstrate some playwright for test developers. This pattern should not be re-u */ const { test, expect } = require('../../../../pluginFixtures.js'); -const { createDomainObjectWithDefaults } = require('../../../../appActions'); +const { + createDomainObjectWithDefaults, + createExampleTelemetryObject +} = require('../../../../appActions'); let conditionSetUrl; let getConditionSetIdentifierFromUrl; @@ -205,23 +208,31 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => { }); test.describe('Basic Condition Set Use', () => { + let conditionSet; + test.beforeEach(async ({ page }) => { // Open a browser, navigate to the main page, and wait until all network events to resolve await page.goto('./', { waitUntil: 'domcontentloaded' }); - }); - test('Can add a condition', async ({ page }) => { // Create a new condition set - await createDomainObjectWithDefaults(page, { + conditionSet = await createDomainObjectWithDefaults(page, { type: '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 await page.locator('[title="Edit"]').click(); // Click Add Condition button await page.locator('#addCondition').click(); // 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); }); test('ConditionSet should display appropriate view options', async ({ page }) => { @@ -238,16 +249,13 @@ test.describe('Basic Condition Set Use', () => { type: 'Sine Wave Generator', name: 'Beta Sine Wave Generator' }); - const conditionSet1 = await createDomainObjectWithDefaults(page, { - type: 'Condition Set', - name: 'Test Condition Set' - }); + + await page.goto(conditionSet.url); // Change the object to edit mode await page.locator('[title="Edit"]').click(); // Expand the 'My Items' folder in the left tree - await page.goto(conditionSet1.url); page.click('button[title="Show selected item in tree"]'); // Add the Alpha & Beta Sine Wave Generator to the Condition Set and save changes const treePane = page.getByRole('tree', { @@ -264,9 +272,9 @@ test.describe('Basic Condition Set Use', () => { await alphaGeneratorTreeItem.dragTo(conditionCollection); await betaGeneratorTreeItem.dragTo(conditionCollection); - const saveButtonLocator = page.locator('button[title="Save"]'); - await saveButtonLocator.click(); + await page.locator('button[title="Save"]').click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); + await page.click('button[title="Change the current view"]'); 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: /Telemetry Table/ })).toBeVisible(); }); - test('ConditionSet should output blank instead of the default value', async ({ page }) => { - //Navigate to baseURL - await page.goto('./', { waitUntil: 'domcontentloaded' }); + test('ConditionSet has correct outputs when telemetry is and is not available', async ({ + page + }) => { + const exampleTelemetry = await createExampleTelemetryObject(page); - //Click the Create button - await page.click('button:has-text("Create")'); - - // 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' - }); + await page.getByTitle('Show selected item in tree').click(); + await page.goto(conditionSet.url); // Change the object to edit mode 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('#conditionCollection').getByRole('textbox').nth(0).fill('First Condition'); await page.locator('#conditionCollection').getByRole('textbox').nth(1).fill('Second Condition'); - // Expand the 'My Items' folder in the left tree - await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click(); - // Add the Sine Wave Generator to the Condition Set and save changes - const treePane = page.getByRole('tree', { - name: 'Main Tree' - }); - const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', { - name: 'Delayed Sine Wave Generator' - }); - const conditionCollection = await page.locator('#conditionCollection'); - + // Add Telemetry to ConditionSet + const sineWaveGeneratorTreeItem = page + .getByRole('tree', { + name: 'Main Tree' + }) + .getByRole('treeitem', { + name: exampleTelemetry.name + }); + const conditionCollection = page.locator('#conditionCollection'); await sineWaveGeneratorTreeItem.dragTo(conditionCollection); - const firstCriterionTelemetry = await page.locator( + // Modify First Criterion + const firstCriterionTelemetry = page.locator( '[aria-label="Criterion Telemetry Selection"] >> nth=0' ); - firstCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' }); - - const secondCriterionTelemetry = await page.locator( - '[aria-label="Criterion Telemetry Selection"] >> nth=1' - ); - secondCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' }); - - const firstCriterionMetadata = await page.locator( + firstCriterionTelemetry.selectOption({ label: exampleTelemetry.name }); + const firstCriterionMetadata = page.locator( '[aria-label="Criterion Metadata Selection"] >> nth=0' ); 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' ); secondCriterionMetadata.selectOption({ label: 'Sine' }); - const firstCriterionComparison = await page.locator( - '[aria-label="Criterion Comparison Selection"] >> nth=0' - ); - firstCriterionComparison.selectOption({ label: 'is greater than or equal to' }); - - const secondCriterionComparison = await page.locator( + const secondCriterionComparison = page.locator( '[aria-label="Criterion Comparison Selection"] >> nth=1' ); secondCriterionComparison.selectOption({ label: 'is less than' }); - const firstCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=0'); - await firstCriterionInput.fill('0'); - - const secondCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=1'); + const secondCriterionInput = page.locator('[aria-label="Criterion Input"] >> nth=1'); await secondCriterionInput.fill('0'); - const saveButtonLocator = page.locator('button[title="Save"]'); - await saveButtonLocator.click(); + // Save ConditionSet + await page.locator('button[title="Save"]').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('---'); }); }); diff --git a/e2e/tests/functional/plugins/plot/tagging.e2e.spec.js b/e2e/tests/functional/plugins/plot/tagging.e2e.spec.js index c1c00b169b..d8bcd3c1fe 100644 --- a/e2e/tests/functional/plugins/plot/tagging.e2e.spec.js +++ b/e2e/tests/functional/plugins/plot/tagging.e2e.spec.js @@ -29,7 +29,8 @@ const { createDomainObjectWithDefaults, setRealTimeMode, setFixedTimeMode, - waitForPlotsToRender + waitForPlotsToRender, + selectInspectorTab } = require('../../../../appActions'); test.describe('Plot Tagging', () => { @@ -146,7 +147,10 @@ test.describe('Plot Tagging', () => { // wait for plots to load 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(); const canvas = page.locator('canvas').nth(1); diff --git a/example/generator/WorkerInterface.js b/example/generator/WorkerInterface.js index 996add4f7f..d02546d34a 100644 --- a/example/generator/WorkerInterface.js +++ b/example/generator/WorkerInterface.js @@ -88,10 +88,10 @@ define(['uuid'], function ({ v4: uuid }) { }; WorkerInterface.prototype.subscribe = function (request, cb) { - const id = request.id; + const { id, loadDelay } = request; const messageId = this.dispatch('subscribe', request, (message) => { if (!this.staleTelemetryIds[id]) { - cb(message.data); + setTimeout(() => cb(message.data), Math.max(loadDelay, 0)); } }); diff --git a/src/plugins/condition/ConditionManager.js b/src/plugins/condition/ConditionManager.js index 99379f2938..b72b90702e 100644 --- a/src/plugins/condition/ConditionManager.js +++ b/src/plugins/condition/ConditionManager.js @@ -399,7 +399,7 @@ export default class ConditionManager extends EventEmitter { } shouldEvaluateNewTelemetry(currentTimestamp) { - return this.openmct.time.bounds().end >= currentTimestamp; + return this.openmct.time.getBounds().end >= currentTimestamp; } telemetryReceived(endpoint, datum) {