@eclipse-che/che-e2e 7.64.0-dev-2c00276 → 7.64.1-dev-43c3317
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.
- package/configs/inversify.config.ts +10 -4
- package/configs/inversify.types.ts +3 -0
- package/constants/TestConstants.ts +14 -1
- package/constants/TimeoutConstants.ts +3 -3
- package/dist/configs/inversify.config.js +7 -3
- package/dist/configs/inversify.config.js.map +1 -1
- package/dist/configs/inversify.types.js +3 -0
- package/dist/configs/inversify.types.js.map +1 -1
- package/dist/constants/TestConstants.js +12 -2
- package/dist/constants/TestConstants.js.map +1 -1
- package/dist/constants/TimeoutConstants.js +3 -3
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/pageobjects/dashboard/Dashboard.js +5 -4
- package/dist/pageobjects/dashboard/Dashboard.js.map +1 -1
- package/dist/pageobjects/dashboard/Workspaces.js +4 -1
- package/dist/pageobjects/dashboard/Workspaces.js.map +1 -1
- package/dist/pageobjects/ide/CheCodeLocatorLoader.js +5 -0
- package/dist/pageobjects/ide/CheCodeLocatorLoader.js.map +1 -1
- package/dist/pageobjects/login/RedHatLoginPage.js +14 -15
- package/dist/pageobjects/login/RedHatLoginPage.js.map +1 -1
- package/dist/pageobjects/openshift/OcpApplicationPage.js +60 -0
- package/dist/pageobjects/openshift/OcpApplicationPage.js.map +1 -0
- package/dist/pageobjects/openshift/OcpImportFromGitPage.js +91 -0
- package/dist/pageobjects/openshift/OcpImportFromGitPage.js.map +1 -0
- package/dist/pageobjects/openshift/OcpLoginPage.js +3 -3
- package/dist/pageobjects/openshift/OcpLoginPage.js.map +1 -1
- package/dist/pageobjects/openshift/OcpMainPage.js +108 -0
- package/dist/pageobjects/openshift/OcpMainPage.js.map +1 -0
- package/dist/specs/api/CloneGitRepoAPI.spec.js +7 -7
- package/dist/specs/api/CloneGitRepoAPI.spec.js.map +1 -1
- package/dist/specs/api/ContainerOverridesAPI.spec.js +36 -0
- package/dist/specs/api/ContainerOverridesAPI.spec.js.map +1 -0
- package/dist/specs/api/PodOverridesAPI.spec.js +42 -0
- package/dist/specs/api/PodOverridesAPI.spec.js.map +1 -0
- package/dist/specs/dashboard-samples/RecomendedExtentions.spec.js +58 -19
- package/dist/specs/dashboard-samples/RecomendedExtentions.spec.js.map +1 -1
- package/dist/specs/devconsole-intergration/DevConsoleIntegration.spec.js +75 -0
- package/dist/specs/devconsole-intergration/DevConsoleIntegration.spec.js.map +1 -0
- package/dist/specs/factory/Factory.spec.js.map +1 -1
- package/dist/specs/factory/NoSetupRepoFactory.spec.js.map +1 -1
- package/dist/specs/factory/RefusedOAuthFactory.spec.js.map +1 -1
- package/dist/tests-library/LoginTests.js +19 -10
- package/dist/tests-library/LoginTests.js.map +1 -1
- package/dist/tests-library/ProjectAndFileTests.js +4 -0
- package/dist/tests-library/ProjectAndFileTests.js.map +1 -1
- package/dist/tests-library/WorkspaceHandlingTests.js +2 -2
- package/dist/tests-library/WorkspaceHandlingTests.js.map +1 -1
- package/dist/utils/BrowserTabsUtil.js +16 -1
- package/dist/utils/BrowserTabsUtil.js.map +1 -1
- package/dist/utils/CheReporter.js +6 -0
- package/dist/utils/CheReporter.js.map +1 -1
- package/dist/utils/DriverHelper.js +29 -3
- package/dist/utils/DriverHelper.js.map +1 -1
- package/dist/utils/KubernetesCommandLineToolsExecutor.js +162 -0
- package/dist/utils/KubernetesCommandLineToolsExecutor.js.map +1 -0
- package/dist/utils/ShellExecutor.js +15 -0
- package/dist/utils/ShellExecutor.js.map +1 -0
- package/index.ts +5 -1
- package/package.json +4 -3
- package/pageobjects/dashboard/Dashboard.ts +5 -4
- package/pageobjects/dashboard/Workspaces.ts +5 -2
- package/pageobjects/ide/CheCodeLocatorLoader.ts +5 -0
- package/pageobjects/login/RedHatLoginPage.ts +14 -16
- package/pageobjects/openshift/OcpApplicationPage.ts +42 -0
- package/pageobjects/openshift/OcpImportFromGitPage.ts +87 -0
- package/pageobjects/openshift/OcpLoginPage.ts +3 -3
- package/pageobjects/openshift/OcpMainPage.ts +109 -0
- package/resources/container-overrides.yaml +28 -0
- package/resources/pod-overrides.yaml +37 -0
- package/specs/api/CloneGitRepoAPI.spec.ts +8 -7
- package/specs/api/ContainerOverridesAPI.spec.ts +37 -0
- package/specs/api/PodOverridesAPI.spec.ts +43 -0
- package/specs/dashboard-samples/RecomendedExtentions.spec.ts +73 -21
- package/specs/devconsole-intergration/DevConsoleIntegration.spec.ts +98 -0
- package/specs/factory/Factory.spec.ts +1 -1
- package/specs/factory/NoSetupRepoFactory.spec.ts +1 -1
- package/specs/factory/RefusedOAuthFactory.spec.ts +1 -1
- package/tests-library/LoginTests.ts +17 -7
- package/tests-library/ProjectAndFileTests.ts +4 -0
- package/tests-library/WorkspaceHandlingTests.ts +2 -2
- package/utils/BrowserTabsUtil.ts +18 -3
- package/utils/CheReporter.ts +6 -0
- package/utils/DriverHelper.ts +36 -4
- package/utils/KubernetesCommandLineToolsExecutor.ts +167 -0
- package/utils/ShellExecutor.ts +13 -0
- package/dist/utils/OpenshiftClientExecutor.js +0 -98
- package/dist/utils/OpenshiftClientExecutor.js.map +0 -1
- package/utils/OpenshiftClientExecutor.ts +0 -117
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
kind: DevWorkspace
|
|
2
|
+
apiVersion: workspace.devfile.io/v1alpha2
|
|
3
|
+
metadata:
|
|
4
|
+
name: web-terminal-container-overrides
|
|
5
|
+
spec:
|
|
6
|
+
started: true
|
|
7
|
+
template:
|
|
8
|
+
attributes:
|
|
9
|
+
controller.devfile.io/storage-type: ephemeral
|
|
10
|
+
projects:
|
|
11
|
+
- name: web-nodejs-sample
|
|
12
|
+
git:
|
|
13
|
+
remotes:
|
|
14
|
+
origin: "https://github.com/che-samples/web-nodejs-sample.git"
|
|
15
|
+
components:
|
|
16
|
+
- name: web-terminal
|
|
17
|
+
attributes:
|
|
18
|
+
container-overrides: {"resources":{"limits":{"nvidia.com/gpu":"1"}}}
|
|
19
|
+
container:
|
|
20
|
+
image: quay.io/wto/web-terminal-tooling:next
|
|
21
|
+
args:
|
|
22
|
+
- tail
|
|
23
|
+
- '-f'
|
|
24
|
+
- /dev/null
|
|
25
|
+
cpuLimit: 400m
|
|
26
|
+
cpuRequest: 100m
|
|
27
|
+
memoryLimit: 256Mi
|
|
28
|
+
memoryRequest: 128Mi
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
kind: DevWorkspace
|
|
2
|
+
apiVersion: workspace.devfile.io/v1alpha2
|
|
3
|
+
metadata:
|
|
4
|
+
name: code-latest-pod-overrides
|
|
5
|
+
spec:
|
|
6
|
+
started: true
|
|
7
|
+
template:
|
|
8
|
+
attributes:
|
|
9
|
+
pod-overrides:
|
|
10
|
+
metadata:
|
|
11
|
+
annotations:
|
|
12
|
+
io.openshift.userns: "true"
|
|
13
|
+
io.kubernetes.cri-o.userns-mode: "auto:size=65536;map-to-root=true" # <-- user namespace
|
|
14
|
+
openshift.io/scc: container-build
|
|
15
|
+
spec:
|
|
16
|
+
runtimeClassName: kata
|
|
17
|
+
schedulerName: stork
|
|
18
|
+
projects:
|
|
19
|
+
- name: web-nodejs-sample
|
|
20
|
+
git:
|
|
21
|
+
remotes:
|
|
22
|
+
origin: "https://github.com/che-samples/web-nodejs-sample.git"
|
|
23
|
+
commands:
|
|
24
|
+
- id: say-hello
|
|
25
|
+
exec:
|
|
26
|
+
component: che-code-runtime-description
|
|
27
|
+
commandLine: echo "Hello from $(pwd)"
|
|
28
|
+
workingDir: ${PROJECT_SOURCE}/app
|
|
29
|
+
contributions:
|
|
30
|
+
- name: che-code
|
|
31
|
+
uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml
|
|
32
|
+
components:
|
|
33
|
+
- name: che-code-runtime-description
|
|
34
|
+
container:
|
|
35
|
+
env:
|
|
36
|
+
- name: CODE_HOST
|
|
37
|
+
value: 0.0.0.0
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor';
|
|
2
2
|
import { expect } from 'chai';
|
|
3
3
|
import { ShellString } from 'shelljs';
|
|
4
4
|
import { GitUtil } from '../../utils/vsc/GitUtil';
|
|
5
5
|
import { TestConstants } from '../../constants/TestConstants';
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
const gitRepository: string = 'https://github.com/crw-qe/web-nodejs-sample';
|
|
8
9
|
|
|
9
10
|
suite(`Test cloning of repo "${gitRepository}" into empty workspace.`, async function (): Promise<void> {
|
|
10
11
|
// works only for root user
|
|
11
|
-
const namespace: string =
|
|
12
|
+
const namespace: string = TestConstants.TS_API_TEST_NAMESPACE ? TestConstants.TS_API_TEST_NAMESPACE : undefined;
|
|
12
13
|
const workspaceName: string = 'empty-' + Math.floor(Math.random() * 1000);
|
|
13
14
|
const clonedProjectName: string = GitUtil.getProjectNameFromGitUrl(gitRepository);
|
|
14
15
|
let containerWorkDir: string = '';
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
-
const containerTerminal:
|
|
17
|
+
const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = new KubernetesCommandLineToolsExecutor(workspaceName, namespace);
|
|
18
|
+
const containerTerminal: KubernetesCommandLineToolsExecutor.ContainerTerminal = new KubernetesCommandLineToolsExecutor.ContainerTerminal(kubernetesCommandLineToolsExecutor);
|
|
18
19
|
|
|
19
20
|
const emptyYaml: string =
|
|
20
21
|
'apiVersion: workspace.devfile.io/v1alpha2\n' +
|
|
@@ -39,12 +40,12 @@ suite(`Test cloning of repo "${gitRepository}" into empty workspace.`, async fun
|
|
|
39
40
|
' value: 0.0.0.0';
|
|
40
41
|
|
|
41
42
|
suiteSetup('Create empty workspace with OC client', function (): void {
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
kubernetesCommandLineToolsExecutor.loginToOcp();
|
|
44
|
+
kubernetesCommandLineToolsExecutor.applyAndWaitDevWorkspace(emptyYaml);
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
suiteTeardown('Delete workspace', function (): void {
|
|
47
|
-
|
|
48
|
+
kubernetesCommandLineToolsExecutor.deleteDevWorkspace();
|
|
48
49
|
});
|
|
49
50
|
|
|
50
51
|
suite('Clone public repo without previous setup', function (): void {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import YAML from 'yaml';
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
|
|
7
|
+
suite(`Test defining container overrides via attribute.`, async function (): Promise<void> {
|
|
8
|
+
const pathToSampleFile: string = path.resolve('resources/container-overrides.yaml');
|
|
9
|
+
const workspaceName: string = YAML.parse(fs.readFileSync(pathToSampleFile, 'utf8')).metadata.name;
|
|
10
|
+
const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = new KubernetesCommandLineToolsExecutor(workspaceName);
|
|
11
|
+
|
|
12
|
+
suiteSetup('Login into OC client', function (): void {
|
|
13
|
+
kubernetesCommandLineToolsExecutor.loginToOcp();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
suiteTeardown('Delete DewWorkspace', function (): void {
|
|
17
|
+
kubernetesCommandLineToolsExecutor.deleteDevWorkspace();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('Apply container-overrides sample as DewWorkspace with OC client', function (): void {
|
|
21
|
+
kubernetesCommandLineToolsExecutor.applyYamlConfigurationAsFile(pathToSampleFile);
|
|
22
|
+
kubernetesCommandLineToolsExecutor.wait(5);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('Check that fields are overridden in the Deployment for DewWorkspace', function (): void {
|
|
26
|
+
const devWorkspaceFullYamlOutput: any = YAML.parse(kubernetesCommandLineToolsExecutor.getDevWorkspaceYamlConfiguration());
|
|
27
|
+
expect(devWorkspaceFullYamlOutput.spec.template.components[0].attributes['container-overrides']).eqls({
|
|
28
|
+
resources: {
|
|
29
|
+
limits: {
|
|
30
|
+
'nvidia.com/gpu': '1'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { KubernetesCommandLineToolsExecutor } from '../../utils/KubernetesCommandLineToolsExecutor';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import YAML from 'yaml';
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
|
|
7
|
+
suite(`Test defining pod overrides via attribute.`, async function (): Promise<void> {
|
|
8
|
+
const pathToSampleFile: string = path.resolve('resources/pod-overrides.yaml');
|
|
9
|
+
const workspaceName: string = YAML.parse(fs.readFileSync(pathToSampleFile, 'utf8')).metadata.name;
|
|
10
|
+
const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = new KubernetesCommandLineToolsExecutor(workspaceName);
|
|
11
|
+
|
|
12
|
+
suiteSetup('Login into OC client', function (): void {
|
|
13
|
+
kubernetesCommandLineToolsExecutor.loginToOcp();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
suiteTeardown('Delete DewWorkspace', function (): void {
|
|
17
|
+
kubernetesCommandLineToolsExecutor.deleteDevWorkspace();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('Apply pod-overrides sample as DewWorkspace with OC client', function (): void {
|
|
21
|
+
kubernetesCommandLineToolsExecutor.applyYamlConfigurationAsFile(pathToSampleFile);
|
|
22
|
+
kubernetesCommandLineToolsExecutor.wait(5);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('Check that fields are overridden in the Deployment for DewWorkspace', function (): void {
|
|
26
|
+
const devWorkspaceFullYamlOutput: any = YAML.parse(kubernetesCommandLineToolsExecutor.getDevWorkspaceYamlConfiguration());
|
|
27
|
+
expect(devWorkspaceFullYamlOutput.spec.template.attributes['pod-overrides']).eqls({
|
|
28
|
+
metadata: {
|
|
29
|
+
annotations: {
|
|
30
|
+
'io.kubernetes.cri-o.userns-mode': 'auto:size=65536;map-to-root=true',
|
|
31
|
+
'io.openshift.userns': 'true',
|
|
32
|
+
'openshift.io/scc': 'container-build'
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
spec: {
|
|
36
|
+
runtimeClassName: 'kata',
|
|
37
|
+
schedulerName: 'stork'
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
|
|
@@ -34,6 +34,7 @@ import { CheCodeLocatorLoader } from '../../pageobjects/ide/CheCodeLocatorLoader
|
|
|
34
34
|
import { expect } from 'chai';
|
|
35
35
|
import { TimeoutConstants } from '../../constants/TimeoutConstants';
|
|
36
36
|
import { TestConstants } from '../../constants/TestConstants';
|
|
37
|
+
import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil';
|
|
37
38
|
|
|
38
39
|
const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests);
|
|
39
40
|
const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
|
|
@@ -41,7 +42,8 @@ const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
|
|
|
41
42
|
const driverHelper: DriverHelper = e2eContainer.get(CLASSES.DriverHelper);
|
|
42
43
|
|
|
43
44
|
const webCheCodeLocators: Locators = new CheCodeLocatorLoader().webCheCodeLocators;
|
|
44
|
-
const samples:
|
|
45
|
+
const samples: string[] = TestConstants.TS_SAMPLE_LIST.split(',');
|
|
46
|
+
const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil);
|
|
45
47
|
|
|
46
48
|
suite(`Check if recommended extensions installed for ${samples}`, async function (): Promise<void> {
|
|
47
49
|
let projectSection: ViewSection;
|
|
@@ -80,7 +82,7 @@ suite(`Check if recommended extensions installed for ${samples}`, async function
|
|
|
80
82
|
Logger.debug(`trustedProjectDialog.pushButton: "${buttonYesITrustTheAuthors}"`);
|
|
81
83
|
await trustedProjectDialog.pushButton(buttonYesITrustTheAuthors);
|
|
82
84
|
} catch (e) {
|
|
83
|
-
Logger.
|
|
85
|
+
Logger.debug(`Welcome modal dialog was not shown: ${e}`);
|
|
84
86
|
}
|
|
85
87
|
});
|
|
86
88
|
|
|
@@ -96,51 +98,101 @@ suite(`Check if recommended extensions installed for ${samples}`, async function
|
|
|
96
98
|
Logger.debug(`editor.getText(): get recommended extensions as text from editor, delete comments and parse to object.`);
|
|
97
99
|
recommendedExtensions = JSON.parse((await editor.getText()).replace(/\/\*[\s\S]*?\*\/|(?<=[^:])\/\/.*|^\/\/.*/g, '').trim());
|
|
98
100
|
Logger.debug(`recommendedExtensions.recommendations: Get recommendations clear names using map().`);
|
|
99
|
-
recommendedExtensions.recommendations = recommendedExtensions.recommendations.map((r:
|
|
101
|
+
recommendedExtensions.recommendations = recommendedExtensions.recommendations.map((r: { split: (arg: string) => [any, any]; }) => {
|
|
102
|
+
const [publisher, name] = r.split('.');
|
|
103
|
+
return {publisher, name};
|
|
104
|
+
});
|
|
105
|
+
Logger.info(`Recommended extension for this workspace:\n${JSON.stringify(recommendedExtensions.recommendations)}.`);
|
|
100
106
|
});
|
|
101
107
|
|
|
102
108
|
test(`Open "Extensions" view section`, async function (): Promise<void> {
|
|
103
109
|
Logger.debug(`ActivityBar().getViewControl('Extensions'))?.openView(): open Extensions view.`);
|
|
104
110
|
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
|
|
105
|
-
Logger.debug(`extensionsView?.getContent().getSections(): get current section.`);
|
|
106
|
-
[extensionSection] = await extensionsView?.getContent().getSections() as ExtensionsViewSection[];
|
|
107
111
|
});
|
|
108
112
|
|
|
109
|
-
test(`
|
|
113
|
+
test(`Let extensions complete installation`, async function (): Promise<void> {
|
|
110
114
|
Logger.info(`Time for extensions installation TimeoutConstants.TS_COMMON_PLUGIN_TEST_TIMEOUT=${TimeoutConstants.TS_COMMON_PLUGIN_TEST_TIMEOUT}`);
|
|
111
115
|
await driverHelper.wait(TimeoutConstants.TS_COMMON_PLUGIN_TEST_TIMEOUT);
|
|
112
116
|
});
|
|
113
117
|
|
|
114
118
|
test(`Check if extensions is installed and enabled`, async function (): Promise<void> {
|
|
115
|
-
|
|
119
|
+
this.retries(10);
|
|
120
|
+
Logger.debug(`ActivityBar().getViewControl('Extensions'))?.openView(): open Extensions view.`);
|
|
121
|
+
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
|
|
122
|
+
|
|
123
|
+
Logger.debug(`extensionsView?.getContent().getSections(): get current section.`);
|
|
124
|
+
[extensionSection] = await extensionsView?.getContent().getSections() as ExtensionsViewSection[];
|
|
125
|
+
await driverHelper.waitAllPresence(webCheCodeLocators.ExtensionsViewSection.itemTitle, TimeoutConstants.TS_EDITOR_TAB_INTERACTION_TIMEOUT);
|
|
126
|
+
|
|
116
127
|
for (const extension of recommendedExtensions.recommendations) {
|
|
117
|
-
Logger.
|
|
118
|
-
|
|
128
|
+
Logger.info(`Check if ${JSON.stringify(extension)} are installed.`);
|
|
129
|
+
|
|
130
|
+
Logger.debug(`extensionSection.findItem(${extension.name}).`);
|
|
131
|
+
await extensionSection.findItem(extension.name);
|
|
132
|
+
|
|
133
|
+
// check if extension require reload the page
|
|
134
|
+
if (await driverHelper.isVisible((webCheCodeLocators.ExtensionsViewSection as any).requireReloadButton)) {
|
|
135
|
+
Logger.debug(`Extension require reload the editor. Refreshing the page..`);
|
|
136
|
+
await browserTabsUtil.refreshPage();
|
|
137
|
+
await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
|
|
138
|
+
Logger.debug(`ActivityBar().getViewControl('Extensions'))?.openView(): open Extensions view.`);
|
|
139
|
+
extensionsView = await (await new ActivityBar().getViewControl('Extensions'))?.openView();
|
|
140
|
+
Logger.debug(`extensionsView?.getContent().getSections(): get current section.`);
|
|
141
|
+
[extensionSection] = await extensionsView?.getContent().getSections() as ExtensionsViewSection[];
|
|
142
|
+
await driverHelper.waitAllPresence(webCheCodeLocators.ExtensionsViewSection.itemTitle, TimeoutConstants.TS_EDITOR_TAB_INTERACTION_TIMEOUT);
|
|
143
|
+
Logger.debug(`extensionSection.findItem(${extension.name}).`);
|
|
144
|
+
await extensionSection.findItem(extension.name);
|
|
145
|
+
}
|
|
146
|
+
|
|
119
147
|
Logger.debug(`extensionsView?.getContent().getSections(): switch to marketplace section.`);
|
|
120
148
|
const [marketplaceSection]: ExtensionsViewSection[] = await extensionsView?.getContent().getSections() as ExtensionsViewSection[];
|
|
121
|
-
await driverHelper.waitVisibility(webCheCodeLocators.ExtensionsViewSection.items, TimeoutConstants.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
await driverHelper.waitVisibility(webCheCodeLocators.ExtensionsViewSection.items, TimeoutConstants.TS_EDITOR_TAB_INTERACTION_TIMEOUT);
|
|
150
|
+
|
|
151
|
+
Logger.debug(`marketplaceSection.getVisibleItems(): get all found items.`);
|
|
152
|
+
const allFinedItems: ExtensionsViewItem[] = await marketplaceSection.getVisibleItems();
|
|
153
|
+
|
|
154
|
+
let itemWithRightNameAndPublisher: ExtensionsViewItem | undefined;
|
|
155
|
+
for (const item of allFinedItems) {
|
|
156
|
+
Logger.debug(`Try to find extension published by ${extension.publisher}.`);
|
|
157
|
+
if (await item.getAuthor() === extension.publisher) {
|
|
158
|
+
itemWithRightNameAndPublisher = item;
|
|
159
|
+
Logger.debug(`Extension was found: ${await itemWithRightNameAndPublisher?.getTitle()}`);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
if (itemWithRightNameAndPublisher === undefined) {
|
|
163
|
+
Logger.error(`Extension with publisher as ${extension.publisher} was not found.`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Logger.debug(`itemWithRightNameAndPublisher?.isInstalled()`);
|
|
168
|
+
const isInstalled: boolean = await itemWithRightNameAndPublisher?.isInstalled() as boolean;
|
|
169
|
+
|
|
170
|
+
Logger.debug(`itemWithRightNameAndPublisher?.isInstalled(): ${isInstalled}.`);
|
|
127
171
|
expect(isInstalled).eqls(true);
|
|
128
|
-
|
|
129
|
-
|
|
172
|
+
|
|
173
|
+
Logger.debug(`itemWithRightNameAndPublisher.manage(): get context menu.`);
|
|
174
|
+
const extensionManageMenu: ContextMenu | undefined = await itemWithRightNameAndPublisher?.manage();
|
|
175
|
+
|
|
130
176
|
Logger.debug(`extensionManageMenu.getItems(): get menu items.`);
|
|
131
|
-
const extensionMenuItems: ContextMenuItem[] = await extensionManageMenu
|
|
177
|
+
const extensionMenuItems: ContextMenuItem[] | undefined = await extensionManageMenu?.getItems();
|
|
132
178
|
let extensionMenuItemLabels: string = '';
|
|
133
|
-
for (const item of extensionMenuItems) {
|
|
179
|
+
for (const item of extensionMenuItems as ContextMenuItem[]) {
|
|
134
180
|
Logger.trace(`extensionMenuItems -> item.getLabel(): get menu items names.`);
|
|
135
181
|
extensionMenuItemLabels += (await item.getLabel()) + ' ';
|
|
136
182
|
}
|
|
183
|
+
|
|
137
184
|
Logger.debug(`extensionMenuItemLabels: ${extensionMenuItemLabels}.`);
|
|
138
185
|
expect(extensionMenuItemLabels).contains('Disable').and.not.contains('Enable');
|
|
139
186
|
}
|
|
140
187
|
});
|
|
141
188
|
|
|
142
|
-
test('
|
|
143
|
-
await workspaceHandlingTests.
|
|
189
|
+
test('Stop the workspace', async function (): Promise<void> {
|
|
190
|
+
await workspaceHandlingTests.stopWorkspace(WorkspaceHandlingTests.getWorkspaceName());
|
|
191
|
+
await browserTabsUtil.closeAllTabsExceptCurrent();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('Delete the workspace', async function (): Promise<void> {
|
|
195
|
+
await workspaceHandlingTests.removeWorkspace(WorkspaceHandlingTests.getWorkspaceName());
|
|
144
196
|
});
|
|
145
197
|
}
|
|
146
198
|
|
|
@@ -0,0 +1,98 @@
|
|
|
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 and Developer role on DevConsole', async function (): Promise<void> {
|
|
54
|
+
await ocpMainPage.selectDeveloperRole();
|
|
55
|
+
await ocpMainPage.selectProject(projectName);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('Open import from git project page', async function (): Promise<void> {
|
|
59
|
+
ocpImportPage = await ocpMainPage.openImportFromGitPage();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('Fill and submit import data', async function (): Promise<void> {
|
|
63
|
+
ocpApplicationPage = await ocpImportPage.fitAndSubmitConfiguration(gitImportRepo, gitImportReference, projectLabel);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('Wait until application creates', async function (): Promise<void> {
|
|
67
|
+
await ocpApplicationPage.waitApplicationIcon();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('Check if application has worked link "Open Source Code"', async function (): Promise<void> {
|
|
71
|
+
await ocpApplicationPage.waitAndOpenEditSourceCodeIcon();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
loginTests.loginIntoChe();
|
|
75
|
+
|
|
76
|
+
workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
|
|
77
|
+
|
|
78
|
+
test('Registering the running workspace', async function (): Promise<void> {
|
|
79
|
+
registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName());
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('Check if application source code opens in workspace', async function (): Promise<void> {
|
|
83
|
+
await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('Check if project and files imported', async function (): Promise<void> {
|
|
87
|
+
const applicationSourceProjectName: string = GitUtil.getProjectNameFromGitUrl(gitImportRepo);
|
|
88
|
+
const projectSection: ViewSection = await new SideBarView().getContent().getSection(applicationSourceProjectName);
|
|
89
|
+
const isFileImported: ViewItem | undefined = await projectSection.findItem(TestConstants.TS_SELENIUM_PROJECT_ROOT_FILE_NAME);
|
|
90
|
+
expect(isFileImported).not.eqls(undefined);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
loginTests.logoutFromChe();
|
|
94
|
+
|
|
95
|
+
suiteTeardown('Delete project using ocp', async function (): Promise<void> {
|
|
96
|
+
kubernetesCommandLineToolsExecutor.deleteProject(projectName);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
30
|
-
|
|
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
|
|
|
@@ -23,8 +23,12 @@ export class ProjectAndFileTests {
|
|
|
23
23
|
@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
|
|
24
24
|
|
|
25
25
|
public async waitWorkspaceReadinessForCheCodeEditor(): Promise<void> {
|
|
26
|
+
Logger.debug(`${this.constructor.name}.${this.waitWorkspaceReadinessForCheCodeEditor.name} - Waiting for editor.`);
|
|
26
27
|
try {
|
|
28
|
+
const start: number = new Date().getTime();
|
|
27
29
|
await this.driverHelper.getDriver().wait(until.elementLocated(By.className('monaco-workbench')), TimeoutConstants.TS_SELENIUM_START_WORKSPACE_TIMEOUT);
|
|
30
|
+
const end: number = new Date().getTime();
|
|
31
|
+
Logger.debug(`${this.constructor.name}.${this.waitWorkspaceReadinessForCheCodeEditor.name} - editor was opened in ${end - start} seconds.`);
|
|
28
32
|
} catch (err) {
|
|
29
33
|
Logger.error(`ProjectAndFileTestsCheCode.waitWorkspaceReadinessForCheCodeEditor - waiting for workspace readiness failed: ${err}`);
|
|
30
34
|
throw err;
|
|
@@ -103,12 +103,12 @@ export class WorkspaceHandlingTests {
|
|
|
103
103
|
break;
|
|
104
104
|
} catch (err) {
|
|
105
105
|
if (err instanceof error.StaleElementReferenceError) {
|
|
106
|
-
Logger.
|
|
106
|
+
Logger.trace(`WorkspaceHandlingTests.obtainWorkspaceNameFromStartingPage Failed to obtain name from workspace start page, element possibly detached from DOM. Retrying.`);
|
|
107
107
|
await this.driverHelper.wait(polling);
|
|
108
108
|
continue;
|
|
109
109
|
}
|
|
110
110
|
if (err instanceof error.NoSuchElementError) {
|
|
111
|
-
Logger.
|
|
111
|
+
Logger.trace(`WorkspaceHandlingTests.obtainWorkspaceNameFromStartingPage Failed to obtain name from workspace start page, element not visible yet. Retrying.`);
|
|
112
112
|
await this.driverHelper.wait(polling);
|
|
113
113
|
continue;
|
|
114
114
|
}
|
package/utils/BrowserTabsUtil.ts
CHANGED
|
@@ -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 {
|
|
@@ -89,10 +90,24 @@ export class BrowserTabsUtil {
|
|
|
89
90
|
}, timeout);
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
|
|
93
|
+
async maximize(): Promise<void> {
|
|
93
94
|
Logger.trace(`BrowserTabsUtil.maximize`);
|
|
94
|
-
|
|
95
|
-
|
|
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
100
|
|
|
101
|
+
async closeAllTabsExceptCurrent(): Promise<void> {
|
|
102
|
+
Logger.trace(`${this.constructor.name}.${this.closeAllTabsExceptCurrent.name}`);
|
|
103
|
+
const allTabsHandles: string[] = await this.getAllWindowHandles();
|
|
104
|
+
const currentTabHandle: string = await this.getCurrentWindowHandle();
|
|
105
|
+
allTabsHandles.splice(allTabsHandles.indexOf(currentTabHandle), 1);
|
|
106
|
+
|
|
107
|
+
for (const tabHandle of allTabsHandles) {
|
|
108
|
+
await this.switchToWindow(tabHandle);
|
|
109
|
+
await this.driverHelper.getDriver().close();
|
|
110
|
+
}
|
|
111
|
+
await this.switchToWindow(currentTabHandle);
|
|
112
|
+
}
|
|
98
113
|
}
|
package/utils/CheReporter.ts
CHANGED
|
@@ -55,6 +55,12 @@ class CheReporter extends mocha.reporters.Spec {
|
|
|
55
55
|
TS_SELENIUM_LOG_LEVEL: ${TestConstants.TS_SELENIUM_LOG_LEVEL}
|
|
56
56
|
TS_SELENIUM_LAUNCH_FULLSCREEN: ${TestConstants.TS_SELENIUM_LAUNCH_FULLSCREEN}
|
|
57
57
|
|
|
58
|
+
TS_COMMON_DASHBOARD_WAIT_TIMEOUT: ${TimeoutConstants.TS_COMMON_DASHBOARD_WAIT_TIMEOUT}
|
|
59
|
+
TS_SELENIUM_START_WORKSPACE_TIMEOUT: ${TimeoutConstants.TS_SELENIUM_START_WORKSPACE_TIMEOUT}
|
|
60
|
+
TS_WAIT_LOADER_PRESENCE_TIMEOUT: ${TimeoutConstants.TS_WAIT_LOADER_PRESENCE_TIMEOUT}
|
|
61
|
+
|
|
62
|
+
TS_SAMPLE_LIST: ${TestConstants.TS_SAMPLE_LIST}
|
|
63
|
+
|
|
58
64
|
${process.env.MOCHA_DIRECTORY ? 'MOCHA_DIRECTORY: ' + process.env.MOCHA_DIRECTORY : 'MOCHA_DRIRECTORY is not set'}
|
|
59
65
|
${process.env.USERSTORY ? 'USERSTORY: ' + process.env.USERSTORY : 'USERSTORY is not set'}
|
|
60
66
|
`;
|