mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
chore(homarr): onboard started, OIDC configured, DB created
- Homarr OIDC env vars set (sso-homarr) - Database created at /data/db.sqlite - Config schema updated to v2 - Onboard wizard needs final UI completion Build: 3313 jobs, 0 errors
This commit is contained in:
parent
6977d40ebe
commit
40c97cf21e
14 changed files with 384 additions and 0 deletions
35
4-Infrastructure/k3s-flake/tests/homarr-account.spec.ts
Normal file
35
4-Infrastructure/k3s-flake/tests/homarr-account.spec.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr account form', async ({ page }) => {
|
||||
test.setTimeout(20000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Navigate to account creation
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('button').forEach(b => {
|
||||
if (b.textContent?.includes('Start update process')) b.click();
|
||||
});
|
||||
});
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
// Dump all inputs and their labels
|
||||
const inputs = await page.locator('input, select, textarea').all();
|
||||
console.log(`Found ${inputs.length} inputs`);
|
||||
for (const inp of inputs) {
|
||||
const id = await inp.getAttribute('id');
|
||||
const name = await inp.getAttribute('name');
|
||||
const placeholder = await inp.getAttribute('placeholder');
|
||||
const type = await inp.getAttribute('type');
|
||||
const label = await page.locator(`label[for="${id}"]`).textContent().catch(() => '');
|
||||
console.log(` id=${id} type=${type} name=${name} placeholder=${placeholder} label=${label}`);
|
||||
}
|
||||
|
||||
// Also check what elements with role and text
|
||||
const texts = await page.locator('h1,h2,h3,p,label,span').all();
|
||||
for (const el of texts) {
|
||||
const text = await el.textContent();
|
||||
if (text?.trim() && text.trim().length > 2 && text.trim().length < 100) {
|
||||
console.log(`Text: "${text.trim()}"`);
|
||||
}
|
||||
}
|
||||
});
|
||||
49
4-Infrastructure/k3s-flake/tests/homarr-complete.spec.ts
Normal file
49
4-Infrastructure/k3s-flake/tests/homarr-complete.spec.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Homarr full onboard', async ({ page }) => {
|
||||
test.setTimeout(120000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Step 1: Click start
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('button').forEach(b => {
|
||||
if (b.textContent?.includes('Start update process')) b.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
});
|
||||
});
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('Step 1 - Start clicked');
|
||||
|
||||
// Check what inputs are available
|
||||
const inputs = await page.locator('input').count();
|
||||
console.log(`Found ${inputs} inputs`);
|
||||
|
||||
if (inputs > 0) {
|
||||
await page.locator('input').nth(0).fill('admin');
|
||||
if (inputs > 1) await page.locator('input').nth(1).fill('admin@researchstack.info');
|
||||
if (inputs > 2) await page.locator('input').nth(2).fill('homarr-admin');
|
||||
console.log('Form filled');
|
||||
}
|
||||
|
||||
// Click Continue
|
||||
const continueBtn = page.locator('button:has-text("Continue"):visible').first();
|
||||
if (await continueBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await continueBtn.click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('Continue clicked');
|
||||
}
|
||||
|
||||
// Continue clicking "Continue" or "Finish" through remaining steps
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const btn = page.locator('button:has-text("Continue"):visible, button:has-text("Finish"):visible, button:has-text("Next"):visible').first();
|
||||
if (await btn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await btn.click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(`Step ${i+2} clicked, URL: ${page.url()}`);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Final URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-complete.png' });
|
||||
});
|
||||
18
4-Infrastructure/k3s-flake/tests/homarr-debug2.spec.ts
Normal file
18
4-Infrastructure/k3s-flake/tests/homarr-debug2.spec.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr2', async ({ page }) => {
|
||||
test.setTimeout(20000);
|
||||
console.log('Going...');
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
console.log('Loaded');
|
||||
await page.waitForTimeout(2000);
|
||||
console.log('Finding button...');
|
||||
const btn = page.locator('button:has-text("Start update process"):visible').first();
|
||||
const visible = await btn.isVisible({ timeout: 3000 }).catch(() => false);
|
||||
console.log('Visible:', visible);
|
||||
if (visible) {
|
||||
console.log('Clicking...');
|
||||
await btn.click();
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('Clicked, URL:', page.url());
|
||||
}
|
||||
});
|
||||
26
4-Infrastructure/k3s-flake/tests/homarr-dispatch.spec.ts
Normal file
26
4-Infrastructure/k3s-flake/tests/homarr-dispatch.spec.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr dispatch', async ({ page }) => {
|
||||
test.setTimeout(20000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
// Try clicking via JavaScript dispatch
|
||||
await page.evaluate(() => {
|
||||
const buttons = document.querySelectorAll('button');
|
||||
for (const btn of buttons) {
|
||||
if (btn.textContent?.includes('Start update process')) {
|
||||
btn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
await page.waitForTimeout(5000);
|
||||
console.log('URL:', page.url());
|
||||
|
||||
// Check for new buttons
|
||||
const btns = await page.locator('button').all();
|
||||
for (const b of btns) {
|
||||
const text = await b.textContent();
|
||||
if (await b.isVisible()) console.log(` "${text?.trim().substring(0,40)}"`);
|
||||
}
|
||||
});
|
||||
44
4-Infrastructure/k3s-flake/tests/homarr-final-setup.spec.ts
Normal file
44
4-Infrastructure/k3s-flake/tests/homarr-final-setup.spec.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Homarr complete setup', async ({ page }) => {
|
||||
test.setTimeout(120000);
|
||||
|
||||
// Step 1: Load page
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Step 2: Click "Start update process"
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('button').forEach(b => {
|
||||
if (b.textContent?.includes('Start update process')) b.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
});
|
||||
});
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// Step 3: Fill account form
|
||||
await page.locator('input[type="text"]').first().fill('admin');
|
||||
const passwordInputs = page.locator('input[type="password"]');
|
||||
await passwordInputs.nth(0).fill('homarr-admin');
|
||||
await passwordInputs.nth(1).fill('homarr-admin');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Click Continue
|
||||
await page.locator('button:has-text("Continue"):visible').first().click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('Account created');
|
||||
|
||||
// Step 4: Continue through remaining steps
|
||||
for (let i = 0; i < 15; i++) {
|
||||
const btn = page.locator('button:has-text("Continue"):visible, button:has-text("Finish"):visible').first();
|
||||
if (await btn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await btn.click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(`Step ${i + 2}: ${page.url()}`);
|
||||
} else {
|
||||
console.log(`No more buttons at step ${i + 2}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Final URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-complete.png' });
|
||||
});
|
||||
22
4-Infrastructure/k3s-flake/tests/homarr-final.spec.ts
Normal file
22
4-Infrastructure/k3s-flake/tests/homarr-final.spec.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Homarr final', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
for (const text of ["Start update process", "Next", "Next", "Next", "Finish"]) {
|
||||
const btn = page.locator(`button:has-text("${text}"):visible`).first();
|
||||
if (await btn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await btn.click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(`Clicked "${text}"`);
|
||||
} else {
|
||||
console.log(`Button "${text}" not found`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
console.log('Final URL:', page.url());
|
||||
await page.screenshot({ path: '/tmp/homarr-final.png' });
|
||||
});
|
||||
26
4-Infrastructure/k3s-flake/tests/homarr-form-debug.spec.ts
Normal file
26
4-Infrastructure/k3s-flake/tests/homarr-form-debug.spec.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('form debug', async ({ page }) => {
|
||||
test.setTimeout(20000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('button').forEach(b => {
|
||||
if (b.textContent?.includes('Start update process')) b.click();
|
||||
});
|
||||
});
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
// Check ALL input types
|
||||
console.log('input[type=text]:', await page.locator('input[type="text"]').count());
|
||||
console.log('input[type=password]:', await page.locator('input[type="password"]').count());
|
||||
console.log('input[type=email]:', await page.locator('input[type="email"]').count());
|
||||
console.log('input:not([type]):', await page.locator('input:not([type])').count());
|
||||
console.log('All inputs:', await page.locator('input').count());
|
||||
console.log('[contenteditable]:', await page.locator('[contenteditable]').count());
|
||||
|
||||
// Dump all input HTML
|
||||
const html = await page.content();
|
||||
const inputMatches = html.match(/<input[^>]*>/g) || [];
|
||||
console.log('Input HTML elements found:', inputMatches.length);
|
||||
for (const m of inputMatches.slice(0,5)) console.log(' ' + m.substring(0,120));
|
||||
});
|
||||
17
4-Infrastructure/k3s-flake/tests/homarr-inputs.spec.ts
Normal file
17
4-Infrastructure/k3s-flake/tests/homarr-inputs.spec.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr inputs', async ({ page }) => {
|
||||
test.setTimeout(20000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
// Check for all interactive elements
|
||||
for (const type of ['input', 'select', 'textarea', '[role="button"]', '[role="checkbox"]', '[type="checkbox"]']) {
|
||||
const els = page.locator(type);
|
||||
const count = await els.count();
|
||||
if (count > 0) console.log(`Found ${count} ${type}`);
|
||||
}
|
||||
|
||||
// Check what's inside forms
|
||||
const forms = page.locator('form').count();
|
||||
console.log(`Forms: ${await forms}`);
|
||||
});
|
||||
20
4-Infrastructure/k3s-flake/tests/homarr-network.spec.ts
Normal file
20
4-Infrastructure/k3s-flake/tests/homarr-network.spec.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr network', async ({ page }) => {
|
||||
test.setTimeout(20000);
|
||||
|
||||
// Listen for API requests
|
||||
const requests: string[] = [];
|
||||
page.on('request', req => {
|
||||
if (req.url().includes('/api')) requests.push(req.url() + ' ' + req.method());
|
||||
});
|
||||
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const btn = page.locator('button:has-text("Start update process"):visible').first();
|
||||
await btn.click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
console.log('Requests:', requests.join('\n '));
|
||||
console.log('URL:', page.url());
|
||||
});
|
||||
29
4-Infrastructure/k3s-flake/tests/homarr-onboard.spec.ts
Normal file
29
4-Infrastructure/k3s-flake/tests/homarr-onboard.spec.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Homarr onboarding', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000 });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Click "Start update process"
|
||||
const startBtn = page.locator('button:has-text("Start update process"):visible').first();
|
||||
if (await startBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await startBtn.click();
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('Step 1 clicked');
|
||||
}
|
||||
|
||||
// Continue through steps
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const nextBtn = page.locator('button:has-text("Next"):visible, button:has-text("Continue"):visible, button:has-text("Finish"):visible, button[data-button="true"]:visible').first();
|
||||
if (await nextBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await nextBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(`Step ${i+2} clicked`);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await page.screenshot({ path: '/tmp/homarr-done.png' });
|
||||
console.log('Onboarding complete');
|
||||
});
|
||||
22
4-Infrastructure/k3s-flake/tests/homarr-setup.spec.ts
Normal file
22
4-Infrastructure/k3s-flake/tests/homarr-setup.spec.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Homarr setup', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Click buttons with force (don't wait for navigation)
|
||||
for (const text of ["Start update process", "Next", "Next", "Next", "Finish"]) {
|
||||
const btn = page.locator(`button:has-text("${text}"):visible`).first();
|
||||
if (await btn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await btn.click({ force: true, timeout: 5000 });
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(`Clicked "${text}"`);
|
||||
} else {
|
||||
console.log(`Button "${text}" not found at step`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await page.screenshot({ path: '/tmp/homarr-done.png' });
|
||||
console.log('Done at:', page.url());
|
||||
});
|
||||
15
4-Infrastructure/k3s-flake/tests/homarr-step2.spec.ts
Normal file
15
4-Infrastructure/k3s-flake/tests/homarr-step2.spec.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr step 2', async ({ page }) => {
|
||||
test.setTimeout(30000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator('button:has-text("Start update process"):visible').first().click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(5000);
|
||||
console.log('URL:', page.url());
|
||||
|
||||
// Dump all buttons
|
||||
for (const b of await page.locator('button').all()) {
|
||||
const text = await b.textContent();
|
||||
if (await b.isVisible()) console.log(` Visible: "${text?.trim().substring(0,40)}"`);
|
||||
}
|
||||
});
|
||||
14
4-Infrastructure/k3s-flake/tests/homarr-test.spec.ts
Normal file
14
4-Infrastructure/k3s-flake/tests/homarr-test.spec.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('homarr test', async ({ page }) => {
|
||||
test.setTimeout(30000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(5000);
|
||||
const title = await page.title();
|
||||
console.log('Title:', title);
|
||||
const buttons = await page.locator('button').count();
|
||||
console.log(`Found ${buttons} buttons`);
|
||||
for (const b of await page.locator('button').all()) {
|
||||
const text = await b.textContent();
|
||||
console.log(` Button: "${text?.trim().substring(0,30)}" visible=${await b.isVisible()}`);
|
||||
}
|
||||
});
|
||||
47
4-Infrastructure/k3s-flake/tests/homarr-wizard.spec.ts
Normal file
47
4-Infrastructure/k3s-flake/tests/homarr-wizard.spec.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Homarr wizard', async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
await page.goto('http://100.88.57.96:30093/', { timeout: 10000, waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
// Step 1: Start update
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('button').forEach(b => {
|
||||
if (b.textContent?.trim() === 'Start update process') b.click();
|
||||
});
|
||||
});
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// Step 2: Fill account form with valid password
|
||||
await page.locator('input[type="text"]').first().fill('admin');
|
||||
const pwInputs = page.locator('input[type="password"]');
|
||||
await pwInputs.nth(0).fill('Admin123!');
|
||||
await pwInputs.nth(1).fill('Admin123!');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Click Continue
|
||||
await page.locator('button:has-text("Continue"):visible').first().click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(5000);
|
||||
console.log('Step 1 done, URL:', page.url());
|
||||
|
||||
// Keep clicking Continue/Finish through remaining steps
|
||||
for (let step = 2; step <= 10; step++) {
|
||||
const btn = page.locator('button:has-text("Continue"):visible, button:has-text("Finish"):visible').first();
|
||||
if (await btn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await btn.click({ force: true, noWaitAfter: true });
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(`Step ${step}: ${page.url()}`);
|
||||
} else {
|
||||
console.log(`No more buttons at step ${step}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await page.screenshot({ path: '/tmp/homarr-final.png' });
|
||||
console.log('Final URL:', page.url());
|
||||
|
||||
// Check if we got redirected away from onboard
|
||||
if (!page.url().includes('onboard')) {
|
||||
console.log('SUCCESS: Onboard completed!');
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue