diff --git a/tests/e2e/constants/EDITOR_CONSTANTS.ts b/tests/e2e/constants/EDITOR_CONSTANTS.ts new file mode 100644 index 00000000000..502bfda1057 --- /dev/null +++ b/tests/e2e/constants/EDITOR_CONSTANTS.ts @@ -0,0 +1,120 @@ +/** ******************************************************************* + * 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 + **********************************************************************/ + +export type EditorType = 'vscode' | 'intellij'; + +export interface EditorConfig { + readonly environmentId: string; + readonly xpath: string; + readonly name: string; + readonly type: EditorType; +} + +export const ALL_EDITORS: Map = new Map([ + [ + 'VSCODE_DESKTOP_SSH_EDITOR', + { + environmentId: 'VSCODE_DESKTOP_SSH_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-code-sshd/latest"]', + name: 'VSCode Desktop SSH', + type: 'vscode' + } + ], + [ + 'CLION_EDITOR', + { + environmentId: 'CLION_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-clion-server/latest"]', + name: 'CLion', + type: 'intellij' + } + ], + [ + 'GOLAND_EDITOR', + { + environmentId: 'GOLAND_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-goland-server/latest"]', + name: 'GoLand', + type: 'intellij' + } + ], + [ + 'INTELLIJ_IDEA_EDITOR', + { + environmentId: 'INTELLIJ_IDEA_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-idea-server/latest"]', + name: 'IntelliJ IDEA', + type: 'intellij' + } + ], + [ + 'PHPSTORM_EDITOR', + { + environmentId: 'PHPSTORM_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-phpstorm-server/latest"]', + name: 'PhpStorm', + type: 'intellij' + } + ], + [ + 'PYCHARM_EDITOR', + { + environmentId: 'PYCHARM_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-pycharm-server/latest"]', + name: 'PyCharm', + type: 'intellij' + } + ], + [ + 'RIDER_EDITOR', + { + environmentId: 'RIDER_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-rider-server/latest"]', + name: 'Rider', + type: 'intellij' + } + ], + [ + 'RUBYMINE_EDITOR', + { + environmentId: 'RUBYMINE_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-rubymine-server/latest"]', + name: 'RubyMine', + type: 'intellij' + } + ], + [ + 'WEBSTORM_EDITOR', + { + environmentId: 'WEBSTORM_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-webstorm-server/latest"]', + name: 'WebStorm', + type: 'intellij' + } + ], + [ + 'KIRO_EDITOR', + { + environmentId: 'KIRO_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/che-code-sshd-kiro/latest"]', + name: 'Kiro', + type: 'vscode' + } + ], + [ + 'JETBRAINS_SSH_EDITOR', + { + environmentId: 'JETBRAINS_SSH_EDITOR', + xpath: '//*[@id="editor-selector-card-che-incubator/jetbrains-sshd/latest"]', + name: 'JetBrains Toolbox App', + type: 'intellij' + } + ] +]); diff --git a/tests/e2e/index.ts b/tests/e2e/index.ts index 72c2834aa0f..99713138654 100644 --- a/tests/e2e/index.ts +++ b/tests/e2e/index.ts @@ -57,6 +57,7 @@ export * from './tests-library/WorkspaceHandlingTests'; export * from './constants/API_TEST_CONSTANTS'; export * from './constants/BASE_TEST_CONSTANTS'; export * from './constants/CHROME_DRIVER_CONSTANTS'; +export * from './constants/EDITOR_CONSTANTS'; export * from './constants/FACTORY_TEST_CONSTANTS'; export * from './constants/MOCHA_CONSTANTS'; export * from './constants/MONACO_CONSTANTS'; diff --git a/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingVSCodeDesktopSshEditor.spec.ts b/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingDesktopEditors.spec.ts similarity index 57% rename from tests/e2e/specs/dashboard-samples/StartWorkspaceUsingVSCodeDesktopSshEditor.spec.ts rename to tests/e2e/specs/dashboard-samples/StartWorkspaceUsingDesktopEditors.spec.ts index 808b65adfc8..2bf18cb08a6 100644 --- a/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingVSCodeDesktopSshEditor.spec.ts +++ b/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingDesktopEditors.spec.ts @@ -14,25 +14,46 @@ 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 { assert, expect } from 'chai'; import { Logger } from '../../utils/Logger'; import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS'; import { DriverHelper } from '../../utils/DriverHelper'; +import { EditorConfig, ALL_EDITORS } from '../../constants/EDITOR_CONSTANTS'; -suite('Check Visual Studio Code (desktop) (SSH) with all samples', function (): void { - this.timeout(6000000); +suite('Check all editors with all samples', function (): void { + this.timeout(24000000); const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests); const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard); const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil); const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper); - const vsCodeDesktopSshEditor: string = '//*[@id="editor-selector-card-che-incubator/che-code-sshd/latest"]'; const useExtensionSwitcher: string = '//label[@class="switch"]'; - const titlexPath: string = '//div[@class="header-title"]'; + const intellijTitleXpath: string = '/html/body/h1'; + const vsCodeTitleXpath: string = '//div[@class="header-title"]'; let currentTabHandle: string = 'undefined'; - const pollingForCheckTitle: number = 100; + const pollingForCheckTitleVSCode: number = 100; + const pollingForCheckTitleIntelliJ: number = 500; + + // filter editors based on environment variables + const selectAllEditors: boolean = process.env.SELECT_ALL_EDITORS === 'true'; + let editorsForCheck: EditorConfig[]; + + if (selectAllEditors) { + editorsForCheck = Array.from(ALL_EDITORS.values()); + Logger.info('SELECT_ALL_EDITORS is true - running tests for all editors'); + } else { + editorsForCheck = Array.from(ALL_EDITORS.values()).filter((editor): boolean => { + const envValue: string | undefined = process.env[editor.environmentId]; + return envValue === 'true'; + }); + Logger.info(`Running tests for selected editors: ${editorsForCheck.map((e): string => e.name).join(', ')}`); + + if (editorsForCheck.length === 0) { + assert.fail('No editors selected via environment variables'); + } + } const samplesForCheck: string[] = [ 'Empty Workspace', @@ -50,12 +71,14 @@ suite('Check Visual Studio Code (desktop) (SSH) with all samples', function (): 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' + 'https://github.com/crw-qe/ubi9-based-sample-public/tree/ubi9-minimal', + 'https://github.com/crw-qe/ubi10-based-sample-public/tree/main' ]; 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' + 'https://gh.crw-qe.com/test-automation-only/ubi9-based-sample-public/tree/ubi9-minimal', + 'https://gh.crw-qe.com/test-automation-only/ubi10-based-sample-public/tree/main' ]; suiteSetup('Login into Che', async function (): Promise { @@ -75,58 +98,35 @@ suite('Check Visual Studio Code (desktop) (SSH) with all samples', function (): currentTabHandle = 'undefined'; } - async function testWorkspaceStartup(sampleNameOrUrl: string, isUrl: boolean): Promise { - await dashboard.openDashboard(); - currentTabHandle = await browserTabsUtil.getCurrentWindowHandle(); - await dashboard.clickCreateWorkspaceButton(); - - if (isUrl) { - await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndGitUrl( - vsCodeDesktopSshEditor, - sampleNameOrUrl, - titlexPath, - pollingForCheckTitle - ); - } else { - await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndSample( - vsCodeDesktopSshEditor, - sampleNameOrUrl, - titlexPath, - pollingForCheckTitle - ); - } + async function verifyVSCodeEditor(): Promise { + Logger.debug(); - // read page const pageTextBeforeUseExtensionSwitcher: string = await driverHelper.getDriver().executeScript('return document.body.innerText;'); - // click on "Use Extension" switcher await clickOnElementByXpath(useExtensionSwitcher); - // read page const pageTextAfterUseExtensionSwitcher: string = await driverHelper.getDriver().executeScript('return document.body.innerText;'); - // checks for "Install extensions" state expect(pageTextBeforeUseExtensionSwitcher).contains('Install the following VS Code extensions'); - Logger.info('"Install the following VS Code extensions" was found in page before "Use Extension" clicked'); + Logger.debug('"Install the following VS Code extensions" was found in page before "Use Extension" clicked'); expect(pageTextBeforeUseExtensionSwitcher).contains('Workspace ' + WorkspaceHandlingTests.getWorkspaceName() + ' is running'); - Logger.info( + Logger.debug( 'Workspace name "' + WorkspaceHandlingTests.getWorkspaceName() + ' is running" was found before "Use Extension" clicked' ); - // checks for SSH state expect(pageTextAfterUseExtensionSwitcher).contains('Workspace ' + WorkspaceHandlingTests.getWorkspaceName() + ' is running'); - Logger.info( + Logger.debug( 'Workspace name "' + WorkspaceHandlingTests.getWorkspaceName() + ' is running" was found after "Use Extension" clicked' ); expect(pageTextAfterUseExtensionSwitcher).contains('oc port-forward -n admin-devspaces'); - Logger.info('"oc port-forward -n admin-devspaces" was found after "Use Extension" clicked'); + Logger.debug('"oc port-forward -n admin-devspaces" was found'); expect(pageTextAfterUseExtensionSwitcher) .contains('-----BEGIN OPENSSH PRIVATE KEY-----') .and.contains('-----END OPENSSH PRIVATE KEY-----'); - Logger.info('SSH private key (BEGIN and END markers) was found after "Use Extension" clicked'); + Logger.debug('SSH private key (BEGIN and END markers) was found'); expect(pageTextAfterUseExtensionSwitcher) .contains('HostName') @@ -134,31 +134,77 @@ suite('Check Visual Studio Code (desktop) (SSH) with all samples', function (): .and.contains('Port') .and.contains('IdentityFile') .and.contains('UserKnownHostsFile'); - Logger.info( - 'SSH config parameters (HostName, User, Port, IdentityFile, UserKnownHostsFile) were found after "Use Extension" clicked' - ); + Logger.debug('SSH config parameters (HostName, User, Port, IdentityFile, UserKnownHostsFile) were found'); } - samplesForCheck.forEach((sampleName): void => { - test('Test start of VSCode (desktop) (SSH) with default Samples', async function (): Promise { - await testWorkspaceStartup(sampleName, false); + async function verifyIntelliJEditor(titleXpath: string): Promise { + Logger.debug(); + + const headerText: string = await workspaceHandlingTests.getTextFromUIElementByXpath(titleXpath); + expect('Workspace ' + WorkspaceHandlingTests.getWorkspaceName() + ' is running').equal(headerText); + Logger.debug('Workspace title verified for IntelliJ editor: ' + headerText); + } + + async function testWorkspaceStartup( + editorXpath: string, + editorType: 'vscode' | 'intellij', + sampleNameOrUrl: string, + isUrl: boolean + ): Promise { + await dashboard.openDashboard(); + currentTabHandle = await browserTabsUtil.getCurrentWindowHandle(); + await dashboard.clickCreateWorkspaceButton(); + + const pollingForCheckTitle: number = editorType === 'vscode' ? pollingForCheckTitleVSCode : pollingForCheckTitleIntelliJ; + const titleXpath: string = editorType === 'vscode' ? vsCodeTitleXpath : intellijTitleXpath; + + if (isUrl) { + await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndGitUrl( + editorXpath, + sampleNameOrUrl, + titleXpath, + pollingForCheckTitle + ); + } else { + await workspaceHandlingTests.createAndOpenWorkspaceWithSpecificEditorAndSample( + editorXpath, + sampleNameOrUrl, + titleXpath, + pollingForCheckTitle + ); + } + + if (editorType === 'vscode') { + await verifyVSCodeEditor(); + } else { + await verifyIntelliJEditor(titleXpath); + } + } + + editorsForCheck.forEach((editor): void => { + samplesForCheck.forEach((sampleName): void => { + test(`Test start of ${editor.name} with sample: ${sampleName}`, async function (): Promise { + await testWorkspaceStartup(editor.xpath, editor.type, sampleName, false); + }); }); }); - if (BASE_TEST_CONSTANTS.IS_CLUSTER_DISCONNECTED()) { - Logger.info('Test cluster is disconnected. Using url for airgap cluster.'); - gitRepoUrlsToCheckAirgap.forEach((url): void => { - test('Test start of VSCode (desktop) (SSH) with ubi', async function (): Promise { - await testWorkspaceStartup(url, true); + editorsForCheck.forEach((editor): void => { + if (BASE_TEST_CONSTANTS.IS_CLUSTER_DISCONNECTED()) { + Logger.info('Test cluster is disconnected. Using url for airgap cluster.'); + gitRepoUrlsToCheckAirgap.forEach((url): void => { + test(`Test start of ${editor.name} with ubi url: ${url}`, async function (): Promise { + await testWorkspaceStartup(editor.xpath, editor.type, url, true); + }); }); - }); - } else { - gitRepoUrlsToCheck.forEach((url): void => { - test('Test start of VSCode (desktop) (SSH) with ubi', async function (): Promise { - await testWorkspaceStartup(url, true); + } else { + gitRepoUrlsToCheck.forEach((url): void => { + test(`Test start of ${editor.name} with ubi url: ${url}`, async function (): Promise { + await testWorkspaceStartup(editor.xpath, editor.type, url, true); + }); }); - }); - } + } + }); teardown('Delete DevWorkspace', async function (): Promise { Logger.info('Delete DevWorkspace. After each test.'); diff --git a/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingIntellijIdeaEditor.spec.ts b/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingIntellijIdeaEditor.spec.ts deleted file mode 100644 index fe65d976f48..00000000000 --- a/tests/e2e/specs/dashboard-samples/StartWorkspaceUsingIntellijIdeaEditor.spec.ts +++ /dev/null @@ -1,154 +0,0 @@ -/** ******************************************************************* - * 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"]', - '//*[@id="editor-selector-card-che-incubator/jetbrains-sshd/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'; - } - - 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(); - await dashboard.clickCreateWorkspaceButton(); - - 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); - } - - editorsForCheck.forEach((editorXpath): void => { - samplesForCheck.forEach((sampleName): void => { - test(`Test start of Editor with xPath: ${editorXpath} and with sample name: ${sampleName}`, async function (): Promise { - await testWorkspaceStartup(editorXpath, sampleName, false); - }); - }); - }); - - editorsForCheck.forEach((editorXpath): void => { - if (BASE_TEST_CONSTANTS.IS_CLUSTER_DISCONNECTED()) { - gitRepoUrlsToCheckAirgap.forEach((gitUbiUrl): void => { - test(`Test start of Editor with xPath: ${editorXpath} and with ubi url: ${gitUbiUrl}`, async function (): Promise { - await testWorkspaceStartup(editorXpath, gitUbiUrl, true); - }); - }); - } else { - gitRepoUrlsToCheck.forEach((gitUbiUrl): void => { - test(`Test start of Editor with xPath: ${editorXpath} and with ubi url: ${gitUbiUrl}`, async function (): Promise { - await testWorkspaceStartup(editorXpath, gitUbiUrl, true); - }); - }); - } - }); - - teardown('Delete DevWorkspace', async function (): Promise { - Logger.info('Delete DevWorkspace. After each test.'); - if (currentTabHandle !== 'undefined') { - await browserTabsUtil.switchToWindow(currentTabHandle); - } - - await dashboard.openDashboard(); - await browserTabsUtil.closeAllTabsExceptCurrent(); - - if (WorkspaceHandlingTests.getWorkspaceName() !== 'undefined') { - Logger.info('Workspace name is defined. Deleting workspace...'); - await dashboard.deleteStoppedWorkspaceByUI(WorkspaceHandlingTests.getWorkspaceName()); - } - - WorkspaceHandlingTests.clearWorkspaceName(); - clearCurrentTabHandle(); - }); -});