mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-08-18 09:10:34 +00:00
118 lines
4.6 KiB
TypeScript
118 lines
4.6 KiB
TypeScript
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' });
|
|
}
|
|
}
|
|
|
|
// Force NextAuth OIDC authentication by navigating to the login URL
|
|
console.log('Navigating directly to /auth/login to trigger OIDC session sync...');
|
|
await page.goto('https://researchstack.info/auth/login');
|
|
await page.waitForTimeout(6000);
|
|
|
|
// If Authentik consent/authorization screen appears after navigating to login
|
|
if (page.url().includes('consent') || page.url().includes('authorize') || page.url().includes('application/o/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({ timeout: 5000 }).catch(() => false)) {
|
|
await continueBtn.click();
|
|
await page.waitForTimeout(6000);
|
|
}
|
|
}
|
|
|
|
// Navigate back to the home board
|
|
console.log('Navigating back to home board...');
|
|
await page.goto('https://researchstack.info/');
|
|
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);
|
|
}
|
|
});
|