Skip to main content

Cross-Browser Testing

How to configure Playwright projects for multi-browser SAP UI5 testing. Covers browser-specific differences in UI5 rendering, project configuration, and CI matrix strategies.

Playwright Browser Projects​

Playwright supports Chromium, Firefox, and WebKit. SAP UI5 officially supports Chrome, Firefox, Safari, and Edge (Chromium-based).

Basic Multi-Browser Config​

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
timeout: 120_000,

projects: [
// Auth setup per browser
{
name: 'chromium-setup',
testMatch: /auth-setup\.ts/,
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox-setup',
testMatch: /auth-setup\.ts/,
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit-setup',
testMatch: /auth-setup\.ts/,
use: { ...devices['Desktop Safari'] },
},

// Tests per browser
{
name: 'chromium',
dependencies: ['chromium-setup'],
use: {
...devices['Desktop Chrome'],
storageState: '.auth/chromium-session.json',
},
},
{
name: 'firefox',
dependencies: ['firefox-setup'],
use: {
...devices['Desktop Firefox'],
storageState: '.auth/firefox-session.json',
},
},
{
name: 'webkit',
dependencies: ['webkit-setup'],
use: {
...devices['Desktop Safari'],
storageState: '.auth/webkit-session.json',
},
},
],
});

Browser-Specific Auth Setup​

Each browser needs its own storage state file because session cookies are browser-specific:

// tests/auth-setup.ts
import { join } from 'node:path';
import { test as setup } from '@playwright/test';

setup('SAP authentication', async ({ page, context, browserName }) => {
const authFile = join(process.cwd(), '.auth', `${browserName}-session.json`);

// ... perform login ...

await context.storageState({ path: authFile });
});

SAP UI5 Cross-Browser Differences​

UI5 controls render slightly differently across browsers. These are the most common differences that affect test stability.

Rendering Differences​

ControlChromeFirefoxSafari/WebKit
sap.m.TableStandard renderingMinor scrollbar width differencesTouch-optimized rendering
sap.m.DatePickerNative date popup availableCustom UI5 popup onlyNative date popup available
sap.ui.table.TableSmooth scrollingRow height may vary by 1-2pxMomentum scrolling
sap.m.DialogStandard animationAnimation timing differsBackdrop rendering differs
sap.m.PopoverStandard positioningSameMay position differently near edges

Event Handling Differences​

// Some interactions behave differently across browsers.
// Use Praman's ui5.click() and ui5.fill() — they normalize behavior.

// Avoid browser-specific workarounds like:
// await page.mouse.click(x, y); // Coordinates vary by browser
// await page.keyboard.press('Tab'); // Focus order may differ

// Instead, use semantic selectors:
await ui5.click({
controlType: 'sap.m.Button',
properties: { text: 'Save' },
});

Scroll Behavior​

// Scrolling can differ across browsers. Use UI5 control methods:
await ui5.scrollToControl({
controlType: 'sap.m.Input',
id: /lastFieldOnPage/,
});

// For tables with virtual scrolling:
const table = await ui5.control({
controlType: 'sap.ui.table.Table',
id: /mainTable/,
});
await table.scrollToRow(50);

Selective Browser Testing​

Tag Tests by Browser Compatibility​

// Run specific tests only on certain browsers
test('drag and drop in table (Chromium only)', async ({ ui5, browserName }) => {
test.skip(browserName !== 'chromium', 'Drag and drop is Chromium-only');

// ... drag and drop test ...
});

test('touch gestures (WebKit only)', async ({ ui5, browserName }) => {
test.skip(browserName !== 'webkit', 'Touch-specific test');

// ... touch gesture test ...
});

Browser-Specific Assertions​

test('table rendering across browsers', async ({ ui5, ui5Matchers, browserName }) => {
const table = await ui5.control({ controlType: 'sap.m.Table' });

// Common assertion — works on all browsers
await ui5Matchers.toHaveRowCount(table, 10);

// Browser-specific screenshot comparison
const locator = await table.getLocator();
await expect(locator).toHaveScreenshot(`table-${browserName}.png`, {
maxDiffPixelRatio: browserName === 'webkit' ? 0.02 : 0.01,
});
});

Mobile Browser Testing​

SAP Fiori apps are responsive. Test mobile viewports:

// playwright.config.ts
export default defineConfig({
projects: [
// Desktop
{
name: 'desktop-chrome',
use: { ...devices['Desktop Chrome'] },
},

// Tablet
{
name: 'ipad',
use: { ...devices['iPad Pro 11'] },
},

// Mobile
{
name: 'iphone',
use: { ...devices['iPhone 14'] },
},

// Android
{
name: 'android',
use: { ...devices['Pixel 7'] },
},
],
});

Responsive Layout Tests​

test('list report adapts to mobile viewport', async ({ ui5, page, isMobile }) => {
await test.step('verify responsive table mode', async () => {
if (isMobile) {
// On mobile, SmartTable switches to responsive mode
const mTable = await ui5.controlOrNull({
controlType: 'sap.m.Table',
});
expect(mTable).not.toBeNull();
} else {
// On desktop, SmartTable may use grid table
const gridTable = await ui5.controlOrNull({
controlType: 'sap.ui.table.Table',
});
// Grid table OR responsive table depending on config
expect(gridTable).not.toBeNull();
}
});
});

CI Matrix Strategy​

GitHub Actions Multi-Browser Matrix​

# .github/workflows/cross-browser.yml
name: Cross-Browser Tests
on:
push:
branches: [main]
pull_request:

jobs:
test:
strategy:
fail-fast: false
matrix:
browser: [chromium, firefox, webkit]
os: [ubuntu-latest, windows-latest, macos-latest]
exclude:
# WebKit on Windows is not officially supported by Playwright
- browser: webkit
os: windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install ${{ matrix.browser }}
- run: npx playwright test --project=${{ matrix.browser }}
env:
SAP_BASE_URL: ${{ secrets.SAP_QA_URL }}
SAP_USERNAME: ${{ secrets.SAP_QA_USER }}
SAP_PASSWORD: ${{ secrets.SAP_QA_PASS }}
- uses: actions/upload-artifact@v4
if: failure()
with:
name: report-${{ matrix.browser }}-${{ matrix.os }}
path: playwright-report/

Tiered Browser Strategy​

Not all tests need to run on all browsers. Use a tiered approach:

// playwright.config.ts
export default defineConfig({
projects: [
// Tier 1: Full suite on Chrome (primary browser)
{
name: 'chromium-full',
testDir: './tests',
use: { ...devices['Desktop Chrome'] },
},

// Tier 2: Smoke tests on Firefox
{
name: 'firefox-smoke',
testDir: './tests/smoke',
use: { ...devices['Desktop Firefox'] },
},

// Tier 3: Critical path on WebKit
{
name: 'webkit-critical',
testDir: './tests/critical',
use: { ...devices['Desktop Safari'] },
},
],
});

Best Practices​

PracticeWhy
Use Praman fixtures, not raw PlaywrightPraman normalizes cross-browser differences in UI5 interactions
Separate auth state per browserSession cookies are browser-specific
Use maxDiffPixelRatio for screenshotsRendering differs slightly per browser
Run Chrome as primary, others as smokeChrome covers most users; other browsers catch critical regressions
Skip known browser limitationsUse test.skip() with clear reason, not silent failures
Use fail-fast: false in CI matrixOne browser failure should not block others from completing