Preserve local clock offsets on mode switch, fall back to defaults (#5217)

This commit is contained in:
Jesse Mazzella 2022-05-23 14:10:59 -07:00 committed by GitHub
parent f999b9e12b
commit 405418b9d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 162 additions and 29 deletions

View File

@ -430,9 +430,7 @@ test.describe('Example imagery thumbnails resize in display layouts', () => {
expect(thumbsWrapperLocator.isVisible()).toBeTruthy(); expect(thumbsWrapperLocator.isVisible()).toBeTruthy();
await expect(thumbsWrapperLocator).not.toHaveClass(/is-small-thumbs/); await expect(thumbsWrapperLocator).not.toHaveClass(/is-small-thumbs/);
}); });
}); });
test.describe('Example Imagery in Flexible layout', () => { test.describe('Example Imagery in Flexible layout', () => {

View File

@ -23,7 +23,7 @@
const { test } = require('../../../fixtures.js'); const { test } = require('../../../fixtures.js');
const { expect } = require('@playwright/test'); const { expect } = require('@playwright/test');
test.describe('Time counductor operations', () => { test.describe('Time conductor operations', () => {
test('validate start time does not exceeds end time', async ({ page }) => { test('validate start time does not exceeds end time', async ({ page }) => {
// Go to baseURL // Go to baseURL
await page.goto('/', { waitUntil: 'networkidle' }); await page.goto('/', { waitUntil: 'networkidle' });
@ -73,37 +73,163 @@ test.describe('Time counductor operations', () => {
// Try to change the realtime offsets when in realtime (local clock) mode. // Try to change the realtime offsets when in realtime (local clock) mode.
test.describe('Time conductor input fields real-time mode', () => { test.describe('Time conductor input fields real-time mode', () => {
test('validate input fields in real-time mode', async ({ page }) => { test('validate input fields in real-time mode', async ({ page }) => {
const startOffset = {
secs: '23'
};
const endOffset = {
secs: '31'
};
// Go to baseURL // Go to baseURL
await page.goto('/', { waitUntil: 'networkidle' }); await page.goto('/', { waitUntil: 'networkidle' });
// Click fixed timespan button // Switch to real-time mode
await page.locator('.c-button__label >> text=Fixed Timespan').click(); await setRealTimeMode(page);
// Click local clock // Set start time offset
await page.locator('.icon-clock >> text=Local Clock').click(); await setStartOffset(page, startOffset);
// Click time offset button // Verify time was updated on time offset button
await page.locator('.c-conductor__delta-button >> text=00:30:00').click(); await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText('00:30:23');
// Input start time offset // Set end time offset
await page.fill('.pr-time-controls__secs', '23'); await setEndOffset(page, endOffset);
// Verify time was updated on preceding time offset button
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:31');
});
/**
* Verify that offsets and url params are preserved when switching
* between fixed timespan and real-time mode.
*/
test('preserve offsets and url params when switching between fixed and real-time mode', async ({ page }) => {
const startOffset = {
mins: '30',
secs: '23'
};
const endOffset = {
secs: '01'
};
// Convert offsets to milliseconds
const startDelta = (30 * 60 * 1000) + (23 * 1000);
const endDelta = (1 * 1000);
// Go to baseURL
await page.goto('/', { waitUntil: 'networkidle' });
// Switch to real-time mode
await setRealTimeMode(page);
// Set start time offset
await setStartOffset(page, startOffset);
// Set end time offset
await setEndOffset(page, endOffset);
// Switch to fixed timespan mode
await setFixedTimeMode(page);
// Switch back to real-time mode
await setRealTimeMode(page);
// Verify updated start time offset persists after mode switch
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText('00:30:23');
// Verify updated end time offset persists after mode switch
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:01');
// Verify url parameters persist after mode switch
await page.waitForNavigation();
expect(page.url()).toContain(`startDelta=${startDelta}`);
expect(page.url()).toContain(`endDelta=${endDelta}`);
});
});
/**
* @typedef {Object} OffsetValues
* @property {string | undefined} hours
* @property {string | undefined} mins
* @property {string | undefined} secs
*/
/**
* Set the values (hours, mins, secs) for the start time offset when in realtime mode
* @param {import('@playwright/test').Page} page
* @param {OffsetValues} offset
*/
async function setStartOffset(page, offset) {
const startOffsetButton = page.locator('data-testid=conductor-start-offset-button');
await setTimeConductorOffset(page, offset, startOffsetButton);
}
/**
* Set the values (hours, mins, secs) for the end time offset when in realtime mode
* @param {import('@playwright/test').Page} page
* @param {OffsetValues} offset
*/
async function setEndOffset(page, offset) {
const endOffsetButton = page.locator('data-testid=conductor-end-offset-button');
await setTimeConductorOffset(page, offset, endOffsetButton);
}
/**
* Set the time conductor to fixed timespan mode
* @param {import('@playwright/test').Page} page
*/
async function setFixedTimeMode(page) {
await setTimeConductorMode(page, true);
}
/**
* Set the time conductor to realtime mode
* @param {import('@playwright/test').Page} page
*/
async function setRealTimeMode(page) {
await setTimeConductorMode(page, false);
}
/**
* Set the values (hours, mins, secs) for the TimeConductor offsets when in realtime mode
* @param {import('@playwright/test').Page} page
* @param {OffsetValues} offset
* @param {import('@playwright/test').Locator} offsetButton
*/
async function setTimeConductorOffset(page, {hours, mins, secs}, offsetButton) {
await offsetButton.click();
if (hours) {
await page.fill('.pr-time-controls__hrs', hours);
}
if (mins) {
await page.fill('.pr-time-controls__mins', mins);
}
if (secs) {
await page.fill('.pr-time-controls__secs', secs);
}
// Click the check button // Click the check button
await page.locator('.icon-check').click(); await page.locator('.icon-check').click();
}
// Verify time was updated on time offset button /**
await expect(page.locator('.c-conductor__delta-button').first()).toContainText('00:30:23'); * Set the time conductor mode to either fixed timespan or realtime mode.
* @param {import('@playwright/test').Page} page
* @param {boolean} [isFixedTimespan=true] true for fixed timespan mode, false for realtime mode; default is true
*/
async function setTimeConductorMode(page, isFixedTimespan = true) {
// Click 'mode' button
await page.locator('.c-mode-button').click();
// Click time offset set preceding now button // Switch time conductor mode
await page.locator('.c-conductor__delta-button >> text=00:00:30').click(); if (isFixedTimespan) {
await page.locator('data-testid=conductor-modeOption-fixed').click();
// Input preceding time offset } else {
await page.fill('.pr-time-controls__secs', '31'); await page.locator('data-testid=conductor-modeOption-realtime').click();
}
// Click the check buttons }
await page.locator('.icon-check').click();
// Verify time was updated on preceding time offset button
await expect(page.locator('.c-conductor__delta-button').nth(1)).toContainText('00:00:31');
});
});

View File

@ -12,6 +12,7 @@
:key="action.name" :key="action.name"
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']" :class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
:title="action.description" :title="action.description"
:data-testid="action.testId || false"
@click="action.onItemClicked" @click="action.onItemClicked"
> >
{{ action.name }} {{ action.name }}
@ -37,6 +38,7 @@
:key="action.name" :key="action.name"
:class="action.cssClass" :class="action.cssClass"
:title="action.description" :title="action.description"
:data-testid="action.testId || false"
@click="action.onItemClicked" @click="action.onItemClicked"
> >
{{ action.name }} {{ action.name }}

View File

@ -15,6 +15,7 @@
:key="action.name" :key="action.name"
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']" :class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
:title="action.description" :title="action.description"
:data-testid="action.testId || false"
@click="action.onItemClicked" @click="action.onItemClicked"
@mouseover="toggleItemDescription(action)" @mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()" @mouseleave="toggleItemDescription()"
@ -45,6 +46,7 @@
:key="action.name" :key="action.name"
:class="action.cssClass" :class="action.cssClass"
:title="action.description" :title="action.description"
:data-testid="action.testId || false"
@click="action.onItemClicked" @click="action.onItemClicked"
@mouseover="toggleItemDescription(action)" @mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()" @mouseleave="toggleItemDescription()"

View File

@ -22,6 +22,7 @@
ref="startOffset" ref="startOffset"
class="c-button c-conductor__delta-button" class="c-button c-conductor__delta-button"
title="Set the time offset after now" title="Set the time offset after now"
data-testid="conductor-start-offset-button"
@click.prevent.stop="showTimePopupStart" @click.prevent.stop="showTimePopupStart"
> >
{{ offsets.start }} {{ offsets.start }}
@ -61,6 +62,7 @@
ref="endOffset" ref="endOffset"
class="c-button c-conductor__delta-button" class="c-button c-conductor__delta-button"
title="Set the time offset preceding now" title="Set the time offset preceding now"
data-testid="conductor-end-offset-button"
@click.prevent.stop="showTimePopupEnd" @click.prevent.stop="showTimePopupEnd"
> >
{{ offsets.end }} {{ offsets.end }}

View File

@ -105,6 +105,7 @@ export default {
name: 'Fixed Timespan', name: 'Fixed Timespan',
description: 'Query and explore data that falls between two fixed datetimes.', description: 'Query and explore data that falls between two fixed datetimes.',
cssClass: 'icon-tabular', cssClass: 'icon-tabular',
testId: 'conductor-modeOption-fixed',
onItemClicked: () => this.setOption(key) onItemClicked: () => this.setOption(key)
}; };
} else { } else {
@ -116,6 +117,7 @@ export default {
description: "Monitor streaming data in real-time. The Time " description: "Monitor streaming data in real-time. The Time "
+ "Conductor and displays will automatically advance themselves based on this clock. " + clock.description, + "Conductor and displays will automatically advance themselves based on this clock. " + clock.description,
cssClass: clock.cssClass || 'icon-clock', cssClass: clock.cssClass || 'icon-clock',
testId: 'conductor-modeOption-realtime',
onItemClicked: () => this.setOption(key) onItemClicked: () => this.setOption(key)
}; };
} }
@ -148,7 +150,8 @@ export default {
if (clockKey === undefined) { if (clockKey === undefined) {
this.openmct.time.stopClock(); this.openmct.time.stopClock();
} else { } else {
this.openmct.time.clock(clockKey, configuration.clockOffsets); const offsets = this.openmct.time.clockOffsets() || configuration.clockOffsets;
this.openmct.time.clock(clockKey, offsets);
} }
}, },