Interactive Inspector
The inspect command opens a live SAP application in a headed browser and lets you click any element to see its UI5 control metadata, bindings, and the best ui5=... selector — ready to paste into your test.
Quick Start
npx praman inspect https://my-sap-system.example.com/sap/bc/ui5_ui5/ui2/ushell/shells/abap/FioriLaunchpad.html
This launches a Chromium window, navigates to the URL, injects the Praman bridge, and activates the click-capture overlay. You click elements in the browser and see their metadata in your terminal.
If no URL is given, the inspector falls back to the PRAMAN_BASE_URL environment variable:
PRAMAN_BASE_URL=https://my-sap.example.com npx praman inspect
Authentication
To inspect an app that requires login, pass a Playwright storageState file with the --auth option. This is the same storage state produced by Playwright's auth setup projects:
npx praman inspect https://my-sap-system.example.com --auth .auth/user.json
The file is passed directly to Playwright's browser.newContext({ storageState }), so any valid storage state JSON works — whether generated by a Playwright global setup, exported from the browser, or created manually.
Clicking Elements
When you click an element in the browser, the inspector captures the click (preventing the actual button/link action), resolves the DOM element to its closest UI5 control, and prints a report in the terminal:
━━━ Clicked: sap.m.Button ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ID: __button0--orderCreateBtn
Type: sap.m.Button
Visible: true Enabled: true
Properties:
text = "Create Order"
type = "Emphasized"
icon = "sap-icon://add"
Bindings:
text → {i18n>CREATE_ORDER}
━━━ Selectors (best → worst) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
① ui5=sap.m.Button[text=Create Order]
② ui5=sap.m.Button#orderCreateBtn
③ ui5=sap.m.Button[text=Create Order][type=Emphasized]
Fixture:
await ui5.control({ controlType: 'sap.m.Button', properties: { text: 'Create Order', type: 'Emphasized' } });
Locator:
page.locator("ui5=sap.m.Button[text=Create Order]")
The browser highlights the inspected control with a blue border overlay so you can confirm you clicked the right element. If the clicked element is not a UI5 control, the terminal shows a warning with the HTML tag name instead.
Selector Ranking
The inspector generates multiple selector candidates for each control and ranks them by stability:
| Rank | Strategy | Example | When used |
|---|---|---|---|
| 1 | Key string property | sap.m.Button[text=Save] | First match from: text, title, label, value, placeholder, key |
| 2 | Stable ID | sap.m.Button#orderCreateBtn | ID does not start with __ (i.e. not auto-generated) |
| 3 | Multiple properties | sap.m.Button[text=Create Order][type=Emphasized] | First two non-empty string properties combined |
| 4 | Type-only fallback | sap.m.Button | No unique property or stable ID available |
Keyboard Shortcuts
While the inspector is running, use these keys in the terminal:
| Key | Action |
|---|---|
t | Show the full UI5 control tree (JSON) |
s | Re-print selectors for the last clicked control |
c | Copy the best selector to system clipboard |
f | Copy fixture code to clipboard: await ui5.control({ ... }) |
l | Copy locator code to clipboard: page.locator('ui5=...') |
b | Show binding paths for the last clicked control |
r | Re-inject bridge (use after page navigation or reload) |
h | Show help |
q | Quit the inspector (also Ctrl+C) |
Control Tree View
Press t to dump the full UI5 control tree for the current page as JSON. The tree is produced by createControlTreeScript() with a max depth of 6 and up to 2000 controls:
━━━ Control Tree ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
"id": "shell",
"type": "sap.ushell.ui.Shell",
"children": [
{
"id": "app",
"type": "sap.m.App",
"children": [ ... ]
}
]
}
This is useful for understanding the page structure before writing tests — you can identify which controls exist, their IDs, and their nesting.
Binding Paths
Press b after clicking a control to see its model binding paths:
━━━ Bindings: sap.m.Input ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
value → {/PurchaseOrder/CompanyCode}
placeholder → {i18n>COMPANY_CODE_PLACEHOLDER}
Binding paths are useful when writing assertions — they tell you which OData property or i18n key a field is bound to, and they survive theme changes and language switches.
Command Options
Usage: praman inspect [url] [options]
Options:
--auth <path> Playwright storageState JSON file for authentication
--browser <name> Browser to use: chromium, firefox, webkit (default: chromium)
--timeout <ms> UI5 bootstrap timeout in milliseconds (default: 30000)
--viewport <WxH> Browser viewport size (default: 1920x1080)
-h, --help Display help
Browser Choice
The --browser option selects the Playwright browser engine. Defaults to chromium:
npx praman inspect https://my-sap.example.com --browser firefox
npx praman inspect https://my-sap.example.com --browser webkit
Viewport
The --viewport option accepts a WIDTHxHEIGHT string. Falls back to 1920x1080 if the format is invalid:
npx praman inspect https://my-sap.example.com --viewport 1440x900
Typical Workflow
- Launch:
npx praman inspect https://my-sap.example.com --auth .auth/user.json - Navigate: Use the browser to navigate to the page you want to test (click tiles, follow links)
- Click: Click the first element you want to interact with in your test
- Copy: Press
fto copy the fixture code to clipboard - Paste: Switch to your IDE, paste
await ui5.control({ controlType: 'sap.m.Button', properties: { text: 'Create Order' } })into your test - Repeat: Click the next element, press
f, paste - Tree: Press
tto see the full control tree if you need to understand the page structure - Bindings: Press
bto check binding paths when writing assertions - Quit: Press
qwhen done
After page navigation (clicking a tile, following a link), the bridge may need to be re-injected. Press r to re-inject without restarting the inspector.
Clipboard Support
The c, f, and l keys copy text to your system clipboard using platform-native tools:
| Platform | Tool |
|---|---|
| macOS | pbcopy |
| Windows | clip |
| Linux | xclip or xsel |
If the clipboard tool is not available, the inspector prints the text to the terminal so you can copy it manually.
Comparison with UI5 Diagnostics
SAP UI5 includes a built-in diagnostics tool (press Ctrl+Alt+Shift+S in any UI5 app). Here is how the Praman inspector differs:
| Aspect | UI5 Diagnostics | Praman Inspector |
|---|---|---|
| Output | Raw UI5 metadata (control tree, properties) | Praman selectors ready to paste into tests |
| Selector format | Control IDs (often generated, not test-stable) | ui5=... selectors ranked by stability |
| Clipboard | Manual copy of individual values | Press c/f/l for selector, fixture code, or locator code |
| Bindings | Shown in control detail panel | Shown as property → binding path pairs |
| Auth | Must log in manually in the browser | Reuses Playwright storageState file |
| Availability | Always available (built into UI5 framework) | Requires Praman installed (npx praman inspect) |
The UI5 Diagnostics tool and Praman inspector complement each other. Use UI5 Diagnostics for deep framework debugging (XML views, routing, OData model state). Use Praman inspector for test authoring (finding the right selectors quickly).
How It Works
The inspector builds on existing Praman bridge APIs:
-
Bridge injection (
src/bridge/injection.ts): The sameinjectBridge()function used by the test fixtures injectswindow.__praman_bridgeinto the page. -
Control inspection (
src/bridge/browser-scripts/inspect-control.ts): ThecreateInspectControlScript()function retrieves full metadata (properties, aggregations, bindings) for any control by ID. -
Control tree (
src/bridge/browser-scripts/control-tree.ts): ThecreateControlTreeScript()function serializes the entire UI5 control registry into a hierarchical JSON tree. -
Click overlay: A browser-side IIFE intercepts all clicks, resolves the DOM element to its closest UI5 control using
sap.ui.core.Element.closestTo()(with fallback to registry walk), highlights the element, and sends the control ID back to Node viaconsole.log. -
Selector builder (
src/cli/inspect-commands.ts): ThebuildSelectors()function generates ranked selector candidates from the control metadata — checking key string properties first, then stable IDs, then multi-property combinations.