Skip to content

Commit 949f348

Browse files
trdoyle81Triona DoyleTriona Doyle
authored
Gitops 9592 local admin UI test with playwright (#1140)
* Add login via local credentials test Signed-off-by: Triona Doyle <bot@example.com> * address coderabbit feedback for timeouts and cross-version locators Signed-off-by: Triona Doyle <tekton@example.com> * Address coderabbit suggestion: ensure Playwright context closes cleanly on failure Signed-off-by: Triona Doyle <tekton@example.com> --------- Signed-off-by: Triona Doyle <bot@example.com> Signed-off-by: Triona Doyle <tekton@example.com> Co-authored-by: Triona Doyle <bot@example.com> Co-authored-by: Triona Doyle <tekton@example.com>
1 parent 2b779a2 commit 949f348

1 file changed

Lines changed: 55 additions & 0 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { test, expect } from '@playwright/test';
2+
import { execSync } from 'node:child_process';
3+
4+
test('Log into Argo CD as local admin', async ({ browser }) => {
5+
let rawOutput: string;
6+
let routeUrl: string;
7+
8+
try {
9+
rawOutput = execSync(
10+
'oc extract secret/openshift-gitops-cluster -n openshift-gitops --keys=admin.password --to=-',
11+
{ timeout: 15000, stdio: 'pipe' }
12+
).toString();
13+
} catch (error) {
14+
throw new Error("Failed to extract admin password. Please check your cluster connection and oc CLI.");
15+
}
16+
17+
//get credentials
18+
const password = rawOutput.split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('#'))[0];
19+
20+
try {
21+
routeUrl = execSync(
22+
'oc get route openshift-gitops-server -n openshift-gitops -o jsonpath="{.spec.host}"',
23+
{ timeout: 15000, stdio: 'pipe' }
24+
).toString().trim();
25+
} catch (error) {
26+
throw new Error("Failed to fetch Argo CD route. Please check your cluster connection and oc CLI.");
27+
}
28+
29+
//Fresh context to avoid any cached state issues
30+
const context = await browser.newContext({
31+
storageState: { cookies: [], origins: [] },
32+
ignoreHTTPSErrors: true
33+
});
34+
35+
try {
36+
//Navigate and wait for the page to be loaded
37+
const page = await context.newPage();
38+
const loginUrl = `https://${routeUrl}/login?dex=none`;
39+
await page.goto(loginUrl, { waitUntil: 'load' });
40+
41+
const userField = page.getByLabel(/username/i);
42+
await userField.waitFor({ state: 'visible', timeout: 20000 });
43+
44+
//Fill and Sign In
45+
await userField.fill('admin');
46+
await page.locator('input[type="password"]').fill(password);
47+
await page.getByRole('button', { name: /sign in/i }).click();
48+
49+
//Verify we're logged in
50+
await expect(page.locator('.sidebar, [data-testid="sidebar"]').first()).toBeVisible({ timeout: 20000 });
51+
} finally {
52+
// This guarantees the context closes even if an assertion fails above!
53+
await context.close();
54+
}
55+
});

0 commit comments

Comments
 (0)