from pathlib import Path import time from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.ui import WebDriverWait ROOT = Path(__file__).resolve().parent.parent options = Options() options.add_argument('-headless') driver = webdriver.Firefox(options=options) driver.set_page_load_timeout(60) try: driver.get('http://127.0.0.1:8180/web/?firmware=/_scratch/crosspoint-reader-1.4.1-release-firmware.bin&variant=x3') confirm = driver.find_element(By.CSS_SELECTOR, '[data-button="confirm"]') WebDriverWait(driver, 8 * 60).until(lambda _: confirm.get_attribute('disabled') is None) indicator = driver.find_element(By.ID, 'frame-generation') def generation(): return int(indicator.get_attribute('value') or '-1') def wait_frame(previous, timeout=180): WebDriverWait(driver, timeout).until(lambda _: generation() > previous) def wait_stable(quiet=5, timeout=180): deadline = time.time() + timeout last = generation() stable_since = time.time() while time.time() < deadline: time.sleep(0.25) current = generation() if current != last: last = current stable_since = time.time() elif time.time() - stable_since >= quiet: return current raise RuntimeError('display did not settle') power = driver.find_element(By.CSS_SELECTOR, '[data-button="power"]') before = generation() ActionChains(driver).click_and_hold(power).perform() wait_frame(before) ActionChains(driver).release(power).perform() wait_stable() def press(button): driver.execute_script('arguments[0].scrollIntoView({block: "center"})', button) before = wait_stable() ActionChains(driver).click_and_hold(button).perform() time.sleep(0.3) ActionChains(driver).release(button).perform() wait_frame(before) wait_stable() press(confirm) # Browse Files press(confirm) # Test press(confirm) # example.txt time.sleep(60) status = driver.find_element(By.ID, 'status').text log = driver.find_element(By.ID, 'log').text (ROOT / '_scratch/browser-raw-sd.log').write_text(log) driver.save_screenshot(str(ROOT / '_scratch/browser-raw-sd.png')) bad = ( 'RuntimeError', 'Guru Meditation', "panic'ed", 'Invalid SD card size', 'FS error', 'SPI:', 'SD:', 'Unexpected response to cmd', ) matched = [marker for marker in bad if marker in log or marker in status] if matched: raise RuntimeError(f'emulator failure detected: {matched}') print(f'browser raw-SD test passed at frame generation {generation()}') finally: driver.quit()