"""Manage holdings' "+ Add an instrument", driven in a real browser. Its lookup kept the first answer it gave: a NASDAQ ticker typed before its exchange was changed stayed on the ASX guess, CODE.AX, which has no prices. The lookup's own answers now give way to the next one, and typed text never does. The class comes from the answer too, as it does when recording a trade. """ from __future__ import annotations import json import re import subprocess import pytest from test_trade_dialog_in_the_browser import CHROME, HTML, _standalone import factories as fac from test_routes import bind_to_only_portfolio, make_login pytestmark = pytest.mark.visual BY_EXCHANGE = """ """ DRIVER = """ """ def test_changing_the_exchange_looks_the_ticker_up_again(client, session_factory, tmp_path): make_login(client, session_factory) page = client.get("/holdings", headers=HTML) assert page.status_code == 200 target = tmp_path / "holdings.html" target.write_text(_standalone(page.text, DRIVER).replace("
", "" + BY_EXCHANGE, 1), encoding="utf-8") dom = subprocess.run( [CHROME, "--headless", "--disable-gpu", "--dump-dom", "--no-sandbox", "--allow-file-access-from-files", "--window-size=1400,1000", "--virtual-time-budget=8000", target.as_uri()], capture_output=True, text=True, timeout=90).stdout found = re.search(r'(.*?)', dom, re.S) assert found, "the driver did not finish" out = json.loads(found.group(1).replace(""", '"')) assert out["onTheAsx"] == "GOOG.AX" assert out["onNasdaq"] == {"symbol": "GOOG", "name": "Alphabet Inc.", "currency": "USD", "cls": "share"} assert out["typedKept"] == {"symbol": "GOOGL", "cls": "etf"} # The ASX answer is slow and the NASDAQ one quick, so the ASX one lands last. LATE_ASX = """ """ RACE = """ """ def test_an_answer_that_arrives_late_does_not_overwrite_a_newer_one( client, session_factory, tmp_path): make_login(client, session_factory) page = client.get("/holdings", headers=HTML) target = tmp_path / "holdings.html" target.write_text(_standalone(page.text, RACE).replace("", "" + LATE_ASX, 1), encoding="utf-8") dom = subprocess.run( [CHROME, "--headless", "--disable-gpu", "--dump-dom", "--no-sandbox", "--allow-file-access-from-files", "--window-size=1400,1000", "--virtual-time-budget=8000", target.as_uri()], capture_output=True, text=True, timeout=90).stdout found = re.search(r'
(.*?)', dom, re.S) assert found, "the driver did not finish" assert json.loads(found.group(1).replace(""", '"')) == { "symbol": "GOOG", "name": "Alphabet Inc.", "currency": "USD"} # The page's own rows have fields named like the dialog's: name, currency, # yahoo_symbol. A lookup that searched the whole page filled the first row's. ROWS = """ """ def test_the_lookup_fills_the_dialog_and_leaves_the_rows_alone(client, session_factory, tmp_path): make_login(client, session_factory) with session_factory() as s: bind_to_only_portfolio(s) fac.hold(s, fac.make_instrument(s, "ACME", name="Acme")) # this portfolio's alone s.commit() page = client.get("/holdings", headers=HTML) target = tmp_path / "holdings.html" target.write_text(_standalone(page.text, ROWS).replace("", "" + BY_EXCHANGE, 1), encoding="utf-8") dom = subprocess.run( [CHROME, "--headless", "--disable-gpu", "--dump-dom", "--no-sandbox", "--allow-file-access-from-files", "--window-size=1400,1000", "--virtual-time-budget=8000", target.as_uri()], capture_output=True, text=True, timeout=90).stdout found = re.search(r'
(.*?)', dom, re.S) assert found, "the driver did not finish" out = json.loads(found.group(1).replace(""", '"')) assert out["rowBefore"]["name"] == "Acme" assert out["rowAfter"] == out["rowBefore"] assert out["dialog"] == {"name": "Alphabet Inc.", "currency": "USD", "symbol": "GOOG"} FEED_OFF = """ """ SAYS = """ """ def test_a_lookup_with_the_feed_off_says_so(client, session_factory, tmp_path): """Not "no match for GOOG", which sends somebody to check a ticker that is fine.""" make_login(client, session_factory) page = client.get("/holdings", headers=HTML) target = tmp_path / "holdings.html" target.write_text(_standalone(page.text, SAYS).replace("", "" + FEED_OFF, 1), encoding="utf-8") dom = subprocess.run( [CHROME, "--headless", "--disable-gpu", "--dump-dom", "--no-sandbox", "--allow-file-access-from-files", "--virtual-time-budget=4000", target.as_uri()], capture_output=True, text=True, timeout=90).stdout found = re.search(r'
(.*?)', dom, re.S) assert found, "the driver did not finish" assert json.loads(found.group(1).replace(""", '"')) == { "status": "not looked up: the price feed is off"}