mirror of
https://github.com/nasa/openmct.git
synced 2025-01-30 16:13:53 +00:00
[Telemetry Tables] Make sure tables auto scroll correctly on first load (#7720)
* run scroll method to scroll to top after initial load of historical data * clarifying comment * added e2e test to make sure tables auto scroll on mount * adding descriptive comments * adding in ascending check as well * added new appAction for navigating to/in realtime, using it in table scroll test * lint --------- Co-authored-by: David Tsay <3614296+davetsay@users.noreply.github.com>
This commit is contained in:
parent
977792fae8
commit
810d580b18
@ -275,6 +275,17 @@ async function navigateToObjectWithFixedTimeBounds(page, url, start, end) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates directly to a given object url, in real-time mode.
|
||||||
|
* @param {import('@playwright/test').Page} page
|
||||||
|
* @param {string} url The url to the domainObject
|
||||||
|
*/
|
||||||
|
async function navigateToObjectWithRealTime(page, url, start = '1800000', end = '30000') {
|
||||||
|
await page.goto(
|
||||||
|
`${url}?tc.mode=local&tc.startDelta=${start}&tc.endDelta=${end}&tc.timeSystem=utc`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the given `domainObject`'s context menu from the object tree.
|
* Open the given `domainObject`'s context menu from the object tree.
|
||||||
* Expands the path to the object and scrolls to it if necessary.
|
* Expands the path to the object and scrolls to it if necessary.
|
||||||
@ -656,6 +667,7 @@ export {
|
|||||||
getFocusedObjectUuid,
|
getFocusedObjectUuid,
|
||||||
getHashUrlToDomainObject,
|
getHashUrlToDomainObject,
|
||||||
navigateToObjectWithFixedTimeBounds,
|
navigateToObjectWithFixedTimeBounds,
|
||||||
|
navigateToObjectWithRealTime,
|
||||||
openObjectTreeContextMenu,
|
openObjectTreeContextMenu,
|
||||||
renameObjectFromContextMenu,
|
renameObjectFromContextMenu,
|
||||||
setEndOffset,
|
setEndOffset,
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
createDomainObjectWithDefaults,
|
createDomainObjectWithDefaults,
|
||||||
setTimeConductorBounds,
|
navigateToObjectWithRealTime,
|
||||||
setTimeConductorMode
|
setTimeConductorBounds
|
||||||
} from '../../../../appActions.js';
|
} from '../../../../appActions.js';
|
||||||
import { expect, test } from '../../../../pluginFixtures.js';
|
import { expect, test } from '../../../../pluginFixtures.js';
|
||||||
|
|
||||||
@ -39,12 +39,52 @@ test.describe('Telemetry Table', () => {
|
|||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
parent: table.uuid
|
parent: table.uuid
|
||||||
});
|
});
|
||||||
await page.goto(table.url);
|
await navigateToObjectWithRealTime(page, table.url);
|
||||||
await setTimeConductorMode(page, false);
|
|
||||||
const rows = page.getByLabel('table content').getByLabel('Table Row');
|
const rows = page.getByLabel('table content').getByLabel('Table Row');
|
||||||
await expect(rows).toHaveCount(50);
|
await expect(rows).toHaveCount(50);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('on load, auto scrolls to top for descending, and to bottom for ascending', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
|
const sineWaveGenerator = await createDomainObjectWithDefaults(page, {
|
||||||
|
type: 'Sine Wave Generator',
|
||||||
|
parent: table.uuid
|
||||||
|
});
|
||||||
|
|
||||||
|
// verify in telemetry table object view
|
||||||
|
await navigateToObjectWithRealTime(page, table.url);
|
||||||
|
|
||||||
|
expect(await getScrollPosition(page)).toBe(0);
|
||||||
|
|
||||||
|
// verify in telemetry table view
|
||||||
|
await page.goto(sineWaveGenerator.url);
|
||||||
|
await page.getByLabel('Open the View Switcher Menu').click();
|
||||||
|
await page.getByText('Telemetry Table', { exact: true }).click();
|
||||||
|
|
||||||
|
expect(await getScrollPosition(page)).toBe(0);
|
||||||
|
|
||||||
|
// navigate back to table
|
||||||
|
await page.goto(table.url);
|
||||||
|
|
||||||
|
// go into edit mode
|
||||||
|
await page.getByLabel('Edit Object').click();
|
||||||
|
|
||||||
|
// change sort direction
|
||||||
|
await page.locator('thead div').filter({ hasText: 'Time' }).click();
|
||||||
|
|
||||||
|
// save view
|
||||||
|
await page.getByRole('button', { name: 'Save' }).click();
|
||||||
|
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||||
|
|
||||||
|
// navigate away and back
|
||||||
|
await page.goto(sineWaveGenerator.url);
|
||||||
|
await page.goto(table.url);
|
||||||
|
|
||||||
|
// verify scroll position
|
||||||
|
expect(await getScrollPosition(page, false)).toBeLessThan(1);
|
||||||
|
});
|
||||||
|
|
||||||
test('unpauses and filters data when paused by button and user changes bounds', async ({
|
test('unpauses and filters data when paused by button and user changes bounds', async ({
|
||||||
page
|
page
|
||||||
}) => {
|
}) => {
|
||||||
@ -183,3 +223,42 @@ test.describe('Telemetry Table', () => {
|
|||||||
await page.click('button[title="Pause"]');
|
await page.click('button[title="Pause"]');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function getScrollPosition(page, top = true) {
|
||||||
|
const tableBody = page.locator('.c-table__body-w');
|
||||||
|
|
||||||
|
// Wait for the scrollbar to appear
|
||||||
|
await tableBody.evaluate((node) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
function checkScroll() {
|
||||||
|
if (node.scrollHeight > node.clientHeight) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
setTimeout(checkScroll, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkScroll();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// make sure there are rows
|
||||||
|
const rows = page.getByLabel('table content').getByLabel('Table Row');
|
||||||
|
await rows.first().waitFor();
|
||||||
|
|
||||||
|
// Using this to allow for rows to come and go, so we can truly test the scroll position
|
||||||
|
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
const { scrollTop, clientHeight, scrollHeight } = await tableBody.evaluate((node) => ({
|
||||||
|
scrollTop: node.scrollTop,
|
||||||
|
clientHeight: node.clientHeight,
|
||||||
|
scrollHeight: node.scrollHeight
|
||||||
|
}));
|
||||||
|
|
||||||
|
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||||
|
if (top) {
|
||||||
|
return scrollTop;
|
||||||
|
} else {
|
||||||
|
return Math.abs(scrollHeight - (scrollTop + clientHeight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -561,6 +561,9 @@ export default {
|
|||||||
|
|
||||||
this.table.initialize();
|
this.table.initialize();
|
||||||
this.rescaleToContainer();
|
this.rescaleToContainer();
|
||||||
|
|
||||||
|
// Scroll to the top of the table after loading
|
||||||
|
this.addToAfterLoadActions(this.scroll);
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
this.table.off('object-added', this.addObject);
|
this.table.off('object-added', this.addObject);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user