Lesson 1 of 5
How Fiori renders
18 min
Listen to this lesson
Every SAP Fiori app you automate is an SAPUI5 application running in the browser. That sounds obvious, but it changes how you should find things on the screen. In SAP GUI you address fields by their screen element IDs. On a plain web page you might reach for CSS selectors or XPath. In a UI5 app, neither the raw HTML nor its generated IDs are the real model of the screen. The real model is the UI5 control tree, and automation that speaks to controls lasts far longer than automation that speaks to HTML.
Controls, views and the rendered HTML
A UI5 app is built from controls: a sap.m.Button, a sap.m.Input, a sap.m.Table, a sap.ui.comp.smartfilterbar.SmartFilterBar and so on. Controls are arranged in views (usually XML views), and views live inside a component, which is what the launchpad starts when a user clicks a tile. Each control has properties (text, value, enabled), aggregations (the rows of a table, the items of a list) and bindings to the OData model. When the control renders, UI5 writes HTML into the page. One control can produce many nested HTML elements, and that HTML is an implementation detail the control is free to change between UI5 versions.
Generated IDs versus stable IDs
If a developer does not give a control an ID, UI5 generates one at runtime. SAP's ID handling guide shows examples like __page0 and __table0, and notes that two views without IDs become __view0 and __view1 depending on which one opened first. These generated IDs change whenever the control structure of the app changes, so a script that clicks __button7 can start clicking a different button after a harmless enhancement. The UI5 Test Recorder documentation says it plainly: unstable IDs start with a double underscore and are not suitable for tests.
A stable ID is one the developer sets in the control's id attribute. At runtime UI5 concatenates it with the component and view IDs. SAP's guide gives the pattern: a button myButton in view mainView inside component myApp becomes myApp---mainView--myButton, with three hyphens after the component and two after the view. Know the pattern so you can read IDs in a log, but SAP also warns not to rely on the exact prefix syntax because it may change. That is one more reason to locate controls through UI5 APIs rather than by building DOM ID strings yourself.
| Locator style | Example | What breaks it | Verdict |
|---|---|---|---|
| Generated DOM ID | __button7 | Any change in control creation order, a new field, a UI5 upgrade | Never use |
| XPath / CSS over HTML | third div inside the toolbar | Theme change, renderer change, responsive layout, new UI5 version | Last resort only |
| Stable control ID | view orderList, ID createButton | A developer renaming or deleting the control | Preferred for custom apps |
| Control type plus property or binding | sap.m.Button with text from the i18n key for Create | Text or binding path change; ambiguous if several match | Good fallback, keep it specific |
Control selectors
UI5 ships an API for exactly this problem. The sap.ui.test.RecordReplay module, described in its own source as the record-and-replay implementation for OPA5, defines a control selector: a small JSON object that identifies one control by combinations of id, viewName, controlType, bindingPath, I18NText, labelFor and properties. RecordReplay can turn a selector into the right DOM element at runtime and can wait until UI5 has finished its asynchronous work before you interact. Browser-driving frameworks that are UI5-aware build on this idea. Whatever tool your team uses, ask whether it can locate UI5 controls by selector; if it can only see HTML, you will spend your life repairing locators.
Freestyle apps versus SAP Fiori elements
Most SAP-delivered S/4HANA apps are built with SAP Fiori elements: the list report, object page and other floorplans are generated from OData annotations and the app manifest. You do not control their IDs, but the framework assigns IDs systematically, so they tend to be consistent across loads. Custom apps written by your developers are often freestyle UI5, where stability depends entirely on whether developers set IDs. Treat the two differently: for Fiori elements apps, prefer selectors built from control type, labels and binding paths and confirm them after each upgrade; for custom apps, agree stable IDs with the developers (lesson 5).
What would you do?
Kenji's team has delivered a custom freestyle app, Manage Core Returns, built over the custom core return agreements table that the conversion carried over from ECC. An automation engineer finds that the Approve button has the ID <code>__button12</code>. What should happen next?
- Fiori apps are UI5 control trees; the HTML is an output detail that changes with versions and themes.
- IDs starting with a double underscore are generated and unstable; never build tests on them.
- Stable IDs are prefixed by component and view IDs at runtime; read the pattern, but use UI5 APIs rather than building ID strings.
- Control selectors (ID and view name, control type, binding path, i18n text, properties) are the stable way to find controls.
Check your understanding · not graded
Lesson check
1. A control on a Fiori screen has the ID __input3. What does that tell an automation engineer?
2. What does a UI5 control selector identify a control by?
3. Why should automation avoid locators built on the rendered HTML of a UI5 control?
4. Which kind of app most depends on developers setting IDs for stable automation?