Skip to content

Commit

Permalink
Adding start dev/stop dev UI test
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas Grossmann authored and vrubezhny committed Aug 17, 2024
1 parent 44ebc51 commit 5a39c83
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 23 deletions.
1 change: 1 addition & 0 deletions test/ui/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const MENUS = {
deleteProject: 'Delete Project',
bindService: 'Bind Service',
startDev: 'Start Dev',
stopDev: 'Stop Dev',
};

export const COMPONENTS = {
Expand Down
98 changes: 98 additions & 0 deletions test/ui/common/ui/webviewView/openshiftTerminalWebviewView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*-----------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/
import { By, Key, WebElement, WebviewView } from 'vscode-extension-tester';
import { WebviewViewForm } from './webviewViewForm';

export class OpenshiftTerminalWebviewView extends WebviewViewForm {

public constructor() {
super();
}

public async getTerminalText(): Promise<string> {
const copyKeys = [`${Key.CONTROL}${Key.SHIFT}a`,`${Key.CONTROL}${Key.SHIFT}c`]
await this.sendKeysToTerminal(copyKeys);
const cb = await import('clipboardy');
return await cb.read();
}

public async getActiveTabName(): Promise<string> {
let text: string;
await this.enterWebviewView(async (webviewView) => {
const activeTab = await this.getActiveTab(webviewView);
text = await activeTab.getText();
})
return text;
}

public async closeTab(name: string): Promise<void> {
await this.enterWebviewView(async (webviewView) => {
const closeButton = await webviewView.findWebElement(By.xpath(
`//div[div[contains(text(),"${name}")]]//*[@data-testid="CloseIcon"]`
));
await closeButton.click();
})
}

public async closeActiveTab(): Promise<void> {
await this.enterWebviewView(async (webviewView) => {
await webviewView.findWebElement(By.xpath('//button[@aria-selected = "true"]//*[@data-testid = "TerminalIcon"]'));
});
}

public async closeAllInactiveTabs(): Promise<void> {
await this.enterWebviewView(async (webviewView) => {
const closeButtons = await webviewView.findWebElements(By.xpath('//button[@aria-selected = "false"]//*[@data-testid = "TerminalIcon"]'));
for (const button of closeButtons) {
await button.click();
}
})
}

public async switchToTab(name: string): Promise<void> {
await this.enterWebviewView(async (webviewView) => {
const tabs = await this.getTerminalTabs(webviewView);
for (const tab of tabs) {
const text = await tab.getText();
if (text === name) {
await tab.click();
}
}
});
}

public async sendKeysToTerminal(keys: string[]): Promise<void> {
await this.enterWebviewView(async (webviewView) => {
const terminal = await this.getTerminalInstance(webviewView);
await terminal.click();
for (const key of keys) {
await terminal.sendKeys(key);
}
});
}

public async isAnyTabOpened(): Promise<boolean> {
let tabs: WebElement[];
await this.enterWebviewView(async (webviewView) => {
tabs = await this.getTerminalTabs(webviewView);
});
return tabs.length > 0;
}

private async getActiveTab(webviewView: WebviewView): Promise<WebElement> {
return await webviewView.findWebElement(By.xpath('//button[@aria-selected = "true"]//div[*[name() = "svg"]]/div'))
}

private async getTerminalTabs(webviewView: WebviewView): Promise<WebElement[]> {
return await webviewView.findWebElements(By.xpath('//div[*[name() = "svg"]]/div'))
}

private async getTerminalInstance(webviewView: WebviewView): Promise<WebElement> {
return await webviewView.findWebElement(By.xpath('//textarea[@aria-label = "Terminal input"]'));
}



}
20 changes: 20 additions & 0 deletions test/ui/common/ui/webviewView/webviewViewForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*-----------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/
import { WebviewView } from 'vscode-extension-tester';

export abstract class WebviewViewForm {

public async enterWebviewView<T>(callbackFunction: (webviewView: WebviewView) => Promise<T>): Promise<T> {
const webviewView = new WebviewView();
await webviewView.switchToFrame();
let retValue: T;
try {
retValue = await callbackFunction(webviewView);
} finally {
await webviewView.switchBack();
}
return retValue;
}
}
2 changes: 2 additions & 0 deletions test/ui/public-ui-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { checkOpenshiftView } from './suite/openshift';
import { testCreateServerlessFunction } from './suite/serverlessFunction';

import * as sourceMapSupport from 'source-map-support';
import { testComponentContextMenu } from './suite/componentContextMenu';

sourceMapSupport.install();

Expand Down Expand Up @@ -45,6 +46,7 @@ describe('Extension public-facing UI tests', function() {
});

checkAboutCommand(clusterIsSet);
testComponentContextMenu();

//tests requiring clusters incoming
});
Expand Down
30 changes: 16 additions & 14 deletions test/ui/suite/command-about.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/

