@webex/plugin-meetings 3.0.0-beta.2 → 3.0.0-beta.200

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (576) hide show
  1. package/README.md +45 -7
  2. package/UPGRADING.md +9 -9
  3. package/browsers.js +19 -24
  4. package/dist/annotation/annotation.types.js +7 -0
  5. package/dist/annotation/annotation.types.js.map +1 -0
  6. package/dist/annotation/constants.js +49 -0
  7. package/dist/annotation/constants.js.map +1 -0
  8. package/dist/annotation/index.js +342 -0
  9. package/dist/annotation/index.js.map +1 -0
  10. package/dist/breakouts/breakout.js +216 -0
  11. package/dist/breakouts/breakout.js.map +1 -0
  12. package/dist/breakouts/collection.js +23 -0
  13. package/dist/breakouts/collection.js.map +1 -0
  14. package/dist/breakouts/edit-lock-error.js +52 -0
  15. package/dist/breakouts/edit-lock-error.js.map +1 -0
  16. package/dist/breakouts/events.js +45 -0
  17. package/dist/breakouts/events.js.map +1 -0
  18. package/dist/breakouts/index.js +1048 -0
  19. package/dist/breakouts/index.js.map +1 -0
  20. package/dist/breakouts/request.js +78 -0
  21. package/dist/breakouts/request.js.map +1 -0
  22. package/dist/breakouts/utils.js +67 -0
  23. package/dist/breakouts/utils.js.map +1 -0
  24. package/dist/common/browser-detection.js +1 -20
  25. package/dist/common/browser-detection.js.map +1 -1
  26. package/dist/common/collection.js +5 -20
  27. package/dist/common/collection.js.map +1 -1
  28. package/dist/common/config.js +0 -7
  29. package/dist/common/config.js.map +1 -1
  30. package/dist/common/errors/captcha-error.js +10 -24
  31. package/dist/common/errors/captcha-error.js.map +1 -1
  32. package/dist/common/errors/intent-to-join.js +11 -24
  33. package/dist/common/errors/intent-to-join.js.map +1 -1
  34. package/dist/common/errors/join-meeting.js +12 -25
  35. package/dist/common/errors/join-meeting.js.map +1 -1
  36. package/dist/common/errors/media.js +10 -24
  37. package/dist/common/errors/media.js.map +1 -1
  38. package/dist/common/errors/parameter.js +5 -33
  39. package/dist/common/errors/parameter.js.map +1 -1
  40. package/dist/common/errors/password-error.js +10 -24
  41. package/dist/common/errors/password-error.js.map +1 -1
  42. package/dist/common/errors/permission.js +9 -23
  43. package/dist/common/errors/permission.js.map +1 -1
  44. package/dist/common/errors/reconnection-in-progress.js +0 -17
  45. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  46. package/dist/common/errors/reconnection.js +10 -24
  47. package/dist/common/errors/reconnection.js.map +1 -1
  48. package/dist/common/errors/stats.js +10 -24
  49. package/dist/common/errors/stats.js.map +1 -1
  50. package/dist/common/errors/webex-errors.js +9 -43
  51. package/dist/common/errors/webex-errors.js.map +1 -1
  52. package/dist/common/errors/webex-meetings-error.js +5 -25
  53. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  54. package/dist/common/events/events-scope.js +0 -22
  55. package/dist/common/events/events-scope.js.map +1 -1
  56. package/dist/common/events/events.js +0 -23
  57. package/dist/common/events/events.js.map +1 -1
  58. package/dist/common/events/trigger-proxy.js +0 -12
  59. package/dist/common/events/trigger-proxy.js.map +1 -1
  60. package/dist/common/events/util.js +0 -15
  61. package/dist/common/events/util.js.map +1 -1
  62. package/dist/common/logs/logger-config.js +0 -4
  63. package/dist/common/logs/logger-config.js.map +1 -1
  64. package/dist/common/logs/logger-proxy.js +1 -8
  65. package/dist/common/logs/logger-proxy.js.map +1 -1
  66. package/dist/common/logs/request.js +37 -60
  67. package/dist/common/logs/request.js.map +1 -1
  68. package/dist/common/queue.js +28 -23
  69. package/dist/common/queue.js.map +1 -1
  70. package/dist/config.js +8 -13
  71. package/dist/config.js.map +1 -1
  72. package/dist/constants.js +250 -66
  73. package/dist/constants.js.map +1 -1
  74. package/dist/controls-options-manager/constants.js +14 -0
  75. package/dist/controls-options-manager/constants.js.map +1 -0
  76. package/dist/controls-options-manager/enums.js +27 -0
  77. package/dist/controls-options-manager/enums.js.map +1 -0
  78. package/dist/controls-options-manager/index.js +297 -0
  79. package/dist/controls-options-manager/index.js.map +1 -0
  80. package/dist/controls-options-manager/types.js +7 -0
  81. package/dist/controls-options-manager/types.js.map +1 -0
  82. package/dist/controls-options-manager/util.js +319 -0
  83. package/dist/controls-options-manager/util.js.map +1 -0
  84. package/dist/index.js +108 -17
  85. package/dist/index.js.map +1 -1
  86. package/dist/interpretation/collection.js +23 -0
  87. package/dist/interpretation/collection.js.map +1 -0
  88. package/dist/interpretation/index.js +366 -0
  89. package/dist/interpretation/index.js.map +1 -0
  90. package/dist/interpretation/siLanguage.js +25 -0
  91. package/dist/interpretation/siLanguage.js.map +1 -0
  92. package/dist/locus-info/controlsUtils.js +101 -29
  93. package/dist/locus-info/controlsUtils.js.map +1 -1
  94. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  95. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  96. package/dist/locus-info/fullState.js +0 -15
  97. package/dist/locus-info/fullState.js.map +1 -1
  98. package/dist/locus-info/hostUtils.js +4 -12
  99. package/dist/locus-info/hostUtils.js.map +1 -1
  100. package/dist/locus-info/index.js +532 -240
  101. package/dist/locus-info/index.js.map +1 -1
  102. package/dist/locus-info/infoUtils.js +3 -37
  103. package/dist/locus-info/infoUtils.js.map +1 -1
  104. package/dist/locus-info/mediaSharesUtils.js +54 -38
  105. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  106. package/dist/locus-info/parser.js +284 -154
  107. package/dist/locus-info/parser.js.map +1 -1
  108. package/dist/locus-info/selfUtils.js +110 -92
  109. package/dist/locus-info/selfUtils.js.map +1 -1
  110. package/dist/media/index.js +95 -226
  111. package/dist/media/index.js.map +1 -1
  112. package/dist/media/properties.js +99 -194
  113. package/dist/media/properties.js.map +1 -1
  114. package/dist/media/util.js +2 -9
  115. package/dist/media/util.js.map +1 -1
  116. package/dist/mediaQualityMetrics/config.js +505 -495
  117. package/dist/mediaQualityMetrics/config.js.map +1 -1
  118. package/dist/meeting/in-meeting-actions.js +83 -14
  119. package/dist/meeting/in-meeting-actions.js.map +1 -1
  120. package/dist/meeting/index.js +3478 -3563
  121. package/dist/meeting/index.js.map +1 -1
  122. package/dist/meeting/locusMediaRequest.js +291 -0
  123. package/dist/meeting/locusMediaRequest.js.map +1 -0
  124. package/dist/meeting/muteState.js +247 -183
  125. package/dist/meeting/muteState.js.map +1 -1
  126. package/dist/meeting/request.js +344 -344
  127. package/dist/meeting/request.js.map +1 -1
  128. package/dist/meeting/request.type.js +7 -0
  129. package/dist/meeting/request.type.js.map +1 -0
  130. package/dist/meeting/state.js +21 -31
  131. package/dist/meeting/state.js.map +1 -1
  132. package/dist/meeting/util.js +529 -588
  133. package/dist/meeting/util.js.map +1 -1
  134. package/dist/meeting-info/collection.js +6 -25
  135. package/dist/meeting-info/collection.js.map +1 -1
  136. package/dist/meeting-info/index.js +62 -39
  137. package/dist/meeting-info/index.js.map +1 -1
  138. package/dist/meeting-info/meeting-info-v2.js +328 -283
  139. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  140. package/dist/meeting-info/request.js +3 -15
  141. package/dist/meeting-info/request.js.map +1 -1
  142. package/dist/meeting-info/util.js +98 -183
  143. package/dist/meeting-info/util.js.map +1 -1
  144. package/dist/meeting-info/utilv2.js +156 -232
  145. package/dist/meeting-info/utilv2.js.map +1 -1
  146. package/dist/meetings/collection.js +26 -19
  147. package/dist/meetings/collection.js.map +1 -1
  148. package/dist/meetings/index.js +795 -574
  149. package/dist/meetings/index.js.map +1 -1
  150. package/dist/meetings/meetings.types.js +7 -0
  151. package/dist/meetings/meetings.types.js.map +1 -0
  152. package/dist/meetings/request.js +26 -41
  153. package/dist/meetings/request.js.map +1 -1
  154. package/dist/meetings/util.js +186 -155
  155. package/dist/meetings/util.js.map +1 -1
  156. package/dist/member/index.js +126 -85
  157. package/dist/member/index.js.map +1 -1
  158. package/dist/member/types.js +25 -0
  159. package/dist/member/types.js.map +1 -0
  160. package/dist/member/util.js +147 -88
  161. package/dist/member/util.js.map +1 -1
  162. package/dist/members/collection.js +13 -12
  163. package/dist/members/collection.js.map +1 -1
  164. package/dist/members/index.js +178 -204
  165. package/dist/members/index.js.map +1 -1
  166. package/dist/members/request.js +113 -68
  167. package/dist/members/request.js.map +1 -1
  168. package/dist/members/types.js +15 -0
  169. package/dist/members/types.js.map +1 -0
  170. package/dist/members/util.js +314 -260
  171. package/dist/members/util.js.map +1 -1
  172. package/dist/metrics/constants.js +4 -7
  173. package/dist/metrics/constants.js.map +1 -1
  174. package/dist/metrics/index.js +11 -558
  175. package/dist/metrics/index.js.map +1 -1
  176. package/dist/multistream/mediaRequestManager.js +264 -50
  177. package/dist/multistream/mediaRequestManager.js.map +1 -1
  178. package/dist/multistream/receiveSlot.js +58 -65
  179. package/dist/multistream/receiveSlot.js.map +1 -1
  180. package/dist/multistream/receiveSlotManager.js +76 -95
  181. package/dist/multistream/receiveSlotManager.js.map +1 -1
  182. package/dist/multistream/remoteMedia.js +62 -76
  183. package/dist/multistream/remoteMedia.js.map +1 -1
  184. package/dist/multistream/remoteMediaGroup.js +66 -43
  185. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  186. package/dist/multistream/remoteMediaManager.js +502 -442
  187. package/dist/multistream/remoteMediaManager.js.map +1 -1
  188. package/dist/networkQualityMonitor/index.js +40 -59
  189. package/dist/networkQualityMonitor/index.js.map +1 -1
  190. package/dist/personal-meeting-room/index.js +21 -45
  191. package/dist/personal-meeting-room/index.js.map +1 -1
  192. package/dist/personal-meeting-room/request.js +1 -31
  193. package/dist/personal-meeting-room/request.js.map +1 -1
  194. package/dist/personal-meeting-room/util.js +0 -13
  195. package/dist/personal-meeting-room/util.js.map +1 -1
  196. package/dist/reachability/index.js +192 -191
  197. package/dist/reachability/index.js.map +1 -1
  198. package/dist/reachability/request.js +15 -23
  199. package/dist/reachability/request.js.map +1 -1
  200. package/dist/reactions/constants.js +13 -0
  201. package/dist/reactions/constants.js.map +1 -0
  202. package/dist/reactions/reactions.js +109 -0
  203. package/dist/reactions/reactions.js.map +1 -0
  204. package/dist/reactions/reactions.type.js +36 -0
  205. package/dist/reactions/reactions.type.js.map +1 -0
  206. package/dist/reconnection-manager/index.js +384 -476
  207. package/dist/reconnection-manager/index.js.map +1 -1
  208. package/dist/recording-controller/enums.js +17 -0
  209. package/dist/recording-controller/enums.js.map +1 -0
  210. package/dist/recording-controller/index.js +363 -0
  211. package/dist/recording-controller/index.js.map +1 -0
  212. package/dist/recording-controller/util.js +64 -0
  213. package/dist/recording-controller/util.js.map +1 -0
  214. package/dist/roap/index.js +58 -91
  215. package/dist/roap/index.js.map +1 -1
  216. package/dist/roap/request.js +137 -135
  217. package/dist/roap/request.js.map +1 -1
  218. package/dist/roap/turnDiscovery.js +148 -100
  219. package/dist/roap/turnDiscovery.js.map +1 -1
  220. package/dist/rtcMetrics/constants.js +12 -0
  221. package/dist/rtcMetrics/constants.js.map +1 -0
  222. package/dist/rtcMetrics/index.js +115 -0
  223. package/dist/rtcMetrics/index.js.map +1 -0
  224. package/dist/statsAnalyzer/global.js +1 -95
  225. package/dist/statsAnalyzer/global.js.map +1 -1
  226. package/dist/statsAnalyzer/index.js +385 -460
  227. package/dist/statsAnalyzer/index.js.map +1 -1
  228. package/dist/statsAnalyzer/mqaUtil.js +143 -87
  229. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  230. package/dist/transcription/index.js +22 -47
  231. package/dist/transcription/index.js.map +1 -1
  232. package/dist/types/annotation/annotation.types.d.ts +42 -0
  233. package/dist/types/annotation/constants.d.ts +31 -0
  234. package/dist/types/annotation/index.d.ts +117 -0
  235. package/dist/types/breakouts/breakout.d.ts +8 -0
  236. package/dist/types/breakouts/collection.d.ts +5 -0
  237. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  238. package/dist/types/breakouts/events.d.ts +8 -0
  239. package/dist/types/breakouts/index.d.ts +5 -0
  240. package/dist/types/breakouts/request.d.ts +22 -0
  241. package/dist/types/breakouts/utils.d.ts +15 -0
  242. package/dist/types/common/browser-detection.d.ts +9 -0
  243. package/dist/types/common/collection.d.ts +48 -0
  244. package/dist/types/common/config.d.ts +2 -0
  245. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  246. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  247. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  248. package/dist/types/common/errors/media.d.ts +15 -0
  249. package/dist/types/common/errors/parameter.d.ts +15 -0
  250. package/dist/types/common/errors/password-error.d.ts +15 -0
  251. package/dist/types/common/errors/permission.d.ts +14 -0
  252. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  253. package/dist/types/common/errors/reconnection.d.ts +15 -0
  254. package/dist/types/common/errors/stats.d.ts +15 -0
  255. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  256. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  257. package/dist/types/common/events/events-scope.d.ts +17 -0
  258. package/dist/types/common/events/events.d.ts +12 -0
  259. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  260. package/dist/types/common/events/util.d.ts +2 -0
  261. package/dist/types/common/logs/logger-config.d.ts +2 -0
  262. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  263. package/dist/types/common/logs/request.d.ts +34 -0
  264. package/dist/types/common/queue.d.ts +34 -0
  265. package/dist/types/config.d.ts +72 -0
  266. package/dist/types/constants.d.ts +1016 -0
  267. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  268. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  269. package/dist/types/controls-options-manager/index.d.ts +136 -0
  270. package/dist/types/controls-options-manager/types.d.ts +43 -0
  271. package/dist/types/controls-options-manager/util.d.ts +1 -0
  272. package/dist/types/index.d.ts +7 -0
  273. package/dist/types/interpretation/collection.d.ts +5 -0
  274. package/dist/types/interpretation/index.d.ts +5 -0
  275. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  276. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  277. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  278. package/dist/types/locus-info/fullState.d.ts +2 -0
  279. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  280. package/dist/types/locus-info/index.d.ts +322 -0
  281. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  282. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  283. package/dist/types/locus-info/parser.d.ts +271 -0
  284. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  285. package/dist/types/media/index.d.ts +34 -0
  286. package/dist/types/media/properties.d.ts +93 -0
  287. package/dist/types/media/util.d.ts +2 -0
  288. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  289. package/dist/types/meeting/in-meeting-actions.d.ts +153 -0
  290. package/dist/types/meeting/index.d.ts +1471 -0
  291. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  292. package/dist/types/meeting/muteState.d.ts +184 -0
  293. package/dist/types/meeting/request.d.ts +257 -0
  294. package/dist/types/meeting/request.type.d.ts +11 -0
  295. package/dist/types/meeting/state.d.ts +9 -0
  296. package/dist/types/meeting/util.d.ts +78 -0
  297. package/dist/types/meeting-info/collection.d.ts +20 -0
  298. package/dist/types/meeting-info/index.d.ts +62 -0
  299. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  300. package/dist/types/meeting-info/request.d.ts +22 -0
  301. package/dist/types/meeting-info/util.d.ts +2 -0
  302. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  303. package/dist/types/meetings/collection.d.ts +31 -0
  304. package/dist/types/meetings/index.d.ts +367 -0
  305. package/dist/types/meetings/meetings.types.d.ts +4 -0
  306. package/dist/types/meetings/request.d.ts +27 -0
  307. package/dist/types/meetings/util.d.ts +18 -0
  308. package/dist/types/member/index.d.ts +159 -0
  309. package/dist/types/member/types.d.ts +32 -0
  310. package/dist/types/member/util.d.ts +2 -0
  311. package/dist/types/members/collection.d.ts +29 -0
  312. package/dist/types/members/index.d.ts +353 -0
  313. package/dist/types/members/request.d.ts +114 -0
  314. package/dist/types/members/types.d.ts +24 -0
  315. package/dist/types/members/util.d.ts +210 -0
  316. package/dist/types/metrics/constants.d.ts +55 -0
  317. package/dist/types/metrics/index.d.ts +45 -0
  318. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  319. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  320. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  321. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  322. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  323. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  324. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  325. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  326. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  327. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  328. package/dist/types/reachability/index.d.ts +152 -0
  329. package/dist/types/reachability/request.d.ts +37 -0
  330. package/dist/types/reactions/constants.d.ts +3 -0
  331. package/dist/types/reactions/reactions.d.ts +4 -0
  332. package/dist/types/reactions/reactions.type.d.ts +52 -0
  333. package/dist/types/reconnection-manager/index.d.ts +126 -0
  334. package/dist/types/recording-controller/enums.d.ts +7 -0
  335. package/dist/types/recording-controller/index.d.ts +208 -0
  336. package/dist/types/recording-controller/util.d.ts +14 -0
  337. package/dist/types/roap/index.d.ts +77 -0
  338. package/dist/types/roap/request.d.ts +36 -0
  339. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  340. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  341. package/dist/types/rtcMetrics/index.d.ts +46 -0
  342. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  343. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  344. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  345. package/dist/types/transcription/index.d.ts +64 -0
  346. package/internal-README.md +7 -6
  347. package/package.json +29 -21
  348. package/src/annotation/annotation.types.ts +50 -0
  349. package/src/annotation/constants.ts +36 -0
  350. package/src/annotation/index.ts +328 -0
  351. package/src/breakouts/README.md +220 -0
  352. package/src/breakouts/breakout.ts +188 -0
  353. package/src/breakouts/collection.ts +19 -0
  354. package/src/breakouts/edit-lock-error.ts +25 -0
  355. package/src/breakouts/events.ts +56 -0
  356. package/src/breakouts/index.ts +925 -0
  357. package/src/breakouts/request.ts +55 -0
  358. package/src/breakouts/utils.ts +57 -0
  359. package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
  360. package/src/common/collection.ts +9 -7
  361. package/src/common/{config.js → config.ts} +1 -1
  362. package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
  363. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
  364. package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
  365. package/src/common/errors/{media.js → media.ts} +11 -7
  366. package/src/common/errors/parameter.ts +11 -7
  367. package/src/common/errors/{password-error.js → password-error.ts} +11 -7
  368. package/src/common/errors/{permission.js → permission.ts} +10 -6
  369. package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
  370. package/src/common/errors/{stats.js → stats.ts} +11 -7
  371. package/src/common/errors/{webex-errors.js → webex-errors.ts} +14 -9
  372. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
  373. package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
  374. package/src/common/events/{events.js → events.ts} +5 -1
  375. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
  376. package/src/common/events/{util.js → util.ts} +2 -3
  377. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  378. package/src/common/logs/logger-proxy.ts +44 -0
  379. package/src/common/logs/{request.js → request.ts} +22 -9
  380. package/src/common/queue.ts +22 -9
  381. package/src/{config.js → config.ts} +17 -17
  382. package/src/constants.ts +197 -22
  383. package/src/controls-options-manager/constants.ts +5 -0
  384. package/src/controls-options-manager/enums.ts +18 -0
  385. package/src/controls-options-manager/index.ts +278 -0
  386. package/src/controls-options-manager/types.ts +59 -0
  387. package/src/controls-options-manager/util.ts +300 -0
  388. package/src/index.ts +39 -0
  389. package/src/interpretation/README.md +60 -0
  390. package/src/interpretation/collection.ts +19 -0
  391. package/src/interpretation/index.ts +332 -0
  392. package/src/interpretation/siLanguage.ts +18 -0
  393. package/src/locus-info/controlsUtils.ts +222 -0
  394. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  395. package/src/locus-info/{fullState.js → fullState.ts} +16 -12
  396. package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
  397. package/src/locus-info/{index.js → index.ts} +518 -111
  398. package/src/locus-info/{infoUtils.js → infoUtils.ts} +19 -8
  399. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +65 -17
  400. package/src/locus-info/{parser.js → parser.ts} +271 -98
  401. package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
  402. package/src/media/index.ts +456 -0
  403. package/src/media/{properties.js → properties.ts} +80 -102
  404. package/src/media/{util.js → util.ts} +2 -2
  405. package/src/mediaQualityMetrics/config.ts +384 -0
  406. package/src/meeting/in-meeting-actions.ts +171 -3
  407. package/src/meeting/index.ts +7070 -0
  408. package/src/meeting/locusMediaRequest.ts +309 -0
  409. package/src/meeting/muteState.ts +450 -0
  410. package/src/meeting/{request.js → request.ts} +354 -214
  411. package/src/meeting/request.type.ts +13 -0
  412. package/src/meeting/{state.js → state.ts} +50 -35
  413. package/src/meeting/util.ts +615 -0
  414. package/src/meeting-info/{collection.js → collection.ts} +6 -2
  415. package/src/meeting-info/index.ts +183 -0
  416. package/src/meeting-info/meeting-info-v2.ts +407 -0
  417. package/src/meeting-info/{request.js → request.ts} +14 -4
  418. package/src/meeting-info/{util.js → util.ts} +60 -51
  419. package/src/meeting-info/{utilv2.js → utilv2.ts} +77 -60
  420. package/src/meetings/{collection.js → collection.ts} +26 -3
  421. package/src/meetings/index.ts +1467 -0
  422. package/src/meetings/meetings.types.ts +12 -0
  423. package/src/meetings/{request.js → request.ts} +34 -25
  424. package/src/meetings/{util.js → util.ts} +137 -36
  425. package/src/member/{index.js → index.ts} +151 -56
  426. package/src/member/types.ts +38 -0
  427. package/src/member/util.ts +383 -0
  428. package/src/members/{collection.js → collection.ts} +10 -2
  429. package/src/members/{index.js → index.ts} +323 -145
  430. package/src/members/request.ts +255 -0
  431. package/src/members/types.ts +28 -0
  432. package/src/members/util.ts +339 -0
  433. package/src/metrics/{constants.js → constants.ts} +2 -6
  434. package/src/metrics/index.ts +73 -0
  435. package/src/multistream/mediaRequestManager.ts +337 -61
  436. package/src/multistream/receiveSlot.ts +69 -26
  437. package/src/multistream/receiveSlotManager.ts +66 -42
  438. package/src/multistream/remoteMedia.ts +40 -5
  439. package/src/multistream/remoteMediaGroup.ts +63 -3
  440. package/src/multistream/remoteMediaManager.ts +263 -66
  441. package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
  442. package/src/personal-meeting-room/{index.js → index.ts} +28 -19
  443. package/src/personal-meeting-room/{request.js → request.ts} +13 -4
  444. package/src/personal-meeting-room/{util.js → util.ts} +4 -4
  445. package/src/reachability/{index.js → index.ts} +157 -94
  446. package/src/reachability/request.ts +46 -35
  447. package/src/reactions/constants.ts +4 -0
  448. package/src/reactions/reactions.ts +104 -0
  449. package/src/reactions/reactions.type.ts +62 -0
  450. package/src/reconnection-manager/{index.js → index.ts} +254 -136
  451. package/src/recording-controller/enums.ts +8 -0
  452. package/src/recording-controller/index.ts +333 -0
  453. package/src/recording-controller/util.ts +75 -0
  454. package/src/roap/{index.js → index.ts} +86 -78
  455. package/src/roap/request.ts +163 -0
  456. package/src/roap/turnDiscovery.ts +111 -49
  457. package/src/rtcMetrics/constants.ts +3 -0
  458. package/src/rtcMetrics/index.ts +96 -0
  459. package/src/statsAnalyzer/global.ts +37 -0
  460. package/src/statsAnalyzer/index.ts +1272 -0
  461. package/src/statsAnalyzer/mqaUtil.ts +291 -0
  462. package/src/transcription/{index.js → index.ts} +46 -39
  463. package/test/integration/spec/converged-space-meetings.js +233 -0
  464. package/test/integration/spec/journey.js +804 -526
  465. package/test/integration/spec/space-meeting.js +391 -204
  466. package/test/integration/spec/transcription.js +7 -8
  467. package/test/unit/spec/annotation/index.ts +418 -0
  468. package/test/unit/spec/breakouts/breakout.ts +237 -0
  469. package/test/unit/spec/breakouts/collection.ts +15 -0
  470. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  471. package/test/unit/spec/breakouts/events.ts +89 -0
  472. package/test/unit/spec/breakouts/index.ts +1790 -0
  473. package/test/unit/spec/breakouts/request.ts +104 -0
  474. package/test/unit/spec/breakouts/utils.js +72 -0
  475. package/test/unit/spec/common/browser-detection.js +9 -28
  476. package/test/unit/spec/common/queue.js +31 -2
  477. package/test/unit/spec/controls-options-manager/index.js +287 -0
  478. package/test/unit/spec/controls-options-manager/util.js +582 -0
  479. package/test/unit/spec/fixture/locus.js +93 -90
  480. package/test/unit/spec/interpretation/collection.ts +15 -0
  481. package/test/unit/spec/interpretation/index.ts +589 -0
  482. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  483. package/test/unit/spec/locus-info/controlsUtils.js +325 -32
  484. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  485. package/test/unit/spec/locus-info/index.js +1176 -18
  486. package/test/unit/spec/locus-info/infoUtils.js +41 -32
  487. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  488. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  489. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  490. package/test/unit/spec/locus-info/parser.js +65 -31
  491. package/test/unit/spec/locus-info/selfConstant.js +120 -103
  492. package/test/unit/spec/locus-info/selfUtils.js +296 -12
  493. package/test/unit/spec/media/index.ts +162 -68
  494. package/test/unit/spec/media/properties.ts +9 -9
  495. package/test/unit/spec/meeting/in-meeting-actions.ts +82 -3
  496. package/test/unit/spec/meeting/index.js +4569 -1773
  497. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  498. package/test/unit/spec/meeting/muteState.js +382 -211
  499. package/test/unit/spec/meeting/request.js +444 -78
  500. package/test/unit/spec/meeting/utils.js +517 -192
  501. package/test/unit/spec/meeting-info/index.js +181 -0
  502. package/test/unit/spec/meeting-info/meetinginfov2.js +481 -76
  503. package/test/unit/spec/meeting-info/request.js +7 -9
  504. package/test/unit/spec/meeting-info/util.js +11 -12
  505. package/test/unit/spec/meeting-info/utilv2.js +131 -74
  506. package/test/unit/spec/meetings/collection.js +15 -1
  507. package/test/unit/spec/meetings/index.js +1254 -330
  508. package/test/unit/spec/meetings/utils.js +220 -14
  509. package/test/unit/spec/member/index.js +58 -5
  510. package/test/unit/spec/member/util.js +494 -26
  511. package/test/unit/spec/members/index.js +423 -55
  512. package/test/unit/spec/members/request.js +228 -40
  513. package/test/unit/spec/members/utils.js +191 -4
  514. package/test/unit/spec/metrics/index.js +12 -66
  515. package/test/unit/spec/multistream/mediaRequestManager.ts +1013 -106
  516. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  517. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  518. package/test/unit/spec/multistream/remoteMedia.ts +40 -2
  519. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  520. package/test/unit/spec/multistream/remoteMediaManager.ts +730 -65
  521. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  522. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  523. package/test/unit/spec/reachability/index.ts +176 -27
  524. package/test/unit/spec/reachability/request.js +66 -0
  525. package/test/unit/spec/reconnection-manager/index.js +155 -9
  526. package/test/unit/spec/recording-controller/index.js +307 -0
  527. package/test/unit/spec/recording-controller/util.js +229 -0
  528. package/test/unit/spec/roap/index.ts +28 -52
  529. package/test/unit/spec/roap/request.ts +225 -0
  530. package/test/unit/spec/roap/turnDiscovery.ts +92 -50
  531. package/test/unit/spec/rtcMetrics/index.ts +60 -0
  532. package/test/unit/spec/stats-analyzer/index.js +116 -60
  533. package/test/utils/cmr.js +44 -42
  534. package/test/utils/constants.js +9 -0
  535. package/test/utils/integrationTestUtils.js +46 -0
  536. package/test/utils/testUtils.js +63 -99
  537. package/test/utils/webex-config.js +22 -18
  538. package/test/utils/webex-test-users.js +57 -50
  539. package/tsconfig.json +6 -0
  540. package/dist/media/internal-media-core-wrapper.js +0 -22
  541. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  542. package/dist/meeting/effectsState.js +0 -327
  543. package/dist/meeting/effectsState.js.map +0 -1
  544. package/dist/metrics/config.js +0 -301
  545. package/dist/metrics/config.js.map +0 -1
  546. package/dist/multistream/multistreamMedia.js +0 -116
  547. package/dist/multistream/multistreamMedia.js.map +0 -1
  548. package/dist/peer-connection-manager/util.js +0 -124
  549. package/dist/peer-connection-manager/util.js.map +0 -1
  550. package/src/common/logs/logger-proxy.js +0 -33
  551. package/src/index.js +0 -15
  552. package/src/locus-info/controlsUtils.js +0 -102
  553. package/src/media/index.js +0 -459
  554. package/src/media/internal-media-core-wrapper.ts +0 -9
  555. package/src/mediaQualityMetrics/config.js +0 -382
  556. package/src/meeting/effectsState.js +0 -205
  557. package/src/meeting/index.js +0 -6284
  558. package/src/meeting/muteState.js +0 -318
  559. package/src/meeting/util.js +0 -506
  560. package/src/meeting-info/index.js +0 -131
  561. package/src/meeting-info/meeting-info-v2.js +0 -255
  562. package/src/meetings/index.js +0 -1015
  563. package/src/member/util.js +0 -254
  564. package/src/members/request.js +0 -131
  565. package/src/members/util.js +0 -258
  566. package/src/metrics/config.js +0 -324
  567. package/src/metrics/index.js +0 -530
  568. package/src/multistream/multistreamMedia.ts +0 -92
  569. package/src/peer-connection-manager/util.ts +0 -117
  570. package/src/roap/request.js +0 -127
  571. package/src/statsAnalyzer/global.js +0 -133
  572. package/src/statsAnalyzer/index.js +0 -1006
  573. package/src/statsAnalyzer/mqaUtil.js +0 -173
  574. package/test/unit/spec/meeting/effectsState.js +0 -291
  575. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  576. /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
