Skip to content

Commit

Permalink
fix(#7791): tc form shouldn't submit bounds changes on dismiss (#7792)
Browse files Browse the repository at this point in the history
* fix(#7791): tc form shouldn't submit bounds changes on dismiss

* test(e2e): add tests for validating time conductor popup

- update appAction for setting time conductor in fixed mode
- add a11y to time conductor in fixed mode
- update tests using `setTimeConductorBounds`

* fix(#7791): actually fix the problem. Also, add a test.

* test: add annotation to regression test

* docs: comments

* test: fix the reset image button flake ONCE AND FOR ALL

- wait for the rightmost image thumbnail to be in the viewport :D

* test: add tests for `setTimeConductorMode` and `setTimeConductorBounds`
  • Loading branch information
ozyx authored Jul 25, 2024
1 parent 689f7cc commit e3fcbe1
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 179 deletions.
73 changes: 51 additions & 22 deletions e2e/appActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,61 +436,67 @@ async function setRealTimeMode(page) {
/**
* 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
* @param {OffsetValues} offset - Object containing offset values
* @param {boolean} [offset.submitChanges=true] - If true, submit the offset changes; otherwise, discard them
*/
async function setTimeConductorOffset(
page,
{ startHours, startMins, startSecs, endHours, endMins, endSecs }
{ startHours, startMins, startSecs, endHours, endMins, endSecs, submitChanges = true }
) {
if (startHours) {
await page.getByRole('spinbutton', { name: 'Start offset hours' }).fill(startHours);
await page.getByLabel('Start offset hours').fill(startHours);
}

if (startMins) {
await page.getByRole('spinbutton', { name: 'Start offset minutes' }).fill(startMins);
await page.getByLabel('Start offset minutes').fill(startMins);
}

if (startSecs) {
await page.getByRole('spinbutton', { name: 'Start offset seconds' }).fill(startSecs);
await page.getByLabel('Start offset seconds').fill(startSecs);
}

if (endHours) {
await page.getByRole('spinbutton', { name: 'End offset hours' }).fill(endHours);
await page.getByLabel('End offset hours').fill(endHours);
}

if (endMins) {
await page.getByRole('spinbutton', { name: 'End offset minutes' }).fill(endMins);
await page.getByLabel('End offset minutes').fill(endMins);
}

if (endSecs) {
await page.getByRole('spinbutton', { name: 'End offset seconds' }).fill(endSecs);
await page.getByLabel('End offset seconds').fill(endSecs);
}

// Click the check button
await page.locator('.pr-time-input--buttons .icon-check').click();
if (submitChanges) {
await page.getByLabel('Submit time offsets').click();
} else {
await page.getByLabel('Discard changes and close time popup').click();
}
}

/**
* Set the values (hours, mins, secs) for the start time offset when in realtime mode
* @param {import('@playwright/test').Page} page
* @param {OffsetValues} offset
* @param {boolean} [submit=true] If true, submit the offset changes; otherwise, discard them
*/
async function setStartOffset(page, offset) {
async function setStartOffset(page, { submitChanges = true, ...offset }) {
// Click 'mode' button
await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click();
await setTimeConductorOffset(page, offset);
await setTimeConductorOffset(page, { submitChanges, ...offset });
}

/**
* Set the values (hours, mins, secs) for the end time offset when in realtime mode
* @param {import('@playwright/test').Page} page
* @param {OffsetValues} offset
* @param {boolean} [submit=true] If true, submit the offset changes; otherwise, discard them
*/
async function setEndOffset(page, offset) {
async function setEndOffset(page, { submitChanges = true, ...offset }) {
// Click 'mode' button
await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click();
await setTimeConductorOffset(page, offset);
await setTimeConductorOffset(page, { submitChanges, ...offset });
}

/**
Expand All @@ -499,17 +505,40 @@ async function setEndOffset(page, offset) {
* NOTE: Unless explicitly testing the Time Conductor itself, it is advised to instead
* navigate directly to the object with the desired time bounds using `navigateToObjectWithFixedTimeBounds()`.
* @param {import('@playwright/test').Page} page
* @param {string} startDate
* @param {string} endDate
* @param {Object} bounds - The time conductor bounds
* @param {string} [bounds.startDate] - The start date in YYYY-MM-DD format
* @param {string} [bounds.startTime] - The start time in HH:mm:ss format
* @param {string} [bounds.endDate] - The end date in YYYY-MM-DD format
* @param {string} [bounds.endTime] - The end time in HH:mm:ss format
* @param {boolean} [bounds.submitChanges=true] - If true, submit the changes; otherwise, discard them.
*/
async function setTimeConductorBounds(page, startDate, endDate) {
// Bring up the time conductor popup
expect(await page.locator('.l-shell__time-conductor.c-compact-tc').count()).toBe(1);
await page.click('.l-shell__time-conductor.c-compact-tc');
async function setTimeConductorBounds(page, { submitChanges = true, ...bounds }) {
const { startDate, endDate, startTime, endTime } = bounds;

await setTimeBounds(page, startDate, endDate);
// Open the time conductor popup
await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click();

await page.keyboard.press('Enter');
if (startDate) {
await page.getByLabel('Start date').fill(startDate);
}

if (startTime) {
await page.getByLabel('Start time').fill(startTime);
}

if (endDate) {
await page.getByLabel('End date').fill(endDate);
}

if (endTime) {
await page.getByLabel('End time').fill(endTime);
}

if (submitChanges) {
await page.getByLabel('Submit time bounds').click();
} else {
await page.getByLabel('Discard changes and close time popup').click();
}
}

/**
Expand Down
35 changes: 27 additions & 8 deletions e2e/tests/framework/appActions.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ import {
createDomainObjectWithDefaults,
createNotification,
expandEntireTree,
openObjectTreeContextMenu
openObjectTreeContextMenu,
setFixedTimeMode,
setRealTimeMode,
setTimeConductorBounds
} from '../../appActions.js';
import { expect, test } from '../../pluginFixtures.js';

test.describe('AppActions', () => {
test('createDomainObjectsWithDefaults', async ({ page }) => {
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });

});
test('createDomainObjectsWithDefaults', async ({ page }) => {
const e2eFolder = await createDomainObjectWithDefaults(page, {
type: 'Folder',
name: 'e2e folder'
Expand Down Expand Up @@ -91,7 +95,6 @@ test.describe('AppActions', () => {
});
});
test('createNotification', async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });
await createNotification(page, {
message: 'Test info notification',
severity: 'info'
Expand All @@ -115,8 +118,6 @@ test.describe('AppActions', () => {
await page.locator('[aria-label="Dismiss"]').click();
});
test('expandEntireTree', async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });

const rootFolder = await createDomainObjectWithDefaults(page, {
type: 'Folder'
});
Expand Down Expand Up @@ -168,12 +169,30 @@ test.describe('AppActions', () => {
expect(await locatorTreeCollapsedItems.count()).toBe(0);
});
test('openObjectTreeContextMenu', async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });

const folder = await createDomainObjectWithDefaults(page, {
type: 'Folder'
});
await openObjectTreeContextMenu(page, folder.url);
await expect(page.getByLabel(`${folder.name} Context Menu`)).toBeVisible();
});
test('setTimeConductorMode', async ({ page }) => {
await setFixedTimeMode(page);
await expect(page.getByLabel('Start bounds:')).toBeVisible();
await expect(page.getByLabel('End bounds:')).toBeVisible();
await setRealTimeMode(page);
await expect(page.getByLabel('Start offset')).toBeVisible();
await expect(page.getByLabel('End offset')).toBeVisible();
});
test('setTimeConductorBounds', async ({ page }) => {
// Assume in real-time mode by default
await setFixedTimeMode(page);
await setTimeConductorBounds(page, {
startDate: '2024-01-01',
endDate: '2024-01-02',
startTime: '00:00:00',
endTime: '23:59:59'
});
await expect(page.getByLabel('Start bounds: 2024-01-01 00:00:00')).toBeVisible();
await expect(page.getByLabel('End bounds: 2024-01-02 23:59:59')).toBeVisible();
});
});
27 changes: 17 additions & 10 deletions e2e/tests/framework/generateLocalStorageData.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,25 @@ test.describe('Generate Visual Test Data @localStorage @generatedata @clock', ()
end: '2024-11-12 20:11:11.000Z'
});

const NEW_GLOBAL_START_BOUNDS = '2024-11-11 19:11:11.000Z';
const NEW_GLOBAL_END_BOUNDS = '2024-11-11 20:11:11.000Z';

await setTimeConductorBounds(page, NEW_GLOBAL_START_BOUNDS, NEW_GLOBAL_END_BOUNDS);
const NEW_GLOBAL_START_DATE = '2024-11-11';
const NEW_GLOBAL_START_TIME = '19:11:11';
const NEW_GLOBAL_END_DATE = '2024-11-11';
const NEW_GLOBAL_END_TIME = '20:11:11';

await setTimeConductorBounds(page, {
startDate: NEW_GLOBAL_START_DATE,
startTime: NEW_GLOBAL_START_TIME,
endDate: NEW_GLOBAL_END_DATE,
endTime: NEW_GLOBAL_END_TIME
});

// Verify that the global time conductor bounds have been updated
expect(
await page.getByLabel('Global Time Conductor').getByLabel('Start bounds').textContent()
).toEqual(NEW_GLOBAL_START_BOUNDS);
expect(
await page.getByLabel('Global Time Conductor').getByLabel('End bounds').textContent()
).toEqual(NEW_GLOBAL_END_BOUNDS);
await expect(
page.getByLabel(`Start bounds: ${NEW_GLOBAL_START_DATE} ${NEW_GLOBAL_START_TIME}.000Z`)
).toBeVisible();
await expect(
page.getByLabel(`End bounds: ${NEW_GLOBAL_END_DATE} ${NEW_GLOBAL_END_TIME}.000Z`)
).toBeVisible();

//Save localStorage for future test execution
await context.storageState({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ test.describe('Example Imagery Object', () => {
// Verify that the created object is focused
await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
await page.getByLabel('Focused Image Element').hover({ trial: true });

// Wait for image thumbnail auto-scroll to complete
await expect(page.getByLabel('Image Thumbnail from').last()).toBeInViewport();
});

test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => {
Expand Down
59 changes: 22 additions & 37 deletions e2e/tests/functional/plugins/plot/logPlot.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Tests to verify log plot functionality. Note this test suite if very much under
necessarily be used for reference when writing new tests in this area.
*/

import { setTimeConductorBounds } from '../../../../appActions.js';
import { createDomainObjectWithDefaults, setTimeConductorBounds } from '../../../../appActions.js';
import { expect, test } from '../../../../pluginFixtures.js';

test.describe('Log plot tests', () => {
Expand Down Expand Up @@ -86,51 +86,36 @@ async function makeOverlayPlot(page, myItemsFolderName) {
// Set a specific time range for consistency, otherwise it will change
// on every test to a range based on the current time.

const start = '2022-03-29 22:00:00.000Z';
const end = '2022-03-29 22:00:30.000Z';
const startDate = '2022-03-29';
const startTime = '22:00:00';
const endDate = '2022-03-29';
const endTime = '22:00:30';

await setTimeConductorBounds(page, start, end);
await setTimeConductorBounds(page, { startDate, startTime, endDate, endTime });

// create overlay plot

await page.locator('button.c-create-button').click();
await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
// Click OK button and wait for Navigate event
await Promise.all([
page.waitForLoadState(),
await page.getByRole('button', { name: 'Save' }).click(),
// Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);

// save the overlay plot
await saveOverlayPlot(page);
const overlayPlot = await createDomainObjectWithDefaults(page, {
type: 'Overlay Plot',
name: 'Unnamed Overlay Plot'
});

// create a sinewave generator
await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: 'Unnamed Sine Wave Generator',
parent: overlayPlot.uuid
});

await page.locator('button.c-create-button').click();
await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
await page.getByLabel('More actions').click();
await page.getByLabel('Edit Properties...').click();

// set amplitude to 6, offset 4, data rate 2 hz
await page.getByLabel('Amplitude', { exact: true }).fill('6');
await page.getByLabel('Offset', { exact: true }).fill('4');
await page.getByLabel('Data Rate (hz)', { exact: true }).fill('2');

await page.getByLabel('Amplitude').fill('6');
await page.getByLabel('Offset').fill('4');
await page.getByLabel('Data Rate (hz)').fill('2');
await page.getByLabel('Save').click();

// Click OK button and wait for Navigate event
await Promise.all([
page.waitForLoadState(),
await page.getByRole('button', { name: 'Save' }).click(),
// Wait for Save Banner to appear
page.waitForSelector('.c-message-banner__message')
]);

// click on overlay plot
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
await Promise.all([
page.waitForLoadState(),
page.locator('text=Unnamed Overlay Plot').first().click()
]);
await page.goto(overlayPlot.url);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,14 @@ test.describe('Telemetry Table', () => {

// Subtract 5 minutes from the current end bound datetime and set it
// Bring up the time conductor popup
let endDate = await page.locator('[aria-label="End bounds"]').textContent();
endDate = new Date(endDate);
let endTimeStamp = await page.getByLabel('End bounds').textContent();
endTimeStamp = new Date(endTimeStamp);

endDate.setUTCMinutes(endDate.getUTCMinutes() - 5);
endDate = endDate.toISOString().replace(/T/, ' ');
endTimeStamp.setUTCMinutes(endTimeStamp.getUTCMinutes() - 5);
const endDate = endTimeStamp.toISOString().split('T')[0];
const endTime = endTimeStamp.toISOString().split('T')[1];

await setTimeConductorBounds(page, undefined, endDate);
await setTimeConductorBounds(page, { endDate, endTime });

await expect(tableWrapper).not.toHaveClass(/is-paused/);

Expand All @@ -131,7 +132,7 @@ test.describe('Telemetry Table', () => {

// Verify that it is <= our new end bound
const latestMilliseconds = Date.parse(latestTelemetryDate);
const endBoundMilliseconds = Date.parse(endDate);
const endBoundMilliseconds = Date.parse(endTimeStamp);
expect(latestMilliseconds).toBeLessThanOrEqual(endBoundMilliseconds);
});

Expand Down
Loading

0 comments on commit e3fcbe1

Please sign in to comment.