Skip to content

e2e: Wait for the WebSocket disconnect before the participant sends a message#6586

Draft
andremion wants to merge 1 commit into
developfrom
andrerego/and-1325-make-the-offline-message-e2e-test-wait-for-the-socket
Draft

e2e: Wait for the WebSocket disconnect before the participant sends a message#6586
andremion wants to merge 1 commit into
developfrom
andrerego/and-1325-make-the-offline-message-e2e-test-wait-for-the-socket

Conversation

@andremion

@andremion andremion commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Goal

test_offlineMessageInTheMessageList has a flake mode where the participant's message is delivered live while the test is taking the app offline. The SDK keeps the WebSocket open for a short period after the app goes to background (the socket is only closed when the delayed lifecycle stop reaches ChatSocketStateService.onStop()), and svc data disable does not close established sockets immediately. So the message.new event can arrive over the still-open socket, the message is stored locally and shown while offline, and the assert "user does not observe a new message from participant" fails.

This change removes the race by waiting until the client socket is actually disconnected before the participant sends the message.

Depends on GetStream/stream-chat-test-mock-server#49, which must merge first because the e2e CI clones the mock server main branch.

Resolves AND-1325

Implementation

  • New BackendRobot.waitForWebSocketDisconnection() in stream-chat-android-e2e-test polls the mock server's new GET /ws/status endpoint until the server reports the socket as closed.
  • test_offlineMessageInTheMessageList and test_offlineRecoveryWithinSession call it after backgrounding the app, before the participant sends. Ordering is now decided on the server: once it reports connected: false, its socket handle is nil, so the participant message is only stored and gets delivered on reconnect.
  • test_offlineRecoveryWithinSession is included because it has the same race. It passes either way today, but without the wait the message can be delivered live before the socket closes, so the test can pass without exercising the recovery path it is meant to cover.

No UI changes.

Testing

  1. Check out the mock server PR branch and start the driver: bundle exec ruby driver.rb.
  2. Build and install the e2e APKs: ./gradlew :stream-chat-android-compose-sample:assembleE2eDebug :stream-chat-android-compose-sample:assembleE2eDebugAndroidTest, then adb install -r both.
  3. Run the two tests, for example: adb shell am instrument -w -e class 'io.getstream.chat.android.compose.tests.MessageListTests#test_offlineMessageInTheMessageList' io.getstream.chat.android.compose.sample.e2etest.debug.test/io.qameta.allure.android.runners.AllureAndroidJUnitRunner.
  4. In the mock server per-test log (logs/test_offlineMessageInTheMessageList_*.log), verify the order: GET /ws/status returns connected: false, then POST /participant/message, then the message is delivered after reconnect through /sync and the channel query.

Both tests pass locally with this flow. spotlessCheck and detekt pass on the touched modules.

Summary by CodeRabbit

  • Tests
    • Improved offline-mode test reliability by waiting for the WebSocket connection to close before simulating connectivity changes and app recovery.
    • Added timeout handling to detect unsuccessful disconnections during end-to-end testing.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@andremion andremion added the pr:test Test-only changes label Jul 23, 2026
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@andremion
andremion requested a review from testableapple July 23, 2026 12:57
@github-actions

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.95 MB 5.95 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.21 MB 11.21 MB 0.00 MB 🟢
stream-chat-android-compose 12.69 MB 12.69 MB 0.00 MB 🟢

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Offline E2E tests now wait for confirmed WebSocket disconnection after backgrounding. BackendRobot polls mock-server status with a timeout and reports failure if the connection remains active.

Changes

Offline WebSocket synchronization

Layer / File(s) Summary
WebSocket disconnection polling
stream-chat-android-e2e-test/.../BackendRobot.kt
Adds waitForWebSocketDisconnection, which polls ws/status, checks the connected flag, and times out if disconnection does not occur.
Offline test synchronization
stream-chat-android-compose-sample/.../MessageListTests.kt
Both offline message-list tests wait for WebSocket disconnection after sending the device to the background.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: pr:ci

Suggested reviewers: testableapple, velikovpetar

Poem

A rabbit watched the socket close,
Then hopped through tests in neat repose.
Background first, then checks align,
Offline messages now behave fine.
“No stale websockets!” squeaks the hare.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: waiting for WebSocket disconnect before the participant sends a message.
Description check ✅ Passed The PR description covers Goal, Implementation, and Testing, and it notes there are no UI changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch andrerego/and-1325-make-the-offline-message-e2e-test-wait-for-the-socket

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@stream-chat-android-e2e-test/src/main/kotlin/io/getstream/chat/android/e2e/test/robots/BackendRobot.kt`:
- Around line 135-153: Update waitForWebSocketDisconnection to ensure each
mockServer.getRequest("ws/status") poll has a timeout bounded by the remaining
timeoutMillis, configuring or passing a bounded HTTP client/call timeout through
the MockServer request path. Preserve the existing polling interval,
disconnected-status return, and failure message while preventing a stalled
request from exceeding the method deadline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 188f86f5-1893-4487-8268-4d8d17b50b61

📥 Commits

Reviewing files that changed from the base of the PR and between 7b95d3f and 1f6936b.

📒 Files selected for processing (2)
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/MessageListTests.kt
  • stream-chat-android-e2e-test/src/main/kotlin/io/getstream/chat/android/e2e/test/robots/BackendRobot.kt

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:test Test-only changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant