From 1c9b84e9252b366a6bd221d4d2e65b2595047377 Mon Sep 17 00:00:00 2001 From: Mario Loriedo Date: Tue, 12 Dec 2023 23:55:25 +0100 Subject: [PATCH 01/85] Fix README links (#22724) --- .devfile.yaml | 6 ++--- .github/ISSUE_TEMPLATE/a_question.yaml | 4 +-- .github/ISSUE_TEMPLATE/bug_report.yml | 6 ++--- .github/ISSUE_TEMPLATE/enhancement.yaml | 4 +-- .github/ISSUE_TEMPLATE/task.yaml | 4 +-- .repositories.yaml | 2 +- CONTRIBUTING.md | 2 +- README.md | 35 ++++++++++++------------- 8 files changed, 30 insertions(+), 33 deletions(-) diff --git a/.devfile.yaml b/.devfile.yaml index b20476e9a4c..09016cd731f 100644 --- a/.devfile.yaml +++ b/.devfile.yaml @@ -6,18 +6,16 @@ # # SPDX-License-Identifier: EPL-2.0 # -schemaVersion: 2.1.0 +schemaVersion: 2.2.0 metadata: name: che -attributes: - controller.devfile.io/storage-type: ephemeral components: - name: devtools container: image: quay.io/mloriedo/universal-developer-image:ubi8-latest memoryLimit: 4G memoryRequest: 256Mi - cpuLimit: 500m + cpuLimit: '2' cpuRequest: 30m commands: - id: update-contributing diff --git a/.github/ISSUE_TEMPLATE/a_question.yaml b/.github/ISSUE_TEMPLATE/a_question.yaml index f29c675853f..37c5fcd9218 100644 --- a/.github/ISSUE_TEMPLATE/a_question.yaml +++ b/.github/ISSUE_TEMPLATE/a_question.yaml @@ -13,11 +13,11 @@ body: Useful Links: - - 📄 Documentation: https://www.eclipse.org/che/docs + - 📄 Documentation: https://eclipse.dev/che/docs - 📝 Contributing: https://github.com/eclipse/che/blob/master/CONTRIBUTING.md 💬 Eclipse Che has public chat on: - - Mattermost: https://mattermost.eclipse.org/eclipse/channels/eclipse-che + - Eclipse Cloud Dev Tools Slack: https://communityinviter.com/apps/ecd-tools/join-the-community - type: textarea id: summary diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 84a33b3075b..fa4b4abb690 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -13,11 +13,11 @@ body: Useful Links: - - 📄 Documentation: https://www.eclipse.org/che/docs + - 📄 Documentation: https://eclipse.dev/che/docs - 📝 Contributing: https://github.com/eclipse/che/blob/master/CONTRIBUTING.md 💬 Eclipse Che has public chat on: - - Mattermost: https://mattermost.eclipse.org/eclipse/channels/eclipse-che + - Eclipse Cloud Dev Tools Slack: https://communityinviter.com/apps/ecd-tools/join-the-community - type: textarea id: describe-bug @@ -156,7 +156,7 @@ body: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks - description: "How to collect logs: https://www.eclipse.org/che/docs/che-7/collecting-logs-using-chectl" + description: "How to collect logs: https://eclipse.dev/che/docs/stable/administration-guide/collecting-logs-using-chectl/" render: shell - type: textarea diff --git a/.github/ISSUE_TEMPLATE/enhancement.yaml b/.github/ISSUE_TEMPLATE/enhancement.yaml index 77cbba9af5a..63f387b4ca4 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yaml +++ b/.github/ISSUE_TEMPLATE/enhancement.yaml @@ -13,11 +13,11 @@ body: Useful Links: - - 📄 Documentation: https://www.eclipse.org/che/docs + - 📄 Documentation: https://eclipse.dev/che/docs - 📝 Contributing: https://github.com/eclipse/che/blob/master/CONTRIBUTING.md 💬 Eclipse Che has public chat on: - - Mattermost: https://mattermost.eclipse.org/eclipse/channels/eclipse-che + - Eclipse Cloud Dev Tools Slack: https://communityinviter.com/apps/ecd-tools/join-the-community - type: textarea id: problem diff --git a/.github/ISSUE_TEMPLATE/task.yaml b/.github/ISSUE_TEMPLATE/task.yaml index f6f9c37ae65..e4f6b3380a9 100644 --- a/.github/ISSUE_TEMPLATE/task.yaml +++ b/.github/ISSUE_TEMPLATE/task.yaml @@ -13,11 +13,11 @@ body: Useful Links: - - 📄 Documentation: https://www.eclipse.org/che/docs + - 📄 Documentation: https://eclipse.dev/che/docs - 📝 Contributing: https://github.com/eclipse/che/blob/master/CONTRIBUTING.md 💬 Eclipse Che has public chat on: - - Mattermost: https://mattermost.eclipse.org/eclipse/channels/eclipse-che + - Eclipse Cloud Dev Tools Slack: https://communityinviter.com/apps/ecd-tools/join-the-community - type: textarea id: problem diff --git a/.repositories.yaml b/.repositories.yaml index 50446e34315..00a742314bc 100644 --- a/.repositories.yaml +++ b/.repositories.yaml @@ -94,7 +94,7 @@ repositories: - url: https://github.com/eclipse-che/che-website name: website description: >- - https://eclipse.org/che website source code. + https://eclipse.dev/che website source code. devfile: https://github.com/eclipse-che/che-website/blob/main/.devfile.yaml useCheReleaseLifecycle: false - url: https://github.com/eclipse-che/che-workspace-client diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df0bd8bff31..42d1876b5b0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ Repository | Component | Description | Devfile | Documentation [machine-exec](https://github.com/eclipse-che/che-machine-exec) | | Interface to execute tasks and terminals on other containers within a workspace. | [devfile](https://github.com/eclipse-che/che-machine-exec/blob/main/devfile.yaml) | [doc](https://github.com/eclipse-che/che-machine-exec/blob/main/CONTRIBUTING.md) [operator](https://github.com/eclipse-che/che-operator) | | Che operator to deploy, update and manage K8S/OpenShift resources of Che. | [devfile](https://github.com/eclipse-che/che-operator/blob/main/devfile.yaml) | [plugin-registry](https://github.com/eclipse-che/che-plugin-registry) | | The default set of Che plugins (vscode extension + containers) or editors that could be installed on any Che workspaces. | | -[website](https://github.com/eclipse-che/che-website) | | https://eclipse.org/che website source code. | [devfile](https://github.com/eclipse-che/che-website/blob/main/.devfile.yaml) | +[website](https://github.com/eclipse-che/che-website) | | https://eclipse.dev/che website source code. | [devfile](https://github.com/eclipse-che/che-website/blob/main/.devfile.yaml) | [workspace-client](https://github.com/eclipse-che/che-workspace-client) | | JS library to interact with a che-server. | | [configbump](https://github.com/che-incubator/configbump) | | Simple Kubernetes controller that is able to quickly synchronize a set of config maps | | [workspace-data-sync](https://github.com/che-incubator/workspace-data-sync) | | Provides the ability to increase I/O performance for a developer workspaces | | diff --git a/README.md b/README.md index e2f3645428e..371102bdf6d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ https://github.com/eclipse-che/che-server @@ -28,7 +28,7 @@ https://www.eclipse.org/che/) --- -**Visit website at: https://www.eclipse.org/che/** and documentation at: https://www.eclipse.org/che/docs +**Visit website at: https://eclipse.dev/che/** and documentation at: https://eclipse.dev/che/docs - [**Getting Started**](#getting-started) - [**Using Eclipse Che**](#using-eclipse-che) @@ -41,22 +41,23 @@ https://www.eclipse.org/che/) ### Getting Started Here you can find links on how to get started with Eclipse Che: -- [Use Eclipse Che online](https://www.eclipse.org/che/getting-started/cloud/) -- [Run Eclipse Che on your own K8S cluster](https://www.eclipse.org/che/docs/che-7/che-quick-starts) +- [Use Eclipse Che online](https://eclipse.dev/che/getting-started/cloud/) +- [Run Eclipse Che on your own Kubernetes cluster](https://eclipse.dev/che/docs/stable/administration-guide/preparing-the-installation/) ### Using Eclipse Che Here you can find references to useful documentation and hands-on guides to learn how to get the most of Eclipse Che: -- [Customize Che workspaces for your projects](https://www.eclipse.org/che/docs/che-7/configuring-a-workspace-using-a-devfile/) -- [Run VSCode Extensions in Che workspaces](https://www.eclipse.org/che/docs/che-7/end-user-guide/adding-a-vs-code-extension-to-a-workspace/) -- [Creating and configuring a new Che 7 workspace](https://www.eclipse.org/che/docs/che-7/end-user-guide/creating-and-configuring-a-new-workspace/) -- [Making a workspace portable using a devfile](https://www.eclipse.org/che/docs/che-7/end-user-guide/making-a-workspace-portable-using-a-devfile/) - +- [Customize Che workspaces for your projects](https://eclipse.dev/che/docs/stable/end-user-guide/customizing-workspace-components/) +- [Automatically run VSCode Extensions in Che workspaces](https://eclipse.dev/che/docs/stable/end-user-guide/microsoft-visual-studio-code-open-source-ide/#automating-installation-of-microsoft-visual-studio-code-extensions-at-workspace-startup) +- [Starting a workspace from a Git repository URL](https://eclipse.dev/che/docs/stable/end-user-guide/starting-a-workspace-from-a-git-repository-url/) +- [Making a workspace portable using a devfile](https://eclipse.dev/che/docs/stable/end-user-guide/devfile-introduction/) +- [Configure your instance of Che](https://eclipse.dev/che/docs/stable/administration-guide/checluster-custom-resource-fields-reference/) using the [CheCluster Kubernetes Custom Resource](https://doc.crds.dev/github.com/eclipse-che/che-operator) +- [Use and customize the embedded VSCode extensions registry.](https://eclipse.dev/che/docs/stable/administration-guide/extensions-for-microsoft-visual-studio-code-open-source/#adding-or-removing-extensions-in-the-embedded-open-vsx-registry-instance) ### Feedback and Community We love to hear from users and developers. Here are the various ways to get in touch with us: * **Support:** You can ask questions, report bugs, and request features using [GitHub issues](https://github.com/eclipse/che/issues). -* **Public Chat:** Join the public [eclipse-che](https://mattermost.eclipse.org/eclipse/channels/eclipse-che) Mattermost channel to discuss with community and contributors. +* **Public Chat:** Join the public [eclipse-che](https://communityinviter.com/apps/ecd-tools/join-the-community) Mattermost channel to discuss with community and contributors. * **Twitter:** [@eclipse_che](https://twitter.com/eclipse_che) * **Mailing List:** [che-dev@eclipse.org](https://accounts.eclipse.org/mailing-list/che-dev) * **Weekly Meetings:** Join us in our [Che community meeting](https://github.com/eclipse/che/wiki/Che-Dev-Meetings) every second monday. @@ -67,18 +68,16 @@ If you are interested in fixing issues and contributing directly to the code bas - :bug: [Submitting bugs](https://github.com/eclipse/che/issues/new/choose) - :page_facing_up: [Contributor license agreement](https://github.com/eclipse/che/wiki/Eclipse-Contributor-Agreement) - :checkered_flag: [Development workflows](./CONTRIBUTING.md) -- :ok_hand: [Review source code changes](https://github.com/eclipse/che/pulls) -- :pencil: [Improve docs](https://github.com/eclipse/che-docs) -- :building_construction: [Che architecture](https://www.eclipse.org/che/docs/che-7/administration-guide/che-architecture-overview/) +- :pencil: [Improve docs](https://github.com/eclipse-che/che-docs) +- :building_construction: [Che architecture](https://eclipse.dev/che/docs/stable/administration-guide/architecture-overview/) - :octocat: [Che repositories](./CONTRIBUTING.md#other-che-repositories) - :sparkles: [Good first issue for new contributors](https://github.com/eclipse/che/wiki/Labels#new-contributors) #### Extending Eclipse Che -- [Add a new language support. (to be provided soon)](https://www.eclipse.org/che/docs/che-7/adding-support-for-a-new-language/) -- [Package your favorite VSCode extensions and make them available in Che.](https://www.eclipse.org/che/docs/che-7/end-user-guide/publishing-metadata-for-a-vs-code-extension/) -- [Write your own VSCode extension that runs on a dedicated side car container.](https://www.eclipse.org/che/docs/che-7/what-is-a-che-theia-plug-in/) -- [Build and package your custom Che-Theia editor with your extensions and plugins.](https://www.eclipse.org/che/docs/che-7/using-alternative-ides-in-che/) +- [Customize the default dev tooling container (the universal developer image or UDI).](https://github.com/devfile/developer-images/) +- [Customize the list of getting started samples.](https://eclipse.dev/che/docs/stable/administration-guide/configuring-getting-started-samples/) +- [Add your own editor definition.](https://github.com/eclipse-che/che-plugin-registry/blob/main/che-editors.yaml) ### Roadmap We maintain the [Che roadmap](https://github.com/eclipse/che/wiki/Roadmap) in the open way. We welcome anyone to ask question and contribute to the roadmap by joining our [community meetings](https://github.com/eclipse/che/wiki/Che-Dev-Meetings). From 93348b505459105be4b2df515334e4d9b1bf7d29 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 19 Dec 2023 15:59:48 +0200 Subject: [PATCH 02/85] add UserPreferences page test and page object (#22734) --- tests/e2e/configs/inversify.config.ts | 2 + tests/e2e/configs/inversify.types.ts | 3 +- .../pageobjects/dashboard/UserPreferences.ts | 89 +++++++++++++++++++ .../miscellaneous/UserPreferencesTest.spec.ts | 30 +++++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/pageobjects/dashboard/UserPreferences.ts create mode 100644 tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts diff --git a/tests/e2e/configs/inversify.config.ts b/tests/e2e/configs/inversify.config.ts index 7dce0b5ae32..6aba4125dae 100644 --- a/tests/e2e/configs/inversify.config.ts +++ b/tests/e2e/configs/inversify.config.ts @@ -51,6 +51,7 @@ import { DevfilesRegistryHelper } from '../utils/DevfilesRegistryHelper'; import { Main as Generator } from '@eclipse-che/che-devworkspace-generator/lib/main'; import { ContainerTerminal, KubernetesCommandLineToolsExecutor } from '../utils/KubernetesCommandLineToolsExecutor'; import { ShellExecutor } from '../utils/ShellExecutor'; +import { UserPreferences } from '../pageobjects/dashboard/UserPreferences'; const e2eContainer: Container = new Container({ defaultScope: 'Transient', skipBaseClassChecks: true }); @@ -84,6 +85,7 @@ e2eContainer.bind(CLASSES.DevfilesRegistryHelper).to(Dev e2eContainer.bind(CLASSES.KubernetesCommandLineToolsExecutor).to(KubernetesCommandLineToolsExecutor); e2eContainer.bind(CLASSES.ShellExecutor).to(ShellExecutor); e2eContainer.bind(CLASSES.ContainerTerminal).to(ContainerTerminal); +e2eContainer.bind(CLASSES.UserPreferences).to(UserPreferences); e2eContainer.bind(EXTERNAL_CLASSES.Generator).to(Generator); e2eContainer.bind(EXTERNAL_CLASSES.LocatorLoader).to(LocatorLoader); diff --git a/tests/e2e/configs/inversify.types.ts b/tests/e2e/configs/inversify.types.ts index f2d2dff1071..1e040aecb8c 100644 --- a/tests/e2e/configs/inversify.types.ts +++ b/tests/e2e/configs/inversify.types.ts @@ -47,7 +47,8 @@ const CLASSES: any = { DevfilesRegistryHelper: 'DevfilesRegistryHelper', KubernetesCommandLineToolsExecutor: 'KubernetesCommandLineToolsExecutor', ShellExecutor: 'ShellExecutor', - ContainerTerminal: 'ContainerTerminal' + ContainerTerminal: 'ContainerTerminal', + UserPreferences: 'UserPreferences' }; const EXTERNAL_CLASSES: any = { diff --git a/tests/e2e/pageobjects/dashboard/UserPreferences.ts b/tests/e2e/pageobjects/dashboard/UserPreferences.ts new file mode 100644 index 00000000000..d0a5c560748 --- /dev/null +++ b/tests/e2e/pageobjects/dashboard/UserPreferences.ts @@ -0,0 +1,89 @@ +/** ******************************************************************* + * copyright (c) 2019-2023 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 { inject, injectable } from 'inversify'; +import 'reflect-metadata'; +import { CLASSES } from '../../configs/inversify.types'; +import { By } from 'selenium-webdriver'; +import { DriverHelper } from '../../utils/DriverHelper'; +import { Logger } from '../../utils/Logger'; + +@injectable() +export class UserPreferences { + private static readonly USER_SETTINGS_DROPDOWN: By = By.xpath('//header//button/span[text()!=""]//parent::button'); + private static readonly USER_PREFERENCES_BUTTON: By = By.xpath('//button[text()="User Preferences"]'); + private static readonly USER_PREFERENCES_PAGE: By = By.xpath('//h1[text()="User Preferences"]'); + + private static readonly CONTAINER_REGISTRIES_TAB: By = By.xpath('//button[text()="Container Registries"]'); + private static readonly GIT_SERVICES_TAB: By = By.xpath('//button[text()="Git Services"]'); + + private static readonly PAT_TAB: By = By.xpath('//button[text()="Personal Access Tokens"]'); + private static readonly ADD_NEW_PAT_BUTTON: By = By.xpath('//button[text()="Add Personal Access Token"]'); + + private static readonly GIT_CONFIG_PAGE: By = By.xpath('//button[text()="Gitconfig"]'); + + private static readonly SSH_KEY_TAB: By = By.xpath('//button[text()="SSH Keys"]'); + private static readonly ADD_NEW_SSH_KEY_BUTTON: By = By.xpath('//button[text()="Add SSH Key"]'); + + constructor( + @inject(CLASSES.DriverHelper) + readonly driverHelper: DriverHelper + ) {} + + async openUserPreferencesPage(): Promise { + Logger.debug(); + + await this.driverHelper.waitAndClick(UserPreferences.USER_SETTINGS_DROPDOWN); + await this.driverHelper.waitAndClick(UserPreferences.USER_PREFERENCES_BUTTON); + + await this.driverHelper.waitVisibility(UserPreferences.USER_PREFERENCES_PAGE); + } + + async checkTabsAvailability(): Promise { + Logger.debug(); + + await this.openContainerRegistriesTab(); + await this.openGitServicesTab(); + await this.openPatTab(); + await this.openGitConfigPage(); + await this.openSshKeyTab(); + } + + async openContainerRegistriesTab(): Promise { + Logger.debug(); + + await this.driverHelper.waitAndClick(UserPreferences.CONTAINER_REGISTRIES_TAB); + } + + async openGitServicesTab(): Promise { + Logger.debug(); + + await this.driverHelper.waitAndClick(UserPreferences.GIT_SERVICES_TAB); + } + + async openPatTab(): Promise { + Logger.debug(); + + await this.driverHelper.waitAndClick(UserPreferences.PAT_TAB); + await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_PAT_BUTTON); + } + + async openGitConfigPage(): Promise { + Logger.debug(); + + await this.driverHelper.waitAndClick(UserPreferences.GIT_CONFIG_PAGE); + } + + async openSshKeyTab(): Promise { + Logger.debug(); + + await this.driverHelper.waitAndClick(UserPreferences.SSH_KEY_TAB); + await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_SSH_KEY_BUTTON); + } +} diff --git a/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts b/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts new file mode 100644 index 00000000000..90344449303 --- /dev/null +++ b/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts @@ -0,0 +1,30 @@ +/** ******************************************************************* + * copyright (c) 2020-2023 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 { e2eContainer } from '../../configs/inversify.config'; +import { CLASSES } from '../../configs/inversify.types'; +import { LoginTests } from '../../tests-library/LoginTests'; +import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS'; +import { UserPreferences } from '../../pageobjects/dashboard/UserPreferences'; + + +suite(`"Check User Preferences page" test ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { + const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); + const userPreferences: UserPreferences = e2eContainer.get(CLASSES.UserPreferences); + + suiteSetup('Login', async function (): Promise { + await loginTests.loginIntoChe(); + }); + + test(`Check user preferences page`, async function (): Promise { + await userPreferences.openUserPreferencesPage(); + await userPreferences.checkTabsAvailability(); + }); + +}); From 25713247743c704d2e67b383b65dc04b729b667d Mon Sep 17 00:00:00 2001 From: Mykhailo Kuznietsov Date: Thu, 21 Dec 2023 14:06:33 +0000 Subject: [PATCH 03/85] chore: Bump to 7.80.0-next in main Signed-off-by: Mykhailo Kuznietsov --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 +- VERSION | 2 +- tests/e2e/package-lock.json | 4 +- tests/e2e/package.json | 2 +- .../pageobjects/dashboard/UserPreferences.ts | 76 +++++++++---------- .../miscellaneous/UserPreferencesTest.spec.ts | 2 - 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fa4b4abb690..d8288f1d9c4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,8 +33,9 @@ body: label: Che version description: if workspace is running, version can be obtained with help/about menu options: - - "7.78@latest" + - "7.79@latest" - "next (development version)" + - "7.78" - "7.77" - "7.75" - "7.74" diff --git a/VERSION b/VERSION index 12aebec0966..3b2d88b1625 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.79.0-next +7.80.0-next diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 30ae8be0df7..95e4d3ac941 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -1,12 +1,12 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.79.0-next", + "version": "7.80.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@eclipse-che/che-e2e", - "version": "7.79.0-next", + "version": "7.80.0-next", "license": "ISC", "dependencies": { "@eclipse-che/api": "latest", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index fe2944e1f59..63a57183d41 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.79.0-next", + "version": "7.80.0-next", "description": "", "main": "dist/index.js", "scripts": { diff --git a/tests/e2e/pageobjects/dashboard/UserPreferences.ts b/tests/e2e/pageobjects/dashboard/UserPreferences.ts index d0a5c560748..d607508ef5f 100644 --- a/tests/e2e/pageobjects/dashboard/UserPreferences.ts +++ b/tests/e2e/pageobjects/dashboard/UserPreferences.ts @@ -20,16 +20,16 @@ export class UserPreferences { private static readonly USER_PREFERENCES_BUTTON: By = By.xpath('//button[text()="User Preferences"]'); private static readonly USER_PREFERENCES_PAGE: By = By.xpath('//h1[text()="User Preferences"]'); - private static readonly CONTAINER_REGISTRIES_TAB: By = By.xpath('//button[text()="Container Registries"]'); - private static readonly GIT_SERVICES_TAB: By = By.xpath('//button[text()="Git Services"]'); + private static readonly CONTAINER_REGISTRIES_TAB: By = By.xpath('//button[text()="Container Registries"]'); + private static readonly GIT_SERVICES_TAB: By = By.xpath('//button[text()="Git Services"]'); - private static readonly PAT_TAB: By = By.xpath('//button[text()="Personal Access Tokens"]'); - private static readonly ADD_NEW_PAT_BUTTON: By = By.xpath('//button[text()="Add Personal Access Token"]'); + private static readonly PAT_TAB: By = By.xpath('//button[text()="Personal Access Tokens"]'); + private static readonly ADD_NEW_PAT_BUTTON: By = By.xpath('//button[text()="Add Personal Access Token"]'); - private static readonly GIT_CONFIG_PAGE: By = By.xpath('//button[text()="Gitconfig"]'); + private static readonly GIT_CONFIG_PAGE: By = By.xpath('//button[text()="Gitconfig"]'); - private static readonly SSH_KEY_TAB: By = By.xpath('//button[text()="SSH Keys"]'); - private static readonly ADD_NEW_SSH_KEY_BUTTON: By = By.xpath('//button[text()="Add SSH Key"]'); + private static readonly SSH_KEY_TAB: By = By.xpath('//button[text()="SSH Keys"]'); + private static readonly ADD_NEW_SSH_KEY_BUTTON: By = By.xpath('//button[text()="Add SSH Key"]'); constructor( @inject(CLASSES.DriverHelper) @@ -37,7 +37,7 @@ export class UserPreferences { ) {} async openUserPreferencesPage(): Promise { - Logger.debug(); + Logger.debug(); await this.driverHelper.waitAndClick(UserPreferences.USER_SETTINGS_DROPDOWN); await this.driverHelper.waitAndClick(UserPreferences.USER_PREFERENCES_BUTTON); @@ -45,45 +45,45 @@ export class UserPreferences { await this.driverHelper.waitVisibility(UserPreferences.USER_PREFERENCES_PAGE); } - async checkTabsAvailability(): Promise { - Logger.debug(); + async checkTabsAvailability(): Promise { + Logger.debug(); - await this.openContainerRegistriesTab(); - await this.openGitServicesTab(); - await this.openPatTab(); - await this.openGitConfigPage(); - await this.openSshKeyTab(); - } + await this.openContainerRegistriesTab(); + await this.openGitServicesTab(); + await this.openPatTab(); + await this.openGitConfigPage(); + await this.openSshKeyTab(); + } - async openContainerRegistriesTab(): Promise { - Logger.debug(); + async openContainerRegistriesTab(): Promise { + Logger.debug(); - await this.driverHelper.waitAndClick(UserPreferences.CONTAINER_REGISTRIES_TAB); - } + await this.driverHelper.waitAndClick(UserPreferences.CONTAINER_REGISTRIES_TAB); + } - async openGitServicesTab(): Promise { - Logger.debug(); + async openGitServicesTab(): Promise { + Logger.debug(); - await this.driverHelper.waitAndClick(UserPreferences.GIT_SERVICES_TAB); - } + await this.driverHelper.waitAndClick(UserPreferences.GIT_SERVICES_TAB); + } - async openPatTab(): Promise { - Logger.debug(); + async openPatTab(): Promise { + Logger.debug(); - await this.driverHelper.waitAndClick(UserPreferences.PAT_TAB); - await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_PAT_BUTTON); - } + await this.driverHelper.waitAndClick(UserPreferences.PAT_TAB); + await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_PAT_BUTTON); + } - async openGitConfigPage(): Promise { - Logger.debug(); + async openGitConfigPage(): Promise { + Logger.debug(); - await this.driverHelper.waitAndClick(UserPreferences.GIT_CONFIG_PAGE); - } + await this.driverHelper.waitAndClick(UserPreferences.GIT_CONFIG_PAGE); + } - async openSshKeyTab(): Promise { - Logger.debug(); + async openSshKeyTab(): Promise { + Logger.debug(); - await this.driverHelper.waitAndClick(UserPreferences.SSH_KEY_TAB); - await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_SSH_KEY_BUTTON); - } + await this.driverHelper.waitAndClick(UserPreferences.SSH_KEY_TAB); + await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_SSH_KEY_BUTTON); + } } diff --git a/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts b/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts index 90344449303..c4f28353760 100644 --- a/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts +++ b/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts @@ -13,7 +13,6 @@ import { LoginTests } from '../../tests-library/LoginTests'; import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS'; import { UserPreferences } from '../../pageobjects/dashboard/UserPreferences'; - suite(`"Check User Preferences page" test ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); const userPreferences: UserPreferences = e2eContainer.get(CLASSES.UserPreferences); @@ -26,5 +25,4 @@ suite(`"Check User Preferences page" test ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT await userPreferences.openUserPreferencesPage(); await userPreferences.checkTabsAvailability(); }); - }); From 66ed29f126c59b6290362450b7c03762e34c734d Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Thu, 4 Jan 2024 14:40:39 +0200 Subject: [PATCH 04/85] Rewrite test userstory for WTO under admin (#22748) * rewriting WTO UI tests using CHE project --- tests/e2e/configs/inversify.config.ts | 3 +- tests/e2e/configs/inversify.types.ts | 3 +- tests/e2e/constants/REPORTER_CONSTANTS.ts | 16 ++- tests/e2e/index.ts | 2 + .../e2e/pageobjects/openshift/OcpMainPage.ts | 19 --- .../webterminal/WebTerminalPage.ts | 119 ++++++++++++++++++ .../web-terminal/WebTerminalTest.spec.ts | 4 +- .../WebTerminalUnderAdmin.spec.ts | 92 ++++++++++++++ 8 files changed, 230 insertions(+), 28 deletions(-) create mode 100644 tests/e2e/pageobjects/webterminal/WebTerminalPage.ts create mode 100644 tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts diff --git a/tests/e2e/configs/inversify.config.ts b/tests/e2e/configs/inversify.config.ts index 6aba4125dae..0ef3b06aafa 100644 --- a/tests/e2e/configs/inversify.config.ts +++ b/tests/e2e/configs/inversify.config.ts @@ -52,6 +52,7 @@ import { Main as Generator } from '@eclipse-che/che-devworkspace-generator/lib/m import { ContainerTerminal, KubernetesCommandLineToolsExecutor } from '../utils/KubernetesCommandLineToolsExecutor'; import { ShellExecutor } from '../utils/ShellExecutor'; import { UserPreferences } from '../pageobjects/dashboard/UserPreferences'; +import { WebTerminalPage } from "../pageobjects/webterminal/WebTerminalPage"; const e2eContainer: Container = new Container({ defaultScope: 'Transient', skipBaseClassChecks: true }); @@ -85,8 +86,8 @@ e2eContainer.bind(CLASSES.DevfilesRegistryHelper).to(Dev e2eContainer.bind(CLASSES.KubernetesCommandLineToolsExecutor).to(KubernetesCommandLineToolsExecutor); e2eContainer.bind(CLASSES.ShellExecutor).to(ShellExecutor); e2eContainer.bind(CLASSES.ContainerTerminal).to(ContainerTerminal); +e2eContainer.bind(CLASSES.WebTerminalPage).to(WebTerminalPage); e2eContainer.bind(CLASSES.UserPreferences).to(UserPreferences); - e2eContainer.bind(EXTERNAL_CLASSES.Generator).to(Generator); e2eContainer.bind(EXTERNAL_CLASSES.LocatorLoader).to(LocatorLoader); diff --git a/tests/e2e/configs/inversify.types.ts b/tests/e2e/configs/inversify.types.ts index 1e040aecb8c..6308302ce82 100644 --- a/tests/e2e/configs/inversify.types.ts +++ b/tests/e2e/configs/inversify.types.ts @@ -48,7 +48,8 @@ const CLASSES: any = { KubernetesCommandLineToolsExecutor: 'KubernetesCommandLineToolsExecutor', ShellExecutor: 'ShellExecutor', ContainerTerminal: 'ContainerTerminal', - UserPreferences: 'UserPreferences' + UserPreferences: 'UserPreferences', + WebTerminalPage: 'WebTerminalPage' }; const EXTERNAL_CLASSES: any = { diff --git a/tests/e2e/constants/REPORTER_CONSTANTS.ts b/tests/e2e/constants/REPORTER_CONSTANTS.ts index 7987a11e609..5d636bb82de 100644 --- a/tests/e2e/constants/REPORTER_CONSTANTS.ts +++ b/tests/e2e/constants/REPORTER_CONSTANTS.ts @@ -12,7 +12,7 @@ import { MOCHA_CONSTANTS } from './MOCHA_CONSTANTS'; export const REPORTER_CONSTANTS: { DELETE_SCREENCAST_IF_TEST_PASS: boolean; - RP_ENDPOINT(): string; + RP_ENDPOINT(): string | undefined; RP_IS_LOCAL_SERVER: boolean; REPORTERS_ENABLED(): string; RP_API_KEY: string; @@ -124,14 +124,18 @@ export const REPORTER_CONSTANTS: { /** * url with endpoints where ReportPortal is */ - RP_ENDPOINT: (): string => { - return process.env.RP_ENDPOINT || REPORTER_CONSTANTS.RP_IS_LOCAL_SERVER - ? 'http://localhost:8080/api/v1' - : 'https://reportportal-crw.apps.ocp-c1.prod.psi.redhat.com/api/v1'; + RP_ENDPOINT: (): string | undefined => { + if (process.env.RP_ENDPOINTRP_IS_LOCAL_SERVER) { + return 'http://localhost:8080/api/v1'; + } + if (process.env.RP_ENDPOINT !== '') { + return process.env.RP_ENDPOINT; + } + return 'https://reportportal-crw.apps.ocp-c1.prod.psi.redhat.com/api/v1'; }, /** - * use personal project to save launch, if false launch will be send to devspaces or che project, true by default + * use personal project to save launch, if false launch will be sent to devspaces or che project, true by default */ RP_USE_PERSONAL: process.env.RP_USE_PERSONAL !== 'false', diff --git a/tests/e2e/index.ts b/tests/e2e/index.ts index 1f5309042f5..6ac7baade19 100644 --- a/tests/e2e/index.ts +++ b/tests/e2e/index.ts @@ -24,6 +24,7 @@ export * from './utils/workspace/TestWorkspaceUtil'; export * from './utils/workspace/WorkspaceStatus'; export * from './pageobjects/dashboard/CreateWorkspace'; export * from './pageobjects/dashboard/Dashboard'; +export * from './pageobjects/dashboard/UserPreferences'; export * from './pageobjects/dashboard/workspace-details/WorkspaceDetails'; export * from './pageobjects/dashboard/Workspaces'; export * from './pageobjects/git-providers/OauthPage'; @@ -40,6 +41,7 @@ export * from './pageobjects/login/openshift/RegularUserOcpCheLoginPage'; export * from './pageobjects/openshift/OcpApplicationPage'; export * from './pageobjects/openshift/OcpImportFromGitPage'; export * from './pageobjects/openshift/OcpMainPage'; +export * from './pageobjects/webterminal/WebTerminalPage'; export * from './tests-library/LoginTests'; export * from './tests-library/ProjectAndFileTests'; export * from './tests-library/WorkspaceHandlingTests'; diff --git a/tests/e2e/pageobjects/openshift/OcpMainPage.ts b/tests/e2e/pageobjects/openshift/OcpMainPage.ts index 5534f9155d5..41dcd8f4ac2 100644 --- a/tests/e2e/pageobjects/openshift/OcpMainPage.ts +++ b/tests/e2e/pageobjects/openshift/OcpMainPage.ts @@ -26,9 +26,6 @@ export class OcpMainPage { private static readonly SELECT_PROJECT_DROPDOWN: By = By.xpath('//div[@class="co-namespace-dropdown"]//button'); private static readonly PROJECT_FILTER_INPUT: By = By.xpath('//*[@data-test="dropdown-text-filter"]'); private static readonly SKIP_TOUR_BUTTON: By = By.xpath('//*[text()="Skip tour"]'); - private static readonly WEB_TERMINAL_BUTTON: By = By.xpath('//button[@data-quickstart-id="qs-masthead-cloudshell"]'); - private static readonly WEB_TERMINAL_PAGE: By = By.xpath('//*[@class="xterm-helper-textarea"]'); - private static readonly START_WT_COMMAND_LINE_TERMINAL_BUTTON: By = By.xpath('//*[@data-test-id="submit-button"]'); constructor( @inject(CLASSES.DriverHelper) @@ -85,22 +82,6 @@ export class OcpMainPage { await this.driverHelper.waitAndClick(this.getProjectDropdownItemLocator(projectName)); } - async openWebTerminal(): Promise { - Logger.debug(); - - await this.waitOpenMainPage(); - await this.driverHelper.waitAndClick(OcpMainPage.WEB_TERMINAL_BUTTON); - await this.driverHelper.waitAndClick(OcpMainPage.START_WT_COMMAND_LINE_TERMINAL_BUTTON); - await this.driverHelper.waitPresence(OcpMainPage.WEB_TERMINAL_PAGE, TIMEOUT_CONSTANTS.TS_WAIT_LOADER_ABSENCE_TIMEOUT); - } - - async typeToWebTerminal(text: string): Promise { - Logger.debug(); - - await this.driverHelper.waitPresence(OcpMainPage.WEB_TERMINAL_PAGE, TIMEOUT_CONSTANTS.TS_IDE_LOAD_TIMEOUT); - await this.driverHelper.typeToInvisible(OcpMainPage.WEB_TERMINAL_PAGE, text); - } - private getRoleLocator(role: string): By { return By.xpath(`//a//*[text()="${role}"]`); } diff --git a/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts b/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts new file mode 100644 index 00000000000..95579267aff --- /dev/null +++ b/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts @@ -0,0 +1,119 @@ +/** ******************************************************************* + * copyright (c) 2019-2023 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 'reflect-metadata'; +import { inject, injectable } from 'inversify'; +import { DriverHelper } from '../../utils/DriverHelper'; +import { CLASSES } from '../../configs/inversify.types'; +import { By, Key } from 'selenium-webdriver'; +import { Logger } from '../../utils/Logger'; +import { TIMEOUT_CONSTANTS } from '../../constants/TIMEOUT_CONSTANTS'; + +@injectable() +export class WebTerminalPage { + private static readonly TIMEOUT_BUTTON: By = By.xpath('//button[(text()="Timeout")]'); + private static readonly IMAGE_BUTTON: By = By.xpath('//button[(text()="Image")]'); + private static readonly WEB_TERMINAL_BUTTON: By = By.xpath('//button[@data-quickstart-id="qs-masthead-cloudshell"]'); + private static readonly WEB_TERMINAL_PAGE: By = By.xpath('//*[@class="xterm-helper-textarea"]'); + private static readonly START_WT_COMMAND_LINE_TERMINAL_BUTTON: By = By.css('button[data-test-id="submit-button"]'); + private static readonly WEB_TERMINAL_PROJECT_SELECTION_DROPDOWN: By = By.css('input#form-input-namespace-field'); + private static readonly WEB_TERMINAL_PROJECT_CANCEL_BUTTON: By = By.css('button[data-test-id="reset-button"]'); + private static readonly TERMINAL_INACTIVITY_MESS: By = By.xpath('//div[text()="The terminal connection has closed."]'); + private static readonly RESTART_BUTTON: By = By.xpath('//button[text()="Restart terminal"]'); + constructor( + @inject(CLASSES.DriverHelper) + private readonly driverHelper: DriverHelper + ) {} + + async clickOnWebTerminalIcon(): Promise { + Logger.debug(); + await this.driverHelper.waitAndClick(WebTerminalPage.WEB_TERMINAL_BUTTON, TIMEOUT_CONSTANTS.TS_SELENIUM_WAIT_FOR_URL); + } + async waitTerminalIsStarted(): Promise { + Logger.debug(); + await this.driverHelper.waitPresence(WebTerminalPage.WEB_TERMINAL_PAGE, TIMEOUT_CONSTANTS.TS_WAIT_LOADER_ABSENCE_TIMEOUT); + } + async clickOnStartWebTerminalIcon(): Promise { + Logger.debug(); + await this.driverHelper.waitAndClick(WebTerminalPage.START_WT_COMMAND_LINE_TERMINAL_BUTTON); + } + async getAdminProjectName(): Promise { + Logger.debug(); + return await this.driverHelper.waitAndGetValue( + By.css('input#form-input-namespace-field'), + TIMEOUT_CONSTANTS.TS_SELENIUM_WAIT_FOR_URL + ); + } + async openWebTerminal(): Promise { + Logger.debug(); + await this.clickOnWebTerminalIcon(); + await this.clickOnStartWebTerminalIcon(); + await this.waitTerminalIsStarted(); + } + async waitDisabledProjectFieldAndGetProjectName(): Promise { + Logger.debug(); + return await this.driverHelper.waitAndGetElementAttribute(WebTerminalPage.WEB_TERMINAL_PROJECT_SELECTION_DROPDOWN, 'value'); + } + async typeIntoWebTerminal(text: string): Promise { + Logger.debug(); + await this.driverHelper.waitPresence(WebTerminalPage.WEB_TERMINAL_PAGE, TIMEOUT_CONSTANTS.TS_IDE_LOAD_TIMEOUT); + await this.driverHelper.typeToInvisible(WebTerminalPage.WEB_TERMINAL_PAGE, text); + } + + async typeAndEnterIntoWebTerminal(text: string): Promise { + Logger.debug(); + await this.driverHelper.waitPresence(WebTerminalPage.WEB_TERMINAL_PAGE, TIMEOUT_CONSTANTS.TS_IDE_LOAD_TIMEOUT); + await this.driverHelper.typeToInvisible(WebTerminalPage.WEB_TERMINAL_PAGE, text + Key.ENTER); + } + async clickOnProjectListDropDown(): Promise { + Logger.debug(); + { + await this.driverHelper.waitPresence( + WebTerminalPage.WEB_TERMINAL_PROJECT_SELECTION_DROPDOWN, + TIMEOUT_CONSTANTS.TS_COMMON_DASHBOARD_WAIT_TIMEOUT + ); + } + } + async waitTimeoutButton(): Promise { + Logger.debug(); + { + await this.driverHelper.waitPresence(WebTerminalPage.TIMEOUT_BUTTON); + } + } + async waitImageButton(): Promise { + Logger.debug(); + { + await this.driverHelper.waitPresence(WebTerminalPage.IMAGE_BUTTON); + } + } + async waitStartButton(): Promise { + Logger.debug(); + { + await this.driverHelper.waitPresence(WebTerminalPage.START_WT_COMMAND_LINE_TERMINAL_BUTTON); + } + } + + async waitCancelButton(): Promise { + Logger.debug(); + { + await this.driverHelper.waitPresence(WebTerminalPage.WEB_TERMINAL_PROJECT_CANCEL_BUTTON); + } + } + async waitTerminalWidget(): Promise { + Logger.debug(); + await this.waitStartButton(); + await this.waitCancelButton(); + await this.waitTimeoutButton(); + await this.waitImageButton(); + } + async waitTerminalInactivity(): Promise { + await this.driverHelper.waitPresence(WebTerminalPage.TERMINAL_INACTIVITY_MESS, TIMEOUT_CONSTANTS.TS_COMMON_PLUGIN_TEST_TIMEOUT); + await this.driverHelper.waitPresence(WebTerminalPage.RESTART_BUTTON); + } +} diff --git a/tests/e2e/specs/web-terminal/WebTerminalTest.spec.ts b/tests/e2e/specs/web-terminal/WebTerminalTest.spec.ts index 247b5d56a59..deaa2d0af18 100644 --- a/tests/e2e/specs/web-terminal/WebTerminalTest.spec.ts +++ b/tests/e2e/specs/web-terminal/WebTerminalTest.spec.ts @@ -15,9 +15,11 @@ import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS'; import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor'; import { ShellExecutor } from '../../utils/ShellExecutor'; import { expect } from 'chai'; +import { WebTerminalPage } from '../../pageobjects/webterminal/WebTerminalPage'; suite(`Login to Openshift console and start WebTerminal ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); + const webTerminal: WebTerminalPage = e2eContainer.get(CLASSES.WebTerminalPage); const ocpMainPage: OcpMainPage = e2eContainer.get(CLASSES.OcpMainPage); const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get( CLASSES.KubernetesCommandLineToolsExecutor @@ -33,7 +35,7 @@ suite(`Login to Openshift console and start WebTerminal ${BASE_TEST_CONSTANTS.TE test('Open Web Terminal', async function (): Promise { await ocpMainPage.waitOpenMainPage(); - await ocpMainPage.openWebTerminal(); + await webTerminal.openWebTerminal(); }); test('Check username is correct', function (): void { diff --git a/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts b/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts new file mode 100644 index 00000000000..8eba693d1ea --- /dev/null +++ b/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts @@ -0,0 +1,92 @@ +/** ******************************************************************* + * copyright (c) 2024 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 { CLASSES } from '../../configs/inversify.types'; +import { e2eContainer } from '../../configs/inversify.config'; +import { LoginTests } from '../../tests-library/LoginTests'; +import { OcpMainPage } from '../../pageobjects/openshift/OcpMainPage'; +import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS'; +import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor'; +import { ShellExecutor } from '../../utils/ShellExecutor'; +import { DriverHelper } from '../../utils/DriverHelper'; +import { WebTerminalPage } from '../../pageobjects/webterminal/WebTerminalPage'; +import { expect } from 'chai'; +import YAML from 'yaml'; + +suite(`Login to Openshift console and start WebTerminal ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { + const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); + const ocpMainPage: OcpMainPage = e2eContainer.get(CLASSES.OcpMainPage); + const webTerminal: WebTerminalPage = e2eContainer.get(CLASSES.WebTerminalPage); + const shellExecutor: ShellExecutor = e2eContainer.get(CLASSES.ShellExecutor); + const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get( + CLASSES.KubernetesCommandLineToolsExecutor + ); + + const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper); + const webTerminalToolContainerName: string = 'web-terminal-tooling'; + const fileForVerificationTerminalCommands: string = 'result.txt'; + suiteSetup(function (): void { + kubernetesCommandLineToolsExecutor.loginToOcp('admin'); + }); + + loginTests.loginIntoOcpConsole(); + test('Open Web Terminal after first installation', async function (): Promise { + await ocpMainPage.waitOpenMainPage(); + await driverHelper.refreshPage(); + await webTerminal.clickOnWebTerminalIcon(); + }); + test('Verify inactivity dropdown menu for admin user', async function (): Promise { + await webTerminal.clickOnProjectListDropDown(); + }); + test('Verify first started WTO widget and disabled state Project field under admin user', async function (): Promise { + await webTerminal.waitTerminalWidget(); + expect(await webTerminal.waitDisabledProjectFieldAndGetProjectName()).equal('openshift-terminal'); + }); + test('Check starting Web Terminal under admin', async function (): Promise { + kubernetesCommandLineToolsExecutor.namespace = await webTerminal.getAdminProjectName(); + await webTerminal.clickOnStartWebTerminalIcon(); + await webTerminal.waitTerminalIsStarted(); + await webTerminal.typeAndEnterIntoWebTerminal(`oc whoami > ${fileForVerificationTerminalCommands}`); + const devWorkspaceYaml: string = shellExecutor.executeArbitraryShellScript( + `oc get dw -n ${kubernetesCommandLineToolsExecutor.namespace} -o yaml` + ); + kubernetesCommandLineToolsExecutor.workspaceName = YAML.parse(devWorkspaceYaml).items[0].metadata.name; + kubernetesCommandLineToolsExecutor.getPodAndContainerNames(); + const commandResult: string = kubernetesCommandLineToolsExecutor.execInContainerCommand( + `cat /home/user/${fileForVerificationTerminalCommands}`, + webTerminalToolContainerName + ); + expect(commandResult).contains('admin'); + }); + test('Verify help command under admin user', async function (): Promise { + const helpCommandExpectedResult: string = + 'oc \\d+\\.\\d+\\.\\d+ OpenShift CLI\n' + + 'kubectl \\d+\\.\\d+\\.\\d+ Kubernetes CLI\n' + + 'kustomize \\d+\\.\\d+\\.\\d+ Kustomize CLI \\(built-in to kubectl\\)\n' + + 'helm \\d+\\.\\d+\\.\\d+ Helm CLI\n' + + 'kn \\d+\\.\\d+\\.\\d+ KNative CLI\n' + + 'tkn \\d+\\.\\d+\\.\\d+ Tekton CLI\n' + + 'subctl \\d+\\.\\d+\\.\\d+ Submariner CLI\n' + + 'odo \\d+\\.\\d+\\.\\d+ Red Hat OpenShift Developer CLI\n' + + 'virtctl \\d+\\.\\d+\\.\\d+ KubeVirt CLI\n' + + 'jq \\d+\\.\\d+ jq'; + + await webTerminal.typeAndEnterIntoWebTerminal(`help > ${fileForVerificationTerminalCommands}`); + const commandResult: string = kubernetesCommandLineToolsExecutor.execInContainerCommand( + `cat /home/user/${fileForVerificationTerminalCommands}`, + webTerminalToolContainerName + ); + expect(commandResult).to.match(new RegExp(helpCommandExpectedResult)); + }); + + test('Verify help command under admin user', async function (): Promise { + await webTerminal.typeAndEnterIntoWebTerminal('wtoctl set timeout 30s'); + await webTerminal.waitTerminalInactivity(); + }); +}); From a31face1530047b2918fa2addf465077a4b103b1 Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Tue, 9 Jan 2024 15:06:53 +0200 Subject: [PATCH 05/85] update chrome driver to v.120.0 (#22754) --- tests/e2e/build/dockerfiles/Dockerfile | 6 +++--- tests/e2e/package-lock.json | 30 +++++++++++++------------- tests/e2e/package.json | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/e2e/build/dockerfiles/Dockerfile b/tests/e2e/build/dockerfiles/Dockerfile index 83c2e7065aa..f618865cb88 100644 --- a/tests/e2e/build/dockerfiles/Dockerfile +++ b/tests/e2e/build/dockerfiles/Dockerfile @@ -1,12 +1,12 @@ -FROM selenium/standalone-chrome:114.0 +FROM selenium/standalone-chrome:120.0 ENV DISPLAY=':20' USER root RUN apt-get update && apt-get install && \ - apt-get install -y ftp x11vnc ffmpeg libvpx6 && \ - curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - && \ + apt-get install -y ftp x11vnc ffmpeg libvpx7 && \ + curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && \ apt-get install -y nodejs && \ npm install -g typescript && \ node -v diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 95e4d3ac941..f580883c88d 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -33,7 +33,7 @@ "axios": "^0.25.0", "chai": "^4.3.4", "chrome-har": "^0.13.2", - "chromedriver": "^117.0.3", + "chromedriver": "^120.0", "clone-deep": "^4.0.1", "eslint": "^8.45.0", "eslint-config-prettier": "^8.10.0", @@ -1911,19 +1911,19 @@ } }, "node_modules/chromedriver": { - "version": "117.0.3", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz", - "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==", + "version": "120.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-120.0.1.tgz", + "integrity": "sha512-ETTJlkibcAmvoKsaEoq2TFqEsJw18N0O9gOQZX6Uv/XoEiOV8p+IZdidMeIRYELWJIgCZESvlOx5d1QVnB4v0w==", "dev": true, "hasInstallScript": true, "dependencies": { - "@testim/chrome-version": "^1.1.3", - "axios": "^1.4.0", - "compare-versions": "^6.0.0", + "@testim/chrome-version": "^1.1.4", + "axios": "^1.6.0", + "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^1.1.0", - "tcp-port-used": "^1.0.1" + "tcp-port-used": "^1.0.2" }, "bin": { "chromedriver": "bin/chromedriver" @@ -1933,12 +1933,12 @@ } }, "node_modules/chromedriver/node_modules/axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.4.tgz", + "integrity": "sha512-heJnIs6N4aa1eSthhN9M5ioILu8Wi8vmQW9iHQ9NUvfkJb0lEEDUiIdQNAuBtfUt3FxReaKdpQA5DbmMOqzF/A==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -2892,9 +2892,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true, "funding": [ { diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 63a57183d41..808463f401e 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -40,7 +40,7 @@ "axios": "^0.25.0", "chai": "^4.3.4", "chrome-har": "^0.13.2", - "chromedriver": "^117.0.3", + "chromedriver": "^120.0", "clone-deep": "^4.0.1", "eslint": "^8.45.0", "eslint-config-prettier": "^8.10.0", From a25d3b57fc597bc72f9ad52ec5c50ba16612516e Mon Sep 17 00:00:00 2001 From: Mykhailo Kuznietsov Date: Wed, 10 Jan 2024 16:04:48 +0000 Subject: [PATCH 06/85] chore: Bump to 7.81.0-next in main Signed-off-by: Mykhailo Kuznietsov --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- VERSION | 2 +- tests/e2e/configs/inversify.config.ts | 2 +- tests/e2e/configs/mocharc.ts | 18 +++++++++--------- tests/e2e/constants/BASE_TEST_CONSTANTS.ts | 4 ++-- tests/e2e/package-lock.json | 4 ++-- tests/e2e/package.json | 2 +- tests/e2e/specs/MochaHooks.ts | 2 +- .../utils/DevWorkspaceConfigurationHelper.ts | 8 ++++---- 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d8288f1d9c4..ae7a2e35671 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,8 +33,9 @@ body: label: Che version description: if workspace is running, version can be obtained with help/about menu options: - - "7.79@latest" + - "7.80@latest" - "next (development version)" + - "7.79" - "7.78" - "7.77" - "7.75" diff --git a/VERSION b/VERSION index 3b2d88b1625..a8739df289d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.80.0-next +7.81.0-next diff --git a/tests/e2e/configs/inversify.config.ts b/tests/e2e/configs/inversify.config.ts index 0ef3b06aafa..9f647c6de54 100644 --- a/tests/e2e/configs/inversify.config.ts +++ b/tests/e2e/configs/inversify.config.ts @@ -52,7 +52,7 @@ import { Main as Generator } from '@eclipse-che/che-devworkspace-generator/lib/m import { ContainerTerminal, KubernetesCommandLineToolsExecutor } from '../utils/KubernetesCommandLineToolsExecutor'; import { ShellExecutor } from '../utils/ShellExecutor'; import { UserPreferences } from '../pageobjects/dashboard/UserPreferences'; -import { WebTerminalPage } from "../pageobjects/webterminal/WebTerminalPage"; +import { WebTerminalPage } from '../pageobjects/webterminal/WebTerminalPage'; const e2eContainer: Container = new Container({ defaultScope: 'Transient', skipBaseClassChecks: true }); diff --git a/tests/e2e/configs/mocharc.ts b/tests/e2e/configs/mocharc.ts index bb9ef2ce867..7cc86c71074 100644 --- a/tests/e2e/configs/mocharc.ts +++ b/tests/e2e/configs/mocharc.ts @@ -31,15 +31,15 @@ module.exports = { BASE_TEST_CONSTANTS.TEST_ENVIRONMENT !== '' ? `dist/suites/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_SUITE}.suite.js` : // variable MOCHA_DIRECTORY uses in command "test-all-devfiles" and sets up automatically. - // you can set it up to run files from specific directory with export environmental variable. - MOCHA_CONSTANTS.MOCHA_DIRECTORY - ? // to run one file (name without extension). uses in "test", "test-all-devfiles". - MOCHA_CONSTANTS.MOCHA_USERSTORY - ? `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js` - : `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/**.spec.js` - : MOCHA_CONSTANTS.MOCHA_USERSTORY - ? [`dist/specs/**/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`, `dist/specs/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`] - : ['dist/specs/**/**.spec.js', 'dist/specs/**.spec.js'], + // you can set it up to run files from specific directory with export environmental variable. + MOCHA_CONSTANTS.MOCHA_DIRECTORY + ? // to run one file (name without extension). uses in "test", "test-all-devfiles". + MOCHA_CONSTANTS.MOCHA_USERSTORY + ? `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js` + : `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/**.spec.js` + : MOCHA_CONSTANTS.MOCHA_USERSTORY + ? [`dist/specs/**/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`, `dist/specs/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`] + : ['dist/specs/**/**.spec.js', 'dist/specs/**.spec.js'], retries: MOCHA_CONSTANTS.MOCHA_RETRIES, grep: MOCHA_CONSTANTS.MOCHA_GREP }; diff --git a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts index 5f9b320d124..86b38cd0cdb 100644 --- a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts @@ -66,8 +66,8 @@ export const BASE_TEST_CONSTANTS: { return BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('devspaces') ? 'devspaces' : BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('che') - ? 'che' - : 'default'; + ? 'che' + : 'default'; }, /** * testing application version diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index f580883c88d..76f36863c84 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -1,12 +1,12 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.80.0-next", + "version": "7.81.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@eclipse-che/che-e2e", - "version": "7.80.0-next", + "version": "7.81.0-next", "license": "ISC", "dependencies": { "@eclipse-che/api": "latest", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 808463f401e..db4b9ae07b3 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.80.0-next", + "version": "7.81.0-next", "description": "", "main": "dist/index.js", "scripts": { diff --git a/tests/e2e/specs/MochaHooks.ts b/tests/e2e/specs/MochaHooks.ts index 2477a518f87..0eb7caca40a 100644 --- a/tests/e2e/specs/MochaHooks.ts +++ b/tests/e2e/specs/MochaHooks.ts @@ -38,7 +38,7 @@ export function registerRunningWorkspace(workspaceName: string): void { : ((): void => { Logger.debug('delete workspace name'); WorkspaceHandlingTests.clearWorkspaceName(); - })(); + })(); latestWorkspace = workspaceName; } diff --git a/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts b/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts index 54d131eded4..c2289ebd5ba 100644 --- a/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts +++ b/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts @@ -90,10 +90,10 @@ export class DevWorkspaceConfigurationHelper { e.kind === 'DevWorkspace' ? (content.DevWorkspace = e) : e.kind === 'DevWorkspaceTemplate' - ? (content.DevWorkspaceTemplate = e) - : Logger.error( - 'Problems with configuration parsing, string should be in format "DevWorkspace\\n---\\nDevWorkspaceTemplate"' - ); + ? (content.DevWorkspaceTemplate = e) + : Logger.error( + 'Problems with configuration parsing, string should be in format "DevWorkspace\\n---\\nDevWorkspaceTemplate"' + ); }); return content; From 6728732dceb18b56fc1c1a28b739c60ff1a2f8b1 Mon Sep 17 00:00:00 2001 From: Dmytro Nochevnov Date: Thu, 11 Jan 2024 17:05:33 +0200 Subject: [PATCH 07/85] Fix Java sample titles/paths in tests; fix Documentation test (#22761) Signed-off-by: Dmytro Nochevnov --- tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts | 2 +- .../specs/dashboard-samples/Documentation.spec.ts | 12 +++--------- tests/e2e/specs/dashboard-samples/Quarkus.spec.ts | 2 +- tests/performance/api-tests/api-test-lombok.sh | 2 +- tests/performance/api-tests/api-test-quarkus.sh | 2 +- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts b/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts index 2b4406aaa2d..e5ad1ef5469 100644 --- a/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts @@ -13,5 +13,5 @@ export const PLUGIN_TEST_CONSTANTS: { TS_SAMPLE_LIST: string } = { */ TS_SAMPLE_LIST: process.env.TS_SAMPLE_LIST || - 'Node.js MongoDB,Node.js Express,Java 11 with Lombok,Java 11 with Quarkus,Python,.NET,C/C++,Go,PHP,Ansible' + 'Node.js MongoDB,Node.js Express,Java Lombok,Quarkus REST API,Python,.NET,C/C++,Go,PHP,Ansible' }; diff --git a/tests/e2e/specs/dashboard-samples/Documentation.spec.ts b/tests/e2e/specs/dashboard-samples/Documentation.spec.ts index 6280c5f538f..bf02990af6e 100644 --- a/tests/e2e/specs/dashboard-samples/Documentation.spec.ts +++ b/tests/e2e/specs/dashboard-samples/Documentation.spec.ts @@ -40,7 +40,7 @@ suite(`Check links to documentation page in Dashboard ${BASE_TEST_CONSTANTS.TEST const workspaceDetails: WorkspaceDetails = e2eContainer.get(CLASSES.WorkspaceDetails); const shellExecutor: ShellExecutor = e2eContainer.get(CLASSES.ShellExecutor); const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil); - const testingVersion: string = BASE_TEST_CONSTANTS.TESTING_APPLICATION_VERSION; + const majorMinorVersion: string = BASE_TEST_CONSTANTS.TESTING_APPLICATION_VERSION.split('.').slice(0, 2).join('.'); // extract major.minor version from full version let parentGUID: string = ''; let docs: any, links: any, productVersion: any; let webSocketTroubleshooting: any, workspace: any, devfile: any, general: any, storageTypes: any; @@ -55,7 +55,7 @@ suite(`Check links to documentation page in Dashboard ${BASE_TEST_CONSTANTS.TEST try { ({ docs, links, productVersion } = JSON.parse( shellExecutor.curl( - `https://raw.githubusercontent.com/redhat-developer/devspaces-images/devspaces-${testingVersion}-rhel-8/devspaces-dashboard/packages/dashboard-frontend/assets/branding/product.json` + `https://raw.githubusercontent.com/redhat-developer/devspaces-images/devspaces-${majorMinorVersion}-rhel-8/devspaces-dashboard/packages/dashboard-frontend/assets/branding/product.json` ) )); } catch (e) { @@ -71,7 +71,7 @@ suite(`Check links to documentation page in Dashboard ${BASE_TEST_CONSTANTS.TEST test('Check if product.json config contains correct application version', function (): void { [productVersion, links[1].href, devfile, workspace, general, storageTypes, webSocketTroubleshooting].forEach((e): void => { - expect(e, 'Fetched links not matches with tested product version').contains(testingVersion); + expect(e, 'Fetched links not matches with tested product version').contains(majorMinorVersion); }); }); @@ -112,12 +112,6 @@ suite(`Check links to documentation page in Dashboard ${BASE_TEST_CONSTANTS.TEST expect(await workspaceDetails.getOpenStorageTypeDocumentationLink(), '"Storage types" doc link is broken').eqls(storageTypes); }); - test('Check if Workspace Details page contains "Devfile" documentation link', async function (): Promise { - await workspaceDetails.closeStorageTypeInfo(); - await workspaceDetails.selectTab('Devfile'); - expect(await workspaceDetails.getDevfileDocumentationLink(), '"Devfile" doc link is broken').eqls(devfile); - }); - if (BASE_TEST_CONSTANTS.IS_PRODUCT_DOCUMENTATION_RELEASED) { test('Check if product.json documentation links returns status code 200', async function (): Promise { const documentationLinks: string[] = [devfile, workspace, general, storageTypes, webSocketTroubleshooting]; diff --git a/tests/e2e/specs/dashboard-samples/Quarkus.spec.ts b/tests/e2e/specs/dashboard-samples/Quarkus.spec.ts index f1aacb142bd..bdb682129bf 100644 --- a/tests/e2e/specs/dashboard-samples/Quarkus.spec.ts +++ b/tests/e2e/specs/dashboard-samples/Quarkus.spec.ts @@ -21,7 +21,7 @@ import { expect } from 'chai'; import { ITestWorkspaceUtil } from '../../utils/workspace/ITestWorkspaceUtil'; import { Dashboard } from '../../pageobjects/dashboard/Dashboard'; -const stackName: string = 'Java 11 with Quarkus'; +const stackName: string = 'Quarkus REST API'; suite(`The ${stackName} userstory ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests); diff --git a/tests/performance/api-tests/api-test-lombok.sh b/tests/performance/api-tests/api-test-lombok.sh index 1edb00176f2..c85b8f80c8d 100755 --- a/tests/performance/api-tests/api-test-lombok.sh +++ b/tests/performance/api-tests/api-test-lombok.sh @@ -4,7 +4,7 @@ set -e wget -O /tmp/api-utils.sh https://raw.githubusercontent.com/eclipse/che/main/tests/performance/api-tests/api-utils.sh source /tmp/api-utils.sh -export TEST_DEVFILE_PATH="devfile-registry/devfiles/java11-maven-lombok__lombok-project-sample/devworkspace-che-code-latest.yaml" +export TEST_DEVFILE_PATH="devfile-registry/devfiles/java-maven-lombok__lombok-project-sample/devworkspace-che-code-latest.yaml" export WORKSPACE_NAME="java-lombok" export projectName="lombok-project-sample" export expectedCommandOutput="BUILD SUCCESS" diff --git a/tests/performance/api-tests/api-test-quarkus.sh b/tests/performance/api-tests/api-test-quarkus.sh index 8c9dfdbf8e0..c6ce1c03fe2 100644 --- a/tests/performance/api-tests/api-test-quarkus.sh +++ b/tests/performance/api-tests/api-test-quarkus.sh @@ -4,7 +4,7 @@ set -e wget -O /tmp/api-utils.sh https://raw.githubusercontent.com/eclipse/che/main/tests/performance/api-tests/api-utils.sh source /tmp/api-utils.sh -export TEST_DEVFILE_PATH="devfile-registry/devfiles/java11-maven-quarkus__quarkus-quickstarts/devworkspace-che-code-latest.yaml" +export TEST_DEVFILE_PATH="devfile-registry/devfiles/java-maven-quarkus__quarkus-quickstarts/devworkspace-che-code-latest.yaml" export WORKSPACE_NAME="quarkus-quickstart" export projectName="quarkus-quickstarts/getting-started" export expectedCommandOutput="BUILD SUCCESS" From 07ed023e6d80e46c9a1759d7ff25a77d4e9ab535 Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Mon, 15 Jan 2024 01:08:01 +0200 Subject: [PATCH 08/85] Add user story for testing WTO under regular user (#22763) * Add user story for testing WTO under regular user --- .../webterminal/WebTerminalPage.ts | 74 +++++++++++++-- .../WebTerminalUnderAdmin.spec.ts | 13 +-- .../WebTerminalUnderRegularUser.spec.ts | 91 +++++++++++++++++++ 3 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 tests/e2e/specs/web-terminal/WebTerminalUnderRegularUser.spec.ts diff --git a/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts b/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts index 95579267aff..721570338da 100644 --- a/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts +++ b/tests/e2e/pageobjects/webterminal/WebTerminalPage.ts @@ -15,6 +15,11 @@ import { By, Key } from 'selenium-webdriver'; import { Logger } from '../../utils/Logger'; import { TIMEOUT_CONSTANTS } from '../../constants/TIMEOUT_CONSTANTS'; +export enum TimeUnits { + Seconds = 'Seconds', + Minutes = 'Minutes', + Hours = 'Hours' +} @injectable() export class WebTerminalPage { private static readonly TIMEOUT_BUTTON: By = By.xpath('//button[(text()="Timeout")]'); @@ -24,8 +29,18 @@ export class WebTerminalPage { private static readonly START_WT_COMMAND_LINE_TERMINAL_BUTTON: By = By.css('button[data-test-id="submit-button"]'); private static readonly WEB_TERMINAL_PROJECT_SELECTION_DROPDOWN: By = By.css('input#form-input-namespace-field'); private static readonly WEB_TERMINAL_PROJECT_CANCEL_BUTTON: By = By.css('button[data-test-id="reset-button"]'); - private static readonly TERMINAL_INACTIVITY_MESS: By = By.xpath('//div[text()="The terminal connection has closed."]'); + private static readonly TERMINAL_INACTIVITY_MESS: By = By.xpath('//div[contains(text(),"The terminal connection has closed")]'); private static readonly RESTART_BUTTON: By = By.xpath('//button[text()="Restart terminal"]'); + private static readonly PROJECT_NAMESPACE_DROP_DAWN: By = By.css('button#form-ns-dropdown-namespace-field'); + private static readonly PROJECT_SELECTION_FIELD: By = By.css('input[data-test-id="dropdown-text-filter"]'); + private static readonly PROJECT_NAME_FIELD: By = By.css('input#form-input-newNamespace-field'); + private static readonly TIMEOUT_INPUT: By = By.css( + 'input[aria-describedby="form-resource-limit-advancedOptions-timeout-limit-field-helper"]' + ); + private static readonly INCREMENT_TIMEOUT_BTN: By = By.css('button[data-test-id="Decrement"]'); + private static readonly DECREMENT_TIMEOUT_BTN: By = By.css('button[data-test-id="Increment'); + private static readonly TIME_UNIT_DROP_DAWN: By = By.css('div.request-size-input__unit button'); + constructor( @inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper @@ -39,7 +54,7 @@ export class WebTerminalPage { Logger.debug(); await this.driverHelper.waitPresence(WebTerminalPage.WEB_TERMINAL_PAGE, TIMEOUT_CONSTANTS.TS_WAIT_LOADER_ABSENCE_TIMEOUT); } - async clickOnStartWebTerminalIcon(): Promise { + async clickOnStartWebTerminalButton(): Promise { Logger.debug(); await this.driverHelper.waitAndClick(WebTerminalPage.START_WT_COMMAND_LINE_TERMINAL_BUTTON); } @@ -53,7 +68,7 @@ export class WebTerminalPage { async openWebTerminal(): Promise { Logger.debug(); await this.clickOnWebTerminalIcon(); - await this.clickOnStartWebTerminalIcon(); + await this.clickOnStartWebTerminalButton(); await this.waitTerminalIsStarted(); } async waitDisabledProjectFieldAndGetProjectName(): Promise { @@ -112,8 +127,55 @@ export class WebTerminalPage { await this.waitTimeoutButton(); await this.waitImageButton(); } - async waitTerminalInactivity(): Promise { - await this.driverHelper.waitPresence(WebTerminalPage.TERMINAL_INACTIVITY_MESS, TIMEOUT_CONSTANTS.TS_COMMON_PLUGIN_TEST_TIMEOUT); - await this.driverHelper.waitPresence(WebTerminalPage.RESTART_BUTTON); + async waitTerminalInactivity(customTimeout?: number): Promise { + await this.driverHelper.waitVisibility( + WebTerminalPage.TERMINAL_INACTIVITY_MESS, + TIMEOUT_CONSTANTS.TS_COMMON_PLUGIN_TEST_TIMEOUT || customTimeout + ); + + await this.driverHelper.waitVisibility(WebTerminalPage.RESTART_BUTTON); + } + async waitWebTerminalProjectNameField(): Promise { + await this.driverHelper.waitPresence(WebTerminalPage.PROJECT_NAMESPACE_DROP_DAWN); + } + async typeProjectName(projectName: string): Promise { + await this.waitWebTerminalProjectNameField(); + await this.driverHelper.type(WebTerminalPage.PROJECT_NAME_FIELD, projectName, TIMEOUT_CONSTANTS.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM); + } + async openProjectDropDawn(): Promise { + await this.driverHelper.waitAndClick(WebTerminalPage.PROJECT_NAMESPACE_DROP_DAWN); + } + async typeProjectNameForSelecting(projectName: string): Promise { + await this.driverHelper.type(WebTerminalPage.PROJECT_SELECTION_FIELD, projectName); + } + + async selectProjectFromDropDawnList(projectName: string): Promise { + await this.driverHelper.waitAndClick(By.xpath(`//span[@class="pf-c-menu__item-text" and text()="${projectName}"]`)); + } + + async findAndSelectProject(projectName: string): Promise { + await this.openProjectDropDawn(); + await this.typeProjectNameForSelecting(projectName); + await this.selectProjectFromDropDawnList(projectName); + } + async clickOnTimeoutButton(): Promise { + await this.driverHelper.waitAndClick(WebTerminalPage.TIMEOUT_BUTTON); + } + async setTimeoutByEntering(timeValue: number): Promise { + await this.driverHelper.type(WebTerminalPage.TIMEOUT_INPUT, timeValue.toString()); + } + async clickOnPlusBtn(): Promise { + await this.driverHelper.waitAndClick(WebTerminalPage.INCREMENT_TIMEOUT_BTN); + } + + async clickOnMinutesBtn(): Promise { + await this.driverHelper.waitAndClick(WebTerminalPage.DECREMENT_TIMEOUT_BTN); + } + + async clickOnTimeUnitDropDown(): Promise { + await this.driverHelper.waitAndClick(WebTerminalPage.TIME_UNIT_DROP_DAWN); + } + async selectTimeUnit(timeUnits: TimeUnits): Promise { + await this.driverHelper.waitAndClick(By.xpath(`//button[@data-test-id='dropdown-menu' and text()='${timeUnits}']`)); } } diff --git a/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts b/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts index 8eba693d1ea..ecfad2d0f0c 100644 --- a/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts +++ b/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts @@ -27,30 +27,31 @@ suite(`Login to Openshift console and start WebTerminal ${BASE_TEST_CONSTANTS.TE const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get( CLASSES.KubernetesCommandLineToolsExecutor ); - + const defaultWTOProjectNameForAdmin: string = 'openshift-terminal'; const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper); const webTerminalToolContainerName: string = 'web-terminal-tooling'; const fileForVerificationTerminalCommands: string = 'result.txt'; + suiteSetup(function (): void { kubernetesCommandLineToolsExecutor.loginToOcp('admin'); }); + suiteTeardown(function (): void { + shellExecutor.executeArbitraryShellScript(`oc delete dw --all -n ${defaultWTOProjectNameForAdmin}`); + }); loginTests.loginIntoOcpConsole(); test('Open Web Terminal after first installation', async function (): Promise { await ocpMainPage.waitOpenMainPage(); await driverHelper.refreshPage(); await webTerminal.clickOnWebTerminalIcon(); }); - test('Verify inactivity dropdown menu for admin user', async function (): Promise { - await webTerminal.clickOnProjectListDropDown(); - }); test('Verify first started WTO widget and disabled state Project field under admin user', async function (): Promise { await webTerminal.waitTerminalWidget(); - expect(await webTerminal.waitDisabledProjectFieldAndGetProjectName()).equal('openshift-terminal'); + expect(await webTerminal.waitDisabledProjectFieldAndGetProjectName()).equal(defaultWTOProjectNameForAdmin); }); test('Check starting Web Terminal under admin', async function (): Promise { kubernetesCommandLineToolsExecutor.namespace = await webTerminal.getAdminProjectName(); - await webTerminal.clickOnStartWebTerminalIcon(); + await webTerminal.clickOnStartWebTerminalButton(); await webTerminal.waitTerminalIsStarted(); await webTerminal.typeAndEnterIntoWebTerminal(`oc whoami > ${fileForVerificationTerminalCommands}`); const devWorkspaceYaml: string = shellExecutor.executeArbitraryShellScript( diff --git a/tests/e2e/specs/web-terminal/WebTerminalUnderRegularUser.spec.ts b/tests/e2e/specs/web-terminal/WebTerminalUnderRegularUser.spec.ts new file mode 100644 index 00000000000..a6b8dcea30f --- /dev/null +++ b/tests/e2e/specs/web-terminal/WebTerminalUnderRegularUser.spec.ts @@ -0,0 +1,91 @@ +/** ******************************************************************* + * copyright (c) 2024 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 { CLASSES } from '../../configs/inversify.types'; +import { e2eContainer } from '../../configs/inversify.config'; +import { LoginTests } from '../../tests-library/LoginTests'; +import { OcpMainPage } from '../../pageobjects/openshift/OcpMainPage'; +import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS'; +import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor'; +import { ShellExecutor } from '../../utils/ShellExecutor'; +import { DriverHelper } from '../../utils/DriverHelper'; +import { TimeUnits, WebTerminalPage } from '../../pageobjects/webterminal/WebTerminalPage'; +import { expect } from 'chai'; +import YAML from 'yaml'; +import { afterEach } from 'mocha'; +import { By } from 'selenium-webdriver'; + +suite(`Login to Openshift console and check WebTerminal ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { + const webTerminalToolContainerName: string = 'web-terminal-tooling'; + const testProjectName: string = 'wto-under-regular-user-test'; + const fileForVerificationTerminalCommands: string = 'result.txt'; + const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); + const ocpMainPage: OcpMainPage = e2eContainer.get(CLASSES.OcpMainPage); + const webTerminal: WebTerminalPage = e2eContainer.get(CLASSES.WebTerminalPage); + const shellExecutor: ShellExecutor = e2eContainer.get(CLASSES.ShellExecutor); + const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get( + CLASSES.KubernetesCommandLineToolsExecutor + ); + + const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper); + + suiteSetup(function (): void { + kubernetesCommandLineToolsExecutor.loginToOcp(); + }); + + suiteTeardown(function (): void { + kubernetesCommandLineToolsExecutor.deleteProject(testProjectName); + }); + + afterEach(function (): void { + try { + shellExecutor.executeArbitraryShellScript(`oc delete dw --all -n ${testProjectName}`); + } catch (e) { + console.log(`cannot delete the ${testProjectName} under regular user:`, e); + } + }); + + loginTests.loginIntoOcpConsole(); + + test('Open WebTerminal after first installation', async function (): Promise { + await ocpMainPage.waitOpenMainPage(); + await driverHelper.refreshPage(); + await webTerminal.clickOnWebTerminalIcon(); + }); + + test('Check WebTerminal with creating new Openshift Project', async function (): Promise { + kubernetesCommandLineToolsExecutor.namespace = testProjectName; + await webTerminal.typeProjectName(testProjectName); + await webTerminal.clickOnStartWebTerminalButton(); + await webTerminal.waitTerminalIsStarted(); + await webTerminal.typeAndEnterIntoWebTerminal(`oc whoami > ${fileForVerificationTerminalCommands}`); + const devWorkspaceYaml: string = shellExecutor.executeArbitraryShellScript( + `oc get dw -n ${kubernetesCommandLineToolsExecutor.namespace} -o yaml` + ); + kubernetesCommandLineToolsExecutor.workspaceName = YAML.parse(devWorkspaceYaml).items[0].metadata.name; + kubernetesCommandLineToolsExecutor.getPodAndContainerNames(); + const commandResult: string = kubernetesCommandLineToolsExecutor.execInContainerCommand( + `cat /home/user/${fileForVerificationTerminalCommands}`, + webTerminalToolContainerName + ); + const currentUserName: string = await driverHelper.waitAndGetText(By.css('span[data-test="username"]')); + expect(commandResult).contains(currentUserName); + }); + + test('Check running WebTerminal in the existed Project with custom timeout', async function (): Promise { + await webTerminal.findAndSelectProject(testProjectName); + await webTerminal.clickOnTimeoutButton(); + await webTerminal.clickOnTimeUnitDropDown(); + await webTerminal.selectTimeUnit(TimeUnits.Seconds); + await webTerminal.setTimeoutByEntering(20); + await webTerminal.clickOnStartWebTerminalButton(); + await webTerminal.waitTerminalIsStarted(); + await webTerminal.waitTerminalInactivity(); + }); +}); From f7a4289b338e6ca96cc966430f6a4334ad946374 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Mon, 15 Jan 2024 17:25:38 +0200 Subject: [PATCH 09/85] [Test] Add test that revokes OAuth access from Dashboard (#22762) --- tests/e2e/configs/inversify.types.ts | 3 +- .../pageobjects/dashboard/UserPreferences.ts | 42 +++++++++++++++++++ .../specs/miscellaneous/RevokeOauth.spec.ts | 32 ++++++++++++++ .../miscellaneous/UserPreferencesTest.spec.ts | 2 +- 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/e2e/specs/miscellaneous/RevokeOauth.spec.ts diff --git a/tests/e2e/configs/inversify.types.ts b/tests/e2e/configs/inversify.types.ts index 6308302ce82..dd44525a41e 100644 --- a/tests/e2e/configs/inversify.types.ts +++ b/tests/e2e/configs/inversify.types.ts @@ -49,7 +49,8 @@ const CLASSES: any = { ShellExecutor: 'ShellExecutor', ContainerTerminal: 'ContainerTerminal', UserPreferences: 'UserPreferences', - WebTerminalPage: 'WebTerminalPage' + WebTerminalPage: 'WebTerminalPage', + RevokeOauthPage: 'RevokeOauthPage' }; const EXTERNAL_CLASSES: any = { diff --git a/tests/e2e/pageobjects/dashboard/UserPreferences.ts b/tests/e2e/pageobjects/dashboard/UserPreferences.ts index d607508ef5f..1d0f6d4ad6d 100644 --- a/tests/e2e/pageobjects/dashboard/UserPreferences.ts +++ b/tests/e2e/pageobjects/dashboard/UserPreferences.ts @@ -13,6 +13,7 @@ import { CLASSES } from '../../configs/inversify.types'; import { By } from 'selenium-webdriver'; import { DriverHelper } from '../../utils/DriverHelper'; import { Logger } from '../../utils/Logger'; +import { GitProviderType } from '../../constants/FACTORY_TEST_CONSTANTS'; @injectable() export class UserPreferences { @@ -21,7 +22,9 @@ export class UserPreferences { private static readonly USER_PREFERENCES_PAGE: By = By.xpath('//h1[text()="User Preferences"]'); private static readonly CONTAINER_REGISTRIES_TAB: By = By.xpath('//button[text()="Container Registries"]'); + private static readonly GIT_SERVICES_TAB: By = By.xpath('//button[text()="Git Services"]'); + private static readonly GIT_SERVICES_REVOKE_BUTTON: By = By.xpath('//button[text()="Revoke"]'); private static readonly PAT_TAB: By = By.xpath('//button[text()="Personal Access Tokens"]'); private static readonly ADD_NEW_PAT_BUTTON: By = By.xpath('//button[text()="Add Personal Access Token"]'); @@ -31,6 +34,10 @@ export class UserPreferences { private static readonly SSH_KEY_TAB: By = By.xpath('//button[text()="SSH Keys"]'); private static readonly ADD_NEW_SSH_KEY_BUTTON: By = By.xpath('//button[text()="Add SSH Key"]'); + private static readonly CONFIRMATION_WINDOW: By = By.xpath('//span[text()="Revoke Git Services"]'); + private static readonly DELETE_CONFIRMATION_CHECKBOX: By = By.xpath('//input[@data-testid="warning-info-checkbox"]'); + private static readonly DELETE_ITEM_BUTTON_ENABLED: By = By.xpath('//button[@data-testid="revoke-button" and not(@disabled)]'); + constructor( @inject(CLASSES.DriverHelper) readonly driverHelper: DriverHelper @@ -67,6 +74,24 @@ export class UserPreferences { await this.driverHelper.waitAndClick(UserPreferences.GIT_SERVICES_TAB); } + async revokeGitService(servicesName: string): Promise { + Logger.debug(); + + await this.selectListItem(servicesName); + await this.driverHelper.waitAndClick(UserPreferences.GIT_SERVICES_REVOKE_BUTTON); + + await this.driverHelper.waitVisibility(UserPreferences.CONFIRMATION_WINDOW); + await this.driverHelper.waitAndClick(UserPreferences.DELETE_CONFIRMATION_CHECKBOX); + await this.driverHelper.waitAndClick(UserPreferences.DELETE_ITEM_BUTTON_ENABLED); + await this.driverHelper.waitDisappearance(this.getServicesListItemLocator(servicesName)); + } + + async selectListItem(servicesName: string): Promise { + Logger.debug(`of the '${servicesName}' list item`); + + await this.driverHelper.waitAndClick(this.getServicesListItemLocator(servicesName)); + } + async openPatTab(): Promise { Logger.debug(); @@ -86,4 +111,21 @@ export class UserPreferences { await this.driverHelper.waitAndClick(UserPreferences.SSH_KEY_TAB); await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_SSH_KEY_BUTTON); } + + getServiceConfig(service: string): string { + const gitService: { [key: string]: string } = { + [GitProviderType.GITHUB]: 'GitHub', + [GitProviderType.GITLAB]: 'GitLab', + [GitProviderType.AZURE_DEVOPS]: 'Microsoft Azure DevOps', + [GitProviderType.BITBUCKET_CLOUD_OAUTH2]: 'Bitbucket Cloud', + [GitProviderType.BITBUCKET_SERVER_OAUTH1]: 'Bitbucket Server', + [GitProviderType.BITBUCKET_SERVER_OAUTH2]: 'Bitbucket Server' + }; + + return gitService[service]; + } + + private getServicesListItemLocator(servicesName: string): By { + return By.xpath(`//tr[td[text()='${servicesName}']]//input`); + } } diff --git a/tests/e2e/specs/miscellaneous/RevokeOauth.spec.ts b/tests/e2e/specs/miscellaneous/RevokeOauth.spec.ts new file mode 100644 index 00000000000..364e49f69ce --- /dev/null +++ b/tests/e2e/specs/miscellaneous/RevokeOauth.spec.ts @@ -0,0 +1,32 @@ +/** ******************************************************************* + * copyright (c) 2020-2024 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 { e2eContainer } from '../../configs/inversify.config'; +import { CLASSES } from '../../configs/inversify.types'; +import { LoginTests } from '../../tests-library/LoginTests'; +import { UserPreferences } from '../../pageobjects/dashboard/UserPreferences'; +import { FACTORY_TEST_CONSTANTS } from '../../constants/FACTORY_TEST_CONSTANTS'; + +suite('"Revoke OAuth" test', function (): void { + const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests); + const userPreferences: UserPreferences = e2eContainer.get(CLASSES.UserPreferences); + const gitService: string = FACTORY_TEST_CONSTANTS.TS_SELENIUM_FACTORY_GIT_PROVIDER || 'github'; + + suiteSetup('Login', async function (): Promise { + await loginTests.loginIntoChe(); + }); + + test('Revoke OAuth test', async function (): Promise { + await userPreferences.openUserPreferencesPage(); + await userPreferences.openGitServicesTab(); + + const selectedService: string = userPreferences.getServiceConfig(gitService); + await userPreferences.revokeGitService(selectedService); + }); +}); diff --git a/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts b/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts index c4f28353760..cd22c46eeb5 100644 --- a/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts +++ b/tests/e2e/specs/miscellaneous/UserPreferencesTest.spec.ts @@ -21,7 +21,7 @@ suite(`"Check User Preferences page" test ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT await loginTests.loginIntoChe(); }); - test(`Check user preferences page`, async function (): Promise { + test('Check user preferences page', async function (): Promise { await userPreferences.openUserPreferencesPage(); await userPreferences.checkTabsAvailability(); }); From 909fadccf9546d78048d75c6eca11de1bc30e960 Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Wed, 17 Jan 2024 16:30:52 +0100 Subject: [PATCH 10/85] fix: remove unsupported theia badge (#22770) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 371102bdf6d..58448ca18b5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ [![Dev](https://img.shields.io/static/v1?label=Open%20in&message=Che%20dogfooding%20server%20(with%20VS%20Code)&logo=eclipseche&color=FDB940&labelColor=525C86)](https://che-dogfooding.apps.che-dev.x6e0.p1.openshiftapps.com/#https://github.com/eclipse/che?che-editor=che-incubator/che-code/insiders) -[![Dev](https://img.shields.io/static/v1?label=Open%20in&message=Che%20dogfooding%20server%20(with%20Theia)&logo=eclipseche&color=FDB940&labelColor=525C86)](https://che-dogfooding.apps.che-dev.x6e0.p1.openshiftapps.com/#https://github.com/eclipse/che?che-editor=eclipse/che-theia/next) ### Eclipse Che Server has moved! From 0476d6dbe7da73d51c893050658c003577b7a60a Mon Sep 17 00:00:00 2001 From: Nick Boldt Date: Mon, 22 Jan 2024 13:49:53 -0400 Subject: [PATCH 11/85] chore: remove Nick and Tibor as code owners; add Sam Change-Id: I1dabf0a3fbe1547da1091cb6f3927ffbc290b9c9 Signed-off-by: Nick Boldt --- .github/CODEOWNERS | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0438a3140b3..fcbb0de18d0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,11 +1,8 @@ # Global Owners -* @nickboldt - -# dockerfiles -dockerfiles/** @nickboldt +* @dmytro-ndp @SDawley # e2e tests -tests/e2e/** @musienko-maxim @nickboldt @ScrewTSW @dmytro-ndp +tests/e2e/** @musienko-maxim @dmytro-ndp # devworkspace happy path test tests/devworkspace-happy-path/** @musienko-maxim From b489639191e2f1ed2efd42233786dc813f02c5a1 Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Tue, 30 Jan 2024 16:13:21 +0200 Subject: [PATCH 12/85] Fix WorkspaceWithParent test (#22795) * add stabilization parts to the test --- tests/e2e/constants/BASE_TEST_CONSTANTS.ts | 4 ++-- .../miscellaneous/WorkspaceWithParent.spec.ts | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts index 86b38cd0cdb..5f9b320d124 100644 --- a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts @@ -66,8 +66,8 @@ export const BASE_TEST_CONSTANTS: { return BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('devspaces') ? 'devspaces' : BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('che') - ? 'che' - : 'default'; + ? 'che' + : 'default'; }, /** * testing application version diff --git a/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts b/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts index 14efe97b5dc..9e927d61014 100644 --- a/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts +++ b/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts @@ -22,6 +22,8 @@ import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTes import { registerRunningWorkspace } from '../MochaHooks'; import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor'; import { ITestWorkspaceUtil } from '../../utils/workspace/ITestWorkspaceUtil'; +import { DriverHelper } from '../../utils/DriverHelper'; +import { TIMEOUT_CONSTANTS } from '../../constants/TIMEOUT_CONSTANTS'; suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests); @@ -34,6 +36,8 @@ suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMEN const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get( CLASSES.KubernetesCommandLineToolsExecutor ); + const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper); + let podName: string = ''; suiteSetup(function (): void { @@ -51,6 +55,9 @@ suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMEN await workspaceHandlingTests.obtainWorkspaceNameFromStartingPage(); registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName()); await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor(); + // add 10 sec timeout for waiting for finishing animation of all IDE parts (Welcome parts. bottom widgets. etc.) + // using 10 sec easier than performing of finishing animation a all elements + await driverHelper.wait(TIMEOUT_CONSTANTS.TS_SELENIUM_WAIT_FOR_URL); await projectAndFileTests.performTrustAuthorDialog(); }); @@ -68,8 +75,12 @@ suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMEN await input.setText('>Tasks: Run Task'); const runTaskItem: QuickPickItem | undefined = await input.findQuickPick('Tasks: Run Task'); await runTaskItem?.click(); + // pause for avoiding StaleElement exception. It is easier solution than try/catch or writing separate function for this + await driverHelper.wait(TIMEOUT_CONSTANTS.TS_SELENIUM_DEFAULT_POLLING); const devFileTask: QuickPickItem | undefined = await input.findQuickPick('devfile'); await devFileTask?.click(); + // pause for avoiding StaleElement exception. It is easier solution than try/catch or writing separate function for this + await driverHelper.wait(TIMEOUT_CONSTANTS.TS_SELENIUM_DEFAULT_POLLING); const firstExpectedQuickPick: QuickPickItem | undefined = await input.findQuickPick('1. This command from the devfile'); const secondExpectedQuickPick: QuickPickItem | undefined = await input.findQuickPick('2. This command from the parent'); expect(firstExpectedQuickPick).not.undefined; @@ -77,16 +88,16 @@ suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMEN }); test('Check expected containers in the parent POD', function (): void { - const getPodNameCommand: string = `${API_TEST_CONSTANTS.TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL} get pods -n ${BASE_TEST_CONSTANTS.TEST_NAMESPACE} --selector=controller.devfile.io/devworkspace_name=sample-using-parent --output jsonpath=\'{.items[0].metadata.name}\'`; + const getPodNameCommand: string = `${API_TEST_CONSTANTS.TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL} get pods -n ${kubernetesCommandLineToolsExecutor.namespace} --selector=controller.devfile.io/devworkspace_name=sample-using-parent --output jsonpath=\'{.items[0].metadata.name}\'`; podName = shellExecutor.executeArbitraryShellScript(getPodNameCommand); const containerNames: string = shellExecutor.executeArbitraryShellScript( - `${API_TEST_CONSTANTS.TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL} get pod ${podName} -n ${BASE_TEST_CONSTANTS.TEST_NAMESPACE} --output jsonpath=\'{.spec.containers[*].name}\'` + `${API_TEST_CONSTANTS.TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL} get pod ${podName} -n ${kubernetesCommandLineToolsExecutor.namespace} --output jsonpath=\'{.spec.containers[*].name}\'` ); expect(containerNames).contains('tools').and.contains('che-gateway'); const initContainerName: string = shellExecutor.executeArbitraryShellScript( - `${API_TEST_CONSTANTS.TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL} get pod ${podName} -n ${BASE_TEST_CONSTANTS.TEST_NAMESPACE} --output jsonpath=\'{.spec.initContainers[].name}\'` + `${API_TEST_CONSTANTS.TS_API_TEST_KUBERNETES_COMMAND_LINE_TOOL} get pod ${podName} -n ${kubernetesCommandLineToolsExecutor.namespace} --output jsonpath=\'{.spec.initContainers[].name}\'` ); expect(initContainerName).contains('che-code-injector'); }); From 00e282aa4d9e8f90eaa158abf3fd52acdb902ecc Mon Sep 17 00:00:00 2001 From: Mykhailo Kuznietsov Date: Wed, 31 Jan 2024 16:41:35 +0000 Subject: [PATCH 13/85] chore: Bump to 7.82.0-next in main Signed-off-by: Mykhailo Kuznietsov --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- VERSION | 2 +- tests/e2e/constants/BASE_TEST_CONSTANTS.ts | 4 ++-- tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts | 3 +-- tests/e2e/package-lock.json | 4 ++-- tests/e2e/package.json | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ae7a2e35671..ab7ce828592 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,8 +33,9 @@ body: label: Che version description: if workspace is running, version can be obtained with help/about menu options: - - "7.80@latest" + - "7.81@latest" - "next (development version)" + - "7.80" - "7.79" - "7.78" - "7.77" diff --git a/VERSION b/VERSION index a8739df289d..1790d07bfc8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.81.0-next +7.82.0-next diff --git a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts index 5f9b320d124..86b38cd0cdb 100644 --- a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts @@ -66,8 +66,8 @@ export const BASE_TEST_CONSTANTS: { return BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('devspaces') ? 'devspaces' : BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('che') - ? 'che' - : 'default'; + ? 'che' + : 'default'; }, /** * testing application version diff --git a/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts b/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts index e5ad1ef5469..2d524d6a518 100644 --- a/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/PLUGIN_TEST_CONSTANTS.ts @@ -12,6 +12,5 @@ export const PLUGIN_TEST_CONSTANTS: { TS_SAMPLE_LIST: string } = { * dashboard samples to check in RecommendedExtensions.spec.ts */ TS_SAMPLE_LIST: - process.env.TS_SAMPLE_LIST || - 'Node.js MongoDB,Node.js Express,Java Lombok,Quarkus REST API,Python,.NET,C/C++,Go,PHP,Ansible' + process.env.TS_SAMPLE_LIST || 'Node.js MongoDB,Node.js Express,Java Lombok,Quarkus REST API,Python,.NET,C/C++,Go,PHP,Ansible' }; diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 76f36863c84..e3914abe93d 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -1,12 +1,12 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.81.0-next", + "version": "7.82.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@eclipse-che/che-e2e", - "version": "7.81.0-next", + "version": "7.82.0-next", "license": "ISC", "dependencies": { "@eclipse-che/api": "latest", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index db4b9ae07b3..391cf270dbd 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.81.0-next", + "version": "7.82.0-next", "description": "", "main": "dist/index.js", "scripts": { From 8e56965c7b605eea45487df34eeade2919c01fc7 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 13 Feb 2024 17:02:42 +0200 Subject: [PATCH 14/85] [Test] Use test constants to get OCP user name and password in WorkspaceIdleTimeout test (#22818) --- tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts b/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts index b0f35b5539f..b2a89ac7ab6 100644 --- a/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts +++ b/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts @@ -46,7 +46,7 @@ suite('"Check workspace idle timeout" test', function (): void { let stopWorkspaceTimeout: number = 0; suiteSetup(function (): void { - kubernetesCommandLineToolsExecutor.loginToOcp('admin'); + kubernetesCommandLineToolsExecutor.loginToOcp(); shellExecutor.executeCommand('oc project openshift-devspaces'); // get current value of spec.devEnvironments.secondsOfInactivityBeforeIdling From e76edad6aa73ae0737c8dba170fc63c724ec8f4a Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Wed, 14 Feb 2024 12:51:47 +0200 Subject: [PATCH 15/85] [Test] Dev Spaces load tests based on `kubect apply` (#22815) --- tests/performance/load-tests/README.md | 18 +++++ tests/performance/load-tests/load-test.sh | 96 +++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 tests/performance/load-tests/README.md create mode 100755 tests/performance/load-tests/load-test.sh diff --git a/tests/performance/load-tests/README.md b/tests/performance/load-tests/README.md new file mode 100644 index 00000000000..95e79e14792 --- /dev/null +++ b/tests/performance/load-tests/README.md @@ -0,0 +1,18 @@ +# Overview +This script tests how well OpenShift environment can handle running simultaneously many of workspaces. It evaluates the performance of the system under test by checking the average results across all pods and identifying failures that occur during the testing process. + +## Prerequisites +What do you need to run those tests +- `kubectl` client installed +- Openshift cluster with running Openshift DevSpaces +- test user logged into DevSpaces Dashboard(this quaranies that user namespaces are created) + +## Running load tests +1. Log in to Openshift cluster with Openshift DevSpaces or Eclipse Che deployed from terminal +2. Start `load-test.sh` script from `test/e2e/performance/load-tests`. Set number of started workspaces by -c parameter(like ./load-test.sh -c 5). +3. This script gets `cpp` sample devfile.yaml from DevSpaces devfile registry and starts workspaces. +4. As results there are average time of workspace starting and number of failed workspaces. + + +## Results and logs +If workspace failed to start, logs are saved in current directory. diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh new file mode 100755 index 00000000000..ebbca59aa1e --- /dev/null +++ b/tests/performance/load-tests/load-test.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +set -e + +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +function print() { + echo -e "${GREEN}$1${NC}" +} + +function print_error() { + echo -e "${RED}$1${NC}" +} + +function cleanup() { + echo "Clean up the environment" + kubectl delete dw --all > /dev/null + kubectl delete dwt --all > /dev/null +} + +while getopts "c:" opt; do + case $opt in + c) export COMPLETITIONS_COUNT=$OPTARG + ;; + \?) # invalid option + exit 1 + ;; + :) + echo "Option \"$opt\" needs an argument." + exit 1 + ;; + esac +done + +# Set the number of workspaces to start +if [ -z $COMPLETITIONS_COUNT ]; then + echo "Parameter -c wasn't set, setting completitions count to 3." + export COMPLETITIONS_COUNT=3 +fi + +# Checkout to user devspaces namespace +export userName=$(kubectl config view --minify -o jsonpath='{.users[0].name}' | sed 's|/.*||') +kubectl config set-context --current --namespace=$userName-devspaces + +# Delete all dw and dwt objects from test namespace +cleanup + +# Delete logs +rm dw* || true + +# Get Openshift DevSpaces url and path to sample devfile yaml from devfile-registry +export devworkspaceUrl=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' | sed 's/:6443//' | sed 's/api/devspaces.apps/') +export testDevfilePath="devfile-registry/devfiles/TP__cpp__c-plus-plus/devworkspace-che-code-latest.yaml" + +echo "Download the devfile" +curl --insecure "$devworkspaceUrl/$testDevfilePath" -o devfile.yaml + +echo "Start workspaces from sample devfile" +csplit devfile.yaml /---/ +mv xx00 dwt.yaml +mv xx01 dw.yaml +kubectl apply -f dwt.yaml + +for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do + cat dw.yaml | sed "0,/name: cpp/s//name: dw$i/" | kubectl apply -f - +done + +total_time=0 +succeeded=0 +echo "Wait for all workspaces are started and calculate average workspaces starting time" +for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do + if kubectl wait --for=condition=Ready "dw/dw$i" --timeout=120s; then + start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') + end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') + start_timestamp=$(date -d $start_time +%s) + end_timestamp=$(date -d $end_time +%s) + dw_starting_time=$((end_timestamp - start_timestamp)) + + print "Devworkspace dw$i starting time: $dw_starting_time seconds" + total_time=$((total_time + dw_starting_time)) + succeeded=$((succeeded + 1)) + else + print_error "Timeout waiting for dw$i to become ready or an error occurred." + kubectl describe dw dw$i > dw$i-log.log + kubectl logs $(oc get dw dw$i --template='{{.status.devworkspaceId}}') > dw$i-pod.log || true +fi +done + +print "==================== Test results ====================" +print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" +print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." + +trap cleanup ERR EXIT + From a697721b7bd614d049855267a60ea330811dcedb Mon Sep 17 00:00:00 2001 From: Shmaraiev Oleksandr Date: Fri, 16 Feb 2024 18:27:45 +0200 Subject: [PATCH 16/85] Change 'if' expression in 'OcpUserLoginPage' (#22824) --- tests/e2e/pageobjects/login/openshift/OcpUserLoginPage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/pageobjects/login/openshift/OcpUserLoginPage.ts b/tests/e2e/pageobjects/login/openshift/OcpUserLoginPage.ts index c78fb51721a..a242e5f53b2 100644 --- a/tests/e2e/pageobjects/login/openshift/OcpUserLoginPage.ts +++ b/tests/e2e/pageobjects/login/openshift/OcpUserLoginPage.ts @@ -22,7 +22,7 @@ export class OcpUserLoginPage implements IOcpLoginPage { async login(): Promise { Logger.debug(); - if (OAUTH_CONSTANTS.TS_OCP_LOGIN_PAGE_PROVIDER_TITLE !== '') { + if (await this.ocpLogin.isIdentityProviderLinkVisible()) { await this.ocpLogin.waitAndClickOnLoginProviderTitle(); } From 7b8dde416d1f25e70c5d6922952d0401220d80d9 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 20 Feb 2024 11:47:30 +0200 Subject: [PATCH 17/85] wait that github service disabled after OAuth revoking (#22829) --- tests/e2e/pageobjects/dashboard/UserPreferences.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/e2e/pageobjects/dashboard/UserPreferences.ts b/tests/e2e/pageobjects/dashboard/UserPreferences.ts index 1d0f6d4ad6d..9e074e7bc48 100644 --- a/tests/e2e/pageobjects/dashboard/UserPreferences.ts +++ b/tests/e2e/pageobjects/dashboard/UserPreferences.ts @@ -14,6 +14,7 @@ import { By } from 'selenium-webdriver'; import { DriverHelper } from '../../utils/DriverHelper'; import { Logger } from '../../utils/Logger'; import { GitProviderType } from '../../constants/FACTORY_TEST_CONSTANTS'; +import { TIMEOUT_CONSTANTS } from '../../constants/TIMEOUT_CONSTANTS'; @injectable() export class UserPreferences { @@ -83,7 +84,13 @@ export class UserPreferences { await this.driverHelper.waitVisibility(UserPreferences.CONFIRMATION_WINDOW); await this.driverHelper.waitAndClick(UserPreferences.DELETE_CONFIRMATION_CHECKBOX); await this.driverHelper.waitAndClick(UserPreferences.DELETE_ITEM_BUTTON_ENABLED); - await this.driverHelper.waitDisappearance(this.getServicesListItemLocator(servicesName)); + + await this.driverHelper.waitAttributeValue( + this.getServicesListItemLocator(servicesName), + 'disabled', + 'true', + TIMEOUT_CONSTANTS.TS_COMMON_DASHBOARD_WAIT_TIMEOUT + ); } async selectListItem(servicesName: string): Promise { From 962f06bd21a93933b61daf31f184d9ceb03d6148 Mon Sep 17 00:00:00 2001 From: Dmytro Nochevnov Date: Wed, 21 Feb 2024 18:26:09 +0200 Subject: [PATCH 18/85] Update test name in WorkspaceWithParent.spec.ts (#22838) Fix misleading test name to point to child devfile. --- tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts b/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts index 9e927d61014..ba6ddf6b57b 100644 --- a/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts +++ b/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts @@ -48,7 +48,7 @@ suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMEN await loginTests.loginIntoChe(); }); - test('Create a workspace using a parent', async function (): Promise { + test('Create a workspace from child devfile', async function (): Promise { const factoryUrl: string = `${BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL}/dashboard/#https://github.com/testsfactory/parentDevfile`; await dashboard.waitPage(); await browserTabsUtil.navigateTo(factoryUrl); From fe3c6cfc626bc5ad1716a8736750e5cab428c70c Mon Sep 17 00:00:00 2001 From: Mykhailo Kuznietsov Date: Wed, 21 Feb 2024 19:43:59 +0000 Subject: [PATCH 19/85] chore: Bump to 7.83.0-next in main Signed-off-by: Mykhailo Kuznietsov --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- VERSION | 2 +- tests/e2e/package-lock.json | 4 ++-- tests/e2e/package.json | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ab7ce828592..5c930e0992a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,8 +33,9 @@ body: label: Che version description: if workspace is running, version can be obtained with help/about menu options: - - "7.81@latest" + - "7.82@latest" - "next (development version)" + - "7.81" - "7.80" - "7.79" - "7.78" diff --git a/VERSION b/VERSION index 1790d07bfc8..f389fef08a7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.82.0-next +7.83.0-next diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index e3914abe93d..6d619ce67eb 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -1,12 +1,12 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.82.0-next", + "version": "7.83.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@eclipse-che/che-e2e", - "version": "7.82.0-next", + "version": "7.83.0-next", "license": "ISC", "dependencies": { "@eclipse-che/api": "latest", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 391cf270dbd..3cabe6992d1 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.82.0-next", + "version": "7.83.0-next", "description": "", "main": "dist/index.js", "scripts": { From 301503fd01428ce9463dc8d385ab7ce3b1a4cc9f Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Wed, 28 Feb 2024 12:16:20 +0200 Subject: [PATCH 20/85] [Test] Use local devfile.yaml for workspace creation in load-test script (#22855) --- tests/performance/load-tests/devfile.yaml | 20 ++++++++++++++ tests/performance/load-tests/load-test.sh | 33 +++++++++-------------- 2 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 tests/performance/load-tests/devfile.yaml diff --git a/tests/performance/load-tests/devfile.yaml b/tests/performance/load-tests/devfile.yaml new file mode 100644 index 00000000000..f0d42bc66bd --- /dev/null +++ b/tests/performance/load-tests/devfile.yaml @@ -0,0 +1,20 @@ +kind: DevWorkspace +apiVersion: workspace.devfile.io/v1alpha2 +metadata: + name: code-latest +spec: + started: true + template: + components: + - name: dev + container: + image: quay.io/devfile/universal-developer-image:latest + contributions: + - name: che-code + uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml + components: + - name: che-code-runtime-description + container: + env: + - name: CODE_HOST + value: 0.0.0.0 diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index ebbca59aa1e..aedfab093e5 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -40,38 +40,30 @@ if [ -z $COMPLETITIONS_COUNT ]; then export COMPLETITIONS_COUNT=3 fi -# Checkout to user devspaces namespace -export userName=$(kubectl config view --minify -o jsonpath='{.users[0].name}' | sed 's|/.*||') -kubectl config set-context --current --namespace=$userName-devspaces - # Delete all dw and dwt objects from test namespace cleanup # Delete logs -rm dw* || true +rm dw* || true > /dev/null -# Get Openshift DevSpaces url and path to sample devfile yaml from devfile-registry -export devworkspaceUrl=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' | sed 's/:6443//' | sed 's/api/devspaces.apps/') -export testDevfilePath="devfile-registry/devfiles/TP__cpp__c-plus-plus/devworkspace-che-code-latest.yaml" -echo "Download the devfile" -curl --insecure "$devworkspaceUrl/$testDevfilePath" -o devfile.yaml +for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do + cat devfile.yaml | sed "0,/name: code-latest/s//name: dw$i/" | kubectl apply -f - & +done -echo "Start workspaces from sample devfile" -csplit devfile.yaml /---/ -mv xx00 dwt.yaml -mv xx01 dw.yaml -kubectl apply -f dwt.yaml +wait for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - cat dw.yaml | sed "0,/name: cpp/s//name: dw$i/" | kubectl apply -f - + kubectl wait --for=condition=Ready "dw/dw$i" --timeout=180s || true & done +wait + total_time=0 succeeded=0 echo "Wait for all workspaces are started and calculate average workspaces starting time" for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - if kubectl wait --for=condition=Ready "dw/dw$i" --timeout=120s; then + if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') start_timestamp=$(date -d $start_time +%s) @@ -84,13 +76,14 @@ for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do else print_error "Timeout waiting for dw$i to become ready or an error occurred." kubectl describe dw dw$i > dw$i-log.log - kubectl logs $(oc get dw dw$i --template='{{.status.devworkspaceId}}') > dw$i-pod.log || true -fi + kubectl logs $(kubectl get dw dw$i --template='{{.status.devworkspaceId}}') > dw$i-pod.log || true +fi done +wait + print "==================== Test results ====================" print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." trap cleanup ERR EXIT - From a6543def541ef15cb94aca2a631c31993257b09e Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Wed, 28 Feb 2024 11:28:07 +0100 Subject: [PATCH 21/85] fix: Adding ephemeral attribute --- tests/performance/load-tests/devfile.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/performance/load-tests/devfile.yaml b/tests/performance/load-tests/devfile.yaml index f0d42bc66bd..3efa0962aa4 100644 --- a/tests/performance/load-tests/devfile.yaml +++ b/tests/performance/load-tests/devfile.yaml @@ -5,6 +5,8 @@ metadata: spec: started: true template: + attributes: + controller.devfile.io/storage-type: ephemeral components: - name: dev container: From 2fd2e2bf1ac8a219471e9d6308aa23c337de8e71 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Wed, 28 Feb 2024 13:17:44 +0200 Subject: [PATCH 22/85] Increase kubectl wait timeout to 360 in load-test (#22857) --- tests/performance/load-tests/load-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index aedfab093e5..fe933864c09 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -54,7 +54,7 @@ done wait for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - kubectl wait --for=condition=Ready "dw/dw$i" --timeout=180s || true & + kubectl wait --for=condition=Ready "dw/dw$i" --timeout=360s || true & done wait From cd28d98a668ea7208a1659e84d786e64d0b8da13 Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Wed, 28 Feb 2024 13:29:37 +0100 Subject: [PATCH 23/85] chore: Update README.md with contribute badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 58448ca18b5..45583590de1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Contribute](https://www.eclipse.org/che/contribute.svg)](https://workspaces.openshift.com#https://github.com/eclipse/che) [![Dev](https://img.shields.io/static/v1?label=Open%20in&message=Che%20dogfooding%20server%20(with%20VS%20Code)&logo=eclipseche&color=FDB940&labelColor=525C86)](https://che-dogfooding.apps.che-dev.x6e0.p1.openshiftapps.com/#https://github.com/eclipse/che?che-editor=che-incubator/che-code/insiders) ### Eclipse Che Server has moved! From 5a06db1c8e5ba45723667cb469a919c1498ae96a Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Wed, 28 Feb 2024 15:03:49 +0100 Subject: [PATCH 24/85] fix: Update .devfile.yaml (#22859) --- .devfile.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devfile.yaml b/.devfile.yaml index 09016cd731f..c8da7b79e1b 100644 --- a/.devfile.yaml +++ b/.devfile.yaml @@ -12,8 +12,8 @@ metadata: components: - name: devtools container: - image: quay.io/mloriedo/universal-developer-image:ubi8-latest - memoryLimit: 4G + image: quay.io/devfile/universal-developer-image:ubi8-latest + memoryLimit: 12G memoryRequest: 256Mi cpuLimit: '2' cpuRequest: 30m From bdad2b727b4786bc0aee0407cdd8ce7e2145309b Mon Sep 17 00:00:00 2001 From: Tibor Dancs Date: Fri, 1 Mar 2024 14:56:40 +0100 Subject: [PATCH 25/85] Devtools week che dogfooding test development (#22282) * Adding update dependencies command to the che devfile Signed-off-by: Tibor Dancs * Adding project, setting up language metadata, adding container build capabilities Signed-off-by: Tibor Dancs * Updated UBI8 image Signed-off-by: Tibor Dancs * Added default editor configuration Signed-off-by: Tibor Dancs * Removed references to my personal repo and specific branch, updated NodeJS to lts/hydrogen (nodejs 18) Signed-off-by: Tibor Dancs * TODO: Add remote launch capability against dogfooding Signed-off-by: Tibor Dancs --------- Signed-off-by: Tibor Dancs Co-authored-by: Dmytro Nochevnov --- .che/che-editor.yaml | 1 + .devfile.yaml | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 .che/che-editor.yaml diff --git a/.che/che-editor.yaml b/.che/che-editor.yaml new file mode 100644 index 00000000000..b096f7f98bf --- /dev/null +++ b/.che/che-editor.yaml @@ -0,0 +1 @@ +id: che-incubator/che-code/insiders diff --git a/.devfile.yaml b/.devfile.yaml index c8da7b79e1b..b860b492ec8 100644 --- a/.devfile.yaml +++ b/.devfile.yaml @@ -9,6 +9,18 @@ schemaVersion: 2.2.0 metadata: name: che + language: typescript +attributes: + controller.devfile.io/scc: container-build + controller.devfile.io/storage-type: per-workspace +projects: + - name: che + git: + remotes: + origin: 'https://github.com/eclipse/che.git' + checkoutFrom: + remote: origin + revision: main components: - name: devtools container: @@ -17,6 +29,11 @@ components: memoryRequest: 256Mi cpuLimit: '2' cpuRequest: 30m + mountSources: true + sourceMapping: /projects + env: + - name: KUBEDOCK_ENABLED + value: 'true' commands: - id: update-contributing exec: @@ -26,3 +43,38 @@ commands: exec: commandLine: '.repositories-update-contributing.sh IN_DOCKER' component: devtools +- id: tests-update-dependencies + exec: + commandLine: >- + cd tests/e2e && + echo "Installing/Updating nvm" && + curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash && + export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && + nvm --version && + echo "Updating nodejs" && + nvm install lts/hydrogen && nvm alias default lts/hydrogen && nvm use default && + echo "Updating npm" && + npm install -g npm && + echo "Installing test dependencies" && + rm -rf package-lock.json && + npm install && + npm uninstall chromedriver && npm install chromedriver --save-dev && + cd ../../ + component: devtools +- id: tests-lint-project + exec: + commandLine: >- + cd tests/e2e && + npm run lint + component: devtools +- id: tests-build-tests + exec: + commandLine: >- + cd tests/e2e && + npm run tsc + component: devtools +- id: tests-happy-path-remote + exec: + commandLine: >- + echo "TODO: Start pod in dogfooding user namespace and collect logs" + component: devtools From 96cef9fcf01b5f8686369e913c9f416c777c2f4b Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Fri, 1 Mar 2024 16:45:47 +0200 Subject: [PATCH 26/85] update load-tests script (#22860) --- tests/performance/load-tests/README.md | 4 +- .../{devfile.yaml => devworkspace.yaml} | 0 tests/performance/load-tests/load-test.sh | 160 ++++++++++-------- 3 files changed, 95 insertions(+), 69 deletions(-) rename tests/performance/load-tests/{devfile.yaml => devworkspace.yaml} (100%) diff --git a/tests/performance/load-tests/README.md b/tests/performance/load-tests/README.md index 95e79e14792..893a41b1956 100644 --- a/tests/performance/load-tests/README.md +++ b/tests/performance/load-tests/README.md @@ -9,8 +9,8 @@ What do you need to run those tests ## Running load tests 1. Log in to Openshift cluster with Openshift DevSpaces or Eclipse Che deployed from terminal -2. Start `load-test.sh` script from `test/e2e/performance/load-tests`. Set number of started workspaces by -c parameter(like ./load-test.sh -c 5). -3. This script gets `cpp` sample devfile.yaml from DevSpaces devfile registry and starts workspaces. +2. Start `load-test.sh` script from `test/e2e/performance/load-tests`. Set number of started workspaces by -c parameter(like ./load-test.sh -c 5). Set timeout for waiting workspaces to start by -t parameter in seconds(like ./load-test.sh -t 240). +3. This script uses local dewvorspace.yaml to starts workspaces. 4. As results there are average time of workspace starting and number of failed workspaces. diff --git a/tests/performance/load-tests/devfile.yaml b/tests/performance/load-tests/devworkspace.yaml similarity index 100% rename from tests/performance/load-tests/devfile.yaml rename to tests/performance/load-tests/devworkspace.yaml diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index fe933864c09..49820d9fef5 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -6,84 +6,110 @@ GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' # No Color +# Do cleanup if the script is interrupted or fails +trap cleanup ERR SIGINT + function print() { - echo -e "${GREEN}$1${NC}" + echo -e "${GREEN}$1${NC}" } function print_error() { - echo -e "${RED}$1${NC}" + echo -e "${RED}$1${NC}" } function cleanup() { - echo "Clean up the environment" - kubectl delete dw --all > /dev/null - kubectl delete dwt --all > /dev/null + echo "Clean up the environment" + kubectl delete dw --all > /dev/null + kubectl delete dwt --all > /dev/null } -while getopts "c:" opt; do - case $opt in - c) export COMPLETITIONS_COUNT=$OPTARG - ;; - \?) # invalid option - exit 1 - ;; - :) - echo "Option \"$opt\" needs an argument." - exit 1 - ;; - esac -done - -# Set the number of workspaces to start -if [ -z $COMPLETITIONS_COUNT ]; then - echo "Parameter -c wasn't set, setting completitions count to 3." - export COMPLETITIONS_COUNT=3 -fi - -# Delete all dw and dwt objects from test namespace -cleanup - -# Delete logs -rm dw* || true > /dev/null - - -for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - cat devfile.yaml | sed "0,/name: code-latest/s//name: dw$i/" | kubectl apply -f - & -done - -wait - -for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - kubectl wait --for=condition=Ready "dw/dw$i" --timeout=360s || true & -done - -wait +function parseArguments() { + while getopts "t:c:" opt; do + case $opt in + t) export WORKSPACE_IDLE_TIMEOUT=$OPTARG + ;; + c) # Check if the argument to -c is a number + if ! [[ $OPTARG =~ ^[0-9]+$ ]]; then + print_error "Error: Option -c requires a numeric argument." >&2 + exit 1 + fi + export COMPLETITIONS_COUNT=$OPTARG + ;; + \?) + print_error "Invalid option -c. Try for example something like ./load-test.sh -c 7" + exit 1 + ;; + esac + done +} -total_time=0 -succeeded=0 -echo "Wait for all workspaces are started and calculate average workspaces starting time" -for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then - start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') - end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') - start_timestamp=$(date -d $start_time +%s) - end_timestamp=$(date -d $end_time +%s) - dw_starting_time=$((end_timestamp - start_timestamp)) +function setCompletitionsCount() { + # Set the number of workspaces to start + if [ -z $COMPLETITIONS_COUNT ]; then + echo "Parameter -c wasn't set, setting completitions count to 3." + export COMPLETITIONS_COUNT=3 + else + echo "Parameter -c was set to $COMPLETITIONS_COUNT ." + fi + + # Set the number of timeouts for waiting for workspaces to start + if [ -z $WORKSPACE_IDLE_TIMEOUT ]; then + echo "Parameter -t wasn't set, setting timeout to 120 second." + export WORKSPACE_IDLE_TIMEOUT=120 + else + echo "Parameter -t was set to $WORKSPACE_IDLE_TIMEOUT second." + fi +} - print "Devworkspace dw$i starting time: $dw_starting_time seconds" - total_time=$((total_time + dw_starting_time)) - succeeded=$((succeeded + 1)) - else - print_error "Timeout waiting for dw$i to become ready or an error occurred." - kubectl describe dw dw$i > dw$i-log.log - kubectl logs $(kubectl get dw dw$i --template='{{.status.devworkspaceId}}') > dw$i-pod.log || true -fi -done +function runTest() { + # start COMPLETITIONS_COUNT workspaces in parallel + for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do + cat devworkspace.yaml | sed "0,/name: code-latest/s//name: dw$i/" | kubectl apply -f - & + done + wait + + # wait for all workspaces to be started + echo "Wait for all workspaces are started" + for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do + kubectl wait --for=condition=Ready "dw/dw$i" --timeout=${WORKSPACE_IDLE_TIMEOUT}s || true & + done + wait + + # Delete logs on file system if it exists + rm -f logs/dw* + + total_time=0 + succeeded=0 + echo "Calculate average workspaces starting time" + for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do + if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then + start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') + end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') + start_timestamp=$(date -d $start_time +%s) + end_timestamp=$(date -d $end_time +%s) + dw_starting_time=$((end_timestamp - start_timestamp)) + + print "Devworkspace dw$i starting time: $dw_starting_time seconds" + total_time=$((total_time + dw_starting_time)) + succeeded=$((succeeded + 1)) + else + print_error "Timeout waiting for dw$i to become ready or an error occurred." + kubectl describe dw dw$i > logs/dw$i-log.log + kubectl logs $(oc get dw dw$i --template='{{.status.devworkspaceId}}') > logs/dw$i-pod.log || true + fi + done -wait +} -print "==================== Test results ====================" -print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" -print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." +function printResults() { + print "==================== Test results ====================" + print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" + print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." +} -trap cleanup ERR EXIT +parseArguments "$@" +setCompletitionsCount +cleanup +runTest +printResults +cleanup From b2ee337d9dd5f85c7ae283fcddc83d4452a85366 Mon Sep 17 00:00:00 2001 From: Shmaraiev Oleksandr Date: Tue, 5 Mar 2024 15:40:04 +0200 Subject: [PATCH 27/85] Fix up E2E tests related to factory test flow (#22861) * Update files related to factory test flow * Update files according to formatting --- tests/e2e/configs/mocharc.ts | 18 ++++++++-------- tests/e2e/constants/BASE_TEST_CONSTANTS.ts | 4 ++-- .../pageobjects/ide/CheCodeLocatorLoader.ts | 2 +- tests/e2e/specs/MochaHooks.ts | 2 +- tests/e2e/specs/factory/Factory.spec.ts | 21 +++++++------------ .../specs/factory/NoSetupRepoFactory.spec.ts | 10 ++++----- .../specs/factory/RefusedOAuthFactory.spec.ts | 8 +++---- .../utils/DevWorkspaceConfigurationHelper.ts | 8 +++---- 8 files changed, 34 insertions(+), 39 deletions(-) diff --git a/tests/e2e/configs/mocharc.ts b/tests/e2e/configs/mocharc.ts index 7cc86c71074..bb9ef2ce867 100644 --- a/tests/e2e/configs/mocharc.ts +++ b/tests/e2e/configs/mocharc.ts @@ -31,15 +31,15 @@ module.exports = { BASE_TEST_CONSTANTS.TEST_ENVIRONMENT !== '' ? `dist/suites/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_SUITE}.suite.js` : // variable MOCHA_DIRECTORY uses in command "test-all-devfiles" and sets up automatically. - // you can set it up to run files from specific directory with export environmental variable. - MOCHA_CONSTANTS.MOCHA_DIRECTORY - ? // to run one file (name without extension). uses in "test", "test-all-devfiles". - MOCHA_CONSTANTS.MOCHA_USERSTORY - ? `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js` - : `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/**.spec.js` - : MOCHA_CONSTANTS.MOCHA_USERSTORY - ? [`dist/specs/**/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`, `dist/specs/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`] - : ['dist/specs/**/**.spec.js', 'dist/specs/**.spec.js'], + // you can set it up to run files from specific directory with export environmental variable. + MOCHA_CONSTANTS.MOCHA_DIRECTORY + ? // to run one file (name without extension). uses in "test", "test-all-devfiles". + MOCHA_CONSTANTS.MOCHA_USERSTORY + ? `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js` + : `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/**.spec.js` + : MOCHA_CONSTANTS.MOCHA_USERSTORY + ? [`dist/specs/**/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`, `dist/specs/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`] + : ['dist/specs/**/**.spec.js', 'dist/specs/**.spec.js'], retries: MOCHA_CONSTANTS.MOCHA_RETRIES, grep: MOCHA_CONSTANTS.MOCHA_GREP }; diff --git a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts index 86b38cd0cdb..5f9b320d124 100644 --- a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts @@ -66,8 +66,8 @@ export const BASE_TEST_CONSTANTS: { return BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('devspaces') ? 'devspaces' : BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('che') - ? 'che' - : 'default'; + ? 'che' + : 'default'; }, /** * testing application version diff --git a/tests/e2e/pageobjects/ide/CheCodeLocatorLoader.ts b/tests/e2e/pageobjects/ide/CheCodeLocatorLoader.ts index d044ee2f701..176055bf45e 100644 --- a/tests/e2e/pageobjects/ide/CheCodeLocatorLoader.ts +++ b/tests/e2e/pageobjects/ide/CheCodeLocatorLoader.ts @@ -42,7 +42,7 @@ export class CheCodeLocatorLoader extends LocatorLoader { button: By.xpath('//div[@class="monaco-dialog-box"]//a[@class="monaco-button monaco-text-button"]') }, ScmView: { - actionConstructor: (title: string): By => By.xpath(`.//a[@title='${title}']`) + actionConstructor: (title: string): By => By.xpath(`.//a[@aria-label='${title}']`) } }, extras: { diff --git a/tests/e2e/specs/MochaHooks.ts b/tests/e2e/specs/MochaHooks.ts index 0eb7caca40a..2477a518f87 100644 --- a/tests/e2e/specs/MochaHooks.ts +++ b/tests/e2e/specs/MochaHooks.ts @@ -38,7 +38,7 @@ export function registerRunningWorkspace(workspaceName: string): void { : ((): void => { Logger.debug('delete workspace name'); WorkspaceHandlingTests.clearWorkspaceName(); - })(); + })(); latestWorkspace = workspaceName; } diff --git a/tests/e2e/specs/factory/Factory.spec.ts b/tests/e2e/specs/factory/Factory.spec.ts index 37ebddbb0e9..48e78be18db 100644 --- a/tests/e2e/specs/factory/Factory.spec.ts +++ b/tests/e2e/specs/factory/Factory.spec.ts @@ -63,7 +63,6 @@ suite( const timeToRefresh: number = 1500; const changesToCommit: string = new Date().getTime().toString(); const fileToChange: string = 'Date.txt'; - const commitChangesButtonLabel: string = `Commit Changes on "${FACTORY_TEST_CONSTANTS.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}"`; const refreshButtonLabel: string = 'Refresh'; const pushItemLabel: string = 'Push'; let testRepoProjectName: string; @@ -141,8 +140,8 @@ suite( test('Check if the changes are displayed in the source control manager', async function (): Promise { await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); // wait while changes counter will be refreshed await driverHelper.wait(timeToRefresh); const changes: number = await scmProvider.getChangeCount(); @@ -164,8 +163,8 @@ suite( await scmProvider.commitChanges('Commit ' + changesToCommit); await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); // wait while changes counter will be refreshed await driverHelper.wait(timeToRefresh); const changes: number = await scmProvider.getChangeCount(); @@ -174,11 +173,7 @@ suite( }); test('Push the changes', async function (): Promise { - await driverHelper.waitVisibility( - webCheCodeLocators.ScmView.actionConstructor( - `Push 1 commits to origin/${FACTORY_TEST_CONSTANTS.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}` - ) - ); + await driverHelper.waitVisibility(webCheCodeLocators.Notification.action); await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); Logger.debug('scmProvider.openMoreActions'); scmContextMenu = await scmProvider.openMoreActions(); @@ -190,10 +185,10 @@ suite( test('Check if the changes were pushed', async function (): Promise { await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); const isCommitButtonDisabled: string = await driverHelper.waitAndGetElementAttribute( - webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel), + webCheCodeLocators.Notification.action, 'aria-disabled' ); expect(isCommitButtonDisabled).to.equal('true'); diff --git a/tests/e2e/specs/factory/NoSetupRepoFactory.spec.ts b/tests/e2e/specs/factory/NoSetupRepoFactory.spec.ts index 2c2576bff85..9baf6e0f2f8 100644 --- a/tests/e2e/specs/factory/NoSetupRepoFactory.spec.ts +++ b/tests/e2e/specs/factory/NoSetupRepoFactory.spec.ts @@ -158,8 +158,8 @@ suite( test('Check if the changes are displayed in the source control manager', async function (): Promise { await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); // wait while changes counter will be refreshed await driverHelper.wait(timeToRefresh); const changes: number = await scmProvider.getChangeCount(); @@ -181,8 +181,8 @@ suite( await scmProvider.commitChanges('Commit ' + changesToCommit); await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); // wait while changes counter will be refreshed await driverHelper.wait(timeToRefresh); const changes: number = await scmProvider.getChangeCount(); @@ -232,7 +232,7 @@ suite( test('Check if the changes were pushed', async function (): Promise { try { Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); } catch (e) { Logger.info( 'Check you use correct credentials.' + diff --git a/tests/e2e/specs/factory/RefusedOAuthFactory.spec.ts b/tests/e2e/specs/factory/RefusedOAuthFactory.spec.ts index 8fecc558472..bf36f71cc87 100644 --- a/tests/e2e/specs/factory/RefusedOAuthFactory.spec.ts +++ b/tests/e2e/specs/factory/RefusedOAuthFactory.spec.ts @@ -159,8 +159,8 @@ suite( test('Check if the changes are displayed in the source control manager', async function (): Promise { await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); // wait while changes counter will be refreshed await driverHelper.wait(timeToRefresh); const changes: number = await scmProvider.getChangeCount(); @@ -182,8 +182,8 @@ suite( await scmProvider.commitChanges('Commit ' + changesToCommit); await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more); await driverHelper.wait(timeToRefresh); - Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`); - await scmProvider.takeAction(refreshButtonLabel); + Logger.debug(`wait and click on: "${refreshButtonLabel}"`); + await driverHelper.waitAndClick(webCheCodeLocators.ScmView.actionConstructor(refreshButtonLabel)); // wait while changes counter will be refreshed await driverHelper.wait(timeToRefresh); const changes: number = await scmProvider.getChangeCount(); diff --git a/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts b/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts index c2289ebd5ba..54d131eded4 100644 --- a/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts +++ b/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts @@ -90,10 +90,10 @@ export class DevWorkspaceConfigurationHelper { e.kind === 'DevWorkspace' ? (content.DevWorkspace = e) : e.kind === 'DevWorkspaceTemplate' - ? (content.DevWorkspaceTemplate = e) - : Logger.error( - 'Problems with configuration parsing, string should be in format "DevWorkspace\\n---\\nDevWorkspaceTemplate"' - ); + ? (content.DevWorkspaceTemplate = e) + : Logger.error( + 'Problems with configuration parsing, string should be in format "DevWorkspace\\n---\\nDevWorkspaceTemplate"' + ); }); return content; From c6982af6fd9b3849eccab85cf7b8dac5455d0ae7 Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Wed, 6 Mar 2024 18:50:12 +0200 Subject: [PATCH 28/85] Change regexp in WebTerminalUnderRegularUser (#22867) * Change regexp in WebTerminalUnderRegularUser update selenium in the test Image --- tests/e2e/build/dockerfiles/Dockerfile | 2 +- tests/e2e/package-lock.json | 294 ++++++++++++++++-- tests/e2e/package.json | 2 +- .../WebTerminalUnderAdmin.spec.ts | 20 +- 4 files changed, 286 insertions(+), 32 deletions(-) diff --git a/tests/e2e/build/dockerfiles/Dockerfile b/tests/e2e/build/dockerfiles/Dockerfile index f618865cb88..d7f19d44b0a 100644 --- a/tests/e2e/build/dockerfiles/Dockerfile +++ b/tests/e2e/build/dockerfiles/Dockerfile @@ -1,4 +1,4 @@ -FROM selenium/standalone-chrome:120.0 +FROM selenium/standalone-chrome:122.0 ENV DISPLAY=':20' diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 6d619ce67eb..096e49f68fa 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -33,7 +33,7 @@ "axios": "^0.25.0", "chai": "^4.3.4", "chrome-har": "^0.13.2", - "chromedriver": "^120.0", + "chromedriver": "^122.0", "clone-deep": "^4.0.1", "eslint": "^8.45.0", "eslint-config-prettier": "^8.10.0", @@ -724,6 +724,12 @@ "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", "dev": true }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -1135,15 +1141,15 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", "dev": true, "dependencies": { - "debug": "4" + "debug": "^4.3.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -1324,6 +1330,18 @@ "node": "*" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1644,6 +1662,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -1911,17 +1938,17 @@ } }, "node_modules/chromedriver": { - "version": "120.0.1", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-120.0.1.tgz", - "integrity": "sha512-ETTJlkibcAmvoKsaEoq2TFqEsJw18N0O9gOQZX6Uv/XoEiOV8p+IZdidMeIRYELWJIgCZESvlOx5d1QVnB4v0w==", + "version": "122.0.4", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-122.0.4.tgz", + "integrity": "sha512-MxkaWaxCqefHyh9UorGzl1F6ZNBgC7pqgT0piAysLZdw20ojSgJ62ljG8SFbhDJqBTegKbmuioa6MQ1m4Czdsg==", "dev": true, "hasInstallScript": true, "dependencies": { "@testim/chrome-version": "^1.1.4", - "axios": "^1.6.0", + "axios": "^1.6.7", "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", - "https-proxy-agent": "^5.0.1", + "proxy-agent": "^6.4.0", "proxy-from-env": "^1.1.0", "tcp-port-used": "^1.0.2" }, @@ -1933,9 +1960,9 @@ } }, "node_modules/chromedriver/node_modules/axios": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.4.tgz", - "integrity": "sha512-heJnIs6N4aa1eSthhN9M5ioILu8Wi8vmQW9iHQ9NUvfkJb0lEEDUiIdQNAuBtfUt3FxReaKdpQA5DbmMOqzF/A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dev": true, "dependencies": { "follow-redirects": "^1.15.4", @@ -2109,6 +2136,15 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/dayjs": { "version": "1.11.7", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", @@ -2330,6 +2366,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2430,6 +2480,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint": { "version": "8.49.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", @@ -2607,7 +2688,6 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "peer": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2993,6 +3073,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dev": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3177,6 +3286,19 @@ "node": ">=0.10.0" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3193,16 +3315,16 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dev": true, "dependencies": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -3323,6 +3445,31 @@ "integrity": "sha512-/seBlVp5bXrLQS3DpKEmlgeZL6C7Tf/QITd+IMQrbBBGuCbxb7k3hRAWu9XSreNpFzLgSboz3sClLSEmGwHphw==", "dev": true }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, "node_modules/ip-regex": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", @@ -4186,6 +4333,15 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4332,6 +4488,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dev": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -4491,6 +4679,34 @@ "node": ">=0.10" } }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -4926,6 +5142,44 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 3cabe6992d1..0b34943012c 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -40,7 +40,7 @@ "axios": "^0.25.0", "chai": "^4.3.4", "chrome-har": "^0.13.2", - "chromedriver": "^120.0", + "chromedriver": "^122.0", "clone-deep": "^4.0.1", "eslint": "^8.45.0", "eslint-config-prettier": "^8.10.0", diff --git a/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts b/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts index ecfad2d0f0c..38e69a45e80 100644 --- a/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts +++ b/tests/e2e/specs/web-terminal/WebTerminalUnderAdmin.spec.ts @@ -67,16 +67,16 @@ suite(`Login to Openshift console and start WebTerminal ${BASE_TEST_CONSTANTS.TE }); test('Verify help command under admin user', async function (): Promise { const helpCommandExpectedResult: string = - 'oc \\d+\\.\\d+\\.\\d+ OpenShift CLI\n' + - 'kubectl \\d+\\.\\d+\\.\\d+ Kubernetes CLI\n' + - 'kustomize \\d+\\.\\d+\\.\\d+ Kustomize CLI \\(built-in to kubectl\\)\n' + - 'helm \\d+\\.\\d+\\.\\d+ Helm CLI\n' + - 'kn \\d+\\.\\d+\\.\\d+ KNative CLI\n' + - 'tkn \\d+\\.\\d+\\.\\d+ Tekton CLI\n' + - 'subctl \\d+\\.\\d+\\.\\d+ Submariner CLI\n' + - 'odo \\d+\\.\\d+\\.\\d+ Red Hat OpenShift Developer CLI\n' + - 'virtctl \\d+\\.\\d+\\.\\d+ KubeVirt CLI\n' + - 'jq \\d+\\.\\d+ jq'; + 'oc.*\\d+\\.\\d+\\.\\d+.*OpenShift CLI\n' + + 'kubectl.*\\d+\\.\\d+\\.\\d+.*Kubernetes CLI\n' + + 'kustomize.*\\d+\\.\\d+\\.\\d+.*Kustomize CLI \\(built-in to kubectl\\)\n' + + 'helm.*\\d+\\.\\d+\\.\\d+.*Helm CLI\n' + + 'kn.*\\d+\\.\\d+\\.\\d+.*KNative CLI\n' + + 'tkn.*\\d+\\.\\d+\\.\\d+.*Tekton CLI\n' + + 'subctl.*\\d+\\.\\d+\\.\\d+.*Submariner CLI\n' + + 'odo.*\\d+\\.\\d+\\.\\d+.*Red Hat OpenShift Developer CLI\n' + + 'virtctl.*\\d+\\.\\d+\\.\\d+.*KubeVirt CLI\n' + + 'jq.*\\d+\\.\\d+.*jq'; await webTerminal.typeAndEnterIntoWebTerminal(`help > ${fileForVerificationTerminalCommands}`); const commandResult: string = kubernetesCommandLineToolsExecutor.execInContainerCommand( From e0487a2b2cdf737f5fac126435d8c3b7b1b642a7 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Fri, 8 Mar 2024 14:25:28 +0200 Subject: [PATCH 29/85] [Test] Format load-test script, correct 'no workspaces started' error handling (#22872) * format load-test script --- tests/performance/load-tests/load-test.sh | 154 +++++++++++----------- 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index 49820d9fef5..4f678d0b986 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -10,101 +10,107 @@ NC='\033[0m' # No Color trap cleanup ERR SIGINT function print() { - echo -e "${GREEN}$1${NC}" + echo -e "${GREEN}$1${NC}" } function print_error() { - echo -e "${RED}$1${NC}" + echo -e "${RED}$1${NC}" } function cleanup() { - echo "Clean up the environment" - kubectl delete dw --all > /dev/null - kubectl delete dwt --all > /dev/null + echo "Clean up the environment" + kubectl delete dw --all >/dev/null + kubectl delete dwt --all >/dev/null } function parseArguments() { while getopts "t:c:" opt; do - case $opt in - t) export WORKSPACE_IDLE_TIMEOUT=$OPTARG - ;; - c) # Check if the argument to -c is a number - if ! [[ $OPTARG =~ ^[0-9]+$ ]]; then - print_error "Error: Option -c requires a numeric argument." >&2 - exit 1 - fi - export COMPLETITIONS_COUNT=$OPTARG - ;; - \?) - print_error "Invalid option -c. Try for example something like ./load-test.sh -c 7" - exit 1 - ;; - esac - done + case $opt in + t) + export WORKSPACE_IDLE_TIMEOUT=$OPTARG + ;; + c) # Check if the argument to -c is a number + if ! [[ $OPTARG =~ ^[0-9]+$ ]]; then + print_error "Error: Option -c requires a numeric argument." >&2 + exit 1 + fi + export COMPLETITIONS_COUNT=$OPTARG + ;; + \?) + print_error "Invalid option -c. Try for example something like ./load-test.sh -c 7" + exit 1 + ;; + esac + done } function setCompletitionsCount() { - # Set the number of workspaces to start - if [ -z $COMPLETITIONS_COUNT ]; then - echo "Parameter -c wasn't set, setting completitions count to 3." - export COMPLETITIONS_COUNT=3 - else - echo "Parameter -c was set to $COMPLETITIONS_COUNT ." - fi - - # Set the number of timeouts for waiting for workspaces to start - if [ -z $WORKSPACE_IDLE_TIMEOUT ]; then - echo "Parameter -t wasn't set, setting timeout to 120 second." - export WORKSPACE_IDLE_TIMEOUT=120 - else - echo "Parameter -t was set to $WORKSPACE_IDLE_TIMEOUT second." - fi + # Set the number of workspaces to start + if [ -z $COMPLETITIONS_COUNT ]; then + echo "Parameter -c wasn't set, setting completitions count to 3." + export COMPLETITIONS_COUNT=3 + else + echo "Parameter -c was set to $COMPLETITIONS_COUNT ." + fi + + # Set the number of timeouts for waiting for workspaces to start + if [ -z $WORKSPACE_IDLE_TIMEOUT ]; then + echo "Parameter -t wasn't set, setting timeout to 120 second." + export WORKSPACE_IDLE_TIMEOUT=120 + else + echo "Parameter -t was set to $WORKSPACE_IDLE_TIMEOUT second." + fi } function runTest() { - # start COMPLETITIONS_COUNT workspaces in parallel - for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - cat devworkspace.yaml | sed "0,/name: code-latest/s//name: dw$i/" | kubectl apply -f - & - done - wait - - # wait for all workspaces to be started - echo "Wait for all workspaces are started" - for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - kubectl wait --for=condition=Ready "dw/dw$i" --timeout=${WORKSPACE_IDLE_TIMEOUT}s || true & - done - wait - - # Delete logs on file system if it exists - rm -f logs/dw* - - total_time=0 - succeeded=0 - echo "Calculate average workspaces starting time" - for ((i=1; i<=$COMPLETITIONS_COUNT; i++)); do - if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then - start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') - end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') - start_timestamp=$(date -d $start_time +%s) - end_timestamp=$(date -d $end_time +%s) - dw_starting_time=$((end_timestamp - start_timestamp)) - - print "Devworkspace dw$i starting time: $dw_starting_time seconds" - total_time=$((total_time + dw_starting_time)) - succeeded=$((succeeded + 1)) - else - print_error "Timeout waiting for dw$i to become ready or an error occurred." - kubectl describe dw dw$i > logs/dw$i-log.log - kubectl logs $(oc get dw dw$i --template='{{.status.devworkspaceId}}') > logs/dw$i-pod.log || true + # start COMPLETITIONS_COUNT workspaces in parallel + for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do + cat devworkspace.yaml | sed "0,/name: code-latest/s//name: dw$i/" | kubectl apply -f - & + done + wait + + # wait for all workspaces to be started + echo "Wait for all workspaces are started" + for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do + kubectl wait --for=condition=Ready "dw/dw$i" --timeout=${WORKSPACE_IDLE_TIMEOUT}s || true & + done + wait + + # Delete logs on file system if it exists + rm -f logs/dw* + + total_time=0 + succeeded=0 + echo "Calculate average workspaces starting time" + for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do + if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then + start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') + end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') + start_timestamp=$(date -d $start_time +%s) + end_timestamp=$(date -d $end_time +%s) + dw_starting_time=$((end_timestamp - start_timestamp)) + + print "Devworkspace dw$i starting time: $dw_starting_time seconds" + total_time=$((total_time + dw_starting_time)) + succeeded=$((succeeded + 1)) + else + print_error "Timeout waiting for dw$i to become ready or an error occurred." + kubectl describe dw dw$i >logs/dw$i-log.log + kubectl logs $(kubectl get dw dw$i --template='{{.status.devworkspaceId}}') >logs/dw$i-pod.log || true fi - done + done } function printResults() { - print "==================== Test results ====================" - print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" - print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." + print "==================== Test results ====================" + if [ $succeeded -eq 0 ]; then + print_error "No workspaces started successfully." + exit 1 + else + print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" + fi + print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." } parseArguments "$@" From 693d93a5b889b9ea12bcec67fd14d1360c4697c4 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Fri, 8 Mar 2024 14:39:41 +0200 Subject: [PATCH 30/85] precreate logs folder (#22874) --- tests/performance/load-tests/load-test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index 4f678d0b986..eb21d39be81 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -78,6 +78,8 @@ function runTest() { # Delete logs on file system if it exists rm -f logs/dw* + # Create logs directory + mkdir logs || true total_time=0 succeeded=0 From c9a069fd8acf5fe19abaf89f1f9ced9b1aca2d1c Mon Sep 17 00:00:00 2001 From: Mykhailo Kuznietsov Date: Fri, 15 Mar 2024 18:15:33 +0000 Subject: [PATCH 31/85] chore: Bump to 7.84.0-next in main Signed-off-by: Mykhailo Kuznietsov --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- VERSION | 2 +- tests/e2e/configs/mocharc.ts | 18 +++++++++--------- tests/e2e/constants/BASE_TEST_CONSTANTS.ts | 4 ++-- tests/e2e/package-lock.json | 4 ++-- tests/e2e/package.json | 2 +- tests/e2e/specs/MochaHooks.ts | 2 +- .../utils/DevWorkspaceConfigurationHelper.ts | 8 ++++---- 8 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5c930e0992a..872251204cf 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,8 +33,9 @@ body: label: Che version description: if workspace is running, version can be obtained with help/about menu options: - - "7.82@latest" + - "7.83@latest" - "next (development version)" + - "7.82" - "7.81" - "7.80" - "7.79" diff --git a/VERSION b/VERSION index f389fef08a7..1cd302ef8a8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.83.0-next +7.84.0-next diff --git a/tests/e2e/configs/mocharc.ts b/tests/e2e/configs/mocharc.ts index bb9ef2ce867..7cc86c71074 100644 --- a/tests/e2e/configs/mocharc.ts +++ b/tests/e2e/configs/mocharc.ts @@ -31,15 +31,15 @@ module.exports = { BASE_TEST_CONSTANTS.TEST_ENVIRONMENT !== '' ? `dist/suites/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_SUITE}.suite.js` : // variable MOCHA_DIRECTORY uses in command "test-all-devfiles" and sets up automatically. - // you can set it up to run files from specific directory with export environmental variable. - MOCHA_CONSTANTS.MOCHA_DIRECTORY - ? // to run one file (name without extension). uses in "test", "test-all-devfiles". - MOCHA_CONSTANTS.MOCHA_USERSTORY - ? `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js` - : `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/**.spec.js` - : MOCHA_CONSTANTS.MOCHA_USERSTORY - ? [`dist/specs/**/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`, `dist/specs/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`] - : ['dist/specs/**/**.spec.js', 'dist/specs/**.spec.js'], + // you can set it up to run files from specific directory with export environmental variable. + MOCHA_CONSTANTS.MOCHA_DIRECTORY + ? // to run one file (name without extension). uses in "test", "test-all-devfiles". + MOCHA_CONSTANTS.MOCHA_USERSTORY + ? `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js` + : `dist/specs/${MOCHA_CONSTANTS.MOCHA_DIRECTORY}/**.spec.js` + : MOCHA_CONSTANTS.MOCHA_USERSTORY + ? [`dist/specs/**/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`, `dist/specs/${MOCHA_CONSTANTS.MOCHA_USERSTORY}.spec.js`] + : ['dist/specs/**/**.spec.js', 'dist/specs/**.spec.js'], retries: MOCHA_CONSTANTS.MOCHA_RETRIES, grep: MOCHA_CONSTANTS.MOCHA_GREP }; diff --git a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts index 5f9b320d124..86b38cd0cdb 100644 --- a/tests/e2e/constants/BASE_TEST_CONSTANTS.ts +++ b/tests/e2e/constants/BASE_TEST_CONSTANTS.ts @@ -66,8 +66,8 @@ export const BASE_TEST_CONSTANTS: { return BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('devspaces') ? 'devspaces' : BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL.includes('che') - ? 'che' - : 'default'; + ? 'che' + : 'default'; }, /** * testing application version diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 096e49f68fa..78bbc24d4e0 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -1,12 +1,12 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.83.0-next", + "version": "7.84.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@eclipse-che/che-e2e", - "version": "7.83.0-next", + "version": "7.84.0-next", "license": "ISC", "dependencies": { "@eclipse-che/api": "latest", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 0b34943012c..ee2614634cb 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.83.0-next", + "version": "7.84.0-next", "description": "", "main": "dist/index.js", "scripts": { diff --git a/tests/e2e/specs/MochaHooks.ts b/tests/e2e/specs/MochaHooks.ts index 2477a518f87..0eb7caca40a 100644 --- a/tests/e2e/specs/MochaHooks.ts +++ b/tests/e2e/specs/MochaHooks.ts @@ -38,7 +38,7 @@ export function registerRunningWorkspace(workspaceName: string): void { : ((): void => { Logger.debug('delete workspace name'); WorkspaceHandlingTests.clearWorkspaceName(); - })(); + })(); latestWorkspace = workspaceName; } diff --git a/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts b/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts index 54d131eded4..c2289ebd5ba 100644 --- a/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts +++ b/tests/e2e/utils/DevWorkspaceConfigurationHelper.ts @@ -90,10 +90,10 @@ export class DevWorkspaceConfigurationHelper { e.kind === 'DevWorkspace' ? (content.DevWorkspace = e) : e.kind === 'DevWorkspaceTemplate' - ? (content.DevWorkspaceTemplate = e) - : Logger.error( - 'Problems with configuration parsing, string should be in format "DevWorkspace\\n---\\nDevWorkspaceTemplate"' - ); + ? (content.DevWorkspaceTemplate = e) + : Logger.error( + 'Problems with configuration parsing, string should be in format "DevWorkspace\\n---\\nDevWorkspaceTemplate"' + ); }); return content; From 77799bf440bc6490d807f28bfa3e2c00037df6ed Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 19 Mar 2024 16:45:24 +0200 Subject: [PATCH 32/85] check dialog buttons in WorkspaceIdleTimeout test (#22885) --- .../WorkspaceIdleTimeout.spec.ts | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts b/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts index b2a89ac7ab6..9bc98d34576 100644 --- a/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts +++ b/tests/e2e/specs/miscellaneous/WorkspaceIdleTimeout.spec.ts @@ -18,12 +18,11 @@ import { Workspaces } from '../../pageobjects/dashboard/Workspaces'; import { TIMEOUT_CONSTANTS } from '../../constants/TIMEOUT_CONSTANTS'; import { DriverHelper } from '../../utils/DriverHelper'; import { CheCodeLocatorLoader } from '../../pageobjects/ide/CheCodeLocatorLoader'; -import { Locators, ModalDialog } from 'monaco-page-objects'; +import { By, Locators, ModalDialog } from 'monaco-page-objects'; import { expect } from 'chai'; import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor'; import { ShellExecutor } from '../../utils/ShellExecutor'; import { ITestWorkspaceUtil } from '../../utils/workspace/ITestWorkspaceUtil'; -import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil'; suite('"Check workspace idle timeout" test', function (): void { const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests); @@ -39,12 +38,15 @@ suite('"Check workspace idle timeout" test', function (): void { ); const shellExecutor: ShellExecutor = e2eContainer.get(CLASSES.ShellExecutor); const testWorkspaceUtil: ITestWorkspaceUtil = e2eContainer.get(TYPES.WorkspaceUtil); - const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil); const stackName: string = 'Empty Workspace'; const cheClusterName: string = 'devspaces'; let stopWorkspaceTimeout: number = 0; + async function checkDialogButton(buttonName: string): Promise { + await driverHelper.waitVisibility(By.xpath(`//div[@class='dialog-buttons']//a[text()='${buttonName}']`)); + } + suiteSetup(function (): void { kubernetesCommandLineToolsExecutor.loginToOcp(); shellExecutor.executeCommand('oc project openshift-devspaces'); @@ -84,21 +86,18 @@ suite('"Check workspace idle timeout" test', function (): void { await projectAndFileTests.performTrustAuthorDialog(); }); - test('Wait idle timeout dialog and click on "Return to Dashboard" button', async function (): Promise { + test('Wait idle timeout dialog and check Dialog buttons', async function (): Promise { await driverHelper.waitVisibility(webCheCodeLocators.Dialog.details, TIMEOUT_CONSTANTS.TS_SELENIUM_START_WORKSPACE_TIMEOUT); const dialog: ModalDialog = new ModalDialog(); expect(await dialog.getDetails()).includes('Your workspace has stopped due to inactivity.'); - await dialog.pushButton('Return to dashboard'); + await checkDialogButton('Cancel'); + await checkDialogButton('Return to dashboard'); + await checkDialogButton('Restart your workspace'); }); test('Check that the workspace has Stopped state', async function (): Promise { - await dashboard.waitPage(); - await workspaces.waitWorkspaceWithStoppedStatus(WorkspaceHandlingTests.getWorkspaceName()); - }); - - suiteTeardown('Open dashboard and close all other tabs', async function (): Promise { await dashboard.openDashboard(); - await browserTabsUtil.closeAllTabsExceptCurrent(); + await workspaces.waitWorkspaceWithStoppedStatus(WorkspaceHandlingTests.getWorkspaceName()); }); suiteTeardown('Stop and delete the workspace by API', async function (): Promise { From 12fd009ffd20bca004177cf643c5b60310d82ea4 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Wed, 20 Mar 2024 15:35:21 +0200 Subject: [PATCH 33/85] [Tests] Load tests should work correctly on macOs (#22887) --- tests/performance/load-tests/load-test.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index eb21d39be81..c03ae596380 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -8,6 +8,8 @@ NC='\033[0m' # No Color # Do cleanup if the script is interrupted or fails trap cleanup ERR SIGINT +# Detect the operating system +OS="$(uname)" function print() { echo -e "${GREEN}$1${NC}" @@ -49,7 +51,6 @@ function setCompletitionsCount() { if [ -z $COMPLETITIONS_COUNT ]; then echo "Parameter -c wasn't set, setting completitions count to 3." export COMPLETITIONS_COUNT=3 - else echo "Parameter -c was set to $COMPLETITIONS_COUNT ." fi @@ -62,10 +63,19 @@ function setCompletitionsCount() { fi } +function getTimestamp() { + if [ "$OS" = "Darwin" ]; then + date -j -f "%Y-%m-%dT%H:%M:%S" "$1" "+%s" + else + [ "$OS" = "Linux" ] + date -d $1 +%s + fi +} + function runTest() { # start COMPLETITIONS_COUNT workspaces in parallel for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do - cat devworkspace.yaml | sed "0,/name: code-latest/s//name: dw$i/" | kubectl apply -f - & + awk '/name:/ && !modif { sub(/name: .*/, "name: '"dw$i"'"); modif=1 } {print}' devworkspace.yaml | kubectl apply -f - & done wait @@ -88,8 +98,8 @@ function runTest() { if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') - start_timestamp=$(date -d $start_time +%s) - end_timestamp=$(date -d $end_time +%s) + start_timestamp=$(getTimestamp $start_time) + end_timestamp=$(getTimestamp $end_time) dw_starting_time=$((end_timestamp - start_timestamp)) print "Devworkspace dw$i starting time: $dw_starting_time seconds" From ac6f4ef0ad37a3d82a29eda4e314c59b9027d2a5 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Fri, 22 Mar 2024 16:03:53 +0200 Subject: [PATCH 34/85] [Test] Save events from failed workspaces in load-tests script (#22888) * save events from failed workspaces --- tests/performance/load-tests/load-test.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index c03ae596380..b4822fa236f 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -91,6 +91,9 @@ function runTest() { # Create logs directory mkdir logs || true + # Get all events + kubectl get events --field-selector involvedObject.kind=Pod >logs/events.log + total_time=0 succeeded=0 echo "Calculate average workspaces starting time" @@ -107,8 +110,9 @@ function runTest() { succeeded=$((succeeded + 1)) else print_error "Timeout waiting for dw$i to become ready or an error occurred." - kubectl describe dw dw$i >logs/dw$i-log.log - kubectl logs $(kubectl get dw dw$i --template='{{.status.devworkspaceId}}') >logs/dw$i-pod.log || true + devworkspace_id=$(kubectl get dw dw$i --template='{{.status.devworkspaceId}}') + kubectl describe dw dw$i >logs/dw$i-describe.log + cat logs/events.log | grep $devworkspace_id >logs/dw$i-$devworkspace_id-events.log fi done From 799565a67fceab31c561be9ec732ca6c41a21b8a Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Mon, 25 Mar 2024 13:27:40 +0200 Subject: [PATCH 35/85] [Test] Add argument that allows to use downloaded devworkspace file load-tests script (#22890) * add argument that allows to specify devfile that will be used --- tests/performance/load-tests/README.md | 3 +- .../{devworkspace.yaml => example.yaml} | 0 tests/performance/load-tests/load-test.sh | 29 +++++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) rename tests/performance/load-tests/{devworkspace.yaml => example.yaml} (100%) diff --git a/tests/performance/load-tests/README.md b/tests/performance/load-tests/README.md index 893a41b1956..79a8b2611c1 100644 --- a/tests/performance/load-tests/README.md +++ b/tests/performance/load-tests/README.md @@ -11,7 +11,8 @@ What do you need to run those tests 1. Log in to Openshift cluster with Openshift DevSpaces or Eclipse Che deployed from terminal 2. Start `load-test.sh` script from `test/e2e/performance/load-tests`. Set number of started workspaces by -c parameter(like ./load-test.sh -c 5). Set timeout for waiting workspaces to start by -t parameter in seconds(like ./load-test.sh -t 240). 3. This script uses local dewvorspace.yaml to starts workspaces. -4. As results there are average time of workspace starting and number of failed workspaces. +4. Also it is possible to get test devworkspace yam file by link using -l option(like `./load-test.sh -l https://gist.githubusercontent.com/SkorikSergey/1856af20514ecce6c0dbb71f44fc0bcb/raw/3f6a38f0f6adf017dcecf6486ffe507ebe6cfc31/load-test-devworkspace.yaml)`. +5. As results there are average time of workspace starting and number of failed workspaces. ## Results and logs diff --git a/tests/performance/load-tests/devworkspace.yaml b/tests/performance/load-tests/example.yaml similarity index 100% rename from tests/performance/load-tests/devworkspace.yaml rename to tests/performance/load-tests/example.yaml diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index b4822fa236f..16462f14c5f 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -26,7 +26,7 @@ function cleanup() { } function parseArguments() { - while getopts "t:c:" opt; do + while getopts "t:c:l:" opt; do case $opt in t) export WORKSPACE_IDLE_TIMEOUT=$OPTARG @@ -38,6 +38,9 @@ function parseArguments() { fi export COMPLETITIONS_COUNT=$OPTARG ;; + l) + export DEVWORKSPACE_LINK=$OPTARG + ;; \?) print_error "Invalid option -c. Try for example something like ./load-test.sh -c 7" exit 1 @@ -46,7 +49,7 @@ function parseArguments() { done } -function setCompletitionsCount() { +function checkScriptVariables() { # Set the number of workspaces to start if [ -z $COMPLETITIONS_COUNT ]; then echo "Parameter -c wasn't set, setting completitions count to 3." @@ -61,6 +64,26 @@ function setCompletitionsCount() { else echo "Parameter -t was set to $WORKSPACE_IDLE_TIMEOUT second." fi + + # Get devworkspace yaml from link if it is set + # example - https://gist.githubusercontent.com/SkorikSergey/1856af20514ecce6c0dbb71f44fc0bcb/raw/3f6a38f0f6adf017dcecf6486ffe507ebe6cfc31/load-test-devworkspace.yaml + if [ -n "$DEVWORKSPACE_LINK" ]; then + if curl --fail --insecure "$DEVWORKSPACE_LINK" -o devworkspace.yaml; then + echo "Download succeeded, saved to devworkspace.yaml file." + + echo "Check the devworkspace.yaml file content correctness." + if ! kubectl apply -f devworkspace.yaml --dry-run=server; then + print_error "Devworkspace.yaml file is not correct." + exit 1 + fi + else + print_error "Download of $DEVWORKSPACE_LINK file failed" + exit 1 + fi + else + print "Local devworkspace.yaml file will be used." + cp -f example.yaml devworkspace.yaml + fi } function getTimestamp() { @@ -130,7 +153,7 @@ function printResults() { } parseArguments "$@" -setCompletitionsCount +checkScriptVariables cleanup runTest printResults From a83be80b139a7e650b3c28a31ecba872c83bbf06 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Mon, 25 Mar 2024 17:48:06 +0200 Subject: [PATCH 36/85] get workspace starting time in threads, simplify devworkspace yaml (#22893) --- tests/performance/load-tests/example.yaml | 9 ----- tests/performance/load-tests/load-test.sh | 40 ++++++++++++++++------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/tests/performance/load-tests/example.yaml b/tests/performance/load-tests/example.yaml index 3efa0962aa4..301a93ba360 100644 --- a/tests/performance/load-tests/example.yaml +++ b/tests/performance/load-tests/example.yaml @@ -11,12 +11,3 @@ spec: - name: dev container: image: quay.io/devfile/universal-developer-image:latest - contributions: - - name: che-code - uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml - components: - - name: che-code-runtime-description - container: - env: - - name: CODE_HOST - value: 0.0.0.0 diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index 16462f14c5f..c6e6bfa1d9d 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -11,6 +11,9 @@ trap cleanup ERR SIGINT # Detect the operating system OS="$(uname)" +# Capture start time +start=$(date +%s) + function print() { echo -e "${GREEN}$1${NC}" } @@ -21,8 +24,19 @@ function print_error() { function cleanup() { echo "Clean up the environment" - kubectl delete dw --all >/dev/null - kubectl delete dwt --all >/dev/null + kubectl delete dw --all + kubectl delete dwt --all +} + +function getDwStartingTime() { + start_time=$(kubectl get dw dw$1 --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') + end_time=$(kubectl get dw dw$1 --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') + start_timestamp=$(getTimestamp $start_time) + end_timestamp=$(getTimestamp $end_time) + dw_starting_time=$((end_timestamp - start_timestamp)) + + print "Devworkspace dw$1 starting time: $dw_starting_time seconds" + echo $dw_starting_time >>logs/sum.log } function parseArguments() { @@ -110,9 +124,10 @@ function runTest() { wait # Delete logs on file system if it exists - rm -f logs/dw* + rm -f logs/* # Create logs directory mkdir logs || true + touch logs/sum.log # Get all events kubectl get events --field-selector involvedObject.kind=Pod >logs/events.log @@ -122,14 +137,7 @@ function runTest() { echo "Calculate average workspaces starting time" for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then - start_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') - end_time=$(kubectl get dw dw$i --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') - start_timestamp=$(getTimestamp $start_time) - end_timestamp=$(getTimestamp $end_time) - dw_starting_time=$((end_timestamp - start_timestamp)) - - print "Devworkspace dw$i starting time: $dw_starting_time seconds" - total_time=$((total_time + dw_starting_time)) + getDwStartingTime $i & # >>logs/sum.log & succeeded=$((succeeded + 1)) else print_error "Timeout waiting for dw$i to become ready or an error occurred." @@ -139,9 +147,15 @@ function runTest() { fi done + wait } function printResults() { + # Calculate average workspace starting time + while IFS= read -r line; do + ((total_time += line)) + done <"logs/sum.log" + print "==================== Test results ====================" if [ $succeeded -eq 0 ]; then print_error "No workspaces started successfully." @@ -150,6 +164,10 @@ function printResults() { print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" fi print "$((COMPLETITIONS_COUNT - succeeded)) workspaces failed. See failed workspace pod logs in the current folder for details." + + # Calculate and display the elapsed time + end=$(date +%s) + print "Elapsed time: $((end - start)) seconds" } parseArguments "$@" From d9b7d2b124210c13852ed54661fe6e8d870893a6 Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Thu, 7 Mar 2024 14:11:41 +0100 Subject: [PATCH 37/85] docs: Update README.md (project description) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45583590de1..85e69d0b91a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ https://github.com/eclipse-che/che-server [![Eclipse Che - Eclipse Next-Generation IDE](https://raw.githubusercontent.com/eclipse/che/assets/eclipseche.png)]( https://eclipse.dev/che/) -**Next-generation container development platform, developer workspace server and cloud IDE** +**Platform for providing Kubernetes-based Cloud Development Environments for Enterprise Teams** [![Eclipse License](https://img.shields.io/badge/license-Eclipse-brightgreen.svg)](https://github.com/codenvy/che/blob/master/LICENSE) From 02c771ca1f29fd0cf7612522386c849867a9bcb2 Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Fri, 29 Mar 2024 11:09:58 +0200 Subject: [PATCH 38/85] Add ability to set c0ustom factory url for the WorkspaceWithParent (#22903) --- tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts b/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts index ba6ddf6b57b..c7fd451905e 100644 --- a/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts +++ b/tests/e2e/specs/miscellaneous/WorkspaceWithParent.spec.ts @@ -24,6 +24,7 @@ import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesComman import { ITestWorkspaceUtil } from '../../utils/workspace/ITestWorkspaceUtil'; import { DriverHelper } from '../../utils/DriverHelper'; import { TIMEOUT_CONSTANTS } from '../../constants/TIMEOUT_CONSTANTS'; +import { FACTORY_TEST_CONSTANTS } from '../../constants/FACTORY_TEST_CONSTANTS'; suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void { const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests); @@ -49,7 +50,10 @@ suite(`Workspace using a parent test suite ${BASE_TEST_CONSTANTS.TEST_ENVIRONMEN }); test('Create a workspace from child devfile', async function (): Promise { - const factoryUrl: string = `${BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL}/dashboard/#https://github.com/testsfactory/parentDevfile`; + const factoryUrl: string = + FACTORY_TEST_CONSTANTS.TS_SELENIUM_FACTORY_GIT_REPO_URL.length === 0 + ? BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL + '/dashboard/#/' + 'https://github.com/testsfactory/parentDevfile' + : BASE_TEST_CONSTANTS.TS_SELENIUM_BASE_URL + '/dashboard/#/' + FACTORY_TEST_CONSTANTS.TS_SELENIUM_FACTORY_GIT_REPO_URL; await dashboard.waitPage(); await browserTabsUtil.navigateTo(factoryUrl); await workspaceHandlingTests.obtainWorkspaceNameFromStartingPage(); From 817ddaf8d79569ff63d33a5e38afab474553fd70 Mon Sep 17 00:00:00 2001 From: Maksym Musiienko Date: Fri, 29 Mar 2024 11:12:51 +0200 Subject: [PATCH 39/85] Add comments and remove the duplicated PredefinedNamespace test descriptions (#22900) --- .../specs/miscellaneous/PredefinedNamespace.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/e2e/specs/miscellaneous/PredefinedNamespace.spec.ts b/tests/e2e/specs/miscellaneous/PredefinedNamespace.spec.ts index ec12d49fc52..bccb16dad7c 100644 --- a/tests/e2e/specs/miscellaneous/PredefinedNamespace.spec.ts +++ b/tests/e2e/specs/miscellaneous/PredefinedNamespace.spec.ts @@ -65,13 +65,13 @@ suite(`Create predefined workspace and check it ${BASE_TEST_CONSTANTS.TEST_ENVIR }); // verify that just created workspace is available for the dedicated user - test('Validate the created workspace is present in predefined namespace', function (): void { + test('Validate that predefined namespace has been created', function (): void { const expectedProject: string = shellExecutor.executeArbitraryShellScript('oc get projects'); expect(expectedProject).contains(predefinedNamespaceName); }); - // make sure that the generated devspace has been created in the predefined namespace - test('Validate the created workspace is present in predefined namespace', function (): void { + // ensure the generated DevSpace is created within the predefined namespace + test('Create test DevWorkspace and verify its creation within the predefined namespace', function (): void { kubernetesCommandLineToolsExecutor.namespace = predefinedNamespaceName; kubernetesCommandLineToolsExecutor.workspaceName = workspaceName; // relogin under the admin user (because regular user does not have permissions for getting pod states) @@ -79,8 +79,8 @@ suite(`Create predefined workspace and check it ${BASE_TEST_CONSTANTS.TEST_ENVIR expect(kubernetesCommandLineToolsExecutor.waitDevWorkspace().stdout).contains('condition met'); }); - // verify that just created workspace with unique name is present in the predefined namespace - test('Validate the created workspace is present in predefined namespace', function (): void { + // verify that the newly created workspace, identified by a unique name, exists within the predefined namespace. Given that multiple users may use the same cluster and create multiple DevSpaces within the same OpenShift project, it's essential to confirm that our test project, distinguished by a unique name, has been successfully created. + test('Validate the creation of the correct DevWorkspace with a unique name', function (): void { const ocDevWorkspaceOutput: string = kubernetesCommandLineToolsExecutor.getDevWorkspaceYamlConfiguration(); expect(ocDevWorkspaceOutput).includes(workspaceName); }); From bc658b5546b9374d095d08dd6ec7e26a280bc924 Mon Sep 17 00:00:00 2001 From: Sergey Skorik Date: Tue, 2 Apr 2024 14:18:06 +0300 Subject: [PATCH 40/85] [Test] Add a feature to start workspaces in separate namespaces (#22901) --- tests/performance/load-tests/README.md | 25 ++-- tests/performance/load-tests/load-test.sh | 137 ++++++++++++++---- .../simple-ephemeral.yaml} | 0 .../load-tests/samples/simple-pvc.yaml | 11 ++ .../samples/simple-with-editor-ephemeral.yaml | 22 +++ .../samples/simple-with-editor-pvc.yaml | 20 +++ 6 files changed, 172 insertions(+), 43 deletions(-) rename tests/performance/load-tests/{example.yaml => samples/simple-ephemeral.yaml} (100%) create mode 100644 tests/performance/load-tests/samples/simple-pvc.yaml create mode 100644 tests/performance/load-tests/samples/simple-with-editor-ephemeral.yaml create mode 100644 tests/performance/load-tests/samples/simple-with-editor-pvc.yaml diff --git a/tests/performance/load-tests/README.md b/tests/performance/load-tests/README.md index 79a8b2611c1..bc28e3476a1 100644 --- a/tests/performance/load-tests/README.md +++ b/tests/performance/load-tests/README.md @@ -1,19 +1,20 @@ # Overview -This script tests how well OpenShift environment can handle running simultaneously many of workspaces. It evaluates the performance of the system under test by checking the average results across all pods and identifying failures that occur during the testing process. +This script tests the performance of an OpenShift environment by running multiple workspaces simultaneously. It evaluates the system under test by checking the average results across all pods and identifying any failures that occur during the testing process. ## Prerequisites -What do you need to run those tests -- `kubectl` client installed -- Openshift cluster with running Openshift DevSpaces -- test user logged into DevSpaces Dashboard(this quaranies that user namespaces are created) +To run these tests, you will need: +- The `kubectl` client installed +- An OpenShift cluster with running OpenShift DevSpaces +- A test user logged into the DevSpaces Dashboard (this ensures that user namespaces are created) ## Running load tests -1. Log in to Openshift cluster with Openshift DevSpaces or Eclipse Che deployed from terminal -2. Start `load-test.sh` script from `test/e2e/performance/load-tests`. Set number of started workspaces by -c parameter(like ./load-test.sh -c 5). Set timeout for waiting workspaces to start by -t parameter in seconds(like ./load-test.sh -t 240). -3. This script uses local dewvorspace.yaml to starts workspaces. -4. Also it is possible to get test devworkspace yam file by link using -l option(like `./load-test.sh -l https://gist.githubusercontent.com/SkorikSergey/1856af20514ecce6c0dbb71f44fc0bcb/raw/3f6a38f0f6adf017dcecf6486ffe507ebe6cfc31/load-test-devworkspace.yaml)`. -5. As results there are average time of workspace starting and number of failed workspaces. - +Follow these steps to run the load tests: +1. Log in to the OpenShift cluster with OpenShift DevSpaces or Eclipse Che deployed from the terminal. +2. Start the `load-test.sh` script from `test/e2e/performance/load-tests`. Set the number of workspaces to start using the `-c` parameter (e.g., `./load-test.sh -c 5`). Set the timeout for waiting for workspaces to start using the `-t` parameter in seconds (e.g., `./load-test.sh -t 240`). +3. This script uses the local `example.yaml` file to start the workspaces. +4. Alternatively, you can provide a link to the test devworkspace YAML file using the `-l` argument (e.g., `./load-test.sh -l https://raw.githubusercontent.com/eclipse/che/main/tests/performance/load-tests/samples/simple-with-editor-pvc.yaml`). +5. If you want to start workspaces in separate namespaces (one workspace per namespace), use the `-s` as flag option (e.g., `./load-test.sh -s `). +6. The script will provide the average time for workspace starting and the number of failed workspaces. ## Results and logs -If workspace failed to start, logs are saved in current directory. +If a workspace fails to start, the logs will be saved in the `logs` directory. diff --git a/tests/performance/load-tests/load-test.sh b/tests/performance/load-tests/load-test.sh index c6e6bfa1d9d..a4ba52aa26c 100755 --- a/tests/performance/load-tests/load-test.sh +++ b/tests/performance/load-tests/load-test.sh @@ -13,6 +13,16 @@ OS="$(uname)" # Capture start time start=$(date +%s) +# Current namespace where the script is running +current_namespace=$(kubectl config view --minify --output 'jsonpath={..namespace}') +start_separately=false +# Default value for test namespace name +test_namespace_name=load-test-namespace- +# Default value for test devworkspace name +dw_name=load-test-dw- +# default values for label selector +label_type="test-type" +label_key="load-test" function print() { echo -e "${GREEN}$1${NC}" @@ -22,25 +32,29 @@ function print_error() { echo -e "${RED}$1${NC}" } -function cleanup() { - echo "Clean up the environment" - kubectl delete dw --all - kubectl delete dwt --all -} - -function getDwStartingTime() { - start_time=$(kubectl get dw dw$1 --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') - end_time=$(kubectl get dw dw$1 --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') - start_timestamp=$(getTimestamp $start_time) - end_timestamp=$(getTimestamp $end_time) - dw_starting_time=$((end_timestamp - start_timestamp)) - - print "Devworkspace dw$1 starting time: $dw_starting_time seconds" - echo $dw_starting_time >>logs/sum.log +# Function to display help information +function display_help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " -t Set the timeout in seconds (default: 120)" + echo " -c Set the number of workspaces to start (default: 3)" + echo " -l Set the link to the devworkspace.yaml file" + echo " -s Start workspaces in separate namespaces(one workspace per namespace)" + echo " --help Display this help message" + exit 0 } function parseArguments() { - while getopts "t:c:l:" opt; do + for arg in "$@"; do + case $arg in + # Check for --help argument + --help) + display_help + ;; + esac + done + + while getopts "t:c:l:sh" opt; do case $opt in t) export WORKSPACE_IDLE_TIMEOUT=$OPTARG @@ -55,6 +69,12 @@ function parseArguments() { l) export DEVWORKSPACE_LINK=$OPTARG ;; + s) + export start_separately=true + ;; + h) + display_help + ;; \?) print_error "Invalid option -c. Try for example something like ./load-test.sh -c 7" exit 1 @@ -63,6 +83,17 @@ function parseArguments() { done } +function cleanup() { + echo "Clean up the environment" + + if [ $start_separately = true ]; then + echo "Delete test namespaces" + kubectl delete namespace --selector=$label_type=$label_key >/dev/null 2>&1 || true + else + kubectl delete dw --selector=$label_type=$label_key -n $current_namespace >/dev/null 2>&1 || true + fi +} + function checkScriptVariables() { # Set the number of workspaces to start if [ -z $COMPLETITIONS_COUNT ]; then @@ -80,7 +111,7 @@ function checkScriptVariables() { fi # Get devworkspace yaml from link if it is set - # example - https://gist.githubusercontent.com/SkorikSergey/1856af20514ecce6c0dbb71f44fc0bcb/raw/3f6a38f0f6adf017dcecf6486ffe507ebe6cfc31/load-test-devworkspace.yaml + # example - https://raw.githubusercontent.com/eclipse/che/main/tests/performance/load-tests/samples/simple-ephemeral.yaml if [ -n "$DEVWORKSPACE_LINK" ]; then if curl --fail --insecure "$DEVWORKSPACE_LINK" -o devworkspace.yaml; then echo "Download succeeded, saved to devworkspace.yaml file." @@ -96,7 +127,30 @@ function checkScriptVariables() { fi else print "Local devworkspace.yaml file will be used." - cp -f example.yaml devworkspace.yaml + cp -f samples/simple-ephemeral.yaml devworkspace.yaml + fi +} + +function getDwStartingTime() { + start_time=$(kubectl get dw $dw_name$1 -n $2 --template='{{range .status.conditions}}{{if eq .type "Started"}}{{.lastTransitionTime}}{{end}}{{end}}') + end_time=$(kubectl get dw $dw_name$1 -n $2 --template='{{range .status.conditions}}{{if eq .type "Ready"}}{{.lastTransitionTime}}{{end}}{{end}}') + start_timestamp=$(getTimestamp $start_time) + end_timestamp=$(getTimestamp $end_time) + dw_starting_time=$((end_timestamp - start_timestamp)) + + print "Devworkspace $dw_name$1 in $2 namespace starting time: $dw_starting_time seconds" + echo $dw_starting_time >>logs/sum.log + kubectl delete dw $dw_name$1 -n $2 >/dev/null 2>&1 +} + +function precreateNamespaces() { + if [ $start_separately = true ]; then + echo "Create test namespaces" + for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do + namespace=$test_namespace_name$i + kubectl create namespace $namespace + oc label namespace $namespace $label_type=$label_key >/dev/null 2>&1 + done fi } @@ -110,16 +164,27 @@ function getTimestamp() { } function runTest() { + # add label to devworkspace.yaml + cat devworkspace.yaml | awk -v key="$label_type" -v value=" $label_key" '/metadata:/{$0=$0"\n labels:\n "key":"value}1' >patched-dw.yaml + # start COMPLETITIONS_COUNT workspaces in parallel + namespace=$current_namespace for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do - awk '/name:/ && !modif { sub(/name: .*/, "name: '"dw$i"'"); modif=1 } {print}' devworkspace.yaml | kubectl apply -f - & + if [ $start_separately = true ]; then + namespace=$test_namespace_name$i + fi + awk '/name:/ && !modif { sub(/name: .*/, "name: '"$dw_name$i"'"); modif=1 } {print}' patched-dw.yaml | kubectl apply -n $namespace -f - & done wait # wait for all workspaces to be started echo "Wait for all workspaces are started" + namespace=$current_namespace for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do - kubectl wait --for=condition=Ready "dw/dw$i" --timeout=${WORKSPACE_IDLE_TIMEOUT}s || true & + if [ $start_separately = true ]; then + namespace=$test_namespace_name$i + fi + kubectl wait --for=condition=Ready "dw/$dw_name$i" --timeout=${WORKSPACE_IDLE_TIMEOUT}s -n $namespace || true & done wait @@ -129,21 +194,29 @@ function runTest() { mkdir logs || true touch logs/sum.log - # Get all events - kubectl get events --field-selector involvedObject.kind=Pod >logs/events.log + # Get events from all cluster in start_separately mode and only from current namespace in default mode + if [ $start_separately = true ]; then + kubectl get events --field-selector involvedObject.kind=Pod --all-namespaces >logs/events.log + else + kubectl get events --field-selector involvedObject.kind=Pod >logs/events.log + fi total_time=0 succeeded=0 echo "Calculate average workspaces starting time" + namespace=$current_namespace for ((i = 1; i <= $COMPLETITIONS_COUNT; i++)); do - if [ "$(kubectl get dw dw$i --template='{{.status.phase}}')" == "Running" ]; then - getDwStartingTime $i & # >>logs/sum.log & + if [ $start_separately = true ]; then + namespace=$test_namespace_name$i + fi + if [ "$(kubectl get dw $dw_name$i -n $namespace --template='{{.status.phase}}')" == "Running" ]; then + getDwStartingTime $i $namespace & succeeded=$((succeeded + 1)) else - print_error "Timeout waiting for dw$i to become ready or an error occurred." - devworkspace_id=$(kubectl get dw dw$i --template='{{.status.devworkspaceId}}') - kubectl describe dw dw$i >logs/dw$i-describe.log - cat logs/events.log | grep $devworkspace_id >logs/dw$i-$devworkspace_id-events.log + print_error "Timeout waiting for $dw_name$i to become ready or an error occurred." + devworkspace_id=$(kubectl get dw $dw_name$i -n $namespace --template='{{.status.devworkspaceId}}') + kubectl describe dw $dw_name$i -n $namespace >logs/$dw_name$i-describe.log + cat logs/events.log | grep $devworkspace_id >logs/$dw_name$i-$devworkspace_id-events.log || true fi done @@ -156,10 +229,9 @@ function printResults() { ((total_time += line)) done <"logs/sum.log" - print "==================== Test results ====================" + echo "==================== Test results ====================" if [ $succeeded -eq 0 ]; then print_error "No workspaces started successfully." - exit 1 else print "Average workspace starting time for $succeeded workspaces from $COMPLETITIONS_COUNT started: $((total_time / succeeded)) seconds" fi @@ -171,8 +243,11 @@ function printResults() { } parseArguments "$@" -checkScriptVariables +checkScriptVariables "$@" cleanup + +precreateNamespaces runTest printResults + cleanup diff --git a/tests/performance/load-tests/example.yaml b/tests/performance/load-tests/samples/simple-ephemeral.yaml similarity index 100% rename from tests/performance/load-tests/example.yaml rename to tests/performance/load-tests/samples/simple-ephemeral.yaml diff --git a/tests/performance/load-tests/samples/simple-pvc.yaml b/tests/performance/load-tests/samples/simple-pvc.yaml new file mode 100644 index 00000000000..0c89ca4bdcd --- /dev/null +++ b/tests/performance/load-tests/samples/simple-pvc.yaml @@ -0,0 +1,11 @@ +kind: DevWorkspace +apiVersion: workspace.devfile.io/v1alpha2 +metadata: + name: code-latest +spec: + started: true + template: + components: + - name: dev + container: + image: quay.io/devfile/universal-developer-image:latest diff --git a/tests/performance/load-tests/samples/simple-with-editor-ephemeral.yaml b/tests/performance/load-tests/samples/simple-with-editor-ephemeral.yaml new file mode 100644 index 00000000000..3efa0962aa4 --- /dev/null +++ b/tests/performance/load-tests/samples/simple-with-editor-ephemeral.yaml @@ -0,0 +1,22 @@ +kind: DevWorkspace +apiVersion: workspace.devfile.io/v1alpha2 +metadata: + name: code-latest +spec: + started: true + template: + attributes: + controller.devfile.io/storage-type: ephemeral + components: + - name: dev + container: + image: quay.io/devfile/universal-developer-image:latest + contributions: + - name: che-code + uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml + components: + - name: che-code-runtime-description + container: + env: + - name: CODE_HOST + value: 0.0.0.0 diff --git a/tests/performance/load-tests/samples/simple-with-editor-pvc.yaml b/tests/performance/load-tests/samples/simple-with-editor-pvc.yaml new file mode 100644 index 00000000000..f0d42bc66bd --- /dev/null +++ b/tests/performance/load-tests/samples/simple-with-editor-pvc.yaml @@ -0,0 +1,20 @@ +kind: DevWorkspace +apiVersion: workspace.devfile.io/v1alpha2 +metadata: + name: code-latest +spec: + started: true + template: + components: + - name: dev + container: + image: quay.io/devfile/universal-developer-image:latest + contributions: + - name: che-code + uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml + components: + - name: che-code-runtime-description + container: + env: + - name: CODE_HOST + value: 0.0.0.0 From 364b044d4f2efa193f156a6e7779f12e0b694086 Mon Sep 17 00:00:00 2001 From: Mykhailo Kuznietsov Date: Thu, 4 Apr 2024 10:51:07 +0000 Subject: [PATCH 41/85] chore: Bump to 7.85.0-next in main Signed-off-by: Mykhailo Kuznietsov --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- VERSION | 2 +- tests/e2e/package-lock.json | 4 ++-- tests/e2e/package.json | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 872251204cf..9781666cd2c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,8 +33,9 @@ body: label: Che version description: if workspace is running, version can be obtained with help/about menu options: - - "7.83@latest" + - "7.84@latest" - "next (development version)" + - "7.83" - "7.82" - "7.81" - "7.80" diff --git a/VERSION b/VERSION index 1cd302ef8a8..f0c65c72dbd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.84.0-next +7.85.0-next diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 78bbc24d4e0..cd5585cb237 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -1,12 +1,12 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.84.0-next", + "version": "7.85.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@eclipse-che/che-e2e", - "version": "7.84.0-next", + "version": "7.85.0-next", "license": "ISC", "dependencies": { "@eclipse-che/api": "latest", diff --git a/tests/e2e/package.json b/tests/e2e/package.json index ee2614634cb..f8114e64c78 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "@eclipse-che/che-e2e", - "version": "7.84.0-next", + "version": "7.85.0-next", "description": "", "main": "dist/index.js", "scripts": { From 0be7bcb0e7920d9b1d84cf8f81f9fc704a9ff7f0 Mon Sep 17 00:00:00 2001 From: Ilya Buziuk Date: Thu, 4 Apr 2024 14:03:51 +0200 Subject: [PATCH 42/85] chore: README cleanup --- README.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 85e69d0b91a..83400d5d8d2 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,9 @@ +