Skip to content

Commit e88b970

Browse files
author
Triona Doyle
committed
Merge foundation branch and combine login methods
Signed-off-by: Triona Doyle <bot@example.com>
2 parents bf41766 + 23c8791 commit e88b970

4 files changed

Lines changed: 49 additions & 54 deletions

File tree

test/ui-e2e/.auth/setup.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,23 @@ import { test as setup } from '@playwright/test';
33
const authFile = '.auth/storageState.json';
44

55
setup('authenticate to OpenShift Cluster', async ({ page, baseURL }) => {
6-
// 1. Navigate to the OpenShift Console
7-
// It checks Playwright's config (baseURL) first, then falls back to environment variables
6+
// Navigate to the OpenShift Console
87
const targetUrl = baseURL || process.env.CONSOLE_URL || process.env.BASE_URL;
98

109
if (!targetUrl) {
1110
throw new Error("No Console URL provided! Ensure your bash script exports BASE_URL or CONSOLE_URL.");
1211
}
1312

1413
console.log(`Navigating to OpenShift Console: ${targetUrl}`);
15-
await page.goto(targetUrl); // <-- THIS WAS THE MISSING LINK!
14+
await page.goto(targetUrl);
1615

17-
// 2. Define our locators flexibly
16+
//set locators
1817
const idpScreenText = page.getByText(/Log in with/i);
1918
const usernameInput = page.getByLabel(/Username/i)
2019
.or(page.locator('input[name="username"]'))
2120
.or(page.getByPlaceholder(/Username/i));
2221

23-
// 3. Wait for EITHER the IDP screen OR the Username field to appear
22+
//wait for the IDP screen OR the Username field to appear
2423
try {
2524
await Promise.race([
2625
idpScreenText.waitFor({ state: 'visible', timeout: 15000 }),
@@ -30,40 +29,37 @@ setup('authenticate to OpenShift Cluster', async ({ page, baseURL }) => {
3029
console.log("Timed out waiting for OpenShift login page to render.");
3130
}
3231

33-
// Set a default user to prevent undefined errors if you forget to export it
32+
const idpName = process.env.IDP || 'kube:admin';
3433
const user = process.env.CLUSTER_USER || 'kubeadmin';
3534

36-
// 4. Handle the IDP Screen if it exists
3735
if (await idpScreenText.isVisible()) {
38-
console.log("IDP selection screen detected. Selecting provider...");
36+
console.log(`IDP selection screen detected. Selecting provider: "${idpName}"`);
3937

40-
// Decide which IDP to click based on the user
41-
const idpRegex = (user === 'kubeadmin') ? /kube:admin/i : /htpasswd/i;
38+
// look for the specific IDP
39+
const idpLink = page.getByRole('link', { name: new RegExp(idpName, 'i') });
4240

43-
// OpenShift IDPs are usually links styled as buttons
44-
await page.getByRole('link', { name: idpRegex }).click();
41+
await idpLink.waitFor({ state: 'visible', timeout: 5000 });
42+
await idpLink.click();
4543
} else {
46-
console.log("No IDP screen detected, proceeding directly to credentials...");
44+
console.log("No IDP screen detected (or already selected), proceeding to credentials...");
4745
}
4846

49-
// 5. Fill in Cluster Credentials
47+
// fill in the Credentials
5048
await usernameInput.waitFor({ state: 'visible', timeout: 10000 });
51-
await usernameInput.fill(user); // Using the fallback variable defined above
49+
await usernameInput.fill(user);
5250

5351
const passwordInput = page.getByLabel(/Password/i)
5452
.or(page.locator('input[name="password"]'))
5553
.or(page.getByPlaceholder(/Password/i));
5654

57-
// Assert that password exists so we don't accidentally type 'undefined'
5855
if (!process.env.CLUSTER_PASSWORD) {
5956
throw new Error("CLUSTER_PASSWORD is not set in the environment!");
6057
}
6158

6259
await passwordInput.fill(process.env.CLUSTER_PASSWORD);
6360
await page.getByRole('button', { name: /Log in/i }).click();
6461

65-
// 6. Save this pure OpenShift auth state
66-
// Added a brief wait to ensure login completes before saving state
62+
//save the auth state
6763
await page.waitForLoadState('networkidle');
6864
await page.context().storageState({ path: authFile });
6965
});

test/ui-e2e/run-ui-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ if ! oc whoami > /dev/null 2>&1; then
2020
fi
2121

2222
#find the URLs for console and argocd
23-
echo "🔍 Discovering component URLs..."
23+
echo "Discovering component URLs..."
2424
export ARGOCD_URL=$(oc get route openshift-gitops-server -n openshift-gitops -o jsonpath='{"https://"}{.spec.host}')
2525
export CONSOLE_URL=$(oc whoami --show-console)
2626

test/ui-e2e/src/pages/LoginPage.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Page, expect } from '@playwright/test';
1+
import { Page } from '@playwright/test';
22

33
export class LoginPage {
44
readonly page: Page;
@@ -8,58 +8,58 @@ export class LoginPage {
88
}
99

1010
async goto() {
11+
//navigate to the baseURL defined in playwright.config.ts
1112
await this.page.goto('/');
1213
}
1314

15+
//login Via OpenShift SSO
1416
async loginViaOpenShift(user: string, pass: string, idp: string = 'kube:admin') {
15-
16-
// ======================================================
17-
// Argo CD Login Screen
18-
// ======================================================
19-
// We just wait patiently. Even if Argo CD does its weird
20-
// redirect dance for 2 seconds, Playwright will wait up to
21-
// 10 seconds for this button to finally appear.
17+
//click the SSO button on the Argo CD landing page
2218
const ssoButton = this.page.getByText(/LOG IN VIA OPENSHIFT/i);
2319
await ssoButton.waitFor({ state: 'visible', timeout: 10000 });
2420
await ssoButton.click();
2521

26-
// ======================================================
27-
// OpenShift Login (with optional IDP step)
28-
// ======================================================
29-
// Sometimes OpenShift asks which IDP to use. We check for it quickly.
22+
//handle the OpenShift IDP selection screen if it appears
3023
try {
3124
const idpButton = this.page.getByText(idp, { exact: true });
32-
// Only wait 3 seconds. If it's not there, OpenShift skipped straight to the form.
3325
await idpButton.waitFor({ state: 'visible', timeout: 3000 });
3426
await idpButton.click();
35-
console.log(`Clicked IDP: ${idp}`);
3627
} catch (e) {
37-
console.log('No IDP selection screen, proceeding to credentials form...');
28+
//if it's not there then OpenShift likely defaulted to another
3829
}
3930

40-
// Now fill out the actual Username/Password form
31+
//fil out the OpenShift credentials
4132
await this.page.getByLabel(/Username/i).waitFor({ state: 'visible' });
4233
await this.page.getByLabel(/Username/i).fill(user);
4334
await this.page.getByLabel(/Password/i).fill(pass);
4435
await this.page.getByRole('button', { name: /Log in/i }).click();
4536

46-
// ======================================================
47-
// Authorize Access (First Login Only)
48-
// ======================================================
37+
//Auth Handle the Allow Permissions screen
4938
try {
50-
const allowButton = this.page.getByRole('button', { name: 'Allow selected permissions' });
51-
// Wait 5 seconds. If it's not there, we've already authorized in the past.
39+
const allowButton = this.page.getByRole('button', { name: /Allow selected permissions/i });
5240
await allowButton.waitFor({ state: 'visible', timeout: 5000 });
5341
await allowButton.click();
54-
console.log('Clicked Authorize Access button.');
5542
} catch (error) {
56-
console.log('No Authorize screen appeared, continuing...');
43+
// Screen didn't appear likely already authorised.
5744
}
5845

59-
// ======================================================
60-
// Argo CD Dashboard (Success)
61-
// ======================================================
62-
// Wait for the URL to change to the applications dashboard
46+
//Success Checking make we land on the applications dashboard
6347
await this.page.waitForURL('**/applications**', { timeout: 20000 });
6448
}
49+
50+
//login As Local Admin
51+
async loginAsLocalAdmin(password: string) {
52+
//force the local login screen by appending ?dex=none
53+
await this.page.goto(`${this.page.url()}?dex=none`);
54+
55+
//fill out the local admin credentials
56+
const userField = this.page.getByRole('textbox').first();
57+
await userField.waitFor({ state: 'visible' });
58+
await userField.fill('admin');
59+
60+
await this.page.locator('input[type="password"]').fill(password);
61+
62+
//Click sign in
63+
await this.page.getByRole('button', { name: /sign in/i }).click();
64+
}
6565
}

test/ui-e2e/tests/login.spec.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
import { test, expect } from '@playwright/test';
22
import { LoginPage } from '../src/pages/LoginPage';
33

4-
test.describe('Authentication Flow', () => {
4+
test.describe('Argo CD SSO Authentication', () => {
55

6-
// don't not use the saved login state
7-
// make sure we always get to the argo login screen, even after setup.ts already ran.
6+
//clear storageState to force a full login flow for this specific test
87
test.use({ storageState: { cookies: [], origins: [] } });
98

10-
//login via openshift
11-
test('Scenario: Successful OpenShift SSO Login', async ({ page }) => {
9+
test('should successfully log in via OpenShift SSO', async ({ page }) => {
1210
const loginPage = new LoginPage(page);
11+
1312
await loginPage.goto();
1413

1514
await loginPage.loginViaOpenShift(
1615
process.env.CLUSTER_USER!,
1716
process.env.CLUSTER_PASSWORD!,
18-
process.env.IDP
17+
process.env.IDP || 'kube:admin'
1918
);
2019

21-
const newAppButton = page.getByRole('button', { name: /NEW APP/i });
22-
await expect(newAppButton).toBeVisible({ timeout: 15000 });
20+
//Check the button is visible as proof of successful login
21+
await expect(page.getByRole('button', { name: /NEW APP/i })).toBeVisible({ timeout: 15000 });
2322
});
2423
});

0 commit comments

Comments
 (0)