@eclipse-che/che-e2e 7.66.0-dev-7156932 → 7.66.0-dev-2c79499

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/configs/inversify.config.ts +10 -4
  2. package/configs/inversify.types.ts +3 -0
  3. package/dist/configs/inversify.config.js +7 -3
  4. package/dist/configs/inversify.config.js.map +1 -1
  5. package/dist/configs/inversify.types.js +3 -0
  6. package/dist/configs/inversify.types.js.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/pageobjects/dashboard/Dashboard.js +5 -4
  10. package/dist/pageobjects/dashboard/Dashboard.js.map +1 -1
  11. package/dist/pageobjects/login/RedHatLoginPage.js +14 -15
  12. package/dist/pageobjects/login/RedHatLoginPage.js.map +1 -1
  13. package/dist/pageobjects/openshift/OcpApplicationPage.js +60 -0
  14. package/dist/pageobjects/openshift/OcpApplicationPage.js.map +1 -0
  15. package/dist/pageobjects/openshift/OcpImportFromGitPage.js +91 -0
  16. package/dist/pageobjects/openshift/OcpImportFromGitPage.js.map +1 -0
  17. package/dist/pageobjects/openshift/OcpLoginPage.js +3 -3
  18. package/dist/pageobjects/openshift/OcpLoginPage.js.map +1 -1
  19. package/dist/pageobjects/openshift/OcpMainPage.js +91 -0
  20. package/dist/pageobjects/openshift/OcpMainPage.js.map +1 -0
  21. package/dist/specs/dashboard-samples/RecomendedExtentions.spec.js +1 -1
  22. package/dist/specs/dashboard-samples/RecomendedExtentions.spec.js.map +1 -1
  23. package/dist/specs/devconsole-intergration/DevConsoleIntegration.spec.js +74 -0
  24. package/dist/specs/devconsole-intergration/DevConsoleIntegration.spec.js.map +1 -0
  25. package/dist/specs/factory/Factory.spec.js.map +1 -1
  26. package/dist/specs/factory/NoSetupRepoFactory.spec.js.map +1 -1
  27. package/dist/specs/factory/RefusedOAuthFactory.spec.js.map +1 -1
  28. package/dist/tests-library/LoginTests.js +19 -10
  29. package/dist/tests-library/LoginTests.js.map +1 -1
  30. package/dist/utils/BrowserTabsUtil.js +5 -1
  31. package/dist/utils/BrowserTabsUtil.js.map +1 -1
  32. package/dist/utils/DriverHelper.js +29 -3
  33. package/dist/utils/DriverHelper.js.map +1 -1
  34. package/dist/utils/KubernetesCommandLineToolsExecutor.js +22 -4
  35. package/dist/utils/KubernetesCommandLineToolsExecutor.js.map +1 -1
  36. package/index.ts +3 -0
  37. package/package.json +1 -1
  38. package/pageobjects/dashboard/Dashboard.ts +5 -4
  39. package/pageobjects/login/RedHatLoginPage.ts +14 -16
  40. package/pageobjects/openshift/OcpApplicationPage.ts +42 -0
  41. package/pageobjects/openshift/OcpImportFromGitPage.ts +87 -0
  42. package/pageobjects/openshift/OcpLoginPage.ts +3 -3
  43. package/pageobjects/openshift/OcpMainPage.ts +87 -0
  44. package/specs/dashboard-samples/RecomendedExtentions.spec.ts +1 -1
  45. package/specs/devconsole-intergration/DevConsoleIntegration.spec.ts +97 -0
  46. package/specs/factory/Factory.spec.ts +1 -1
  47. package/specs/factory/NoSetupRepoFactory.spec.ts +1 -1
  48. package/specs/factory/RefusedOAuthFactory.spec.ts +1 -1
  49. package/tests-library/LoginTests.ts +17 -7
  50. package/utils/BrowserTabsUtil.ts +5 -3
  51. package/utils/DriverHelper.ts +36 -4
  52. package/utils/KubernetesCommandLineToolsExecutor.ts +26 -5
@@ -15,48 +15,46 @@ import { DriverHelper } from '../../utils/DriverHelper';
15
15
  import { Logger } from '../../utils/Logger';
16
16
  import { TestConstants } from '../../constants/TestConstants';
17
17
 
18
- const USERNAME_INPUT_ID: string = 'username-verification';
19
- const PASSWORD_INPUT_ID: string = 'password';
20
- const NEXT_BUTTON_ID: string = 'login-show-step2';
21
- const LOGIN_BUTTON_ID: string = 'rh-password-verification-submit-button';
22
- const timeout: number = 10000;
23
-
24
18
  @injectable()
