mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
test(ui): align source pickers and mock responses with current contracts
This commit is contained in:
parent
7f61c080bf
commit
358be285ee
9 changed files with 64 additions and 21 deletions
|
|
@ -215,8 +215,10 @@ def test_partial_account_refresh_keeps_draft_and_only_failed_account_history(acc
|
|||
assert "not in discovery" in suggestions(page, field)[DRAFT_MODEL]
|
||||
account.select_option("work")
|
||||
assert "not checked" in suggestions(page, field)[DRAFT_MODEL]
|
||||
assert row.locator("[data-subagent-status]").inner_text() == "Draft · Not checked"
|
||||
assert "model list could not be read" in row.locator("[data-subagent-meta]").inner_text()
|
||||
status = row.locator("[data-subagent-status]")
|
||||
assert status.inner_text() == "Draft · Not checked"
|
||||
# The unread account catalog is disclosed on the row's own status sentence.
|
||||
assert "model list could not be read" in status.get_attribute("title")
|
||||
account.select_option("")
|
||||
roles.capture(page, "account-catalog-partial-" + consumer.lower().replace(" ", "-"))
|
||||
assert_saved(ui, consumer, DRAFT_MODEL, "")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ def catalog(ui):
|
|||
|
||||
def select_model_field(ui, consumer):
|
||||
roles.configure_mixed(ui)
|
||||
# The catalog above is unprefixed, so every consumer is put on the same
|
||||
# OpenRouter API lane the suggestions belong to.
|
||||
lane = roles.api_lane(ui)
|
||||
if consumer in ['Scope', 'Deep']:
|
||||
slots = ui['fixture']['preview']['reviewer_slots']
|
||||
if consumer == 'Scope': slots['scope'] = [{'slot_id': 'scope_1', 'route': {'kind': 'api_chat', 'target_id': 'owner/model'}}]
|
||||
|
|
@ -33,15 +36,16 @@ def select_model_field(ui, consumer):
|
|||
page.locator('[data-settings-tab="models"]').click()
|
||||
if consumer == 'Fallback': page.locator('[data-model-add]').click()
|
||||
group = page.locator('[data-model-role="main"]') if consumer == 'Models' else page.locator('[data-model-role-group="fallback"] .model-role-row').first
|
||||
group.locator('[data-model-role-source]').select_option('openrouter')
|
||||
group.locator('[data-model-role-source]').select_option(lane)
|
||||
return page, group.locator('[data-model-role-model]')
|
||||
if consumer == "Actor":
|
||||
row = page.locator('[data-subagent-row]').nth(1)
|
||||
row.locator('[data-subagent-field="route"]').select_option(lane)
|
||||
return page, row.locator('[data-subagent-field="model"]')
|
||||
if consumer == 'Scope': return page, page.locator('[data-slot-id="scope_1"] [data-slot-custom-api]')
|
||||
if consumer == 'Deep': return page, page.locator('[data-deep-review-api-model]')
|
||||
row = page.locator('[data-slot-id="triad_1"]') if consumer == "Triad" else page.locator('[data-advisory-row]')
|
||||
row.locator('[data-slot-route], [data-advisory-route]').select_option('api')
|
||||
row.locator('[data-slot-route], [data-advisory-route]').select_option(lane)
|
||||
return page, row.locator('[data-slot-custom-api], [data-advisory-api-model]')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,15 @@ capture = setup_browser.capture
|
|||
|
||||
pytestmark = [pytest.mark.ui_browser, pytest.mark.serial]
|
||||
TASK = "analysis-task"
|
||||
# The wait picker offers an API lane per provider whose credential is stored.
|
||||
API_LANE = "api:openai"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def waiting_ui(subscription_ui):
|
||||
ui = subscription_ui
|
||||
page = ui["page"]
|
||||
ui["settings"]["OPENAI_API_KEY"] = "***set***"
|
||||
rows = {
|
||||
key: {"wait_id": key, "revision": 1, "task_attempt": 1, "role": role,
|
||||
"model": "claudexor::codex=gpt-test", "source": "codex",
|
||||
|
|
@ -162,7 +165,7 @@ def test_multiple_waits_toggle_and_exact_role_switch_wait_for_application(waitin
|
|||
page.wait_for_selector('[data-wait-id="light-wait"] [data-wait-change]:not([disabled])')
|
||||
assert not light.locator('[data-wait-auto]').is_checked()
|
||||
light.locator('[data-wait-change]').click()
|
||||
light.locator('[data-model-role-source]').select_option('openai')
|
||||
light.locator('[data-model-role-source]').select_option(API_LANE)
|
||||
light.locator('[data-model-role-model]').fill('owner-model')
|
||||
assert not light.locator('[data-wait-persist]').is_checked()
|
||||
light.locator('[data-wait-apply]').click()
|
||||
|
|
@ -320,7 +323,7 @@ def test_wait_reconnect_preserves_unsubmitted_form_without_context_or_animation(
|
|||
field = row.locator('[data-model-role-model]')
|
||||
field.wait_for()
|
||||
assert row.locator('.model-role-details').count() == 0
|
||||
row.locator('[data-model-role-source]').select_option('openai')
|
||||
row.locator('[data-model-role-source]').select_option(API_LANE)
|
||||
assert row.locator('.model-role-details').count() == 0
|
||||
field.fill('unfinished-owner-model')
|
||||
row.locator('[data-wait-persist]').check()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from ouroboros import model_wait, owner_mailbox
|
|||
from ouroboros.task_results import load_task_result
|
||||
from tests.test_llm_claudexor import setup as subscription_transport
|
||||
from tests.test_model_wait import live_wait as wait_fixture
|
||||
from tests.test_model_wait_browser import TASK, waiting_ui as waiting_fixture
|
||||
from tests.test_model_wait_browser import API_LANE, TASK, waiting_ui as waiting_fixture
|
||||
from tests.test_subscription_setup_browser import subscription_ui as ui_fixture, capture
|
||||
|
||||
setup = subscription_transport
|
||||
|
|
@ -97,7 +97,7 @@ def test_fallback_local_change_discloses_task_only_and_keeps_other_roles(waiting
|
|||
waiter = page.locator('[data-wait-id="light-wait"]')
|
||||
waiter.locator('[data-wait-role]').filter(has_text="Fallback 2").wait_for()
|
||||
waiter.locator('[data-wait-change]').click()
|
||||
waiter.locator('[data-model-role-source]').select_option("openai")
|
||||
waiter.locator('[data-model-role-source]').select_option(API_LANE)
|
||||
waiter.locator('[data-model-role-model]').fill("replacement")
|
||||
local = waiter.locator('[data-model-local]')
|
||||
persist = waiter.locator('[data-wait-persist]')
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ def test_onboarding_processing_draft_returns_and_reaches_finish(subscription_ui)
|
|||
main.locator('summary').click()
|
||||
main.locator('[data-model-role-processing]').select_option('standard')
|
||||
page.locator('#next-btn').click()
|
||||
page.wait_for_selector('#reviewer-slots-section')
|
||||
page.wait_for_selector('[data-collapse="reviewers"]')
|
||||
page.locator('#back-btn').click()
|
||||
page.wait_for_selector('[data-global-processing]')
|
||||
assert page.locator('[data-global-processing]').input_value() == 'fast'
|
||||
|
|
|
|||
|
|
@ -9,6 +9,15 @@ from tests import test_subscription_setup_browser as setup_browser
|
|||
pytestmark = [pytest.mark.ui_browser, pytest.mark.serial]
|
||||
subscription_ui = setup_browser.subscription_ui
|
||||
capture = setup_browser.capture
|
||||
# Every route picker offers an API lane per provider whose credential is
|
||||
# stored, so a fixture that selects one advertises that provider's key first.
|
||||
API_KEYS = {"openrouter": "OPENROUTER_API_KEY", "openai": "OPENAI_API_KEY"}
|
||||
|
||||
|
||||
def api_lane(ui, provider="openrouter"):
|
||||
"""Store `provider`'s key in the served settings and return its route choice."""
|
||||
ui["settings"][API_KEYS[provider]] = "***set***"
|
||||
return f"api:{provider}"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -72,6 +81,7 @@ def open_agents(ui):
|
|||
|
||||
def test_reviewer_source_roundtrip_restores_its_own_model_and_account(role_ui):
|
||||
configure_mixed(role_ui)
|
||||
lane = api_lane(role_ui, 'openai')
|
||||
page = open_agents(role_ui)
|
||||
for selector, model_field, account_field in [
|
||||
('[data-slot-id="triad_1"]', '[data-slot-custom-api]', '[data-slot-profile]'),
|
||||
|
|
@ -79,13 +89,15 @@ def test_reviewer_source_roundtrip_restores_its_own_model_and_account(role_ui):
|
|||
]:
|
||||
row = page.locator(selector)
|
||||
route = row.locator('[data-slot-route], [data-advisory-route]')
|
||||
route.select_option('api')
|
||||
row.locator(model_field).fill('openai::other-choice')
|
||||
route.select_option(lane)
|
||||
# The chooser holds the model alone; the source select names the provider.
|
||||
row.locator(model_field).fill('other-choice')
|
||||
route.select_option('subscription:opaque-source')
|
||||
assert row.locator(model_field).input_value() == 'gpt-test'
|
||||
assert row.locator(account_field).input_value() == 'personal'
|
||||
route.select_option('api')
|
||||
assert row.locator(model_field).input_value() == 'openai::other-choice'
|
||||
route.select_option(lane)
|
||||
assert row.locator(model_field).input_value() == 'other-choice'
|
||||
assert route.input_value() == lane
|
||||
route.select_option('subscription:opaque-source')
|
||||
page.locator('[data-advisory-row]').scroll_into_view_if_needed()
|
||||
capture(page, "reviewer-source-roundtrip-restored")
|
||||
|
|
@ -93,7 +105,7 @@ def test_reviewer_source_roundtrip_restores_its_own_model_and_account(role_ui):
|
|||
with page.expect_response('**/api/reviewer-slots'):
|
||||
page.locator('#btn-reload-settings').click()
|
||||
page.get_by_role('button', name='Discard and continue', exact=True).click()
|
||||
page.locator('[data-advisory-route]').select_option('api')
|
||||
page.locator('[data-advisory-route]').select_option(lane)
|
||||
assert page.locator('[data-advisory-api-model]').input_value() == ''
|
||||
|
||||
|
||||
|
|
@ -164,9 +176,10 @@ def test_subscription_accounts_roundtrip_existing_editors(role_ui, width):
|
|||
def test_source_switch_and_catalog_refresh_keep_focus_and_draft(role_ui):
|
||||
ui = role_ui
|
||||
configure_mixed(ui)
|
||||
lane = api_lane(ui, 'openai')
|
||||
page = open_agents(ui)
|
||||
triad = page.locator('[data-slot-id="triad_1"]')
|
||||
triad.locator('[data-slot-route]').select_option("api")
|
||||
triad.locator('[data-slot-route]').select_option(lane)
|
||||
assert triad.locator('[data-slot-profile]').count() == 0
|
||||
triad.locator('[data-slot-custom-api]').fill("openai::gpt-api")
|
||||
triad.locator('[data-slot-route]').select_option("subscription:opaque-source")
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ def integrated_wait(subscription_ui, live_wait, monkeypatch):
|
|||
config.SETTINGS_PATH.write_text(json.dumps(settings), encoding="utf-8")
|
||||
original_settings = config.SETTINGS_PATH.read_bytes()
|
||||
ui["settings"].update(settings)
|
||||
# The wait picker offers an API lane per provider whose credential is stored.
|
||||
ui["settings"]["OPENAI_API_KEY"] = "***set***"
|
||||
|
||||
source_entered, source_release = threading.Event(), threading.Event()
|
||||
catalog_entered, catalog_release = threading.Event(), threading.Event()
|
||||
|
|
@ -265,7 +267,7 @@ def test_browser_wait_controls_apply_once_and_only_to_light(integrated_wait, per
|
|||
assert not row.locator("[data-wait-auto]").is_checked()
|
||||
|
||||
row.locator("[data-wait-change]").click()
|
||||
row.locator("[data-model-role-source]").select_option("openai")
|
||||
row.locator("[data-model-role-source]").select_option("api:openai")
|
||||
row.locator("[data-model-role-model]").fill("owner-model")
|
||||
assert not row.locator("[data-wait-persist]").is_checked()
|
||||
if persist_role:
|
||||
|
|
|
|||
|
|
@ -99,12 +99,29 @@ def test_large_attachment_returns_through_real_document_handler_and_download(
|
|||
"name": "send_file", "arguments": json.dumps({"file_path": str(staged[0]), "caption": "Complete large dataset"}),
|
||||
},
|
||||
}]}
|
||||
finish = "tool_calls" if message.get("tool_calls") else "stop"
|
||||
payload = {"id": "mock-large-file", "object": "chat.completion",
|
||||
"choices": [{"message": message, "finish_reason": "tool_calls" if message.get("tool_calls") else "stop"}],
|
||||
"model": request.get("model") or "mock-model",
|
||||
"choices": [{"index": 0, "message": message, "finish_reason": finish}],
|
||||
"usage": {"prompt_tokens": 1, "completion_tokens": 1, "total_tokens": 2}}
|
||||
data = json.dumps(payload).encode()
|
||||
content_type = "application/json"
|
||||
if request.get("stream"):
|
||||
# The main loop streams every completion: answer in SSE frames with
|
||||
# the terminal framing the assembler requires.
|
||||
content_type = "text/event-stream"
|
||||
delta = dict(message)
|
||||
if delta.get("tool_calls"):
|
||||
delta["tool_calls"] = [dict(call, index=index)
|
||||
for index, call in enumerate(delta["tool_calls"])]
|
||||
common = {"id": payload["id"], "model": payload["model"], "object": "chat.completion.chunk"}
|
||||
frames = [{**common, "choices": [{"index": 0, "delta": delta, "finish_reason": finish}]},
|
||||
{**common, "choices": [], "usage": payload["usage"]}]
|
||||
data = ("".join("data: " + json.dumps(frame) + "\n\n" for frame in frames)
|
||||
+ "data: [DONE]\n\n").encode()
|
||||
else:
|
||||
data = json.dumps(payload).encode()
|
||||
handler.send_response(200)
|
||||
handler.send_header("Content-Type", "application/json")
|
||||
handler.send_header("Content-Type", content_type)
|
||||
handler.send_header("Content-Length", str(len(data)))
|
||||
handler.end_headers()
|
||||
handler.wfile.write(data)
|
||||
|
|
|
|||
|
|
@ -211,6 +211,8 @@ def test_initial_settings_document_survives_early_edit_while_enrichment_waits(su
|
|||
ui, pending = subscription_ui, {"reviewers": [], "status": [], "catalog": []}
|
||||
page = ui["page"]
|
||||
ui["settings"]["OUROBOROS_MODEL"] = "claudexor::opaque-source=gpt-test"
|
||||
# An API lane is offered per provider whose credential is stored.
|
||||
ui["settings"]["OPENROUTER_API_KEY"] = "***set***"
|
||||
ui["fixture"]["catalog"]["model_sources"] = [
|
||||
{"id": "opaque-source", "label": "Managed models", "credentialHarness": "codex"},
|
||||
]
|
||||
|
|
@ -225,7 +227,7 @@ def test_initial_settings_document_survives_early_edit_while_enrichment_waits(su
|
|||
assert pending["status"], "the status read must still be pending"
|
||||
assert page.locator('#btn-save-settings').is_enabled(), "the known document can be saved before enrichment"
|
||||
source = main.locator('[data-model-role-source]')
|
||||
source.select_option("openrouter")
|
||||
source.select_option("api:openrouter")
|
||||
model = main.locator('[data-model-role-model]')
|
||||
model.fill("owner-kept-model")
|
||||
model.evaluate("element => { window.__earlyModel = element; element.setSelectionRange(4, 4); }")
|
||||
|
|
@ -245,7 +247,7 @@ def test_initial_settings_document_survives_early_edit_while_enrichment_waits(su
|
|||
page.wait_for_function("""() => document.querySelector('[data-model-role="main"] [data-model-role-source]')
|
||||
.querySelector('option[value="subscription:opaque-source"]')""")
|
||||
expect(model).to_have_value("owner-kept-model")
|
||||
assert source.input_value() == "openrouter"
|
||||
assert source.input_value() == "api:openrouter"
|
||||
assert model.evaluate("element => element === window.__earlyModel && element.selectionStart === 4")
|
||||
expect(page.locator('#settings-unsaved-indicator')).to_have_class(re.compile('is-visible'))
|
||||
expect(page.locator('#btn-save-settings')).to_be_enabled()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue