Files
MyManagingTools/tests/conftest.py

200 lines
5.8 KiB
Python

from io import BytesIO
import subprocess
import pandas as pd
import pytest
import requests
import time
import sys
import os
from pathlib import Path
from components.datagrid.DataGrid import reset_instances
from playwright_config import BROWSER_CONFIG, BASE_URL
from tests.fixtures.test_database import TestDatabaseManager
from tests.fixtures.test_users import TestUsers
USER_EMAIL = "test@mail.com"
USER_ID = "test_user"
APP_PORT = 5002
@pytest.fixture(scope="session")
def test_database():
"""Configure temporary database for tests"""
# Create temporary DB
temp_db_path = TestDatabaseManager.create_temp_db_path()
# Save original environment
original_env = {
"DB_PATH": os.environ.get("DB_PATH"),
"ADMIN_EMAIL": os.environ.get("ADMIN_EMAIL"),
"ADMIN_PASSWORD": os.environ.get("ADMIN_PASSWORD"),
"SECRET_KEY": os.environ.get("SECRET_KEY")
}
# Configure test environment
TestDatabaseManager.setup_test_environment(temp_db_path)
print(f"Test database created at: {temp_db_path}")
yield temp_db_path
# Cleanup: restore environment and clean up DB
TestDatabaseManager.restore_original_environment(original_env)
TestDatabaseManager.cleanup_test_db(temp_db_path)
print(f"Test database cleaned up: {temp_db_path}")
@pytest.fixture(scope="session")
def test_users():
"""Define available test users"""
return {
"admin": TestUsers.ADMIN,
"regular_user": TestUsers.REGULAR_USER,
"invalid_cases": TestUsers.INVALID_CREDENTIALS,
"protected_urls": TestUsers.PROTECTED_URLS
}
@pytest.fixture(scope="session")
def app_server(test_database, test_users):
"""Start application server with test database"""
# Use the same Python executable that's running pytest
python_executable = sys.executable
# Get the absolute path to the src directory
project_root = Path(__file__).parent.parent
src_path = project_root / "src"
# Create test environment
test_env = os.environ.copy()
test_env["DB_PATH"] = test_database
test_env["ADMIN_EMAIL"] = test_users["admin"]["email"]
test_env["ADMIN_PASSWORD"] = test_users["admin"]["password"]
test_env["SECRET_KEY"] = "test-secret-key-for-e2e-tests"
# Start the application server
print(f"Starting server on url {BASE_URL} with test database...")
port = BASE_URL.split(':')[-1].split('/')[0] if ':' in BASE_URL else APP_PORT
print(f"Using port {port}")
print(f"Test DB path: {test_database}")
server_process = subprocess.Popen(
[python_executable, "main.py", "--port", "5002"],
cwd=str(src_path), # Change to src directory where main.py is located
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=test_env # Use test environment
)
# Wait for the server to start
max_retries = 10 # Wait up to 30 seconds
for i in range(max_retries):
try:
print(f"Waiting retry {i}/{max_retries}")
response = requests.get(BASE_URL, timeout=1)
if response.status_code in [200, 302, 404]: # Server is responding
print(f"Server started successfully after {i + 1} attempts")
break
except requests.exceptions.RequestException:
time.sleep(1)
else:
# If we get here, the server didn't start in time
print(f"Failed to start after {max_retries} attempts.")
server_process.kill()
stdout, stderr = server_process.communicate()
raise RuntimeError(
f"Server failed to start within {max_retries} seconds.\n"
f"STDOUT: {stdout.decode()}\n"
f"STDERR: {stderr.decode()}"
)
# Yield control to the tests
print('Test server started with isolated database!')
yield server_process
# Cleanup: terminate the server after tests
server_process.terminate()
try:
server_process.wait(timeout=5)
print('Test server stopped.')
except subprocess.TimeoutExpired:
server_process.kill()
server_process.wait()
print('Test server killed!')
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
"""Configure browser context arguments"""
return {
**browser_context_args,
**BROWSER_CONFIG,
"record_video_dir": "test-results/videos/",
"record_har_path": "test-results/har/trace.har",
"record_video_size": {"width": 1280, "height": 720},
}
@pytest.fixture(scope="session")
def app_url():
"""Base URL for the application"""
return BASE_URL
@pytest.fixture
def excel_file_content():
# Create a simple Excel file in memory
df = pd.DataFrame({
'Column 1': ['Aba', 'Johan', 'Kodjo'],
'Column 2': ['Female', 'Male', 'Male']
})
excel_io = BytesIO()
df.to_excel(excel_io, index=False)
excel_io.seek(0)
return excel_io.read()
@pytest.fixture
def excel_file_content_2():
# Create a simple Excel file in memory
df = pd.DataFrame({
'Column 1': ['C', 'A', 'B'],
'Column 2': [1, 2, 3]
})
excel_io = BytesIO()
df.to_excel(excel_io, index=False)
excel_io.seek(0)
return excel_io.read()
@pytest.fixture
def excel_file_content_with_sheet_name():
# Create a DataFrame
df = pd.DataFrame({
'Column 1 ': ['Aba', 'Johan', 'Kodjo'],
'Column 2': [False, True, True],
'Column 3 ': [10, 20, 30],
})
# Create an in-memory bytes buffer
excel_io = BytesIO()
# Write the dataframe to the buffer with a custom sheet name
df.to_excel(excel_io, index=False, sheet_name="sheet_name")
# Move the pointer to the start of the stream
excel_io.seek(0)
return excel_io.read() # Return the binary data
@pytest.fixture(autouse=True)
def reset_datagrid_instances():
reset_instances()
@pytest.fixture
def session():
return {"user_id": USER_ID, "user_email": USER_EMAIL}