File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -448,9 +448,16 @@ def _run_jupyter_cell_and_get_output(
448448
449449 Returns True once the output area shows ``2``; False if all *attempts* are
450450 exhausted without output (the caller decides whether that is a skip).
451+
452+ The first attempt gets the full ``TIMEOUT_CODE_EXEC`` budget (a healthy but
453+ cold kernel can be slow to produce its first result in Docker CI). Retries
454+ exist only to recover a *lost* keystroke against an already-live kernel,
455+ which resolves in seconds, so they use the shorter ``TIMEOUT_DIALOG`` budget
456+ — keeping the worst-case failure path bounded instead of ``attempts ×`` the
457+ full timeout.
451458 """
452459 cell_output = notebook_panel .locator (JupyterLabSession .CELL_OUTPUT ).first
453- for _attempt in range (attempts ):
460+ for attempt in range (attempts ):
454461 # A leftover kernel dialog can reappear between attempts; clear it first.
455462 _accept_open_dialogs (page )
456463
@@ -467,8 +474,9 @@ def _run_jupyter_cell_and_get_output(
467474 continue
468475
469476 cell_input .press ("Shift+Enter" )
477+ output_timeout = TIMEOUT_CODE_EXEC if attempt == 0 else TIMEOUT_DIALOG
470478 try :
471- expect (cell_output ).to_contain_text ("2" , timeout = TIMEOUT_CODE_EXEC )
479+ expect (cell_output ).to_contain_text ("2" , timeout = output_timeout )
472480 return True
473481 except AssertionError :
474482 # No output yet — loop and re-issue the run.
You can’t perform that action at this time.
0 commit comments