25
19
  export class RedHatLoginPage {
20
+ private readonly USERNAME_INPUT_ID: string = 'username-verification';
21
+ private readonly PASSWORD_INPUT_ID: string = 'password';
22
+ private readonly NEXT_BUTTON_ID: string = 'login-show-step2';
23
+ private readonly LOGIN_BUTTON_ID: string = 'rh-password-verification-submit-button';
26
24
 
27
25
  constructor(
28
26
  @inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) { }
29
27
 
30
28
  async waitRedHatLoginWelcomePage(): Promise<void> {
31
29
  Logger.debug('RedHatLoginPage.waitRedHatLoginWelcomePage');
32
- await this.driverHelper.waitVisibility(By.id(USERNAME_INPUT_ID));
30
+ await this.driverHelper.waitVisibility(By.id(this.USERNAME_INPUT_ID));
33
31
  }
34
32
 
35
33
  async enterPasswordRedHat(): Promise<void> {
36
34
  Logger.debug('RedHatLoginPage.enterPasswordRedHat');
37
- const passwordFieldLocator: By = By.id(PASSWORD_INPUT_ID);
35
+ const passwordFieldLocator: By = By.id(this.PASSWORD_INPUT_ID);
38
36
  await this.driverHelper.waitVisibility(passwordFieldLocator, 3000);
39
- await this.driverHelper.enterValue(passwordFieldLocator, TestConstants.TS_SELENIUM_OCP_PASSWORD, timeout );
37
+ await this.driverHelper.enterValue(passwordFieldLocator, TestConstants.TS_SELENIUM_OCP_PASSWORD);
40
38
  }
41
39
  async clickOnLoginButton(): Promise<void> {
42
40
  Logger.debug('RedHatLoginPage.clickOnLoginButton');
43
- const loginButtonLocator: By = By.id(LOGIN_BUTTON_ID);
44
- await this.driverHelper.waitAndClick(loginButtonLocator, timeout);
41
+ const loginButtonLocator: By = By.id(this.LOGIN_BUTTON_ID);
42
+ await this.driverHelper.waitAndClick(loginButtonLocator);
45
43
  }
46
44
  async waitDisappearanceRedHatLoginWelcomePage(): Promise<void> {
47
45
  Logger.debug('RedHatLoginPage.waitDisappearanceRedHatLoginWelcomePage');
48
- await this.driverHelper.waitDisappearance(By.id(LOGIN_BUTTON_ID));
46
+ await this.driverHelper.waitDisappearance(By.id(this.LOGIN_BUTTON_ID));
49
47
  }
50
48
  async enterUserNameRedHat(): Promise<void> {
51
49
  Logger.debug('RedHatLoginPage.enterUserNameRedHat');
52
- const usernameFieldLocator: By = By.id(USERNAME_INPUT_ID);
50
+ const usernameFieldLocator: By = By.id(this.USERNAME_INPUT_ID);
53
51
  await this.driverHelper.waitVisibility(usernameFieldLocator, 20000);
54
- await this.driverHelper.enterValue(usernameFieldLocator, TestConstants.TS_SELENIUM_OCP_USERNAME, timeout );
52
+ await this.driverHelper.enterValue(usernameFieldLocator, TestConstants.TS_SELENIUM_OCP_USERNAME);
55
53
  }
56
54
 
57
55
  async clickNextButton(): Promise<void> {
58
56
  Logger.debug('RedHatLoginPage.clickNextButton');
59
- const nextButtonLocator: By = By.id(NEXT_BUTTON_ID);
60
- await this.driverHelper.waitAndClick(nextButtonLocator, timeout);
57
+ const nextButtonLocator: By = By.id(this.NEXT_BUTTON_ID);
58
+ await this.driverHelper.waitAndClick(nextButtonLocator);
61
59
  }
62
60
  }
