376d302e1d
Bumps third_party/qemu to the wasm32 store-TB TCI workaround so the browser reader no longer panics in uzlib font decompression. Adds docs/wasm-inflate-panic.md with the full investigation (native control, non-deterministic reject, JIT promotion) and next steps. Updates ISSUES: the panic is worked around; the reader now inverts into muddled grayscale after the initial BW page (new top reader defect). tests navigate the 4th Open press into the reader.
79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
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 directory
|
|
press(confirm) # highlight example.txt (browser indexes a preview)
|
|
press(confirm) # Open example.txt into the reader
|
|
wait_stable(quiet=10, timeout=600)
|
|
|
|
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()
|