Skip to main content

From Tosca to Playwright-Praman

A comprehensive guide for teams migrating from Tricentis Tosca to Playwright + Praman for SAP Fiori and UI5 web application testing. Covers concept mapping, workflow changes, and practical code examples.

Why Migrate?​

FactorToscaPlaywright + Praman
License costPer-user commercial licenseOpen source (MIT)
SAP Fiori supportVia SAP UI5 scan / engineNative UI5 control registry
CI/CD integrationTosca CI adapterFirst-class CLI (npx playwright test)
Version controlTosca workspaceGit (standard branching, PRs, diffs)
Parallel executionTosca Distributed ExecutionNative Playwright workers
AI/MLTosca Vision AI (image-based)LLM-powered test generation + recipe library
Browser supportChrome, Firefox, EdgeChrome, Firefox, Safari, Edge
Scripting languageTosca TestStepValues / ModulesTypeScript (full programming language)
CommunityTricentis communityPlaywright 80k+ GitHub stars, npm ecosystem
SAP GUI Testing

Tosca excels at SAP GUI testing via its SAP engine. If your test scope includes SAP GUI transactions (not browser-based Fiori apps), keep Tosca for those tests and use Praman for Fiori/UI5 web apps. Both can coexist in a CI pipeline.

Concept Mapping Table​

The following table maps 25 core Tosca concepts to their Playwright/Praman equivalents.

#Tosca ConceptPlaywright/Praman EquivalentNotes
1WorkspaceGit repositoryTests are TypeScript files in a Git repo
2TestCasetest('name', async () => {...})A single test function in a .test.ts file
3TestSteptest.step('name', async () => {...})Collapsible step in HTML report
4TestStepValueVariable / parameterconst vendor = '100001';
5ModulePlaywright fixtureasync ({ ui5, fe }) => {...}
6ModuleAttributeFixture property / methodui5.control(), fe.listReport.search()
7TestCaseDesign (TCD)Test data fixturetestData.generate({ vendor: '{{uuid}}' })
8TestConfigurationplaywright.config.ts + praman.config.tsTwo config files: runner + SAP-specific
9ExecutionListPlaywright projectprojects: [{ name: 'chromium', ... }]
10TestDataContainer.env file + testData fixtureEnvironment vars + template generation
11ActionMode Verifyexpect() assertionawait expect(btn).toBeUI5Enabled()
12ActionMode Inputui5.fill() / ui5.select()await ui5.fill({ id: 'vendorInput' }, '100001')
13ActionMode BufferVariable assignmentconst value = await control.getValue()
14ActionMode WaitOnui5.control() auto-waitBuilt-in waitForUI5Stable()
15Steering ParameterConfig option / env varPRAMAN_LOG_LEVEL=debug npx playwright test
16Recovery Scenariotest.afterEach() / fixture teardownAuto-cleanup in fixtures (locks, test data)
17Scan (UI5 Engine)UI5Selector object{ controlType: 'sap.m.Button', properties: { text: 'Save' } }
18XScan / TBoxpage.locator() (CSS/XPath)For non-UI5 elements; ui5.control() for UI5
19Librarynpm package / utility moduleShared helpers via import
20RequirementsTest annotations / tagstest('PO @smoke', ...) + --grep @smoke
21Execution logPlaywright HTML reportnpx playwright show-report
22ScreenshotsAutomatic screenshotsscreenshot: 'only-on-failure' in config
23Distributed Executionworkers configworkers: 4 in playwright.config.ts
24Tosca CommanderVS Code / terminalIDE + npx playwright test
25DEX AgentCI runner (GitHub Actions, Jenkins)npx playwright test in pipeline YAML

Tosca TestCase to Playwright Test​

Tosca TestCase (Conceptual)​

TestCase: Create Purchase Order
TestStep: Login
Module: SAP_Login
Username = {TC_User}
Password = {TC_Password}
TestStep: Navigate to Create PO
Module: FLP_Navigation
Tile = "Create Purchase Order"
TestStep: Fill Header Data
Module: PO_Header
Vendor = {TC_Vendor}
PurchaseOrg = {TC_PurchOrg}
CompanyCode = {TC_CompCode}
TestStep: Add Item
Module: PO_Item
Material = {TC_Material}
Quantity = {TC_Quantity}
Plant = {TC_Plant}
TestStep: Save
Module: PO_Footer
Action = Save
TestStep: Verify Success
Module: PO_Message
MessageType = Success [Verify]