@@ -0,0 +1,42 @@
1
+ /*********************************************************************
2
+ * Copyright (c) 2019-2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ **********************************************************************/
10
+ import 'reflect-metadata';
11
+ import { inject, injectable } from 'inversify';
12
+ import { DriverHelper } from '../../utils/DriverHelper';
13
+ import { CLASSES } from '../../configs/inversify.types';
14
+ import { By } from 'selenium-webdriver';
15
+ import { Logger } from '../../utils/Logger';
16
+ import { TimeoutConstants } from '../../constants/TimeoutConstants';
17
+ import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil';
18
+
19
+ @injectable()
20
+ export class OcpApplicationPage {
21
+
22
+ private static readonly APPLICATION_ICON_LOCATOR: By = By.xpath('//*[@data-test-id="base-node-handler"]');
23
+ private static readonly EDIT_SOURCE_CODE_ICON_LOCATOR: By = By.xpath('//*[@aria-label="Edit source code"]');
24
+
25
+ constructor(
26
+ @inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper,
27
+ @inject(CLASSES.BrowserTabsUtil) private readonly browserTabsUtil: BrowserTabsUtil) {
28
+ }
29
+
30
+ async waitApplicationIcon(): Promise<void> {
31
+ Logger.debug(`${this.constructor.name}.${this.waitApplicationIcon.name}`);
32
+
33
+ await this.driverHelper.waitPresence(OcpApplicationPage.APPLICATION_ICON_LOCATOR, TimeoutConstants.TS_SELENIUM_LOAD_PAGE_TIMEOUT);
34
+ }
35
+
36
+ async waitAndOpenEditSourceCodeIcon(): Promise<void> {
37
+ Logger.debug(`${this.constructor.name}.${this.waitAndOpenEditSourceCodeIcon.name}`);
38
+ const parentGUID: string = await this.browserTabsUtil.getCurrentWindowHandle();
39
+ await this.driverHelper.waitAndClick(OcpApplicationPage.EDIT_SOURCE_CODE_ICON_LOCATOR);
40
+ await this.browserTabsUtil.waitAndSwitchToAnotherWindow(parentGUID, TimeoutConstants.TS_SELENIUM_LOAD_PAGE_TIMEOUT);
41
+ }
42
+ }
@@ -0,0 +1,87 @@
1
+ /*********************************************************************
2
+ * Copyright (c) 2019-2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ **********************************************************************/
10
+ import 'reflect-metadata';
11
+ import { inject, injectable } from 'inversify';
12
+ import { DriverHelper } from '../../utils/DriverHelper';
13
+ import { CLASSES } from '../../configs/inversify.types';
14
+ import { By } from 'selenium-webdriver';
15
+ import { Logger } from '../../utils/Logger';
16
+ import { OcpApplicationPage } from './OcpApplicationPage';
17
+ import { e2eContainer } from '../../configs/inversify.config';
18
+
19
+ @injectable()
20
+ export class OcpImportFromGitPage {
21
+
22
+ private static readonly GIT_URL_INPUT_LOCATOR: By = By.id('form-input-git-url-field');
23
+ private static readonly SHOW_ADVANCED_GIT_OPTIONS_LINK_LOCATOR: By = By.xpath('//*[text()="Show advanced Git options"]//ancestor::button');
24
+ private static readonly HIDE_ADVANCED_GIT_OPTIONS_LOCATOR: By = By.xpath('//*[text()="Hide advanced Git options"]');
25
+ private static readonly GIT_REFERENCE_INPUT_LOCATOR: By = By.id('form-input-git-ref-field');
26
+ private static readonly EDIT_IMPORT_STRATEGY_LINK_LOCATOR: By = By.xpath('//*[text()="Edit Import Strategy"]//ancestor::button');
27
+ private static readonly BUILDER_IMAGE_STRATEGY_ITEM_LOCATOR: By = By.xpath('//*[text()="Builder Image"]//parent::div//parent::div');
28
+ private static readonly ADD_LABEL_LINK_LOCATOR: By = By.xpath('//button[text()="Labels"]');
29
+ private static readonly ADD_LABEL_INPUT_LOCATOR: By = By.id('form-selector-labels-field');
30
+ private static readonly SUBMIT_BUTTON_LOCATOR: By = By.xpath('//*[@data-test-id="submit-button"]');
31
+
32
+ constructor(
33
+ @inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {
34
+ }
35
+
36
+ async enterGitRepoUrl(gitRepoUrl: string): Promise<void> {
37
+ Logger.debug(`${this.constructor.name}.${this.enterGitRepoUrl.name} "${gitRepoUrl}"`);
38
+
39
+ await this.driverHelper.enterValue(OcpImportFromGitPage.GIT_URL_INPUT_LOCATOR, gitRepoUrl);
40
+ }
41
+
42
+ async clickOnAdvancedOptionsButton(): Promise<void> {
43
+ Logger.debug(`${this.constructor.name}.${this.clickOnAdvancedOptionsButton.name}`);
44
+
45
+ if (!(await this.driverHelper.isVisible(OcpImportFromGitPage.HIDE_ADVANCED_GIT_OPTIONS_LOCATOR))) {
46
+ await this.driverHelper.waitAndClick(OcpImportFromGitPage.SHOW_ADVANCED_GIT_OPTIONS_LINK_LOCATOR);
47
+ }
48
+ }
49
+
50
+ async enterGitReference(gitReference: string): Promise<void> {
51
+ Logger.debug(`${this.constructor.name}.${this.enterGitReference.name} "${gitReference}"`);
52
+
53
+ await this.driverHelper.enterValue(OcpImportFromGitPage.GIT_REFERENCE_INPUT_LOCATOR, gitReference);
54
+ }
55
+
56
+ async selectBuilderImageImportStrategy(): Promise<void> {
57
+ Logger.debug(`${this.constructor.name}.${this.selectBuilderImageImportStrategy.name}`);
58
+
59
+ await this.driverHelper.scrollToAndClick(OcpImportFromGitPage.EDIT_IMPORT_STRATEGY_LINK_LOCATOR);
60
+ await this.driverHelper.scrollToAndClick(OcpImportFromGitPage.BUILDER_IMAGE_STRATEGY_ITEM_LOCATOR);
61
+ }
62
+
63
+ async addLabel(label: string): Promise<void> {
64
+ Logger.debug(`${this.constructor.name}.${this.addLabel.name} "${label}"`);
65
+
66
+ await this.driverHelper.scrollToAndClick(OcpImportFromGitPage.ADD_LABEL_LINK_LOCATOR);
67
+ await this.driverHelper.scrollToAndEnterValue(OcpImportFromGitPage.ADD_LABEL_INPUT_LOCATOR, label);
68
+ }
69
+
70
+ async submitConfiguration(): Promise<OcpApplicationPage> {
71
+ Logger.debug(`${this.constructor.name}.${this.submitConfiguration.name}`);
72
+
73
+ await this.driverHelper.waitAndClick(OcpImportFromGitPage.SUBMIT_BUTTON_LOCATOR);
74
+ return e2eContainer.get(CLASSES.OcpApplicationPage);
75
+ }
76
+
77
+ async fitAndSubmitConfiguration(gitRepoUrl: string, gitReference: string, label: string): Promise<OcpApplicationPage> {
78
+ Logger.debug(`${this.constructor.name}.${this.fitAndSubmitConfiguration.name}`);
79
+
80
+ await this.enterGitRepoUrl(gitRepoUrl);
81
+ await this.clickOnAdvancedOptionsButton();
82
+ await this.enterGitReference(gitReference);
83
+ await this.selectBuilderImageImportStrategy();
84
+ await this.addLabel(label);
85
+ return await this.submitConfiguration();
86
+ }
87
+ }
@@ -34,7 +34,7 @@ export class OcpLoginPage {
34
34
  Logger.debug('OcpLoginPage.clickOnLoginProviderTitle');
35
35
 
36
36
  const loginProviderTitleLocator: By = By.xpath(`//a[text()=\'${TestConstants.TS_OCP_LOGIN_PAGE_PROVIDER_TITLE}\']`);
37
- await this.driverHelper.waitAndClick(loginProviderTitleLocator);
37
+ await this.driverHelper.waitAndClick(loginProviderTitleLocator, TimeoutConstants.TS_SELENIUM_WAIT_FOR_URL);
38
38
  }
39
39
 
40
40
  async isIdentityProviderLinkVisible(): Promise<boolean> {
@@ -80,8 +80,8 @@ export class OcpLoginPage {
80
80
  async clickOnLoginButton(): Promise<void> {
81
81
  Logger.debug('OcpLoginPage.clickOnLoginButton');
82
82
 
83
- const loginButtonlocator: By = By.css('button[type=submit]');
84
- await this.driverHelper.waitAndClick(loginButtonlocator);
83
+ const loginButtonLocator: By = By.css('button[type=submit]');
84
+ await this.driverHelper.waitAndClick(loginButtonLocator);
85
85
  }
86
86
 
87
87
  async waitDisappearanceOpenShiftLoginWelcomePage(): Promise<void> {
@@ -0,0 +1,87 @@
1
+ /*********************************************************************
2
+ * Copyright (c) 2019-2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ **********************************************************************/
10
+ import 'reflect-metadata';
11
+ import { inject, injectable } from 'inversify';
12
+ import { DriverHelper } from '../../utils/DriverHelper';
13
+ import { CLASSES } from '../../configs/inversify.types';
14
+ import { By } from 'selenium-webdriver';
15
+ import { Logger } from '../../utils/Logger';
16
+ import { TimeoutConstants } from '../../constants/TimeoutConstants';
17
+ import { OcpImportFromGitPage } from './OcpImportFromGitPage';
18
+ import { e2eContainer } from '../../configs/inversify.config';
19
+
20
+ @injectable()
21
+ export class OcpMainPage {
22
+
23
+ private static readonly MAIN_PAGE_HEADER_LOCATOR: By = By.id('page-main-header');
24
+ private static readonly SELECT_ROLE_BUTTON_LOCATOR: By = By.xpath('//*[@data-test-id="perspective-switcher-toggle"]');
25
+ private static readonly ADD_BUTTON_LOCATOR: By = By.xpath('//*[@data-test-id="+Add-header"]');
26
+ private static readonly IMPORT_FROM_GIT_ITEM_LOCATOR: By = By.xpath('//*[@data-test="item import-from-git"]');
27
+ private static readonly SELECT_PROJECT_DROPDOWN_LOCATOR: By = By.xpath('//div[@class="co-namespace-dropdown"]//button');
28
+ private static readonly PROJECT_FILTER_INPUT_LOCATOR: By = By.xpath('//*[@data-test="dropdown-text-filter"]');
29
+
30
+ private static getRoleLocator(role: string): By {
31
+ return By.xpath(`//a//*[text()="${role}"]`);
32
+ }
33
+
34
+ private static getProjectDropdownItemLocator(projectName: string): By {
35
+ return By.xpath(`//button//*[text()="${projectName}"]`);
36
+ }
37
+
38
+ constructor(
39
+ @inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) { }
40
+
41
+ async waitOpenMainPage(): Promise<void> {
42
+ Logger.debug(`${this.constructor.name}.${this.waitOpenMainPage.name}`);
43
+
44
+ await this.driverHelper.waitVisibility(OcpMainPage.MAIN_PAGE_HEADER_LOCATOR, TimeoutConstants.TS_SELENIUM_LOAD_PAGE_TIMEOUT);
45
+ }
46
+
47
+ async clickOnSelectRoleButton(): Promise<void> {
48
+ Logger.debug(`${this.constructor.name}.${this.clickOnSelectRoleButton.name}`);
49
+
50
+ await this.driverHelper.waitAndClick(OcpMainPage.SELECT_ROLE_BUTTON_LOCATOR);
51
+ }
52
+
53
+ async clickAddToProjectButton(): Promise<void> {
54
+ Logger.debug(`${this.constructor.name}.${this.clickAddToProjectButton.name}`);
55
+
56
+ await this.driverHelper.waitAndClick(OcpMainPage.ADD_BUTTON_LOCATOR);
57
+ }
58
+
59
+ async selectDeveloperRole(): Promise<void> {
60
+ Logger.debug(`${this.constructor.name}.${this.selectDeveloperRole.name}`);
61
+
62
+ await this.driverHelper.waitAndClick(OcpMainPage.getRoleLocator('Developer'));
63
+ }
64
+
65
+ async selectImportFromGitMethod(): Promise<OcpImportFromGitPage> {
66
+ Logger.debug(`${this.constructor.name}.${this.selectImportFromGitMethod.name}`);
67
+
68
+ await this.driverHelper.waitAndClick(OcpMainPage.IMPORT_FROM_GIT_ITEM_LOCATOR);
69
+ return e2eContainer.get(CLASSES.OcpImportFromGitPage);
70
+ }
71
+
72
+ async openImportFromGitPage(): Promise<OcpImportFromGitPage> {
73
+ await this.waitOpenMainPage();
74
+ await this.clickOnSelectRoleButton();
75
+ await this.selectDeveloperRole();
76
+ await this.clickAddToProjectButton();
77
+ return await this.selectImportFromGitMethod();
78
+ }
79
+
80
+ async selectProject(projectName: string): Promise<void> {
81
+ Logger.debug(`${this.constructor.name}.${this.selectProject.name}`);
82
+
83
+ await this.driverHelper.waitAndClick(OcpMainPage.SELECT_PROJECT_DROPDOWN_LOCATOR);
84
+ await this.driverHelper.enterValue(OcpMainPage.PROJECT_FILTER_INPUT_LOCATOR, projectName);
85
+ await this.driverHelper.waitAndClick(OcpMainPage.getProjectDropdownItemLocator(projectName));
86
+ }
87
+ }
@@ -109,7 +109,7 @@ suite(`Check if recommended extensions installed for ${samples}`, async function
109
109
  test(`Let extensions complete installation`, async function (): Promise<void> {
110
110
  Logger.info(`Time for extensions installation TimeoutConstants.TS_COMMON_PLUGIN_TEST_TIMEOUT=${TimeoutConstants.TS_COMMON_PLUGIN_TEST_TIMEOUT}`);
111
111
  await driverHelper.wait(TimeoutConstants.TS_COMMON_PLUGIN_TEST_TIMEOUT);
112
- browserTabsUtil.refreshPage();
112
+ await browserTabsUtil.refreshPage();
113
113
  await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
114
114
  });
115
115
 
@@ -0,0 +1,97 @@
1
+ /*********************************************************************
2
+ * Copyright (c) 2019-2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ **********************************************************************/
10
+
11
+ import {
12
+ SideBarView,
13
+ ViewItem,
14
+ ViewSection
15
+ } from 'monaco-page-objects';
16
+ import { registerRunningWorkspace } from '../MochaHooks';
17
+ import { LoginTests } from '../../tests-library/LoginTests';
18
+ import { e2eContainer } from '../../configs/inversify.config';
19
+ import { CLASSES } from '../../configs/inversify.types';
20
+ import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests';
21
+ import { ProjectAndFileTests } from '../../tests-library/ProjectAndFileTests';
22
+ import { expect } from 'chai';
23
+ import { TestConstants } from '../../constants/TestConstants';
24
+ import { OcpMainPage } from '../../pageobjects/openshift/OcpMainPage';
25
+ import { OcpImportFromGitPage } from '../../pageobjects/openshift/OcpImportFromGitPage';
26
+ import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor';
27
+ import { GitUtil } from '../../utils/vsc/GitUtil';
28
+ import { OcpApplicationPage } from '../../pageobjects/openshift/OcpApplicationPage';
29
+
30
+ const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests);
31
+ const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
32
+ const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
33
+ const ocpMainPage: OcpMainPage = e2eContainer.get(CLASSES.OcpMainPage);
34
+ let ocpImportPage: OcpImportFromGitPage;
35
+ let ocpApplicationPage: OcpApplicationPage;
36
+ const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = new KubernetesCommandLineToolsExecutor();
37
+
38
+ // works only with no-admin user
39
+ suite(`DevConsole Integration`, async function (): Promise<void> {
40
+ // test specific data
41
+ const gitImportRepo: string = 'https://github.com/crw-qe/summit-lab-spring-music.git';
42
+ const gitImportReference: string = 'pipeline';
43
+ const projectLabel: string = 'app.openshift.io/runtime=spring';
44
+ const projectName: string = 'devconsole-integration-test';
45
+
46
+ suiteSetup('Create new empty project using ocp', async function (): Promise<void> {
47
+ kubernetesCommandLineToolsExecutor.loginToOcp();
48
+ kubernetesCommandLineToolsExecutor.createProject(projectName);
49
+ });
50
+
51
+ loginTests.loginIntoOcpConsole();
52
+
53
+ test('Select test project on DevConsole', async function (): Promise<void> {
54
+ await ocpMainPage.selectProject(projectName);
55
+ });
56
+
57
+ test('Open import from git project page as Developer', async function (): Promise<void> {
58
+ ocpImportPage = await ocpMainPage.openImportFromGitPage();
59
+ });
60
+
61
+ test('Fill and submit import data', async function (): Promise<void> {
62
+ ocpApplicationPage = await ocpImportPage.fitAndSubmitConfiguration(gitImportRepo, gitImportReference, projectLabel);
63
+ });
64
+
65
+ test('Wait until application creates', async function (): Promise<void> {
66
+ await ocpApplicationPage.waitApplicationIcon();
67
+ });
68
+
69
+ test('Check if application has worked link "Open Source Code"', async function (): Promise<void> {
70
+ await ocpApplicationPage.waitAndOpenEditSourceCodeIcon();
71
+ });
72
+
73
+ loginTests.loginIntoChe();
74
+
75
+ workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
76
+
77
+ test('Registering the running workspace', async function (): Promise<void> {
78
+ registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName());
79
+ });
80
+
81
+ test('Check if application source code opens in workspace', async function (): Promise<void> {
82
+ await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
83
+ });
84
+
85
+ test('Check if project and files imported', async function (): Promise<void> {
86
+ const applicationSourceProjectName: string = GitUtil.getProjectNameFromGitUrl(gitImportRepo);
87
+ const projectSection: ViewSection = await new SideBarView().getContent().getSection(applicationSourceProjectName);
88
+ const isFileImported: ViewItem | undefined = await projectSection.findItem(TestConstants.TS_SELENIUM_PROJECT_ROOT_FILE_NAME);
89
+ expect(isFileImported).not.eqls(undefined);
90
+ });
91
+
92
+ loginTests.logoutFromChe();
93
+
94
+ suiteTeardown('Delete project using ocp', async function (): Promise<void> {
95
+ kubernetesCommandLineToolsExecutor.deleteProject(projectName);
96
+ });
97
+ });
@@ -89,7 +89,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
89
89
 
90
90
  test('Check if a project folder has been created', async function (): Promise<void> {
91
91
  Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
92
- projectSection = await new SideBarView().getContent().getSection(testRepoProjectName as unknown as string);
92
+ projectSection = await new SideBarView().getContent().getSection(testRepoProjectName);
93
93
  });
94
94
 
95
95
  test('Check if the project files were imported', async function (): Promise<void> {
@@ -115,7 +115,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
115
115
 
116
116
  test('Check if a project folder has been created', async function (): Promise<void> {
117
117
  Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
118
- projectSection = await new SideBarView().getContent().getSection(testRepoProjectName as unknown as string);
118
+ projectSection = await new SideBarView().getContent().getSection(testRepoProjectName);
119
119
  });
120
120
 
121
121
  test('Accept the project as a trusted one', async function (): Promise<void> {
@@ -98,7 +98,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
98
98
 
99
99
  test('Check if a project folder has been created', async function (): Promise<void> {
100
100
  Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
101
- projectSection = await new SideBarView().getContent().getSection(testRepoProjectName as unknown as string);
101
+ projectSection = await new SideBarView().getContent().getSection(testRepoProjectName);
102
102
  });
103
103
 
104
104
  test('Accept the project as a trusted one', async function (): Promise<void> {
@@ -12,26 +12,36 @@ import { CLASSES, TYPES } from '../configs/inversify.types';
12
12
  import { ICheLoginPage } from '../pageobjects/login/ICheLoginPage';
13
13
  import { TestConstants } from '../constants/TestConstants';
14
14
  import { BrowserTabsUtil } from '../utils/BrowserTabsUtil';
15
- import { Logger } from '../utils/Logger';
16
15
  import { inject, injectable } from 'inversify';
17
16
  import { Dashboard } from '../pageobjects/dashboard/Dashboard';
17
+ import { IOcpLoginPage } from '../pageobjects/login/IOcpLoginPage';
18
18
 
19
19
  @injectable()
20
20
  export class LoginTests {
21
21
  constructor(
22
22
  @inject(CLASSES.BrowserTabsUtil) private readonly browserTabsUtil: BrowserTabsUtil,
23
- @inject(TYPES.CheLogin) private readonly loginPage: ICheLoginPage,
23
+ @inject(TYPES.CheLogin) private readonly productLoginPage: ICheLoginPage,
24
+ @inject(TYPES.OcpLogin) private readonly ocpLoginPage: IOcpLoginPage,
24
25
  @inject(CLASSES.Dashboard) private readonly dashboard: Dashboard) {
25
26
  }
26
27
 
27
28
  public loginIntoChe(): void {
28
29
  test('Login', async () => {
29
- await this.browserTabsUtil.navigateTo(TestConstants.TS_SELENIUM_BASE_URL);
30
- await this.loginPage.login();
31
- if (TestConstants.TS_SELENIUM_LAUNCH_FULLSCREEN) {
32
- Logger.debug(`TS_SELENIUM_LAUNCH_FULLSCREEN is set to true, maximizing window.`);
33
- await this.browserTabsUtil.maximize();
30
+ if (!(await this.browserTabsUtil.getCurrentUrl()).includes(TestConstants.TS_SELENIUM_BASE_URL)) {
31
+ await this.browserTabsUtil.navigateTo(TestConstants.TS_SELENIUM_BASE_URL);
34
32
  }
33
+ await this.productLoginPage.login();
34
+ await this.browserTabsUtil.maximize();
35
+ await this.dashboard.waitStartingPageLoaderDisappearance();
36
+ });
37
+ }
38
+
39
+ public loginIntoOcpConsole(): void {
40
+ test('Login into ocp console', async () => {
41
+ const openshiftConsoleUrl: string = TestConstants.TS_SELENIUM_BASE_URL.replace('devspaces', 'console-openshift-console');
42
+ await this.browserTabsUtil.navigateTo(openshiftConsoleUrl);
43
+ await this.ocpLoginPage.login();
44
+ await this.browserTabsUtil.maximize();
35
45
  });
36
46
  }
37
47
 
@@ -13,6 +13,7 @@ import { CLASSES } from '../configs/inversify.types';
13
13
  import { DriverHelper } from './DriverHelper';
14
14
  import { Logger } from './Logger';
15
15
  import { TimeoutConstants } from '../constants/TimeoutConstants';
16
+ import { TestConstants } from '../constants/TestConstants';
16
17
 
17
18
  @injectable()
18
19
  export class BrowserTabsUtil {
@@ -91,8 +92,9 @@ export class BrowserTabsUtil {
91
92
 
92
93
  public async maximize(): Promise<void> {
93
94
  Logger.trace(`BrowserTabsUtil.maximize`);
94
-
95
- await this.driverHelper.getDriver().manage().window().maximize();
95
+ if (TestConstants.TS_SELENIUM_LAUNCH_FULLSCREEN) {
96
+ Logger.debug(`TS_SELENIUM_LAUNCH_FULLSCREEN is set to true, maximizing window.`);
97
+ await this.driverHelper.getDriver().manage().window().maximize();
98
+ }
96
99
  }
97
-
98
100
  }
@@ -48,6 +48,12 @@ export class DriverHelper {
48
48
  await this.driver.sleep(milliseconds);
49
49
  }
50
50
 
51
+ public async refreshPage(): Promise<void> {
52
+ Logger.trace(`DriverHelper.refreshPage`);
53
+
54
+ await this.driver.navigate().refresh();
55
+ }
56
+
51
57
  public async waitVisibilityBoolean(locator: By,
52
58
  attempts: number = TestConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
53
59
  polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
@@ -273,12 +279,27 @@ export class DriverHelper {
273
279
  await element.click();
274
280
  return;
275
281
  } catch (err) {
276
- if (err instanceof error.StaleElementReferenceError) {
277
- Logger.debug(`DriverHelper.waitAndClik - ${elementLocator} - StaleElementReferenceError - ${err}`);
282
+ function isElementClickInterceptedOnLastAttempt(err: Error, i: number): boolean {
283
+ return err instanceof error.ElementClickInterceptedError && i === attempts - 1;
284
+ }
285
+
286
+ if (err instanceof error.StaleElementReferenceError || err instanceof error.ElementClickInterceptedError) {
287
+ Logger.debug(`DriverHelper.waitAndClick - ${elementLocator} - ${err}`);
278
288
  await this.wait(polling);
279
289
  continue;
280
290
  }
281
291
 
292
+ if (isElementClickInterceptedOnLastAttempt(err, i)) {
293
+ Logger.debug(`DriverHelper.waitAndClick - Element is not clickable, try to perform pointer click`);
294
+ await this.getAction()
295
+ .move({
296
+ origin: await this.waitPresence(elementLocator)
297
+ })
298
+ .click()
299
+ .perform();
300
+ return;
301
+ }
302
+
282
303
  Logger.error(`DriverHelper.waitAndClick - failed with an unexpected exception - ${err}`);
283
304
  throw err;
284
305
  }
@@ -658,7 +679,8 @@ export class DriverHelper {
658
679
  }
659
680
 
660
681
  try {
661
- await this.getAction().move({origin: element}).perform();
682
+ await this.getDriver()
683
+ .executeScript('arguments[0].scrollIntoView(true);', element);
662
684
  return;
663
685
  } catch (err) {
664
686
  if (err instanceof error.StaleElementReferenceError) {
@@ -674,7 +696,17 @@ export class DriverHelper {
674
696
  throw new error.TimeoutError(`Exceeded maximum mouse move attempts, for the '${elementLocator}' element`);
675
697
  }
676
698
 
677
- getDriver(): ThenableWebDriver {
699
+ public async scrollToAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
700
+ await this.scrollTo(elementLocator, timeout);
701
+ await this.waitAndClick(elementLocator, timeout);
702
+ }
703
+
704
+ public async scrollToAndEnterValue(elementLocator: By, value: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
705
+ await this.scrollTo(elementLocator, timeout);
706
+ await this.enterValue(elementLocator, value, timeout);
707
+ }
708
+
709
+ getDriver(): ThenableWebDriver {
678
710
  Logger.trace('DriverHelper.getDriver');
679
711
 
680
712
  return this.driver;
@@ -2,6 +2,7 @@ import { echo, exec, ShellString } from 'shelljs';
2
2
  import { KubernetesCommandLineTool, TestConstants } from '../constants/TestConstants';
3
3
  import { Logger } from './Logger';
4
4
  import { ShellExecutor } from './ShellExecutor';
5
+ import { TimeoutConstants } from '../constants/TimeoutConstants';
5
6
 
6
7
  export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
7
8
  private static container: string;
@@ -27,11 +28,14 @@ export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
27
28
  // login to Openshift cluster with username and password
28
29
  loginToOcp(): void {
29
30
  if (this.KUBERNETES_COMMAND_LINE_TOOL === KubernetesCommandLineTool.OC) {
30
- Logger.debug(`${this.getLoggingName(this.loginToOcp.name)}: Login to the "OC" client`);
31
+ Logger.debug(`${this.getLoggingName(this.loginToOcp.name)}: Login to the "OC" client.`);
31
32
  const url: string = this.getServerUrl();
32
- Logger.debug(url, TestConstants.TS_SELENIUM_OCP_USERNAME);
33
- exec(`sleep 5
34
- oc login --server=${url} -u=${TestConstants.TS_SELENIUM_OCP_USERNAME} -p=${TestConstants.TS_SELENIUM_OCP_PASSWORD} --insecure-skip-tls-verify`);
33
+ if (this.isUserLoggedIn()) {
34
+ Logger.debug(`${this.getLoggingName(this.loginToOcp.name)}: User already logged`);
35
+ } else {
36
+ Logger.debug(`${this.getLoggingName(this.loginToOcp.name)}: Login ${url}, ${TestConstants.TS_SELENIUM_OCP_USERNAME}`);
37
+ exec(`oc login --server=${url} -u=${TestConstants.TS_SELENIUM_OCP_USERNAME} -p=${TestConstants.TS_SELENIUM_OCP_PASSWORD} --insecure-skip-tls-verify`);
38
+ }
35
39
  } else {
36
40
  Logger.debug(`${this.getLoggingName(this.loginToOcp.name)}: doesn't support login command`);
37
41
  }
@@ -54,6 +58,7 @@ export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
54
58
  Logger.debug(`${this.getLoggingName(this.deleteDevWorkspace.name)}: Delete '${this.workspaceName}' workspace`);
55
59
  this.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} patch dw ${this.workspaceName} -n ${this.namespace} -p '{ "metadata": { "finalizers": null }}' --type merge || true`);
56
60
  this.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} delete dw ${this.workspaceName} -n ${this.namespace} || true`);
61
+ this.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} delete dwt ${TestConstants.TS_SELENIUM_EDITOR}-${this.workspaceName} -n ${this.namespace} || true`);
57
62
  }
58
63
 
59
64
  applyAndWaitDevWorkspace(yamlConfiguration: string): ShellString {
@@ -89,6 +94,22 @@ export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
89
94
  this.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} create namespace ${this.namespace}`);
90
95
  }
91
96
 
97
+ createProject(projectName: string, timeout: number = TimeoutConstants.TS_SELENIUM_TERMINAL_DEFAULT_TIMEOUT * 2): void {
98
+ Logger.debug(`${this.getLoggingName(this.createProject.name)}: Create new project "${projectName}".`);
99
+ this.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} new-project ${projectName} -n ${this.namespace}`);
100
+ }
101
+
102
+ deleteProject(projectName: string): void {
103
+ Logger.debug(`${this.getLoggingName(this.deleteProject.name)}: Delete "${projectName}".`);
104
+ this.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} delete project ${projectName} -n ${this.namespace}`);
105
+ }
106
+
107
+ private isUserLoggedIn(): boolean {
108
+ const whoamiCommandOutput: ShellString = this.execWithLog('oc whoami && oc whoami --show-server=true');
109
+
110
+ return whoamiCommandOutput.stdout.includes(TestConstants.TS_SELENIUM_OCP_USERNAME) && whoamiCommandOutput.stdout.includes(this.getServerUrl());
111
+ }
112
+
92
113
  private getLoggingName(methodName: string): string {
93
114
  return `${this.constructor.name}.${methodName} - ${(this.KUBERNETES_COMMAND_LINE_TOOL)}`;
94
115
  }
@@ -110,7 +131,7 @@ export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
110
131
  export namespace KubernetesCommandLineToolsExecutor {
111
132
  export class ContainerTerminal extends KubernetesCommandLineToolsExecutor {
112
133
  constructor(cluster: KubernetesCommandLineToolsExecutor) {
113
- super(cluster.getWorkspaceName, cluster.getNamespace);
134
+ super(cluster.getWorkspaceName, cluster.getNamespace);
114
135
  }
115
136
 
116
137
  ls(path: string = ''): ShellString {