Implement manual and automated tests for auto-save countdown feature
- Added a comprehensive manual testing guide for the countdown functionality in `test_countdown_manual.md`. - Developed a detailed Selenium test suite in `test_countdown_selenium.py` to verify countdown behavior, including server accessibility, login, countdown progression, and UI elements. - Created a minimal Selenium test version in `test_countdown_selenium_minimal.py` for quick checks without complex setup. - Introduced a verification script in `test_countdown_verification.py` to analyze code correctness, including server checks, build file existence, and countdown logic.
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Minimal Selenium Test - Auto-save Countdown
|
||||
Ultra-simpel version der prøver at undgå Chrome profile konflikter
|
||||
"""
|
||||
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
|
||||
# Load credentials from .env
|
||||
LOGIN_USERNAME = "toemrer"
|
||||
LOGIN_PASSWORD = "REDACTED_AUTH"
|
||||
|
||||
def test_countdown():
|
||||
"""Minimal test uden fancy setup"""
|
||||
driver = None
|
||||
|
||||
try:
|
||||
print("🔧 Starter Chrome...")
|
||||
|
||||
# Absolut minimal options
|
||||
options = Options()
|
||||
options.add_argument('--headless=new')
|
||||
options.add_argument('--no-sandbox')
|
||||
options.add_argument('--disable-dev-shm-usage')
|
||||
|
||||
# Prøv at starte Chrome
|
||||
driver = webdriver.Chrome(options=options)
|
||||
print("✅ Chrome startet!")
|
||||
|
||||
# Test 1: Load siden
|
||||
print("\n📍 Test 1: Loading http://localhost:4031...")
|
||||
driver.get("http://localhost:4031")
|
||||
time.sleep(3)
|
||||
print(f" ✅ Side loaded: {driver.title}")
|
||||
|
||||
# Test 2: Find login eller homepage elementer
|
||||
print("\n📍 Test 2: Finder elementer...")
|
||||
try:
|
||||
# Prøv at finde navigation
|
||||
nav_elements = driver.find_elements(By.CLASS_NAME, "nav-btn")
|
||||
if nav_elements:
|
||||
print(f" ✅ Fandt {len(nav_elements)} navigation knapper")
|
||||
|
||||
# Prøv at finde login
|
||||
login_fields = driver.find_elements(By.ID, "username")
|
||||
if login_fields:
|
||||
print(" ℹ️ Login påkrævet")
|
||||
print(f" 🔑 Bruger credentials fra .env: {LOGIN_USERNAME}")
|
||||
|
||||
driver.find_element(By.ID, "username").send_keys(LOGIN_USERNAME)
|
||||
driver.find_element(By.ID, "password").send_keys(LOGIN_PASSWORD)
|
||||
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
|
||||
time.sleep(3)
|
||||
print(" ✅ Login gennemført")
|
||||
|
||||
# Naviger til projekt flow
|
||||
print("\n📍 Test 2b: Navigerer til Projekt Flow...")
|
||||
nav_buttons = driver.find_elements(By.CLASS_NAME, "nav-btn")
|
||||
for btn in nav_buttons:
|
||||
if "Projekt Flow" in btn.text:
|
||||
btn.click()
|
||||
time.sleep(2)
|
||||
print(" ✅ Navigeret til Projekt Flow")
|
||||
break
|
||||
|
||||
# Opret et simpelt projekt først
|
||||
print("\n📍 Test 2c: Opretter test projekt...")
|
||||
try:
|
||||
# Udfyld projekt navn
|
||||
project_name = driver.find_element(By.ID, "projectName")
|
||||
project_name.clear()
|
||||
project_name.send_keys("Selenium Test Projekt")
|
||||
|
||||
# Udfyld kunde navn
|
||||
customer_name = driver.find_element(By.ID, "customerName")
|
||||
customer_name.clear()
|
||||
customer_name.send_keys("Test Kunde")
|
||||
time.sleep(1)
|
||||
|
||||
# Klik gem/næste knap
|
||||
save_buttons = driver.find_elements(By.XPATH,
|
||||
"//button[contains(text(), 'Næste') or contains(text(), 'Gem') or contains(text(), 'Opret')]")
|
||||
if save_buttons:
|
||||
save_buttons[0].click()
|
||||
time.sleep(3)
|
||||
print(" ✅ Projekt oprettet")
|
||||
else:
|
||||
print(" ⚠️ Kunne ikke finde gem knap")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Projekt oprettelse: {e}")
|
||||
|
||||
# Klik på Geometri step
|
||||
print("\n📍 Test 2d: Åbner Geometri sektion...")
|
||||
try:
|
||||
# Find geometri step - det er typisk step #2
|
||||
steps = driver.find_elements(By.CLASS_NAME, "step")
|
||||
print(f" 📊 Fandt {len(steps)} steps")
|
||||
|
||||
if len(steps) >= 2:
|
||||
geometry_step = steps[1] # Index 1 = anden step (Geometri)
|
||||
step_name = geometry_step.text
|
||||
print(f" 🎯 Klikker på step: {step_name[:50]}...")
|
||||
|
||||
# Klik på step
|
||||
geometry_step.click()
|
||||
time.sleep(3)
|
||||
print(" ✅ Geometri step klikket, venter på loading...")
|
||||
|
||||
# Vent på at geometri form loader
|
||||
time.sleep(2)
|
||||
else:
|
||||
print(f" ⚠️ Kunne kun finde {len(steps)} steps")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Kunne ikke åbne geometri: {e}")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Element søgning: {e}")
|
||||
|
||||
# Test 3: Søg efter countdown text
|
||||
print("\n📍 Test 3: Søger efter countdown...")
|
||||
try:
|
||||
# Vent lidt for at lade siden loade
|
||||
time.sleep(3)
|
||||
|
||||
# Scroll ned for at se geometri inputs
|
||||
driver.execute_script("window.scrollTo(0, 500);")
|
||||
time.sleep(1)
|
||||
|
||||
# Find alle input felter
|
||||
all_inputs = driver.find_elements(By.TAG_NAME, "input")
|
||||
number_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='number']")
|
||||
print(f" 📊 Fandt {len(all_inputs)} input felter totalt ({len(number_inputs)} numeriske)")
|
||||
|
||||
# Find labels for at identificere felter
|
||||
labels = driver.find_elements(By.TAG_NAME, "label")
|
||||
print(f" 🏷️ Fandt {len(labels)} labels")
|
||||
|
||||
page_text = driver.find_element(By.TAG_NAME, "body").text
|
||||
if "Gemmes automatisk" in page_text or "sekund" in page_text:
|
||||
print(" ✅ Countdown tekst fundet på siden!")
|
||||
|
||||
# Find specifik countdown
|
||||
countdown_elements = driver.find_elements(By.XPATH,
|
||||
"//*[contains(text(), 'Gemmes automatisk')]")
|
||||
if countdown_elements:
|
||||
print(f" ✅ Countdown element: {countdown_elements[0].text}")
|
||||
|
||||
# Prøv at observere countdown i aktion
|
||||
print("\n📍 Test 3b: Trigger countdown...")
|
||||
# Find input felter
|
||||
inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='number']")
|
||||
if inputs:
|
||||
print(f" ✅ Fandt {len(inputs)} numeriske input felter")
|
||||
# Udfyld første felt
|
||||
inputs[0].clear()
|
||||
inputs[0].send_keys("10")
|
||||
time.sleep(0.5)
|
||||
|
||||
# Observér countdown
|
||||
print(" ⏱️ Observerer countdown i 4 sekunder...")
|
||||
for i in range(4):
|
||||
try:
|
||||
countdown_el = driver.find_element(By.XPATH,
|
||||
"//*[contains(text(), 'Gemmes automatisk')]")
|
||||
print(f" [{i+1}s] Countdown: {countdown_el.text}")
|
||||
time.sleep(1)
|
||||
except:
|
||||
print(f" [{i+1}s] Countdown element ikke fundet")
|
||||
break
|
||||
else:
|
||||
print(" ⚠️ Countdown tekst ikke synlig på denne side")
|
||||
|
||||
# Debug: Søg efter specifikke elementer
|
||||
print("\n 🔍 Debug - søger efter geometry-relaterede elementer:")
|
||||
geometry_classes = driver.find_elements(By.CSS_SELECTOR,
|
||||
"[class*='geometry'], [class*='Geometry'], [class*='enhanced']")
|
||||
print(f" - Geometry elementer: {len(geometry_classes)}")
|
||||
|
||||
form_groups = driver.find_elements(By.CLASS_NAME, "form-group")
|
||||
print(f" - Form groups: {len(form_groups)}")
|
||||
|
||||
# Hvis der er input felter, prøv at udfylde et
|
||||
if number_inputs and len(number_inputs) >= 2:
|
||||
print(f"\n 🧪 Udfylder bredde og længde felter...")
|
||||
|
||||
# Scroll til første input
|
||||
driver.execute_script("arguments[0].scrollIntoView(true);", number_inputs[0])
|
||||
time.sleep(0.5)
|
||||
|
||||
# Udfyld bredde (første felt)
|
||||
number_inputs[0].click()
|
||||
number_inputs[0].clear()
|
||||
number_inputs[0].send_keys("10")
|
||||
print(" ✅ Bredde sat til 10m")
|
||||
time.sleep(0.5)
|
||||
|
||||
# Udfyld længde (andet felt)
|
||||
number_inputs[1].click()
|
||||
number_inputs[1].clear()
|
||||
number_inputs[1].send_keys("15")
|
||||
print(" ✅ Længde sat til 15m")
|
||||
time.sleep(0.5)
|
||||
|
||||
# Nu skal countdown være synlig - søg igen
|
||||
print("\n ⏱️ Søger efter countdown efter input...")
|
||||
for attempt in range(6):
|
||||
page_text = driver.find_element(By.TAG_NAME, "body").text
|
||||
if "Gemmes automatisk" in page_text and "sekund" in page_text:
|
||||
print(f" ✅ [Forsøg {attempt+1}] Countdown med sekunder fundet!")
|
||||
|
||||
# Prøv flere selectors
|
||||
countdown_el = None
|
||||
try:
|
||||
# Prøv span først
|
||||
countdown_el = driver.find_element(By.XPATH,
|
||||
"//span[contains(text(), 'Gemmes automatisk')]")
|
||||
except:
|
||||
try:
|
||||
# Prøv div
|
||||
countdown_el = driver.find_element(By.XPATH,
|
||||
"//div[contains(text(), 'Gemmes automatisk')]")
|
||||
except:
|
||||
# Prøv enhver element
|
||||
countdown_el = driver.find_element(By.XPATH,
|
||||
"//*[contains(text(), 'Gemmes automatisk')]")
|
||||
|
||||
if countdown_el:
|
||||
initial_text = countdown_el.text
|
||||
print(f" ✅ Initial countdown: {initial_text}")
|
||||
|
||||
# Observér countdown over tid
|
||||
print("\n 📊 Observerer countdown progression...")
|
||||
for i in range(5):
|
||||
time.sleep(1)
|
||||
try:
|
||||
countdown_el = driver.find_element(By.XPATH,
|
||||
"//span[contains(text(), 'Gemmes automatisk')]")
|
||||
current_text = countdown_el.text
|
||||
print(f" [{i+1}s] {current_text}")
|
||||
except:
|
||||
print(f" [{i+1}s] Countdown forsvundet (data gemt)")
|
||||
break
|
||||
else:
|
||||
print(" ⚠️ Kunne ikke finde countdown element")
|
||||
break
|
||||
elif "Gemmes automatisk" in page_text:
|
||||
print(f" ℹ️ [Forsøg {attempt+1}] 'Gemmes automatisk' fundet, men ikke med sekunder")
|
||||
if attempt < 5:
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
if attempt < 5:
|
||||
print(f" ⏳ [Forsøg {attempt+1}] Venter på countdown...")
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
print(" ⚠️ Countdown stadig ikke synlig efter 6 forsøg")
|
||||
elif number_inputs:
|
||||
print(f" ⚠️ Kun {len(number_inputs)} numeriske felter fundet, behøver mindst 2")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Countdown søgning: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# Test 4: Take screenshot
|
||||
print("\n📍 Test 4: Tager screenshot...")
|
||||
try:
|
||||
screenshot_path = "/mnt/HC_Volume_103713257/tilbudgivern/selenium_screenshot.png"
|
||||
driver.save_screenshot(screenshot_path)
|
||||
print(f" ✅ Screenshot gemt: {screenshot_path}")
|
||||
|
||||
# Gem også HTML for debugging
|
||||
html_path = "/mnt/HC_Volume_103713257/tilbudgivern/selenium_page.html"
|
||||
with open(html_path, 'w', encoding='utf-8') as f:
|
||||
f.write(driver.page_source)
|
||||
print(f" ✅ HTML gemt: {html_path}")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Screenshot/HTML: {e}")
|
||||
|
||||
print("\n✅ Test gennemført!")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Test fejlede: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
finally:
|
||||
if driver:
|
||||
driver.quit()
|
||||
print("🔒 Chrome lukket")
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = test_countdown()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user