diff --git a/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingIntellijIdeEditor.spec.ts b/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingIntellijIdeEditor.spec.ts new file mode 100644 index 00000000000..b2429dd12e4 --- /dev/null +++ b/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingIntellijIdeEditor.spec.ts @@ -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'; + 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 { + 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 { + await loginTests.loginIntoChe(); + }); + + async function testWorkspaceStartup(editorXpath: string, sampleNameOrUrl: string, isUrl: boolean): Promise { + await dashboard.openDashboard(); + currentTabHandle = await browserTabsUtil.getCurrentWindowHandle(); + + if (isUrl) { + await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndGitUrl( + editorXpath, + sampleNameOrUrl, + titlexPath, + pollingForCheckTitle + ); + } else { + await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndSample( + editorXpath, + sampleNameOrUrl, + titlexPath, + 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 { + 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 { + 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 { + 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()); + } + }); +}); diff --git a/tests/e2e/tests-library/WorkspaceHandlingTests.ts b/tests/e2e/tests-library/WorkspaceHandlingTests.ts index 4e884d44709..3b3928ac5be 100644 --- a/tests/e2e/tests-library/WorkspaceHandlingTests.ts +++ b/tests/e2e/tests-library/WorkspaceHandlingTests.ts @@ -150,18 +150,28 @@ export class WorkspaceHandlingTests { Logger.info('Start workspace progress description: ' + alertDescription); } - async createAndOpenWorkspaceWithSpecificEditorAndSample(editor: string, sampleName: string, xPath: string): Promise { + async createAndOpenWorkspaceWithSpecificEditorAndSample( + editor: string, + sampleName: string, + xPath: string, + polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT + ): Promise { 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 { + async createAndOpenWorkspaceWithSpecificEditorAndGitUrl( + editor: string, + sampleUrl: string, + xPath: string, + polling: number = TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT + ): Promise { 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 { @@ -175,11 +185,11 @@ export class WorkspaceHandlingTests { return await this.driverHelper.getDriver().findElement(By.xpath(xpath)).getText(); } - private async waitForControlXpath(xPathToWait: string): Promise { + private async waitForControlXpath(xPathToWait: string, polling: number): Promise { 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 { diff --git a/tests/e2e/utils/DriverHelper.ts b/tests/e2e/utils/DriverHelper.ts index f94a6796133..d041fd82b6a 100644 --- a/tests/e2e/utils/DriverHelper.ts +++ b/tests/e2e/utils/DriverHelper.ts @@ -92,8 +92,11 @@ export class DriverHelper { return false; } - async waitVisibility(elementLocator: By, timeout: number = TIMEOUT_CONSTANTS.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise { - 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 { const attempts: number = Math.ceil(timeout / polling); Logger.trace(`${elementLocator}`);