Praman Equivalent​

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

// Test data replaces Tosca TestCaseDesign / TestDataContainer
const testInput = {
vendor: '100001',
purchaseOrg: '1000',
companyCode: '1000',
material: 'MAT-001',
quantity: '10',
plant: '1000',
};

test('create purchase order', async ({ ui5, ui5Navigation, fe, ui5Footer }) => {
// TestStep: Navigate (login handled by setup project -- no code needed)
await test.step('Navigate to Create PO', async () => {
await ui5Navigation.navigateToTile('Create Purchase Order');
});

// TestStep: Fill Header Data
await test.step('Fill header data', async () => {
await ui5.fill({ id: 'vendorInput' }, testInput.vendor);
await ui5.fill({ id: 'purchOrgInput' }, testInput.purchaseOrg);
await ui5.fill({ id: 'compCodeInput' }, testInput.companyCode);
});

// TestStep: Add Item
await test.step('Add line item', async () => {
await ui5.fill({ id: 'materialInput' }, testInput.material);
await ui5.fill({ id: 'quantityInput' }, testInput.quantity);
await ui5.fill({ id: 'plantInput' }, testInput.plant);
});

// TestStep: Save (replaces Tosca PO_Footer module)
await test.step('Save', async () => {
await ui5Footer.clickSave();
});

// TestStep: Verify (replaces Tosca ActionMode Verify)
await test.step('Verify success message', async () => {
const message = await ui5.control({
controlType: 'sap.m.MessageStrip',
properties: { type: 'Success' },
searchOpenDialogs: true,
});
await expect(message).toBeUI5Visible();
});
});

Intent API and SAP Transaction Codes​

Praman's Intent API provides high-level business operations that map to SAP transaction codes and Fiori apps.

SAP TCodeFiori AppPraman Intent API
ME21NCreate Purchase Orderintent.procurement.createPurchaseOrder()
ME23NDisplay Purchase Orderintent.procurement.displayPurchaseOrder()
VA01Create Sales Orderintent.sales.createSalesOrder()
VA03Display Sales Orderintent.sales.displaySalesOrder()
FB60Enter Vendor Invoiceintent.finance.postVendorInvoice()
FBL1NVendor Line Itemsintent.finance.displayVendorLineItems()
CO01Create Production Orderintent.manufacturing.createProductionOrder()
MM01Create Material Masterintent.masterData.createMaterial()

Using the Intent API​

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

test('create PO via intent API', async ({ intent }) => {
await test.step('Create purchase order', async () => {
await intent.procurement.createPurchaseOrder({
vendor: '100001',
material: 'MAT-001',
quantity: 10,
plant: '1000',
});
});

await test.step('Post vendor invoice', async () => {
await intent.finance.postVendorInvoice({
vendor: '100001',
amount: 5000,
currency: 'EUR',
});
});
});

Team Workflow Transition​

From Tosca Commander to Git + IDE​

WorkflowToscaPraman
Create testTosca Commander GUICreate .test.ts file in VS Code
Edit testTosca Module editorEdit TypeScript in any IDE
Version controlTosca workspace versioningGit branches + pull requests
Code reviewNot built-inGitHub/GitLab PR reviews
Merge conflictsWorkspace conflicts (binary)Text-based Git merge (readable diffs)
Share test assetsExport/import workspacenpm install shared packages
CollaborateWorkspace locksGit branching (multiple people edit simultaneously)

Suggested Team Transition Plan​

Week 1-2: Foundation

  • Install Node.js, VS Code, and Playwright on developer machines
  • Complete the Playwright Primer (2-3 hours per person)
  • Set up a Git repository for the test project

Week 3-4: First Tests

  • Convert 3-5 Tosca TestCases from a single Fiori app to Praman tests
  • Set up authentication via setup projects
  • Run tests locally and review the HTML report

Week 5-6: CI Integration

  • Add npx playwright test to your CI/CD pipeline
  • Configure screenshot: 'only-on-failure' and trace: 'on-first-retry'
  • Set up environment variables for SAP credentials in CI secrets

