@eclipse-che/che-e2e 7.68.0-dev-52d73d3 → 7.68.0-dev-8aa6599
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/constants/DevfilesRegistryConstants.ts +26 -0
- package/constants/TestConstants.ts +4 -1
- package/dist/constants/DevfilesRegistryConstants.js +32 -0
- package/dist/constants/DevfilesRegistryConstants.js.map +1 -0
- package/dist/constants/TestConstants.js +3 -1
- package/dist/constants/TestConstants.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/specs/api/CloneGitRepoAPI.spec.js +2 -1
- package/dist/specs/api/CloneGitRepoAPI.spec.js.map +1 -1
- package/dist/specs/api/ContainerOverridesAPI.spec.js +5 -4
- package/dist/specs/api/ContainerOverridesAPI.spec.js.map +1 -1
- package/dist/specs/api/DevfileAcceptanceTestAPI.spec.js +41 -0
- package/dist/specs/api/DevfileAcceptanceTestAPI.spec.js.map +1 -0
- package/dist/specs/api/PodOverridesAPI.spec.js +5 -4
- package/dist/specs/api/PodOverridesAPI.spec.js.map +1 -1
- package/dist/specs/dashboard-samples/RecomendedExtentions.spec.js +3 -3
- package/dist/specs/dashboard-samples/RecomendedExtentions.spec.js.map +1 -1
- package/dist/specs/factory/Factory.spec.js +3 -2
- package/dist/specs/factory/Factory.spec.js.map +1 -1
- package/dist/specs/factory/NoSetupRepoFactory.spec.js +3 -2
- package/dist/specs/factory/NoSetupRepoFactory.spec.js.map +1 -1
- package/dist/specs/factory/RefusedOAuthFactory.spec.js +3 -2
- package/dist/specs/factory/RefusedOAuthFactory.spec.js.map +1 -1
- package/dist/tests-library/LoginTests.js.map +1 -1
- package/dist/tests-library/ProjectAndFileTests.js.map +1 -1
- package/dist/tests-library/WorkspaceHandlingTests.js.map +1 -1
- package/dist/utils/DevWorkspaceConfigurationHelper.js +52 -0
- package/dist/utils/DevWorkspaceConfigurationHelper.js.map +1 -0
- package/dist/utils/DriverHelper.js +4 -0
- package/dist/utils/DriverHelper.js.map +1 -1
- package/dist/utils/KubernetesCommandLineToolsExecutor.js +14 -14
- package/dist/utils/KubernetesCommandLineToolsExecutor.js.map +1 -1
- package/dist/utils/Logger.js.map +1 -1
- package/dist/utils/Sanitizer.js.map +1 -1
- package/dist/utils/ShellExecutor.js +5 -2
- package/dist/utils/ShellExecutor.js.map +1 -1
- package/dist/utils/request-handlers/CheApiRequestHandler.js.map +1 -1
- package/dist/utils/vsc/GitUtil.js +22 -1
- package/dist/utils/vsc/GitUtil.js.map +1 -1
- package/dist/utils/workspace/ApiUrlResolver.js.map +1 -1
- package/dist/utils/workspace/TestWorkspaceUtil.js.map +1 -1
- package/index.ts +1 -0
- package/package.json +2 -1
- package/specs/api/CloneGitRepoAPI.spec.ts +2 -1
- package/specs/api/ContainerOverridesAPI.spec.ts +5 -4
- package/specs/api/DevfileAcceptanceTestAPI.spec.ts +50 -0
- package/specs/api/PodOverridesAPI.spec.ts +5 -4
- package/specs/dashboard-samples/RecomendedExtentions.spec.ts +4 -4
- package/specs/factory/Factory.spec.ts +3 -2
- package/specs/factory/NoSetupRepoFactory.spec.ts +3 -2
- package/specs/factory/RefusedOAuthFactory.spec.ts +3 -2
- package/tests-library/LoginTests.ts +3 -3
- package/tests-library/ProjectAndFileTests.ts +1 -1
- package/tests-library/WorkspaceHandlingTests.ts +10 -10
- package/utils/DevWorkspaceConfigurationHelper.ts +57 -0
- package/utils/DriverHelper.ts +34 -29
- package/utils/KubernetesCommandLineToolsExecutor.ts +15 -15
- package/utils/Logger.ts +5 -5
- package/utils/Sanitizer.ts +1 -1
- package/utils/ShellExecutor.ts +6 -2
- package/utils/request-handlers/CheApiRequestHandler.ts +2 -2
- package/utils/vsc/GitUtil.ts +19 -1
- package/utils/workspace/ApiUrlResolver.ts +2 -2
- package/utils/workspace/TestWorkspaceUtil.ts +7 -7
|
@@ -62,7 +62,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
62
62
|
const commitChangesButtonLabel: string = `Commit Changes on "${TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}"`;
|
|
63
63
|
const refreshButtonLabel: string = 'Refresh';
|
|
64
64
|
const pushItemLabel: string = 'Push';
|
|
65
|
-
|
|
65
|
+
let testRepoProjectName: string;
|
|
66
66
|
|
|
67
67
|
loginTests.loginIntoChe();
|
|
68
68
|
test(`Navigate to the factory URL`, async function (): Promise<void> {
|
|
@@ -88,6 +88,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
test('Check if a project folder has been created', async function (): Promise<void> {
|
|
91
|
+
testRepoProjectName = GitUtil.getProjectNameFromGitUrl(TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_URL);
|
|
91
92
|
Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
|
|
92
93
|
projectSection = await new SideBarView().getContent().getSection(testRepoProjectName);
|
|
93
94
|
});
|
|
@@ -129,7 +130,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
129
130
|
Logger.debug(`scmView.getProviders: "${scmProvider}, ${scmProvider}"`);
|
|
130
131
|
});
|
|
131
132
|
|
|
132
|
-
test('Check if the changes
|
|
133
|
+
test('Check if the changes are displayed in the source control manager', async function (): Promise<void> {
|
|
133
134
|
await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
|
|
134
135
|
await driverHelper.wait(timeToRefresh);
|
|
135
136
|
Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
|
|
@@ -68,7 +68,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
68
68
|
const commitChangesButtonLabel: string = `Commit Changes on "${TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_BRANCH}"`;
|
|
69
69
|
const refreshButtonLabel: string = 'Refresh';
|
|
70
70
|
const label: string = TestConstants.TS_SELENIUM_PROJECT_ROOT_FILE_NAME;
|
|
71
|
-
|
|
71
|
+
let testRepoProjectName: string;
|
|
72
72
|
const isPrivateRepo: string = TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO ? 'private' : 'public';
|
|
73
73
|
|
|
74
74
|
loginTests.loginIntoChe();
|
|
@@ -114,6 +114,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
test('Check if a project folder has been created', async function (): Promise<void> {
|
|
117
|
+
testRepoProjectName = GitUtil.getProjectNameFromGitUrl(TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_URL);
|
|
117
118
|
Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
|
|
118
119
|
projectSection = await new SideBarView().getContent().getSection(testRepoProjectName);
|
|
119
120
|
});
|
|
@@ -170,7 +171,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
170
171
|
Logger.debug(`scmView.getProviders: "${scmProvider}, ${scmProvider}"`);
|
|
171
172
|
});
|
|
172
173
|
|
|
173
|
-
test('Check if the changes
|
|
174
|
+
test('Check if the changes are displayed in the source control manager', async function (): Promise<void> {
|
|
174
175
|
await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
|
|
175
176
|
await driverHelper.wait(timeToRefresh);
|
|
176
177
|
Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
|
|
@@ -65,7 +65,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
65
65
|
const refreshButtonLabel: string = 'Refresh';
|
|
66
66
|
const pushItemLabel: string = 'Push';
|
|
67
67
|
const label: string = TestConstants.TS_SELENIUM_PROJECT_ROOT_FILE_NAME;
|
|
68
|
-
|
|
68
|
+
let testRepoProjectName: string;
|
|
69
69
|
const isPrivateRepo: string = TestConstants.TS_SELENIUM_IS_PRIVATE_FACTORY_GIT_REPO ? 'private' : 'public';
|
|
70
70
|
|
|
71
71
|
loginTests.loginIntoChe();
|
|
@@ -97,6 +97,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
test('Check if a project folder has been created', async function (): Promise<void> {
|
|
100
|
+
testRepoProjectName = GitUtil.getProjectNameFromGitUrl(TestConstants.TS_SELENIUM_FACTORY_GIT_REPO_URL);
|
|
100
101
|
Logger.debug(`new SideBarView().getContent().getSection: get ${testRepoProjectName}`);
|
|
101
102
|
projectSection = await new SideBarView().getContent().getSection(testRepoProjectName);
|
|
102
103
|
});
|
|
@@ -167,7 +168,7 @@ suite(`Create a workspace via launching a factory from the ${TestConstants.TS_SE
|
|
|
167
168
|
Logger.debug(`scmView.getProviders: "${scmProvider}, ${scmProvider}"`);
|
|
168
169
|
});
|
|
169
170
|
|
|
170
|
-
test('Check if the changes
|
|
171
|
+
test('Check if the changes are displayed in the source control manager', async function (): Promise<void> {
|
|
171
172
|
await driverHelper.waitVisibility(webCheCodeLocators.ScmView.more);
|
|
172
173
|
await driverHelper.wait(timeToRefresh);
|
|
173
174
|
Logger.debug(`scmProvider.takeAction: "${refreshButtonLabel}"`);
|
|
@@ -25,7 +25,7 @@ export class LoginTests {
|
|
|
25
25
|
@inject(CLASSES.Dashboard) private readonly dashboard: Dashboard) {
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
loginIntoChe(): void {
|
|
29
29
|
test('Login', async () => {
|
|
30
30
|
if (!(await this.browserTabsUtil.getCurrentUrl()).includes(TestConstants.TS_SELENIUM_BASE_URL)) {
|
|
31
31
|
await this.browserTabsUtil.navigateTo(TestConstants.TS_SELENIUM_BASE_URL);
|
|
@@ -36,7 +36,7 @@ export class LoginTests {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
loginIntoOcpConsole(): void {
|
|
40
40
|
test('Login into ocp console', async () => {
|
|
41
41
|
const openshiftConsoleUrl: string = TestConstants.TS_SELENIUM_BASE_URL.replace('devspaces', 'console-openshift-console');
|
|
42
42
|
await this.browserTabsUtil.navigateTo(openshiftConsoleUrl);
|
|
@@ -45,7 +45,7 @@ export class LoginTests {
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
logoutFromChe(): void {
|
|
49
49
|
test('Logout', async () => {
|
|
50
50
|
await this.dashboard.logout();
|
|
51
51
|
});
|
|
@@ -22,7 +22,7 @@ export class ProjectAndFileTests {
|
|
|
22
22
|
constructor(
|
|
23
23
|
@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
async waitWorkspaceReadinessForCheCodeEditor(): Promise<void> {
|
|
26
26
|
Logger.debug(`${this.constructor.name}.${this.waitWorkspaceReadinessForCheCodeEditor.name} - Waiting for editor.`);
|
|
27
27
|
try {
|
|
28
28
|
const start: number = new Date().getTime();
|
|
@@ -25,7 +25,7 @@ import { TestConstants } from '../constants/TestConstants';
|
|
|
25
25
|
@injectable()
|
|
26
26
|
export class WorkspaceHandlingTests {
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
static getWorkspaceName(): string {
|
|
29
29
|
return WorkspaceHandlingTests.workspaceName;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -41,15 +41,15 @@ export class WorkspaceHandlingTests {
|
|
|
41
41
|
@inject(CLASSES.ApiUrlResolver) private readonly apiUrlResolver: ApiUrlResolver,
|
|
42
42
|
@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
setWindowHandle(guid: string): void {
|
|
45
45
|
WorkspaceHandlingTests.parentGUID = guid;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
getWindowHandle(): string {
|
|
49
49
|
return WorkspaceHandlingTests.parentGUID;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
createAndOpenWorkspace(stack: string): void {
|
|
53
53
|
test(`Create and open new workspace, stack:${stack}`, async () => {
|
|
54
54
|
await this.dashboard.clickWorkspacesButton();
|
|
55
55
|
await this.dashboard.waitPage();
|
|
@@ -63,7 +63,7 @@ export class WorkspaceHandlingTests {
|
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
createAndOpenWorkspaceFromGitRepository(factoryUrl: string): void {
|
|
67
67
|
test(`Create and open new workspace from factory:${factoryUrl}`, async () => {
|
|
68
68
|
await this.dashboard.waitPage();
|
|
69
69
|
Logger.debug(`Fetching user kubernetes namespace, storing auth token by getting workspaces API URL.`);
|
|
@@ -76,7 +76,7 @@ export class WorkspaceHandlingTests {
|
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
openExistingWorkspace(workspaceName: string): void {
|
|
80
80
|
test('Open and start existing workspace', async () => {
|
|
81
81
|
await this.dashboard.waitPage();
|
|
82
82
|
Logger.debug(`Fetching user kubernetes namespace, storing auth token by getting workspaces API URL.`);
|
|
@@ -87,7 +87,7 @@ export class WorkspaceHandlingTests {
|
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
obtainWorkspaceNameFromStartingPage(): void {
|
|
91
91
|
test('Obtain workspace name from workspace loader page', async() => {
|
|
92
92
|
const timeout: number = TimeoutConstants.TS_IDE_LOAD_TIMEOUT;
|
|
93
93
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
@@ -125,17 +125,17 @@ export class WorkspaceHandlingTests {
|
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
async stopWorkspace(workspaceName: string): Promise<void> {
|
|
129
129
|
await this.dashboard.openDashboard();
|
|
130
130
|
await this.dashboard.stopWorkspaceByUI(workspaceName);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
async removeWorkspace(workspaceName: string): Promise<void> {
|
|
134
134
|
await this.dashboard.openDashboard();
|
|
135
135
|
await this.dashboard.deleteStoppedWorkspaceByUI(workspaceName);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
async stopAndRemoveWorkspace(workspaceName: string): Promise<void> {
|
|
139
139
|
await this.dashboard.openDashboard();
|
|
140
140
|
await this.dashboard.stopAndRemoveWorkspaceByUI(workspaceName);
|
|
141
141
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Main as Generator } from '@eclipse-che/che-devworkspace-generator/lib/main';
|
|
2
|
+
import { DevfileContext } from '@eclipse-che/che-devworkspace-generator/lib/api/devfile-context';
|
|
3
|
+
import { V1alpha2DevWorkspaceTemplate } from '@devfile/api';
|
|
4
|
+
import YAML from 'yaml';
|
|
5
|
+
import * as axios from 'axios';
|
|
6
|
+
import { Logger } from './Logger';
|
|
7
|
+
|
|
8
|
+
interface IContextParams {
|
|
9
|
+
devfilePath?: string | undefined;
|
|
10
|
+
devfileUrl?: string | undefined;
|
|
11
|
+
devfileContent?: string | undefined;
|
|
12
|
+
outputFile?: string | undefined;
|
|
13
|
+
editorPath?: string | undefined;
|
|
14
|
+
editorContent?: string | undefined;
|
|
15
|
+
editorEntry?: string | undefined;
|
|
16
|
+
pluginRegistryUrl?: string | undefined;
|
|
17
|
+
projects: {
|
|
18
|
+
name: string;
|
|
19
|
+
location: string;
|
|
20
|
+
}[];
|
|
21
|
+
injectDefaultComponent?: string | undefined;
|
|
22
|
+
defaultComponentImage?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class DevWorkspaceConfigurationHelper {
|
|
26
|
+
private generator: Generator = new Generator();
|
|
27
|
+
private readonly params: IContextParams;
|
|
28
|
+
|
|
29
|
+
constructor(params: IContextParams) {
|
|
30
|
+
// check if all undefined
|
|
31
|
+
if (!(params.editorPath || params.editorEntry || params.editorContent)) {
|
|
32
|
+
params.editorEntry = 'che-incubator/che-code/latest';
|
|
33
|
+
}
|
|
34
|
+
this.params = params;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async generateDevfileContext(): Promise<DevfileContext> {
|
|
38
|
+
Logger.debug(`${this.constructor.name}.${this.generateDevfileContext.name}`);
|
|
39
|
+
return await this.generator.generateDevfileContext(
|
|
40
|
+
{
|
|
41
|
+
...this.params
|
|
42
|
+
},
|
|
43
|
+
axios.default as any
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// write templates and then DevWorkspace in a single file
|
|
48
|
+
async getDevWorkspaceConfigurationYamlAsString(context: DevfileContext): Promise<string> {
|
|
49
|
+
Logger.debug(`${this.constructor.name}.${this.getDevWorkspaceConfigurationYamlAsString.name}`);
|
|
50
|
+
const allContentArray: any[] = context.devWorkspaceTemplates.map(
|
|
51
|
+
(template: V1alpha2DevWorkspaceTemplate) => YAML.stringify(template)
|
|
52
|
+
);
|
|
53
|
+
allContentArray.push(YAML.stringify(context.devWorkspace));
|
|
54
|
+
|
|
55
|
+
return allContentArray.join('---\n');
|
|
56
|
+
}
|
|
57
|
+
}
|
package/utils/DriverHelper.ts
CHANGED
|
@@ -25,13 +25,13 @@ export class DriverHelper {
|
|
|
25
25
|
this.driver = driver.get() as ThenableWebDriver;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
getAction(): Actions {
|
|
29
29
|
Logger.trace('DriverHelper.getAction');
|
|
30
30
|
|
|
31
31
|
return this.driver.actions();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
async isVisible(locator: By): Promise<boolean> {
|
|
35
35
|
Logger.trace(`DriverHelper.isVisible ${locator}`);
|
|
36
36
|
|
|
37
37
|
try {
|
|
@@ -42,19 +42,19 @@ export class DriverHelper {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
async wait(milliseconds: number): Promise<void> {
|
|
46
46
|
Logger.trace(`DriverHelper.wait (${milliseconds} milliseconds)`);
|
|
47
47
|
|
|
48
48
|
await this.driver.sleep(milliseconds);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
async refreshPage(): Promise<void> {
|
|
52
52
|
Logger.trace(`DriverHelper.refreshPage`);
|
|
53
53
|
|
|
54
54
|
await this.driver.navigate().refresh();
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
async waitVisibilityBoolean(locator: By,
|
|
58
58
|
attempts: number = TestConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
|
|
59
59
|
polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
|
|
60
60
|
|
|
@@ -73,7 +73,7 @@ export class DriverHelper {
|
|
|
73
73
|
return false;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
async waitDisappearanceBoolean(locator: By,
|
|
77
77
|
attempts: number = TestConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
|
|
78
78
|
polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<boolean> {
|
|
79
79
|
|
|
@@ -92,7 +92,7 @@ export class DriverHelper {
|
|
|
92
92
|
return false;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
async waitVisibility(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
|
|
96
96
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
97
97
|
const attempts: number = Math.ceil(timeout / polling);
|
|
98
98
|
|
|
@@ -150,7 +150,7 @@ export class DriverHelper {
|
|
|
150
150
|
throw new error.TimeoutError(`Exceeded maximum visibility checkings attempts for '${elementLocator}' element, timeouted after ${timeout}`);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
async waitPresence(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<WebElement> {
|
|
154
154
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
155
155
|
const attempts: number = Math.ceil(timeout / polling);
|
|
156
156
|
|
|
@@ -178,7 +178,7 @@ export class DriverHelper {
|
|
|
178
178
|
throw new error.TimeoutError(`Exceeded maximum presence checking attempts, problems with 'StaleElementReferenceError' of '${elementLocator}' element`);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
async waitAllPresence(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<Array<WebElement>> {
|
|
182
182
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
183
183
|
const attempts: number = Math.ceil(timeout / polling);
|
|
184
184
|
|
|
@@ -206,7 +206,7 @@ export class DriverHelper {
|
|
|
206
206
|
throw new error.TimeoutError(`Exceeded maximum presence checkings attempts, problems with 'StaleElementReferenceError' of '${elementLocator}' element`);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
async waitAllVisibility(locators: Array<By>, timeout: number): Promise<void> {
|
|
210
210
|
Logger.trace(`DriverHelper.waitAllVisibility ${locators}`);
|
|
211
211
|
|
|
212
212
|
for (const elementLocator of locators) {
|
|
@@ -214,7 +214,7 @@ export class DriverHelper {
|
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
async waitDisappearance(elementLocator: By,
|
|
218
218
|
attempts: number = TestConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
|
|
219
219
|
polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<void> {
|
|
220
220
|
|
|
@@ -227,7 +227,7 @@ export class DriverHelper {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
async waitDisappearanceWithTimeout(elementLocator: By, timeout: number): Promise<void> {
|
|
231
231
|
Logger.trace(`DriverHelper.waitDisappearanceWithTimeout ${elementLocator}`);
|
|
232
232
|
|
|
233
233
|
await this.getDriver().wait(async () => {
|
|
@@ -239,7 +239,7 @@ export class DriverHelper {
|
|
|
239
239
|
}, timeout);
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
async waitAllDisappearance(locators: Array<By>,
|
|
243
243
|
attemptsPerLocator: number = TestConstants.TS_SELENIUM_DEFAULT_ATTEMPTS,
|
|
244
244
|
pollingPerLocator: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING): Promise<void> {
|
|
245
245
|
|
|
@@ -250,7 +250,7 @@ export class DriverHelper {
|
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
async waitAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
254
254
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
255
255
|
const attempts: number = Math.ceil(timeout / polling);
|
|
256
256
|
|
|
@@ -308,7 +308,7 @@ export class DriverHelper {
|
|
|
308
308
|
throw new error.TimeoutError(`Exceeded maximum clicking attempts, the '${elementLocator}' element is not clickable`);
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
async waitAndGetElementAttribute(elementLocator: By, attribute: string,
|
|
312
312
|
timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
|
|
313
313
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
314
314
|
const attempts: number = Math.ceil(timeout / polling);
|
|
@@ -350,7 +350,7 @@ export class DriverHelper {
|
|
|
350
350
|
throw new error.TimeoutError(`Exceeded maximum gettin of the '${attribute}' attribute attempts, from the '${elementLocator}' element`);
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
-
|
|
353
|
+
async waitAndGetCssValue(elementLocator: By, cssAttribute: string,
|
|
354
354
|
timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
|
|
355
355
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
356
356
|
const attempts: number = Math.ceil(timeout / polling);
|
|
@@ -392,7 +392,7 @@ export class DriverHelper {
|
|
|
392
392
|
throw new error.TimeoutError(`Exceeded maximum gettin of the '${cssAttribute}' css attribute attempts, from the '${elementLocator}' element`);
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
-
|
|
395
|
+
async waitAttributeValue(elementLocator: By,
|
|
396
396
|
attribute: string,
|
|
397
397
|
expectedValue: string,
|
|
398
398
|
timeout: number): Promise<void> {
|
|
@@ -408,7 +408,7 @@ export class DriverHelper {
|
|
|
408
408
|
`The '${attribute}' attribute value doesn't match with expected value '${expectedValue}'`);
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
-
|
|
411
|
+
async type(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
412
412
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
413
413
|
const attempts: number = Math.ceil(timeout / polling);
|
|
414
414
|
|
|
@@ -454,7 +454,7 @@ export class DriverHelper {
|
|
|
454
454
|
throw new error.TimeoutError(`Exceeded maximum typing attempts, to the '${elementLocator}' element`);
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
-
|
|
457
|
+
async typeToInvisible(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
458
458
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
459
459
|
const attempts: number = Math.ceil(timeout / polling);
|
|
460
460
|
|
|
@@ -496,7 +496,7 @@ export class DriverHelper {
|
|
|
496
496
|
throw new error.TimeoutError(`Exceeded maximum typing attempts, to the '${elementLocator}' element`);
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
-
|
|
499
|
+
async clear(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
500
500
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
501
501
|
const attempts: number = Math.ceil(timeout / polling);
|
|
502
502
|
|
|
@@ -538,7 +538,7 @@ export class DriverHelper {
|
|
|
538
538
|
throw new error.TimeoutError(`Exceeded maximum clearing attempts, to the '${elementLocator}' element`);
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
-
|
|
541
|
+
async clearInvisible(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
542
542
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
543
543
|
const attempts: number = Math.ceil(timeout / polling);
|
|
544
544
|
|
|
@@ -580,7 +580,7 @@ export class DriverHelper {
|
|
|
580
580
|
throw new error.TimeoutError(`Exceeded maximum clearing attempts, to the '${elementLocator}' element`);
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
-
|
|
583
|
+
async enterValue(elementLocator: By, text: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
584
584
|
if (elementLocator.toString().toLocaleLowerCase().includes('password')) {
|
|
585
585
|
Logger.trace(`DriverHelper.enterValue ${elementLocator} text: ***`);
|
|
586
586
|
} else {
|
|
@@ -594,13 +594,13 @@ export class DriverHelper {
|
|
|
594
594
|
await this.waitAttributeValue(elementLocator, 'value', text, timeout);
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
-
|
|
597
|
+
async waitAndSwitchToFrame(iframeLocator: By, timeout: number): Promise<void> {
|
|
598
598
|
Logger.trace(`DriverHelper.waitAndSwitchToFrame ${iframeLocator}`);
|
|
599
599
|
|
|
600
600
|
await this.driver.wait(until.ableToSwitchToFrame(iframeLocator), timeout);
|
|
601
601
|
}
|
|
602
602
|
|
|
603
|
-
|
|
603
|
+
async waitAndGetText(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<string> {
|
|
604
604
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
605
605
|
const attempts: number = Math.ceil(timeout / polling);
|
|
606
606
|
|
|
@@ -641,19 +641,19 @@ export class DriverHelper {
|
|
|
641
641
|
throw new error.TimeoutError(`Exceeded maximum text obtaining attempts, from the '${elementLocator}' element`);
|
|
642
642
|
}
|
|
643
643
|
|
|
644
|
-
|
|
644
|
+
async waitAndGetValue(elementLocator: By, timeout: number): Promise<string> {
|
|
645
645
|
Logger.trace(`DriverHelper.waitAndGetValue ${elementLocator}`);
|
|
646
646
|
|
|
647
647
|
return await this.waitAndGetElementAttribute(elementLocator, 'value', timeout);
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
-
|
|
650
|
+
async waitUntilTrue(callback: any, timeout: number): Promise<void> {
|
|
651
651
|
Logger.trace('DriverHelper.waitUntilTrue');
|
|
652
652
|
|
|
653
653
|
await this.driver.wait(callback, timeout);
|
|
654
654
|
}
|
|
655
655
|
|
|
656
|
-
|
|
656
|
+
async scrollTo(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
657
657
|
const polling: number = TestConstants.TS_SELENIUM_DEFAULT_POLLING;
|
|
658
658
|
const attempts: number = Math.ceil(timeout / polling);
|
|
659
659
|
|
|
@@ -696,16 +696,21 @@ export class DriverHelper {
|
|
|
696
696
|
throw new error.TimeoutError(`Exceeded maximum mouse move attempts, for the '${elementLocator}' element`);
|
|
697
697
|
}
|
|
698
698
|
|
|
699
|
-
|
|
699
|
+
async scrollToAndClick(elementLocator: By, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
700
700
|
await this.scrollTo(elementLocator, timeout);
|
|
701
701
|
await this.waitAndClick(elementLocator, timeout);
|
|
702
702
|
}
|
|
703
703
|
|
|
704
|
-
|
|
704
|
+
async scrollToAndEnterValue(elementLocator: By, value: string, timeout: number = TimeoutConstants.TS_SELENIUM_CLICK_ON_VISIBLE_ITEM): Promise<void> {
|
|
705
705
|
await this.scrollTo(elementLocator, timeout);
|
|
706
706
|
await this.enterValue(elementLocator, value, timeout);
|
|
707
707
|
}
|
|
708
708
|
|
|
709
|
+
// method is useful to debug page object elements
|
|
710
|
+
async highLightElement(element: WebElement): Promise<void> {
|
|
711
|
+
await this.getDriver().executeScript('arguments[0].style.border=\'2px solid red\'', element);
|
|
712
|
+
}
|
|
713
|
+
|
|
709
714
|
getDriver(): ThenableWebDriver {
|
|
710
715
|
Logger.trace('DriverHelper.getDriver');
|
|
711
716
|
|
|
@@ -43,22 +43,22 @@ export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
|
|
|
43
43
|
|
|
44
44
|
getContainerName(): string {
|
|
45
45
|
Logger.debug(`${this.getLoggingName(this.getContainerName.name)}: Get container name.`);
|
|
46
|
-
const output: ShellString =
|
|
46
|
+
const output: ShellString = ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} get ${(KubernetesCommandLineToolsExecutor.pod)} -o jsonpath='{.spec.containers[*].name}' -n ${this.namespace}`);
|
|
47
47
|
echo('\n');
|
|
48
48
|
return output.stderr ? output.stderr : output.stdout;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
getWorkspacePodName(): string {
|
|
52
52
|
Logger.debug(`${this.getLoggingName(this.getWorkspacePodName.name)}: Get workspace pod name.`);
|
|
53
|
-
const output: ShellString =
|
|
53
|
+
const output: ShellString = ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} get pod -l controller.devfile.io/devworkspace_name=${this.workspaceName} -n ${this.namespace} -o name`);
|
|
54
54
|
return output.stderr ? output.stderr : output.stdout.replace('\n', '');
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
deleteDevWorkspace(): void {
|
|
58
58
|
Logger.debug(`${this.getLoggingName(this.deleteDevWorkspace.name)}: Delete '${this.workspaceName}' workspace`);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} patch dw ${this.workspaceName} -n ${this.namespace} -p '{ "metadata": { "finalizers": null }}' --type merge || true`);
|
|
60
|
+
ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} delete dw ${this.workspaceName} -n ${this.namespace} || true`);
|
|
61
|
+
ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} delete dwt ${TestConstants.TS_SELENIUM_EDITOR}-${this.workspaceName} -n ${this.namespace} || true`);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
applyAndWaitDevWorkspace(yamlConfiguration: string): ShellString {
|
|
@@ -74,48 +74,48 @@ export class KubernetesCommandLineToolsExecutor extends ShellExecutor {
|
|
|
74
74
|
|
|
75
75
|
executeCommand(commandToExecute: string): ShellString {
|
|
76
76
|
Logger.debug(`${this.getLoggingName(this.executeCommand.name)}:`);
|
|
77
|
-
return
|
|
77
|
+
return ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} exec -i ${KubernetesCommandLineToolsExecutor.pod} -n ${this.namespace} -c ${KubernetesCommandLineToolsExecutor.container} -- sh -c "${commandToExecute}"`);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
applyYamlConfigurationAsStringOutput(yamlConfiguration: string):
|
|
80
|
+
applyYamlConfigurationAsStringOutput(yamlConfiguration: string): ShellString {
|
|
81
81
|
Logger.debug(`${this.getLoggingName(this.applyYamlConfigurationAsStringOutput.name)}:`);
|
|
82
|
-
|
|
82
|
+
return ShellExecutor.execWithLog(`cat <<EOF | ${this.KUBERNETES_COMMAND_LINE_TOOL} apply -n ${this.namespace} -f - \n` +
|
|
83
83
|
yamlConfiguration + '\n' +
|
|
84
84
|
'EOF');
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
applyYamlConfigurationAsFile(pathToFile: string): void {
|
|
88
88
|
Logger.debug(`${this.getLoggingName(this.applyYamlConfigurationAsFile.name)}:`);
|
|
89
|
-
|
|
89
|
+
ShellExecutor.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} apply -n ${this.namespace} -f "${path.resolve(pathToFile)}"`);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
getDevWorkspaceYamlConfiguration(): ShellString {
|
|
93
93
|
Logger.debug(`${this.getLoggingName(this.getDevWorkspaceYamlConfiguration.name)}:`);
|
|
94
|
-
return
|
|
94
|
+
return ShellExecutor.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} get dw ${this.workspaceName} -n ${this.namespace} -o yaml`);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
waitDevWorkspace(timeout: number = 360): ShellString {
|
|
98
98
|
Logger.debug(`${this.getLoggingName(this.waitDevWorkspace.name)}: Wait till workspace ready.`);
|
|
99
|
-
return
|
|
99
|
+
return ShellExecutor.execWithLog(`${(this.KUBERNETES_COMMAND_LINE_TOOL)} wait -n ${this.namespace} --for=condition=Ready dw ${this.workspaceName} --timeout=${timeout}s`);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
createNamespace(): void {
|
|
103
103
|
Logger.debug(`${this.getLoggingName(this.createNamespace.name)}: Create namespace "${this.namespace}".`);
|
|
104
|
-
|
|
104
|
+
ShellExecutor.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} create namespace ${this.namespace}`);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
createProject(projectName: string): void {
|
|
108
108
|
Logger.debug(`${this.getLoggingName(this.createProject.name)}: Create new project "${projectName}".`);
|
|
109
|
-
|
|
109
|
+
ShellExecutor.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} new-project ${projectName} -n ${this.namespace}`);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
deleteProject(projectName: string): void {
|
|
113
113
|
Logger.debug(`${this.getLoggingName(this.deleteProject.name)}: Delete "${projectName}".`);
|
|
114
|
-
|
|
114
|
+
ShellExecutor.execWithLog(`${this.KUBERNETES_COMMAND_LINE_TOOL} delete project ${projectName} -n ${this.namespace}`);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
private isUserLoggedIn(): boolean {
|
|
118
|
-
const whoamiCommandOutput: ShellString =
|
|
118
|
+
const whoamiCommandOutput: ShellString = ShellExecutor.execWithLog('oc whoami && oc whoami --show-server=true');
|
|
119
119
|
|
|
120
120
|
return whoamiCommandOutput.stdout.includes(TestConstants.TS_SELENIUM_OCP_USERNAME) && whoamiCommandOutput.stdout.includes(this.getServerUrl());
|
|
121
121
|
}
|
package/utils/Logger.ts
CHANGED
|
@@ -17,7 +17,7 @@ export abstract class Logger {
|
|
|
17
17
|
* @param text log text
|
|
18
18
|
* @param indentLevel log level
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
static error(text: string, indentLevel: number = 1): void {
|
|
21
21
|
this.logText(indentLevel, `[ERROR] ${text}`);
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ export abstract class Logger {
|
|
|
26
26
|
* @param text log text
|
|
27
27
|
* @param indentLevel log level
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
static warn(text: string, indentLevel: number = 1): void {
|
|
30
30
|
if (TestConstants.TS_SELENIUM_LOG_LEVEL === 'ERROR') {
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
@@ -38,7 +38,7 @@ export abstract class Logger {
|
|
|
38
38
|
* @param text log text
|
|
39
39
|
* @param indentLevel log level
|
|
40
40
|
*/
|
|
41
|
-
|
|
41
|
+
static info(text: string, indentLevel: number = 3): void {
|
|
42
42
|
if (TestConstants.TS_SELENIUM_LOG_LEVEL === 'ERROR' ||
|
|
43
43
|
TestConstants.TS_SELENIUM_LOG_LEVEL === 'WARN') {
|
|
44
44
|
return;
|
|
@@ -51,7 +51,7 @@ export abstract class Logger {
|
|
|
51
51
|
* @param text log text
|
|
52
52
|
* @param indentLevel log level
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
static debug(text: string, indentLevel: number = 5): void {
|
|
55
55
|
if (TestConstants.TS_SELENIUM_LOG_LEVEL === 'ERROR' ||
|
|
56
56
|
TestConstants.TS_SELENIUM_LOG_LEVEL === 'WARN' ||
|
|
57
57
|
TestConstants.TS_SELENIUM_LOG_LEVEL === 'INFO') {
|
|
@@ -66,7 +66,7 @@ export abstract class Logger {
|
|
|
66
66
|
* @param text log text
|
|
67
67
|
* @param indentLevel log level
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
static trace(text: string, indentLevel: number = 6): void {
|
|
70
70
|
if (TestConstants.TS_SELENIUM_LOG_LEVEL === 'ERROR' ||
|
|
71
71
|
TestConstants.TS_SELENIUM_LOG_LEVEL === 'WARN' ||
|
|
72
72
|
TestConstants.TS_SELENIUM_LOG_LEVEL === 'INFO' ||
|
package/utils/Sanitizer.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { injectable } from 'inversify';
|
|
|
13
13
|
@injectable()
|
|
14
14
|
export class Sanitizer {
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
sanitize(arg: string): string {
|
|
17
17
|
return arg.replace(/[\/]/g, '+').replace(/[\,]/g, '.').replace(/[\:]/g, '-').replace(/[\'\"]/g, '').replace(/[^a-z0-9\+\-\.\(\)\[\]\_]/gi, '_');
|
|
18
18
|
}
|
|
19
19
|
}
|