test(calling): add mobius socket WebSocket E2E test infrastructure#4995
test(calling): add mobius socket WebSocket E2E test infrastructure#4995eigengravy wants to merge 7 commits into
Conversation
|
This pull request is automatically being deployed by Amplify Hosting (learn more). |
| contentType: 'application/json', | ||
| body: JSON.stringify({error: 'Internal Server Error'}), | ||
| if (mobiusWsMode) { | ||
| failStatus = true; |
There was a problem hiding this comment.
Q. How are we using this value ?
There was a problem hiding this comment.
This flag gates the interceptor's onRequest callback — when failStatus = true, any CALL_STATUS frame hitting the interceptor returns a 500 (simulating a keepalive failure). The value is toggled from the test body after the call is established, so the interceptor only starts failing keepalives at the right moment.
| expectedPrimaryUrl = isInt ? PRIMARY_MOBIUS_URL.INT : PRIMARY_MOBIUS_URL.PROD; | ||
| tm = new TestManager(testInfo.project.name); | ||
| if (mobiusWsMode) { | ||
| mobiusWsInterceptor = new MobiusWsInterceptor({ |
There was a problem hiding this comment.
Do you think making this interceptor a singleton will make it easy and performant to use ?
We can create the interceptor once and then we can add the onResponse() through a setter based on the test. After each test we can reset the interceptor (clear the existing onResponse() )
Shreyas281299
left a comment
There was a problem hiding this comment.
Submitting existing pending review to allow fresh inline comments.
| }); | ||
| } | ||
|
|
||
| await navigateToCallingApp(page); |
There was a problem hiding this comment.
[High / Test correctness] REG-011 in WS mode passes vacuously. The interceptor is installed above (lines 19–39), but setMobiusWebSocket(page, true) is never called and this test deliberately bypasses initializeCallingSDK. The sample-app's localStorage flag stays unset, the SDK falls back to HTTP, the interceptor sees zero traffic, and registrationPosts stays at 0. The only WS-validating assertion (if (registrationPosts > 0) expect(registrationStatus).toBe(401)) is therefore skipped, and the remaining assertions ("not registered") pass regardless of transport with an invalid token — so MOBIUS=ws runs give zero coverage of the WS 401 path.
Suggestion: enable WS explicitly in the WS branch, then make the assertion unconditional:
await navigateToCallingApp(page);
await setServiceIndicator(page, 'calling');
if (mobiusWsMode) {
await setMobiusWebSocket(page, true);
}
// ...
if (mobiusWsMode) {
expect(registrationPosts).toBeGreaterThan(0);
expect(registrationStatus).toBe(401);
} else if (registrationPosts > 0) {
expect(registrationStatus).toBe(401);
}There was a problem hiding this comment.
Investigated — in WS mode, the SDK fails at HTTP service discovery (region/server lookup returns 401) before it ever opens a WebSocket connection. The invalid token 'invalid-token-12345' gets rejected at the HTTP layer, so the WS interceptor was dead code that never fired.
Removed the WS interceptor, kept the test running in both modes (it still validates the "not registered" end state via UI assertions), and scoped the network-level registrationPosts/401 assertion to HTTP mode only. Added a comment documenting why.
| @@ -56,9 +71,11 @@ export function callErrorTests() { | |||
| await verifyLineRegistered(page); | |||
| await getMediaStreams(page); | |||
|
|
|||
| await context.route(/\/devices\/[^/]+\/call$/, (route) => { | |||
| route.abort('failed'); | |||
| }); | |||
| if (!mobiusWsMode) { | |||
| await context.route(/\/devices\/[^/]+\/call$/, (route) => { | |||
| route.abort('failed'); | |||
There was a problem hiding this comment.
[Medium / Test correctness] CALL-013 exercises different failure modes in the two transports under one ID. The WS branch returns a structured {statusCode: 500, ...} response for CALL_SETUP — the SDK gets a server-side error. The HTTP branch uses route.abort('failed') — a transport-level network error (no response, fetch rejection). These hit different code paths in the SDK (response error vs transport error). The "no stuck call" assertion is true in both cases, but the test isn't validating equivalent behavior across transports.
Pick one failure mode and mirror it: either drop the WS connection / never reply on the WS side, or use route.fulfill({status: 500, ...}) on the HTTP side.
There was a problem hiding this comment.
Valid — aligned the HTTP branch to use route.fulfill({status: 500, body: ...}) instead of route.abort('failed') so both transports now exercise the same failure mode (server-side 500 on call setup). Both still validate the same end state: no stuck call objects after cleanup.
…ments - Replace nested ternary interceptor creation with if/else blocks - Add try/catch around onRequest/onResponse callbacks in MobiusWsInterceptor - Redact authorization tokens from captured frames to prevent trace leaks
…lback - Rename ambiguous `tm` variable to `testManager` across all test groups - Extract inline onRequest callback to named variable in registration-errors
…alignment
REG-011: Remove dead WS interceptor that never fires (SDK fails at HTTP
service discovery before opening a WebSocket with an invalid token). Keep
the test running in both modes — it still validates "not registered" end
state. Network-level 401 assertion now scoped to HTTP mode only.
CALL-013: Align HTTP branch to use route.fulfill({status: 500}) instead
of route.abort('failed') so both transports exercise server-side error
cleanup rather than testing different failure modes.
rarajes2
left a comment
There was a problem hiding this comment.
LGTM. We can discuss the singleton pattern for the interceptor in person, it's not a blocker for this PR.
COMPLETES CAI-7883
This pull request addresses
The Calling SDK Playwright E2E suite needs to exercise flows over the new mobius WebSocket transport (introduced in #4906 / #4982) in addition to the existing HTTP transport. Without a way to intercept and mock mobius WS frames, the existing registration, keepalive, call lifecycle, and error-flow tests cannot be re-run against the WS transport, leaving the new socket path uncovered by E2E.
by making the following changes
packages/calling/playwright/utils/mobius-ws.ts— a reusable WebSocket route interceptor for mobius frames (auth/register/unregister/device_status/call_*) with hooks for request/response mocking, plus tracking-id correlation.playwright/utils/setup.tsandtest-manager.tsto support running suites in mobius WS mode via env, including conditional WS route installation per worker.registration-lifecycle,registration-failover,registration-keepalive,registration-errors,call-lifecycle,call-controls,call-keepalive,call-errors) to drive the same scenarios over the WS transport using the new interceptor.oauth.setup.tsto be transport-agnostic.Change Type
The following scenarios were tested
MOBIUS_TRANSPORT=wsvia env) covering:The GAI Coding Policy And Copyright Annotation Best Practices
I certified that
Make sure to have followed the contributing guidelines before submitting.