mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-01-31 10:01:20 -05:00
- Mac - Flask debug - Threaded flask - propagate token in GET requests - enhance spec docs - normalize MAC x2 - mcp disablement redundant private attribute - run all tests imports
150 lines
6.1 KiB
Python
150 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Device Details Page UI Tests
|
|
Tests device details page, field updates, and delete operations
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
from selenium.webdriver.common.by import By
|
|
|
|
# Add test directory to path
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
from .test_helpers import BASE_URL, API_BASE_URL, api_get, wait_for_page_load, wait_for_element_by_css, wait_for_input_value # noqa: E402
|
|
|
|
|
|
def test_device_list_page_loads(driver):
|
|
"""Test: Device list page loads successfully"""
|
|
driver.get(f"{BASE_URL}/devices.php")
|
|
wait_for_page_load(driver, timeout=10)
|
|
assert "device" in driver.page_source.lower(), "Page should contain device content"
|
|
|
|
|
|
def test_devices_table_present(driver):
|
|
"""Test: Devices table is rendered"""
|
|
driver.get(f"{BASE_URL}/devices.php")
|
|
wait_for_page_load(driver, timeout=10)
|
|
wait_for_element_by_css(driver, "table, #devicesTable", timeout=10)
|
|
table = driver.find_elements(By.CSS_SELECTOR, "table, #devicesTable")
|
|
assert len(table) > 0, "Devices table should be present"
|
|
|
|
|
|
def test_device_search_works(driver):
|
|
"""Test: Device search/filter functionality works"""
|
|
driver.get(f"{BASE_URL}/devices.php")
|
|
wait_for_page_load(driver, timeout=10)
|
|
|
|
# Find search input (common patterns)
|
|
search_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='search'], input[placeholder*='search' i], .dataTables_filter input")
|
|
|
|
if len(search_inputs) > 0:
|
|
search_box = search_inputs[0]
|
|
assert search_box.is_displayed(), "Search box should be visible"
|
|
|
|
# Type in search box and wait briefly for filter to apply
|
|
search_box.clear()
|
|
search_box.send_keys("test")
|
|
# Wait for DOM/JS to react (at least one row or filtered content) — if datatables in use, table body should update
|
|
wait_for_element_by_css(driver, "table tbody tr", timeout=5)
|
|
|
|
# Verify search executed (page content changed or filter applied)
|
|
assert True, "Search executed successfully"
|
|
else:
|
|
# If no search box, just verify page loaded
|
|
assert len(driver.page_source) > 100, "Page should load content"
|
|
|
|
|
|
def test_devices_api(api_token):
|
|
"""Test: Devices API endpoint returns data"""
|
|
response = api_get("/devices", api_token)
|
|
assert response.status_code == 200, "API should return 200"
|
|
|
|
data = response.json()
|
|
assert isinstance(data, (list, dict)), "API should return list or dict"
|
|
|
|
|
|
def test_devices_totals_api(api_token):
|
|
"""Test: Devices totals API endpoint works"""
|
|
response = api_get("/devices/totals", api_token)
|
|
assert response.status_code == 200, "API should return 200"
|
|
|
|
data = response.json()
|
|
assert isinstance(data, (list, dict)), "API should return list or dict"
|
|
assert len(data) > 0, "Response should contain data"
|
|
|
|
|
|
def test_add_device_with_generated_mac_ip(driver, api_token):
|
|
"""Add a new device using the UI, always clicking Generate MAC/IP buttons"""
|
|
import requests
|
|
|
|
driver.get(f"{BASE_URL}/devices.php")
|
|
wait_for_page_load(driver, timeout=10)
|
|
|
|
# --- Click "Add Device" ---
|
|
# Wait for the "New Device" link specifically to ensure it's loaded
|
|
add_selector = "a[href*='deviceDetails.php?mac=new'], button#btnAddDevice, .btn-add-device"
|
|
try:
|
|
add_button = wait_for_element_by_css(driver, add_selector, timeout=10)
|
|
except Exception:
|
|
# Fallback to broader search if specific selector fails
|
|
add_buttons = driver.find_elements(By.XPATH, "//button[contains(text(),'Add') or contains(text(),'New')] | //a[contains(text(),'Add') or contains(text(),'New')]")
|
|
if add_buttons:
|
|
add_button = add_buttons[0]
|
|
else:
|
|
assert True, "Add device button not found, skipping test"
|
|
return
|
|
|
|
# Use JavaScript click to bypass any transparent overlays from the chart
|
|
driver.execute_script("arguments[0].click();", add_button)
|
|
|
|
# Wait for the device form to appear (use the NEWDEV_devMac field as indicator)
|
|
wait_for_element_by_css(driver, "#NEWDEV_devMac", timeout=10)
|
|
|
|
# --- Helper to click generate button for a field ---
|
|
def click_generate_button(field_id):
|
|
btn = driver.find_element(By.CSS_SELECTOR, f"span[onclick*='generate_{field_id}']")
|
|
driver.execute_script("arguments[0].click();", btn)
|
|
# Wait for the input to be populated and return it
|
|
return wait_for_input_value(driver, field_id, timeout=10)
|
|
|
|
# --- Generate MAC ---
|
|
test_mac = click_generate_button("NEWDEV_devMac")
|
|
assert test_mac, "MAC should be generated"
|
|
|
|
# --- Generate IP ---
|
|
test_ip = click_generate_button("NEWDEV_devLastIP")
|
|
assert test_ip, "IP should be generated"
|
|
|
|
# --- Fill Name ---
|
|
name_field = driver.find_element(By.ID, "NEWDEV_devName")
|
|
name_field.clear()
|
|
name_field.send_keys("Test Device Selenium")
|
|
|
|
# --- Click Save ---
|
|
save_buttons = driver.find_elements(By.CSS_SELECTOR, "button#btnSave, button#save, button[type='submit'], button.btn-primary, button[onclick*='save' i]")
|
|
if not save_buttons:
|
|
save_buttons = driver.find_elements(By.XPATH, "//button[contains(translate(text(),'SAVE','save'),'save')]")
|
|
if not save_buttons:
|
|
assert True, "Save button not found, skipping test"
|
|
return
|
|
driver.execute_script("arguments[0].click();", save_buttons[0])
|
|
|
|
# --- Verify device via API ---
|
|
headers = {"Authorization": f"Bearer {api_token}"}
|
|
verify_response = requests.get(f"{API_BASE_URL}/device/{test_mac}", headers=headers)
|
|
if verify_response.status_code == 200:
|
|
device_data = verify_response.json()
|
|
assert device_data is not None, "Device should exist in database"
|
|
|
|
else:
|
|
# Fallback: check UI
|
|
driver.get(f"{BASE_URL}/devices.php")
|
|
wait_for_page_load(driver, timeout=10)
|
|
if test_mac in driver.page_source or "Test Device Selenium" in driver.page_source:
|
|
assert True, "Device appears in UI"
|
|
else:
|
|
error_elements = driver.find_elements(By.CSS_SELECTOR, ".alert-danger, .error-message, .callout-danger")
|
|
has_error = any(elem.is_displayed() and elem.text for elem in error_elements)
|
|
assert not has_error, "Save should not produce visible errors"
|