// test_webui.cpp — Browser-based E2E tests for Ch5 Web UI. // Uses webdriver.h (cpp-httplib + json.hpp) to control headless Firefox. // // Usage: test_webui // port: the translate-server port (e.g. 18080) #include "webdriver.h" #include #include #include // ─── Test framework (minimal) ──────────────────────────────── static int pass_count = 0; static int fail_count = 0; #define PASS(label) \ do { \ std::cout << " PASS: " << (label) << "\n"; \ ++pass_count; \ } while (0) #define FAIL(label, detail) \ do { \ std::cout << " FAIL: " << (label) << "\n"; \ std::cout << " " << (detail) << "\n"; \ ++fail_count; \ } while (0) #define ASSERT_TRUE(cond, label) \ do { \ if (cond) { \ PASS(label); \ } else { \ FAIL(label, "condition was false"); \ } \ } while (0) #define ASSERT_CONTAINS(haystack, needle, label) \ do { \ if (std::string(haystack).find(needle) != std::string::npos) { \ PASS(label); \ } else { \ FAIL(label, "'" + std::string(haystack) + "' does not contain '" + \ std::string(needle) + "'"); \ } \ } while (0) #define ASSERT_ELEMENT_EXISTS(session, selector) \ do { \ try { \ (session).css(selector); \ PASS("Element " selector " exists"); \ } catch (...) { FAIL("Element " selector " exists", "not found"); } \ } while (0) // ─── Helpers ───────────────────────────────────────────────── static std::string base_url; void navigate_and_wait_for_models(webdriver::Session &session) { session.navigate(base_url); session.wait_until( "return document.querySelectorAll('#model-select option').length > 0", 5000); } void test_page_loads(webdriver::Session &session) { std::cout << "=== TC1: Page loads with correct structure\n"; session.navigate(base_url); auto title = session.title(); ASSERT_CONTAINS(title, "Translate", "Page title contains 'Translate'"); // Verify main DOM elements exist ASSERT_ELEMENT_EXISTS(session, "#model-select"); ASSERT_ELEMENT_EXISTS(session, "#input-text"); ASSERT_ELEMENT_EXISTS(session, "#output-text"); ASSERT_ELEMENT_EXISTS(session, "#target-lang"); } void test_model_dropdown(webdriver::Session &session) { std::cout << "=== TC2: Model dropdown is populated\n"; navigate_and_wait_for_models(session); // Note: WebDriver findElements cannot find