@eclipse-che/che-e2e 7.64.0-dev-20514b2 → 7.64.0-dev-f0466d9

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 (165) hide show
  1. package/README.md +11 -37
  2. package/build/dockerfiles/entrypoint.sh +1 -1
  3. package/configs/inversify.config.ts +11 -26
  4. package/configs/inversify.types.ts +5 -35
  5. package/configs/mocharc.ts +9 -3
  6. package/configs/sh-scripts/initDefaultValues.sh +0 -5
  7. package/constants/TestConstants.ts +35 -97
  8. package/constants/TimeoutConstants.ts +1 -1
  9. package/dist/configs/inversify.config.js +8 -23
  10. package/dist/configs/inversify.config.js.map +1 -1
  11. package/dist/configs/inversify.types.js +3 -33
  12. package/dist/configs/inversify.types.js.map +1 -1
  13. package/dist/configs/mocharc.js +11 -4
  14. package/dist/configs/mocharc.js.map +1 -1
  15. package/dist/constants/TestConstants.js +31 -86
  16. package/dist/constants/TestConstants.js.map +1 -1
  17. package/dist/constants/TimeoutConstants.js.map +1 -1
  18. package/dist/driver/ChromeDriver.js +1 -1
  19. package/dist/driver/ChromeDriver.js.map +1 -1
  20. package/dist/index.js +63 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/pageobjects/dashboard/CreateWorkspace.js +8 -16
  23. package/dist/pageobjects/dashboard/CreateWorkspace.js.map +1 -1
  24. package/dist/pageobjects/dashboard/Dashboard.js +16 -1
  25. package/dist/pageobjects/dashboard/Dashboard.js.map +1 -1
  26. package/dist/pageobjects/dashboard/Workspaces.js +1 -3
  27. package/dist/pageobjects/dashboard/Workspaces.js.map +1 -1
  28. package/dist/pageobjects/git-providers/OauthPage.js +150 -0
  29. package/dist/pageobjects/git-providers/OauthPage.js.map +1 -0
  30. package/dist/pageobjects/ide/CheCodeLocatorLoader.js +65 -0
  31. package/dist/pageobjects/ide/CheCodeLocatorLoader.js.map +1 -0
  32. package/dist/pageobjects/login/OcpRedHatLoginPage.js +67 -0
  33. package/dist/pageobjects/login/OcpRedHatLoginPage.js.map +1 -0
  34. package/dist/pageobjects/login/RedHatLoginPage.js +78 -0
  35. package/dist/pageobjects/login/RedHatLoginPage.js.map +1 -0
  36. package/dist/pageobjects/login/RegularUserOcpCheLoginPage.js +3 -21
  37. package/dist/pageobjects/login/RegularUserOcpCheLoginPage.js.map +1 -1
  38. package/dist/pageobjects/openshift/CheLoginPage.js +0 -33
  39. package/dist/pageobjects/openshift/CheLoginPage.js.map +1 -1
  40. package/dist/pageobjects/openshift/OcpLoginPage.js +0 -14
  41. package/dist/pageobjects/openshift/OcpLoginPage.js.map +1 -1
  42. package/dist/specs/MochaHooks.js +2 -2
  43. package/dist/specs/MochaHooks.js.map +1 -1
  44. package/dist/specs/SmokeTest.spec.js +49 -0
  45. package/dist/specs/SmokeTest.spec.js.map +1 -0
  46. package/dist/specs/devfiles/EmptyWorkspace.spec.js +1 -0
  47. package/dist/specs/devfiles/EmptyWorkspace.spec.js.map +1 -1
  48. package/dist/specs/devfiles/Quarkus.spec.js +50 -0
  49. package/dist/specs/devfiles/Quarkus.spec.js.map +1 -0
  50. package/dist/specs/factory/Factory.spec.js +160 -0
  51. package/dist/specs/factory/Factory.spec.js.map +1 -0
  52. package/dist/specs/factory/NoSetupRepoFactory.spec.js +228 -0
  53. package/dist/specs/factory/NoSetupRepoFactory.spec.js.map +1 -0
  54. package/dist/specs/factory/RefusedOAuthFactory.spec.js +220 -0
  55. package/dist/specs/factory/RefusedOAuthFactory.spec.js.map +1 -0
  56. package/dist/specs/miscellaneous/PredefinedNamespace.spec.js +66 -0
  57. package/dist/specs/miscellaneous/PredefinedNamespace.spec.js.map +1 -0
  58. package/dist/tests-library/LoginTests.js +10 -2
  59. package/dist/tests-library/LoginTests.js.map +1 -1
  60. package/dist/tests-library/WorkspaceHandlingTests.js +15 -6
  61. package/dist/tests-library/WorkspaceHandlingTests.js.map +1 -1
  62. package/dist/utils/BrowserTabsUtil.js +2 -21
  63. package/dist/utils/BrowserTabsUtil.js.map +1 -1
  64. package/dist/utils/CheReporter.js +5 -2
  65. package/dist/utils/CheReporter.js.map +1 -1
  66. package/dist/utils/DriverHelper.js +11 -73
  67. package/dist/utils/DriverHelper.js.map +1 -1
  68. package/dist/utils/Logger.js +5 -0
  69. package/dist/utils/Logger.js.map +1 -1
  70. package/dist/utils/Sanitizer.js.map +1 -1
  71. package/dist/utils/ScreenCatcher.js.map +1 -1
  72. package/dist/utils/request-handlers/CheApiRequestHandler.js +1 -1
  73. package/dist/utils/request-handlers/CheApiRequestHandler.js.map +1 -1
  74. package/dist/utils/request-handlers/headers/CheMultiuserAuthorizationHeaderHandler.js.map +1 -1
  75. package/dist/utils/vsc/GitUtil.js +36 -0
  76. package/dist/utils/vsc/GitUtil.js.map +1 -0
  77. package/dist/utils/workspace/ApiUrlResolver.js +0 -3
  78. package/dist/utils/workspace/ApiUrlResolver.js.map +1 -1
  79. package/dist/utils/workspace/TestWorkspaceUtil.js +3 -193
  80. package/dist/utils/workspace/TestWorkspaceUtil.js.map +1 -1
  81. package/driver/ChromeDriver.ts +3 -3
  82. package/index.ts +37 -0
  83. package/package.json +9 -5
  84. package/pageobjects/dashboard/CreateWorkspace.ts +10 -21
  85. package/pageobjects/dashboard/Dashboard.ts +37 -16
  86. package/pageobjects/dashboard/Workspaces.ts +21 -23
  87. package/pageobjects/dashboard/workspace-details/WorkspaceDetails.ts +16 -16
  88. package/pageobjects/git-providers/OauthPage.ts +156 -0
  89. package/pageobjects/ide/CheCodeLocatorLoader.ts +69 -0
  90. package/pageobjects/login/OcpRedHatLoginPage.ts +49 -0
  91. package/pageobjects/login/OcpUserLoginPage.ts +1 -1
  92. package/pageobjects/login/RedHatLoginPage.ts +62 -0
  93. package/pageobjects/login/RegularUserOcpCheLoginPage.ts +2 -21
  94. package/pageobjects/openshift/CheLoginPage.ts +8 -57
  95. package/pageobjects/openshift/OcpLoginPage.ts +8 -29
  96. package/specs/MochaHooks.ts +9 -9
  97. package/specs/SmokeTest.spec.ts +50 -0
  98. package/specs/devfiles/EmptyWorkspace.spec.ts +1 -0
  99. package/specs/devfiles/Quarkus.spec.ts +52 -0
  100. package/specs/factory/Factory.spec.ts +199 -0
  101. package/specs/factory/NoSetupRepoFactory.spec.ts +272 -0
  102. package/specs/factory/RefusedOAuthFactory.spec.ts +260 -0
  103. package/specs/miscellaneous/PredefinedNamespace.spec.ts +74 -0
  104. package/tests-library/LoginTests.ts +9 -1
  105. package/tests-library/WorkspaceHandlingTests.ts +16 -7
  106. package/tslint.json +4 -4
  107. package/utils/BrowserTabsUtil.ts +9 -31
  108. package/utils/CheReporter.ts +12 -8
  109. package/utils/DriverHelper.ts +40 -115
  110. package/utils/Logger.ts +13 -8
  111. package/utils/Sanitizer.ts +0 -1
  112. package/utils/ScreenCatcher.ts +8 -7
  113. package/utils/request-handlers/CheApiRequestHandler.ts +1 -1
  114. package/utils/request-handlers/headers/CheMultiuserAuthorizationHeaderHandler.ts +2 -1
  115. package/utils/vsc/GitUtil.ts +25 -0
  116. package/utils/workspace/ApiUrlResolver.ts +3 -6
  117. package/utils/workspace/ITestWorkspaceUtil.ts +1 -56
  118. package/utils/workspace/TestWorkspaceUtil.ts +24 -265
  119. package/dist/pageobjects/dashboard/workspace-details/WorkspaceDetailsPlugins.js +0 -97
  120. package/dist/pageobjects/dashboard/workspace-details/WorkspaceDetailsPlugins.js.map +0 -1
  121. package/dist/pageobjects/login/MultiUserLoginPage.js +0 -49
  122. package/dist/pageobjects/login/MultiUserLoginPage.js.map +0 -1
  123. package/dist/pageobjects/login/UpdateAccountInformationPage.js +0 -74
  124. package/dist/pageobjects/login/UpdateAccountInformationPage.js.map +0 -1
  125. package/dist/pageobjects/third-parties/GitLoginPage.js +0 -85
  126. package/dist/pageobjects/third-parties/GitLoginPage.js.map +0 -1
  127. package/dist/pageobjects/third-parties/GitOauthAppsSettings.js +0 -110
  128. package/dist/pageobjects/third-parties/GitOauthAppsSettings.js.map +0 -1
  129. package/dist/specs/login/LinkCheAndOcpUsers.spec.js +0 -40
  130. package/dist/specs/login/LinkCheAndOcpUsers.spec.js.map +0 -1
  131. package/dist/utils/WorkspaceNameHandler.js +0 -60
  132. package/dist/utils/WorkspaceNameHandler.js.map +0 -1
  133. package/dist/utils/request-handlers/tokens/CheMultiuserTokenHandler.js +0 -50
  134. package/dist/utils/request-handlers/tokens/CheMultiuserTokenHandler.js.map +0 -1
  135. package/dist/utils/request-handlers/tokens/ITokenHandler.js +0 -12
  136. package/dist/utils/request-handlers/tokens/ITokenHandler.js.map +0 -1
  137. package/dist/utils/vsc/CheGitApi.js +0 -42
  138. package/dist/utils/vsc/CheGitApi.js.map +0 -1
  139. package/dist/utils/vsc/github/GitHubUtil.js +0 -126
  140. package/dist/utils/vsc/github/GitHubUtil.js.map +0 -1
  141. package/files/devfiles/plugins/GitHubPullRequestPlugin.yaml +0 -11
  142. package/files/devfiles/plugins/InstallPluginUsingUI.yaml +0 -3
  143. package/files/devfiles/plugins/Java11PluginTest.yaml +0 -17
  144. package/files/devfiles/plugins/PhpPluginTest.yaml +0 -47
  145. package/files/devfiles/plugins/PythonPluginTest.yaml +0 -14
  146. package/files/devfiles/plugins/TypescriptNodeDebug2PluginTest.yaml +0 -49
  147. package/files/devfiles/plugins/VscodeKubernetesPlugin.yaml +0 -12
  148. package/files/devfiles/plugins/VscodeShellcheckPlugin.yaml +0 -12
  149. package/files/devfiles/plugins/VscodeValePlugin.yaml +0 -42
  150. package/files/devfiles/plugins/VscodeXmlPlugin.yaml +0 -12
  151. package/files/devfiles/plugins/VscodeYamlPlugin.yaml +0 -12
  152. package/files/happy-path/containers-happy-path.yaml +0 -127
  153. package/files/happy-path/happy-path-workspace.yaml +0 -95
  154. package/files/happy-path/petclinic-classpath.txt +0 -49
  155. package/pageobjects/dashboard/workspace-details/WorkspaceDetailsPlugins.ts +0 -95
  156. package/pageobjects/login/MultiUserLoginPage.ts +0 -33
  157. package/pageobjects/login/UpdateAccountInformationPage.ts +0 -70
  158. package/pageobjects/third-parties/GitLoginPage.ts +0 -81
  159. package/pageobjects/third-parties/GitOauthAppsSettings.ts +0 -110
  160. package/specs/login/LinkCheAndOcpUsers.spec.ts +0 -49
  161. package/utils/WorkspaceNameHandler.ts +0 -48
  162. package/utils/request-handlers/tokens/CheMultiuserTokenHandler.ts +0 -41
  163. package/utils/request-handlers/tokens/ITokenHandler.ts +0 -14
  164. package/utils/vsc/CheGitApi.ts +0 -22
  165. package/utils/vsc/github/GitHubUtil.ts +0 -110
