"""App loading tests — verify the sm3sh app renders in the browser.""" import json import time import pytest import websocket from selenium.webdriver.common.by import By from nostr_helpers import TEST_SECKEY, TEST_PUBKEY, make_event class TestAppLoad: """Verify the app loads and renders basic UI.""" def test_page_loads(self, relay, browser): browser.get(relay["url"]) time.sleep(2) title = browser.title assert "smesh" in title.lower() def test_root_element(self, relay, browser, h): browser.get(relay["url"]) time.sleep(2) root = browser.find_element(By.ID, "app-root") assert root is not None # The root should have children (the app rendered). children = root.find_elements(By.XPATH, "./*") assert len(children) > 0, "app-root has no children — JS may have failed" def test_console_log_version(self, relay, browser, h): browser.get(relay["url"]) time.sleep(2) # The app logs "starting smesh " on init. version = h.js("return document.querySelector('[data-version]')?.getAttribute('data-version')") assert version is not None, "data-version attribute not found" def test_login_screen(self, relay, browser, h): """Without a stored pubkey, the app should show a login screen.""" # Clear localStorage to ensure clean state. browser.get(relay["url"]) time.sleep(1) h.js("localStorage.clear()") browser.refresh() time.sleep(2) # Look for login-related elements (button or input). page = h.js("return document.body.innerText") assert page is not None class TestFeed: """Verify the kind-1 note feed renders.""" def test_feed_notes_appear(self, relay, browser, h): """Seed events to local relay, then verify feed renders them.""" # Publish a few kind-1 notes to the local relay via WebSocket. ws = websocket.create_connection(relay["ws"]) for i in range(3): ev = make_event(TEST_SECKEY, f"test note {i}") ws.send(json.dumps(["EVENT", ev])) resp = ws.recv() ws.close() # Load app with the test pubkey. browser.get(relay["url"]) time.sleep(1) h.js(f"localStorage.setItem('smesh-pubkey', '{TEST_PUBKEY}')") browser.get(relay["url"]) time.sleep(12) notes = h.js("return document.querySelectorAll('div[style*=\"border-bottom\"]').length") assert notes > 0, "no kind-1 notes rendered in the feed" class TestAppTheme: """Theme toggle works.""" def test_dark_mode_toggle(self, relay, browser, h): browser.get(relay["url"]) time.sleep(2) has_dark = h.js("return document.body.classList.contains('dark')") # Toggle — find any button in the top bar area. # The theme button is a small button with a sun/moon emoji. # We can't easily target it by text since it's an HTML entity, # so we'll check the class toggles by setting localStorage. h.js("localStorage.setItem('smesh-theme', 'dark')") browser.refresh() time.sleep(2) is_dark = h.js("return document.body.classList.contains('dark')") assert is_dark, "dark class not applied after setting theme preference" h.js("localStorage.setItem('smesh-theme', 'light')") browser.refresh() time.sleep(2) is_light = not h.js("return document.body.classList.contains('dark')") assert is_light, "dark class still present after setting light theme"