"""v1.1 WP-C: the browser harness's download helpers, without a browser. `tools/m11_webdriver.wait_for_download` is what decides that an export actually left the browser as a file. It must never call a download finished because a file appeared, because it is still being written, or because it is empty — each of those would make "the export works" a claim the evidence does not support. python -m pytest tests/test_v11_c_browser_helpers.py -v """ import threading import time from pathlib import Path import pytest from tools import m11_webdriver as wd def later(seconds, action): timer = threading.Timer(seconds, action) timer.start() return timer def test_a_finished_file_is_returned(tmp_path): later(0.2, lambda: (tmp_path / "campaign.json").write_text('{"format": "x"}')) found = wd.wait_for_download(tmp_path, set(), timeout=5, poll=0.05) assert found == tmp_path / "campaign.json" def test_a_file_that_was_already_there_is_not_the_download(tmp_path): (tmp_path / "old.json").write_text("{}") with pytest.raises(wd.WebDriverError): wd.wait_for_download(tmp_path, {"old.json"}, timeout=0.6, poll=0.05) def test_an_empty_file_never_counts(tmp_path): (tmp_path / "empty.json").write_bytes(b"") with pytest.raises(wd.WebDriverError): wd.wait_for_download(tmp_path, set(), timeout=0.6, poll=0.05) def test_nothing_counts_while_firefox_is_still_writing(tmp_path): """Firefox writes `.part` beside the final name until it is done.""" (tmp_path / "campaign.json").write_text('{"format": "x"}') (tmp_path / "campaign.json.part").write_text("") with pytest.raises(wd.WebDriverError): wd.wait_for_download(tmp_path, set(), timeout=0.6, poll=0.05) later(0.1, lambda: (tmp_path / "campaign.json.part").unlink()) assert wd.wait_for_download(tmp_path, set(), timeout=5, poll=0.05).name == "campaign.json" def test_a_file_that_is_still_growing_is_not_finished(tmp_path): target = tmp_path / "big.json" target.write_text("{") stop = threading.Event() def grow(): for _ in range(8): if stop.is_set(): return with target.open("a") as fh: fh.write("x" * 100) time.sleep(0.05) writer = threading.Thread(target=grow) started = time.monotonic() writer.start() found = wd.wait_for_download(tmp_path, set(), timeout=5, poll=0.05, stable_polls=3) writer.join() # Returned only once the size held still, so after the last write. assert found == target assert target.stat().st_size == 1 + 8 * 100 assert time.monotonic() - started >= 0.4 def test_the_prefs_save_downloads_unasked_to_the_folder_given(tmp_path): prefs = wd.firefox_download_prefs(tmp_path) assert prefs["browser.download.folderList"] == 2 assert prefs["browser.download.dir"] == str(tmp_path) assert prefs["browser.download.useDownloadDir"] is True assert prefs["browser.download.always_ask_before_handling_new_types"] is False assert "application/json" in prefs["browser.helperApps.neverAsk.saveToDisk"] def test_a_download_folder_must_be_under_home(): with pytest.raises(wd.WebDriverError): wd.require_under_home(Path("/tmp/wp-c-downloads")) inside = Path.home() / "v11-evidence" / "wp-c" / "downloads" assert wd.require_under_home(inside) == inside.resolve()