404 lines
16 KiB
Python
404 lines
16 KiB
Python
import pytest
|
|
from selenium import webdriver
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.webdriver.chrome.options import Options
|
|
import time
|
|
from selenium.webdriver.common.keys import Keys
|
|
|
|
@pytest.fixture(scope="function")
|
|
def driver():
|
|
"""Create a new browser instance for each test"""
|
|
chrome_options = Options()
|
|
chrome_options.add_argument("--headless")
|
|
chrome_options.add_argument("--no-sandbox")
|
|
chrome_options.add_argument("--disable-dev-shm-usage")
|
|
chrome_options.add_argument("--disable-gpu")
|
|
|
|
driver = webdriver.Chrome(options=chrome_options)
|
|
driver.implicitly_wait(10)
|
|
yield driver
|
|
driver.quit()
|
|
|
|
# calculator_page fixture is now defined in conftest.py
|
|
|
|
class TestCalculatorNavigation:
|
|
"""Test calculator navigation and basic functionality"""
|
|
|
|
def test_debug_page_content(self, driver):
|
|
"""Debug test to see what's actually on the page"""
|
|
driver.get("http://localhost:8008")
|
|
|
|
# Wait for basic page structure
|
|
WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.CLASS_NAME, "sidenav"))
|
|
)
|
|
|
|
# Print page title and basic info
|
|
print(f"\nPage title: {driver.title}")
|
|
print(f"Current URL: {driver.current_url}")
|
|
|
|
# Check if sidenav has any content
|
|
sidenav = driver.find_element(By.CLASS_NAME, "sidenav")
|
|
print(f"Sidenav HTML: {sidenav.get_attribute('innerHTML')}")
|
|
|
|
# Check for JavaScript errors in console
|
|
logs = driver.get_log('browser')
|
|
if logs:
|
|
print(f"\nBrowser console logs:")
|
|
for log in logs:
|
|
print(f" {log['level']}: {log['message']}")
|
|
|
|
# Check if app.js loaded
|
|
try:
|
|
app_js = driver.find_element(By.XPATH, "//script[@src='/js/app.js']")
|
|
print(f"App.js script tag found: {app_js.get_attribute('outerHTML')}")
|
|
except:
|
|
print("App.js script tag NOT found!")
|
|
|
|
# Wait a bit longer and check again
|
|
time.sleep(3)
|
|
sidenav_after_wait = driver.find_element(By.CLASS_NAME, "sidenav")
|
|
print(f"Sidenav HTML after 3s wait: {sidenav_after_wait.get_attribute('innerHTML')}")
|
|
|
|
# This test should always pass for debugging
|
|
assert True
|
|
|
|
def test_page_loads(self, calculator_page):
|
|
"""Test that the calculator page loads correctly"""
|
|
assert "calculator.127local.net" in calculator_page.title
|
|
assert calculator_page.find_element(By.CLASS_NAME, "sidenav")
|
|
assert calculator_page.find_element(By.CLASS_NAME, "content")
|
|
|
|
def test_calculator_list(self, calculator_page):
|
|
"""Test that all calculators are listed in navigation"""
|
|
nav_items = calculator_page.find_elements(By.CSS_SELECTOR, ".sidenav a")
|
|
calculator_names = [item.text for item in nav_items]
|
|
|
|
expected_calculators = [
|
|
"Interest (Simple & Compound)",
|
|
"Bandwidth",
|
|
"NMEA",
|
|
"RAID",
|
|
"Currency Converter"
|
|
]
|
|
|
|
for expected in expected_calculators:
|
|
assert expected in calculator_names, f"Calculator {expected} not found in navigation"
|
|
|
|
class TestInterestCalculator:
|
|
"""Test the Interest calculator functionality"""
|
|
|
|
def test_interest_calculator_loads(self, calculator_page):
|
|
"""Test that interest calculator loads and displays correctly"""
|
|
# Click on interest calculator
|
|
interest_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Interest')]")
|
|
interest_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "principal"))
|
|
)
|
|
|
|
# Check that all inputs are present
|
|
assert calculator_page.find_element(By.NAME, "principal")
|
|
assert calculator_page.find_element(By.NAME, "rate")
|
|
assert calculator_page.find_element(By.NAME, "compound")
|
|
assert calculator_page.find_element(By.NAME, "years")
|
|
assert calculator_page.find_element(By.NAME, "contrib")
|
|
assert calculator_page.find_element(By.NAME, "contribFreq")
|
|
|
|
def test_simple_interest_calculation(self, calculator_page):
|
|
"""Test simple interest calculation"""
|
|
# Load interest calculator
|
|
interest_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Interest')]")
|
|
interest_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "principal"))
|
|
)
|
|
|
|
# Set values for simple interest
|
|
principal_input = calculator_page.find_element(By.NAME, "principal")
|
|
rate_input = calculator_page.find_element(By.NAME, "rate")
|
|
years_input = calculator_page.find_element(By.NAME, "years")
|
|
compound_select = calculator_page.find_element(By.NAME, "compound")
|
|
|
|
principal_input.clear()
|
|
principal_input.send_keys("1000")
|
|
|
|
rate_input.clear()
|
|
rate_input.send_keys("5")
|
|
|
|
years_input.clear()
|
|
years_input.send_keys("3")
|
|
|
|
# Select simple interest (no compounding)
|
|
# Click on the Select Lite button to open dropdown
|
|
compound_button = calculator_page.find_element(By.CSS_SELECTOR, '[name="compound"] + .select-lite__button')
|
|
compound_button.click()
|
|
|
|
# Wait for dropdown to appear and select Simple option
|
|
simple_option = WebDriverWait(calculator_page, 10).until(
|
|
EC.element_to_be_clickable((By.XPATH, "//div[contains(@class, 'select-lite__option') and contains(text(), 'Simple')]"))
|
|
)
|
|
simple_option.click()
|
|
|
|
# Wait for calculation
|
|
time.sleep(1)
|
|
|
|
# Check result
|
|
result = calculator_page.find_element(By.CLASS_NAME, "result")
|
|
assert "Future value:" in result.text
|
|
assert "1,150.00" in result.text # 1000 + (1000 * 0.05 * 3)
|
|
|
|
def test_compound_interest_calculation(self, calculator_page):
|
|
"""Test compound interest calculation"""
|
|
# Load interest calculator
|
|
interest_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Interest')]")
|
|
interest_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "principal"))
|
|
)
|
|
|
|
# Set values for compound interest
|
|
principal_input = calculator_page.find_element(By.NAME, "principal")
|
|
rate_input = calculator_page.find_element(By.NAME, "rate")
|
|
years_input = calculator_page.find_element(By.NAME, "years")
|
|
|
|
principal_input.clear()
|
|
principal_input.send_keys("1000")
|
|
|
|
rate_input.clear()
|
|
rate_input.send_keys("5")
|
|
|
|
years_input.clear()
|
|
years_input.send_keys("3")
|
|
|
|
# Wait for calculation
|
|
time.sleep(1)
|
|
|
|
# Check result (should be higher than simple interest)
|
|
result = calculator_page.find_element(By.CLASS_NAME, "result")
|
|
assert "Future value:" in result.text
|
|
# Compound interest should be > 1150 (simple interest result)
|
|
assert "1,150.00" not in result.text or "1,157.63" in result.text
|
|
|
|
class TestCurrencyConverter:
|
|
"""Test the Currency Converter functionality"""
|
|
|
|
def test_currency_converter_loads(self, calculator_page):
|
|
"""Test that currency converter loads and displays correctly"""
|
|
# Click on currency converter
|
|
currency_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Currency Converter')]")
|
|
currency_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "amount"))
|
|
)
|
|
|
|
# Check that all inputs are present
|
|
assert calculator_page.find_element(By.NAME, "amount")
|
|
assert calculator_page.find_element(By.NAME, "from")
|
|
assert calculator_page.find_element(By.NAME, "to")
|
|
|
|
def test_currency_conversion_same_currency(self, calculator_page):
|
|
"""Test conversion when from and to currencies are the same"""
|
|
# Load currency converter
|
|
currency_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Currency Converter')]")
|
|
currency_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "amount"))
|
|
)
|
|
|
|
# Debug: verify we're on the currency converter
|
|
print(f"Current URL: {calculator_page.current_url}")
|
|
print(f"Page title: {calculator_page.title}")
|
|
|
|
# Check for currency converter specific elements
|
|
try:
|
|
from_select = calculator_page.find_element(By.NAME, "from")
|
|
to_select = calculator_page.find_element(By.NAME, "to")
|
|
print(f"From select value: {from_select.get_attribute('value')}")
|
|
print(f"To select value: {to_select.get_attribute('value')}")
|
|
except Exception as e:
|
|
print(f"Error finding currency elements: {e}")
|
|
|
|
# Set amount
|
|
amount_input = calculator_page.find_element(By.NAME, "amount")
|
|
amount_input.clear()
|
|
amount_input.send_keys("100")
|
|
|
|
# Trigger calculation by changing the amount
|
|
amount_input.send_keys(Keys.TAB)
|
|
|
|
# Wait for calculation to complete
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.CLASS_NAME, "result"))
|
|
)
|
|
|
|
# Wait a bit more for the currency converter to fully load and replace the old result
|
|
time.sleep(1)
|
|
|
|
# Find all result elements and get the one that's actually visible/contains currency content
|
|
result_elements = calculator_page.find_elements(By.CLASS_NAME, "result")
|
|
|
|
# Look for the result element that contains currency-related content
|
|
currency_result = None
|
|
for elem in result_elements:
|
|
html = elem.get_attribute('innerHTML')
|
|
if 'USD' in html or 'EUR' in html or 'Currency' in html or 'conversion' in html.lower():
|
|
currency_result = elem
|
|
break
|
|
|
|
if not currency_result:
|
|
# If no currency result found, use the last result element (most recent)
|
|
currency_result = result_elements[-1]
|
|
|
|
# Check result
|
|
assert "100 USD" in currency_result.text or "100 EUR" in currency_result.text
|
|
|
|
def test_currency_conversion_different_currencies(self, calculator_page):
|
|
"""Test conversion between different currencies"""
|
|
# Load currency converter
|
|
currency_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Currency Converter')]")
|
|
currency_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "amount"))
|
|
)
|
|
|
|
# Set amount
|
|
amount_input = calculator_page.find_element(By.NAME, "amount")
|
|
amount_input.clear()
|
|
amount_input.send_keys("100")
|
|
|
|
# Trigger calculation by changing the amount
|
|
amount_input.send_keys(Keys.TAB)
|
|
|
|
# Wait for calculation and API response
|
|
WebDriverWait(calculator_page, 15).until(
|
|
EC.presence_of_element_located((By.CLASS_NAME, "result"))
|
|
)
|
|
|
|
# Wait a bit more for the currency converter to fully load and replace the old result
|
|
time.sleep(1)
|
|
|
|
# Find all result elements and get the one that's actually visible/contains currency content
|
|
result_elements = calculator_page.find_elements(By.CLASS_NAME, "result")
|
|
|
|
# Look for the result element that contains currency-related content
|
|
currency_result = None
|
|
for elem in result_elements:
|
|
html = elem.get_attribute('innerHTML')
|
|
if 'USD' in html or 'EUR' in html or 'Currency' in html or 'conversion' in html.lower():
|
|
currency_result = elem
|
|
break
|
|
|
|
if not currency_result:
|
|
# If no currency result found, use the last result element (most recent)
|
|
currency_result = result_elements[-1]
|
|
|
|
# Check that some result is displayed
|
|
assert currency_result.text.strip() != ""
|
|
# Check for either conversion result or static rates message
|
|
assert any(text in currency_result.text for text in ["USD", "EUR", "Static rates", "Live rates"])
|
|
|
|
class TestBandwidthCalculator:
|
|
"""Test the Bandwidth calculator functionality"""
|
|
|
|
def test_bandwidth_calculator_loads(self, calculator_page):
|
|
"""Test that bandwidth calculator loads"""
|
|
bandwidth_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Bandwidth')]")
|
|
bandwidth_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.CLASS_NAME, "result"))
|
|
)
|
|
|
|
# Check that result area is present
|
|
assert calculator_page.find_element(By.CLASS_NAME, "result")
|
|
|
|
class TestNMEACalculator:
|
|
"""Test the NMEA calculator functionality"""
|
|
|
|
def test_nmea_calculator_loads(self, calculator_page):
|
|
"""Test that NMEA calculator loads"""
|
|
nmea_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'NMEA')]")
|
|
nmea_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.CLASS_NAME, "result"))
|
|
)
|
|
|
|
# Check that result area is present
|
|
assert calculator_page.find_element(By.CLASS_NAME, "result")
|
|
|
|
class TestRAIDCalculator:
|
|
"""Test the RAID calculator functionality"""
|
|
|
|
def test_raid_calculator_loads(self, calculator_page):
|
|
"""Test that RAID calculator loads"""
|
|
raid_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'RAID')]")
|
|
raid_btn.click()
|
|
|
|
# Wait for calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.CLASS_NAME, "result"))
|
|
)
|
|
|
|
# Check that result area is present
|
|
assert calculator_page.find_element(By.CLASS_NAME, "result")
|
|
|
|
class TestCalculatorResponsiveness:
|
|
"""Test calculator responsiveness and UI behavior"""
|
|
|
|
def test_theme_toggle(self, calculator_page):
|
|
"""Test that theme toggle button works"""
|
|
theme_btn = calculator_page.find_element(By.ID, "themeToggle")
|
|
initial_text = theme_btn.text
|
|
|
|
# Click theme toggle
|
|
theme_btn.click()
|
|
|
|
# Wait for theme change
|
|
time.sleep(1)
|
|
|
|
# Check that text changed
|
|
assert theme_btn.text != initial_text
|
|
|
|
def test_calculator_switching(self, calculator_page):
|
|
"""Test switching between different calculators"""
|
|
# Start with interest calculator
|
|
interest_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Interest')]")
|
|
interest_btn.click()
|
|
|
|
# Wait for interest calculator to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "principal"))
|
|
)
|
|
|
|
# Switch to currency converter
|
|
currency_btn = calculator_page.find_element(By.XPATH, "//a[contains(text(), 'Currency Converter')]")
|
|
currency_btn.click()
|
|
|
|
# Wait for currency converter to load
|
|
WebDriverWait(calculator_page, 10).until(
|
|
EC.presence_of_element_located((By.NAME, "amount"))
|
|
)
|
|
|
|
# Verify we're on currency converter
|
|
assert calculator_page.find_element(By.NAME, "amount")
|
|
assert calculator_page.find_element(By.NAME, "from")
|
|
assert calculator_page.find_element(By.NAME, "to")
|
|
|