init
This commit is contained in:
commit
97f9a95415
21 changed files with 2963 additions and 0 deletions
404
tests/test_calculators.py
Normal file
404
tests/test_calculators.py
Normal file
|
@ -0,0 +1,404 @@
|
|||
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")
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue