From 2897ca65b3066fc1421a1c89261608207e116d90 Mon Sep 17 00:00:00 2001 From: John Hill Date: Mon, 26 Feb 2024 08:59:20 -0800 Subject: [PATCH] first pass of lint fixes --- e2e/.eslintrc.cjs | 10 +++- e2e/README.md | 12 ++++- e2e/helper/faultUtils.js | 2 +- e2e/tests/functional/couchdb.e2e.spec.js | 6 +-- e2e/tests/functional/forms.e2e.spec.js | 4 +- .../conditionSet/conditionSet.e2e.spec.js | 10 ++-- .../displayLayout/displayLayout.e2e.spec.js | 4 +- .../imagery/exampleImagery.e2e.spec.js | 6 +-- .../exportAsJson.e2e.spec.js | 2 +- .../notebook/notebookWithCouchDB.e2e.spec.js | 16 +++--- .../plugins/plot/missingPlotObj.e2e.spec.js | 6 +-- e2e/tests/functional/renaming.e2e.spec.js | 2 +- e2e/tests/functional/tooltips.e2e.spec.js | 52 +++++++++---------- e2e/tests/functional/tree.e2e.spec.js | 35 ++++++------- .../contract/imagery.contract.perf.spec.js | 14 ++--- .../contract/notebook.contract.perf.spec.js | 19 ++++--- .../memory/navigation.memory.perf.spec.js | 4 +- e2e/tests/performance/tabs.perf.spec.js | 2 +- e2e/tests/performance/tagging.perf.spec.js | 2 +- .../components/header.visual.spec.js | 2 +- .../visual-a11y/telemetryViews.visual.spec.js | 2 +- 21 files changed, 112 insertions(+), 100 deletions(-) diff --git a/e2e/.eslintrc.cjs b/e2e/.eslintrc.cjs index 9d378f77c0..527a4e8bd6 100644 --- a/e2e/.eslintrc.cjs +++ b/e2e/.eslintrc.cjs @@ -6,9 +6,15 @@ module.exports = { }, overrides: [ { - files: ['tests/visual/*.spec.js'], + files: ['**/*.visual.spec.js'], rules: { - 'playwright/no-wait-for-timeout': 'off' + 'playwright/expect-expect': 'off' + } + }, + { + files: ['**/*.perf.spec.js'], + rules: { + 'playwright/expect-expect': 'off' } } ] diff --git a/e2e/README.md b/e2e/README.md index ee0debe9dd..70462eac95 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -382,7 +382,7 @@ By adhering to this principle, we can create tests that are both robust and refl 1. Avoid creating locator aliases. This likely means that you're compensating for a bad locator. Improve the application instead. 1. Leverage `await page.goto('./', { waitUntil: 'domcontentloaded' });` instead of `{ waitUntil: 'networkidle' }`. Tests run against deployments with websockets often have issues with the networkidle detection. -#### How to make tests faster and more resilient +#### How to make tests faster and more resilient to application changes 1. Avoid app interaction when possible. The best way of doing this is to navigate directly by URL: ```js @@ -397,6 +397,16 @@ By adhering to this principle, we can create tests that are both robust and refl - Initial navigation should _almost_ always use the `{ waitUntil: 'domcontentloaded' }` option. 1. Avoid repeated setup to test a single assertion. Write longer tests with multiple soft assertions. This ensures that your changes will be picked up with large refactors. + 1. Use [user-facing locators](https://playwright.dev/docs/best-practices#use-locators) (Now a eslint rule!) + + ```js + page.getByRole('button', { name: 'Create' } ) + ``` + Instead of + ```js + page.locator('.c-create-button') + ``` + Note: `page.locator()` can be used in performance tests as xk6-browser does not yet support the new `page.getBy` pattern and css lookups can be [1.5x faster](https://serpapi.com/blog/css-selectors-faster-than-getbyrole-playwright/) ##### Utilizing LocalStorage 1. In order to save test runtime in the case of tests that require a decent amount of initial setup (such as in the case of testing complex displays), you may use [Playwright's `storageState` feature](https://playwright.dev/docs/api/class-browsercontext#browser-context-storage-state) to generate and load localStorage states. diff --git a/e2e/helper/faultUtils.js b/e2e/helper/faultUtils.js index aecbee2ba9..6ec4cee6dd 100644 --- a/e2e/helper/faultUtils.js +++ b/e2e/helper/faultUtils.js @@ -58,7 +58,7 @@ async function navigateToFaultManagementWithoutExample(page) { * @param {import('@playwright/test').Page} page */ async function navigateToFaultItemInTree(page) { - await page.goto('./', { waitUntil: 'networkidle' }); + await page.goto('./', { waitUntil: 'domcontentloaded' }); const faultManagementTreeItem = page .getByRole('tree', { diff --git a/e2e/tests/functional/couchdb.e2e.spec.js b/e2e/tests/functional/couchdb.e2e.spec.js index b4042e8eaf..3afa9033e2 100644 --- a/e2e/tests/functional/couchdb.e2e.spec.js +++ b/e2e/tests/functional/couchdb.e2e.spec.js @@ -41,7 +41,7 @@ test.describe('CouchDB Status Indicator with mocked responses @couchdb', () => { //Go to baseURL await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', { - waitUntil: 'networkidle' + waitUntil: 'domcontentloaded' }); await expect(page.locator('div:has-text("CouchDB is connected")').nth(3)).toBeVisible(); }); @@ -56,7 +56,7 @@ test.describe('CouchDB Status Indicator with mocked responses @couchdb', () => { //Go to baseURL await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', { - waitUntil: 'networkidle' + waitUntil: 'domcontentloaded' }); await expect(page.locator('div:has-text("CouchDB is offline")').nth(3)).toBeVisible(); }); @@ -71,7 +71,7 @@ test.describe('CouchDB Status Indicator with mocked responses @couchdb', () => { //Go to baseURL await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', { - waitUntil: 'networkidle' + waitUntil: 'domcontentloaded' }); await expect(page.locator('div:has-text("CouchDB connectivity unknown")').nth(3)).toBeVisible(); }); diff --git a/e2e/tests/functional/forms.e2e.spec.js b/e2e/tests/functional/forms.e2e.spec.js index 7ec750c037..51e5d5a277 100644 --- a/e2e/tests/functional/forms.e2e.spec.js +++ b/e2e/tests/functional/forms.e2e.spec.js @@ -188,8 +188,8 @@ test.describe('Persistence operations @couchdb', () => { // Both pages: Go to baseURL await Promise.all([ - page.goto('./', { waitUntil: 'networkidle' }), - page2.goto('./', { waitUntil: 'networkidle' }) + page.goto('./', { waitUntil: 'domcontentloaded' }), + page2.goto('./', { waitUntil: 'domcontentloaded' }) ]); //Slow down the test a bit diff --git a/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js b/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js index d41f884cb0..8d6fac2952 100644 --- a/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js +++ b/e2e/tests/functional/plugins/conditionSet/conditionSet.e2e.spec.js @@ -76,7 +76,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage @2p', () => description: 'https://github.com/nasa/openmct/issues/7421' }); //Navigate to baseURL with injected localStorage - await page.goto(conditionSetUrl, { waitUntil: 'networkidle' }); + await page.goto(conditionSetUrl, { waitUntil: 'domcontentloaded' }); //Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto() await expect @@ -87,7 +87,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage @2p', () => expect.soft(page.locator('_vue=item.name=Unnamed Condition Set')).toBeTruthy(); //Reload Page - await Promise.all([page.reload(), page.waitForLoadState('networkidle')]); + await Promise.all([page.reload(), page.waitForLoadState('domcontentloaded')]); //Re-verify after reload await expect @@ -100,7 +100,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage @2p', () => test('condition set object can be modified on @localStorage', async ({ page, openmctConfig }) => { const { myItemsFolderName } = openmctConfig; - await page.goto(conditionSetUrl, { waitUntil: 'networkidle' }); + await page.goto(conditionSetUrl, { waitUntil: 'domcontentloaded' }); //Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto() await expect @@ -151,7 +151,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage @2p', () => expect(page.locator('a:has-text("Renamed Condition Set")')).toBeTruthy(); //Reload Page - await Promise.all([page.reload(), page.waitForLoadState('networkidle')]); + await Promise.all([page.reload(), page.waitForLoadState('domcontentloaded')]); //Verify Main section reflects updated Name Property await expect @@ -213,7 +213,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage @2p', () => //Feature? //Domain Object is still available by direct URL after delete - await page.goto(conditionSetUrl, { waitUntil: 'networkidle' }); + await page.goto(conditionSetUrl, { waitUntil: 'domcontentloaded' }); await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set'); }); }); diff --git a/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js b/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js index f06b29b509..9fd6d7a679 100644 --- a/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js +++ b/e2e/tests/functional/plugins/displayLayout/displayLayout.e2e.spec.js @@ -410,7 +410,7 @@ test.describe('Display Layout', () => { await page.reload(); // wait for annotations requests to be batched and requested - await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); // Network requests for the composite telemetry with multiple items should be: // 1. a single batched request for annotations expect(networkRequests.length).toBe(1); @@ -422,7 +422,7 @@ test.describe('Display Layout', () => { await page.reload(); // wait for annotations to not load (if we have any, we've got a problem) - await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); // In real time mode, we don't fetch annotations at all expect(networkRequests.length).toBe(0); diff --git a/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js b/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js index 19b3ff526b..7865061b23 100644 --- a/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js +++ b/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js @@ -531,7 +531,7 @@ test.describe('Example Imagery in Flexible layout', () => { // Click text=OK await Promise.all([ - page.waitForNavigation({ waitUntil: 'networkidle' }), + page.waitForNavigation({ waitUntil: 'domcontentloaded' }), page.click('button:has-text("OK")'), //Wait for Save Banner to appear page.waitForSelector('.c-message-banner__message') @@ -575,7 +575,7 @@ test.describe('Example Imagery in Tabs View', () => { // Click text=OK await Promise.all([ - page.waitForNavigation({ waitUntil: 'networkidle' }), + page.waitForNavigation({ waitUntil: 'domcontentloaded' }), page.click('button:has-text("OK")'), //Wait for Save Banner to appear page.waitForSelector('.c-message-banner__message') @@ -1023,7 +1023,7 @@ async function createImageryView(page) { // Click text=OK await Promise.all([ - page.waitForNavigation({ waitUntil: 'networkidle' }), + page.waitForNavigation({ waitUntil: 'domcontentloaded' }), page.click('button:has-text("OK")'), //Wait for Save Banner to appear page.waitForSelector('.c-message-banner__message') diff --git a/e2e/tests/functional/plugins/importAndExportAsJSON/exportAsJson.e2e.spec.js b/e2e/tests/functional/plugins/importAndExportAsJSON/exportAsJson.e2e.spec.js index e8cc3c6344..01aebf0a8a 100644 --- a/e2e/tests/functional/plugins/importAndExportAsJSON/exportAsJson.e2e.spec.js +++ b/e2e/tests/functional/plugins/importAndExportAsJSON/exportAsJson.e2e.spec.js @@ -152,7 +152,7 @@ test.describe('ExportAsJSON Disabled Actions', () => { test.describe('ExportAsJSON ProgressBar @couchdb', () => { let folder; test.beforeEach(async ({ page }) => { - await page.goto('./', { waitUntil: 'networkidle' }); + await page.goto('./', { waitUntil: 'domcontentloaded' }); // Perform actions to create the domain object folder = await createDomainObjectWithDefaults(page, { type: 'Folder' diff --git a/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js b/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js index 985af38447..0465fe212f 100644 --- a/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js +++ b/e2e/tests/functional/plugins/notebook/notebookWithCouchDB.e2e.spec.js @@ -37,7 +37,7 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => { // Create Notebook testNotebook = await createDomainObjectWithDefaults(page, { type: 'Notebook' }); - await page.goto(testNotebook.url, { waitUntil: 'networkidle' }); + await page.goto(testNotebook.url, { waitUntil: 'domcontentloaded' }); }); test('Inspect Notebook Entry Network Requests', async ({ page }) => { @@ -58,7 +58,7 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => { page.click('[aria-label="Add Page"]') ]); // Ensures that there are no other network requests - await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); // Assert that only two requests are made // Network Requests are: @@ -77,7 +77,7 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => { // 2) The shared worker event from 👆 POST request notebookElementsRequests = []; await nbUtils.enterTextEntry(page, 'First Entry'); - await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); expect(notebookElementsRequests.length).toBeLessThanOrEqual(2); // Add some tags @@ -141,7 +141,7 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => { // 4) The shared worker event from 👆 POST request notebookElementsRequests = []; await nbUtils.enterTextEntry(page, 'Fourth Entry'); - page.waitForLoadState('networkidle'); + page.waitForLoadState('domcontentloaded'); expect(filterNonFetchRequests(notebookElementsRequests).length).toBeLessThanOrEqual(4); @@ -153,7 +153,7 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => { // 4) The shared worker event from 👆 POST request notebookElementsRequests = []; await nbUtils.enterTextEntry(page, 'Fifth Entry'); - page.waitForLoadState('networkidle'); + page.waitForLoadState('domcontentloaded'); expect(filterNonFetchRequests(notebookElementsRequests).length).toBeLessThanOrEqual(4); @@ -164,7 +164,7 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => { // 4) The shared worker event from 👆 POST request notebookElementsRequests = []; await nbUtils.enterTextEntry(page, 'Sixth Entry'); - page.waitForLoadState('networkidle'); + page.waitForLoadState('domcontentloaded'); expect(filterNonFetchRequests(notebookElementsRequests).length).toBeLessThanOrEqual(4); }); @@ -227,7 +227,7 @@ async function addTagAndAwaitNetwork(page, tagName) { page.locator(`[aria-label="Autocomplete Options"] >> text=${tagName}`).click(), expect(page.locator(`[aria-label="Tag"]:has-text("${tagName}")`)).toBeVisible() ]); - await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); } /** @@ -246,5 +246,5 @@ async function removeTagAndAwaitNetwork(page, tagName) { ) ]); await expect(page.locator(`[aria-label="Tag"]:has-text("${tagName}")`)).toBeHidden(); - await page.waitForLoadState('networkidle'); + await page.waitForLoadState('domcontentloaded'); } diff --git a/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js b/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js index bee8c83a2d..0acb3bdbb7 100644 --- a/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js +++ b/e2e/tests/functional/plugins/plot/missingPlotObj.e2e.spec.js @@ -59,7 +59,7 @@ test.describe('Handle missing object for plots', () => { await page.evaluate(`window.localStorage.setItem('mct', '${JSON.stringify(parsedData)}')`); //Reloads page and clicks on stacked plot - await Promise.all([page.reload(), page.waitForLoadState('networkidle')]); + await Promise.all([page.reload(), page.waitForLoadState('domcontentloaded')]); //Verify Main section is there on load await expect @@ -92,7 +92,7 @@ async function makeStackedPlot(page, myItemsFolderName) { await page.locator('li[role="menuitem"]:has-text("Stacked Plot")').click(); await Promise.all([ - page.waitForNavigation({ waitUntil: 'networkidle' }), + page.waitForNavigation({ waitUntil: 'domcontentloaded' }), page.locator('button:has-text("OK")').click(), //Wait for Save Banner to appear page.waitForSelector('.c-message-banner__message') @@ -153,7 +153,7 @@ async function createSineWaveGenerator(page) { await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click(); await Promise.all([ - page.waitForNavigation({ waitUntil: 'networkidle' }), + page.waitForNavigation({ waitUntil: 'domcontentloaded' }), page.locator('button:has-text("OK")').click(), //Wait for Save Banner to appear page.waitForSelector('.c-message-banner__message') diff --git a/e2e/tests/functional/renaming.e2e.spec.js b/e2e/tests/functional/renaming.e2e.spec.js index f201c07028..3d6fd5c75a 100644 --- a/e2e/tests/functional/renaming.e2e.spec.js +++ b/e2e/tests/functional/renaming.e2e.spec.js @@ -30,7 +30,7 @@ import { expect, test } from '../../baseFixtures.js'; test.describe('Renaming objects', () => { test.beforeEach(async ({ page }) => { // Go to baseURL - await page.goto('./', { waitUntil: 'networkidle' }); + await page.goto('./', { waitUntil: 'domcontentloaded' }); }); test('When renaming objects, the browse bar and various components all update', async ({ diff --git a/e2e/tests/functional/tooltips.e2e.spec.js b/e2e/tests/functional/tooltips.e2e.spec.js index 527593f217..dffe60c109 100644 --- a/e2e/tests/functional/tooltips.e2e.spec.js +++ b/e2e/tests/functional/tooltips.e2e.spec.js @@ -89,7 +89,7 @@ test.describe('Verify tooltips', () => { await expandEntireTree(page); }); - test('display correct paths for LAD tables', async ({ page, openmctConfig }) => { + test('display correct paths for LAD tables', async ({ page }) => { // Create LAD table await createDomainObjectWithDefaults(page, { type: 'LAD Table', @@ -110,7 +110,7 @@ test.describe('Verify tooltips', () => { async function getToolTip(object) { await page.locator('.c-create-button').hover(); await page.getByRole('cell', { name: object.name }).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); return tooltipText.replace('\n', '').trim(); } @@ -142,7 +142,7 @@ test.describe('Verify tooltips', () => { await page .locator('.plot-series-name', { has: page.locator(`text="${object.name} Hz"`) }) .hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); return tooltipText.replace('\n', '').trim(); } @@ -151,7 +151,7 @@ test.describe('Verify tooltips', () => { await page .locator('.plot-series-name', { has: page.locator(`text="${object.name}"`) }) .hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); return tooltipText.replace('\n', '').trim(); } @@ -181,7 +181,7 @@ test.describe('Verify tooltips', () => { has: page.locator(`text="${object.name}"`) }) .hover(); - const tooltipText = await page.locator('.c-tooltip').textContent(); + const tooltipText = await page.locator('.c-tooltip').innerText(); await page.keyboard.up('Control'); return tooltipText.replace('\n', '').trim(); } @@ -236,7 +236,7 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.getByText('Test Overlay Plot').nth(2).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe('My Items / Test Overlay Plot'); @@ -244,17 +244,17 @@ test.describe('Verify tooltips', () => { await page.locator('.c-plot-legend__view-control >> nth=0').click(); await page.keyboard.down('Control'); await page.locator('.plot-wrapper-expanded-legend .plot-series-name').first().hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); await page.getByText('Test Stacked Plot').nth(2).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe('My Items / Test Stacked Plot'); await page.getByText('SWG 3').nth(2).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(sineWaveObject3.path).toBe(tooltipText); }); @@ -273,12 +273,12 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.getByText('SWG 1').nth(2).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); await page.getByText('SWG 3').nth(2).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); @@ -297,12 +297,12 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.getByText('SWG 1').nth(2).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); await page.getByText('SWG 3').nth(2).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); @@ -310,12 +310,12 @@ test.describe('Verify tooltips', () => { test('display correct paths when hovering tree items', async ({ page }) => { await page.keyboard.down('Control'); await page.getByText('SWG 1').nth(0).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); await page.getByText('SWG 3').nth(0).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); @@ -326,7 +326,7 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.locator('.c-gsearch-result__title').hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); @@ -340,7 +340,7 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); // eslint-disable-next-line playwright/no-force-option await page.locator('.c-gauge.c-dial').hover({ position: { x: 0, y: 0 }, force: true }); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); @@ -354,7 +354,7 @@ test.describe('Verify tooltips', () => { await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-notebook__drag-area'); await page.keyboard.down('Control'); await page.locator('.c-ne__embed').hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); @@ -386,12 +386,12 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.locator('.noselect > [title="SWG 3"]').first().hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); await page.locator('.noselect > [title="SWG 1"]').first().hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); }); @@ -410,17 +410,17 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.getByLabel('Recent Objects').getByText(sineWaveObject3.name).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); await page.getByLabel('Recent Objects').getByText(sineWaveObject2.name).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject2.path); await page.getByLabel('Recent Objects').getByText(sineWaveObject1.name).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); }); @@ -450,17 +450,17 @@ test.describe('Verify tooltips', () => { await page.keyboard.down('Control'); await page.getByText(sineWaveObject1.name).nth(2).hover(); - let tooltipText = await page.locator('.c-tooltip').textContent(); + let tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject1.path); await page.getByText(sineWaveObject2.name).nth(2).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject2.path); await page.getByText(sineWaveObject3.name).nth(2).hover(); - tooltipText = await page.locator('.c-tooltip').textContent(); + tooltipText = await page.locator('.c-tooltip').innerText(); tooltipText = tooltipText.replace('\n', '').trim(); expect(tooltipText).toBe(sineWaveObject3.path); }); diff --git a/e2e/tests/functional/tree.e2e.spec.js b/e2e/tests/functional/tree.e2e.spec.js index c09752993a..fe9d85ca58 100644 --- a/e2e/tests/functional/tree.e2e.spec.js +++ b/e2e/tests/functional/tree.e2e.spec.js @@ -48,7 +48,9 @@ test.describe('Main Tree', () => { }); await expandTreePaneItemByName(page, folder.name); - await assertTreeItemIsVisible(page, clock.name); + await expect( + page.getByRole('tree', { name: 'Main Tree' }).getByRole('treeitem', { name: clock.name }) + ).toBeVisible(); }); test('Creating a child object on one tab and expanding its parent on the other shows the correct composition @2p', async ({ @@ -65,8 +67,8 @@ test.describe('Main Tree', () => { // Both pages: Go to baseURL await Promise.all([ - page.goto('./', { waitUntil: 'networkidle' }), - page2.goto('./', { waitUntil: 'networkidle' }) + page.goto('./', { waitUntil: 'domcontentloaded' }), + page2.goto('./', { waitUntil: 'domcontentloaded' }) ]); const page1Folder = await createDomainObjectWithDefaults(page, { @@ -74,7 +76,11 @@ test.describe('Main Tree', () => { }); await expandTreePaneItemByName(page2, myItemsFolderName); - await assertTreeItemIsVisible(page2, page1Folder.name); + await expect( + page2 + .getByRole('tree', { name: 'Main Tree' }) + .getByRole('treeitem', { name: page1Folder.name }) + ).toBeVisible(); }); test('Creating a child object on one tab and expanding its parent on the other shows the correct composition @couchdb @2p', async ({ @@ -91,8 +97,8 @@ test.describe('Main Tree', () => { // Both pages: Go to baseURL await Promise.all([ - page.goto('./', { waitUntil: 'networkidle' }), - page2.goto('./', { waitUntil: 'networkidle' }) + page.goto('./', { waitUntil: 'domcontentloaded' }), + page2.goto('./', { waitUntil: 'domcontentloaded' }) ]); const page1Folder = await createDomainObjectWithDefaults(page, { @@ -100,7 +106,11 @@ test.describe('Main Tree', () => { }); await expandTreePaneItemByName(page2, myItemsFolderName); - await assertTreeItemIsVisible(page2, page1Folder.name); + await expect( + page2 + .getByRole('tree', { name: 'Main Tree' }) + .getByRole('treeitem', { name: page1Folder.name }) + ).toBeVisible(); }); test('Renaming an object reorders the tree @unstable', async ({ page, openmctConfig }) => { @@ -221,17 +231,6 @@ async function getAndAssertTreeItems(page, expected) { expect(allTexts).toEqual(expected); } -async function assertTreeItemIsVisible(page, name) { - const mainTree = page.getByRole('tree', { - name: 'Main Tree' - }); - const treeItem = mainTree.getByRole('treeitem', { - name - }); - - await expect(treeItem).toBeVisible(); -} - /** * @param {import('@playwright/test').Page} page * @param {string} name diff --git a/e2e/tests/performance/contract/imagery.contract.perf.spec.js b/e2e/tests/performance/contract/imagery.contract.perf.spec.js index c87e6df5ea..6d5ad73d95 100644 --- a/e2e/tests/performance/contract/imagery.contract.perf.spec.js +++ b/e2e/tests/performance/contract/imagery.contract.perf.spec.js @@ -39,7 +39,7 @@ const filePath = 'e2e/test-data/PerformanceDisplayLayout.json'; test.describe('Performance tests', () => { test.beforeEach(async ({ page, browser }, testInfo) => { // Go to baseURL - await page.goto('./', { waitUntil: 'networkidle' }); + await page.goto('./', { waitUntil: 'domcontentloaded' }); // Click a:has-text("My Items") await page.locator('a:has-text("My Items")').click({ @@ -129,12 +129,12 @@ test.describe('Performance tests', () => { ]); //Time to Example Imagery Frame loads within Display Layout - await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' }); + await page.locator('.c-imagery__main-image__bg').waitFor({ state: 'visible' }); //Time to Example Imagery object loads - await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' }); + await page.locator('.c-imagery__main-image__background-image').waitFor({ state: 'visible' }); //Get background-image url from background-image css prop - const backgroundImage = await page.locator('.c-imagery__main-image__background-image'); + const backgroundImage = page.locator('.c-imagery__main-image__background-image'); let backgroundImageUrl = await backgroundImage.evaluate((el) => { return window .getComputedStyle(el) @@ -156,15 +156,15 @@ test.describe('Performance tests', () => { await page.evaluate(() => window.performance.mark('viewLarge.start.test')); //This is a mark only to compare evaluate timing //Time to Imagery Rendered in Large Frame - await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' }); + await page.locator('.c-imagery__main-image__bg').waitFor({ state: 'visible' }); await page.evaluate(() => window.performance.mark('background-image-frame')); //Time to Example Imagery object loads - await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' }); + await page.locator('.c-imagery__main-image__background-image').waitFor({ state: 'visible' }); await page.evaluate(() => window.performance.mark('background-image-visible')); // Get Current number of images in thumbstrip - await page.waitForSelector('.c-imagery__thumb'); + await page.locator('.c-imagery__thumb').waitFor({ state: 'visible' }); const thumbCount = await page.locator('.c-imagery__thumb').count(); console.log('number of thumbs rendered ' + thumbCount); await page.locator('.c-imagery__thumb').last().click(); diff --git a/e2e/tests/performance/contract/notebook.contract.perf.spec.js b/e2e/tests/performance/contract/notebook.contract.perf.spec.js index a1a96e3a28..7e9b8fa84f 100644 --- a/e2e/tests/performance/contract/notebook.contract.perf.spec.js +++ b/e2e/tests/performance/contract/notebook.contract.perf.spec.js @@ -38,7 +38,7 @@ const notebookFilePath = 'e2e/test-data/PerformanceNotebook.json'; test.describe('Performance tests', () => { test.beforeEach(async ({ page, browser }, testInfo) => { // Go to baseURL - await page.goto('./', { waitUntil: 'networkidle' }); + await page.goto('./', { waitUntil: 'domcontentloaded' }); // Click a:has-text("My Items") await page.locator('a:has-text("My Items")').click({ @@ -110,20 +110,19 @@ test.describe('Performance tests', () => { await page.evaluate(() => window.performance.mark('search-entered')); //Search Result Appears and is clicked await Promise.all([ - page.waitForNavigation(), page.locator('a:has-text("Performance Notebook")').first().click(), page.evaluate(() => window.performance.mark('click-search-result')) ]); - await page.waitForSelector('.c-tree__item c-tree-and-search__loading loading', { - state: 'hidden' - }); + await page + .locator('.c-tree__item c-tree-and-search__loading loading') + .waitFor({ state: 'hidden' }); await page.evaluate(() => window.performance.mark('search-spinner-gone')); - await page.waitForSelector('.l-browse-bar__object-name', { state: 'visible' }); + await page.locator('.l-browse-bar__object-name').waitFor({ state: 'visible' }); await page.evaluate(() => window.performance.mark('object-title-appears')); - await page.waitForSelector('.c-notebook__entry >> nth=0', { state: 'visible' }); + await page.locator('.c-notebook__entry >> nth=0').waitFor({ state: 'visible' }); await page.evaluate(() => window.performance.mark('notebook-entry-appears')); // Click Add new Notebook Entry @@ -139,9 +138,9 @@ test.describe('Performance tests', () => { await page.evaluate(() => window.performance.mark('notebook-search-start')); await page.locator('.c-notebook__search >> input').fill('Existing Entry'); await page.evaluate(() => window.performance.mark('notebook-search-filled')); - await page.waitForSelector('text=Search Results (3)', { state: 'visible' }); + await page.locator('text=Search Results (3)').waitFor({ state: 'visible' }); await page.evaluate(() => window.performance.mark('notebook-search-processed')); - await page.waitForSelector('.c-notebook__entry >> nth=2', { state: 'visible' }); + await page.locator('.c-notebook__entry >> nth=2').waitFor({ state: 'visible' }); await page.evaluate(() => window.performance.mark('notebook-search-processed')); //Clear Search @@ -154,7 +153,7 @@ test.describe('Performance tests', () => { await page.locator('div.c-ne__time-and-content').last().hover(); await page.locator('button[title="Delete this entry"]').last().click(); await page.locator('button:has-text("Ok")').click(); - await page.waitForSelector('.c-notebook__entry >> nth=3', { state: 'detached' }); + await page.locator('.c-notebook__entry >> nth=3').waitFor({ state: 'detached' }); await page.evaluate(() => window.performance.mark('new-notebook-entry-deleted')); //await client.send('HeapProfiler.enable'); diff --git a/e2e/tests/performance/memory/navigation.memory.perf.spec.js b/e2e/tests/performance/memory/navigation.memory.perf.spec.js index 17074fd8e0..69a615bdde 100644 --- a/e2e/tests/performance/memory/navigation.memory.perf.spec.js +++ b/e2e/tests/performance/memory/navigation.memory.perf.spec.js @@ -228,9 +228,7 @@ test.describe('Navigation memory leak is not detected in', () => { expect(result).toBe(true); }); - test('display layout with plots of swgs, alphanumerics, and condition sets, ', async ({ - page - }) => { + test('display layout with plots of swgs, alphanumerics, and condition sets', async ({ page }) => { const result = await navigateToObjectAndDetectMemoryLeak( page, 'display-layout-simple-telemetry' diff --git a/e2e/tests/performance/tabs.perf.spec.js b/e2e/tests/performance/tabs.perf.spec.js index 3db219f1da..6141bf61ee 100644 --- a/e2e/tests/performance/tabs.perf.spec.js +++ b/e2e/tests/performance/tabs.perf.spec.js @@ -78,7 +78,7 @@ test.describe('Tabs View', () => { await page.getByLabel(`${sineWaveGenerator.name} tab`, { exact: true }).click(); // ensure sine wave generator visible - expect(await page.locator('.c-plot').isVisible()).toBe(true); + await expect(page.locator('.c-plot')).toBeVisible(); // now select notebook and clear animation calls await page.getByLabel(`${notebook.name} tab`, { exact: true }).click(); diff --git a/e2e/tests/performance/tagging.perf.spec.js b/e2e/tests/performance/tagging.perf.spec.js index 495026f7a8..4fa19db2f9 100644 --- a/e2e/tests/performance/tagging.perf.spec.js +++ b/e2e/tests/performance/tagging.perf.spec.js @@ -84,7 +84,7 @@ test.describe('Plot Tagging Performance', () => { await setRealTimeMode(page); // Search for Science - await page.getByRole('searchbox', { name: 'Search Input' }); + await page.getByRole('searchbox', { name: 'Search Input' }).click(); await page.getByRole('searchbox', { name: 'Search Input' }).fill('sc'); // click on the search result diff --git a/e2e/tests/visual-a11y/components/header.visual.spec.js b/e2e/tests/visual-a11y/components/header.visual.spec.js index ba9320a83b..e2074facd4 100644 --- a/e2e/tests/visual-a11y/components/header.visual.spec.js +++ b/e2e/tests/visual-a11y/components/header.visual.spec.js @@ -75,7 +75,7 @@ test.describe('Visual - Header @a11y', () => { await percySnapshot(page, `Notebook Snapshot Show button (theme: '${theme}')`, { scope: header }); - await expect(await page.getByLabel('Show Snapshots')).toBeVisible(); + await expect(page.getByLabel('Show Snapshots')).toBeVisible(); }); }); // Skipping for https://github.com/nasa/openmct/issues/7421 diff --git a/e2e/tests/visual-a11y/telemetryViews.visual.spec.js b/e2e/tests/visual-a11y/telemetryViews.visual.spec.js index 3e382c0b0b..77376e0942 100644 --- a/e2e/tests/visual-a11y/telemetryViews.visual.spec.js +++ b/e2e/tests/visual-a11y/telemetryViews.visual.spec.js @@ -57,7 +57,7 @@ test.describe('Visual - Telemetry Views', () => { await page.getByLabel('Telemetry Table').click(); //Get Table View in place - expect(await page.getByLabel('Expand Columns')).toBeInViewport(); + await expect(page.getByLabel('Expand Columns')).toBeInViewport(); await percySnapshot(page, `Default Telemetry Table View (theme: ${theme})`);