Browser Testing
Master Raiken's multi-browser testing capabilities to ensure your application works consistently across Chromium, Firefox, and WebKit browsers.
Overview
Raiken provides comprehensive multi-browser testing support through Playwright, enabling you to test your application across different browser engines with consistent APIs and rich reporting capabilities.
Supported Browsers
Chromium
- Based on: Google Chrome and Microsoft Edge
- Use Cases: Primary testing browser, most web applications
- Features: Full DevTools protocol support, perfect video recording
- Mobile Testing: Android emulation
Firefox
- Based on: Mozilla Firefox
- Use Cases: Cross-browser compatibility, Gecko engine testing
- Features: Excellent screenshot capabilities, privacy-focused testing
- Mobile Testing: Limited mobile emulation
WebKit
- Based on: Safari browser engine
- Use Cases: Safari compatibility, iOS behavior testing
- Features: Native macOS/iOS behavior simulation
- Mobile Testing: iOS Safari emulation
Browser Configuration
Default Settings
Raiken comes with optimized browser configurations:
// playwright.config.ts (auto-generated by Raiken)
export default {
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
video: 'retain-on-failure',
screenshot: 'only-on-failure'
},
},
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
video: 'retain-on-failure',
screenshot: 'only-on-failure'
},
},
{
name: 'webkit',
use: {
...devices['Desktop Safari'],
video: 'retain-on-failure',
screenshot: 'only-on-failure'
},
},
],
}
Custom Browser Settings
Configure browsers through Raiken's interface:
- Open Settings - Click the gear icon in Raiken
- Navigate to Browser - Select browser configuration
- Configure Options:
- Headless mode (on/off)
- Viewport size
- Device emulation
- Video recording
- Screenshot capture
Command Line Configuration
# Run tests on specific browser
npx playwright test --project=chromium
# Run tests on all browsers
npx playwright test
# Run with headed browsers (visible)
npx playwright test --headed
# Run with specific viewport
npx playwright test --headed --viewport=1920,1080
Writing Cross-Browser Tests
Browser-Agnostic Test Patterns
Write tests that work consistently across browsers:
import { test, expect } from '@playwright/test'
test.describe('Cross-Browser Navigation', () => {
test('should navigate between pages consistently', async ({ page, browserName }) => {
await page.goto('/dashboard')
// Wait for page to be fully loaded (important for all browsers)
await page.waitForLoadState('networkidle')
// Use data-testid selectors (consistent across browsers)
await page.click('[data-testid="nav-products"]')
// Verify URL change
await expect(page).toHaveURL('/products')
// Check page content loaded
await expect(page.locator('[data-testid="product-list"]')).toBeVisible()
})
})
Browser-Specific Considerations
Handle browser-specific behaviors:
test('should handle file downloads', async ({ page, browserName }) => {
// Different browsers handle downloads differently
const downloadPromise = page.waitForEvent('download')
await page.click('[data-testid="download-button"]')
const download = await downloadPromise
// WebKit might need additional handling
if (browserName === 'webkit') {
// WebKit-specific download handling
await download.saveAs('./downloads/' + download.suggestedFilename())
} else {
// Standard handling for Chromium/Firefox
await download.path()
}
})
Mobile Browser Testing
Device Emulation
Test mobile experiences across browser engines:
import { test, devices } from '@playwright/test'
// iPhone testing (WebKit)
test.describe('Mobile Safari', () => {
test.use({ ...devices['iPhone 13'] })
test('should work on iPhone', async ({ page }) => {
await page.goto('/mobile-app')
// Touch interactions
await page.tap('[data-testid="menu-button"]')
// Mobile-specific assertions
await expect(page.locator('[data-testid="mobile-menu"]')).toBeVisible()
})
})
// Android testing (Chromium)
test.describe('Mobile Chrome', () => {
test.use({ ...devices['Pixel 5'] })
test('should work on Android', async ({ page }) => {
await page.goto('/mobile-app')
// Android-specific behaviors
await page.locator('[data-testid="input"]').tap()
await page.keyboard.type('Mobile text input')
})
})
Responsive Design Testing
Test responsive breakpoints across browsers:
const viewports = [
{ width: 375, height: 667, name: 'iPhone SE' },
{ width: 768, height: 1024, name: 'iPad' },
{ width: 1920, height: 1080, name: 'Desktop' },
]
viewports.forEach(({ width, height, name }) => {
test(`should work on ${name}`, async ({ page }) => {
await page.setViewportSize({ width, height })
await page.goto('/responsive-page')
// Responsive layout checks
if (width < 768) {
await expect(page.locator('[data-testid="mobile-nav"]')).toBeVisible()
} else {
await expect(page.locator('[data-testid="desktop-nav"]')).toBeVisible()
}
})
})
Performance Testing
Browser Performance Comparison
Measure performance across different browsers:
test('should load quickly in all browsers', async ({ page, browserName }) => {
const startTime = Date.now()
await page.goto('/performance-test')
await page.waitForSelector('[data-testid="content-loaded"]')
const loadTime = Date.now() - startTime
// Different browsers have different performance characteristics
let threshold = 3000 // Default 3 seconds
if (browserName === 'webkit') {
threshold = 4000 // WebKit might be slower on some systems
}
expect(loadTime).toBeLessThan(threshold)
// Measure JavaScript performance
const jsMetrics = await page.evaluate(() => {
return performance.getEntriesByType('navigation')[0]
})
console.log(`${browserName} load time: ${jsMetrics.loadEventEnd - jsMetrics.loadEventStart}ms`)
})
Visual Testing
Cross-Browser Screenshots
Compare visual appearance across browsers:
test('should look consistent across browsers', async ({ page, browserName }) => {
await page.goto('/visual-test')
// Wait for all images and fonts to load
await page.waitForLoadState('networkidle')
// Take screenshot with browser name
await expect(page).toHaveScreenshot(`homepage-${browserName}.png`)
})
Handling Visual Differences
Account for expected browser differences:
test('should handle browser-specific rendering', async ({ page, browserName }) => {
await page.goto('/styled-page')
// Different browsers might render fonts slightly differently
const screenshotOptions = {
threshold: browserName === 'webkit' ? 0.3 : 0.2,
maxDiffPixels: 100
}
await expect(page).toHaveScreenshot('styled-page.png', screenshotOptions)
})
Browser-Specific Features
Chromium Features
Leverage Chromium's advanced capabilities:
test('should use Chromium DevTools features', async ({ page, browserName }) => {
test.skip(browserName !== 'chromium', 'Chromium-specific test')
// Network interception (best on Chromium)
await page.route('**/api/slow-endpoint', route => {
route.fulfill({
status: 200,
body: JSON.stringify({ fast: true })
})
})
// Performance monitoring
await page.coverage.startJSCoverage()
await page.goto('/app')
const coverage = await page.coverage.stopJSCoverage()
expect(coverage.length).toBeGreaterThan(0)
})
Firefox Features
Test Firefox-specific behaviors:
test('should handle Firefox privacy features', async ({ page, browserName }) => {
test.skip(browserName !== 'firefox', 'Firefox-specific test')
// Firefox privacy mode testing
await page.goto('/privacy-sensitive-page')
// Test cookies and storage restrictions
await page.evaluate(() => {
try {
localStorage.setItem('test', 'value')
return true
} catch (e) {
return false
}
})
})
WebKit Features
Test Safari-specific behaviors:
test('should handle WebKit touch events', async ({ page, browserName }) => {
test.skip(browserName !== 'webkit', 'WebKit-specific test')
await page.goto('/touch-interface')
// WebKit touch handling
await page.touchscreen.tap(100, 100)
// Safari-specific date picker
await page.locator('[type="date"]').click()
await expect(page.locator('.date-picker')).toBeVisible()
})
CI/CD Integration
Multi-Browser Pipeline
Set up CI/CD for cross-browser testing:
# .github/workflows/test.yml
name: Cross-Browser Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
browser: [chromium, firefox, webkit]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run tests
run: npx playwright test --project=${{ matrix.browser }}
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results-${{ matrix.browser }}
path: test-results/
Parallel Browser Testing
Run browsers in parallel for faster feedback:
- name: Run parallel browser tests
run: npx playwright test --workers=3
Debugging Browser Issues
Browser-Specific Debugging
Debug issues in specific browsers:
# Debug in specific browser with UI
npx playwright test --project=firefox --debug
# Run headed for visual debugging
npx playwright test --project=webkit --headed
# Trace specific browser issues
npx playwright test --project=chromium --trace=on
Browser Logs and Console
Capture browser-specific console output:
test('should capture browser console', async ({ page, browserName }) => {
const consoleMessages = []
page.on('console', msg => {
consoleMessages.push(`[${browserName}] ${msg.type()}: ${msg.text()}`)
})
await page.goto('/console-test')
// Check for browser-specific console messages
expect(consoleMessages.some(msg => msg.includes('loaded'))).toBe(true)
})
Best Practices
Cross-Browser Compatibility
- Use Standard Selectors: Prefer data-testid over CSS selectors
- Handle Timing: Use waitFor methods instead of hard waits
- Test Critical Paths: Focus on user workflows across browsers
- Monitor Performance: Track performance differences between browsers
Browser Selection Strategy
- Primary Browser: Chromium for development and most testing
- Compatibility Testing: Firefox for cross-engine verification
- Safari Testing: WebKit for iOS/macOS specific features
- Mobile Testing: Device emulation for responsive design
Maintenance Tips
- Keep Browsers Updated: Regular
npx playwright install - Monitor Test Flakiness: Some tests may be browser-specific
- Use Conditional Logic: Skip unsupported features per browser
- Regular Visual Updates: Update screenshots when design changes
Next Steps
Now that you understand browser testing:
- CI/CD Integration - Automate cross-browser testing
- Examples - See browser-specific test examples
- Performance Testing - Advanced performance testing
Ready for automation? Continue with CI/CD Integration to set up automated cross-browser testing.