You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
7.6 KiB
192 lines
7.6 KiB
# -*- coding: utf-8 -*-
|
|
from playwright.sync_api import sync_playwright
|
|
import sys, io
|
|
import re
|
|
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
|
|
def run():
|
|
with sync_playwright() as p:
|
|
browser = p.chromium.launch(headless=True)
|
|
page = browser.new_page(viewport={'width': 1440, 'height': 900})
|
|
|
|
errors = []
|
|
page.on('pageerror', lambda err: errors.append(f'PAGE_ERR: {str(err)[:200]}'))
|
|
|
|
page.goto('http://localhost:5173', wait_until='networkidle', timeout=30000)
|
|
page.wait_for_timeout(1000)
|
|
|
|
# Login
|
|
page.locator('input[type="text"]').first.fill('admin')
|
|
page.locator('input[type="password"]').first.fill('admin123')
|
|
page.locator('button').first.click()
|
|
page.wait_for_timeout(3000)
|
|
|
|
# =====================================================
|
|
# TEST: Model Config modal - check select visibility
|
|
# =====================================================
|
|
print('=' * 60)
|
|
print('TEST: Model Config 弹窗控件可见性')
|
|
print('=' * 60)
|
|
|
|
page.evaluate('window.location.hash = "/settings/model-config"')
|
|
page.wait_for_timeout(2000)
|
|
page.screenshot(path='/tmp/report_model_before.png', full_page=True)
|
|
|
|
# Click new config button
|
|
add_btn = page.locator('button:has-text("新建配置")')
|
|
if add_btn.count() > 0:
|
|
add_btn.first.click()
|
|
page.wait_for_timeout(1500)
|
|
page.screenshot(path='/tmp/report_model_modal.png', full_page=True)
|
|
|
|
# Get all selects in dialog
|
|
all_selects = page.locator('.t-dialog .t-select__wrap').all()
|
|
print(f'弹窗中所有 t-select__wrap: {len(all_selects)}')
|
|
for i, s in enumerate(all_selects):
|
|
visible = s.is_visible()
|
|
bb = s.bounding_box()
|
|
print(f' 下拉{i}: visible={visible}, box={bb}')
|
|
|
|
# Check provider select specially
|
|
provider_select = page.locator('.t-dialog .t-select__wrap').nth(1) # second select
|
|
print(f'\nProvider select visible: {provider_select.is_visible()}')
|
|
print(f'Provider select box: {provider_select.bounding_box()}')
|
|
|
|
# Check model input
|
|
model_input = page.locator('.t-dialog input[placeholder*="模型名称"]')
|
|
print(f'Model input count: {model_input.count()}')
|
|
|
|
# Count ALL inputs in dialog
|
|
all_inputs = page.locator('.t-dialog input:not([type="hidden"])')
|
|
print(f'\nAll dialog inputs: {all_inputs.count()}')
|
|
for i, inp in enumerate(all_inputs.all()[:15]):
|
|
tp = inp.get_attribute('type') or 'text'
|
|
ph = inp.get_attribute('placeholder') or ''
|
|
vis = inp.is_visible()
|
|
print(f' input{i}: type={tp}, placeholder="{ph[:40]}", visible={vis}')
|
|
|
|
page.keyboard.press('Escape')
|
|
page.wait_for_timeout(500)
|
|
|
|
# =====================================================
|
|
# TEST: Check the appType filter select in toolbar
|
|
# =====================================================
|
|
print('\n' + '=' * 60)
|
|
print('TEST: 页面工具栏下拉控件')
|
|
print('=' * 60)
|
|
|
|
# Back to model config page
|
|
toolbar_selects = page.locator('.t-select__wrap, .t-select').all()
|
|
visible_selects = [s for s in toolbar_selects if s.is_visible()]
|
|
print(f'可见下拉总数: {len(visible_selects)}')
|
|
|
|
# =====================================================
|
|
# TEST: Doc upload modal
|
|
# =====================================================
|
|
print('\n' + '=' * 60)
|
|
print('TEST: 文档管理 - 上传弹窗')
|
|
print('=' * 60)
|
|
|
|
page.evaluate('window.location.hash = "/knowledge/document"')
|
|
page.wait_for_timeout(2000)
|
|
|
|
# 检查页面上的上传按钮 - 在旧代码中是 .upload-area 或按钮
|
|
upload_triggers = page.locator('button').all()
|
|
upload_found = False
|
|
for btn in upload_triggers:
|
|
text = btn.inner_text() if btn.is_visible() else ''
|
|
if '上传' in text:
|
|
print(f'找到上传相关按钮: "{text}"')
|
|
btn.click()
|
|
page.wait_for_timeout(1000)
|
|
upload_found = True
|
|
page.screenshot(path='/tmp/report_upload_modal.png', full_page=True)
|
|
page.keyboard.press('Escape')
|
|
page.wait_for_timeout(500)
|
|
break
|
|
|
|
if not upload_found:
|
|
print('WARNING: 未找到上传按钮')
|
|
|
|
# =====================================================
|
|
# TEST: FAQ modal - check selects
|
|
# =====================================================
|
|
print('\n' + '=' * 60)
|
|
print('TEST: FAQ 弹窗 - 下拉控件详情')
|
|
print('=' * 60)
|
|
|
|
page.evaluate('window.location.hash = "/knowledge/faq"')
|
|
page.wait_for_timeout(2000)
|
|
|
|
add_faq = page.locator('button:has-text("添加 FAQ")')
|
|
if add_faq.count() > 0:
|
|
add_faq.first.click()
|
|
page.wait_for_timeout(1000)
|
|
page.screenshot(path='/tmp/report_faq_modal.png', full_page=True)
|
|
|
|
faq_selects = page.locator('.t-dialog .t-select__wrap').all()
|
|
for i, ds in enumerate(faq_selects):
|
|
visible = ds.is_visible()
|
|
bb = ds.bounding_box()
|
|
print(f' FAQ弹窗下拉{i}: visible={visible}, box={bb}')
|
|
|
|
page.keyboard.press('Escape')
|
|
page.wait_for_timeout(500)
|
|
|
|
# =====================================================
|
|
# TEST: Sensitive word modal - check selects
|
|
# =====================================================
|
|
print('\n' + '=' * 60)
|
|
print('TEST: 敏感词弹窗 - 下拉控件详情')
|
|
print('=' * 60)
|
|
|
|
page.evaluate('window.location.hash = "/settings/sensitive"')
|
|
page.wait_for_timeout(2000)
|
|
|
|
add_sw = page.locator('button:has-text("添加敏感词")')
|
|
if add_sw.count() > 0:
|
|
add_sw.first.click()
|
|
page.wait_for_timeout(1000)
|
|
page.screenshot(path='/tmp/report_sensitive_modal.png', full_page=True)
|
|
|
|
sw_selects = page.locator('.t-dialog .t-select__wrap').all()
|
|
for i, ds in enumerate(sw_selects):
|
|
visible = ds.is_visible()
|
|
bb = ds.bounding_box()
|
|
print(f' 敏感词弹窗下拉{i}: visible={visible}, box={bb}')
|
|
if visible:
|
|
try:
|
|
ds.click()
|
|
page.wait_for_timeout(400)
|
|
opts = page.locator('.t-select-option').all()
|
|
print(f' 展开选项数: {len(opts)}')
|
|
for o in opts:
|
|
print(f' - {o.inner_text()[:50]}')
|
|
page.keyboard.press('Escape')
|
|
page.wait_for_timeout(200)
|
|
except Exception as e:
|
|
print(f' 展开异常: {e}')
|
|
|
|
page.keyboard.press('Escape')
|
|
page.wait_for_timeout(500)
|
|
|
|
# =====================================================
|
|
# FINAL SUMMARY
|
|
# =====================================================
|
|
print('\n' + '=' * 60)
|
|
print('FINAL SUMMARY')
|
|
print('=' * 60)
|
|
|
|
if errors:
|
|
unique_errs = list(set(errors))
|
|
print(f'PAGE ERRORS ({len(unique_errs)}):')
|
|
for e in unique_errs:
|
|
print(f' {e}')
|
|
else:
|
|
print('NO PAGE ERRORS')
|
|
|
|
browser.close()
|
|
|
|
if __name__ == '__main__':
|
|
run()
|