@@ -0,0 +1,272 @@
1
+ /*********************************************************************
2
+ * Copyright (c) 2021 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 'reflect-metadata';
12
+ import { e2eContainer } from '../../configs/inversify.config';
13
+ import {
14
+ ActivityBar,
15
+ ContextMenu,
16
+ EditorView,
17
+ error,
18
+ InputBox,
19
+ Locators,
20
+ ModalDialog,
21
+ NewScmView,
22
+ SideBarView,
23
+ SingleScmProvider,
24
+ TextEditor,
25
+ ViewControl,
26
+ ViewItem,
27
+ ViewSection
28
+ } from 'monaco-page-objects';
29
+ import { expect } from 'chai';
30
+ import { GitUtil } from '../../utils/vsc/GitUtil';
31
+ import { CheCodeLocatorLoader } from '../../pageobjects/ide/CheCodeLocatorLoader';
32
+ import WebDriverError = error.WebDriverError;
33
+ import { registerRunningWorkspace } from '../MochaHooks';
34
+ import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil';
35
+ import { CLASSES } from '../../configs/inversify.types';
36
+ import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests';
37
+ import { ProjectAndFileTests } from '../../tests-library/ProjectAndFileTests';
38
+ import { DriverHelper } from '../../utils/DriverHelper';
39
+ import { Dashboard } from '../../pageobjects/dashboard/Dashboard';
40
+ import { Workspaces } from '../../pageobjects/dashboard/Workspaces';
41
+ import { GitProviderType, TestConstants } from '../../constants/TestConstants';
42
+ import { TimeoutConstants } from '../../constants/TimeoutConstants';
43
+ import { Logger } from '../../utils/Logger';
44
+ import { LoginTests } from '../../tests-library/LoginTests';
45
+
46
+ const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil);
47
+ const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
48
+ const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests);
49
+ const webCheCodeLocators: Locators = new CheCodeLocatorLoader().webCheCodeLocators;
50
+ const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
51
+ const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
52
+ const workspaces: Workspaces = e2eContainer.get(CLASSES.Workspaces);
53
+ const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
54
+
55
+ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SELENIUM_FACTORY_GIT_PROVIDER} repository without OAuth setup`, async function (): Promise<void> {
56
+
57
+ let projectSection: ViewSection;
58
+ let scmProvider: SingleScmProvider;
59
+ let rest: SingleScmProvider[];
60
+ let scmContextMenu: ContextMenu;
61
+ const gitUtilCheCode: GitUtil = new GitUtil();
62
+
63
+ // test specific data
64
+ let numberOfCreatedWorkspaces: number = 0;
65
+ const timeToRefresh: number = 1500;
66
+ const changesToCommit: string = (new Date()).getTime().toString();
67
+ const fileToChange: string = 'Date.txt';
68
+ const pushItemLabel: string = 'Push';
69
+ const commitChangesButtonLabel: string = `Commit Changes on "${TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}"`;
70
+ const refreshButtonLabel: string = 'Refresh';
71
+ const label: string = TestConstants.TS_SELENIUM_PROJECT_ROOT_FILE_NAME;
72
+ const testRepoProjectName: string = gitUtilCheCode.getProjectNameFromGitUrl(TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_URL);
73
+ const isPrivateRepo: string = TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO ? 'private' : 'public';
74
+
75
+ loginTests.loginIntoChe();
76
+
77
+ test('Get number of previously created workspaces', async function (): Promise<void> {
78
+ await dashboard.clickWorkspacesButton();
79
+ await workspaces.waitPage();
80
+ numberOfCreatedWorkspaces = (await workspaces.getAllCreatedWorkspacesNames()).length;
81
+ });
82
+
83
+ test(`Navigate to the ${isPrivateRepo} repository factory URL`, async function (): Promise<void> {
84
+ await browserTabsUtil.navigateTo(TestConstants.TS_SELENIUM_FACTORY_URL());
85
+ });
86
+
87
+ if (TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO) {
88
+
89
+ test(`Check that workspace cannot be created without OAuth for ${isPrivateRepo} repo`, async function (): Promise<void> {
90
+ await dashboard.waitLoader();
91
+ const loaderAlert: string = await dashboard.getLoaderAlert();
92
+ expect(loaderAlert).contains('Failed to create the workspace')
93
+ .and.contains('Cause: Unsupported OAuth provider ');
94
+ });
95
+
96
+ test(`Check that workspace was not created`, async function (): Promise<void> {
97
+ await dashboard.openDashboard();
98
+ await dashboard.clickWorkspacesButton();
99
+ await workspaces.waitPage();
100
+ const allCreatedWorkspacesNames: string[] = await workspaces.getAllCreatedWorkspacesNames();
101
+ expect(allCreatedWorkspacesNames).has.length(numberOfCreatedWorkspaces);
102
+ });
103
+
104
+ loginTests.logoutFromChe();
105
+
106
+ } else {
107
+ workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
108
+
109
+ test('Registering the running workspace', async function (): Promise<void> {
110
+ registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName());
111
+ });
112
+
113
+ test('Wait the workspace readiness', async function (): Promise<void> {
114
+ await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
115
+ });
116
+
117
+ test('Check if a project folder has been created', async function (): Promise<void> {
118
+ Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
119
+ projectSection = await new SideBarView().getContent().getSection(testRepoProjectName as unknown as string);
120
+ });
121
+
122
+ test('Accept the project as a trusted one', async function (): Promise<void> {
123
+ // click somewhere to trigger "Welcome Content" dialog
124
+ try {
125
+ await driverHelper.waitAndClick(webCheCodeLocators.Workbench.notificationItem);
126
+ } catch (e) {
127
+ Logger.info(`Click on ${webCheCodeLocators.Workbench.notificationItem} to get "Welcome Content" dialog ${e as string}`);
128
+ }
129
+ // "Welcome Content" dialog can be shown before of after dialog with an error for private repo
130
+ try {
131
+ const buttonYesITrustTheAuthors: string = `Yes, I trust the authors`;
132
+ await driverHelper.waitVisibility(webCheCodeLocators.WelcomeContent.text, TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM);
133
+ const welcomeContentDialog: ModalDialog = new ModalDialog();
134
+ Logger.debug(`trustedProjectDialog.pushButton: "${buttonYesITrustTheAuthors}"`);
135
+ await welcomeContentDialog.pushButton(buttonYesITrustTheAuthors);
136
+ await driverHelper.waitDisappearance(webCheCodeLocators.WelcomeContent.text);
137
+ } catch (e) {
138
+ Logger.info(`"Accept the project as a trusted one" dialog was not shown firstly for "${isPrivateRepo}"`);
139
+ if (!TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO) {
140
+ throw new WebDriverError(e as string);
141
+ }
142
+ }
143
+ });
144
+
145
+ test('Check if the project files were imported', async function (): Promise<void> {
146
+ Logger.debug(`projectSection.findItem: find ${label}`);
147
+ const isFileImported: ViewItem | undefined = await projectSection.findItem(label);
148
+ // projectSection.findItem(label) can return undefined but test will goes on
149
+ expect(isFileImported).not.eqls(undefined);
150
+ });
151
+
152
+ test('Make changes to the file', async function (): Promise<void> {
153
+ Logger.debug(`projectSection.openItem: "${fileToChange}"`);
154
+ await projectSection.openItem(fileToChange);
155
+ const editor: TextEditor = await new EditorView().openEditor(fileToChange) as TextEditor;
156
+ await driverHelper.waitVisibility(webCheCodeLocators.Editor.inputArea);
157
+ Logger.debug(`editor.clearText`);
158
+ await editor.clearText();
159
+ Logger.debug(`editor.typeTextAt: "${changesToCommit}"`);
160
+ await editor.typeTextAt(1, 1, changesToCommit);
161
+ });
162
+
163
+ test('Open a source control manager', async function (): Promise<void> {
164
+ const viewSourceControl: string = `Source Control`;
165
+ const sourceControl: ViewControl = await new ActivityBar().getViewControl(viewSourceControl) as ViewControl;
166
+ Logger.debug(`sourceControl.openView: "${viewSourceControl}"`);
167
+ await sourceControl.openView();
168
+ const scmView: NewScmView = new NewScmView();
169
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel));
170
+ [scmProvider, ...rest] = await scmView.getProviders();
171
+ Logger.debug(`scmView.getProviders: "${scmProvider}, ${scmProvider}"`);
172
+ });
173
+
174
+ test('Check if the changes is displayed in the source control manager', async function (): Promise<void> {
175
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
176
+ await driverHelper.wait(timeToRefresh);
177
+ Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
178
+ await scmProvider.takeAction(refreshButtonLabel);
179
+ // wait while changes counter will be refreshed
180
+ await driverHelper.wait(timeToRefresh);
181
+ const changes: number = await scmProvider.getChangeCount();
182
+ Logger.debug(`scmProvider.getChangeCount: number of changes is "${changes}"`);
183
+ expect(changes).eql(1);
184
+ });
185
+
186
+ test('Stage the changes', async function (): Promise<void> {
187
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
188
+ Logger.debug(`scmProvider.openMoreActions`);
189
+ scmContextMenu = await scmProvider.openMoreActions();
190
+ await driverHelper.waitVisibility(webCheCodeLocators.ContextMenu.contextView);
191
+ Logger.debug(`scmContextMenu.select: "Changes" -> "Stage All Changes"`);
192
+ await scmContextMenu.select('Changes', 'Stage All Changes');
193
+ });
194
+
195
+ test('Commit the changes', async function (): Promise<void> {
196
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel));
197
+ Logger.debug(`scmProvider.commitChanges: commit name "Commit ${changesToCommit}"`);
198
+ await scmProvider.commitChanges('Commit ' + changesToCommit);
199
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
200
+ await driverHelper.wait(timeToRefresh);
201
+ Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
202
+ await scmProvider.takeAction(refreshButtonLabel);
203
+ // wait while changes counter will be refreshed
204
+ await driverHelper.wait(timeToRefresh);
205
+ const changes: number = await scmProvider.getChangeCount();
206
+ Logger.debug(`scmProvider.getChangeCount: number of changes is "${changes}"`);
207
+ expect(changes).eql(0);
208
+ });
209
+
210
+ test('Push the changes', async function (): Promise<void> {
211
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.actionConstructor(`Push 1 commits to origin/${TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}`));
212
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
213
+ Logger.debug(`scmProvider.openMoreActions`);
214
+ scmContextMenu = await scmProvider.openMoreActions();
215
+ await driverHelper.waitVisibility(webCheCodeLocators.ContextMenu.itemConstructor(pushItemLabel));
216
+ Logger.debug(`scmContextMenu.select: "${pushItemLabel}"`);
217
+ await scmContextMenu.select(pushItemLabel);
218
+ });
219
+
220
+ if (TestConstants.TS_SELENIUM_FACTORY_GIT_PROVIDER === GitProviderType.GITHUB) {
221
+ test('Decline GitHub Extension', async function (): Promise<void> {
222
+ await driverHelper.waitVisibility(webCheCodeLocators.Dialog.details);
223
+ const gitHaExtensionDialog: ModalDialog = new ModalDialog();
224
+ await gitHaExtensionDialog.pushButton('Cancel');
225
+ });
226
+ }
227
+
228
+ test('Insert git credentials which were asked after push', async function (): Promise<void> {
229
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
230
+
231
+ try {
232
+ await driverHelper.waitVisibility(webCheCodeLocators.Input.inputBox);
233
+ } catch (e) {
234
+ Logger.info(`Workspace did not ask credentials before push - ${e};
235
+ Known issue for github.com - https://issues.redhat.com/browse/CRW-4066`);
236
+ }
237
+ const input: InputBox = new InputBox();
238
+ await input.setText(TestConstants.TS_SELENIUM_GIT_PROVIDER_USERNAME);
239
+ await driverHelper.wait(timeToRefresh);
240
+ await input.confirm();
241
+ await driverHelper.wait(timeToRefresh);
242
+ await input.setText(TestConstants.TS_SELENIUM_GIT_PROVIDER_PASSWORD);
243
+ await input.confirm();
244
+ await driverHelper.wait(timeToRefresh);
245
+ });
246
+
247
+ test('Check if the changes were pushed', async function (): Promise<void> {
248
+ try {
249
+ Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
250
+ await scmProvider.takeAction(refreshButtonLabel);
251
+ } catch (e) {
252
+ Logger.info('Check you use correct credentials.' +
253
+ 'For bitbucket.org ensure you use an app password: https://support.atlassian.com/bitbucket-cloud/docs/using-app-passwords/;' +
254
+ 'For github.com - personal access token instead of password.');
255
+ }
256
+ const isCommitButtonDisabled: string = await driverHelper.waitAndGetElementAttribute(webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel), 'aria-disabled');
257
+ expect(isCommitButtonDisabled).eql('true');
258
+ });
259
+
260
+ test(`Stop and remove the workspace`, async function (): Promise<void> {
261
+ await workspaceHandlingTests.stopAndRemoveWorkspace(WorkspaceHandlingTests.getWorkspaceName());
262
+ });
263
+
264
+ loginTests.logoutFromChe();
265
+ }
266
+
267
+ suiteTeardown('Close the browser', async function (): Promise<void> {
268
+ if (!TestConstants.TS_DEBUG_MODE) {
269
+ await driverHelper.getDriver().close();
270
+ }
271
+ });
272
+ });
@@ -0,0 +1,260 @@
1
+ /*********************************************************************
2
+ * Copyright (c) 2021 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 'reflect-metadata';
12
+ import { e2eContainer } from '../../configs/inversify.config';
13
+ import {
14
+ ActivityBar,
15
+ ContextMenu,
16
+ EditorView,
17
+ error,
18
+ InputBox,
19
+ Locators,
20
+ ModalDialog,
21
+ NewScmView,
22
+ SideBarView,
23
+ SingleScmProvider,
24
+ TextEditor,
25
+ ViewControl,
26
+ ViewItem,
27
+ ViewSection
28
+ } from 'monaco-page-objects';
29
+ import { expect } from 'chai';
30
+ import WebDriverError = error.WebDriverError;
31
+ import { registerRunningWorkspace } from '../MochaHooks';
32
+ import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil';
33
+ import { CLASSES } from '../../configs/inversify.types';
34
+ import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests';
35
+ import { CheCodeLocatorLoader } from '../../pageobjects/ide/CheCodeLocatorLoader';
36
+ import { ProjectAndFileTests } from '../../tests-library/ProjectAndFileTests';
37
+ import { DriverHelper } from '../../utils/DriverHelper';
38
+ import { TestConstants } from '../../constants/TestConstants';
39
+ import { OauthPage } from '../../pageobjects/git-providers/OauthPage';
40
+ import { GitUtil } from '../../utils/vsc/GitUtil';
41
+ import { Logger } from '../../utils/Logger';
42
+ import { TimeoutConstants } from '../../constants/TimeoutConstants';
43
+ import { LoginTests } from '../../tests-library/LoginTests';
44
+
45
+ const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil);
46
+ const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
47
+ const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests);
48
+ const webCheCodeLocators: Locators = new CheCodeLocatorLoader().webCheCodeLocators;
49
+ const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
50
+ const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
51
+
52
+ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SELENIUM_FACTORY_GIT_PROVIDER} repository and deny the access`, async function (): Promise<void> {
53
+ const oauthPage: OauthPage = new OauthPage(driverHelper);
54
+
55
+ let projectSection: ViewSection;
56
+ let scmProvider: SingleScmProvider;
57
+ let rest: SingleScmProvider[];
58
+ let scmContextMenu: ContextMenu;
59
+ const gitUtil: GitUtil = new GitUtil();
60
+
61
+ // test specific data
62
+ const timeToRefresh: number = 1500;
63
+ const changesToCommit: string = (new Date()).getTime().toString();
64
+ const fileToChange: string = 'Date.txt';
65
+ const commitChangesButtonLabel: string = `Commit Changes on "${TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}"`;
66
+ const refreshButtonLabel: string = 'Refresh';
67
+ const pushItemLabel: string = 'Push';
68
+ const label: string = TestConstants.TS_SELENIUM_PROJECT_ROOT_FILE_NAME;
69
+ const testRepoProjectName: string = gitUtil.getProjectNameFromGitUrl(TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_URL);
70
+ const isPrivateRepo: string = TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO ? 'private' : 'public';
71
+
72
+ loginTests.loginIntoChe();
73
+
74
+ test(`Navigate to the ${isPrivateRepo} repository factory URL`, async function (): Promise<void> {
75
+ await browserTabsUtil.navigateTo(TestConstants.TS_SELENIUM_FACTORY_URL());
76
+ });
77
+
78
+ if (TestConstants.TS_SELENIUM_GIT_PROVIDER_OAUTH) {
79
+ test(`Authorize with a ${TestConstants.TS_SELENIUM_FACTORY_GIT_PROVIDER} OAuth and deny access`, async function (): Promise<void> {
80
+ await oauthPage.login();
81
+ await oauthPage.waitOauthPage();
82
+ await oauthPage.denyAccess();
83
+ });
84
+ }
85
+
86
+ workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
87
+
88
+ test('The workspace starts with access deny flag in the url', async function (): Promise<void> {
89
+ expect(await driverHelper.getDriver().getCurrentUrl()).contains('&error_code=access_denied');
90
+ });
91
+
92
+ test('Registering the running workspace', async function (): Promise<void> {
93
+ registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName());
94
+ });
95
+
96
+ test('Wait the workspace readiness', async function (): Promise<void> {
97
+ await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
98
+ });
99
+
100
+ test('Check if a project folder has been created', async function (): Promise<void> {
101
+ Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
102
+ projectSection = await new SideBarView().getContent().getSection(testRepoProjectName as unknown as string);
103
+ });
104
+
105
+ test('Accept the project as a trusted one', async function (): Promise<void> {
106
+ // click somewhere to trigger "Welcome Content" dialog
107
+ try {
108
+ await driverHelper.waitAndClick(webCheCodeLocators.Workbench.notificationItem);
109
+ } catch (e) {
110
+ Logger.info(`Click on ${webCheCodeLocators.Workbench.notificationItem} to get "Welcome Content" dialog ${e as string}`);
111
+ }
112
+ // "Welcome Content" dialog can be shown before of after dialog with an error for private repo
113
+ try {
114
+ const buttonYesITrustTheAuthors: string = `Yes, I trust the authors`;
115
+ await driverHelper.waitVisibility(webCheCodeLocators.WelcomeContent.text, TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM);
116
+ const welcomeContentDialog: ModalDialog = new ModalDialog();
117
+ Logger.debug(`trustedProjectDialog.pushButton: "${buttonYesITrustTheAuthors}"`);
118
+ await welcomeContentDialog.pushButton(buttonYesITrustTheAuthors);
119
+ await driverHelper.waitDisappearance(webCheCodeLocators.WelcomeContent.text);
120
+ } catch (e) {
121
+ Logger.info(`"Accept the project as a trusted one" dialog was not shown firstly for "${isPrivateRepo}"`);
122
+ if (!TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO) {
123
+ throw new WebDriverError(e as string);
124
+ }
125
+ }
126
+ });
127
+
128
+ if (TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO) {
129
+ test('Check that project can not be cloned', async function (): Promise<void> {
130
+ await driverHelper.waitVisibility(webCheCodeLocators.Dialog.message);
131
+ const workspaceDoesNotExistDialog: ModalDialog = new ModalDialog();
132
+ const message: string = await workspaceDoesNotExistDialog.getMessage();
133
+ expect(message).contains('space does not exist');
134
+ });
135
+
136
+ test('Check that project files were not imported', async function (): Promise<void> {
137
+ const isFileImported: ViewItem | undefined = await projectSection.findItem(label);
138
+ expect(isFileImported).eqls(undefined);
139
+ });
140
+
141
+ } else {
142
+ test('Check if the project files were imported', async function (): Promise<void> {
143
+ Logger.debug(`projectSection.findItem: find ${label}`);
144
+ const isFileImported: ViewItem | undefined = await projectSection.findItem(label);
145
+ // projectSection.findItem(label) can return undefined but test will goes on
146
+ expect(isFileImported).not.eqls(undefined);
147
+ });
148
+
149
+ test('Make changes to the file', async function (): Promise<void> {
150
+ Logger.debug(`projectSection.openItem: "${fileToChange}"`);
151
+ await projectSection.openItem(fileToChange);
152
+ const editor: TextEditor = await new EditorView().openEditor(fileToChange) as TextEditor;
153
+ await driverHelper.waitVisibility(webCheCodeLocators.Editor.inputArea);
154
+ Logger.debug(`editor.clearText`);
155
+ await editor.clearText();
156
+ Logger.debug(`editor.typeTextAt: "${changesToCommit}"`);
157
+ await editor.typeTextAt(1, 1, changesToCommit);
158
+ });
159
+
160
+ test('Open a source control manager', async function (): Promise<void> {
161
+ const viewSourceControl: string = `Source Control`;
162
+ const sourceControl: ViewControl = await new ActivityBar().getViewControl(viewSourceControl) as ViewControl;
163
+ Logger.debug(`sourceControl.openView: "${viewSourceControl}"`);
164
+ await sourceControl.openView();
165
+ const scmView: NewScmView = new NewScmView();
166
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel));
167
+ [scmProvider, ...rest] = await scmView.getProviders();
168
+ Logger.debug(`scmView.getProviders: "${scmProvider}, ${scmProvider}"`);
169
+ });
170
+
171
+ test('Check if the changes is displayed in the source control manager', async function (): Promise<void> {
172
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
173
+ await driverHelper.wait(timeToRefresh);
174
+ Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
175
+ await scmProvider.takeAction(refreshButtonLabel);
176
+ // wait while changes counter will be refreshed
177
+ await driverHelper.wait(timeToRefresh);
178
+ const changes: number = await scmProvider.getChangeCount();
179
+ Logger.debug(`scmProvider.getChangeCount: number of changes is "${changes}"`);
180
+ expect(changes).eql(1);
181
+ });
182
+
183
+ test('Stage the changes', async function (): Promise<void> {
184
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
185
+ Logger.debug(`scmProvider.openMoreActions`);
186
+ scmContextMenu = await scmProvider.openMoreActions();
187
+ await driverHelper.waitVisibility(webCheCodeLocators.ContextMenu.contextView);
188
+ Logger.debug(`scmContextMenu.select: "Changes" -> "Stage All Changes"`);
189
+ await scmContextMenu.select('Changes', 'Stage All Changes');
190
+ });
191
+
192
+ test('Commit the changes', async function (): Promise<void> {
193
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel));
194
+ Logger.debug(`scmProvider.commitChanges: commit name "Commit ${changesToCommit}"`);
195
+ await scmProvider.commitChanges('Commit ' + changesToCommit);
196
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
197
+ await driverHelper.wait(timeToRefresh);
198
+ Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
199
+ await scmProvider.takeAction(refreshButtonLabel);
200
+ // wait while changes counter will be refreshed
201
+ await driverHelper.wait(timeToRefresh);
202
+ const changes: number = await scmProvider.getChangeCount();
203
+ Logger.debug(`scmProvider.getChangeCount: number of changes is "${changes}"`);
204
+ expect(changes).eql(0);
205
+ });
206
+
207
+ test('Push the changes', async function (): Promise<void> {
208
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.actionConstructor(`Push 1 commits to origin/${TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}`));
209
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
210
+ Logger.debug(`scmProvider.openMoreActions`);
211
+ scmContextMenu = await scmProvider.openMoreActions();
212
+ await driverHelper.waitVisibility(webCheCodeLocators.ContextMenu.itemConstructor(pushItemLabel));
213
+ Logger.debug(`scmContextMenu.select: "${pushItemLabel}"`);
214
+ await scmContextMenu.select(pushItemLabel);
215
+ });
216
+
217
+ test('Insert git credentials which were asked after push', async function (): Promise<void> {
218
+ await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
219
+
220
+ try {
221
+ await driverHelper.waitVisibility(webCheCodeLocators.Input.inputBox);
222
+ } catch (e) {
223
+ Logger.info(`Workspace did not ask credentials before push - ${e};
224
+ Known issue for github.com - https://issues.redhat.com/browse/CRW-4066`);
225
+ }
226
+ const input: InputBox = new InputBox();
227
+ await input.setText(TestConstants.TS_SELENIUM_GIT_PROVIDER_USERNAME);
228
+ await input.confirm();
229
+ await driverHelper.wait(timeToRefresh);
230
+ await input.setText(TestConstants.TS_SELENIUM_GIT_PROVIDER_PASSWORD);
231
+ await input.confirm();
232
+ await driverHelper.wait(timeToRefresh);
233
+ });
234
+
235
+ test('Check if the changes were pushed', async function (): Promise<void> {
236
+ try {
237
+ Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
238
+ await scmProvider.takeAction(refreshButtonLabel);
239
+ } catch (e) {
240
+ Logger.info('Check you use correct credentials.' +
241
+ 'For bitbucket.org ensure you use an app password: https://support.atlassian.com/bitbucket-cloud/docs/using-app-passwords/;' +
242
+ 'For github.com - personal access token instead of password.');
243
+ }
244
+ const isCommitButtonDisabled: string = await driverHelper.waitAndGetElementAttribute(webCheCodeLocators.ScmView.actionConstructor(commitChangesButtonLabel), 'aria-disabled');
245
+ expect(isCommitButtonDisabled).eql('true');
246
+ });
247
+ }
248
+
249
+ test(`Stop and remove the workspace`, async function (): Promise<void> {
250
+ await workspaceHandlingTests.stopAndRemoveWorkspace(WorkspaceHandlingTests.getWorkspaceName());
251
+ });
252
+
253
+ loginTests.logoutFromChe();
254
+
255
+ suiteTeardown('Close the browser', async function (): Promise<void> {
256
+ if (!TestConstants.TS_DEBUG_MODE) {
257
+ await driverHelper.getDriver().close();
258
+ }
259
+ });
260
+ });
@@ -0,0 +1,74 @@
1
+ import { e2eContainer } from '../../configs/inversify.config';
2
+ import { assert } from 'chai';
3
+ import { CLASSES } from '../../configs/inversify.types';
4
+ import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests';
5
+ import { Logger } from '../../utils/Logger';
6
+ import { LoginTests } from '../../tests-library/LoginTests';
7
+ import { registerRunningWorkspace } from '../MochaHooks';
8
+
9
+ const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
10
+ const util: any = require('node:util');
11
+ const exec: any = util.promisify(require('node:child_process').exec);
12
+ const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
13
+ const predefinedNamespaceName: string = 'predefined-ns';
14
+
15
+ async function runShellScript(shellCommandToExecution: string): Promise<string> {
16
+ const {stdout, stderr} = await exec(shellCommandToExecution);
17
+ console.log(stdout);
18
+ console.error(stderr);
19
+ return stdout;
20
+ }
21
+
22
+ suite(`Create predefined workspace and check it `, async function (): Promise<void> {
23
+ let workspaceName: string = '';
24
+
25
+ const setEditRightsForUser: string = `oc adm policy add-role-to-user edit user -n ${predefinedNamespaceName}`;
26
+ const getDevWorkspaceFromPredefinedNameSpace: string = `oc get dw -n ${predefinedNamespaceName}`;
27
+ const deletePredefinedNamespace: string = `oc delete project ${predefinedNamespaceName}`;
28
+ const createPredefinedProjectCommand: string = 'cat <<EOF | oc apply -f - \n' +
29
+ 'kind: Namespace\n' +
30
+ 'apiVersion: v1\n' +
31
+ 'metadata:\n' +
32
+ ` name: ${predefinedNamespaceName}\n` +
33
+ ' labels:\n' +
34
+ ' app.kubernetes.io/part-of: che.eclipse.org\n' +
35
+ ' app.kubernetes.io/component: workspaces-namespace\n' +
36
+ ' annotations:\n' +
37
+ ' che.eclipse.org/username: user\n' +
38
+ 'EOF';
39
+ // create a predefined namespace for user using shell script and login into user dashboard
40
+ suiteSetup(async function (): Promise<void> {
41
+ Logger.info('Test prerequisites:');
42
+ Logger.info(' (1) there is OCP user with username and user password that have been set in the TS_SELENIUM_USERNAME and TS_SELENIUM_PASSWORD variables');
43
+ Logger.info(' (2) \'oc\' client installed and logged into test OCP cluster with admin rights.');
44
+
45
+ await runShellScript(createPredefinedProjectCommand);
46
+ await runShellScript(setEditRightsForUser);
47
+ });
48
+
49
+ suiteTeardown(async (): Promise<void> => {
50
+ const workspaceName: string = WorkspaceHandlingTests.getWorkspaceName();
51
+ try {
52
+ await runShellScript(deletePredefinedNamespace);
53
+ } catch (e) {
54
+ Logger.error(`Cannot remove the predefined project: ${workspaceName}, please fix it manually: ${e}`);
55
+ }
56
+ });
57
+
58
+ loginTests.loginIntoChe();
59
+ // create the Empty workspace using CHE Dashboard
60
+ workspaceHandlingTests.createAndOpenWorkspace('Empty Workspace');
61
+ workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
62
+
63
+ // verify that just created workspace with unique name is present in the predefined namespace
64
+ test('Validate the created workspace is present in predefined namespace', async function (): Promise<void> {
65
+ workspaceName = WorkspaceHandlingTests.getWorkspaceName();
66
+ registerRunningWorkspace(workspaceName);
67
+ const ocDevWorkspaceOutput: string = await runShellScript(getDevWorkspaceFromPredefinedNameSpace);
68
+ await assert.isTrue(ocDevWorkspaceOutput.includes(workspaceName));
69
+ });
70
+
71
+ loginTests.logoutFromChe();
72
+ });
73
+
74
+
@@ -14,12 +14,14 @@ import { TestConstants } from '../constants/TestConstants';
14
14
  import { BrowserTabsUtil } from '../utils/BrowserTabsUtil';
15
15
  import { Logger } from '../utils/Logger';
16
16
  import { inject, injectable } from 'inversify';
17
+ import { Dashboard } from '../pageobjects/dashboard/Dashboard';
17
18
 
18
19
  @injectable()
19
20
  export class LoginTests {
20
21
  constructor(
21
22
  @inject(CLASSES.BrowserTabsUtil) private readonly browserTabsUtil: BrowserTabsUtil,
22
- @inject(TYPES.CheLogin) private readonly loginPage: ICheLoginPage) {
23
+ @inject(TYPES.CheLogin) private readonly loginPage: ICheLoginPage,
24
+ @inject(CLASSES.Dashboard) private readonly dashboard: Dashboard) {
23
25
  }
24
26
 
25
27
  public loginIntoChe(): void {
@@ -32,4 +34,10 @@ export class LoginTests {
32
34
  }
33
35
  });
34
36
  }
37
+
38
+ public logoutFromChe(): void {
39
+ test('Logout', async () => {
40
+ await this.dashboard.logout();
41
+ });
42
+ }
35
43
  }