Technical Articles
Use WDIO and WDI5 for testing UI5 apps
WDIO is a hugely popular E2E testing framework for Web Applications. This also includes hybrid apps. It can drive a real browser and simulate a user interacting with the app. WDIO can work with app that use any web framework but there are certain advantages if the testing framework integrates with the web framework. If this is the case, the tests could be much simpler to write and mainly, much more reliable. Reliability is of paramount importance for E2E tests that typically struggle with flakiness so any improvement can have significant effect on the TCO of testing process.
Why WDIO
WDIO is a de-facto standard for browser testing in the JavaScript world. Of course there are few more frameworks in the E2E testing space, notably Cypress but WDIO is the most widely-used and advanced one. One of the biggest advantages of WDIO is that it is a real, active open-source project with passionate developers and a vibrant community. WDIO is not associated with particular frontend technology or company and as this may seems like a limitation, it is actually a big advantage as WDIO is more future-proof as there is no single backer for the continued development. WDIO provides many advanced features in its core, like parallelisation and many, many more over the extensive plugin library. There are many reporters like JUnit, HTLM with screenshots, several runners – local/remote WebDriver, Appium, Puppeteer, browser cloud providers like SauceLabs, BrowserStack and many more.
Why WDI5
WDIO can work with any web application but lacks the awareness of the web framework that the application uses. WDI5, which is a WDIO plugin, bridges this gap and provides two key benefits, namely control locators and synchronisation with the web framework. WDIO supports many types of locators – css, xpath, even plain javascript code but it lacks understanding of the UI5 controls. WDI5 exposes a browser.byControl() method that accepts a control locator and returns a proxy for the real control. Then the test can assert on the control state or even interact with the control. The second benefit is transparent but equally important – on every element interaction, WDI5 waits for UI5 rendering to complete and for the application to be completely stable. This is similar to the build-in waiting in WDIO but is much more powerful because of the framework awareness. Similarly to Cypress and Protractor, WDI5 will wait for all XHR calls, all ongoing processing, all promises to complete and just then will return the control proxy. Both of those features greatly improve the reliability and simplify the creation and maintenance of E2E tests.
Getting started
Setting up a new test project with WDIO is very easy. You can use the popular console-based wizard that will configure all necessary dependencies.
$> npm i --save-dev @wdio/cli $> npx wdio config
Then you only need to add the WDI5 dependency to package.json and declare the ‘wdi5’ service in wdio.conf.js.
Another option is to use the WDI5 yeoman generator that is part of the popular yeoman runner easy-ui5.
Locating elements
WDI5 supports the control locators, also known as declarative matchers from OPA5. Actually, WDI5 uses UI5 public APIs to delegate finding the control to OPA5 code that works in UI5 runtime.
var search = browser.asControl({ selector: { id: 'searchField', viewName: 'sap.ui.demo.cart.view.Home', } });
You can use all declarative control selectors.
Interactions
WDIO, similarly to Selenium controls the browser over the WebDriver protocol. Using it, the test can query the state of the DOM page but also can interact with the page and with the application behind it.
Native events
WDIO encapsulates the WebDriver protocol and expose the click() and setValue() methods that the test can use. When the test calls them, the WebDriver, together with the browser generate the complete browser native event trail that correspond to the specific request. In practice the application can’t (easily) recognise if an interaction was done by a real user or from test over the WebDriver protocol.
To use native events, the test must resolve the root DOM element from the control proxy and call click() or setValue().
var button = browser.asControl({ selector: { <control selector> } }); button.getWebElement().click();
Control events
WDI5 exposes the complete control API and this includes fireEvent() method, as well as all overrides like firePress(). So the test can call them and simulate the control firing an custom event. Generally, this should be as good as native events but depending on the control and how it keeps the internal state, there could be some glitches.
var button = browser.asControl({ selector: { <control selector> } }); button.firePress();
Assertions
WDIO comes with a built in assertion library that works on the DOM level. You can use all assertions by resolving the root DOM element of the control using getWebElement() method of the control proxy.
var button = browser.asControl({ selector:{ <control selector> } }); expect(button.getWebElement().isDisplayed()).toBeTruthy();
Alternatively, you can use the control proxy getters and assert on any control property.
var header = browser.asControl({ selector: { <control selector> } }); expect(header.getTitle()).toBe(‘<something>’);
All control properties are available, including aggregations.
var list = browser.asControl({ selector: { <control selector> }, }); expect(list.getItems(true).length).toBe(<count>);
Test Recorder
WDI5 declarative locator syntax fully match the OPA control locators, actually under the hood WDI uses the public UI5 APIs so you can utilize the full power of UI5 Test Recorder. If you haven’t used it, under this bold name you can find a snippet generator that can build the best possible control locator by just right-clicking the UI5 control on screen. The test recorder applies a battle-hardened algorithm that traverse the control tree and builds the best possible control locator for the given control. Of course, as will all machine processing, there could be further context that is not considered in the building process but generally the resolved locator is a very good base to start with. Then you can copy it in your test code and edit it manually if necessary.
The test recorder can also encapsulate the generated locator in a skeleton of a PageObject method and so help you structure your test code. Currently only OPA and UIVeri5 dialects formatting is available but hopefully we will see support for WDI5 also.
Tips & Tricks
How to interact with multi-input controls
Unlike UIVeri5 or OPA, the suffix clause in the control locator is not supported (yet) and any interaction will target the root element of the control. Some controls may have have several interaction points like sap.m.SearchField that accepts both text in the input as well as mouse clicks on search and reset icons. One way to overcome this is to chain a second $(“<css locator>) that targets the necessary element. Like $(‘input[type=search]”) for the input field in the sap.m.SearchField. You can see the respective suffix in the DOM elements tree.
var search = browser.asControl({ selector: { <control selector> } }); search.getWebElement().$('input[type=search]').setValue('<something>');
How to interact with element lists
Element lists ($$ in WDIO or element.all() in UIVeri5) need to be handled in code. So you must find the root control using control locator, like the sap.m.List itself and get its aggregation with getItems(). Then you can filter the list and work with specific control.
How to recognise the common “Element not found” error
Sometimes it is tricky to recognise that an element is not found with byControl() call. There is an explicit error message that says it and even mentions the control selector but it is easy to miss it as it is not coloured as error. So typically, the first error you would recognise is “TypeError: Cannot read property … of null” that happens on the first use of the unresolved WDI5 proxy object. Then just look up the console log and you would see the root cause and the control selector that was used.
Conclusion
WDIO + WDI5 is an excellent choice for E2E testing of UI5 apps. It provides a great TCO both in terms of ease of writing test as well as as reliable execution with minimum flakiness. It also fits nicely in the UI5 ecosystem and so you can benefit from all the innovation that comes with it.
References
Introduction of WDI5 on blogs.sap.com
What is the pros/cons compared to the ui-verifi5 ? If you are starting open ui5 project today, what will be the 2e testing framework that you will choose ?
🙂
Looks like "UIVeri5 is deprecated and won’t be developed any further"
https://github.com/SAP/ui5-uiveri5
if you want to give
wdi5
a shot (which you should 😁), please be aware that since the publication of this blog post, we've switched to async notation style:const control = await browser.asControl(selector)
Newly introduced with the async notation style was the fluent async api:
const listItemTitle = await browser.asControl(selector).getItems(5).getTitle()
it allows chaining multiple calls on the retrieved control, similar to the old sync style notation.
more details: https://github.com/js-soft/wdi5#fluent-async-api
Hi Volker,
actually my article and the show syntax is STILL correct as you have not published the 0.8.2 release on npmjs. Once you do it, I will be glad to fix the code snippets.
online since 3 days.
but the async style notation support incl fluent async api was already there since 0.8.0, published Jan 17th.
Ahh, this wdi5 vs wdio-ui5-service mess, the wdi5 package is still on 0.7 in npmjs and made me think you did not release yet.
will, it's not a mess, since they are 2 different packages:
wdi5
→ hybrid app testing,wdio-ui5-service
→ browser-scope testing.still might be confusing at first look.
but this will end soon™ 😁
Hello Volker,
Request to please provide the step by step the document for using SAP BAS with SAP UI5 application testing.
Thanks,
Pragnesh
The SAP BAS colleagues haven't added wdi5 support yet, see https://github.com/ui5-community/wdi5/issues/329 and https://influence.sap.com/sap/ino/#/idea/287947
Best, V.
We created a lot of tests using uiveri5 to test our Fiori apps.
After changing to the SAP Universal ID we were not longer able to run through the login procedure when showing the Google Captchas.
(see https://github.com/SAP/ui5-uiveri5/issues/374)
Exists here in WDI5 a solution for the login procedure?
there are authentication capabilities in wdi5 (https://ui5-community.github.io/wdi5/#/authentication), but they don't cater towards Google Captchas. Having said that, I find it strange that a Google Captcha should appear in a SAP uid login process? I recall seeing regular captchas, but not Google owned ones. Are you sure there isn't a custom IdP involved?
Then again it should be a configuration option in the login procedure on the IdP side to not require Captchas.
Thank you very much for the reply. In the meantime we have solved the problem.
Originally we used the SAP "Default identity provider" in our subaccounts.
The login is done via SAP Universal ID and is secured against bots with Google reCaptcha. This IDP is available by default as soon as a new subaccount is created. However, since we have almost no configuration options for this, we now use our own Identity Authentication Service (IAS) / Identity Provider (IDP) tenant. With this we have the option to disable the use of Google's reCaptcha and thus enable the bot accesses, which is similar to the uiveri5 tests.
Hello Maxim,
I am created UI5 application in SAP BAS then add the init wdi5 then running using npm run wdi5 then below error are come up. Please help me on the below issue.
SevereServiceError in "onPrepare"
SevereServiceError:
A service failed in the 'onPrepare' hook
SevereServiceError: Couldn't start Chromedriver: timeout
Chromedriver failed to start.
at ChromeDriverLauncher.onPrepare (/home/user/projects/finaljs/node_modules/wdio-chromedriver-service/build/launcher.js:106:13)
at async /home/user/projects/finaljs/node_modules/@wdio/cli/build/utils.js:38:17
at async Promise.all (index 0)
at async Launcher.run (/home/user/projects/finaljs/node_modules/@wdio/cli/build/launcher.js:86:13)
Thanks,
Pragnesh
The SAP BAS colleagues haven't added wdi5 support yet, see https://github.com/ui5-community/wdi5/issues/329 and https://influence.sap.com/sap/ino/#/idea/287947
Best, V.