import { By, EditorView, Key, WebElement, WebviewView, Workbench } from 'vscode-extension-tester';
import { By, EditorView, WebviewView, Workbench } from 'vscode-extension-tester';
import { activateCommand } from '../common/command-activator';
import { expect } from 'chai';
import { OpenshiftTerminalWebviewView } from '../common/ui/webviewView/openshiftTerminalWebviewView';

export function checkAboutCommand(clusterIsSet: boolean) {
describe('About Command', () => {
Expand All @@ -15,41 +16,42 @@ export function checkAboutCommand(clusterIsSet: boolean) {
const clusterServer = 'https://127.0.0.1';

let webviewView: WebviewView;
let terminalInstance: WebElement;
let openshiftTerminal: OpenshiftTerminalWebviewView;

before(async () => {
await new EditorView().closeAllEditors();
await activateCommand(command);
});

it('New terminal opens', async function () {
after(async () => {
await openshiftTerminal.closeTab('Show odo Version');
});

it('New terminal opens', async function() {
this.timeout(60_000);
await new Promise((res) => setTimeout(res, 3_000));
await new Workbench().executeCommand(
'Openshift Terminal: Focus on OpenShift Terminal View',
);
webviewView = new WebviewView();
await webviewView.switchToFrame(6_500);
terminalInstance = await webviewView.findWebElement(
await webviewView.findWebElement(
By.xpath('//textarea[@aria-label = "Terminal input"]'),
);
await webviewView.switchBack();
});

it('Terminal shows according information', async function () {
it('Terminal shows according information', async function() {
this.timeout(60_000);
await terminalInstance.click();
openshiftTerminal = new OpenshiftTerminalWebviewView();

await terminalInstance.sendKeys(`${Key.CONTROL}${Key.SHIFT}a`);
await terminalInstance.sendKeys(`${Key.CONTROL}${Key.SHIFT}c`);
await webviewView.switchBack();
const terminalText = await openshiftTerminal.getTerminalText();

const cb = await import('clipboardy');
const clipboard = await cb.read();
expect(clipboard).to.contain(odoVersion);
expect(terminalText).to.contain(odoVersion)
if (!clusterIsSet) {
expect(clipboard).to.contain(noClusterMessage);
expect(terminalText).to.contain(noClusterMessage);
} else {
expect(clipboard).to.contain(clusterServer);
expect(terminalText).to.contain(clusterServer);
}
});
});
Expand Down
118 changes: 118 additions & 0 deletions test/ui/suite/componentContextMenu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*-----------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/

import {
ActivityBar,
EditorView,
Key,
SideBarView,
ViewItem,
ViewSection,
} from 'vscode-extension-tester';
import { collapse } from '../common/overdrives';
import { MENUS, VIEWS } from '../common/constants';
import { itemExists } from '../common/conditions';
import { OpenshiftTerminalWebviewView } from '../common/ui/webviewView/openshiftTerminalWebviewView';
import { expect } from 'chai';

export function testComponentContextMenu() {
describe('Component Context Menu', function() {
let view: SideBarView;
let section: ViewSection;
let component: ViewItem;
let openshiftTerminal: OpenshiftTerminalWebviewView;

const componentName = 'nodejs-starter';
const expectedTerminalName = `odo dev: ${componentName}`;

before(async function context() {
this.timeout(10_000);
await new EditorView().closeAllEditors();
view = await (await new ActivityBar().getViewControl(VIEWS.openshift)).openView();
for (const item of [
VIEWS.appExplorer,
VIEWS.compRegistries,
VIEWS.serverlessFunctions,
VIEWS.debugSessions,
]) {
await collapse(await view.getContent().getSection(item));
}

section = await view.getContent().getSection(VIEWS.components);
});

it('Start Dev works', async function() {
this.timeout(60_000)
//start dev
component = await itemExists(componentName, section);
const contextMenu = await component.openContextMenu();
await contextMenu.select(MENUS.startDev);

//check openshift terminal for tab name
openshiftTerminal = new OpenshiftTerminalWebviewView();
const terminalName = await openshiftTerminal.getActiveTabName();
expect(terminalName).to.contain(expectedTerminalName)

//decline odo telemetry
await openshiftTerminal.sendKeysToTerminal(['n', Key.ENTER])

//wait for start dev to finish
await itemExists(`${componentName} (dev starting)`, section);
await itemExists(`${componentName} (dev running)`, section, 30_000);

//check terminal content
const terminalText = await openshiftTerminal.getTerminalText();
expect(terminalText).to.contain(`Developing using the "${componentName}" Devfile`);
expect(terminalText).to.contain('Running on the cluster in Dev mode');
expect(terminalText).to.contain('Pod is Running');
expect(terminalText).to.contain('Waiting for the application to be ready');
expect(terminalText).to.contain('Keyboard Commands');
});

it('Stop Dev works', async function() {
this.timeout(80_000);

//stop dev
const contextMenu = await component.openContextMenu();
await contextMenu.select(MENUS.stopDev);

//wait for dev to stop
await itemExists(`${componentName} (dev stopping)`, section);
await itemExists(componentName, section, 60_000);

//check for terminal content
const terminalText = await openshiftTerminal.getTerminalText();
expect(terminalText).to.include('Finished executing the application');
expect(terminalText).to.include('Press any key to close this terminal');

//close tab and check
await openshiftTerminal.sendKeysToTerminal([Key.ENTER]);
expect(await openshiftTerminal.isAnyTabOpened()).to.be.false;
});

it('Stop Dev works by pressing Ctrl+c', async function() {
this.timeout(80_000)
//start dev
const contextMenu = await component.openContextMenu();
await contextMenu.select(MENUS.startDev);

//wait for start dev to finish
await itemExists(`${componentName} (dev starting)`, section);
await itemExists(`${componentName} (dev running)`, section, 30_000);

//stop dev
await openshiftTerminal.sendKeysToTerminal([`${Key.CONTROL}c`]);

//wait for stop dev to finish
await itemExists(`${componentName} (dev stopping)`, section);
await itemExists(componentName, section, 60_000);

//check for terminal content
const terminalText = await openshiftTerminal.getTerminalText();
expect(terminalText).to.include('Finished executing the application');
expect(terminalText).to.include('Press any key to close this terminal');
})
});
}
12 changes: 3 additions & 9 deletions test/ui/suite/createComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ export function testCreateComponent(path: string) {
//check if component is in component view
componentName = 'nodejs-starter';
expect(await section.findItem(componentName)).to.be.not.undefined;

dlt = false;
});

//Delete the component using file system
Expand All @@ -167,19 +169,11 @@ export function testCreateComponent(path: string) {
});

after(async function context() {
let prompt = await new Workbench().openCommandPrompt();
const prompt = await new Workbench().openCommandPrompt();
await prompt.setText('>Workspaces: Remove Folder From Workspace...');
await prompt.confirm();
await prompt.setText('node-js-runtime');
await prompt.confirm();
await new Promise((res) => {
setTimeout(res, 2_500);
});
prompt = await new Workbench().openCommandPrompt();
await prompt.setText('>Workspaces: Remove Folder From Workspace...');
await prompt.confirm();
await prompt.setText('nodejs-starter');
await prompt.confirm();
});

async function createComponent(createCompView: CreateComponentWebView): Promise<void> {
Expand Down

0 comments on commit 5a39c83

Please sign in to comment.