Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hand raise API for the video SDK #873

Merged
merged 14 commits into from
Nov 10, 2023
7 changes: 7 additions & 0 deletions .changeset/red-turkeys-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@signalwire/realtime-api': minor
'@signalwire/core': minor
'@signalwire/js': minor
---

Introduce the hand raise API for the Video SDKs (browser and realtime-api)
146 changes: 146 additions & 0 deletions internal/e2e-js/tests/roomSessionRaiseHand.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import type { Video } from '@signalwire/js'
import { test, expect } from '../fixtures'
import {
SERVER_URL,
createTestRoomSession,
randomizeRoomName,
expectRoomJoined,
expectMCUVisible,
} from '../utils'

test.describe('RoomSession Raise/Lower hand', () => {
test('should join a room and be able to set hand prioritization', async ({
createCustomPage,
}) => {
const page = await createCustomPage({ name: 'raise-lower' })
await page.goto(SERVER_URL)

const roomName = randomizeRoomName('raise-lower-e2e')
const memberSettings = {
vrt: {
room_name: roomName,
user_name: 'e2e_participant_meta',
auto_create_room: true,
permissions: ['room.prioritize_handraise'],
},
initialEvents: ['room.updated'],
}

await createTestRoomSession(page, memberSettings)

// --------------- Joining the room ---------------
const joinParams = await expectRoomJoined(page)

expect(joinParams.room).toBeDefined()
expect(joinParams.room_session).toBeDefined()
expect(joinParams.room.name).toBe(roomName)
expect(joinParams.room.prioritize_handraise).toBe(false)

// Checks that the video is visible
await expectMCUVisible(page)

// --------------- Set hand raise priority ---------------
await page.evaluate(
async ({ roomSessionId }) => {
// @ts-expect-error
const roomObj: Video.RoomSession = window._roomObj

const roomUpdated = new Promise((resolve) => {
roomObj.on('room.updated', (params) => {
if (
params.room_session.id === roomSessionId &&
params.room_session.prioritize_handraise == true
) {
resolve(true)
}
})
})

await roomObj.setPrioritizeHandraise(true)

return roomUpdated
},
{ roomSessionId: joinParams.room_session.id }
)
})

test("should join a room and be able to raise/lower member's hand", async ({
createCustomPage,
}) => {
const page = await createCustomPage({ name: 'raise-lower' })
await page.goto(SERVER_URL)

const roomName = randomizeRoomName('raise-lower-e2e')
const memberSettings = {
vrt: {
room_name: roomName,
user_name: 'e2e_participant_meta',
auto_create_room: true,
permissions: ['room.member.raisehand', 'room.member.lowerhand'],
},
initialEvents: ['member.joined', 'member.updated', 'member.left'],
}

await createTestRoomSession(page, memberSettings)

// --------------- Joining the room ---------------
const joinParams = await expectRoomJoined(page)

expect(joinParams.room).toBeDefined()
expect(joinParams.room_session).toBeDefined()
expect(joinParams.room.name).toBe(roomName)

// Checks that the video is visible
await expectMCUVisible(page)

// --------------- Raise a member's hand ---------------
await page.evaluate(
async ({ roomSessionId }) => {
// @ts-expect-error
const roomObj: Video.RoomSession = window._roomObj

const memberUpdated = new Promise((resolve) => {
roomObj.on('member.updated', (params) => {
if (
params.room_session_id === roomSessionId &&
params.member.handraised == true
) {
resolve(true)
}
})
})

await roomObj.setRaisedHand()

return memberUpdated
},
{ roomSessionId: joinParams.room_session.id }
)

await page.waitForTimeout(1000)

// --------------- Lower a member's hand ---------------
await page.evaluate(
async ({ roomSessionId }) => {
// @ts-expect-error
const roomObj: Video.RoomSession = window._roomObj

const memberUpdated = new Promise((resolve) => {
roomObj.on('member.updated', (params) => {
if (
params.room_session_id === roomSessionId &&
params.member.handraised == false
) {
resolve(true)
}
})
})

await roomObj.setRaisedHand({ raised: false })

return memberUpdated
},
{ roomSessionId: joinParams.room_session.id }
)
})
})
95 changes: 93 additions & 2 deletions internal/e2e-realtime-api/src/playwright/video.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { test, expect } from '@playwright/test'
import { uuid } from '@signalwire/core'
import { Video } from '@signalwire/realtime-api'
import { createNewTabRoomSession } from './videoUtils'
import {
createRoomAndRecordPlay,
createRoomSession,
enablePageLogs,
} from './videoUtils'
import { SERVER_URL } from '../../utils'

