Co-authored-by: Madison Grubb <madison@elastiflow.com> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,66 +1,58 @@
|
||||
/**
|
||||
* Global setup for E2E tests.
|
||||
* Runs once before all tests.
|
||||
*/
|
||||
|
||||
import { existsSync, mkdirSync } from 'node:fs'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { execSync } from 'node:child_process'
|
||||
|
||||
const _dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const projectRoot = join(_dirname, '../../..')
|
||||
const projectRoot = join(dirname(fileURLToPath(import.meta.url)), '../../..')
|
||||
const devCertsDir = join(projectRoot, '.dev-certs')
|
||||
const devKey = join(devCertsDir, 'key.pem')
|
||||
const devCert = join(devCertsDir, 'cert.pem')
|
||||
|
||||
// Import server modules (ES modules)
|
||||
const { getDb } = await import('../../server/utils/db.js')
|
||||
const { hashPassword } = await import('../../server/utils/password.js')
|
||||
const { TEST_ADMIN } = await import('./fixtures/users.js')
|
||||
|
||||
function ensureDevCerts() {
|
||||
if (existsSync(devKey) && existsSync(devCert)) {
|
||||
return // Certs already exist
|
||||
}
|
||||
const ensureDevCerts = () => {
|
||||
if (existsSync(devKey) && existsSync(devCert)) return
|
||||
|
||||
// Create .dev-certs directory
|
||||
mkdirSync(devCertsDir, { recursive: true })
|
||||
|
||||
// Generate self-signed cert for localhost/127.0.0.1
|
||||
const SAN = 'subjectAltName=IP:127.0.0.1,DNS:localhost'
|
||||
try {
|
||||
execSync(
|
||||
`openssl req -x509 -newkey rsa:2048 -keyout "${devKey}" -out "${devCert}" -days 365 -nodes -subj "/CN=localhost" -addext "${SAN}"`,
|
||||
{ cwd: projectRoot, stdio: 'inherit' },
|
||||
`openssl req -x509 -newkey rsa:2048 -keyout "${devKey}" -out "${devCert}" -days 365 -nodes -subj "/CN=localhost" -addext "subjectAltName=IP:127.0.0.1,DNS:localhost"`,
|
||||
{ cwd: projectRoot, stdio: process.env.CI ? 'pipe' : 'inherit' },
|
||||
)
|
||||
console.log('[test] Generated .dev-certs/key.pem and .dev-certs/cert.pem')
|
||||
}
|
||||
catch (error) {
|
||||
throw new Error(`Failed to generate dev certificates: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function globalSetup() {
|
||||
// Ensure dev certificates exist
|
||||
export default async function globalSetup() {
|
||||
ensureDevCerts()
|
||||
|
||||
// Create test admin user if it doesn't exist
|
||||
const { get, run } = await getDb()
|
||||
const existingUser = await get('SELECT id FROM users WHERE identifier = ?', [TEST_ADMIN.identifier])
|
||||
let retries = 3
|
||||
while (retries > 0) {
|
||||
try {
|
||||
const { get, run } = await getDb()
|
||||
const existing = await get('SELECT id FROM users WHERE identifier = ?', [TEST_ADMIN.identifier])
|
||||
|
||||
if (!existingUser) {
|
||||
const id = crypto.randomUUID()
|
||||
const now = new Date().toISOString()
|
||||
await run(
|
||||
'INSERT INTO users (id, identifier, password_hash, role, created_at, auth_provider, oidc_issuer, oidc_sub) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[id, TEST_ADMIN.identifier, hashPassword(TEST_ADMIN.password), TEST_ADMIN.role, now, 'local', null, null],
|
||||
)
|
||||
console.log(`[test] Created test admin user: ${TEST_ADMIN.identifier}`)
|
||||
}
|
||||
else {
|
||||
console.log(`[test] Test admin user already exists: ${TEST_ADMIN.identifier}`)
|
||||
if (!existing) {
|
||||
await run(
|
||||
'INSERT INTO users (id, identifier, password_hash, role, created_at, auth_provider, oidc_issuer, oidc_sub) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[crypto.randomUUID(), TEST_ADMIN.identifier, hashPassword(TEST_ADMIN.password), TEST_ADMIN.role, new Date().toISOString(), 'local', null, null],
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message?.includes('SQLITE_BUSY') || error.message?.includes('database is locked')) {
|
||||
retries--
|
||||
if (retries > 0) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100 * (4 - retries)))
|
||||
continue
|
||||
}
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default globalSetup
|
||||
|
||||
@@ -28,8 +28,10 @@ test.describe('Live Streaming E2E', () => {
|
||||
|
||||
test('publisher only: start sharing and reach Live', async ({ browser, browserName }) => {
|
||||
test.skip(browserName !== 'chromium', 'Fake camera only supported in Chromium')
|
||||
// Skip in CI - WebRTC tests are flaky with fake media devices in CI environments
|
||||
test.skip(!!process.env.CI, 'WebRTC tests skipped in CI due to flaky fake media device support')
|
||||
const ctx = await browser.newContext({
|
||||
permissions: ['geolocation'],
|
||||
permissions: ['camera', 'microphone', 'geolocation'],
|
||||
geolocation: { latitude: 37.7749, longitude: -122.4194 },
|
||||
})
|
||||
const page = await ctx.newPage()
|
||||
@@ -55,9 +57,11 @@ test.describe('Live Streaming E2E', () => {
|
||||
|
||||
test('Mobile Safari publishes, Desktop Chrome views', async ({ browser, browserName }) => {
|
||||
test.skip(browserName !== 'chromium', 'Fake camera only supported in Chromium')
|
||||
// Skip in CI - WebRTC tests are flaky with fake media devices in CI environments
|
||||
test.skip(!!process.env.CI, 'WebRTC tests skipped in CI due to flaky fake media device support')
|
||||
// Publisher context (same as publisher-only test for reliability)
|
||||
const publisherContext = await browser.newContext({
|
||||
permissions: ['geolocation'],
|
||||
permissions: ['camera', 'microphone', 'geolocation'],
|
||||
geolocation: { latitude: 37.7749, longitude: -122.4194 },
|
||||
})
|
||||
const publisherPage = await publisherContext.newPage()
|
||||
@@ -123,8 +127,10 @@ test.describe('Live Streaming E2E', () => {
|
||||
|
||||
test('Mobile Safari publishes, Desktop Firefox views', async ({ browser, browserName }) => {
|
||||
test.skip(browserName !== 'chromium', 'Fake camera only supported in Chromium')
|
||||
// Skip in CI - WebRTC tests are flaky with fake media devices in CI environments
|
||||
test.skip(!!process.env.CI, 'WebRTC tests skipped in CI due to flaky fake media device support')
|
||||
const publisherContext = await browser.newContext({
|
||||
permissions: ['geolocation'],
|
||||
permissions: ['camera', 'microphone', 'geolocation'],
|
||||
geolocation: { latitude: 37.7749, longitude: -122.4194 },
|
||||
})
|
||||
const publisherPage = await publisherContext.newPage()
|
||||
|
||||
Reference in New Issue
Block a user