Skip to main content
Version: 1.x

Hybrid Login Flow

Demonstrates the auto-fallback pattern: use Playwright native locators for non-UI5 pages (login forms, IDP redirects) and seamlessly switch to Praman UI5 fixtures once inside the SAP application.

When to Use Each Approach

Page TypeApproachWhy
Login page / IDP redirectpage.locator(), page.fill(), page.click()These are plain HTML, not UI5
SAP Fiori Launchpad tilesui5.control(), ui5.press()UI5 controls with dynamic IDs
SAP app controls (Input, Table, Dialog)ui5.control(), ui5.fill()UI5 controls with event model

Source

import { test, expect } from 'playwright-praman';

test.describe('Hybrid Login Flow', () => {
test('login with Playwright native, then test with Praman', async ({ page, ui5 }) => {
// ================================================================
// PHASE 1: Playwright Native -- Login Form (NOT UI5)
// ================================================================
await test.step('Login via SAP IAS (Playwright native)', async () => {
await page.goto(process.env['SAP_BASE_URL']!);

// IAS login form is plain HTML -- use Playwright locators
await page.waitForSelector('input[name="j_username"], input[name="email"]', {
timeout: 30_000,
});

await page
.locator('input[name="j_username"], input[name="email"]')
.fill(process.env['SAP_USERNAME']!);
await page
.locator('input[name="j_password"], input[name="password"]')
.fill(process.env['SAP_PASSWORD']!);

await page.locator('button[type="submit"], #logOnFormSubmit').click();
await expect(page).toHaveTitle(/Home/, { timeout: 60_000 });
});

// ================================================================
// PHASE 2: Praman UI5 Fixtures -- SAP Application (UI5)
// ================================================================
await test.step('Navigate FLP tile (Praman UI5)', async () => {
// Now on the Fiori Launchpad -- switch to Praman fixtures.
// The bridge is injected automatically on the first ui5.* call.
const tile = await ui5.control({
controlType: 'sap.m.GenericTile',
properties: { header: 'Purchase Orders' },
});

const header = await tile.getProperty('header');
expect(header).toBe('Purchase Orders');

await ui5.press({
controlType: 'sap.m.GenericTile',
properties: { header: 'Purchase Orders' },
});
await ui5.waitForUI5();
});

await test.step('Interact with app controls (Praman UI5)', async () => {
const searchField = await ui5.control({
controlType: 'sap.m.SearchField',
});

const controlType = await searchField.getControlType();
expect(controlType).toBe('sap.m.SearchField');

await ui5.fill({ controlType: 'sap.m.SearchField' }, 'PO-12345');
await ui5.waitForUI5();
});
});
});

Key Concepts

  • No special configuration -- Praman auto-detects UI5 pages and injects the bridge on first ui5.* call
  • Playwright native for non-UI5 -- login pages, IDP redirects, and static HTML forms
  • Praman fixtures for UI5 -- all SAP Fiori controls inside the application
  • Seamless transition -- both approaches work in the same test, same page object