Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the test name.
Correct one: StartWorkspaceUsingIntellijIdeaEditor.

Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/** *******************************************************************
* copyright (c) 2026 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor';
import fs from 'fs';
import path from 'path';
import YAML from 'yaml';
import { e2eContainer } from '../../configs/inversify.config';
import { CLASSES } from '../../configs/inversify.types';
import { LoginTests } from '../../tests-library/LoginTests';
import { Dashboard } from '../../pageobjects/dashboard/Dashboard';
import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil';
import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests';
import { expect } from 'chai';
import { Logger } from '../../utils/Logger';
import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS';

suite('Check Intellij IDE desktop Editor with all samples', function (): void {
this.timeout(24000000);
const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
const pathToSampleFile: string = path.resolve('resources/default-devfile.yaml');
const workspaceName: string = YAML.parse(fs.readFileSync(pathToSampleFile, 'utf8')).metadata.name;
const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get(
CLASSES.KubernetesCommandLineToolsExecutor
);
kubernetesCommandLineToolsExecutor.workspaceName = workspaceName;
const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil);

const titlexPath: string = '/html/body/h1';
Copy link
Contributor

@dmytro-ndp dmytro-ndp Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XPath '/html/body/h1' of the title looks too common, as it doesn't contain any workspace- or editor-specific information to distinguish it from other regular HTML page.

What do you think about an XPath which checks for the presence of HTML code like h1>Workspace (workspace name) is running</h1>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your point. IMHO I dont see a reason to change it as this XPath is not actually a check. Check for correct text is here: https://github.com/eclipse-che/che/pull/23765/changes#diff-732c71179bfd939d6b555b70a9ce4b4f28264ba1f6bedc94a9b2756d48a2fe42R118

let currentTabHandle: string = 'undefined';

const pollingForCheckTitle: number = 500;

const editorsForCheck: string[] = [
'//*[@id="editor-selector-card-che-incubator/che-clion-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-goland-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-idea-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-phpstorm-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-pycharm-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-rider-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-rubymine-server/latest"]',
'//*[@id="editor-selector-card-che-incubator/che-webstorm-server/latest"]'
];

const samplesForCheck: string[] = [
'Empty Workspace',
'JBoss EAP 8.0',
'Java Lombok',
'Node.js Express',
'Python',
'Quarkus REST API',
'.NET',
'Ansible',
'C/C++',
'Go',
'PHP'
];

const gitRepoUrlsToCheck: string[] = [
'https://github.com/crw-qe/quarkus-api-example-public/tree/ubi8-latest',
'https://github.com/crw-qe/ubi9-based-sample-public/tree/ubi9-minimal'
];

const gitRepoUrlsToCheckAirgap: string[] = [
'https://gh.crw-qe.com/test-automation-only/ubi8/tree/ubi8-latest',
'https://gh.crw-qe.com/test-automation-only/ubi9-based-sample-public/tree/ubi9-minimal'
];

function clearCurrentTabHandle(): void {
currentTabHandle = 'undefined';
}

async function deleteWorkspace(): Promise<void> {
await browserTabsUtil.switchToWindow(currentTabHandle);
await dashboard.openDashboard();
await browserTabsUtil.closeAllTabsExceptCurrent();
await dashboard.stopAndRemoveWorkspaceByUI(WorkspaceHandlingTests.getWorkspaceName());

WorkspaceHandlingTests.clearWorkspaceName();
clearCurrentTabHandle();
}

suiteSetup('Login into Che', async function (): Promise<void> {
await loginTests.loginIntoChe();
});

async function testWorkspaceStartup(editorXpath: string, sampleNameOrUrl: string, isUrl: boolean): Promise<void> {
await dashboard.openDashboard();
currentTabHandle = await browserTabsUtil.getCurrentWindowHandle();

if (isUrl) {
await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndGitUrl(
editorXpath,
sampleNameOrUrl,
titlexPath,
pollingForCheckTitle
);
} else {
await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndSample(
editorXpath,
sampleNameOrUrl,
titlexPath,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

titleXpath is more readable, IMHO

pollingForCheckTitle
);
}

// check title
const headerText: string = await workspaceHandlingTests.getTextFromUIElementByXpath(titlexPath);
expect('Workspace ' + WorkspaceHandlingTests.getWorkspaceName() + ' is running').equal(headerText);

await deleteWorkspace();
}

test('Test start of Intellij IDE with default Samples', async function (): Promise<void> {
Copy link
Contributor

@dmytro-ndp dmytro-ndp Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please write a separate test for each sample to provide a clear error message about which particular sample failed to start?

It is probably possible to do this by enclosing the test() call inside a for-each loop which iterates through the samplesForCheck array.

for (const editorXpath of editorsForCheck) {
for (const sampleName of samplesForCheck) {
await testWorkspaceStartup(editorXpath, sampleName, false);
}
}
});

test('Test start of Intellij IDE (SSH) with ubi', async function (): Promise<void> {
Copy link
Contributor

@dmytro-ndp dmytro-ndp Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please write a separate test for ubi8-latest and ubi9-latest to provide a clear error message about which particular Git URL failed to start?

It is probably possible to do this by enclosing the test() call inside a for-each loop which iterates through the gitRepoUrlsToCheck array.

for (const editorXpath of editorsForCheck) {
if (BASE_TEST_CONSTANTS.IS_CLUSTER_DISCONNECTED()) {
Logger.info('Test cluster is disconnected. Using url for airgap cluster.');
for (const url of gitRepoUrlsToCheckAirgap) {
await testWorkspaceStartup(editorXpath, url, true);
}
} else {
for (const url of gitRepoUrlsToCheck) {
await testWorkspaceStartup(editorXpath, url, true);
}
}
}
});

suiteTeardown('Delete DevWorkspace', async function (): Promise<void> {
Logger.info('Deleting DevWorkspace... After all.');
if (currentTabHandle !== 'undefined') {
await browserTabsUtil.switchToWindow(currentTabHandle);
}

await dashboard.openDashboard();
await browserTabsUtil.closeAllTabsExceptCurrent();

if (WorkspaceHandlingTests.getWorkspaceName() !== 'undefined') {
await dashboard.deleteStoppedWorkspaceByUI(WorkspaceHandlingTests.getWorkspaceName());
}
});
});
22 changes: 16 additions & 6 deletions tests/e2e/tests-library/WorkspaceHandlingTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,28 @@ export class WorkspaceHandlingTests {
Logger.info('Start workspace progress description: ' + alertDescription);
}

async createAndOpenWorkspaceWithSpecificEditorAndSample(editor: string, sampleName: string, xPath: string): Promise<void> {
async createAndOpenWorkspaceWithSpecificEditorAndSample(
editor: string,
sampleName: string,
xPath: string,
polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT
): Promise<void> {
Logger.debug('Create and open workspace with specific Editor and Sample. Sample ' + editor);
await this.selectEditor(editor);
await this.createWorkspace.clickOnSampleNoEditorSelection(sampleName);
await this.waitForControlXpath(xPath);
await this.waitForControlXpath(xPath, polling);
}

async createAndOpenWorkspaceWithSpecificEditorAndGitUrl(editor: string, sampleUrl: string, xPath: string): Promise<void> {
async createAndOpenWorkspaceWithSpecificEditorAndGitUrl(
editor: string,
sampleUrl: string,
xPath: string,
polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT
): Promise<void> {
Logger.debug('Create and open workspace with specific Editor and URL. Sample ' + editor);
await this.selectEditor(editor);
await this.createWorkspace.importFromGitUsingUI(sampleUrl);
await this.waitForControlXpath(xPath);
await this.waitForControlXpath(xPath, polling);
}

async selectEditor(editor: string): Promise<void> {
Expand All @@ -175,11 +185,11 @@ export class WorkspaceHandlingTests {
return await this.driverHelper.getDriver().findElement(By.xpath(xpath)).getText();
}

private async waitForControlXpath(xPathToWait: string): Promise<void> {
private async waitForControlXpath(xPathToWait: string, polling: number): Promise<void> {
await this.browserTabsUtil.waitAndSwitchToAnotherWindow(WorkspaceHandlingTests.parentGUID, TIMEOUT_CONSTANTS.TS_IDE_LOAD_TIMEOUT);
await this.obtainWorkspaceNameFromStartingPage();

await this.driverHelper.waitVisibility(By.xpath(xPathToWait), TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT);
await this.driverHelper.waitVisibility(By.xpath(xPathToWait), TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT, polling);
}

private async getWorkspaceAlertDescription(): Promise<string> {
Expand Down
7 changes: 5 additions & 2 deletions tests/e2e/utils/DriverHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,11 @@ export class DriverHelper {
return false;
}

async waitVisibility(elementLocator: By, timeout: number = TIMEOUT_CONSTANTS.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
const polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_DEFAULT_POLLING;
async waitVisibility(
elementLocator: By,
timeout: number = TIMEOUT_CONSTANTS.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM,
polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_DEFAULT_POLLING
): Promise<WebElement> {
const attempts: number = Math.ceil(timeout / polling);
Logger.trace(`${elementLocator}`);

Expand Down