Skip to content

Commit

Permalink
Merge pull request #575 from shiguredo/feature/e2e-test-signaling
Browse files Browse the repository at this point in the history
Feature/e2e test signaling
  • Loading branch information
voluntas authored Dec 8, 2024
2 parents eafe263 + 75b3b29 commit 807d3fc
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

### misc

- [ADD] E2E テストに `"type": "switched"` のテストを追加する
- @voluntas
- [CHANGE] canary リリース方法を `canary.py` に変更する
- `release_canary.sh` は削除
- @voluntas
Expand Down
15 changes: 13 additions & 2 deletions examples/sendonly/main.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Sora, {
type SignalingNotifyMessage,
type SignalingEvent,
type ConnectionPublisher,
type SoraConnection,
} from 'sora-js-sdk'
Expand Down Expand Up @@ -81,7 +82,10 @@ class SoraClient {
this.metadata = { access_token: access_token }

this.connection = this.sora.sendonly(this.channelId, this.metadata, this.options)
this.connection.on('notify', this.onnotify.bind(this))
this.connection.on('notify', this.onNotify.bind(this))

// E2E テスト用のコード
this.connection.on('signaling', this.onSignaling.bind(this))
}

async connect(stream: MediaStream): Promise<void> {
Expand Down Expand Up @@ -109,7 +113,7 @@ class SoraClient {
return this.connection.pc.getStats()
}

private onnotify(event: SignalingNotifyMessage): void {
private onNotify(event: SignalingNotifyMessage): void {
if (
event.event_type === 'connection.created' &&
this.connection.connectionId === event.connection_id
Expand All @@ -120,4 +124,11 @@ class SoraClient {
}
}
}

// E2E テスト用のコード
private onSignaling(event: SignalingEvent): void {
if (event.type === 'onmessage-switched') {
console.log('[signaling]', event.type, event.transportType)
}
}
}
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
"url": "https://discord.gg/shiguredo"
},
"homepage": "https://github.com/shiguredo/sora-js-sdk#readme",
"files": ["dist"],
"files": [
"dist"
],
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@playwright/test": "1.49.0",
Expand All @@ -41,8 +43,8 @@
"vite": "6.0.1",
"vitest": "2.1.6"
},
"packageManager": "pnpm@9.14.3",
"packageManager": "pnpm@9.15.0",
"engines": {
"node": ">=18"
}
}
}
88 changes: 88 additions & 0 deletions tests/switched.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { expect, test } from '@playwright/test'

test('sendonly type:switched pages', async ({ browser }) => {
// 新しいページを2つ作成
const sendonly = await browser.newPage()

sendonly.on('console', (msg) => {
console.log(msg.type(), msg.text())
})

// それぞれのページに対して操作を行う
await sendonly.goto('http://localhost:9000/sendonly/')

// SDK バージョンの表示
await sendonly.waitForSelector('#sdk-version')
const sendonlySdkVersion = await sendonly.$eval('#sdk-version', (el) => el.textContent)
console.log(`sendonly sdkVersion=${sendonlySdkVersion}`)

await sendonly.click('#connect')
// console.log に [signaling] switched が出力されるまで待機するための Promise を作成する
const consolePromise = sendonly.waitForEvent('console')

// #sendrecv1-connection-id 要素が存在し、その内容が空でないことを確認するまで待つ
await sendonly.waitForSelector('#connection-id:not(:empty)')

// #sendonly-connection-id 要素の内容を取得
const sendonlyConnectionId = await sendonly.$eval('#connection-id', (el) => el.textContent)
console.log(`sendonly connectionId=${sendonlyConnectionId}`)

// レース対策
await sendonly.waitForTimeout(3000)

// Console log の Promise が解決されるまで待機する
const msg = await consolePromise
// log [signaling] switched websocket が出力されるので、args 0/1/2 をそれぞれチェックする
// [signaling]
const value1 = await msg.args()[0].jsonValue()
expect(value1).toBe('[signaling]')
// switched
const value2 = await msg.args()[1].jsonValue()
expect(value2).toBe('onmessage-switched')
// websocket
const value3 = await msg.args()[2].jsonValue()
expect(value3).toBe('websocket')

// 'Get Stats' ボタンをクリックして統計情報を取得
await sendonly.click('#get-stats')

// 統計情報が表示されるまで待機
await sendonly.waitForSelector('#stats-report')
// データセットから統計情報を取得
const sendonlyStatsReportJson: Record<string, unknown>[] = await sendonly.evaluate(() => {
const statsReportDiv = document.querySelector('#stats-report') as HTMLDivElement
return statsReportDiv ? JSON.parse(statsReportDiv.dataset.statsReportJson || '[]') : []
})

// sendonly audio codec
const sendonlyAudioCodecStats = sendonlyStatsReportJson.find(
(report) => report.type === 'codec' && report.mimeType === 'audio/opus',
)
expect(sendonlyAudioCodecStats).toBeDefined()

// sendonly audio outbound-rtp
const sendonlyAudioOutboundRtp = sendonlyStatsReportJson.find(
(report) => report.type === 'outbound-rtp' && report.kind === 'audio',
)
expect(sendonlyAudioOutboundRtp).toBeDefined()
expect(sendonlyAudioOutboundRtp?.bytesSent).toBeGreaterThan(0)
expect(sendonlyAudioOutboundRtp?.packetsSent).toBeGreaterThan(0)

// sendonly video codec
const sendonlyVideoCodecStats = sendonlyStatsReportJson.find(
(stats) => stats.type === 'codec' && stats.mimeType === 'video/VP9',
)
expect(sendonlyVideoCodecStats).toBeDefined()

// sendonly video outbound-rtp
const sendonlyVideoOutboundRtpStats = sendonlyStatsReportJson.find(
(stats) => stats.type === 'outbound-rtp' && stats.kind === 'video',
)
expect(sendonlyVideoOutboundRtpStats).toBeDefined()
expect(sendonlyVideoOutboundRtpStats?.bytesSent).toBeGreaterThan(0)
expect(sendonlyVideoOutboundRtpStats?.packetsSent).toBeGreaterThan(0)

await sendonly.click('#disconnect')

await sendonly.close()
})

0 comments on commit 807d3fc

Please sign in to comment.