@@ -5,10 +5,11 @@ import {assert} from '@webex/test-helper-chai';
5
5
  import {skipInNode} from '@webex/test-helper-mocha';
6
6
  import sinon from 'sinon';
7
7
 
8
- import BrowserDetection from '@webex/plugin-meetings/src/common/browser-detection';
8
+ import BrowserDetection from '@webex/plugin-meetings/dist/common/browser-detection';
9
+ import {createCameraTrack, createDisplayTrack, createMicrophoneTrack, LocalTrackEvents} from '@webex/plugin-meetings';
9
10
 
10
- import DEFAULT_RESOLUTIONS from '../../../src/config';
11
11
  import testUtils from '../../utils/testUtils';
12
+ import integrationTestUtils from '../../utils/integrationTestUtils';
12
13
 
13
14
  require('dotenv').config();
14
15
 
@@ -18,31 +19,73 @@ const {isBrowser} = BrowserDetection();
18
19
 
19
20
  let userSet, alice, bob, chris, enumerateSpy, channelUrlA, channelUrlB;
20
21
 
22
+ const localTracks = {
23
+ alice: {
24
+ microphone: undefined,
25
+ camera: undefined,
26
+ screenShare: {
27
+ video: undefined,
28
+ }
29
+ },
30
+ bob: {
31
+ microphone: undefined,
32
+ camera: undefined,
33
+ screenShare: {
34
+ video: undefined,
35
+ }
36
+ },
37
+ chris: {
38
+ microphone: undefined,
39
+ camera: undefined,
40
+ screenShare: {
41
+ video: undefined,
42
+ }
43
+ },
44
+ };
45
+
46
+
47
+ const waitForPublished = (track, expectedPublished, description) => {
48
+ return testUtils.waitForEvents([{
49
+ scope: track,
50
+ event: LocalTrackEvents.PublishedStateUpdate,
51
+ match: ({isPublished}) => {
52
+ console.log(`${description} is now ${isPublished ? 'published': 'not published'}`);
53
+ return (isPublished === expectedPublished);
54
+ }
55
+ }]);
56
+ };
57
+
21
58
  skipInNode(describe)('plugin-meetings', () => {
22
59
  describe('journey', () => {
23
- before(() => webexTestUsers.generateTestUsers({
24
- count: 3,
25
- whistler: process.env.WHISTLER || process.env.JENKINS
26
- })
27
- .then((users) => {
28
- userSet = users;
29
- alice = userSet[0];
30
- bob = userSet[1];
31
- chris = userSet[2];
32
- alice.name = 'alice';
33
- bob.name = 'bob';
34
- chris.name = 'chris';
35
- alice.webex.meetings.name = 'alice';
36
- bob.webex.meetings.name = 'bob';
37
- chris.webex.meetings.name = 'chris';
38
- channelUrlA = 'https://board-a.wbx2.com/board/api/v1/channels/49cfb550-5517-11eb-a2af-1b9e4bc3da13';
39
- channelUrlB = 'https://board-a.wbx2.com/board/api/v1/channels/977a7330-54f4-11eb-b1ef-91f5eefc7bf3';
40
- })
41
- .then(() => Promise.all([testUtils.syncAndEndMeeting(alice),
42
- testUtils.syncAndEndMeeting(bob)]))
43
- .catch((error) => {
44
- throw error;
45
- }));
60
+ before(() =>
61
+ webexTestUsers
62
+ .generateTestUsers({
63
+ count: 3,
64
+ whistler: process.env.WHISTLER || process.env.JENKINS,
65
+ })
66
+ .then((users) => {
67
+ userSet = users;
68
+ alice = userSet[0];
69
+ bob = userSet[1];
70
+ chris = userSet[2];
71
+ alice.name = 'alice';
72
+ bob.name = 'bob';
73
+ chris.name = 'chris';
74
+ alice.webex.meetings.name = 'alice';
75
+ bob.webex.meetings.name = 'bob';
76
+ chris.webex.meetings.name = 'chris';
77
+ channelUrlA =
78
+ 'https://board-a.wbx2.com/board/api/v1/channels/49cfb550-5517-11eb-a2af-1b9e4bc3da13';
79
+ channelUrlB =
80
+ 'https://board-a.wbx2.com/board/api/v1/channels/977a7330-54f4-11eb-b1ef-91f5eefc7bf3';
81
+ })
82
+ .then(() =>
83
+ Promise.all([testUtils.syncAndEndMeeting(alice), testUtils.syncAndEndMeeting(bob)])
84
+ )
85
+ .catch((error) => {
86
+ throw error;
87
+ })
88
+ );
46
89
 
47
90
  before(() => {
48
91
  enumerateSpy = sinon.spy(navigator.mediaDevices, 'enumerateDevices');
@@ -68,40 +111,51 @@ skipInNode(describe)('plugin-meetings', () => {
68
111
  bob.meeting = null;
69
112
  });
70
113
 
71
- it('Alice Ends a outgoing meeting', () => Promise.all([
72
- testUtils.delayedPromise(alice.webex.meetings.create(bob.emailAddress)),
73
- testUtils.waitForEvents([{scope: alice.webex.meetings, event: 'meeting:added', user: alice}])
74
- ])
75
- .then(() => Promise.all([
76
- testUtils.delayedPromise(alice.meeting.join()),
77
- testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:added', user: bob}])
78
- ]))
79
- .then(() => {
80
- // bob and alice have meeting object
81
- bob.meeting.acknowledge('INCOMING');
82
- assert.equal(bob.meeting.sipUri, alice.emailAddress);
83
- assert.equal(alice.meeting.sipUri, bob.emailAddress);
84
- assert.equal(bob.meeting.state, 'IDLE');
85
- assert.equal(alice.meeting.state, 'JOINED');
86
- })
87
- .then(function aliceLeavesMeetingAndBobGetsMeetingRemoved() {
88
- return Promise.all([
89
- testUtils.delayedPromise(alice.meeting.leave()),
90
- testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:removed', user: bob}])
91
- ]);
92
- })
93
- .then(() => testUtils.waitForStateChange(alice.meeting, 'LEFT'))
94
- .then(() => Promise.all([
95
- testUtils.waitForCallEnded(alice, bob.emailAddress),
96
- testUtils.waitForCallEnded(bob, alice.emailAddress)
97
- ]))
98
- .then(() => {
99
- assert.equal(alice.webex.meetings.getMeetingByType('sipUri', bob.emailAddress), null);
100
- assert.equal(bob.webex.meetings.getMeetingByType('sipUri', alice.emailAddress), null);
101
- })
102
- .catch((err) => {
103
- throw err;
104
- }));
114
+ it('Alice Ends a outgoing meeting', () =>
115
+ Promise.all([
116
+ testUtils.delayedPromise(alice.webex.meetings.create(bob.emailAddress)),
117
+ testUtils.waitForEvents([
118
+ {scope: alice.webex.meetings, event: 'meeting:added', user: alice},
119
+ ]),
120
+ ])
121
+ .then(() =>
122
+ Promise.all([
123
+ testUtils.delayedPromise(alice.meeting.join()),
124
+ testUtils.waitForEvents([
125
+ {scope: bob.webex.meetings, event: 'meeting:added', user: bob},
126
+ ]),
127
+ ])
128
+ )
129
+ .then(() => {
130
+ // bob and alice have meeting object
131
+ bob.meeting.acknowledge('INCOMING');
132
+ assert.equal(bob.meeting.sipUri, alice.emailAddress);
133
+ assert.equal(alice.meeting.sipUri, bob.emailAddress);
134
+ assert.equal(bob.meeting.state, 'IDLE');
135
+ assert.equal(alice.meeting.state, 'JOINED');
136
+ })
137
+ .then(function aliceLeavesMeetingAndBobGetsMeetingRemoved() {
138
+ return Promise.all([
139
+ testUtils.delayedPromise(alice.meeting.leave()),
140
+ testUtils.waitForEvents([
141
+ {scope: bob.webex.meetings, event: 'meeting:removed', user: bob},
142
+ ]),
143
+ ]);
144
+ })
145
+ .then(() => testUtils.waitForStateChange(alice.meeting, 'LEFT'))
146
+ .then(() =>
147
+ Promise.all([
148
+ testUtils.waitForCallEnded(alice, bob.emailAddress),
149
+ testUtils.waitForCallEnded(bob, alice.emailAddress),
150
+ ])
151
+ )
152
+ .then(() => {
153
+ assert.equal(alice.webex.meetings.getMeetingByType('sipUri', bob.emailAddress), null);
154
+ assert.equal(bob.webex.meetings.getMeetingByType('sipUri', alice.emailAddress), null);
155
+ })
156
+ .catch((err) => {
157
+ throw err;
158
+ }));
105
159
  });
106
160
 
107
161
  // The event was coming but incomplete
@@ -109,62 +163,77 @@ skipInNode(describe)('plugin-meetings', () => {
109
163
 
110
164
  // Alice calls bob and bob rejects it
111
165
  xdescribe('reject Incoming Call', () => {
112
- it('alice dials bob and bob receives meeting added', () => Promise.all([
113
- testUtils.delayedPromise(alice.webex.meetings.create(bob.emailAddress)),
114
- testUtils.waitForEvents([{scope: alice.webex.meetings, event: 'meeting:added', user: alice}])
115
- ])
116
- .then(() => Promise.all([
117
- testUtils.delayedPromise(alice.meeting.join()),
118
- testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:added', user: bob}])
119
- ]))
120
- .then(function alicebobJoined() {
121
- assert.exists(bob.meeting);
122
- assert.exists(alice.meeting);
123
- assert.equal(bob.meeting.sipUri, alice.emailAddress);
124
- assert.equal(alice.meeting.sipUri, bob.emailAddress);
125
- assert.exists(bob.meeting.partner);
126
- assert.exists(alice.meeting.partner);
127
- })
128
- .then(function bobState() {
129
- testUtils.waitForStateChange(bob.meeting, 'IDLE');
130
- })
131
- .then(function aliceState() {
132
- testUtils.waitForStateChange(alice.meeting, 'JOINED');
133
- })
134
- .then(function bobDeclinedCall() {
135
- return bob.meeting.acknowledge('INCOMING')
136
- .then(() => bob.meeting.decline('BUSY'))
137
- .then(() => testUtils.waitForStateChange(bob.meeting, 'DECLINED'))
138
- .catch((e) => {
139
- console.error('Bob decline call not successful', e);
140
- throw e;
141
- });
142
- })
143
- .then(function aliceLeaveMeeting() {
144
- assert.equal(alice.meeting.state, 'JOINED');
145
-
146
- return alice.meeting.leave()
147
- .then(() => testUtils.waitForStateChange(alice.meeting, 'LEFT'))
148
- .then(() => testUtils.waitForStateChange(bob.meeting, 'DECLINED'))
149
- .catch((e) => {
150
- console.error('alice was not able to leave the meeting', e);
151
- throw e;
152
- });
153
- })
154
- .then(function WaitForMeetingEnd() {
155
- return Promise.all([
156
- testUtils.waitForCallEnded(alice, bob.emailAddress),
157
- testUtils.waitForCallEnded(bob, alice.emailAddress)
158
- ])
159
- .then(() => {
160
- assert.equal(alice.webex.meetings.getMeetingByType('sipUri', bob.emailAddress), null);
161
- assert.equal(bob.webex.meetings.getMeetingByType('sipUri', alice.emailAddress), null);
162
- })
163
- .catch((e) => {
164
- console.error('Alice bob meeting is deleted', e);
165
- throw e;
166
- });
167
- }));
166
+ it('alice dials bob and bob receives meeting added', () =>
167
+ Promise.all([
168
+ testUtils.delayedPromise(alice.webex.meetings.create(bob.emailAddress)),
169
+ testUtils.waitForEvents([
170
+ {scope: alice.webex.meetings, event: 'meeting:added', user: alice},
171
+ ]),
172
+ ])
173
+ .then(() =>
174
+ Promise.all([
175
+ testUtils.delayedPromise(alice.meeting.join()),
176
+ testUtils.waitForEvents([
177
+ {scope: bob.webex.meetings, event: 'meeting:added', user: bob},
178
+ ]),
179
+ ])
180
+ )
181
+ .then(function alicebobJoined() {
182
+ assert.exists(bob.meeting);
183
+ assert.exists(alice.meeting);
184
+ assert.equal(bob.meeting.sipUri, alice.emailAddress);
185
+ assert.equal(alice.meeting.sipUri, bob.emailAddress);
186
+ assert.exists(bob.meeting.partner);
187
+ assert.exists(alice.meeting.partner);
188
+ })
189
+ .then(function bobState() {
190
+ testUtils.waitForStateChange(bob.meeting, 'IDLE');
191
+ })
192
+ .then(function aliceState() {
193
+ testUtils.waitForStateChange(alice.meeting, 'JOINED');
194
+ })
195
+ .then(function bobDeclinedCall() {
196
+ return bob.meeting
197
+ .acknowledge('INCOMING')
198
+ .then(() => bob.meeting.decline('BUSY'))
199
+ .then(() => testUtils.waitForStateChange(bob.meeting, 'DECLINED'))
200
+ .catch((e) => {
201
+ console.error('Bob decline call not successful', e);
202
+ throw e;
203
+ });
204
+ })
205
+ .then(function aliceLeaveMeeting() {
206
+ assert.equal(alice.meeting.state, 'JOINED');
207
+
208
+ return alice.meeting
209
+ .leave()
210
+ .then(() => testUtils.waitForStateChange(alice.meeting, 'LEFT'))
211
+ .then(() => testUtils.waitForStateChange(bob.meeting, 'DECLINED'))
212
+ .catch((e) => {
213
+ console.error('alice was not able to leave the meeting', e);
214
+ throw e;
215
+ });
216
+ })
217
+ .then(function WaitForMeetingEnd() {
218
+ return Promise.all([
219
+ testUtils.waitForCallEnded(alice, bob.emailAddress),
220
+ testUtils.waitForCallEnded(bob, alice.emailAddress),
221
+ ])
222
+ .then(() => {
223
+ assert.equal(
224
+ alice.webex.meetings.getMeetingByType('sipUri', bob.emailAddress),
225
+ null
226
+ );
227
+ assert.equal(
228
+ bob.webex.meetings.getMeetingByType('sipUri', alice.emailAddress),
229
+ null
230
+ );
231
+ })
232
+ .catch((e) => {
233
+ console.error('Alice bob meeting is deleted', e);
234
+ throw e;
235
+ });
236
+ }));
168
237
  });
169
238
 
170
239
  // Enabled when config.enableUnifiedMeetings = true
@@ -174,30 +243,42 @@ skipInNode(describe)('plugin-meetings', () => {
174
243
  assert.equal(Object.keys(bob.webex.meetings.getAllMeetings()), 0);
175
244
  assert.equal(Object.keys(chris.webex.meetings.getAllMeetings()), 0);
176
245
 
177
- const conversation = await chris.webex.internal.conversation.create({participants: [bob]});
246
+ const conversation = await chris.webex.internal.conversation.create({
247
+ participants: [bob],
248
+ });
178
249
 
179
- await chris.webex.internal.conversation.post(conversation, {displayName: 'hello world how are you '});
250
+ await chris.webex.internal.conversation.post(conversation, {
251
+ displayName: 'hello world how are you ',
252
+ });
180
253
 
181
254
  await Promise.all([
182
- testUtils.delayedPromise(chris.webex.meetings.create(conversation.url, 'CONVERSATION_URL')),
183
- testUtils.waitForEvents([{scope: chris.webex.meetings, event: 'meeting:added', user: chris}])
184
- ])
185
- .then(function chrisJoinsMeeting() {
186
- return Promise.all([
187
- testUtils.delayedPromise(chris.meeting.join()),
188
- testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
189
- {scope: chris.meeting, event: 'meeting:stateChange', user: chris}])
190
- .then((response) => {
191
- assert.equal(response[0].result.payload.currentState, 'ACTIVE');
192
- })
193
- ]);
194
- });
255
+ testUtils.delayedPromise(
256
+ chris.webex.meetings.create(conversation.url, 'CONVERSATION_URL')
257
+ ),
258
+ testUtils.waitForEvents([
259
+ {scope: chris.webex.meetings, event: 'meeting:added', user: chris},
260
+ ]),
261
+ ]).then(function chrisJoinsMeeting() {
262
+ return Promise.all([
263
+ testUtils.delayedPromise(chris.meeting.join()),
264
+ testUtils
265
+ .waitForEvents([
266
+ {scope: bob.webex.meetings, event: 'meeting:added', user: bob},
267
+ {scope: chris.meeting, event: 'meeting:stateChange', user: chris},
268
+ ])
269
+ .then((response) => {
270
+ assert.equal(response[0].result.payload.currentState, 'ACTIVE');
271
+ }),
272
+ ]);
273
+ });
195
274
  });
196
275
 
197
276
  it('Fetch meeting information with invalid conversation URL and throws error', () => {
198
- chris.webex.meetings.meetingInfo.fetchMeetingInfo('http://some-invalid.com', 'CONVERSATION_URL').then((response) => {
199
- assert(response.result === '404');
200
- });
277
+ chris.webex.meetings.meetingInfo
278
+ .fetchMeetingInfo('http://some-invalid.com', 'CONVERSATION_URL')
279
+ .then((response) => {
280
+ assert(response.result === '404');
281
+ });
201
282
  });
202
283
  });