Week 7-8: Scale

  • Convert remaining Tosca TestCases in priority order
  • Adopt Fiori Elements helpers (fe.listReport, fe.objectPage) for standard Fiori apps
  • Enable parallel execution with 2-4 workers

Role Mapping​

Tosca RolePraman Equivalent
Test DesignerTest Engineer (writes .test.ts files)
Test Data ManagerUses testData fixture + .env files
Automation EngineerSame role, now using TypeScript + Playwright
Test ManagerReviews PRs, reads Playwright HTML reports, monitors CI
Tosca AdministratorNot needed (config is in Git, CI handles execution)

Handling Tosca-Specific Patterns​

Recovery Scenarios​

Tosca Recovery Scenarios handle unexpected dialogs or errors. In Praman, use fixture teardown and test.afterEach().

import { test } from 'playwright-praman';

// Automatic recovery: fixtures clean up on teardown
// - flpLocks: deletes stale SM12 locks
// - testData: removes generated test data
// - sapAuth: logs out

// Manual recovery for edge cases
test.afterEach(async ({ ui5 }) => {
// Dismiss any open dialogs
try {
const okButton = await ui5.control({
controlType: 'sap.m.Button',
properties: { text: 'OK' },
searchOpenDialogs: true,
});
await okButton.press();
} catch {
// No dialog open -- nothing to dismiss
}
});

Test Data Parameterization​

Tosca TestCaseDesign provides data-driven testing. In Playwright, use arrays or CSV files.

import { test } from 'playwright-praman';

// Data-driven test (replaces Tosca TCD)
const vendors = [
{ id: '100001', name: 'Vendor A', country: 'US' },
{ id: '100002', name: 'Vendor B', country: 'DE' },
{ id: '100003', name: 'Vendor C', country: 'JP' },
];

for (const vendor of vendors) {
test(`create PO for ${vendor.name}`, async ({ ui5, ui5Navigation }) => {
await ui5Navigation.navigateToApp('PurchaseOrder-create');
await ui5.fill({ id: 'vendorInput' }, vendor.id);
// ... rest of test
});
}

Reusable Modules​

Tosca Modules are reusable test components. In Praman, extract shared logic into helper functions or custom fixtures.

// helpers/po-helpers.ts
import type { UI5Fixture } from 'playwright-praman';

export async function fillPOHeader(
ui5: UI5Fixture,
data: { vendor: string; purchaseOrg: string; companyCode: string },
): Promise<void> {
await ui5.fill({ id: 'vendorInput' }, data.vendor);
await ui5.fill({ id: 'purchOrgInput' }, data.purchaseOrg);
await ui5.fill({ id: 'compCodeInput' }, data.companyCode);
}
// tests/purchase-order.test.ts
import { test } from 'playwright-praman';
import { fillPOHeader } from '../helpers/po-helpers';

test('create PO', async ({ ui5, ui5Navigation }) => {
await ui5Navigation.navigateToApp('PurchaseOrder-create');
await fillPOHeader(ui5, { vendor: '100001', purchaseOrg: '1000', companyCode: '1000' });
// ...
});

Quick Reference Card​

I want to...ToscaPraman
Find a UI5 controlScan / Module with UI5 engineui5.control({ controlType: '...', properties: {...} })
Click a buttonActionMode Input on Button moduleawait ui5.click({ id: 'myBtn' })
Fill a text fieldActionMode Input on Input moduleawait ui5.fill({ id: 'myInput' }, 'value')
Verify a valueActionMode Verifyawait expect(control).toHaveUI5Text('value')
Buffer/read a valueActionMode Bufferconst val = await control.getValue()
Wait for page readyWaitOn / RecoveryAutomatic waitForUI5Stable()
Navigate to appBrowser module + URLawait ui5Navigation.navigateToApp('App-action')
Take screenshotScreenshot stepawait page.screenshot({ path: 'file.png' })
Run in CITosca CI adapter + DEXnpx playwright test in any CI
Parameterize dataTestCaseDesign (TCD)for (const row of data) { test(...) }
Handle errorsRecovery ScenarioFixture teardown + test.afterEach()