fix: login/signup flow working with session-based auth

- Fixed hashPasswordIO to use real PBKDF2 hashing from Sis.Auth
- Added seed route (rseed) for demo data initialization
- Replaced redirect() in update functions with success views
  (redirect uses throwError_ which broke with effectful 2.4)
- Added loginSuccessView and signupSuccessView with dashboard links
- Patched Hyperbole Socket.hs to parse WebSocket form body into Form params
- Patched Hyperbole Wai.hs to include TargetViewId in response metadata
- Fixed View/Page type mismatches (hyper wrapper vs plain view)
- Removed dead pure after redirect calls
- Verified: login submits, session set, success view rendered
This commit is contained in:
2026-07-16 07:27:31 -04:00
parent a99c239852
commit 456eae4717
13 changed files with 207 additions and 18 deletions
+58
View File
@@ -0,0 +1,58 @@
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
// Collect console and page errors
const errors = [];
page.on('console', msg => { if (msg.type() === 'error') errors.push(msg.text()); });
page.on('pageerror', err => errors.push(err.message));
// Test 1: Load login page
console.log("=== Test 1: Load login page ===");
await page.goto('http://localhost:8080/rlogin', { waitUntil: 'networkidle' });
const title = await page.title();
console.log("Title:", title);
const hasForm = await page.$('form') !== null;
console.log("Has form:", hasForm);
const hasWelcome = (await page.content()).includes('Welcome Back');
console.log("Has Welcome:", hasWelcome);
if (errors.length > 0) {
console.log("Errors on load:", errors);
}
// Test 2: Fill and submit login form
console.log("\n=== Test 2: Submit login form ===");
await page.fill('input[name="lfEmail"]', 'alice@demo.com');
await page.fill('input[name="lfPassword"]', 'password123');
await page.check('input[name="lfRemember"]');
// Listen for response
const [response] = await Promise.all([
page.waitForResponse(resp => resp.url().includes('/rlogin'), { timeout: 5000 }).catch(() => null),
page.click('button[type="submit"]')
]);
console.log("Response status:", response ? response.status() : 'no response');
// Wait for navigation or content change
await page.waitForTimeout(2000);
const content = await page.content();
console.log("Page contains 'Dashboard':", content.includes('Dashboard') || content.includes('Overdue'));
console.log("Page contains error:", content.includes('Invalid') || content.includes('error'));
if (errors.length > 0) {
console.log("Errors after submit:", errors);
}
// Test 3: Try signup
console.log("\n=== Test 3: Load signup page ===");
await page.goto('http://localhost:8080/rsignup', { waitUntil: 'networkidle' });
const hasCreate = (await page.content()).includes('Create Account');
console.log("Has Create Account:", hasCreate);
await browser.close();
console.log("\nDone.");
})().catch(e => { console.error("Test failed:", e.message); process.exit(1); });