From 5f296750492119bc779d0bd51092b767543be2bc Mon Sep 17 00:00:00 2001 From: Christopher Mead Date: Mon, 30 Dec 2024 12:04:23 -0700 Subject: [PATCH] E2E Tests: remove MS dependencies for outline, variables, & more (#5863) Removing MS dependencies in several places: * outline POM * variables POM * notebook test * 100x100 test * new project wizard * console POM ### QA Notes All tests should pass. --- .../src/positron/positronConsole.ts | 12 ----------- .../positron/positronInterpreterDropdown.ts | 2 +- .../src/positron/positronNewProjectWizard.ts | 4 ++-- .../src/positron/positronNotebooks.ts | 2 +- .../src/positron/positronOutline.ts | 8 +++++--- .../automation/src/positron/positronPopups.ts | 4 ++-- .../src/positron/positronQuickaccess.ts | 4 ++-- .../src/positron/positronVariables.ts | 20 ++++++++++++------- test/automation/src/workbench.ts | 4 ++-- .../areas/data-explorer/helpers/100x100.ts | 7 ++++--- test/e2e/areas/help/help.test.ts | 10 ++++++---- 11 files changed, 38 insertions(+), 39 deletions(-) diff --git a/test/automation/src/positron/positronConsole.ts b/test/automation/src/positron/positronConsole.ts index 236ec75265f..1b11db17d0b 100644 --- a/test/automation/src/positron/positronConsole.ts +++ b/test/automation/src/positron/positronConsole.ts @@ -183,18 +183,6 @@ export class PositronConsole { throw new Error('Console is not ready after waiting for R or Python to start'); } - async waitForNoInterpretersRunning(retryCount: number = 200) { - const noInterpreter = await this.code.waitForElement( - EMPTY_CONSOLE, - () => true, - retryCount - ); - if (noInterpreter) { - return; - } - throw new Error('Console is not ready after waiting for no interpreters running'); - } - async waitForInterpreterShutdown() { await this.waitForConsoleContents('shut down successfully'); } diff --git a/test/automation/src/positron/positronInterpreterDropdown.ts b/test/automation/src/positron/positronInterpreterDropdown.ts index b77f265dbf6..fc28498b9c2 100644 --- a/test/automation/src/positron/positronInterpreterDropdown.ts +++ b/test/automation/src/positron/positronInterpreterDropdown.ts @@ -117,7 +117,7 @@ export class PositronInterpreterDropdown { await showAllVersionsButton.click(); // Wait for the secondary interpreters to load - await this.code.waitForElements('.secondary-interpreter', false); + await expect(this.code.driver.page.locator('.secondary-interpreter')).toBeVisible(); return await this.interpreterGroups .locator('.secondary-interpreter') .all(); diff --git a/test/automation/src/positron/positronNewProjectWizard.ts b/test/automation/src/positron/positronNewProjectWizard.ts index 3334191f84c..a292af44b77 100644 --- a/test/automation/src/positron/positronNewProjectWizard.ts +++ b/test/automation/src/positron/positronNewProjectWizard.ts @@ -210,7 +210,7 @@ class ProjectWizardPythonConfigurationStep { // Try to find the env provider in the dropdown try { - await this.code.waitForElement(PROJECT_WIZARD_DROPDOWN_POPUP_ITEMS); + await expect(this.code.driver.page.locator(PROJECT_WIZARD_DROPDOWN_POPUP_ITEMS).first()).toBeVisible(); await this.code.driver .page.locator( `${PROJECT_WIZARD_DROPDOWN_POPUP_ITEMS} div.dropdown-entry-title` @@ -258,7 +258,7 @@ class ProjectWizardPythonConfigurationStep { // Try to find the interpreterPath in the dropdown and click the entry if found try { - await this.code.waitForElement(PROJECT_WIZARD_DROPDOWN_POPUP_ITEMS); + await expect(this.code.driver.page.locator(PROJECT_WIZARD_DROPDOWN_POPUP_ITEMS)).toBeVisible(); } catch (error) { throw new Error( `Wait for element ${PROJECT_WIZARD_DROPDOWN_POPUP_ITEMS} failed: ${error}` diff --git a/test/automation/src/positron/positronNotebooks.ts b/test/automation/src/positron/positronNotebooks.ts index e57a887519a..48125c034f4 100644 --- a/test/automation/src/positron/positronNotebooks.ts +++ b/test/automation/src/positron/positronNotebooks.ts @@ -66,7 +66,7 @@ export class PositronNotebooks { await this.quickaccess.openFileQuickAccessAndWait(basename(path), 1); await this.quickinput.selectQuickInputElement(0); - await this.code.waitForElement(ACTIVE_ROW_SELECTOR); + await expect(this.code.driver.page.locator(ACTIVE_ROW_SELECTOR)).toBeVisible(); await this.focusFirstCell(); } diff --git a/test/automation/src/positron/positronOutline.ts b/test/automation/src/positron/positronOutline.ts index 32581bfe91a..c8687cda09a 100644 --- a/test/automation/src/positron/positronOutline.ts +++ b/test/automation/src/positron/positronOutline.ts @@ -42,13 +42,15 @@ export class PositronOutline { fail('Bounding box not found'); } - const outllineElements = await this.code.waitForElements(OUTLINE_ELEMENT, false); + const outllineElements = await this.code.driver.page.locator(OUTLINE_ELEMENT).all(); const outlineData: string[] = []; for (let i = 0; i < outllineElements.length; i++) { const element = outllineElements[i]; - const text = element.textContent; - outlineData.push(text); + const text = await element.textContent(); + if (text !== null) { + outlineData.push(text); + } } return outlineData; diff --git a/test/automation/src/positron/positronPopups.ts b/test/automation/src/positron/positronPopups.ts index 3aa93e13911..1ee7d601a2c 100644 --- a/test/automation/src/positron/positronPopups.ts +++ b/test/automation/src/positron/positronPopups.ts @@ -25,7 +25,7 @@ export class PositronPopups { async popupCurrentlyOpen() { try { - await this.code.waitForElement(POSITRON_MODAL_DIALOG_BOX, undefined, 50); + await expect(this.code.driver.page.locator(POSITRON_MODAL_DIALOG_BOX)).toBeVisible(); return true; } catch (error) { this.code.logger.log('No modal dialog box found'); @@ -37,7 +37,7 @@ export class PositronPopups { try { this.code.logger.log('Checking for modal dialog box'); // fail fast if the modal is not present - await this.code.waitForElement(POSITRON_MODAL_DIALOG_BOX, undefined, 50); + await expect(this.code.driver.page.locator(POSITRON_MODAL_DIALOG_BOX)).toBeVisible(); await this.code.driver.page.locator(POSITRON_MODAL_DIALOG_BOX_OK).click(); this.code.logger.log('Installing ipykernel'); await this.waitForToastToAppear(); diff --git a/test/automation/src/positron/positronQuickaccess.ts b/test/automation/src/positron/positronQuickaccess.ts index 8d2f680225f..5ea6e764652 100644 --- a/test/automation/src/positron/positronQuickaccess.ts +++ b/test/automation/src/positron/positronQuickaccess.ts @@ -3,11 +3,11 @@ * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. *--------------------------------------------------------------------------------------------*/ -import { Editors } from '../editors'; import { Code } from '../code'; import { basename, isAbsolute } from 'path'; import { PositronQuickInput } from './positronQuickInput'; import { expect } from '@playwright/test'; +import { PositronEditors } from './positronEditors'; enum QuickAccessKind { Files = 1, @@ -17,7 +17,7 @@ enum QuickAccessKind { export class PositronQuickAccess { - constructor(private code: Code, private editors: Editors, private quickInput: PositronQuickInput) { } + constructor(private code: Code, private editors: PositronEditors, private quickInput: PositronQuickInput) { } async openDataFile(path: string): Promise { if (!isAbsolute(path)) { diff --git a/test/automation/src/positron/positronVariables.ts b/test/automation/src/positron/positronVariables.ts index d47217a39ec..a7c89c3e176 100644 --- a/test/automation/src/positron/positronVariables.ts +++ b/test/automation/src/positron/positronVariables.ts @@ -13,7 +13,7 @@ interface FlatVariables { type: string; } -const VARIABLE_ITEMS = '.variable-item'; +const VARIABLE_ITEMS = '.variable-item:not(.disabled)'; const VARIABLE_NAMES = 'name-column'; const VARIABLE_DETAILS = 'details-column'; const CURRENT_VARIABLES_GROUP = '.variables-instance[style*="z-index: 1"]'; @@ -33,20 +33,26 @@ export class PositronVariables { async getFlatVariables(): Promise> { const variables = new Map(); - const variableItems = await this.code.waitForElements(VARIABLE_ITEMS, true); + await expect(this.code.driver.page.locator(VARIABLE_ITEMS).first()).toBeVisible(); + const variableItems = await this.code.driver.page.locator(VARIABLE_ITEMS).all(); for (const item of variableItems) { - const name = item.children.find(child => child.className === VARIABLE_NAMES)?.textContent; - const details = item.children.find(child => child.className === VARIABLE_DETAILS); + const nameElement = item.locator(`.${VARIABLE_NAMES}`).first(); + const detailsElement = item.locator(`.${VARIABLE_DETAILS}`).first(); - const value = details?.children[0].textContent; - const type = details?.children[1].textContent; + const name = await nameElement.textContent(); + const value = detailsElement + ? await detailsElement.locator(':scope > *').nth(0).textContent() + : null; + const type = detailsElement + ? await detailsElement.locator(':scope > *').nth(1).textContent() + : null; if (!name || !value || !type) { throw new Error('Could not parse variable item'); } - variables.set(name, { value, type }); + variables.set(name.trim(), { value: value.trim(), type: type.trim() }); } return variables; } diff --git a/test/automation/src/workbench.ts b/test/automation/src/workbench.ts index 037cf22f626..6679f57caa6 100644 --- a/test/automation/src/workbench.ts +++ b/test/automation/src/workbench.ts @@ -138,7 +138,8 @@ export class Workbench { this.positronTopActionBar = new PositronTopActionBar(code); this.positronLayouts = new PositronLayouts(code, this); this.positronQuickInput = new PositronQuickInput(code); - this.positronQuickaccess = new PositronQuickAccess(code, this.editors, this.positronQuickInput); + this.positronEditors = new PositronEditors(code); + this.positronQuickaccess = new PositronQuickAccess(code, this.positronEditors, this.positronQuickInput); this.positronConnections = new PositronConnections(code, this.positronQuickaccess); this.positronNewProjectWizard = new PositronNewProjectWizard(code, this.positronQuickaccess); this.positronOutput = new PositronOutput(code, this.positronQuickaccess, this.positronQuickInput); @@ -152,7 +153,6 @@ export class Workbench { this.positronOutline = new PositronOutline(code, this.positronQuickaccess); this.positronClipboard = new PositronClipboard(code); this.positronExtensions = new PositronExtensions(code, this.positronQuickaccess); - this.positronEditors = new PositronEditors(code); // --- End Positron --- } } diff --git a/test/e2e/areas/data-explorer/helpers/100x100.ts b/test/e2e/areas/data-explorer/helpers/100x100.ts index ca62399d6f7..f50fa40292b 100644 --- a/test/e2e/areas/data-explorer/helpers/100x100.ts +++ b/test/e2e/areas/data-explorer/helpers/100x100.ts @@ -69,11 +69,12 @@ export const testDataExplorer = async ( const row = tsvValues[rowIndex]; for (let columnIndex = 0; columnIndex < row.length; columnIndex++) { // Get the cell. - const cell = await app.code.waitForElement(`#data-grid-row-cell-content-${columnIndex}-${rowIndex} .text-container .text-value`); + const cellLocator = app.code.driver.page.locator(`#data-grid-row-cell-content-${columnIndex}-${rowIndex} .text-container .text-value`); + await expect(cellLocator).toBeVisible(); // Get the cell value and test value. const secsRemover = (value: string) => value.replace(/^(.*)( secs)$/, '$1'); - const cellValue = secsRemover(cell.textContent); + const cellValue = secsRemover((await cellLocator.textContent()) || ''); const testValue = secsRemover(row[columnIndex]); // If the test value is a number, perform a numerical "close enough" comparison; @@ -83,7 +84,7 @@ export const testDataExplorer = async ( Math.abs(Number.parseFloat(cellValue) - Number.parseFloat(testValue)) ).toBeLessThan(0.05); } else { - expect(cell.textContent, `${rowIndex},${columnIndex}`).toStrictEqual(row[columnIndex]); + expect(await cellLocator.textContent(), `${rowIndex},${columnIndex}`).toStrictEqual(row[columnIndex]); } // Move to the next cell. diff --git a/test/e2e/areas/help/help.test.ts b/test/e2e/areas/help/help.test.ts index a86d2469fc6..0958a8d1fb0 100644 --- a/test/e2e/areas/help/help.test.ts +++ b/test/e2e/areas/help/help.test.ts @@ -11,6 +11,12 @@ test.use({ test.describe('Help', { tag: [tags.HELP] }, () => { + test.beforeAll(async function ({ userSettings }) { + // Enable reduced motion so we don't have to wait for animations of expanding + // and collapsing the panel. + await userSettings.set([['workbench.reduceMotion', '"on"']]); + }); + test('Python - Verifies basic help functionality [C633814]', { tag: [tags.WIN] }, async function ({ app, python }) { await app.workbench.positronConsole.executeCode('Python', `?load`, '>>>'); @@ -43,10 +49,6 @@ test.describe('Help', { tag: [tags.HELP] }, () => { // a small margin of error. const sizePrecision = 5; - // Enable reduced motion so we don't have to wait for animations of expanding - // and collapsing the panel. - await app.workbench.settingsEditor.addUserSetting('workbench.reduceMotion', '"on"'); - // Enter layout with help pane docked in session panel await app.workbench.positronLayouts.enterLayout('dockedHelp');