diff --git a/test/automation/src/index.ts b/test/automation/src/index.ts index fbbd96b1e88..5560b4386e8 100644 --- a/test/automation/src/index.ts +++ b/test/automation/src/index.ts @@ -52,5 +52,7 @@ export * from './positron/positronEditor'; export * from './positron/positronTestExplorer'; export * from './positron/positronExplorer'; export * from './positron/utils/positronAWSUtils'; +export * from './positron/positronQuickaccess'; +export * from './positron/positronOutline'; // --- End Positron --- export { getDevElectronPath, getBuildElectronPath, getBuildVersion } from './electron'; diff --git a/test/automation/src/positron/positronDataExplorer.ts b/test/automation/src/positron/positronDataExplorer.ts index 2a8d056daf7..8e3f9e09678 100644 --- a/test/automation/src/positron/positronDataExplorer.ts +++ b/test/automation/src/positron/positronDataExplorer.ts @@ -56,7 +56,7 @@ export class PositronDataExplorer { // unreliable: //await this.code.waitForElement(IDLE_STATUS); - await this.code.driver.getLocator(IDLE_STATUS).waitFor({ state: 'visible', timeout: 30000 }); + await this.code.driver.getLocator(IDLE_STATUS).waitFor({ state: 'visible', timeout: 60000 }); // we have seen intermittent failures where the data explorer is not fully loaded // even though the status bar is idle. This wait is to ensure the data explorer is fully loaded diff --git a/test/automation/src/positron/positronOutline.ts b/test/automation/src/positron/positronOutline.ts new file mode 100644 index 00000000000..0ae5c8b19ca --- /dev/null +++ b/test/automation/src/positron/positronOutline.ts @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2024 Posit Software, PBC. All rights reserved. + * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. + *--------------------------------------------------------------------------------------------*/ + + +import { fail } from 'assert'; +import { Code } from '../code'; +import { QuickAccess } from '../quickaccess'; + +const HORIZONTAL_SASH = '.explorer-viewlet .monaco-sash.horizontal'; +const FOCUS_OUTLINE_COMMAND = 'outline.focus'; +const OUTLINE_ELEMENT = '.outline-element'; + +/* + * Reuseable Positron outline functionality for tests to leverage. + */ +export class PositronOutline { + + constructor(private code: Code, private quickaccess: QuickAccess) { } + + async getOutlineData(): Promise { + + await this.quickaccess.runCommand(FOCUS_OUTLINE_COMMAND); + + const sashLocator = this.code.driver.page.locator(HORIZONTAL_SASH).nth(1); + const sashBoundingBox = await sashLocator.boundingBox(); + + if (sashBoundingBox) { + + await this.code.driver.clickAndDrag({ + from: { + x: sashBoundingBox.x + 10, + y: sashBoundingBox.y + }, + to: { + x: sashBoundingBox.x + 10, + y: sashBoundingBox.y - 150 + } + }); + } else { + fail('Bounding box not found'); + } + + const outllineElements = await this.code.waitForElements(OUTLINE_ELEMENT, false); + + const outlineData: string[] = []; + for (let i = 0; i < outllineElements.length; i++) { + const element = outllineElements[i]; + const text = element.textContent; + outlineData.push(text); + } + + return outlineData; + } + +} diff --git a/test/automation/src/workbench.ts b/test/automation/src/workbench.ts index ccb832acf50..10684dbfb35 100644 --- a/test/automation/src/workbench.ts +++ b/test/automation/src/workbench.ts @@ -45,6 +45,7 @@ import { PositronViewer } from './positron/positronViewer'; import { PositronEditor } from './positron/positronEditor'; import { PositronTestExplorer } from './positron/positronTestExplorer'; import { PositronQuickAccess } from './positron/positronQuickaccess'; +import { PositronOutline } from './positron/positronOutline'; // --- End Positron --- export interface Commands { @@ -94,6 +95,7 @@ export class Workbench { readonly positronEditor: PositronEditor; readonly positronTestExplorer: PositronTestExplorer; readonly positronQuickaccess: PositronQuickAccess; + readonly positronOutline: PositronOutline; // --- End Positron --- constructor(code: Code) { @@ -138,6 +140,7 @@ export class Workbench { this.positronEditor = new PositronEditor(code); this.positronTestExplorer = new PositronTestExplorer(code); this.positronQuickaccess = new PositronQuickAccess(this.quickinput, this.quickaccess); + this.positronOutline = new PositronOutline(code, this.quickaccess); // --- End Positron --- } } diff --git a/test/smoke/src/areas/positron/outline/outline.test.ts b/test/smoke/src/areas/positron/outline/outline.test.ts new file mode 100644 index 00000000000..51b66ae33b3 --- /dev/null +++ b/test/smoke/src/areas/positron/outline/outline.test.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2024 Posit Software, PBC. All rights reserved. + * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. + *--------------------------------------------------------------------------------------------*/ + + +import { join } from 'path'; +import { Application, PositronPythonFixtures, PositronRFixtures } from '../../../../../automation'; +import { setupAndStartApp } from '../../../test-runner/test-hooks'; + + +describe('Outline #web #win', () => { + setupAndStartApp(); + + describe('Outline Test - Python', () => { + before(async function () { + await PositronPythonFixtures.SetupFixtures(this.app as Application); + }); + + it('Python - Verify Outline Contents [C956870]', async function () { + const app = this.app as Application; + await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'workspaces', 'chinook-db-py', 'chinook-sqlite.py')); + + const outlineData = await app.workbench.positronOutline.getOutlineData(); + + const expected = [ + 'data_file_pathdata_file_path = os.path.join(os.getcwd(), \'data-files\', \'chinook\', \'chinook.db\')', + 'connconn = sqlite3.connect(data_file_path)', + 'curcur = conn.cursor()', + 'rowsrows = cur.fetchall()', + 'dfdf = pd.DataFrame(rows)' + ]; + + const missingFromUI = expected.filter(item => !outlineData.includes(item)); + + if (missingFromUI.length > 0) { + console.log(`Missing from UI: ${missingFromUI}`); + } + }); + }); + + + + describe('Outline Test - R', () => { + before(async function () { + await PositronRFixtures.SetupFixtures(this.app as Application); + }); + + it('R - Verify Outline Contents [C956871]', async function () { + const app = this.app as Application; + await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'workspaces', 'chinook-db-r', 'chinook-sqlite.r')); + + const outlineData = await app.workbench.positronOutline.getOutlineData(); + + const expected = [ + 'con', + 'albums', + 'df', + ]; + + const missingFromUI = expected.filter(item => !outlineData.includes(item)); + + if (missingFromUI.length > 0) { + console.log(`Missing from UI: ${missingFromUI}`); + } + }); + }); +}); + +