-
Notifications
You must be signed in to change notification settings - Fork 17
Add optional listen param to dial() to support starting calls using a single method. #1289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…le to send the `verto.answer` (#1263)
Fabric references renamed too Call
# Conflicts: # internal/e2e-client/playwright.config.ts # package-lock.json # packages/js/CHANGELOG.md # packages/js/package.json # packages/realtime-api/CHANGELOG.md # packages/realtime-api/package.json # packages/web-api/CHANGELOG.md # packages/web-api/package.json
- Remove browser-js workflows (production and staging) - Remove realtime-api workflows (production and staging) - Update unit-tests.yml to only run browser-client workflows - Remove stack tests that reference deleted realtime-api package - Add --passWithNoTests flag to test scripts to handle empty test suites This focuses the CI/CD pipeline on the @signalwire/client package only.
- Fix test file path: buildVideoWithCallSDK.spec.ts -> buildVideoWithFabricSDK.spec.ts - Add correct path prefixes for callfabric tests (callfabric/*.spec.ts) - Fix renegotiation test paths to include callfabric/ prefix - Disable relayApp.spec.ts test that depends on removed @signalwire/realtime-api These configuration mismatches were causing e2e workflow failures.
This reverts commit e6537bf.
Merging the type renames for @signalwire/client back to the original repository
# Conflicts: # internal/e2e-js/fixtures.ts # internal/e2e-js/package.json # internal/e2e-js/playwright.config.ts # internal/e2e-js/tests/buildVideoWithVideoSDK.spec.ts # internal/e2e-js/tests/callfabric/agentCustomer.spec.ts # internal/e2e-js/tests/roomSession.spec.ts # internal/e2e-js/tests/roomSessionAudienceCount.spec.ts # internal/e2e-js/tests/roomSessionAutomaticStream.spec.ts # internal/e2e-js/tests/roomSessionBadNetwork.spec.ts # internal/e2e-js/tests/roomSessionCleanup.spec.ts # internal/e2e-js/tests/roomSessionDemote.spec.ts # internal/e2e-js/tests/roomSessionDemoteAudience.spec.ts # internal/e2e-js/tests/roomSessionDemotePromote.spec.ts # internal/e2e-js/tests/roomSessionDemoteReattachPromote.spec.ts # internal/e2e-js/tests/roomSessionDevices.spec.ts # internal/e2e-js/tests/roomSessionFollowLeader.spec.ts # internal/e2e-js/tests/roomSessionJoinFrom.spec.ts # internal/e2e-js/tests/roomSessionJoinUntil.spec.ts # internal/e2e-js/tests/roomSessionLocalStream.spec.ts # internal/e2e-js/tests/roomSessionLockUnlock.spec.ts # internal/e2e-js/tests/roomSessionMaxMembers.spec.ts # internal/e2e-js/tests/roomSessionMethodsOnNonExistingMembers.spec.ts # internal/e2e-js/tests/roomSessionMultipleStreams.spec.ts # internal/e2e-js/tests/roomSessionPromoteDemote.spec.ts # internal/e2e-js/tests/roomSessionPromoteMeta.spec.ts # internal/e2e-js/tests/roomSessionPromoteParticipant.spec.ts # internal/e2e-js/tests/roomSessionPromoteReattachDemote.spec.ts # internal/e2e-js/tests/roomSessionRaiseHand.spec.ts # internal/e2e-js/tests/roomSessionReattach.spec.ts # internal/e2e-js/tests/roomSessionReattachBadAuth.spec.ts # internal/e2e-js/tests/roomSessionReattachMultiple.spec.ts # internal/e2e-js/tests/roomSessionReattachScreenshare.spec.ts # internal/e2e-js/tests/roomSessionReattachWrongCallId.spec.ts # internal/e2e-js/tests/roomSessionReattachWrongProtocol.spec.ts # internal/e2e-js/tests/roomSessionRemoveAllMembers.spec.ts # internal/e2e-js/tests/roomSessionStreaming.spec.ts # internal/e2e-js/tests/roomSessionStreamingAPI.spec.ts # internal/e2e-js/tests/roomSessionTalkingEventsParticipant.spec.ts # internal/e2e-js/tests/roomSessionTalkingEventsToAudience.spec.ts # internal/e2e-js/tests/roomSessionUnauthorized.spec.ts # internal/e2e-js/tests/roomSessionUpdateMedia.spec.ts # internal/e2e-js/tests/roomSettings.spec.ts # internal/e2e-js/utils.ts # packages/js/src/fabric/FabricRoomSession.ts # packages/js/src/fabric/utils/validationProxy.ts # packages/js/src/fabric/utils/validators.ts
- Copy playground-js to playground-client - Remove non-fabric samples (chat, pubSub, video, videoManager) - Update imports to use @signalwire/client instead of @signalwire/js - Add Vite configuration for proper module resolution - Update e2e-client to use playground-client 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]>
- Apply Vite configuration fixes to properly resolve @signalwire/client modules - Update blank template to explicitly import and expose SignalWire exports - Add module aliases, optimization, and process definitions for browser compatibility - This ensures window._SWJS is properly populated during e2e tests The combination of playground-client and these fixes resolves the module loading issue. 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]>
- Remove direct dependency on @signalwire/realtime-api in test file - Create relayAppWorker.js to execute realtime-api operations in Node.js context - Add relayAppClient fixture to manage Node.js child processes - Install @signalwire/realtime-api as dev dependency from npm registry - Update all three test cases to use the new fixture pattern - Maintain same test assertions and behavior This change isolates the realtime-api package execution to a separate Node.js process, allowing the tests to work without importing the Node.js-only package directly. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Co-authored-by: Ammar Ansari <[email protected]>
Co-authored-by: Ammar Ansari <[email protected]>
Co-authored-by: Ammar Ansari <[email protected]>
Co-authored-by: Ammar Ansari <[email protected]>
8e14e95
to
acaa0be
Compare
@@ -436,23 +447,131 @@ const createCFClientWithToken = async ( | |||
return swClient | |||
} | |||
|
|||
export const createCallStateUtility = (page: Page) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an attempt to simplify the e2e tests.
This allows for both waiting for a specific event and waiting for a particular change of state.
// Trigger mute action | ||
await page.evaluate(async () => { | ||
const callObj = window._callObj | ||
await callObj!.audioMute() | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be helpful for debugging purposes if page.evalulate()
call that awaits or resolves a promise should also have a timeout
otherwise we could still potentially have "hanging" promises
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a valid point, especially when the promise resolution depends on external events.
But for method calls, the SDK has its internal timeout, and page.evaluate
has a default timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious and trying to understand if I am missing something - If the page.evaluate
has the default timeout. Why did we even create the new utilities?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, we don't need the utilities; they are a nice-to-have.
What we need is a test to execute a single action each time it runs in the page scope.
If inside the page.evaluate
, we have only await callObj!.audioMute()
like here when this page.evaluate
fail we now exactly why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could take advantage of test.step
to improve readibility of the test
@@ -436,23 +447,131 @@ const createCFClientWithToken = async ( | |||
return swClient | |||
} | |||
|
|||
export const createCallStateUtility = (page: Page) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we might want some unit tests for the _callState
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now you really made me think... I always thought test code is self-testable 🤔
You can still write a faulty test, but that means the code being tested has a "pairing" fault... And if that is the case, the problem most likely is a misunderstanding of the requirements, meaning that all attempts to test will embed the same fault.
I never thought to test a test, but maybe I'm wrong...
But in this case, what do you mean by " unit tests for the _callState"? What function/implementation do you think I should cover?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just that the __callState
instance has state and some methods that might be worthwhile to write unit tests so that:
- That the state and methods work as intended
- There are no unintended regressions or bugs introduced in the future should this test utility change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I was thinking that if these utilities have some level of complexity and are critical to the e2e tests then they might be worthwhile having their own set of basic tests to minimize the chances that the e2e tests don't face errors due to the test code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let me try that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just highlighting:
- the Realtime-API does not have
listen
param with event names. It simply has callback handlers. For eg;onCallReceived
,onPlaybackStarted
, etc. Ref: https://developer.signalwire.com/sdks/realtime-sdk/voice/call#events - similarly the Realtime-API provide event handlers for all the APIs. It also allows attaching child listener on parent. For eg; on parent, the listener callback can be
onPlaybackStarted
, but on the child (playback API), the same listener can be attached asonStarted
. https://developer.signalwire.com/sdks/realtime-sdk/voice/call-playback#events
Based on the above points, I am not sure if that's what the DevExp need. But I will leave this decision up to you.
internal/e2e-client/utils.ts
Outdated
_callState?: { | ||
history: any[] | ||
update(event: string, payload: any): void | ||
getState(): any | ||
getSelfState(): any | ||
logHistory(): void | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid any
, if possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I want any
, this is to handle ANY object passed to it.
internal/e2e-client/utils.ts
Outdated
@@ -58,22 +68,24 @@ export const createTestServer = async ( | |||
logLevel: 'silent', | |||
resolve: { | |||
alias: { | |||
'@signalwire/client': path.resolve(__dirname, '../../packages/client/src'), | |||
'@signalwire/client': path.resolve( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty weird, I am not sure why we even need these aliases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@claude, can you check why we are using the aliases while creating the Playwright test server using Vite? The e2e-client
package is a part of the monorepo, which has the @signalwire/client
package already. Do we even need these aliases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return this.buildOutboundCall(params) | ||
|
||
const callSession = this.buildOutboundCall(params) | ||
return this.initializeCallSession(callSession, params, 'dial') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dial
is now going to start the call as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only if the user opted to pass the listeners.
But yes, dial
now can be used to dial the address, not just build a session then later start the call.
this.logger.debug(`adding listener for event '${eventName}'`) | ||
const wrappedHandler = async (params: any) => { | ||
try { | ||
await handler(params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
await' has no effect on the type of this expression.ts(80007)
You probably don't need the await
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -316,15 +318,55 @@ export class WSClient extends BaseClient<{}> implements WSClientContract { | |||
}) | |||
} | |||
|
|||
public dial(params: DialParams) { | |||
// TODO: Do we need this remove item here? | |||
private async initializeCallSession( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might be able to move this to the CallSession
class so that you don't need to pass the callSession
as a parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, we can do that later
internal/e2e-client/utils.ts
Outdated
}) => { | ||
return new Promise<any>(async (resolve, _reject) => { | ||
// @ts-expect-error | ||
const client: SignalWireContract = window._client | ||
const listenHandlers: any = {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can avoid any
here:
Considering the listen
type in Dial and Reattach is Partial<CallSessionEvents>
, you may need to export the CallSessionEvents
type from the SDK.
const listenHandlers: any = {} | |
const listenHandlers: Partial<CallSessionEvents> = {} |
@@ -4,6 +4,7 @@ import { | |||
IncomingCallHandlers, | |||
} from './incomingCallManager' | |||
import { CallSession } from '../CallSession' | |||
import { CallSessionEvents } from 'packages/client/src/utils/interfaces' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import should be relative to avoid build issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
Claude finished @jpsantosbh's task —— View job Pull Request ReviewReviewing PR #1289: Add optional listen param to dial() to support starting calls using a single method. Review Tasks:
SummaryThis PR successfully implements the optional Code Quality Assessment✅ Strengths
|
Claude finished @jpsantosbh's task —— View job Pull Request ReviewReviewing PR #1289: Add optional listen param to dial() to support starting calls using a single method. Review Tasks:
SummaryThis PR successfully implements the optional Code Quality Assessment✅ Strengths
|
Claude finished @jpsantosbh's task —— View job Pull Request ReviewReviewing PR #1289: Add optional listen param to dial() to support starting calls using a single method. Review Tasks:
SummaryThis PR successfully implements the optional Code Quality Assessment✅ Strengths
|
Description
Make
dial()
async again to support listen parameters similar to the realtime-sdk API. This is an old request from the DevEx team, and we need this before the first public release of @signalwire/client SDK.The old way still allowed developers to choose between the "dial(), add listeners, start()" or "dial(listen:{...})" approach.
Type of change
Code snippets
In case of new feature or breaking changes, please include code snippets.