Add scheduler improvements, API endpoints, and month calendar view
Backend: - Add /api/customers/ endpoint (CustomerViewSet, CustomerSerializer) - Add /api/services/ endpoint with Service model and migrations - Add Resource.type field (STAFF, ROOM, EQUIPMENT) with migration - Fix EventSerializer to return resource_id, customer_id, service_id - Add date range filtering to EventViewSet (start_date, end_date params) - Add create_demo_appointments management command - Set default brand colors in business API Frontend: - Add calendar grid view for month mode in OwnerScheduler - Fix sidebar navigation active link contrast (bg-white/10) - Add default primaryColor/secondaryColor fallbacks in useBusiness - Disable WebSocket (backend not implemented) to stop reconnect loop - Fix Resource.type.toLowerCase() error by adding type to backend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
97
frontend/tests/e2e/business-owner-login.spec.ts
Normal file
97
frontend/tests/e2e/business-owner-login.spec.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('business owner login flow', async ({ page }) => {
|
||||
// Enable console logging
|
||||
page.on('console', msg => {
|
||||
const type = msg.type();
|
||||
const text = msg.text();
|
||||
// Only log errors, warnings, and our custom debug logs
|
||||
if (type === 'error' || type === 'warning' || text.includes('Failed to')) {
|
||||
console.log(`BROWSER ${type.toUpperCase()}:`, text);
|
||||
}
|
||||
});
|
||||
|
||||
// Enable error logging
|
||||
page.on('pageerror', error => {
|
||||
console.error('PAGE ERROR:', error.message);
|
||||
console.error('STACK:', error.stack);
|
||||
});
|
||||
|
||||
// Track network errors
|
||||
page.on('requestfailed', request => {
|
||||
console.error('REQUEST FAILED:', request.url(), request.failure()?.errorText);
|
||||
});
|
||||
|
||||
// Go to the login page
|
||||
console.log('Navigating to login page...');
|
||||
await page.goto('http://lvh.me:5173/#/login');
|
||||
|
||||
// Wait for the page to load
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Take screenshot of initial state
|
||||
await page.screenshot({ path: 'test-results/01-initial-page.png', fullPage: true });
|
||||
|
||||
// Check if DevQuickLogin component loaded
|
||||
const quickLoginVisible = await page.locator('text=Quick Login (Dev Only)').isVisible().catch(() => false);
|
||||
console.log('Quick Login visible:', quickLoginVisible);
|
||||
|
||||
if (quickLoginVisible) {
|
||||
// Click the Business Owner button
|
||||
console.log('Clicking Business Owner button...');
|
||||
await page.click('button:has-text("Business Owner")');
|
||||
|
||||
// Wait for navigation or changes
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Take screenshot after clicking
|
||||
await page.screenshot({ path: 'test-results/02-after-click.png', fullPage: true });
|
||||
|
||||
// Check the current URL
|
||||
const currentUrl = page.url();
|
||||
console.log('Current URL:', currentUrl);
|
||||
|
||||
// Check if #root has content
|
||||
const rootContent = await page.locator('#root').innerHTML();
|
||||
console.log('Root content length:', rootContent.length);
|
||||
console.log('Root content:', rootContent.substring(0, 500));
|
||||
|
||||
// Check full page HTML if root is empty
|
||||
if (rootContent.length === 0) {
|
||||
const bodyContent = await page.locator('body').innerHTML();
|
||||
console.log('\nFull body HTML (first 1000 chars):');
|
||||
console.log(bodyContent.substring(0, 1000));
|
||||
|
||||
// Check for script tags
|
||||
const scripts = await page.locator('script').count();
|
||||
console.log('\nNumber of script tags:', scripts);
|
||||
|
||||
// Evaluate JavaScript in the page context to check for errors
|
||||
const jsErrors = await page.evaluate(() => {
|
||||
// Check if React root exists
|
||||
const root = document.getElementById('root');
|
||||
return {
|
||||
rootExists: !!root,
|
||||
rootHasChildren: root ? root.childNodes.length : 0,
|
||||
documentReady: document.readyState,
|
||||
};
|
||||
});
|
||||
console.log('\nJS Context:', JSON.stringify(jsErrors, null, 2));
|
||||
}
|
||||
|
||||
// Check for React errors
|
||||
const hasReactError = await page.locator('text=/error|failed/i').count();
|
||||
console.log('\nError count on page:', hasReactError);
|
||||
|
||||
} else {
|
||||
console.log('Quick Login component not found. Page content:');
|
||||
const bodyText = await page.locator('body').textContent();
|
||||
console.log(bodyText?.substring(0, 1000));
|
||||
}
|
||||
|
||||
// Wait a bit more to see what happens
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Final screenshot
|
||||
await page.screenshot({ path: 'test-results/03-final-state.png', fullPage: true });
|
||||
});
|
||||
Reference in New Issue
Block a user