Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions apps/simple-camera/__tests__/visioncamera.devices.harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,54 @@ describe('VisionCamera - Devices', () => {
expect(factory.userPreferredCamera?.id).toBe(back.id)
factory.userPreferredCamera = previous
})

it('returns an empty supportedMultiCamDeviceCombinations array when the platform does not support multi-cam', () => {
if (VisionCamera.supportsMultiCamSessions) {
console.log(
'[SKIP] supportedMultiCamDeviceCombinations empty: platform supports multi-cam',
)
return
}
expect(factory.supportedMultiCamDeviceCombinations.length).toBe(0)
})

it('returns at least one supportedMultiCamDeviceCombinations combination when the platform supports multi-cam', () => {
if (!VisionCamera.supportsMultiCamSessions) {
console.log(
'[SKIP] supportedMultiCamDeviceCombinations non-empty: multi-cam not supported on this platform',
)
return
}
expect(factory.supportedMultiCamDeviceCombinations.length).toBeGreaterThanOrEqual(1)
})

it('every device in a supportedMultiCamDeviceCombinations combination is also present in cameraDevices', () => {
const combinations = factory.supportedMultiCamDeviceCombinations
if (combinations.length === 0) {
console.log(
'[SKIP] supportedMultiCamDeviceCombinations device lookup: no combinations on this platform',
)
return
}
const knownIds = new Set(factory.cameraDevices.map((d) => d.id))
for (const combination of combinations) {
expect(combination.length).toBeGreaterThan(0)
for (const device of combination) {
expect(knownIds.has(device.id)).toBe(true)
}
}
})

it('logs every supported multi-cam device combination', () => {
const combinations = factory.supportedMultiCamDeviceCombinations
console.log(
`supportedMultiCamDeviceCombinations: ${combinations.length} combinations`,
)
for (const [index, combination] of combinations.entries()) {
const description = combination
.map((d) => `${d.position}:${d.id}`)
.join(', ')
console.log(` [${index}] ${description}`)
}
})
})
55 changes: 55 additions & 0 deletions apps/simple-camera/__tests__/visioncamera.session.harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,59 @@ describe('VisionCamera - Session', () => {
await session.stop()
sub.remove()
})

it('configures, starts and stops a multi-cam session for every supported device combination', async () => {
if (!VisionCamera.supportsMultiCamSessions) {
console.log(
'[SKIP] multi-cam combinations: not supported on this platform',
)
return
}
const combinations = factory.supportedMultiCamDeviceCombinations
if (combinations.length === 0) {
console.log(
'[SKIP] multi-cam combinations: no combinations reported on this device',
)
return
}

for (const combination of combinations) {
const session = await VisionCamera.createCameraSession(true)
const connections = combination.map((device) => ({
input: device,
outputs: [
{
output: VisionCamera.createPhotoOutput({
targetResolution: CommonResolutions.HD_4_3,
containerFormat: 'jpeg' as const,
quality: 0.8,
qualityPrioritization: 'balanced' as const,
}),
mirrorMode: 'auto' as const,
},
],
constraints: [],
}))

const controllers = await session.configure(connections)
expect(controllers.length).toBe(combination.length)
for (let i = 0; i < combination.length; i++) {
expect(controllers[i]?.device.id).toBe(combination[i]?.id)
}

let started = false
const sub = session.addOnStartedListener(() => {
started = true
})
await session.start()
await waitUntil(() => started, { timeout: 15_000 })
await session.stop()
sub.remove()

const description = combination
.map((d) => `${d.position}:${d.id}`)
.join(', ')
console.log(`multi-cam session ok: [${description}]`)
}
})
})
Loading