test.describe('Video', () => {
test('should join the room and listen for events', async ({ browser }) => {
Expand Down Expand Up @@ -40,7 +45,7 @@ test.describe('Video', () => {
let roomSessionPromises: Promise<void>[] = []
for (let index = 0; index < roomCount; index++) {
roomSessionPromises.push(
createNewTabRoomSession({
createRoomAndRecordPlay({
browser,
pageName: `[page-${index}]`,
room_name: `${prefix}-${index}`,
Expand Down Expand Up @@ -123,4 +128,90 @@ test.describe('Video', () => {
expect(roomSessionCreated.size).toBe(roomCount)
expect(roomSessionsAtEnd).toHaveLength(roomCount)
})

test('should join the room and set hand raise priority', async ({
browser,
}) => {
const page = await browser.newPage()
await page.goto(SERVER_URL)
enablePageLogs(page, '[pageOne]')

// Create a realtime-api Video client
const videoClient = new Video.Client({
// @ts-expect-error
host: process.env.RELAY_HOST,
project: process.env.RELAY_PROJECT as string,
token: process.env.RELAY_TOKEN as string,
debug: { logWsTraffic: true },
})

const prefix = uuid()
const roomName = `${prefix}-hand-raise-priority-e2e`

const findRoomSession = async () => {
const { roomSessions } = await videoClient.getRoomSessions()
return roomSessions.filter((r) => r.name.startsWith(prefix))
}

// Listen for realtime-api event
videoClient.on('room.started', (room) => {
room.on('room.updated', (room) => {
console.log('>> room.updated', room.name)
})
})

// Room length should be 0 before start
const roomSessionsBeforeStart = await findRoomSession()
expect(roomSessionsBeforeStart).toHaveLength(0)

// Create and join room on the web using JS SDK
await createRoomSession({
page,
room_name: roomName,
user_name: `${prefix}-member`,
initialEvents: ['room.updated'],
})

// Room length should be 1 after start
const roomSessionsAfterStart = await findRoomSession()
expect(roomSessionsAfterStart).toHaveLength(1)

const roomSessionNode = roomSessionsAfterStart[0]

const roomSessionWeb = await page.evaluate(() => {
// @ts-expect-error
const roomSession = window._roomOnJoined

return roomSession.room_session
})

// Hand raise is not prioritize on both Node & Web room session object
expect(roomSessionNode.prioritizeHandraise).toBe(false)
expect(roomSessionWeb.prioritize_handraise).toBe(false)

const roomSessionWebUpdated = page.evaluate(() => {
return new Promise<any>((resolve, _reject) => {
// @ts-expect-error
const roomSessionWeb = window._roomObj

roomSessionWeb.on('room.updated', (room) => {
resolve(room.room_session)
})
})
})

// Set the hand raise prioritization via Node SDK
const roomSessionNodeUpdated = await new Promise<Video.RoomSession>(
async (resolve, _reject) => {
roomSessionNode.on('room.updated', (room) => {
resolve(room)
})
await roomSessionNode.setPrioritizeHandraise(true)
}
)

// Expect hand raise prioritization to be true on both Node & Web SDK objects
expect(roomSessionNodeUpdated.prioritizeHandraise).toBe(true)
expect((await roomSessionWebUpdated).prioritize_handraise).toBe(true)
})
})
Loading