-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resolve the
.ended()
promise in case of call failure (#732)
* Emit playback.failed event on playback failure and resolve the playback promise * comments for the e2e changes * end stated variable moved to top * resolve the promise in case of prompt failure * resolve the recording promise when finished * resolve the promise in case the detection has finished * resolve the collect promise on finished * resolve the tap promise and update end state types * e2e test cases for voice prompt * e2e test cases for detect function * e2e test cases for tap function * e2e test cases for recording function * sleep function as a util and changeset update
- Loading branch information
Showing
19 changed files
with
699 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
'@signalwire/realtime-api': minor | ||
'@signalwire/core': minor | ||
--- | ||
|
||
Emit `playback.failed` event on playback failure | ||
Resolve the playback `.ended()` promise in case of Playback failure | ||
Resolve the playback `.ended()` promise in case of Prompt failure | ||
Resolve the playback `.ended()` promise in case of Recording failure | ||
Resolve the playback `.ended()` promise in case of Detect failure | ||
Resolve the playback `.ended()` promise in case of Collect failure | ||
Resolve the playback `.ended()` promise in case of Tap failure |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import tap from 'tap' | ||
import { Voice } from '@signalwire/realtime-api' | ||
import { createTestRunner } from './utils' | ||
|
||
const handler = () => { | ||
return new Promise<number>(async (resolve, reject) => { | ||
const client = new Voice.Client({ | ||
host: process.env.RELAY_HOST || 'relay.swire.io', | ||
project: process.env.RELAY_PROJECT as string, | ||
token: process.env.RELAY_TOKEN as string, | ||
contexts: [process.env.VOICE_CONTEXT as string], | ||
}) | ||
|
||
client.on('call.received', async (call) => { | ||
console.log( | ||
'Inbound - Got call', | ||
call.id, | ||
call.from, | ||
call.to, | ||
call.direction | ||
) | ||
|
||
try { | ||
const resultAnswer = await call.answer() | ||
tap.ok(resultAnswer.id, 'Inbound - Call answered') | ||
tap.equal( | ||
call.id, | ||
resultAnswer.id, | ||
'Inbound - Call answered gets the same instance' | ||
) | ||
|
||
// Send digits 1234 to the caller | ||
const sendDigitResult = await call.sendDigits('1w2w3w4w#') | ||
tap.equal( | ||
call.id, | ||
sendDigitResult.id, | ||
'Inbound - sendDigit returns the same instance' | ||
) | ||
|
||
// Callee hangs up a call | ||
await call.hangup() | ||
} catch (error) { | ||
console.error('Inbound - Error', error) | ||
reject(4) | ||
} | ||
}) | ||
|
||
const call = await client.dialPhone({ | ||
to: process.env.VOICE_DIAL_TO_NUMBER as string, | ||
from: process.env.VOICE_DIAL_FROM_NUMBER as string, | ||
timeout: 30, | ||
}) | ||
tap.ok(call.id, 'Outbound - Call resolved') | ||
|
||
// Start a detect | ||
const detect = await call.detectDigit({ digits: '1234' }) | ||
|
||
tap.equal( | ||
call.id, | ||
detect.callId, | ||
'Outbound - Detect returns the same instance' | ||
) | ||
|
||
const { type } = await detect.ended() | ||
|
||
tap.equal(type, 'digit', 'Outbound - Received the digit') | ||
|
||
resolve(0) | ||
}) | ||
} | ||
|
||
async function main() { | ||
const runner = createTestRunner({ | ||
name: 'Voice Detect E2E', | ||
testHandler: handler, | ||
executionTime: 60_000, | ||
}) | ||
|
||
await runner.run() | ||
} | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import tap from 'tap' | ||
import { Voice } from '@signalwire/realtime-api' | ||
import { createTestRunner } from './utils' | ||
|
||
const handler = () => { | ||
return new Promise<number>(async (resolve, reject) => { | ||
const client = new Voice.Client({ | ||
host: process.env.RELAY_HOST || 'relay.swire.io', | ||
project: process.env.RELAY_PROJECT as string, | ||
token: process.env.RELAY_TOKEN as string, | ||
contexts: [process.env.VOICE_CONTEXT as string], | ||
}) | ||
|
||
client.on('call.received', async (call) => { | ||
console.log( | ||
'Inbound - Got call', | ||
call.id, | ||
call.from, | ||
call.to, | ||
call.direction | ||
) | ||
|
||
try { | ||
const resultAnswer = await call.answer() | ||
tap.ok(resultAnswer.id, 'Inbound - Call answered') | ||
tap.equal( | ||
call.id, | ||
resultAnswer.id, | ||
'Inbound - Call answered gets the same instance' | ||
) | ||
|
||
// Play an invalid audio | ||
const handle = await call.playAudio({ | ||
url: 'https://cdn.fake.com/default-music/fake.mp3', | ||
}) | ||
|
||
tap.equal( | ||
call.id, | ||
handle.callId, | ||
'Inbound - playback returns the same instance' | ||
) | ||
|
||
const waitForPlaybackFailed = new Promise((resolve) => { | ||
call.on('playback.failed', (playback) => { | ||
tap.equal(playback.state, 'error', 'Inbound - playback has failed') | ||
resolve(true) | ||
}) | ||
}) | ||
// Wait for the inbound audio to failed | ||
await waitForPlaybackFailed | ||
|
||
// Callee hangs up a call | ||
await call.hangup() | ||
} catch (error) { | ||
console.error('Inbound - Error', error) | ||
reject(4) | ||
} | ||
}) | ||
|
||
const call = await client.dialPhone({ | ||
to: process.env.VOICE_DIAL_TO_NUMBER as string, | ||
from: process.env.VOICE_DIAL_FROM_NUMBER as string, | ||
timeout: 30, | ||
}) | ||
tap.ok(call.id, 'Outbound - Call resolved') | ||
|
||
// Play an audio | ||
const handle = await call.playAudio({ | ||
url: 'https://cdn.signalwire.com/default-music/welcome.mp3', | ||
}) | ||
|
||
tap.equal( | ||
call.id, | ||
handle.callId, | ||
'Outbound - Playback returns the same instance' | ||
) | ||
|
||
const waitForPlaybackStarted = new Promise((resolve) => { | ||
call.on('playback.started', (playback) => { | ||
tap.equal(playback.state, 'playing', 'Outbound - Playback has started') | ||
resolve(true) | ||
}) | ||
}) | ||
// Wait for the outbound audio to start | ||
await waitForPlaybackStarted | ||
|
||
const waitForPlaybackEnded = new Promise((resolve) => { | ||
call.on('playback.ended', (playback) => { | ||
tap.equal( | ||
playback.state, | ||
'finished', | ||
'Outbound - Playback has finished' | ||
) | ||
resolve(true) | ||
}) | ||
}) | ||
// Wait for the outbound audio to end (callee hung up the call or audio ended) | ||
await waitForPlaybackEnded | ||
|
||
const waitForParams = ['ended', 'ending', ['ending', 'ended']] as const | ||
const results = await Promise.all( | ||
waitForParams.map((params) => call.waitFor(params as any)) | ||
) | ||
waitForParams.forEach((value, i) => { | ||
if (typeof value === 'string') { | ||
tap.ok(results[i], `"${value}": completed successfully.`) | ||
} else { | ||
tap.ok(results[i], `${JSON.stringify(value)}: completed successfully.`) | ||
} | ||
}) | ||
|
||
resolve(0) | ||
}) | ||
} | ||
|
||
async function main() { | ||
const runner = createTestRunner({ | ||
name: 'Voice Playback E2E', | ||
testHandler: handler, | ||
executionTime: 60_000, | ||
}) | ||
|
||
await runner.run() | ||
} | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import tap from 'tap' | ||
import { Voice } from '@signalwire/realtime-api' | ||
import { createTestRunner } from './utils' | ||
|
||
const handler = () => { | ||
return new Promise<number>(async (resolve, reject) => { | ||
const client = new Voice.Client({ | ||
host: process.env.RELAY_HOST || 'relay.swire.io', | ||
project: process.env.RELAY_PROJECT as string, | ||
token: process.env.RELAY_TOKEN as string, | ||
contexts: [process.env.VOICE_CONTEXT as string], | ||
}) | ||
|
||
client.on('call.received', async (call) => { | ||
console.log( | ||
'Inbound - Got call', | ||
call.id, | ||
call.from, | ||
call.to, | ||
call.direction | ||
) | ||
|
||
try { | ||
const resultAnswer = await call.answer() | ||
tap.ok(resultAnswer.id, 'Inbound - Call answered') | ||
tap.equal( | ||
call.id, | ||
resultAnswer.id, | ||
'Inbound - Call answered gets the same instance' | ||
) | ||
|
||
// Send digits 1234 to the caller | ||
const sendDigitResult = await call.sendDigits('1w2w3w4w#') | ||
tap.equal( | ||
call.id, | ||
sendDigitResult.id, | ||
'Inbound - sendDigit returns the same instance' | ||
) | ||
|
||
// Callee hangs up a call | ||
await call.hangup() | ||
} catch (error) { | ||
console.error('Inbound - Error', error) | ||
reject(4) | ||
} | ||
}) | ||
|
||
const call = await client.dialPhone({ | ||
to: process.env.VOICE_DIAL_TO_NUMBER as string, | ||
from: process.env.VOICE_DIAL_FROM_NUMBER as string, | ||
timeout: 30, | ||
}) | ||
tap.ok(call.id, 'Outbound - Call resolved') | ||
|
||
// Start a prompt | ||
const prompt = await call.prompt({ | ||
playlist: new Voice.Playlist({ volume: 1.0 }).add( | ||
Voice.Playlist.TTS({ | ||
text: 'Welcome to SignalWire! Please enter your 4 digits PIN', | ||
}) | ||
), | ||
digits: { | ||
max: 4, | ||
digitTimeout: 10, | ||
terminators: '#', | ||
}, | ||
}) | ||
|
||
tap.equal( | ||
call.id, | ||
prompt.callId, | ||
'Outbound - Prompt returns the same instance' | ||
) | ||
|
||
const { digits } = await prompt.ended() | ||
|
||
tap.equal(digits, '1234', 'Outbound - Received the same digit') | ||
|
||
const waitForParams = ['ended', 'ending', ['ending', 'ended']] as const | ||
const results = await Promise.all( | ||
waitForParams.map((params) => call.waitFor(params as any)) | ||
) | ||
waitForParams.forEach((value, i) => { | ||
if (typeof value === 'string') { | ||
tap.ok(results[i], `"${value}": completed successfully.`) | ||
} else { | ||
tap.ok(results[i], `${JSON.stringify(value)}: completed successfully.`) | ||
} | ||
}) | ||
|
||
resolve(0) | ||
}) | ||
} | ||
|
||
async function main() { | ||
const runner = createTestRunner({ | ||
name: 'Voice Prompt E2E', | ||
testHandler: handler, | ||
executionTime: 60_000, | ||
}) | ||
|
||
await runner.run() | ||
} | ||
|
||
main() |
Oops, something went wrong.