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
This commit is contained in:
192
reports-app/frontend/tests/e2e/button-fix-test.spec.js
Normal file
192
reports-app/frontend/tests/e2e/button-fix-test.spec.js
Normal file
@@ -0,0 +1,192 @@
|
||||
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');
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user