203
284
  });
@@ -207,7 +288,11 @@ skipInNode(describe)('plugin-meetings', () => {
207
288
  // Workaround since getDisplayMedia requires a user gesture to be activated, and this is a integration tests
208
289
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1580944
209
290
  if (isBrowser('firefox') || isBrowser('safari')) {
210
- sinon.replace(navigator.mediaDevices, 'getDisplayMedia', navigator.mediaDevices.getUserMedia);
291
+ sinon.replace(
292
+ navigator.mediaDevices,
293
+ 'getDisplayMedia',
294
+ navigator.mediaDevices.getUserMedia
295
+ );
211
296
  }
212
297
 
213
298
  this.timeout(80000);
@@ -217,76 +302,110 @@ skipInNode(describe)('plugin-meetings', () => {
217
302
  assert.equal(Object.keys(bob.webex.meetings.getAllMeetings()), 0);
218
303
  assert.equal(Object.keys(alice.webex.meetings.getAllMeetings()), 0);
219
304
 
220
- return alice.webex.internal.conversation.create({participants: [bob]})
221
- .then((conversation) => alice.webex.internal.conversation.post(conversation, {displayName: 'hello world how are you '}));
305
+ return alice.webex.internal.conversation
306
+ .create({participants: [bob]})
307
+ .then((conversation) =>
308
+ alice.webex.internal.conversation.post(conversation, {
309
+ displayName: 'hello world how are you ',
310
+ })
311
+ );
222
312
  });
223
313
 
224
- it('alice dials bob and adds media', () => Promise.all([
225
- testUtils.delayedPromise(alice.webex.meetings.create(bob.emailAddress)),
226
- testUtils.waitForEvents([{scope: alice.webex.meetings, event: 'meeting:added', user: alice}])
227
- ])
228
- .then(function aliceJoinsMeeting() {
229
- return Promise.all([
230
- testUtils.delayedPromise(alice.meeting.join()),
231
- testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
232
- {scope: alice.meeting, event: 'meeting:stateChange', user: alice}])
233
- .then((response) => {
234
- assert.equal(response[0].result.payload.currentState, 'ACTIVE');
235
- })
236
- ]);
237
- })
238
- .then(() => {
239
- assert.equal(bob.meeting.partner.state, 'JOINED');
240
- // Wait for openH264 to finsish downloading and peerConnection to be stable
241
- testUtils.waitUntil(4000);
242
- })
243
- .then(() => Promise.all([
244
- testUtils.addMedia(alice),
314
+ it('alice creates local microphone and camera tracks', async () => {
315
+ localTracks.alice.microphone = await createMicrophoneTrack();
316
+ localTracks.alice.camera = await createCameraTrack();
317
+ });
318
+
319
+ it('alice dials bob and adds media', () =>
320
+ Promise.all([
321
+ testUtils.delayedPromise(alice.webex.meetings.create(bob.emailAddress)),
245
322
  testUtils.waitForEvents([
246
- {scope: alice.meeting, event: 'meeting:media:local:start', user: alice}
247
- ])
248
- ]))
249
- .then(() => assert(enumerateSpy.called)));
323
+ {scope: alice.webex.meetings, event: 'meeting:added', user: alice},
324
+ ]),
325
+ ])
326
+ .then(function aliceJoinsMeeting() {
327
+ return Promise.all([
328
+ testUtils.delayedPromise(alice.meeting.join()),
329
+ testUtils
330
+ .waitForEvents([
331
+ {scope: bob.webex.meetings, event: 'meeting:added', user: bob},
332
+ {scope: alice.meeting, event: 'meeting:stateChange', user: alice},
333
+ ])
334
+ .then((response) => {
335
+ assert.equal(response[0].result.payload.currentState, 'ACTIVE');
336
+ }),
337
+ ]);
338
+ })
339
+ .then(() => {
340
+ assert.equal(bob.meeting.partner.state, 'JOINED');
341
+ // Wait for openH264 to finsish downloading and peerConnection to be stable
342
+ testUtils.waitUntil(4000);
343
+ })
344
+ .then(() =>
345
+ Promise.all([
346
+ integrationTestUtils.addMedia(alice, {microphone: localTracks.alice.microphone, camera: localTracks.alice.camera}),
347
+ testUtils.waitForEvents([
348
+ {scope: alice.meeting, event: 'meeting:media:local:start', user: alice},
349
+ ]),
350
+ ])
351
+ )
352
+ .then(() => assert(enumerateSpy.called)));
250
353
 
