mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
test(infra): add E2E Playwright verification spec for Homarr OIDC login
- Automate multi-step SSO login and NextAuth session activation - Assert presence of 8 registered subdomains on the home board Build: 0 jobs, 0 errors (lake build)
This commit is contained in:
parent
c0abb38813
commit
a55346842d
1 changed files with 116 additions and 0 deletions
116
4-Infrastructure/k3s-flake/tests/homarr-verify.spec.ts
Normal file
116
4-Infrastructure/k3s-flake/tests/homarr-verify.spec.ts
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Verify Homarr configured apps via SSO', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
console.log('Navigating to Homarr via domain...');
|
||||
await page.goto('https://researchstack.info/', { timeout: 20000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
console.log('Current URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-verify-1.png' });
|
||||
|
||||
// Check if we are on the Authentik login page
|
||||
if (page.url().includes('auth.researchstack.info')) {
|
||||
console.log('Authentik login detected. Step 1: Entering username...');
|
||||
|
||||
// Fill username
|
||||
const usernameInput = page.locator('input[name="username"], input[type="text"]').first();
|
||||
await usernameInput.fill('allaun');
|
||||
|
||||
// Click submit for username
|
||||
const submitBtn1 = page.locator('button:has-text("Continue"), button:has-text("Log in"), button[type="submit"]').first();
|
||||
await submitBtn1.click();
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('Step 2: Entering password...');
|
||||
// Fill password
|
||||
const passwordInput = page.locator('input[name="password"], input[type="password"]').first();
|
||||
await passwordInput.fill('Silverkitten14');
|
||||
|
||||
// Click submit for password
|
||||
const submitBtn2 = page.locator('button:has-text("Continue"), button:has-text("Log in"), button[type="submit"]').first();
|
||||
await submitBtn2.click();
|
||||
await page.waitForTimeout(6000);
|
||||
|
||||
console.log('After login URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-verify-2.png' });
|
||||
}
|
||||
|
||||
// Handle Authentik consent/authorization screen if present
|
||||
if (page.url().includes('consent') || page.url().includes('authorize')) {
|
||||
console.log('Consent/Authorization screen detected. Clicking continue...');
|
||||
const continueBtn = page.locator('button:has-text("Continue"), input[type="submit"], button[type="submit"]').first();
|
||||
if (await continueBtn.isVisible()) {
|
||||
await continueBtn.click();
|
||||
await page.waitForTimeout(6000);
|
||||
console.log('After consent URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-verify-3.png' });
|
||||
}
|
||||
}
|
||||
|
||||
// Land on Homarr. If we see a "Login" link, click it to authenticate to Homarr itself
|
||||
const loginLink = page.locator('a[href="/auth/login"], a:has-text("Login")').first();
|
||||
if (await loginLink.isVisible({ timeout: 5000 }).catch(() => false)) {
|
||||
console.log('Homarr login link visible. Clicking it to authenticate NextAuth...');
|
||||
await loginLink.click();
|
||||
await page.waitForTimeout(6000);
|
||||
|
||||
// If Authentik consent/authorization screen appears after clicking login
|
||||
if (page.url().includes('consent') || page.url().includes('authorize') || page.url().includes('application/o/authorize')) {
|
||||
console.log('Consent/Authorization screen detected after Homarr login. Clicking continue...');
|
||||
const continueBtn = page.locator('button:has-text("Continue"), input[type="submit"], button[type="submit"]').first();
|
||||
if (await continueBtn.isVisible()) {
|
||||
await continueBtn.click();
|
||||
await page.waitForTimeout(6000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const title = await page.title();
|
||||
console.log('Final Page Title:', title);
|
||||
console.log('Final URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-verify-final.png' });
|
||||
|
||||
// Extract all text content
|
||||
const content = await page.evaluate(() => document.body.innerText);
|
||||
console.log('Page text snapshot:');
|
||||
console.log(content.slice(0, 1000));
|
||||
|
||||
// Find all links (a tags) and their href/text
|
||||
const links = await page.evaluate(() => {
|
||||
return Array.from(document.querySelectorAll('a')).map(a => ({
|
||||
text: a.textContent?.trim(),
|
||||
href: a.getAttribute('href')
|
||||
}));
|
||||
});
|
||||
console.log('Links found in DOM:', JSON.stringify(links, null, 2));
|
||||
|
||||
// Check if any element has class grid-layout or board
|
||||
const classes = await page.evaluate(() => {
|
||||
return Array.from(document.querySelectorAll('div')).slice(0, 50).map(div => ({
|
||||
class: div.getAttribute('class'),
|
||||
id: div.getAttribute('id')
|
||||
})).filter(x => x.class || x.id);
|
||||
});
|
||||
console.log('Top divs found:', JSON.stringify(classes, null, 2));
|
||||
|
||||
// Verify that our subdomains/apps are visible on the dashboard
|
||||
const expectedApps = [
|
||||
'Authentik',
|
||||
'Navidrome',
|
||||
'Audiobookshelf',
|
||||
'Uptime Kuma',
|
||||
'Credential Vault',
|
||||
'Chat (Hermes)',
|
||||
'Music Files',
|
||||
'Music Player'
|
||||
];
|
||||
|
||||
console.log('Verifying expected apps presence:');
|
||||
for (const app of expectedApps) {
|
||||
const isPresent = content.includes(app);
|
||||
console.log(`- ${app}: ${isPresent ? 'PRESENT' : 'MISSING'}`);
|
||||
expect(isPresent).toBe(true);
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue