Skip to content

Commit

Permalink
e2e-test: simplify interpreter fixtures (#5949)
Browse files Browse the repository at this point in the history
### Summary
Per my previous PR #5946 there
is now a lot of overlap between the R/Python fixtures and interpreter
POM.
* Removed R/Python fixtures
* Moved interpreter POM to Fixtures


### QA Notes
✅ ran [full
suite](https://github.com/posit-dev/positron/actions/runs/12714065066)
  • Loading branch information
midleman authored Jan 10, 2025
1 parent 45ac6c1 commit 14bff09
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
*--------------------------------------------------------------------------------------------*/

import test, { expect, Locator } from '@playwright/test';
import { Code, Console } from '../infra';
import { Console } from '../../pages/console';
import { Code } from '../code';

const INTERPRETER_INFO_LINE = '.info .container .line';
const INTERPRETER_ACTIONS_SELECTOR = `.interpreter-actions .action-button`;
const DESIRED_PYTHON = process.env.POSITRON_PY_VER_SEL;
const DESIRED_R = process.env.POSITRON_R_VER_SEL;

export enum InterpreterType {
Python = 'Python',
Expand All @@ -31,15 +34,45 @@ export class Interpreter {

// --- Actions ---

/**
* Action: Start an interpreter via the Quick Access bar.
* @param interpreterType The type of the interpreter to start.
* @param waitForReady Wait for the interpreter to be ready after starting.
*/
startInterpreterViaQuickAccess = async (interpreterType: 'Python' | 'R', waitForReady = true) => {
if (!DESIRED_PYTHON || !DESIRED_R) {
throw new Error('Please set env vars: POSITRON_PYTHON_VER_SEL, POSITRON_R_VER_SEL');
}

await test.step(`Select interpreter via Quick Access: ${interpreterType}`, async () => {
interpreterType === 'Python'
? await this.console.selectInterpreter(InterpreterType.Python, DESIRED_PYTHON)
: await this.console.selectInterpreter(InterpreterType.R, DESIRED_R);

if (waitForReady) {
interpreterType === 'Python'
? await this.console.waitForReady('>>>', 30000)
: await this.console.waitForReady('>', 30000);
}
});
};

/**
* Action: Select an interpreter from the dropdown by the interpreter type and a descriptive string.
* The interpreter type could be 'Python', 'R', etc.
* The string could be 'Python 3.10.4 (Pyenv)', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
* @param interpreterType The type of the interpreter to select.
* @param description The descriptive string of the interpreter to select.
* @param description Description of interpreter to select: 'Python', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
* @param waitForReady Wait for the interpreter to be ready after selecting.
*/
async selectInterpreter(interpreterType: 'Python' | 'R', interpreterDescription: string, waitForInterpreterReady = true) {
await test.step(`Select interpreter: ${interpreterDescription}`, async () => {
async selectInterpreter(
interpreterType: 'Python' | 'R',
interpreterDescription = interpreterType === 'Python' ? DESIRED_PYTHON : DESIRED_R,
waitForReady = true
) {
if (!DESIRED_PYTHON || !DESIRED_R) {
throw new Error('Please set env vars: POSITRON_PYTHON_VER_SEL, POSITRON_R_VER_SEL');
}

await test.step(`Select interpreter via UI: ${interpreterDescription}`, async () => {
await this.openInterpreterDropdown();

const selectedPrimaryInterpreter = this.primaryInterpreter.filter({ hasText: interpreterDescription });
Expand All @@ -58,7 +91,7 @@ export class Interpreter {
await secondaryInterpreterOption.click();
}

if (waitForInterpreterReady) {
if (waitForReady) {
interpreterType === 'Python'
? await this.console.waitForReady('>>>', 30000)
: await this.console.waitForReady('>', 30000);
Expand All @@ -68,8 +101,7 @@ export class Interpreter {

/**
* Action: Restart the primary interpreter
* The interpreter type could be 'Python', 'R', etc.
* The string could be 'Python 3.10.4 (Pyenv)', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
* @param description The description of interpreter to restart: 'Python', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
*/
async restartPrimaryInterpreter(description: string | InterpreterType) {
await test.step(`Restart interpreter: ${description}`, async () => {
Expand All @@ -90,8 +122,7 @@ export class Interpreter {

/**
* Action: Stop the primary interpreter
* The interpreter type could be 'Python', 'R', etc.
* The string could be 'Python 3.10.4 (Pyenv)', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
* @param description The description of interpreter to stop: 'Python', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
*/
async stopPrimaryInterpreter(description: string | InterpreterType, waitForInterpreterShutdown = true) {
await test.step(`Stop interpreter: ${description}`, async () => {
Expand Down Expand Up @@ -173,8 +204,7 @@ export class Interpreter {

/**
* Helper: Get the primary interpreter element by a descriptive string or interpreter type.
* The string could be 'Python 3.10.4 (Pyenv)', 'R 4.4.0', '/opt/homebrew/bin/python3', etc.
* @param descriptionOrType The descriptive string of the interpreter to get.
* @param descriptionOrType The descriptive string or interpreter type to filter the primary interpreter by.
* @returns The primary interpreter element
*/
private async getPrimaryInterpreterElement(descriptionOrType: string | InterpreterType) {
Expand All @@ -189,7 +219,6 @@ export class Interpreter {

/**
* Helper: Get the interpreter name from the interpreter element.
* Examples: 'Python 3.10.4 (Pyenv)', 'R 4.4.0'.
* @param interpreterLocator The locator for the interpreter element.
*/
private async getInterpreterName(interpreterLocator: Locator) {
Expand Down
57 changes: 0 additions & 57 deletions test/e2e/infra/fixtures/python.ts

This file was deleted.

43 changes: 0 additions & 43 deletions test/e2e/infra/fixtures/r.ts

This file was deleted.

4 changes: 1 addition & 3 deletions test/e2e/infra/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export * from './workbench';
// pages
export * from '../pages/console';
export * from '../pages/popups';
export * from '../pages/interpreter';
export * from '../pages/variables';
export * from '../pages/dataExplorer';
export * from '../pages/sideBar';
Expand All @@ -38,9 +37,8 @@ export * from '../pages/editors';
export * from '../pages/settings';

// fixtures
export * from './fixtures/python';
export * from './fixtures/r';
export * from './fixtures/userSettings';
export * from './fixtures/interpreter';

// test-runner
export * from './test-runner';
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/infra/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { Code } from './code';
import { Interpreter } from '../pages/interpreter';
import { Interpreter } from '../infra/fixtures/interpreter';
import { Popups } from '../pages/popups';
import { Console } from '../pages/console';
import { Variables } from '../pages/variables';
Expand Down
10 changes: 7 additions & 3 deletions test/e2e/pages/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ export class Console {
async selectInterpreter(desiredInterpreterType: InterpreterType, desiredInterpreterString: string, waitForReady: boolean = true): Promise<undefined> {

// don't try to start a new interpreter if one is currently starting up
if (waitForReady) {
await this.waitForReadyOrNoInterpreter();
}
await this.waitForReadyOrNoInterpreter();

let command: string;
if (desiredInterpreterType === InterpreterType.Python) {
Expand All @@ -70,6 +68,12 @@ export class Console {
// may include additional items above the desired interpreter string.
await this.quickinput.selectQuickInputElementContaining(desiredInterpreterString);
await this.quickinput.waitForQuickInputClosed();

if (waitForReady) {
desiredInterpreterType === InterpreterType.Python
? await this.waitForReady('>>>', 40000)
: await this.waitForReady('>', 40000);
}
return;
}

Expand Down
14 changes: 6 additions & 8 deletions test/e2e/tests/_test.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { randomUUID } from 'crypto';
import archiver from 'archiver';

// Local imports
import { Application, Logger, PythonFixtures, RFixtures, UserSetting, UserSettingsFixtures, createLogger, createApp, TestTags } from '../infra';
import { Application, Logger, UserSetting, UserSettingsFixtures, createLogger, createApp, TestTags } from '../infra';
import { PackageManager } from '../pages/utils/packageManager';

// Constants
Expand Down Expand Up @@ -109,15 +109,13 @@ export const test = base.extend<TestFixtures, WorkerFixtures>({
}, { scope: 'worker', auto: true, timeout: 60000 }],

interpreter: [async ({ app, page }, use) => {
const setInterpreter = async (interpreterName: 'Python' | 'R') => {
const setInterpreter = async (desiredInterpreter: 'Python' | 'R') => {
const currentInterpreter = await page.locator('.top-action-bar-interpreters-manager').textContent() || '';

if (!currentInterpreter.includes(interpreterName)) {
if (interpreterName === 'Python') {
await PythonFixtures.SetupFixtures(app, false);
} else if (interpreterName === 'R') {
await RFixtures.SetupFixtures(app, false);
}
if (!currentInterpreter.startsWith(desiredInterpreter)) {
desiredInterpreter === 'Python'
? await app.workbench.interpreter.startInterpreterViaQuickAccess('Python')
: await app.workbench.interpreter.startInterpreterViaQuickAccess('R');
}
};

Expand Down

0 comments on commit 14bff09

Please sign in to comment.