Files
roa2web-service-auto/reports-app/frontend/tests/e2e/button-fix-test.spec.js
Marius Mutu 6b13ffa183 Initial commit: ROA2WEB - FastAPI + Vue.js + Telegram Bot
Modern ERP Reports Application with microservices architecture

Tech Stack:
- Backend: FastAPI + python-oracledb (Oracle DB integration)
- Frontend: Vue.js 3 + PrimeVue + Vite
- Telegram Bot: python-telegram-bot + SQLite
- Infrastructure: Shared database pool, JWT authentication, SSH tunnel

Features:
- FastAPI backend with async Oracle connection pool
- Vue.js 3 responsive frontend with PrimeVue components
- Telegram bot alternative interface
- Microservices architecture with shared components
- Complete deployment support (Linux Docker + Windows IIS)
- Comprehensive testing (Playwright E2E + pytest)

Repository Structure:
- reports-app/ - Main application (backend, frontend, telegram-bot)
- shared/ - Shared components (database pool, auth, utils)
- deployment/ - Deployment scripts (Linux & Windows)
- docs/ - Project documentation
- security/ - Security scanning and git hooks
2025-10-25 14:55:08 +03:00

192 lines
6.9 KiB
JavaScript

import { test, expect } from '@playwright/test';
import { LoginPage } from '../page-objects/LoginPage.js';
test.describe('🔧 Button Fix Test - Identify Disabled State Issue', () => {
let loginPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.navigate();
});
test('🐛 Debug Button Disabled State Logic', async ({ page }) => {
console.log('\n=== DEBUGGING BUTTON DISABLED STATE ===');
// Helper function to get detailed button state
const getButtonState = async () => {
return await page.evaluate(() => {
const usernameInput = document.getElementById('username');
const passwordInput = document.querySelector('#password input');
const button = document.querySelector('button[type="submit"]');
// Get Vue component data if available
const vueApp = document.querySelector('#app').__vue__;
let vueData = null;
try {
// Try to access Vue component state
const loginComponent = document.querySelector('.login-container').__vueParentComponent;
if (loginComponent && loginComponent.setupState) {
vueData = {
credentials: loginComponent.setupState.credentials?.value,
formErrors: loginComponent.setupState.formErrors?.value,
isFormValid: loginComponent.setupState.isFormValid?.value
};
}
} catch (e) {
console.log('Could not access Vue state:', e.message);
}
return {
dom: {
usernameValue: usernameInput?.value || '',
passwordValue: passwordInput?.value || '',
buttonDisabled: button?.disabled,
buttonClasses: button?.className,
usernameRequired: usernameInput?.required,
passwordRequired: passwordInput?.required
},
vue: vueData
};
});
};
// Test 1: Initial state
console.log('\n--- Test 1: Initial State ---');
let state = await getButtonState();
console.log('Initial state:', JSON.stringify(state, null, 2));
// Test 2: Fill only username
console.log('\n--- Test 2: Username Only ---');
await page.fill('#username', 'test_user');
await page.waitForTimeout(500); // Wait for Vue reactivity
state = await getButtonState();
console.log('Username only state:', JSON.stringify(state, null, 2));
// Test 3: Fill both fields
console.log('\n--- Test 3: Both Fields ---');
await page.fill('#password input', 'test_password');
await page.waitForTimeout(500); // Wait for Vue reactivity
state = await getButtonState();
console.log('Both fields state:', JSON.stringify(state, null, 2));
// Test 4: Check if validation triggers
console.log('\n--- Test 4: Trigger Validation ---');
await page.click('.login-card'); // Click outside to blur
await page.waitForTimeout(500);
state = await getButtonState();
console.log('After blur state:', JSON.stringify(state, null, 2));
// Test 5: Manual button click attempt
console.log('\n--- Test 5: Button Click Attempt ---');
const isClickable = await page.evaluate(() => {
const button = document.querySelector('button[type="submit"]');
return !button.disabled;
});
console.log('Button is clickable:', isClickable);
if (isClickable) {
console.log('✅ Button should be clickable');
} else {
console.log('❌ Button is still disabled - investigating why...');
// Check validation logic
const validationState = await page.evaluate(() => {
const usernameInput = document.getElementById('username');
const passwordInput = document.querySelector('#password input');
return {
usernameEmpty: !usernameInput.value.trim(),
passwordEmpty: !passwordInput.value.trim(),
usernameLength: usernameInput.value.length,
passwordLength: passwordInput.value.length,
formValidity: usernameInput.form?.checkValidity()
};
});
console.log('Validation details:', JSON.stringify(validationState, null, 2));
}
// Take screenshot for analysis
await page.screenshot({ path: 'button-debug.png', fullPage: true });
});
test('🔄 Test Button Reactivity with Real Input', async ({ page }) => {
console.log('\n=== TESTING BUTTON REACTIVITY ===');
// Monitor button state changes
const buttonStates = [];
const checkButton = async (action) => {
const disabled = await page.locator('button[type="submit"]').isDisabled();
buttonStates.push({ action, disabled });
console.log(`After ${action}: disabled = ${disabled}`);
};
await checkButton('initial load');
// Type character by character to see when button enables
const username = 'test';
const password = 'pass';
for (let i = 0; i < username.length; i++) {
await page.fill('#username', username.substring(0, i + 1));
await page.waitForTimeout(100);
await checkButton(`username: "${username.substring(0, i + 1)}"`);
}
for (let i = 0; i < password.length; i++) {
await page.fill('#password input', password.substring(0, i + 1));
await page.waitForTimeout(100);
await checkButton(`password: "${password.substring(0, i + 1)}"`);
}
console.log('\nButton state progression:');
buttonStates.forEach((state, index) => {
console.log(`${index + 1}. ${state.action}: ${state.disabled ? 'DISABLED' : 'ENABLED'}`);
});
});
test('🎯 Force Button Enable Test', async ({ page }) => {
console.log('\n=== TESTING FORCED BUTTON ENABLE ===');
// Fill valid data
await page.fill('#username', 'valid_user');
await page.fill('#password input', 'valid_password');
// Wait for Vue reactivity
await page.waitForTimeout(1000);
// Force enable button via JavaScript if needed
const buttonEnabled = await page.evaluate(() => {
const button = document.querySelector('button[type="submit"]');
const wasDisabled = button.disabled;
// Try to force enable for testing
button.disabled = false;
button.classList.remove('p-disabled');
return { wasDisabled, nowDisabled: button.disabled };
});
console.log('Button enable attempt:', buttonEnabled);
if (!buttonEnabled.nowDisabled) {
console.log('✅ Button was successfully enabled');
// Try to click it now
await page.click('button[type="submit"]');
console.log('✅ Button click succeeded');
// Wait for potential API call
await page.waitForTimeout(2000);
// Check if login was attempted
const currentUrl = page.url();
console.log('Current URL after click:', currentUrl);
} else {
console.log('❌ Could not enable button');
}
});
});