Skip to content

Commit 5d75852

Browse files
authored
[Test] Add 'SshUrlNoOauthPatFactory' E2E test (#23575)
* Update 'UserPreferences' pageobject * Add 'SshUrlNoOauthPatFactory' test * Add new files to 'resources' folder
1 parent 4507346 commit 5d75852

File tree

5 files changed

+172
-3
lines changed

5 files changed

+172
-3
lines changed

tests/e2e/pageobjects/dashboard/UserPreferences.ts

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** *******************************************************************
2-
* copyright (c) 2019-2023 Red Hat, Inc.
2+
* copyright (c) 2019-2025 Red Hat, Inc.
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -9,6 +9,8 @@
99
**********************************************************************/
1010
import { inject, injectable } from 'inversify';
1111
import 'reflect-metadata';
12+
import * as fs from 'fs';
13+
import * as path from 'path';
1214
import { CLASSES } from '../../configs/inversify.types';
1315
import { By } from 'selenium-webdriver';
1416
import { DriverHelper } from '../../utils/DriverHelper';
@@ -34,6 +36,15 @@ export class UserPreferences {
3436

3537
private static readonly SSH_KEY_TAB: By = By.xpath('//button[text()="SSH Keys"]');
3638
private static readonly ADD_NEW_SSH_KEY_BUTTON: By = By.xpath('//button[text()="Add SSH Key"]');
39+
private static readonly ADD_SSH_KEYS_POPUP: By = By.xpath('//span[text()="Add SSH Keys"]');
40+
private static readonly PASTE_PRIVATE_SSH_KEY_FIELD: By = By.css('textarea[name="ssh-private-key"]');
41+
private static readonly PASTE_PUBLIC_SSH_KEY_FIELD: By = By.css('textarea[name="ssh-public-key"]');
42+
private static readonly ADD_SSH_KEYS_BUTTON: By = By.css('.pf-c-button.pf-m-primary');
43+
private static readonly GIT_SSH_KEY_NAME: By = By.css('[data-testid="title"]');
44+
private static readonly GIT_SSH_KEY_ACTIONS_BUTTON: By = By.css('section[id*="SshKeys-user-preferences"] button[aria-label="Actions"]');
45+
private static readonly DELETE_BUTTON: By = By.xpath('//button[text()="Delete"]');
46+
private static readonly CONFIRM_DELETE_SSH_KEYS_POPUP: By = By.css('div[id^="pf-modal-part"][role="dialog"]');
47+
private static readonly CONFIRM_DELETE_SSH_KEYS_CHECKBOX: By = By.id('delete-ssh-keys-warning-checkbox');
3748

3849
private static readonly CONFIRMATION_WINDOW: By = By.xpath('//span[text()="Revoke Git Services"]');
3950
private static readonly DELETE_CONFIRMATION_CHECKBOX: By = By.xpath('//input[@data-testid="warning-info-checkbox"]');
@@ -60,7 +71,7 @@ export class UserPreferences {
6071
await this.openGitServicesTab();
6172
await this.openPatTab();
6273
await this.openGitConfigPage();
63-
await this.openSshKeyTab();
74+
await this.checkAddSshKeyButtonAvailability();
6475
}
6576

6677
async openContainerRegistriesTab(): Promise<void> {
@@ -116,9 +127,64 @@ export class UserPreferences {
116127
Logger.debug();
117128

118129
await this.driverHelper.waitAndClick(UserPreferences.SSH_KEY_TAB);
130+
}
131+
132+
async checkAddSshKeyButtonAvailability(): Promise<void> {
133+
Logger.debug();
134+
135+
await this.openSshKeyTab();
119136
await this.driverHelper.waitVisibility(UserPreferences.ADD_NEW_SSH_KEY_BUTTON);
120137
}
121138

139+
async addSshKeys(privateSshKeyPath: string, publicSshKeyPath: string): Promise<void> {
140+
Logger.debug();
141+
142+
Logger.info('Adding new SSH keys');
143+
await this.driverHelper.waitAndClick(UserPreferences.ADD_NEW_SSH_KEY_BUTTON);
144+
await this.driverHelper.waitVisibility(UserPreferences.ADD_SSH_KEYS_POPUP);
145+
await this.uploadSshKeys(privateSshKeyPath, publicSshKeyPath);
146+
await this.driverHelper.waitAndClick(UserPreferences.ADD_SSH_KEYS_BUTTON);
147+
await this.driverHelper.waitVisibility(UserPreferences.GIT_SSH_KEY_NAME);
148+
Logger.info('SSH keys have been added');
149+
}
150+
151+
async uploadSshKeys(privateSshKeyPath: string, publicSshKeyPath: string): Promise<void> {
152+
Logger.debug();
153+
const privateSshKey: string = Buffer.from(fs.readFileSync(path.resolve(privateSshKeyPath), 'utf-8'), 'base64').toString('utf-8');
154+
const publicSshKey: string = Buffer.from(fs.readFileSync(path.resolve(publicSshKeyPath), 'utf-8'), 'base64').toString('utf-8');
155+
156+
Logger.info('Pasting private SSH key');
157+
await this.driverHelper.waitAndClick(UserPreferences.PASTE_PRIVATE_SSH_KEY_FIELD);
158+
await this.driverHelper.getAction().sendKeys(privateSshKey).perform();
159+
160+
Logger.info('Pasting public SSH key');
161+
await this.driverHelper.waitAndClick(UserPreferences.PASTE_PUBLIC_SSH_KEY_FIELD);
162+
await this.driverHelper.getAction().sendKeys(publicSshKey).perform();
163+
}
164+
165+
async isSshKeyPresent(): Promise<boolean> {
166+
Logger.debug();
167+
168+
return this.driverHelper.isVisible(UserPreferences.GIT_SSH_KEY_NAME);
169+
}
170+
171+
async deleteSshKeys(): Promise<void> {
172+
Logger.debug();
173+
174+
Logger.info('Deleting SSH keys');
175+
await this.openSshKeyTab();
176+
await this.driverHelper.waitAndClick(
177+
UserPreferences.GIT_SSH_KEY_ACTIONS_BUTTON,
178+
TIMEOUT_CONSTANTS.TS_COMMON_DASHBOARD_WAIT_TIMEOUT
179+
);
180+
await this.driverHelper.waitAndClick(UserPreferences.DELETE_BUTTON);
181+
await this.driverHelper.waitVisibility(UserPreferences.CONFIRM_DELETE_SSH_KEYS_POPUP);
182+
await this.driverHelper.waitAndClick(UserPreferences.CONFIRM_DELETE_SSH_KEYS_CHECKBOX);
183+
await this.driverHelper.waitAndClick(UserPreferences.DELETE_BUTTON);
184+
await this.driverHelper.waitDisappearance(UserPreferences.GIT_SSH_KEY_NAME);
185+
Logger.info('SSH keys have been deleted');
186+
}
187+
122188
getServiceConfig(service: string): string {
123189
const gitService: { [key: string]: string } = {
124190
[GitProviderType.GITHUB]: 'GitHub',
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNBUkFYazVMM3ZLdGl1cStYdUIzd1J3R21VWlV3eVJKOC9iYTRLQjVzZWR3QUFBQUpnTnUyT0NEYnRqCmdnQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDQVJBWGs1TDN2S3RpdXErWHVCM3dSd0dtVVpVd3lSSjgvYmE0S0I1c2Vkd0EKQUFBRUFBQ3pOVjdKUVpFUFNaVUZSQjU3c25oczZKZHlJSEhkUWk2cFBBRkNDUU5SRUJlVGt2ZThxMks2cjVlNEhmQkhBYQpaUmxUREpFbno5dHJnb0hteDUzQUFBQUFGV05vWlhCMWJHeHlaWEV4UUdkdFlXbHNMbU52YlE9PQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUJFQmVUa3ZlOHEySzZyNWU0SGZCSEFhWlJsVERKRW56OXRyZ29IbXg1M0EgY2hlcHVsbHJlcTFAZ21haWwuY29t

tests/e2e/specs/dashboard-samples/Documentation.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ suite(`Check links to documentation page in Dashboard ${BASE_TEST_CONSTANTS.TEST
5555
try {
5656
({ docs, links, productVersion } = JSON.parse(
5757
shellExecutor.executeCommand(
58-
`oc exec deploy/devspaces-dashboard -n openshift-devspaces -- cat /public/dashboard/assets/branding/product.json`
58+
'oc exec deploy/devspaces-dashboard -n openshift-devspaces -- cat /public/dashboard/assets/branding/product.json'
5959
)
6060
));
6161
} catch (e) {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/** *******************************************************************
2+
* copyright (c) 2025 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 { ViewSection } from 'monaco-page-objects';
12+
import { ProjectAndFileTests } from '../../tests-library/ProjectAndFileTests';
13+
import { CLASSES, TYPES } from '../../configs/inversify.types';
14+
import { e2eContainer } from '../../configs/inversify.config';
15+
import { WorkspaceHandlingTests } from '../../tests-library/WorkspaceHandlingTests';
16+
import { registerRunningWorkspace } from '../MochaHooks';
17+
import { LoginTests } from '../../tests-library/LoginTests';
18+
import { StringUtil } from '../../utils/StringUtil';
19+
import { FACTORY_TEST_CONSTANTS } from '../../constants/FACTORY_TEST_CONSTANTS';
20+
import { BrowserTabsUtil } from '../../utils/BrowserTabsUtil';
21+
import { expect } from 'chai';
22+
import { BASE_TEST_CONSTANTS } from '../../constants/BASE_TEST_CONSTANTS';
23+
import { UserPreferences } from '../../pageobjects/dashboard/UserPreferences';
24+
import { Dashboard } from '../../pageobjects/dashboard/Dashboard';
25+
import { ITestWorkspaceUtil } from '../../utils/workspace/ITestWorkspaceUtil';
26+
import { Logger } from '../../utils/Logger';
27+
28+
suite(`The SshUrlNoOauthPatFactory userstory ${BASE_TEST_CONSTANTS.TEST_ENVIRONMENT}`, function (): void {
29+
const projectAndFileTests: ProjectAndFileTests = e2eContainer.get(CLASSES.ProjectAndFileTests);
30+
const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
31+
const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
32+
const browserTabsUtil: BrowserTabsUtil = e2eContainer.get(CLASSES.BrowserTabsUtil);
33+
const userPreferences: UserPreferences = e2eContainer.get(CLASSES.UserPreferences);
34+
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
35+
const testWorkspaceUtil: ITestWorkspaceUtil = e2eContainer.get(TYPES.WorkspaceUtil);
36+
const factoryUrl: string =
37+
FACTORY_TEST_CONSTANTS.TS_SELENIUM_FACTORY_GIT_REPO_URL ||
38+
'ssh://[email protected]/~admin/private-bb-repo.git';
39+
const privateSshKeyPath: string = 'resources/factory/pr-k.txt';
40+
const publicSshKeyPath: string = 'resources/factory/pub-k.txt';
41+
let projectSection: ViewSection;
42+
43+
async function deleteSshKeys(): Promise<void> {
44+
Logger.debug('Deleting SSH keys if they are present');
45+
await userPreferences.openUserPreferencesPage();
46+
await userPreferences.openSshKeyTab();
47+
if (await userPreferences.isSshKeyPresent()) {
48+
await userPreferences.deleteSshKeys();
49+
}
50+
}
51+
52+
suite(`Create workspace from factory:${factoryUrl}`, function (): void {
53+
suiteSetup('Login', async function (): Promise<void> {
54+
await loginTests.loginIntoChe();
55+
await deleteSshKeys();
56+
});
57+
test('Add SSH keys', async function (): Promise<void> {
58+
await userPreferences.openUserPreferencesPage();
59+
await userPreferences.openSshKeyTab();
60+
await userPreferences.addSshKeys(privateSshKeyPath, publicSshKeyPath);
61+
});
62+
test(`Create and open new workspace from factory:${factoryUrl}`, async function (): Promise<void> {
63+
await workspaceHandlingTests.createAndOpenWorkspaceFromGitRepository(factoryUrl);
64+
});
65+
test('Obtain workspace name from workspace loader page', async function (): Promise<void> {
66+
await workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
67+
});
68+
test('Register running workspace', function (): void {
69+
registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName());
70+
});
71+
test('Wait workspace readiness', async function (): Promise<void> {
72+
await projectAndFileTests.waitWorkspaceReadinessForCheCodeEditor();
73+
});
74+
test('Check a project folder has been created', async function (): Promise<void> {
75+
const projectName: string = FACTORY_TEST_CONSTANTS.TS_SELENIUM_PROJECT_NAME || StringUtil.getProjectNameFromGitUrl(factoryUrl);
76+
projectSection = await projectAndFileTests.getProjectViewSession();
77+
expect(await projectAndFileTests.getProjectTreeItem(projectSection, projectName), 'Project folder was not imported').not
78+
.undefined;
79+
});
80+
test('Accept the project as a trusted one', async function (): Promise<void> {
81+
await projectAndFileTests.performTrustAuthorDialog();
82+
});
83+
test('Check the project files was imported', async function (): Promise<void> {
84+
expect(
85+
await projectAndFileTests.getProjectTreeItem(projectSection, BASE_TEST_CONSTANTS.TS_SELENIUM_PROJECT_ROOT_FILE_NAME),
86+
'Project files were not imported'
87+
).not.undefined;
88+
});
89+
suiteTeardown('Delete SSH keys', async function (): Promise<void> {
90+
await dashboard.openDashboard();
91+
await deleteSshKeys();
92+
});
93+
suiteTeardown('Stop and delete the workspace by APII', async function (): Promise<void> {
94+
await browserTabsUtil.closeAllTabsExceptCurrent();
95+
await testWorkspaceUtil.stopAndDeleteWorkspaceByName(WorkspaceHandlingTests.getWorkspaceName());
96+
});
97+
suiteTeardown('Unregister running workspace', function (): void {
98+
registerRunningWorkspace('');
99+
});
100+
});
101+
});

0 commit comments

Comments
 (0)