Skip to content

Commit

Permalink
E2E tests: MS terminal POM replacement (#5864)
Browse files Browse the repository at this point in the history
Putting terminal functions we use into positronTerminal

### QA Notes

All tests should pass.
  • Loading branch information
testlabauto authored Dec 30, 2024
1 parent 5f29675 commit 158abd1
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 15 deletions.
55 changes: 52 additions & 3 deletions test/automation/src/positron/positronTerminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

import { Locator } from '@playwright/test';
import { expect, Locator } from '@playwright/test';
import { Code } from '../code';
import { PositronQuickAccess } from './positronQuickaccess';

const TERMINAL_WRAPPER = '#terminal .terminal-wrapper';

export class PositronTerminal {
terminalTab: Locator;

constructor(private code: Code) {
constructor(private code: Code, private quickaccess: PositronQuickAccess) {
this.terminalTab = this.code.driver.page.getByRole('tab', { name: 'Terminal' }).locator('a');
}

Expand All @@ -18,7 +21,53 @@ export class PositronTerminal {
}

async clickTerminalTab() {
await this.clickTerminalTab();
await this.terminalTab.click();
}

async waitForTerminalText(terminalText: string) {

const terminalLines = this.code.driver.page.locator(TERMINAL_WRAPPER);
const matchingLines = terminalLines.filter({ hasText: terminalText });

await expect(matchingLines).toBeVisible();
}

async waitForTerminalLines() {

await expect(async () => {
const terminalLines = await this.code.driver.page.locator(TERMINAL_WRAPPER).all();
expect(terminalLines.length).toBeGreaterThan(0);
}).toPass();
}

async createTerminal(): Promise<void> {
await this.quickaccess.runCommand('workbench.action.terminal.new');
await this._waitForTerminal();
}

private async _waitForTerminal(): Promise<void> {
await this.code.waitForElement('.terminal.xterm.focus');
await this.waitForTerminalLines();
}

async runCommandInTerminal(commandText: string): Promise<void> {
await this.sendTextToTerminal(commandText);

await this.code.driver.page.keyboard.press('Enter');
}

async sendTextToTerminal(text: string) {
const consoleInput = this.code.driver.page.locator(TERMINAL_WRAPPER);

await expect(consoleInput).toBeVisible();

await consoleInput.evaluate(async (element, evalText) => {

const xterm = (element as any).xterm as (any | undefined);

if (xterm) {
xterm.input(evalText);
}
}, text);
}
}
2 changes: 1 addition & 1 deletion test/automation/src/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export class Workbench {
this.positronConsole = new PositronConsole(code, this.positronQuickaccess, this.positronQuickInput);
this.positronNotebooks = new PositronNotebooks(code, this.positronQuickInput, this.positronQuickaccess);
this.positronWelcome = new PositronWelcome(code);
this.positronTerminal = new PositronTerminal(code);
this.positronTerminal = new PositronTerminal(code, this.positronQuickaccess);
this.positronViewer = new PositronViewer(code);
this.positronEditor = new PositronEditor(code);
this.positronTestExplorer = new PositronTestExplorer(code);
Expand Down
2 changes: 0 additions & 2 deletions test/e2e/areas/apps/python-apps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ test.describe('Python Applications', {

await app.workbench.positronQuickaccess.runCommand('workbench.action.terminal.focus');
await app.workbench.positronTerminal.sendKeysToTerminal('Control+C');
// unreliable on ubuntu:
// await this.app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.includes('^C')));
await app.workbench.positronLayouts.enterLayout('fullSizedAuxBar');
await app.workbench.positronViewer.clearViewer();
});
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/areas/new-project-wizard/new-project-python.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ test.describe('Python - New Project Wizard', { tag: [tags.NEW_PROJECT_WIZARD] },
}).toPass({ timeout: 50000 });

// Git status should show that we're on the main branch
await app.workbench.terminal.createTerminal();
await app.workbench.terminal.runCommandInTerminal('git status');
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(e => e.includes('On branch main')));
await app.workbench.positronTerminal.createTerminal();
await app.workbench.positronTerminal.runCommandInTerminal('git status');
await app.workbench.positronTerminal.waitForTerminalText('On branch main');
});
});

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/areas/r-markdown/r-markdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test.describe('R Markdown', { tag: [tags.WEB, tags.R_MARKDOWN] }, () => {
// Using expect.toPass allows it to retry.
await expect(async () => {
await app.workbench.positronQuickaccess.runCommand('r.rmarkdownRender');
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.startsWith('Output created: basicRmd.html')));
await app.workbench.positronTerminal.waitForTerminalText('Output created: basicRmd.html');
}).toPass({ timeout: 80000 });

// Wrapped in expect.toPass to allow UI to update/render
Expand Down
11 changes: 6 additions & 5 deletions test/e2e/areas/r-pkg-development/r-pkg-development.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ test.describe('R Package Development', { tag: [tags.WEB, tags.R_PKG_DEVELOPMENT]
logger.log('Test R Package');
await app.workbench.positronQuickaccess.runCommand('r.packageTest');
await expect(async () => {
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.startsWith('[ FAIL 1 | WARN 0 | SKIP 0 | PASS 16 ]')));
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.includes('Terminal will be reused by tasks')));
await app.workbench.positronTerminal.waitForTerminalText('[ FAIL 1 | WARN 0 | SKIP 0 | PASS 16 ]');
await app.workbench.positronTerminal.waitForTerminalText('Terminal will be reused by tasks');
}).toPass({ timeout: 70000 });
});

Expand All @@ -53,15 +53,16 @@ test.describe('R Package Development', { tag: [tags.WEB, tags.R_PKG_DEVELOPMENT]
await app.workbench.positronQuickaccess.runCommand('workbench.action.terminal.clear');
await app.workbench.positronQuickaccess.runCommand('r.packageCheck');
await expect(async () => {
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.startsWith('Error: R CMD check found ERRORs')));
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.includes('Terminal will be reused by tasks')));
await app.workbench.positronTerminal.waitForTerminalText('Error: R CMD check found ERRORs');
await app.workbench.positronTerminal.waitForTerminalText('Terminal will be reused by tasks');
}).toPass({ timeout: 70000 });
});

await test.step('Install R Package and Restart R', async () => {
logger.log('Install R Package and Restart R');
await app.workbench.positronQuickaccess.runCommand('r.packageInstall');
await app.workbench.terminal.waitForTerminalText(buffer => buffer.some(line => line.startsWith('✔ Installed testfun 0.0.0.9000')));
// Appears very briefly and test misses it:
// await app.workbench.positronTerminal.waitForTerminalText('✔ Installed testfun 0.0.0.9000');

await app.workbench.positronConsole.waitForConsoleContents('restarted', { timeout: 30000 });
await app.workbench.positronConsole.waitForConsoleContents('library(testfun)');
Expand Down

0 comments on commit 158abd1

Please sign in to comment.