364 lines
16 KiB
Python
364 lines
16 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Selenium test to verify the new kvist layout structure
|
||
- Small collapsible info box at top
|
||
- Main blue measurements box below
|
||
- Everything centered with max-width 800px
|
||
"""
|
||
|
||
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.service import Service
|
||
from selenium.webdriver.chrome.options import Options
|
||
import time
|
||
import sys
|
||
|
||
def test_kvist_layout():
|
||
"""Test the new kvist layout structure"""
|
||
|
||
# Setup Chrome options
|
||
chrome_options = Options()
|
||
chrome_options.add_argument('--headless') # Run headless
|
||
chrome_options.add_argument('--no-sandbox')
|
||
chrome_options.add_argument('--disable-dev-shm-usage')
|
||
chrome_options.add_argument('--window-size=1920,1080')
|
||
chrome_options.add_argument('--user-data-dir=/tmp/selenium-chrome-profile')
|
||
chrome_options.add_argument('--disable-gpu')
|
||
|
||
driver = None
|
||
|
||
try:
|
||
print("🚀 Starting Selenium test for kvist layout...")
|
||
driver = webdriver.Chrome(options=chrome_options)
|
||
wait = WebDriverWait(driver, 10)
|
||
|
||
# Navigate to the application
|
||
print("\n📍 Navigating to application...")
|
||
driver.get('http://localhost:4031')
|
||
time.sleep(3)
|
||
|
||
# Check if we need to login
|
||
print("🔐 Checking for login page...")
|
||
page_html = driver.page_source.lower()
|
||
|
||
if 'login' in page_html or 'password' in page_html:
|
||
print("🔑 Login page detected, attempting to login...")
|
||
|
||
# Find email/username field
|
||
try:
|
||
email_field = driver.find_element(By.CSS_SELECTOR, 'input[type="email"], input[type="text"], input[name="email"]')
|
||
password_field = driver.find_element(By.CSS_SELECTOR, 'input[type="password"]')
|
||
|
||
# Enter credentials
|
||
email_field.clear()
|
||
email_field.send_keys('admin@test.com')
|
||
password_field.clear()
|
||
password_field.send_keys('admin123')
|
||
|
||
# Find and click login button
|
||
login_buttons = driver.find_elements(By.CSS_SELECTOR, 'button[type="submit"], button, input[type="submit"]')
|
||
for button in login_buttons:
|
||
button_text = button.text.lower() if button.text else ''
|
||
button_value = button.get_attribute('value') or ''
|
||
if 'log' in button_text or 'log' in button_value.lower() or 'sign' in button_text:
|
||
button.click()
|
||
print("✅ Login button clicked")
|
||
time.sleep(4)
|
||
break
|
||
except Exception as e:
|
||
print(f"⚠️ Could not complete login: {e}")
|
||
else:
|
||
print("✅ No login required or already logged in")
|
||
|
||
# Navigate to projekter/projects page
|
||
print("\n🏗️ Navigating to projects page...")
|
||
try:
|
||
# Try to find and click "Projekter" or "Projects" link in navigation
|
||
nav_links = driver.find_elements(By.CSS_SELECTOR, 'a, button')
|
||
for link in nav_links:
|
||
link_text = link.text.lower()
|
||
if 'projekt' in link_text and len(link_text) < 15: # Match "Projekter" but not too long descriptions
|
||
print(f"✅ Clicking navigation link: '{link.text}'")
|
||
link.click()
|
||
time.sleep(3)
|
||
break
|
||
except Exception as e:
|
||
print(f"⚠️ Could not navigate to projects: {e}")
|
||
|
||
# Take a screenshot to see what we're working with
|
||
driver.save_screenshot('/tmp/kvist_test_after_nav.png')
|
||
print("📸 Screenshot saved to /tmp/kvist_test_after_nav.png")
|
||
|
||
# Take a screenshot to see what we're working with
|
||
driver.save_screenshot('/tmp/kvist_test_after_nav.png')
|
||
print("<EFBFBD> Screenshot saved to /tmp/kvist_test_after_nav.png")
|
||
|
||
# Look for a project to open or create new one
|
||
print("\n🔍 Looking for existing projects...")
|
||
try:
|
||
# Look for project cards or list items
|
||
project_elements = driver.find_elements(By.CSS_SELECTOR, 'div[class*="project"], a[href*="project"], button')
|
||
|
||
project_opened = False
|
||
for elem in project_elements:
|
||
elem_text = elem.text.lower()
|
||
# Try to click on a test project or any project
|
||
if ('test' in elem_text or 'projekt' in elem_text) and len(elem_text) < 50:
|
||
try:
|
||
elem.click()
|
||
print(f"✅ Opened project: '{elem.text}'")
|
||
time.sleep(3)
|
||
project_opened = True
|
||
break
|
||
except:
|
||
continue
|
||
|
||
if not project_opened:
|
||
print("⚠️ No project clicked, trying to create new or find geometry tab...")
|
||
|
||
# Try to find "Ny Projekt" or "New Project" button
|
||
new_project_btns = driver.find_elements(By.CSS_SELECTOR, 'button, a')
|
||
for btn in new_project_btns:
|
||
if 'ny' in btn.text.lower() and 'projekt' in btn.text.lower():
|
||
btn.click()
|
||
print("✅ Clicked 'Ny Projekt' button")
|
||
time.sleep(2)
|
||
break
|
||
|
||
except Exception as e:
|
||
print(f"⚠️ Error finding projects: {e}")
|
||
|
||
# Take screenshot after project selection
|
||
driver.save_screenshot('/tmp/kvist_test_in_project.png')
|
||
print("📸 Screenshot saved to /tmp/kvist_test_in_project.png")
|
||
|
||
# Look for Geometry tab or Geometri link
|
||
print("\n🔧 Looking for Geometry section...")
|
||
try:
|
||
geom_links = driver.find_elements(By.CSS_SELECTOR, 'a, button, div[role="tab"]')
|
||
for link in geom_links:
|
||
link_text = link.text.lower()
|
||
if 'geometri' in link_text or 'geometry' in link_text:
|
||
link.click()
|
||
print(f"✅ Clicked geometry tab: '{link.text}'")
|
||
time.sleep(2)
|
||
break
|
||
except Exception as e:
|
||
print(f"⚠️ Error navigating to geometry: {e}")
|
||
|
||
# Get page source to debug
|
||
page_source = driver.page_source
|
||
print(f"📄 Page contains 'kvist': {'kvist' in page_source.lower()}")
|
||
print(f"📄 Page contains 'geometry': {'geometry' in page_source.lower()}")
|
||
print(f"📄 Page title: {driver.title}")
|
||
|
||
time.sleep(1)
|
||
|
||
# Look for project selector or create new project
|
||
print("🔍 Looking for project interface...")
|
||
|
||
# Try to find geometry section
|
||
try:
|
||
# Wait for page to load
|
||
time.sleep(3)
|
||
|
||
# Check if we need to select roof type with kviste
|
||
print("🏠 Looking for roof type selector...")
|
||
roof_type_selects = driver.find_elements(By.CSS_SELECTOR, 'select')
|
||
|
||
kvist_option_found = False
|
||
for select in roof_type_selects:
|
||
options = select.find_elements(By.TAG_NAME, 'option')
|
||
for option in options:
|
||
if 'kviste' in option.text.lower():
|
||
print(f"✅ Found kvist option: {option.text}")
|
||
select.click()
|
||
option.click()
|
||
kvist_option_found = True
|
||
time.sleep(2)
|
||
break
|
||
if kvist_option_found:
|
||
break
|
||
|
||
if not kvist_option_found:
|
||
print("⚠️ Could not find roof type selector with kviste option")
|
||
print(" This might be because we're not on the right page yet")
|
||
|
||
# Now look for the kvist section structure
|
||
print("\n🔍 Verifying kvist layout structure...")
|
||
|
||
# Test 1: Check for outer container with maxWidth 800px
|
||
print("\n1️⃣ Checking outer container centering...")
|
||
containers = driver.find_elements(By.CSS_SELECTOR, 'div[style*="max-width"]')
|
||
found_800px = False
|
||
outer_container = None
|
||
|
||
for container in containers:
|
||
style = container.get_attribute('style')
|
||
if '800px' in style and 'margin' in style and 'auto' in style:
|
||
print("✅ Found centered container with max-width: 800px")
|
||
found_800px = True
|
||
outer_container = container
|
||
break
|
||
|
||
if not found_800px:
|
||
print("❌ Could not find outer container with max-width: 800px and centered margin")
|
||
|
||
# Test 2: Check for yellow info box (kvist detaljer)
|
||
print("\n2️⃣ Checking for yellow info box (Kvist detaljer)...")
|
||
yellow_boxes = driver.find_elements(By.CSS_SELECTOR, 'div[style*="#fffacd"]')
|
||
|
||
info_box_found = False
|
||
for box in yellow_boxes:
|
||
style = box.get_attribute('style')
|
||
if '#fffacd' in style and 'border-radius' in style:
|
||
# Check if it contains the title
|
||
try:
|
||
title = box.find_element(By.TAG_NAME, 'h4')
|
||
if 'kvist' in title.text.lower() and 'detaljer' in title.text.lower():
|
||
print(f"✅ Found yellow info box with title: '{title.text}'")
|
||
info_box_found = True
|
||
|
||
# Check for toggle button
|
||
buttons = box.find_elements(By.TAG_NAME, 'button')
|
||
for button in buttons:
|
||
if 'vis' in button.text.lower() or 'skjul' in button.text.lower():
|
||
print(f"✅ Found toggle button: '{button.text}'")
|
||
|
||
# Test toggle functionality
|
||
print("🔄 Testing toggle button...")
|
||
initial_text = button.text
|
||
button.click()
|
||
time.sleep(1)
|
||
new_text = button.text
|
||
|
||
if initial_text != new_text:
|
||
print(f"✅ Toggle works! Changed from '{initial_text}' to '{new_text}'")
|
||
else:
|
||
print(f"⚠️ Toggle button clicked but text didn't change")
|
||
|
||
break
|
||
break
|
||
except:
|
||
continue
|
||
|
||
if not info_box_found:
|
||
print("❌ Could not find yellow info box with 'Kvist detaljer' title")
|
||
|
||
# Test 3: Check for blue measurements box
|
||
print("\n3️⃣ Checking for blue measurements box...")
|
||
blue_boxes = driver.find_elements(By.CSS_SELECTOR, 'div[style*="#f0f8ff"]')
|
||
|
||
measurements_box_found = False
|
||
for box in blue_boxes:
|
||
style = box.get_attribute('style')
|
||
if '#f0f8ff' in style and '#4682b4' in style: # Background and border color
|
||
# Check if it contains measurement fields
|
||
try:
|
||
# Look for "Grundmål for kvist" heading
|
||
headings = box.find_elements(By.TAG_NAME, 'h5')
|
||
for heading in headings:
|
||
if 'grundmål' in heading.text.lower() and 'kvist' in heading.text.lower():
|
||
print(f"✅ Found blue measurements box with heading: '{heading.text}'")
|
||
measurements_box_found = True
|
||
|
||
# Count input fields
|
||
inputs = box.find_elements(By.TAG_NAME, 'input')
|
||
print(f"✅ Found {len(inputs)} input fields in measurements box")
|
||
|
||
# Look for sections
|
||
all_headings = box.find_elements(By.TAG_NAME, 'h5')
|
||
print(f"📊 Sections found:")
|
||
for h in all_headings:
|
||
print(f" - {h.text}")
|
||
|
||
break
|
||
except:
|
||
continue
|
||
|
||
if not measurements_box_found:
|
||
print("❌ Could not find blue measurements box")
|
||
|
||
# Test 4: Verify structure order (yellow box before blue box)
|
||
print("\n4️⃣ Verifying layout order...")
|
||
if outer_container:
|
||
child_divs = outer_container.find_elements(By.XPATH, './div')
|
||
if len(child_divs) >= 2:
|
||
first_div_style = child_divs[0].get_attribute('style')
|
||
second_div_style = child_divs[1].get_attribute('style')
|
||
|
||
if '#fffacd' in first_div_style and '#f0f8ff' in second_div_style:
|
||
print("✅ Layout order is correct: Yellow info box → Blue measurements box")
|
||
else:
|
||
print("⚠️ Layout order might be different than expected")
|
||
else:
|
||
print("⚠️ Could not verify layout order (not enough child divs)")
|
||
|
||
# Summary
|
||
print("\n" + "="*60)
|
||
print("📊 VERIFICATION SUMMARY")
|
||
print("="*60)
|
||
|
||
tests_passed = 0
|
||
total_tests = 4
|
||
|
||
if found_800px:
|
||
print("✅ Outer container centered with max-width 800px")
|
||
tests_passed += 1
|
||
else:
|
||
print("❌ Outer container centering not verified")
|
||
|
||
if info_box_found:
|
||
print("✅ Yellow info box (Kvist detaljer) with toggle button")
|
||
tests_passed += 1
|
||
else:
|
||
print("❌ Yellow info box not found")
|
||
|
||
if measurements_box_found:
|
||
print("✅ Blue measurements box with sections")
|
||
tests_passed += 1
|
||
else:
|
||
print("❌ Blue measurements box not found")
|
||
|
||
if found_800px and info_box_found and measurements_box_found:
|
||
print("✅ Layout structure verified")
|
||
tests_passed += 1
|
||
else:
|
||
print("❌ Complete layout structure not verified")
|
||
|
||
print(f"\n🎯 Tests passed: {tests_passed}/{total_tests}")
|
||
|
||
if tests_passed == total_tests:
|
||
print("\n✅ ALL TESTS PASSED! Layout is correct! 🎉")
|
||
return True
|
||
elif tests_passed >= 2:
|
||
print("\n⚠️ PARTIAL SUCCESS - Some elements verified")
|
||
return True
|
||
else:
|
||
print("\n❌ TESTS FAILED - Layout needs verification")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"❌ Error during test: {str(e)}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"❌ Error setting up Selenium: {str(e)}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
finally:
|
||
if driver:
|
||
print("\n🧹 Cleaning up...")
|
||
driver.quit()
|
||
print("✅ Browser closed")
|
||
|
||
if __name__ == "__main__":
|
||
success = test_kvist_layout()
|
||
sys.exit(0 if success else 1)
|