Skip to content

fix(setup): wait for video track playable before running network checks - #1188

Merged
JamesPHoughton merged 1 commit into
mainfrom
fix/network-connectivity-retry
Feb 18, 2026
Merged

fix(setup): wait for video track playable before running network checks#1188
JamesPHoughton merged 1 commit into
mainfrom
fix/network-connectivity-retry

Conversation

@JamesPHoughton

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause of network connectivity errors: startCamera() resolves when the camera device is initialized, but persistentTrack (required by testNetworkConnectivity) is only populated once the track reaches "playable" state. Calling testNetworkConnectivity(undefined) was throwing an error. Fixed by listening for Daily's local-track-started event before signalling video readiness, with a fallback playable-state check and a 10s timeout if the track never fires.
  • Race between network retry and call quality test: Daily throws if testNetworkConnectivity() is called while testCallQuality() is in progress. When the network test failed and retried, it was racing with call quality starting simultaneously. Fixed by only rendering TestCallQuality once network and websocket tests reach a terminal state.
  • Defensive fix: Added ?. to video?.persistentTrack optional chain in TestNetworkConnectivity.

Closes #1149, #1151

Test plan

  • Run through webcam setup on a normal machine — network/websocket/call quality all pass, user proceeds
  • Confirm in browser console that videoTrackStarted event fires before network checks begin
  • Simulate slow track start (e.g. dev tools throttling) — confirm checks wait rather than error
  • Confirm that if network test needs to retry, call quality test hasn't started yet

🤖 Generated with Claude Code

Daily throws if testNetworkConnectivity() is called while testCallQuality()
is in progress. When the network test fails and retries, it was racing with
the call quality test starting simultaneously. Fix by only rendering
TestCallQuality once network and websocket tests reach a terminal state.

