mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-05-03 16:57:48 +08:00
328 lines
9.3 KiB
Python
328 lines
9.3 KiB
Python
import re
|
|
import os
|
|
import pytest
|
|
from playwright.sync_api import expect
|
|
|
|
from test.playwright.helpers.flow_steps import flow_params, require
|
|
from test.playwright.helpers.auth_selectors import EMAIL_INPUT, PASSWORD_INPUT, SUBMIT_BUTTON
|
|
from test.playwright.helpers.auth_waits import wait_for_login_complete
|
|
from test.playwright.helpers.response_capture import capture_response
|
|
from test.playwright.helpers.model_providers import (
|
|
open_user_settings,
|
|
safe_close_modal,
|
|
select_default_model,
|
|
)
|
|
|
|
RESULT_TIMEOUT_MS = 15000
|
|
|
|
|
|
def step_01_open_login(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
api_key = os.getenv("ZHIPU_AI_API_KEY")
|
|
if not api_key:
|
|
pytest.skip("ZHIPU_AI_API_KEY not set; skipping model providers test.")
|
|
|
|
email, password = seeded_user_credentials
|
|
|
|
flow_state["api_key"] = api_key
|
|
flow_state["email"] = email
|
|
flow_state["password"] = password
|
|
|
|
with step("open login page"):
|
|
flow_page.goto(login_url, wait_until="domcontentloaded")
|
|
flow_state["login_opened"] = True
|
|
snap("login_opened")
|
|
|
|
|
|
def step_02_login(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "login_opened", "email", "password")
|
|
page = flow_page
|
|
form, _ = active_auth_context()
|
|
email_input = form.locator(EMAIL_INPUT)
|
|
password_input = form.locator(PASSWORD_INPUT)
|
|
with step("fill credentials"):
|
|
expect(email_input).to_have_count(1)
|
|
expect(password_input).to_have_count(1)
|
|
email_input.fill(flow_state["email"])
|
|
password_input.fill(flow_state["password"])
|
|
password_input.blur()
|
|
|
|
with step("submit login"):
|
|
submit_button = form.locator(SUBMIT_BUTTON)
|
|
expect(submit_button).to_have_count(1)
|
|
auth_click(submit_button, "submit_login")
|
|
|
|
with step("wait for login"):
|
|
wait_for_login_complete(page, timeout_ms=RESULT_TIMEOUT_MS)
|
|
|
|
flow_state["logged_in"] = True
|
|
snap("home_loaded")
|
|
|
|
|
|
def step_03_open_settings(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "logged_in")
|
|
page = flow_page
|
|
with step("open settings"):
|
|
open_user_settings(page, base_url)
|
|
flow_state["settings_open"] = True
|
|
snap("settings_opened")
|
|
|
|
|
|
def step_04_open_model_providers(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "settings_open")
|
|
page = flow_page
|
|
with step("open model providers"):
|
|
model_nav = page.locator("[data-testid='settings-nav-model-providers']")
|
|
expect(model_nav).to_have_count(1)
|
|
model_nav.first.click()
|
|
expect(page.locator("text=Set default models")).to_be_visible()
|
|
flow_state["model_providers_open"] = True
|
|
snap("model_providers_open")
|
|
|
|
|
|
def step_05_filter_zhipu(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "model_providers_open")
|
|
page = flow_page
|
|
with step("filter providers"):
|
|
search_input = page.locator("[data-testid='model-providers-search']")
|
|
expect(search_input).to_have_count(1)
|
|
search_input.first.fill("zhipu")
|
|
available_section = page.locator("[data-testid='available-models-section']")
|
|
provider = available_section.locator(
|
|
"[data-testid='available-model-card'][data-provider='ZHIPU-AI']"
|
|
).first
|
|
if provider.count() == 0:
|
|
added_section = page.locator("[data-testid='added-models-section']")
|
|
if (
|
|
added_section.locator(
|
|
"[data-testid='added-model-card'][data-provider='ZHIPU-AI']"
|
|
).count()
|
|
== 0
|
|
):
|
|
raise AssertionError("ZHIPU-AI provider not found in available or added models.")
|
|
else:
|
|
expect(provider).to_be_visible()
|
|
flow_state["provider_filtered"] = True
|
|
snap("provider_filtered")
|
|
|
|
|
|
def step_06_add_api_key(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "provider_filtered", "api_key")
|
|
page = flow_page
|
|
available_section = page.locator("[data-testid='available-models-section']")
|
|
provider = available_section.locator(
|
|
"[data-testid='available-model-card'][data-provider='ZHIPU-AI']"
|
|
).first
|
|
|
|
with step("add ZHIPU-AI api key"):
|
|
if provider.count() > 0:
|
|
provider.click()
|
|
else:
|
|
added_section = page.locator("[data-testid='added-models-section']")
|
|
card = added_section.locator(
|
|
"[data-testid='added-model-card'][data-provider='ZHIPU-AI']"
|
|
).first
|
|
api_key_button = card.locator("button", has_text=re.compile("API-?Key", re.I)).first
|
|
expect(api_key_button).to_be_visible()
|
|
api_key_button.click()
|
|
modal = page.locator("[data-testid='apikey-modal']")
|
|
expect(modal).to_be_visible()
|
|
api_input = modal.locator("[data-testid='apikey-input']").first
|
|
save_button = modal.locator("[data-testid='apikey-save']").first
|
|
try:
|
|
def trigger():
|
|
api_input.fill(flow_state["api_key"])
|
|
save_button.click()
|
|
|
|
capture_response(
|
|
page,
|
|
trigger,
|
|
lambda resp: resp.request.method == "POST" and "/v1/llm/set_api_key" in resp.url,
|
|
)
|
|
expect(modal).not_to_be_visible(timeout=RESULT_TIMEOUT_MS)
|
|
except Exception:
|
|
safe_close_modal(modal)
|
|
raise
|
|
|
|
with step("confirm added model"):
|
|
added_section = page.locator("[data-testid='added-models-section']")
|
|
expect(added_section).to_be_visible()
|
|
expect(
|
|
added_section.locator(
|
|
"[data-testid='added-model-card'][data-provider='ZHIPU-AI']"
|
|
)
|
|
).to_be_visible()
|
|
flow_state["provider_added"] = True
|
|
snap("provider_saved")
|
|
|
|
|
|
def step_07_set_defaults(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "provider_added")
|
|
page = flow_page
|
|
with step("set default models"):
|
|
llm_combo = page.locator("[data-testid='default-llm-combobox']").first
|
|
emb_combo = page.locator("[data-testid='default-embedding-combobox']").first
|
|
|
|
select_default_model(
|
|
page,
|
|
expect,
|
|
llm_combo,
|
|
"glm-4-flash@ZHIPU-AI",
|
|
"glm-4-flash",
|
|
list_testid="default-llm-options",
|
|
fallback_to_first=False,
|
|
timeout_ms=RESULT_TIMEOUT_MS,
|
|
)
|
|
selected_emb_text, _ = select_default_model(
|
|
page,
|
|
expect,
|
|
emb_combo,
|
|
"embedding-2@ZHIPU-AI",
|
|
"embedding-2",
|
|
list_testid="default-embedding-options",
|
|
fallback_to_first=True,
|
|
timeout_ms=RESULT_TIMEOUT_MS,
|
|
)
|
|
flow_state["selected_emb_text"] = selected_emb_text
|
|
flow_state["defaults_set"] = True
|
|
snap("defaults_selected")
|
|
|
|
|
|
def step_08_verify_persist(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
require(flow_state, "defaults_set")
|
|
page = flow_page
|
|
with step("reload and verify defaults"):
|
|
page.reload(wait_until="domcontentloaded")
|
|
expect(page.locator("text=Set default models")).to_be_visible()
|
|
llm_combo = page.locator("[data-testid='default-llm-combobox']").first
|
|
emb_combo = page.locator("[data-testid='default-embedding-combobox']").first
|
|
expect(llm_combo).to_contain_text("glm-4-flash")
|
|
expect(emb_combo).to_contain_text(flow_state.get("selected_emb_text") or "embedding-2")
|
|
added_section = page.locator("[data-testid='added-models-section']")
|
|
expect(
|
|
added_section.locator(
|
|
"[data-testid='added-model-card'][data-provider='ZHIPU-AI']"
|
|
)
|
|
).to_be_visible()
|
|
snap("defaults_persisted")
|
|
snap("success")
|
|
|
|
|
|
STEPS = [
|
|
("01_open_login", step_01_open_login),
|
|
("02_login", step_02_login),
|
|
("03_open_settings", step_03_open_settings),
|
|
("04_open_model_providers", step_04_open_model_providers),
|
|
("05_filter_zhipu", step_05_filter_zhipu),
|
|
("06_add_api_key", step_06_add_api_key),
|
|
("07_set_defaults", step_07_set_defaults),
|
|
("08_verify_persist", step_08_verify_persist),
|
|
]
|
|
|
|
|
|
@pytest.mark.p1
|
|
@pytest.mark.auth
|
|
@pytest.mark.parametrize("step_fn", flow_params(STEPS))
|
|
def test_add_zhipu_ai_set_defaults_persist_flow(
|
|
step_fn,
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
):
|
|
step_fn(
|
|
flow_page,
|
|
flow_state,
|
|
base_url,
|
|
login_url,
|
|
active_auth_context,
|
|
step,
|
|
snap,
|
|
auth_click,
|
|
seeded_user_credentials,
|
|
)
|