251
354
  it('bob joins the meeting', () => {
252
- const checkBobIsInMeeting = (event) => !!event.delta.updated.find((member) => bob.meeting.members.selfId === member.id && member.status === 'IN_MEETING');
355
+ const checkBobIsInMeeting = (event) =>
356
+ !!event.delta.updated.find(
357
+ (member) => bob.meeting.members.selfId === member.id && member.status === 'IN_MEETING'
358
+ );
253
359
 
254
360
  return Promise.all([
255
361
  bob.meeting.acknowledge('INCOMING').then(() => bob.meeting.join()),
256
- testUtils.waitForEvents([{
257
- scope: alice.meeting.members, event: 'members:update', user: alice, match: checkBobIsInMeeting
258
- }])
362
+ testUtils.waitForEvents([
363
+ {
364
+ scope: alice.meeting.members,
365
+ event: 'members:update',
366
+ user: alice,
367
+ match: checkBobIsInMeeting,
368
+ },
369
+ ]),
259
370
  ]);
260
371
  });
261
372
 
262
- it('bob adds media to the meeting', () => Promise.all([
263
- testUtils.addMedia(bob),
264
- testUtils.waitForEvents([
265
- {scope: bob.meeting, event: 'meeting:media:local:start', user: bob},
266
- {scope: alice.meeting, event: 'meeting:media:remote:start', user: alice}
267
- ]).catch((e) => {
268
- console.error('Error on remote and local start event', e);
269
- throw e;
270
- })
271
- ])
272
- .then(() => {
273
- assert.equal(bob.meeting.sipUri, alice.id);
274
- assert.equal(alice.meeting.sipUri, bob.id);
275
- assert.exists(alice.meeting.members.locusUrl);
276
- assert.equal(alice.meeting.type, 'CALL');
277
- assert.equal(bob.meeting.type, 'CALL');
278
- assert(enumerateSpy.called);
279
- })
280
- .then(function bobState() {
281
- testUtils.waitForStateChange(bob.meeting, 'JOINED');
282
- })
283
- .then(function aliceState() {
284
- testUtils.waitForStateChange(alice.meeting, 'JOINED');
285
- })
286
- .catch((e) => {
287
- console.error('Error bob joins the meeting ', e);
288
- throw e;
289
- }));
373
+ it('bob creates local microphone and camera tracks', async () => {
374
+ localTracks.bob.microphone = await createMicrophoneTrack();
375
+ localTracks.bob.camera = await createCameraTrack();
376
+ });
377
+
378
+ it('bob adds media to the meeting', () =>
379
+ Promise.all([
380
+ integrationTestUtils.addMedia(bob, {microphone: localTracks.bob.microphone, camera: localTracks.bob.camera}),
381
+ testUtils
382
+ .waitForEvents([
383
+ {scope: bob.meeting, event: 'meeting:media:local:start', user: bob},
384
+ {scope: alice.meeting, event: 'meeting:media:remote:start', user: alice},
385
+ ])
386
+ .catch((e) => {
387
+ console.error('Error on remote and local start event', e);
388
+ throw e;
389
+ }),
390
+ ])
391
+ .then(() => {
392
+ assert.equal(bob.meeting.sipUri, alice.id);
393
+ assert.equal(alice.meeting.sipUri, bob.id);
394
+ assert.exists(alice.meeting.members.locusUrl);
395
+ assert.equal(alice.meeting.type, 'CALL');
396
+ assert.equal(bob.meeting.type, 'CALL');
397
+ assert(enumerateSpy.called);
398
+ })
399
+ .then(function bobState() {
400
+ testUtils.waitForStateChange(bob.meeting, 'JOINED');
401
+ })
402
+ .then(function aliceState() {
403
+ testUtils.waitForStateChange(alice.meeting, 'JOINED');
404
+ })
405
+ .catch((e) => {
406
+ console.error('Error bob joins the meeting ', e);
407
+ throw e;
408
+ }));
290
409
 
