fix: scale replicas in response, K8s metrics client, quota precheck, auth tests
- Add GetMetrics method to MetricsClient interface and implement cluster metrics API - Add QuotaPrecheck service for validating resource quotas before deployment - Add auth DTO with role/permission models and auth handler tests - Add instance diagnostics: mounted NFS volumes, labels, annotations in pod diagnostics - Update workspace handler with GetWorkspace endpoint and shared-user list - Fix monitoring handler to use correct service method name - Add tail_lines fallback in instance handler for snake_case query params - Update nginx config for SSE log streaming support (no buffering) - Add comprehensive test coverage: auth_service_test, auth_handler_test, auth_dto_test, metrics_client_test, quota_precheck_test - Update error messages for quota validation and instance operations - ModifyModal: fix YAML lineWidth:0, modified keys summary, delta-only submit - InstanceCard: correctly disable scale-minus when replicas <= 0 - SidebarLayout: add hover transition for sidebar items - Update todo.md and lessons.md with latest fixes
This commit is contained in:
63
test/user_management_layout_playwright.py
Normal file
63
test/user_management_layout_playwright.py
Normal file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
# Covers admin User Management layout: quota fields and action buttons remain
|
||||
# visible inside the viewport on desktop and tablet widths.
|
||||
|
||||
import os
|
||||
|
||||
from playwright.sync_api import expect, sync_playwright
|
||||
|
||||
|
||||
FRONTEND_URL = os.environ.get("FRONTEND_URL", "http://localhost:18080")
|
||||
ADMIN_USER = os.environ.get("ADMIN_USER", "admin")
|
||||
ADMIN_PASS = os.environ["ADMIN_PASS"]
|
||||
|
||||
|
||||
def login(page):
|
||||
page.goto(FRONTEND_URL, wait_until="networkidle")
|
||||
if page.locator("input[type='password']").count() == 0:
|
||||
return
|
||||
page.locator("input:not([type='password'])").first.fill(ADMIN_USER)
|
||||
page.locator("input[type='password']").first.fill(ADMIN_PASS)
|
||||
page.get_by_role("button").filter(has_text="Login").last.click()
|
||||
page.wait_for_url("**/home", timeout=15000)
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
|
||||
def assert_no_action_overflow(page):
|
||||
expect(page.get_by_role("heading", name="User Management")).to_be_visible(timeout=15000)
|
||||
expect(page.get_by_text("GPU Mem").first).to_be_visible(timeout=15000)
|
||||
overflow = page.evaluate("document.documentElement.scrollWidth > document.documentElement.clientWidth + 2")
|
||||
assert not overflow, "User Management page has horizontal document overflow"
|
||||
buttons = page.locator("button").filter(has_text="Limits")
|
||||
expect(buttons.first).to_be_visible(timeout=15000)
|
||||
viewport = page.viewport_size or {"width": 0, "height": 0}
|
||||
action_labels = ("To User", "To Admin", "Limits", "Disable", "Enable", "Delete")
|
||||
for label in action_labels:
|
||||
matches = page.get_by_role("button", name=label, exact=True)
|
||||
for index in range(min(matches.count(), 8)):
|
||||
box = matches.nth(index).bounding_box()
|
||||
if not box:
|
||||
continue
|
||||
assert box["x"] >= -1, f"{label} button overflows left viewport edge"
|
||||
assert box["x"] + box["width"] <= viewport["width"] + 1, f"{label} button overflows right viewport edge"
|
||||
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
for viewport in (
|
||||
{"width": 1440, "height": 900},
|
||||
{"width": 1280, "height": 900},
|
||||
{"width": 1024, "height": 800},
|
||||
{"width": 900, "height": 760},
|
||||
{"width": 768, "height": 900},
|
||||
):
|
||||
page = browser.new_page(viewport=viewport)
|
||||
login(page)
|
||||
page.get_by_role("button", name="Users", exact=True).click()
|
||||
page.wait_for_load_state("networkidle")
|
||||
page.wait_for_timeout(500)
|
||||
assert_no_action_overflow(page)
|
||||
page.close()
|
||||
browser.close()
|
||||
|
||||
print("PASS: user management layout")
|
||||
Reference in New Issue
Block a user