Closes #1151

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/Call.jsx
  73:9  warning  The 'players' logical expression could make the dependencies of useMemo Hook (at line 213) change on every render. To fix this, wrap the initialization of 'players' in its own useMemo() Hook  react-hooks/exhaustive-deps
  73:9  warning  The 'players' logical expression could make the dependencies of useMemo Hook (at line 242) change on every render. To fix this, wrap the initialization of 'players' in its own useMemo() Hook  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/FixAV.jsx
  331:36  error  Return values from promise executor functions cannot be read  no-promise-executor-return
  505:38  error  Return values from promise executor functions cannot be read  no-promise-executor-return
  649:25  error  Do not use Array index in keys                                react/no-array-index-key
  683:25  error  Do not use Array index in keys                                react/no-array-index-key
  740:25  error  Do not use Array index in keys                                react/no-array-index-key
  797:25  error  Do not use Array index in keys                                react/no-array-index-key
  847:25  error  Do not use Array index in keys                                react/no-array-index-key

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/UserMediaError.jsx
  140:5   error  Arrow function expected no return value  consistent-return
  180:24  error  Do not use Array index in keys           react/no-array-index-key

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/layouts/defaultResponsiveLayout.test.js
  1:32  error  'vi' is defined but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/utils/avRecovery.js
  221:13  error  Use object destructuring                                                                                                                                                   prefer-destructuring
  251:3   error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax
  257:21  error  Unexpected use of continue statement                                                                                                                                       no-continue
  317:3   error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax
  320:7   error  Unexpected use of continue statement                                                                                                                                       no-continue
  331:13  error  Unexpected 'await' inside a loop                                                                                                                                           no-await-in-loop
  347:15  error  Unexpected 'await' inside a loop                                                                                                                                           no-await-in-loop
  365:15  error  Unexpected 'await' inside a loop                                                                                                                                           no-await-in-loop
  376:13  error  Unexpected 'await' inside a loop                                                                                                                                           no-await-in-loop
  393:15  error  Unexpected 'await' inside a loop                                                                                                                                           no-await-in-loop
  404:13  error  Unexpected 'await' inside a loop                                                                                                                                           no-await-in-loop
  455:3   error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax
  457:21  error  Unexpected use of continue statement                                                                                                                                       no-continue

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/call/utils/avRecovery.test.js
   42:7   error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax
  506:45  error  'label' is defined but never used                                                                                                                                          no-unused-vars
  545:45  error  'label' is defined but never used                                                                                                                                          no-unused-vars
  586:45  error  'label' is defined but never used                                                                                                                                          no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/chat/Chat.jsx
  37:7  warning  React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/EmpiricaMenu.jsx
  51:3  error  React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?  react-hooks/rules-of-hooks

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/IdleProvider.jsx
   56:6   warning  React Hook useEffect has a missing dependency: 'resetTimer'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
  120:57  error    ''' can be escaped with '&apos;', '&lsquo;', '&#39;', '&rsquo;'                                                react/no-unescaped-entities

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/SharedNotepad.jsx
  27:6  warning  React Hook useEffect has missing dependencies: 'defaultText', 'game', and 'record'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/components/scroll/useScrollAwareness.js
   67:19  error  Use object destructuring                                                                prefer-destructuring
  108:39  error  Use the '**' operator instead of 'Math.pow'                                             prefer-exponentiation-operator
  108:39  error  'Math.pow' is restricted from being used. Use the exponentiation operator (**) instead  no-restricted-properties

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/Qualtrics.jsx
  55:10  error  'state' is assigned a value but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/Survey.jsx
  9:26  error  Unexpected function expression  prefer-arrow-callback

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/elements/TrainingVideo.jsx
  61:6  warning  React Hook useEffect has missing dependencies: 'timer?.elapsed' and 'url'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Consent.jsx
  132:6  warning  React Hook useEffect has a missing dependency: 'player'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Countdown.jsx
  8:21  error  Use default import syntax to import 'ReactCountdown'  import/no-named-default

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/Lobby.jsx
  64:19  error  ''' can be escaped with '&apos;', '&lsquo;', '&#39;', '&rsquo;'  react/no-unescaped-entities
  64:51  error  ''' can be escaped with '&apos;', '&lsquo;', '&#39;', '&rsquo;'  react/no-unescaped-entities

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/AudioEquipmentCheck.jsx
   87:6   warning  React Hook useEffect has a missing dependency: 'permissionsStatus'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
  104:24  error    Unnecessary return statement                                                                                          no-useless-return
  112:5   error    Arrow function expected no return value                                                                               consistent-return

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/CameraCheck.jsx
  130:6  warning  React Hook useEffect has a missing dependency: 'devices'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/GetPermissions.jsx
  191:5  error  Do not nest ternary expressions  no-nested-ternary
  231:5  error  Do not nest ternary expressions  no-nested-ternary

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/LoopbackCheck.jsx
  165:36  error  Return values from promise executor functions cannot be read  no-promise-executor-return

/home/runner/work/deliberation-empirica/deliberation-empirica/client/src/intro-exit/setup/MicCheck.jsx
  118:7  error  React Hook "useCallback" is called conditionally. React Hooks must be called in the exact same order in every component render  react-hooks/rules-of-hooks

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/01_Normal_Paths_Omnibus.js
   176:34  error  'actualOrder' is already declared in the upper scope on line 157 column 13  no-shadow
   203:31  error  'newOrder' is already declared in the upper scope on line 192 column 13     no-shadow
  1100:9   error  Expected an assignment or function call and instead saw an expression       no-unused-expressions

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/03_Text_Chat.js
  200:9  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions
  215:9  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/15_Scroll_Indicator.js
   48:21  error  Assignment to property of function parameter '$el'  no-param-reassign
   69:21  error  Assignment to property of function parameter '$el'  no-param-reassign
  110:21  error  Assignment to property of function parameter '$el'  no-param-reassign

/home/runner/work/deliberation-empirica/deliberation-empirica/cypress/e2e/16_Video_Discussion_Layouts.js
  162:11  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions
  179:11  error  Expected an assignment or function call and instead saw an expression  no-unused-expressions
  187:9   error  Expected an assignment or function call and instead saw an expression  no-unused-expressions

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/getTreatments.js
    8:33  error  Missing file extension for "./preFlight/validateTreatmentFile"  import/extensions
  327:30  error  Unexpected 'await' inside a loop                                no-await-in-loop

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/index.js
  42:43  error  'p' is defined but never used  no-unused-vars

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/dispatch.js
  477:9  error  Unexpected use of continue statement  no-continue

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/preFlightChecks.js
  20:5  error  iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations  no-restricted-syntax

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/validateDlConfig.test.js
  2:32  error  Missing file extension for "./validateDlConfig"                                                                            import/extensions
  3:1   error  'vscode' import should occur before import of './validateDlConfig'                                                         import/order
  6:25  error  Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the '=>'  arrow-body-style

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/preFlight/validatePromptFile.test.js
  7:8  error  Missing file extension for "./validatePromptFile"  import/extensions

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/providers/dailyco.js
   37:23  error  Expected to return a value at the end of async function 'createRoom'     consistent-return
  157:23  error  Expected to return a value at the end of async function 'stopRecording'  consistent-return
  229:7   error  Unexpected if as the only statement in an else block                     no-lonely-if

/home/runner/work/deliberation-empirica/deliberation-empirica/server/src/utils/logging.js
  1:17  error  'warn' is defined but never used  no-unused-vars
  1:29  error  'log' is defined but never used   no-unused-vars

✖ 77 problems (68 errors, 9 warnings)
  7 errors and 0 warnings potentially fixable with the '--fix' option.

@cypress

cypress Bot commented Feb 18, 2026

Copy link
Copy Markdown

Deliberation    Run #2041

Run Properties:  status check passed Passed #2041  •  git commit 478a86aabc: fix(setup): run call quality test after network/websocket tests complete
Project Deliberation
Branch Review fix/network-connectivity-retry
Run status status check passed Passed #2041
Run duration 08m 16s
Commit git commit 478a86aabc: fix(setup): run call quality test after network/websocket tests complete
Committer James Houghton
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 1
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 21
View all changes introduced in this branch ↗︎

@JamesPHoughton
JamesPHoughton merged commit 9194252 into main Feb 18, 2026
7 checks passed
@JamesPHoughton
JamesPHoughton deleted the fix/network-connectivity-retry branch February 18, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Network connectivity check should retry once on failure

1 participant