291
410
  it('check for meeting properties', () => {
292
411
  assert.exists(alice.meeting.userId, 'userId not present');
@@ -300,413 +419,540 @@ skipInNode(describe)('plugin-meetings', () => {
300
419
  assert.exists(alice.meeting.members.selfId, 'selfId not present');
301
420
  });
302
421
 
303
- it('alice Audio Mute ', () => {
304
- const checkEvent = (event) => !!event.delta.updated.find((member) => alice.meeting.members.selfId === member.id && member.isAudioMuted === true);
422
+ it('alice Audio Mute ', async () => {
423
+ const checkEvent = (event) =>
424
+ !!event.delta.updated.find(
425
+ (member) => alice.meeting.members.selfId === member.id && member.isAudioMuted === true
426
+ );
305
427
 
428
+ await testUtils.waitUntil(2000);
306
429
 
307
- return Promise.all([
308
- testUtils.delayedPromise(alice.meeting.muteAudio()),
309
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update', match: checkEvent}])
310
- ])
311
- .then(() => {
312
- assert.equal(alice.meeting.audio.muted, true);
313
- assert.equal(alice.meeting.isAudioMuted(), true);
314
- });
430
+ const membersUpdate = testUtils.waitForEvents([
431
+ {scope: bob.meeting.members, event: 'members:update', match: checkEvent},
432
+ ]);
433
+
434
+ localTracks.alice.microphone.setMuted(true);
435
+
436
+ await membersUpdate;
437
+
438
+ assert.equal(localTracks.alice.microphone.muted, true);
315
439
  });
316
440
 
317
- it('alice Audio unMute ', () => {
318
- const checkEvent = (event) => !!event.delta.updated.find((member) => alice.meeting.members.selfId === member.id && member.isAudioMuted === false);
441
+ it('alice Audio unMute ', async () => {
442
+ const checkEvent = (event) =>
443
+ !!event.delta.updated.find(
444
+ (member) => alice.meeting.members.selfId === member.id && member.isAudioMuted === false
445
+ );
319
446
 
320
- return Promise.all([
321
- testUtils.delayedPromise(alice.meeting.unmuteAudio()),
322
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update', match: checkEvent}])
323
- ])
324
- .then(() => {
325
- assert.equal(alice.meeting.audio.muted, false);
326
- assert.equal(alice.meeting.isAudioMuted(), false);
327
- });
447
+ await testUtils.waitUntil(2000);
448
+
449
+ const membersUpdate = testUtils.waitForEvents([
450
+ {scope: bob.meeting.members, event: 'members:update', match: checkEvent},
451
+ ]);
452
+
453
+ localTracks.alice.microphone.setMuted(false);
454
+
455
+ await membersUpdate;
456
+
457
+ assert.equal(localTracks.alice.microphone.muted, false);
328
458
  });
329
459
 
330
- it('alice Video Mute', () => {
331
- const checkEvent = (event) => !!event.delta.updated.find((member) => alice.meeting.members.selfId === member.id && member.isVideoMuted === true);
460
+ it('alice video mute', async () => {
461
+ const checkEvent = (event) =>
462
+ !!event.delta.updated.find(
463
+ (member) => alice.meeting.members.selfId === member.id && member.isVideoMuted === true
464
+ );
332
465
 
333
- return Promise.all([
334
- testUtils.delayedPromise(alice.meeting.muteVideo()),
335
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update', match: checkEvent}])
336
- ])
337
- .then(() => {
338
- assert.equal(alice.meeting.video.muted, true);
339
- assert.equal(alice.meeting.isVideoMuted(), true);
340
- });
466
+ await testUtils.waitUntil(2000);
467
+
468
+ const membersUpdate = testUtils.waitForEvents([
469
+ {scope: bob.meeting.members, event: 'members:update', match: checkEvent},
470
+ ]);
471
+
472
+ localTracks.alice.camera.setMuted(true);
473
+
474
+ await membersUpdate;
475
+
476
+ assert.equal(localTracks.alice.camera.muted, true);
341
477
  });
342
478
 
343
- it('alice video unMute', () => {
344
- const checkEvent = (event) => !!event.delta.updated.find((member) => alice.meeting.members.selfId === member.id && member.isVideoMuted === false);
479
+ it('alice video unmute', async () => {
480
+ const checkEvent = (event) =>
481
+ !!event.delta.updated.find(
482
+ (member) => alice.meeting.members.selfId === member.id && member.isVideoMuted === false
483
+ );
345
484
 
346
- return Promise.all([
347
- testUtils.delayedPromise(alice.meeting.unmuteVideo()),
348
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update', match: checkEvent}])
349
- ])
350
- .then(() => {
351
- assert.equal(alice.meeting.video.muted, false);
352
- assert.equal(alice.meeting.isVideoMuted(), false);
353
- });
485
+ await testUtils.waitUntil(2000);
486
+
487
+ const membersUpdate = testUtils.waitForEvents([
488
+ {scope: bob.meeting.members, event: 'members:update', match: checkEvent},
489
+ ]);
490
+
491
+ localTracks.alice.camera.setMuted(false);
492
+
493
+ await membersUpdate;
494
+
495
+ assert.equal(localTracks.alice.camera.muted, false);
354
496
  });
355
497
 
356
- it('alice update Audio', () => {
498
+ it('alice update Audio', async () => {
357
499
  const oldVideoTrackId = alice.meeting.mediaProperties.videoTrack.id;
358
500
 
359
- return alice.meeting.getMediaStreams({sendAudio: true})
360
- .then((response) => Promise.all([
361
- testUtils.delayedPromise(alice.meeting.updateAudio({
362
- sendAudio: true,
363
- receiveAudio: true,
364
- stream: response[0]
365
- })
501
+ const oldMicrophoneTrack = localTracks.alice.microphone;
502
+ const newMicrophoneTrack = await createMicrophoneTrack();
503
+
504
+ assert.equal(oldMicrophoneTrack.published, true);
505
+ assert.notEqual(oldMicrophoneTrack.id, newMicrophoneTrack.id);
506
+
507
+ const oldTrackUnpublished = waitForPublished(oldMicrophoneTrack, false, "Alice AUDIO: old microphone track");
508
+ const newTrackPublished = waitForPublished(newMicrophoneTrack, true, "Alice AUDIO: new microphone track");
509
+
510
+ await testUtils.delayedPromise(
511
+ alice.meeting
512
+ .publishTracks({
513
+ microphone: newMicrophoneTrack,
514
+ })
366
515
  .then(() => {
367
- console.log('AUDIO ', alice.meeting.mediaProperties.audioTrack);
368
- assert.equal(alice.meeting.mediaProperties.audioTrack.id, response[0].getAudioTracks()[0].id);
516
+ console.log('Alice AUDIO: new track on meeting object:', alice.meeting.mediaProperties.audioTrack);
517
+ assert.equal(
518
+ alice.meeting.mediaProperties.audioTrack.id,
519
+ newMicrophoneTrack.id
520
+ );
369
521
  assert.equal(alice.meeting.mediaProperties.videoTrack.id, oldVideoTrackId);
370
- })),
371
- testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
372
- .then((response) => {
373
- console.log('MEDIA:READY event ', response[0].result);
374
- assert.equal(response[0].result.type === 'local', true);
375
522
  })
376
- ]));
523
+ );
524
+
525
+ await oldTrackUnpublished;
526
+ await newTrackPublished;
527
+
528
+ localTracks.alice.microphone = newMicrophoneTrack;
377
529
  });
378
530
 
379
- it('alice update video', () => {
531
+ it('alice update video', async () => {
380
532
  const oldAudioTrackId = alice.meeting.mediaProperties.audioTrack.id;
381
533
 
382
- return alice.meeting.getMediaStreams({sendVideo: true})
383
- .then((response) => Promise.all([
384
- testUtils.delayedPromise(alice.meeting.updateVideo({
385
- sendVideo: true,
386
- receiveVideo: true,
387
- stream: response[0]
388
- })
534
+ const oldCameraTrack = localTracks.alice.camera;
535
+ const newCameraTrack = await createCameraTrack();
536
+
537
+ assert.equal(oldCameraTrack.published, true);
538
+ assert.notEqual(oldCameraTrack.id, newCameraTrack.id);
539
+
540
+ const oldTrackUnpublished = waitForPublished(oldCameraTrack, false, "Alice VIDEO: old camera track");
541
+ const newTrackPublished = waitForPublished(newCameraTrack, true, "Alice VIDEO: new camera track");
542
+
543
+ await testUtils.delayedPromise(
544
+ alice.meeting
545
+ .publishTracks({
546
+ camera: newCameraTrack,
547
+ })
389
548
  .then(() => {
390
- assert.equal(alice.meeting.mediaProperties.videoTrack.id, response[0].getVideoTracks()[0].id);
549
+ console.log('Alice VIDEO: new track on meeting:', alice.meeting.mediaProperties.videoTrack);
550
+ assert.equal(
551
+ alice.meeting.mediaProperties.videoTrack.id,
552
+ newCameraTrack.id
553
+ );
391
554
  assert.equal(alice.meeting.mediaProperties.audioTrack.id, oldAudioTrackId);
392
- })),
393
- testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
394
- .then((response) => {
395
- console.log('MEDIA:READY event ', response[0].result);
396
- assert.equal(response[0].result.type === 'local', true);
397
555
  })
398
- ]));
399
- });
556
+ );
400
557
 
401
- it('alice mutes bob', () => Promise.all([
402
- testUtils.delayedPromise(alice.meeting.mute(bob.meeting.members.selfId, true)),
403
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:self:mutedByOthers'}])
404
- .then((response) => {
405
- console.log('meeting:self:mutedByOthers event ', response[0].result);
406
- assert.equal(response[0].result.payload.unmuteAllowed, true);
407
- })
408
- ]));
558
+ await oldTrackUnpublished;
559
+ await newTrackPublished;
409
560
 
410
- it('alice unmutes bob', () => Promise.all([
411
- testUtils.delayedPromise(alice.meeting.mute(bob.meeting.members.selfId, false)),
412
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:self:unmutedByOthers'}])
413
- .then((response) => {
414
- console.log('meeting:self:unmutedByOthers event ', response[0].result);
415
- })
416
- ]));
561
+ localTracks.alice.camera = newCameraTrack;
562
+ });
417
563
 
418
- it('bob audio mute, so alice cannot unmute bob', (done) => {
419
- const checkEvent = (event) => !!event.delta.updated.find((member) => bob.meeting.members.selfId === member.id && member.isAudioMuted === true);
564
+ it('alice mutes bob', () =>
565
+ Promise.all([
566
+ testUtils.delayedPromise(alice.meeting.mute(bob.meeting.members.selfId, true)),
567
+ testUtils
568
+ .waitForEvents([{scope: bob.meeting, event: 'meeting:self:mutedByOthers'}])
569
+ .then((response) => {
570
+ console.log('meeting:self:mutedByOthers event ', response[0].result);
571
+ assert.equal(response[0].result.payload.unmuteAllowed, true);
572
+ }),
573
+ ]));
574
+
575
+ it('alice unmutes bob', () =>
576
+ Promise.all([
577
+ testUtils.delayedPromise(alice.meeting.mute(bob.meeting.members.selfId, false)),
578
+ testUtils
579
+ .waitForEvents([{scope: bob.meeting, event: 'meeting:self:unmutedByOthers'}])
580
+ .then((response) => {
581
+ console.log('meeting:self:unmutedByOthers event ', response[0].result);
582
+ }),
583
+ ]));
584
+
585
+ it('bob audio mute, so alice cannot unmute bob', async () => {
586
+ const checkEvent = (event) =>
587
+ !!event.delta.updated.find(
588
+ (member) => bob.meeting.members.selfId === member.id && member.isAudioMuted === true
589
+ );
590
+
591
+ const membersUpdate = testUtils.waitForEvents([
592
+ {scope: bob.meeting.members, event: 'members:update', match: checkEvent},
593
+ ]);
420
594
 
421
595
  // first bob mutes himself
422
- Promise.all([
423
- testUtils.delayedPromise(bob.meeting.muteAudio()),
424
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update', match: checkEvent}])
425
- ])
426
- .then(() => {
427
- assert.equal(bob.meeting.audio.muted, true);
428
- assert.equal(bob.meeting.isAudioMuted(), true);
429
- })
430
- // now alice tries to unmmut bob
431
- .then(() => testUtils.delayedPromise(alice.meeting.mute(bob.meeting.members.selfId, false)))
596
+ localTracks.bob.microphone.setMuted(true);
597
+
598
+ await membersUpdate;
599
+
600
+ assert.equal(localTracks.bob.microphone.muted, true);
601
+
602
+ // now alice tries to unmmute bob
603
+ await testUtils.delayedPromise(alice.meeting.mute(bob.meeting.members.selfId, false))
432
604
  // expect the waitForEvents to timeout
433
- .then(() => testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:self:unmutedByOthers'}], 2000))
605
+ .then(() =>
606
+ testUtils.waitForEvents(
607
+ [{scope: bob.meeting, event: 'meeting:self:unmutedByOthers'}],
608
+ 2000
609
+ )
610
+ )
434
611
  .then(() => {
435
612
  assert.fail('bob received unexpected meeting:self:unmutedByOthers event');
436
613
  })
437
614
  .catch(() => {
438
- assert.equal(bob.meeting.audio.muted, true);
439
- assert.equal(bob.meeting.isAudioMuted(), true);
440
- done();
615
+ assert.equal(localTracks.bob.microphone.muted, true);
441
616
  });
442
617
  });
443
618
 
444
- it('bob audio unmute ', () => {
445
- const checkEvent = (event) => !!event.delta.updated.find((member) => bob.meeting.members.selfId === member.id && member.isAudioMuted === false);
619
+ it('bob audio unmute ', async () => {
620
+ const checkEvent = (event) =>
621
+ !!event.delta.updated.find(
622
+ (member) => bob.meeting.members.selfId === member.id && member.isAudioMuted === false
623
+ );
446
624
 
447
- return Promise.all([
448
- testUtils.delayedPromise(bob.meeting.unmuteAudio()),
449
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update', match: checkEvent}])
450
- ])
451
- .then(() => {
452
- assert.equal(bob.meeting.audio.muted, false);
453
- assert.equal(bob.meeting.isAudioMuted(), false);
454
- });
625
+ const membersUpdate = testUtils.waitForEvents([
626
+ {scope: alice.meeting.members, event: 'members:update', match: checkEvent},
627
+ ]);
628
+
629
+ localTracks.bob.microphone.setMuted(false);
630
+
631
+ await membersUpdate;
632
+
633
+ assert.equal(localTracks.bob.microphone.muted, false);
455
634
  });
456
635
 
457
- it('alice shares the screen with highFrameRate', () => Promise.all([
458
- testUtils.delayedPromise(alice.meeting.shareScreen({sharePreferences: {highFrameRate: true}})),
459
- testUtils.waitForEvents([
460
- {scope: alice.meeting, event: 'meeting:startedSharingLocal'}
461
- ]),
462
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingRemote'}])
636
+ it('alice shares the screen with highFrameRate', async () => {
637
+ localTracks.alice.screenShare.video = await createDisplayTrack();
638
+
639
+ const startedSharingLocal = testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingLocal'}]);
640
+ const startedSharingRemote = testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingRemote'}])
463
641
  .then((response) => {
464
642
  assert.equal(response[0].result.memberId, alice.meeting.selfId);
465
- }),
466
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
467
- .then((response) => {
468
- console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
469
- }),
470
- testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
643
+ });
644
+ const bobReceivesMembersUpdate = testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
471
645
  .then((response) => {
472
- console.log('MEDIA:READY event ', response[0].result);
473
- assert.equal(response[0].result.type === 'localShare', true);
474
- })
475
- ])
476
- .then(() => {
477
- // TODO: Re-eanable Safari when screensharing issues have been resolved
478
- if (!isBrowser('safari')) {
479
- assert.equal(alice.meeting.mediaProperties.shareTrack.getConstraints().height, 720);
480
- }
481
- assert.equal(alice.meeting.isSharing, true);
482
- assert.equal(alice.meeting.shareStatus, 'local_share_active');
483
- assert.equal(bob.meeting.shareStatus, 'remote_share_active');
484
- console.log('SCREEN SHARE PARTICIPANTS ', JSON.stringify(alice.meeting.locusInfo.participants));
485
-
486
- return testUtils.waitUntil(10000);
487
- }));
646
+ console.log(
647
+ 'SCREEN SHARE RESPONSE ',
648
+ JSON.stringify(response, testUtils.getCircularReplacer())
649
+ );
650
+ });
651
+ const screenShareVideoPublished = waitForPublished(localTracks.alice.screenShare.video, true, "alice's screen share video track");
652
+
653
+ await testUtils.delayedPromise(alice.meeting.publishTracks({screenShare: {video: localTracks.alice.screenShare.video}}));
488
654
 
489
- it('bob steals the screen share from alice', () => Promise.all([
490
- testUtils.delayedPromise(bob.meeting.shareScreen()),
491
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingLocal'}]),
492
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingLocal'}]),
493
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingRemote'}])
655
+ await screenShareVideoPublished;
656
+ await startedSharingLocal;
657
+ await startedSharingRemote;
658
+ await bobReceivesMembersUpdate;
659
+
660
+ assert.equal(alice.meeting.screenShareFloorState, 'floor_request_granted');
661
+ assert.equal(alice.meeting.shareStatus, 'local_share_active');
662
+ assert.equal(bob.meeting.shareStatus, 'remote_share_active');
663
+ console.log(
664
+ 'SCREEN SHARE PARTICIPANTS ',
665
+ JSON.stringify(alice.meeting.locusInfo.participants)
666
+ );
667
+
668
+ await testUtils.waitUntil(10000);
669
+ });
670
+
671
+ it('bob steals the screen share from alice', async () => {
672
+ localTracks.bob.screenShare.video = await createDisplayTrack();
673
+
674
+ const stoppedSharingLocal = testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingLocal'}]);
675
+ const startedSharingLocal = testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingLocal'}]);
676
+ const startedSharingRemote = testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingRemote'}])
494
677
  .then((response) => {
495
678
  assert.equal(response[0].result.memberId, bob.meeting.selfId);
496
- }),
497
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
498
- .then((response) => {
499
- console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
500
- }),
501
- testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
679
+ });
680
+ const aliceReceivesMembersUpdate = testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
502
681
  .then((response) => {
503
- console.log('MEDIA:READY event ', response[0].result);
504
- assert.equal(response[0].result.type === 'localShare', true);
505
- })
506
- ])
507
- .then(() => {
508
- const heightResolution = DEFAULT_RESOLUTIONS.meetings.screenResolution.idealHeight;
509
-
510
- // TODO: Re-eanable Safari when screensharing issues have been resolved
511
- if (!isBrowser('safari')) {
512
- assert.equal(bob.meeting.mediaProperties.shareTrack.getConstraints().height, heightResolution);
513
- }
514
- assert.equal(bob.meeting.isSharing, true);
515
- assert.equal(bob.meeting.shareStatus, 'local_share_active');
516
- assert.equal(alice.meeting.shareStatus, 'remote_share_active');
517
-
518
- return testUtils.waitUntil(10000);
519
- }));
682
+ console.log(
683
+ 'SCREEN SHARE RESPONSE ',
684
+ JSON.stringify(response, testUtils.getCircularReplacer())
685
+ );
686
+ });
687
+ const aliceScreenShareVideoUnpublished = waitForPublished(localTracks.alice.screenShare.video, false, "alice's screen share video track");
688
+ const bobScreenShareVideoPublished = waitForPublished(localTracks.bob.screenShare.video, true, "bob's screen share video track");
520
689
 
521
- it('bob stops sharing ', () => Promise.all([
522
- // Wait for peerConnection to stabalize
523
- testUtils.waitUntil(20000),
524
- testUtils.delayedPromise(bob.meeting.updateShare({
525
- sendShare: false,
526
- receiveShare: true
527
- })),
528
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:stoppedSharingLocal'}]),
529
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingRemote'}])
530
- ])
531
- .then(() => {
532
- assert.equal(bob.meeting.isSharing, false);
533
- assert.equal(bob.meeting.shareStatus, 'no_share');
534
- assert.equal(alice.meeting.shareStatus, 'no_share');
535
- }));
690
+ await testUtils.delayedPromise(bob.meeting.publishTracks({screenShare: {video: localTracks.bob.screenShare.video}}));
536
691
 
537
- it('alice shares whiteboard A', () => Promise.all([
538
- testUtils.delayedPromise(alice.meeting.startWhiteboardShare(channelUrlA)),
539
- testUtils.waitForEvents([
540
- {scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}
541
- ]),
542
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}])
543
- .then((response) => {
544
- const {memberId, resourceUrl} = response[0].result;
692
+ await bobScreenShareVideoPublished;
693
+ await aliceScreenShareVideoUnpublished;
694
+ await stoppedSharingLocal;
695
+ await startedSharingLocal;
696
+ await startedSharingRemote;
697
+ await aliceReceivesMembersUpdate;
545
698
 
546
- assert.equal(memberId, alice.meeting.selfId);
547
- assert.equal(resourceUrl, channelUrlA);
548
- }),
549
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
550
- .then((response) => {
551
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
552
- })
553
- ])
554
- .then(() => {
555
- assert.equal(alice.meeting.isSharing, false);
699
+ localTracks.alice.screenShare.video.stop();
700
+ localTracks.alice.screenShare.video = undefined;
701
+
702
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_request_granted');
703
+ assert.equal(bob.meeting.shareStatus, 'local_share_active');
704
+ assert.equal(alice.meeting.shareStatus, 'remote_share_active');
705
+
706
+ await testUtils.waitUntil(10000);
707
+ });
708
+
709
+ it('bob stops sharing', async () => {
710
+ const screenShareVideoUnpublished = waitForPublished(localTracks.bob.screenShare.video, false, "bob's screen share video track");
711
+ const stoppedSharingLocal = testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:stoppedSharingLocal'}]);
712
+ const stoppedSharingRemote = testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingRemote'}]);
713
+
714
+ await testUtils.delayedPromise(bob.meeting.unpublishTracks([localTracks.bob.screenShare.video]));
715
+
716
+ await screenShareVideoUnpublished;
717
+ await stoppedSharingLocal;
718
+ await stoppedSharingRemote;
719
+
720
+ localTracks.bob.screenShare.video.stop();
721
+ localTracks.bob.screenShare.video = undefined;
722
+
723
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
724
+ assert.equal(bob.meeting.shareStatus, 'no_share');
725
+ assert.equal(alice.meeting.shareStatus, 'no_share');
726
+
727
+ await testUtils.waitUntil(10000);
728
+ });
729
+
730
+ it('alice shares whiteboard A', () =>
731
+ Promise.all([
732
+ testUtils.delayedPromise(alice.meeting.startWhiteboardShare(channelUrlA)),
733
+ testUtils.waitForEvents([
734
+ {scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'},
735
+ ]),
736
+ testUtils
737
+ .waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}])
738
+ .then((response) => {
739
+ const {memberId, resourceUrl} = response[0].result;
740
+
741
+ assert.equal(memberId, alice.meeting.selfId);
742
+ assert.equal(resourceUrl, channelUrlA);
743
+ }),
744
+ testUtils
745
+ .waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
746
+ .then((response) => {
747
+ console.log(
748
+ 'WHITEBOARD SHARE RESPONSE ',
749
+ JSON.stringify(response, testUtils.getCircularReplacer())
750
+ );
751
+ }),
752
+ ]).then(() => {
753
+ assert.equal(alice.meeting.screenShareFloorState, 'floor_released');
556
754
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
557
755
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
558
756
  }));
559
757
 
560
- it('bob steals share from alice with whiteboard B', () => Promise.all([
561
- testUtils.delayedPromise(bob.meeting.startWhiteboardShare(channelUrlB)),
562
- testUtils.waitForEvents([
563
- {scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}
564
- ]),
565
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}])
566
- .then((response) => {
567
- const {memberId, resourceUrl} = response[0].result;
568
-
569
- assert.equal(memberId, bob.meeting.selfId);
570
- assert.equal(resourceUrl, channelUrlB);
571
- }),
572
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
573
- .then((response) => {
574
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
575
- })
576
- ])
577
- .then(() => {
578
- assert.equal(bob.meeting.isSharing, false);
758
+ it('bob steals share from alice with whiteboard B', () =>
759
+ Promise.all([
760
+ testUtils.delayedPromise(bob.meeting.startWhiteboardShare(channelUrlB)),
761
+ testUtils.waitForEvents([
762
+ {scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'},
763
+ ]),
764
+ testUtils
765
+ .waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}])
766
+ .then((response) => {
767
+ const {memberId, resourceUrl} = response[0].result;
768
+
769
+ assert.equal(memberId, bob.meeting.selfId);
770
+ assert.equal(resourceUrl, channelUrlB);
771
+ }),
772
+ testUtils
773
+ .waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
774
+ .then((response) => {
775
+ console.log(
776
+ 'WHITEBOARD SHARE RESPONSE ',
777
+ JSON.stringify(response, testUtils.getCircularReplacer())
778
+ );
779
+ }),
780
+ ]).then(() => {
781
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
579
782
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
580
783
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
581
784
  }));
582
785
 
583
- it('bob stops sharing ', () => Promise.all([
584
- // Wait for peerConnection to stabalize
585
- testUtils.waitUntil(20000),
586
- testUtils.delayedPromise(bob.meeting.stopWhiteboardShare(channelUrlB)),
587
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:stoppedSharingWhiteboard'}]),
588
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'}])
589
- ])
590
- .then(() => {
591
- assert.equal(bob.meeting.isSharing, false);
786
+ it('bob stops sharing again', () =>
787
+ Promise.all([
788
+ // Wait for peerConnection to stabalize
789
+ testUtils.waitUntil(20000),
790
+ testUtils.delayedPromise(bob.meeting.stopWhiteboardShare(channelUrlB)),
791
+ testUtils.waitForEvents([
792
+ {scope: bob.meeting, event: 'meeting:stoppedSharingWhiteboard'},
793
+ ]),
794
+ testUtils.waitForEvents([
795
+ {scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'},
796
+ ]),
797
+ ]).then(() => {
798
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
592
799
  assert.equal(bob.meeting.shareStatus, 'no_share');
593
800
  assert.equal(alice.meeting.shareStatus, 'no_share');
594
801
  }));
595
802
 
596
- it('alice shares whiteboard B', () => Promise.all([
597
- testUtils.delayedPromise(alice.meeting.startWhiteboardShare(channelUrlB)),
598
- testUtils.waitForEvents([
599
- {scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}
600
- ]),
601
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}])
602
- .then((response) => {
603
- const {memberId, resourceUrl} = response[0].result;
604
-
605
- assert.equal(memberId, alice.meeting.selfId);
606
- assert.equal(resourceUrl, channelUrlB);
607
- }),
608
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
609
- .then((response) => {
610
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
611
- })
612
- ])
613
- .then(() => {
614
- assert.equal(alice.meeting.isSharing, false);
803
+ it('alice shares whiteboard B', () =>
804
+ Promise.all([
805
+ testUtils.delayedPromise(alice.meeting.startWhiteboardShare(channelUrlB)),
806
+ testUtils.waitForEvents([
807
+ {scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'},
808
+ ]),
809
+ testUtils
810
+ .waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}])
811
+ .then((response) => {
812
+ const {memberId, resourceUrl} = response[0].result;
813
+
814
+ assert.equal(memberId, alice.meeting.selfId);
815
+ assert.equal(resourceUrl, channelUrlB);
816
+ }),
817
+ testUtils
818
+ .waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
819
+ .then((response) => {
820
+ console.log(
821
+ 'WHITEBOARD SHARE RESPONSE ',
822
+ JSON.stringify(response, testUtils.getCircularReplacer())
823
+ );
824
+ }),
825
+ ]).then(() => {
826
+ assert.equal(alice.meeting.screenShareFloorState, 'floor_released');
615
827
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
616
828
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
617
829
  }));
618
830
 
619
- it('bob steals the share from alice with desktop share', () => Promise.all([
620
- testUtils.delayedPromise(bob.meeting.shareScreen()),
621
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'}]),
622
- testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingLocal'}]),
623
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingRemote'}])
831
+ it('bob steals the share from alice with desktop share', async () => {
832
+ localTracks.bob.screenShare.video = await createDisplayTrack();
833
+
834
+ const stoppedSharingWhiteboard = testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'}]);
835
+ const startedSharingLocal = testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingLocal'}]);
836
+ const startedSharingRemote = testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingRemote'}])
624
837
  .then((response) => {
625
838
  assert.equal(response[0].result.memberId, bob.meeting.selfId);
626
- }),
627
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
628
- .then((response) => {
629
- console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
630
- }),
631
- testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
839
+ });
840
+ const aliceReceivesMembersUpdate = testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
632
841
  .then((response) => {
633
- console.log('MEDIA:READY event ', response[0].result);
634
- assert.equal(response[0].result.type === 'localShare', true);
635
- })
636
- ])
637
- .then(() => {
638
- const heightResolution = DEFAULT_RESOLUTIONS.meetings.screenResolution.idealHeight;
639
-
640
- // TODO: Re-eanable Safari when screensharing issues have been resolved
641
- if (!isBrowser('safari')) {
642
- assert.equal(bob.meeting.mediaProperties.shareTrack.getConstraints().height, heightResolution);
643
- }
644
- assert.equal(bob.meeting.isSharing, true);
645
- assert.equal(bob.meeting.shareStatus, 'local_share_active');
646
- assert.equal(alice.meeting.shareStatus, 'remote_share_active');
647
-
648
- return testUtils.waitUntil(10000);
649
- }));
842
+ console.log(
843
+ 'SCREEN SHARE RESPONSE ',
844
+ JSON.stringify(response, testUtils.getCircularReplacer())
845
+ );
846
+ });
847
+ const bobScreenShareVideoPublished = waitForPublished(localTracks.bob.screenShare.video, true, "bob's screen share video track");
650
848
 
651
- it('bob shares whiteboard B', () => Promise.all([
652
- testUtils.delayedPromise(bob.meeting.startWhiteboardShare(channelUrlB)),
653
- testUtils.waitForEvents([
654
- {scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}
655
- ]),
656
- testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}])
657
- .then((response) => {
658
- const {memberId, resourceUrl} = response[0].result;
849
+ await testUtils.delayedPromise(bob.meeting.publishTracks({screenShare: {video: localTracks.bob.screenShare.video}}));
659
850
 
660
- assert.equal(memberId, bob.meeting.selfId);
661
- assert.equal(resourceUrl, channelUrlB);
662
- }),
663
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
664
- .then((response) => {
665
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
666
- })
667
- ])
668
- .then(() => {
669
- assert.equal(bob.meeting.isSharing, false);
851
+ await bobScreenShareVideoPublished;
852
+ await stoppedSharingWhiteboard;
853
+ await startedSharingLocal;
854
+ await startedSharingRemote;
855
+ await aliceReceivesMembersUpdate;
856
+
857
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_request_granted');
858
+ assert.equal(bob.meeting.shareStatus, 'local_share_active');
859
+ assert.equal(alice.meeting.shareStatus, 'remote_share_active');
860
+
861
+ await testUtils.waitUntil(10000);
862
+ });
863
+
864
+ it('bob shares whiteboard B', () =>
865
+ Promise.all([
866
+ testUtils.delayedPromise(bob.meeting.startWhiteboardShare(channelUrlB)),
867
+ testUtils.waitForEvents([
868
+ {scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'},
869
+ ]),
870
+ testUtils
871
+ .waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}])
872
+ .then((response) => {
873
+ const {memberId, resourceUrl} = response[0].result;
874
+
875
+ assert.equal(memberId, bob.meeting.selfId);
876
+ assert.equal(resourceUrl, channelUrlB);
877
+ }),
878
+ testUtils
879
+ .waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
880
+ .then((response) => {
881
+ console.log(
882
+ 'WHITEBOARD SHARE RESPONSE ',
883
+ JSON.stringify(response, testUtils.getCircularReplacer())
884
+ );
885
+ }),
886
+ ]).then(() => {
887
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
670
888
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
671
889
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
672
890
  }));
673
891
 
674
- it('alice adds chris as guest to 1:1 meeting', () => Promise.all([
675
- testUtils.delayedPromise(alice.meeting.invite({emailAddress: chris.emailAddress})),
676
- testUtils.waitForEvents([{scope: chris.webex.meetings, event: 'meeting:added', user: chris}]),
677
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
678
- .then((response) => {
679
- const chrisParticipant = response[0].result.delta.added.find((member) => member.participant.identity === chris.id);
680
-
681
- assert.equal(chrisParticipant.status, 'NOT_IN_MEETING');
892
+ it('alice adds chris as guest to 1:1 meeting', () =>
893
+ Promise.all([
894
+ testUtils.delayedPromise(alice.meeting.invite({emailAddress: chris.emailAddress})),
895
+ testUtils.waitForEvents([
896
+ {scope: chris.webex.meetings, event: 'meeting:added', user: chris},
897
+ ]),
898
+ testUtils
899
+ .waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
900
+ .then((response) => {
901
+ const chrisParticipant = response[0].result.delta.added.find(
902
+ (member) => member.participant.identity === chris.id
903
+ );
904
+
905
+ assert.equal(chrisParticipant.status, 'NOT_IN_MEETING');
906
+ }),
907
+ ])
908
+ .catch((e) => {
909
+ console.error('Error adding chris as guest ', e);
910
+ throw e;
682
911
  })
683
- ])
684
- .catch((e) => {
685
- console.error('Error adding chris as guest ', e);
686
- throw e;
687
- })
688
- .then(function memberUpdated() {
689
- assert.exists(chris.meeting);
690
-
691
- return Promise.all([
692
- testUtils.delayedPromise(chris.meeting.join()),
693
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update', match: testUtils.checkParticipantUpdatedStatus(chris, 'IN_MEETING')}])
694
- ])
695
- .then(() => {
696
- assert.equal(alice.meeting.members.membersCollection.get(chris.meeting.members.selfId).participant.state, 'JOINED');
697
- })
698
- .then(() => testUtils.waitForStateChange(chris.meeting, 'JOINED'))
699
- .then(() => testUtils.addMedia(chris))
700
- .then(() => assert(enumerateSpy.called));
701
- })
702
- .then(() => Promise.all([
703
- testUtils.delayedPromise(chris.meeting.leave()),
704
- testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update', match: testUtils.checkParticipantUpdatedStatus(chris, 'NOT_IN_MEETING')}])
705
- ]))
706
- .catch((e) => {
707
- console.error('Error chris joining the meeting ', e);
708
- throw e;
709
- }));
912
+ .then(function memberUpdated() {
913
+ assert.exists(chris.meeting);
914
+
915
+ return Promise.all([
916
+ testUtils.delayedPromise(chris.meeting.join()),
917
+ testUtils.waitForEvents([
918
+ {
919
+ scope: alice.meeting.members,
920
+ event: 'members:update',
921
+ match: testUtils.checkParticipantUpdatedStatus(chris, 'IN_MEETING'),
922
+ },
923
+ ]),
924
+ ])
925
+ .then(() => {
926
+ assert.equal(
927
+ alice.meeting.members.membersCollection.get(chris.meeting.members.selfId)
928
+ .participant.state,
929
+ 'JOINED'
930
+ );
931
+ })
932
+ .then(() => testUtils.waitForStateChange(chris.meeting, 'JOINED'))
933
+ .then(async () => {
934
+ localTracks.chris.microphone = await createMicrophoneTrack();
935
+ localTracks.chris.camera = await createCameraTrack();
936
+ })
937
+ .then(() => integrationTestUtils.addMedia(chris, {microphone: localTracks.chris.microphone, camera: localTracks.chris.camera}))
938
+ .then(() => assert(enumerateSpy.called));
939
+ })
940
+ .then(() =>
941
+ Promise.all([
942
+ testUtils.delayedPromise(chris.meeting.leave()),
943
+ testUtils.waitForEvents([
944
+ {
945
+ scope: alice.meeting.members,
946
+ event: 'members:update',
947
+ match: testUtils.checkParticipantUpdatedStatus(chris, 'NOT_IN_MEETING'),
948
+ },
949
+ ]),
950
+ ])
951
+ )
952
+ .catch((e) => {
953
+ console.error('Error chris joining the meeting ', e);
954
+ throw e;
955
+ }));
710
956
 
711
957
  it('leave on the meeting object', () => {
712
958
  const checkInactive = (result) => result.reason === 'CALL_INACTIVE';
@@ -716,10 +962,13 @@ skipInNode(describe)('plugin-meetings', () => {
716
962
  testUtils.waitForEvents([
717
963
  {scope: alice.meeting.members, event: 'members:update', user: alice},
718
964
  {
719
- scope: bob.webex.meetings, event: 'meeting:removed', user: bob, match: checkInactive
965
+ scope: bob.webex.meetings,
966
+ event: 'meeting:removed',
967
+ user: bob,
968
+ match: checkInactive,
720
969
  },
721
- {scope: alice.webex.meetings, event: 'meeting:removed', user: alice}
722
- ])
970
+ {scope: alice.webex.meetings, event: 'meeting:removed', user: alice},
971
+ ]),
723
972
  ])
724
973
  .then(() => {
725
974
  assert.equal(bob.meeting, null);
@@ -732,6 +981,35 @@ skipInNode(describe)('plugin-meetings', () => {
732
981
  assert.equal(bob.webex.meetings.getMeetingByType('sipUri', alice.emailAddress), null);
733
982
  });
734
983
  });
984
+
985
+ it('stop all local tracks', () => {
986
+ if (localTracks.alice.microphone) {
987
+ localTracks.alice.microphone.stop();
988
+ localTracks.alice.microphone = undefined;
989
+ }
990
+ if (localTracks.alice.camera) {
991
+ localTracks.alice.camera.stop();
992
+ localTracks.alice.camera = undefined;
993
+ }
994
+
995
+ if (localTracks.bob.microphone) {
996
+ localTracks.bob.microphone.stop();
997
+ localTracks.bob.microphone = undefined;
998
+ }
999
+ if (localTracks.bob.camera) {
1000
+ localTracks.bob.camera.stop();
1001
+ localTracks.bob.camera = undefined;
1002
+ }
1003
+
1004
+ if (localTracks.chris.microphone) {
1005
+ localTracks.chris.microphone.stop();
1006
+ localTracks.chris.microphone = undefined;
1007
+ }
1008
+ if (localTracks.chris.camera) {
1009
+ localTracks.chris.camera.stop();
1010
+ localTracks.chris.camera = undefined;
1011
+ }
1012
+ });
735
1013
  });
736
1014
  });
737
1015
  });