Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

## Interface and handling

- keep real-browser regression inputs stable when maintainers replace the GUI
examples, while continuing to verify that each task's example loads

- --outNumberPerSeed selects each seed's best candidate sites before final
deduplication, energy/overlap/count filtering; model P ranks left-most-anchor
ensembles; zero preserves ordinary prediction; the GUI exposes the quota next
Expand Down Expand Up @@ -326,6 +329,11 @@ energies, restricted partition sums, and trackers.
+ Independent chain-enumeration, traceback, seed-only, mode-matrix, merge,
filter, CLI and unchanged-probability regressions; register/install sources.

261026 Alexander Mitrofanov
* scripts/wasm/test-browser.py
* decouple deterministic numerical browser checks from replaceable GUI example
payloads while retaining real-browser coverage of prediction/evaluation loading

261026 Alexander Mitrofanov
* gui/app.js, gui/{index.html,styles.css}, scripts/wasm/test-browser.py
* place Explicit seeds beside a half-width Seed constraint selector and halve
Expand Down
48 changes: 32 additions & 16 deletions scripts/wasm/test-browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,23 @@ def open_group(key):
expect(page.locator('#tab-' + key)).to_have_attribute('aria-selected', 'true')
assert page.locator('.parameter-group:visible').count() == 1

def load_example(task='prediction'):
def load_reference(task='prediction'):
page.locator('#examples-menu summary').click()
page.get_by_role('button', name='Evaluate a duplex' if task == 'evaluation' else 'Short duplex', exact=False).click()
page.locator(f'#example-options [data-example-task="{task}"]').click()
expect(page.locator('#query')).not_to_have_value('')
expect(page.locator('#target')).not_to_have_value('')
if task == 'evaluation':
expect(page.locator('#rri')).not_to_have_value('')

# Examples are maintainer-editable content. Exercise their loading, then
# use a fixed small pair so numerical browser regressions stay stable.
page.locator('#reset').click()
if task == 'evaluation':
page.get_by_role('radio', name='Evaluation').check()
page.locator('#query').fill('>query\nGGGAGGAGGG\n')
page.locator('#target').fill('>target\nCCCUCCUCCC\n')
if task == 'evaluation':
page.locator('#rri').fill('1||||||||||&1||||||||||')
expect(page.locator('#query')).to_have_value('>query\nGGGAGGAGGG\n')

def download_archive(session=None):
Expand Down Expand Up @@ -90,11 +104,13 @@ def predict():
page.keyboard.press('ArrowLeft')
expect(page.get_by_role('radio', name='Prediction')).to_be_checked()
page.locator('#examples-menu summary').click()
expect(page.get_by_role('button', name='Short duplex', exact=False)).to_be_visible()
expect(page.get_by_role('button', name='Evaluate a duplex', exact=False)).not_to_be_visible()
prediction_example = page.locator('#example-options [data-example-task="prediction"]')
evaluation_example = page.locator('#example-options [data-example-task="evaluation"]')
expect(prediction_example).to_be_visible()
expect(evaluation_example).not_to_be_visible()
page.get_by_role('radio', name='Evaluation').check()
expect(page.get_by_role('button', name='Evaluate a duplex', exact=False)).to_be_visible()
expect(page.get_by_role('button', name='Short duplex', exact=False)).not_to_be_visible()
expect(evaluation_example).to_be_visible()
expect(prediction_example).not_to_be_visible()
page.get_by_role('radio', name='Prediction').check()
page.locator('#examples-menu summary').click()

Expand Down Expand Up @@ -242,7 +258,7 @@ def predict():
compute.click()
expect(page.locator('#input-error')).to_contain_text('use only')
expect(page.locator('#loading')).not_to_be_visible()
load_example()
load_reference()
fill('temperature', '101')
open_group('sequence-input')
compute.click()
Expand All @@ -251,7 +267,7 @@ def predict():
expect(page.locator('#query')).to_have_value('')
expect(page.locator('#target')).to_have_value('')
expect(page.locator('#rri')).to_have_value('')
load_example()
load_reference()

# Disabled stale edits neither block a run nor leak into JSON. Re-enabling
# restores local edits; loading/storing uses effective native settings.
Expand Down Expand Up @@ -287,7 +303,7 @@ def predict():
page.locator('#qAcc').select_option('C')
expect(page.locator('#qShape')).to_have_value('invalid inactive shape')
page.locator('#reset').click()
load_example()
load_reference()

# Reference prediction, selectable CSV output and independent table visibility.
fill('outNumber', 10)
Expand Down Expand Up @@ -378,7 +394,7 @@ def predict():
page.set_viewport_size({'width': 1440, 'height': 1100})

# Multi-FASTA prediction, signed inclusive output and additional files.
load_example()
load_reference()
fill('outNumber', 1)
fill('query', '>q1\nGGGAGGAGGG\n>q2\nGGGAGGAGGG')
fill('qIdxPos0', -3)
Expand Down Expand Up @@ -435,7 +451,7 @@ def predict():
fill('rri', '1||||||||||&1||||||||||')
compute.click()
expect(page.locator('#input-error')).to_contain_text('exactly one')
load_example('evaluation')
load_reference('evaluation')
fill('rri', '1||||||||||&1||||||||||:1|||||||||&2|||||||||')
open_group('output-options')
page.locator('#output-options input[value="detailed"]').check()
Expand Down Expand Up @@ -475,7 +491,7 @@ def predict():

# Startup and synchronous C++ cancellation both allow a fresh prediction.
page.get_by_role('radio', name='Prediction').check()
load_example()
load_reference()
held_routes = []
session_count = sessions.count()
page.route('**/wasm/intarna.wasm', lambda route: held_routes.append(route))
Expand All @@ -494,7 +510,7 @@ def predict():
page.keyboard.press('Escape')
expect(status).to_contain_text('aborted')
expect(sessions).to_have_count(session_count)
load_example()
load_reference()
predict()

fill('query', '>no_pairs\nNNNNNNNNNN')
Expand All @@ -508,7 +524,7 @@ def predict():
assert active.locator('tbody img').count() == 0
assert '<img' in rows.first.inner_text()

load_example()
load_reference()
session_count = sessions.count()
page.route('**/wasm/intarna.js', lambda route: route.abort())
compute.click()
Expand All @@ -524,7 +540,7 @@ def predict():
page.reload()
page.wait_for_load_state('networkidle')
expect(sessions).to_have_count(0)
load_example()
load_reference()
fill('temperature', 24)
fill('qIdxPos0', -3)
fill('tIdxPos0', -5)
Expand Down Expand Up @@ -566,7 +582,7 @@ def predict():

# A different task, CSV order and output report own a second result area.
page.get_by_role('radio', name='Evaluation').check()
load_example('evaluation')
load_reference('evaluation')
with page.expect_download() as stored:
page.locator('#store-parameters').click()
second_settings = json.loads(Path(stored.value.path()).read_text())
Expand Down
Loading