TL;DR: All is better now. Don’t bother if you use an older version of WDI5 and you don’t want to update. Use wdi5
as before for hybrid app testing, but check out wdio5-ui5-service npm module
if you test a browser-only app. wdio-ui5-service
is also officially listed as a Webdriver.IO-service: https://webdriver.io/docs/docs/wdio-ui5-service.html ????
In this blog I am going to describe how we derived two wdio testrunner services from the existing wdi5
framework, resulting in wdio-ui5-service
(https://www.npmjs.com/package/wdio-ui5-service) and wdi5
(https://www.npmjs.com/package/wdi5).
Why the effort?
After the success of the previously released version we wanted to have WDI5 available not just for hybrid mobile application testing but rather for all UI5 applications. Hence we noticed the necessity to separate the UI5 part from the hybrid part of the framework.
Goal
Full independence from the wdi5
“hybrid testing package” with full compatibility to wdio
for UI5 browser application testing.
What needed to be done?
- The WDI5 monolith needed to be split up. Now the GIT repository has three folders (
wdi5
,wdio-ui5-service
,test
) in root location. As the names suggest,wdi5
contains the hybrid testing tool,wdio-ui5-service
the Webdriver.IO-plugin andtest
the tests for both (b/cwdi5
tests itself withwdi5
, yeah ????) - Implement an interface so
wdi5
can reliably dependend onwdio-ui5-service
- Restructure all code to support the
wdio
service handling with hooks.
Result
To clarify the confusion: There are 2 (in words: two, dos, deux, zwei) Node.js-modules being built from one git repository:
wdio-ui5-service
: the Webdriver.IO-plugin
it is independent from wdi5
and doesn’t have any other module dependencies
wdi5
: the hybrid UI5-app test module
wdio-ui5-service
is required by wdi5
for runtime, meaning you can drive both the browser- and the hybrid-app with wdi5
.
Plus: wdi5 is fully backwards-compatible to previous versions.
i Note that usually we refer to both when we’re using the term wdi5
. If one of the two modules is explicitly referred to, we try to use the corresponding term
We’re providing extensive documentation for installation and configuration of both wdio-ui5-service
and wdi5
over at https://github.com/js-soft/wdi5/blob/develop/wdio-ui5-service/README.md and https://github.com/js-soft/wdi5/blob/develop/wdi5/README.md.
Note that the usage of both is code-agnostic. Meaning, you’re writing the same syntax and tests no matter whether they run via wdio-ui5-service
in the browser-scope or via wdi5
in the app-scope!
There’s a “main” README detailing all the usage and test-options you have code-wise.
const listItems = browser.asControl(selector).getAggregation('items')
listItems.forEach((listItem) => {
expect(listItem.getTitle()).not.toBe('')
})
getting-started quickly
wdi5
: installation
npm i wdi5 -d
wid5
: configuration
// in wdio.conf.js
const wdi5 = require('wdi5')
...
services: [
[wdi5]
]
...
The wdi5
module provides all capabilities of wdio-ui5-service
– no need for a separate install.
wdio-ui5-service
: installation
npm i wdio-ui5-service -d
This package is a 100% dependency free library to span the bridge from wdio
to UI5. It is required to add all further dependencies by yourself.
wdio-ui5-service
: configuration
...
services: [
"ui5" // yes, that's it!
]
...
Usage
All WDI5 functionality is attached to the global browser
object Webdriver.IO provides. To stay API-compliant with UIveri5, we decided to introduce .asControl()
as the very first entry point to interacting with a UI5 control:
browser.asControl(<selector>)
a
<selector>
is also API-compliant with OPA5 as it refers to an object containing the attributes of the desired UI5 control, such as id
or controlType
:
const selector = {
id: "NavigationButton",
controlType: "sap.m.Button"
}
asControl()
returns the located UI5 control and can then be worked on:
const selector = {
id: "NavigationButton",
controlType: "sap.m.Button"
}
const button = browser.asControl(selector)
const text = button.getText()
expect(text).toBe("next")
// ...
As you might have noticed, wdi5
inherits sync coding ability from Webdriver.IO, so no need to go async notation-wise:
// ⚡️ ⛔️ no need for this:
browser.asControl(selector)
.then((control) => {
//...
})
.catch(...)
//⚡️ ⛔️ ... or this
let button
try {
button = await browser.asControl(selector)
} catch(err) { ... }
// just pretend as if asnyc's not there ???? - we've got ya ????
browser.asControl(selector).setText("bla").setEnabled(true)
Note that consequently, all non-control actions are also triggered via browser
:
browser.screenshot('some-id') // yes, we can do screenshots anywhere :)
browser.goTo({sHash: '#/route'});
Improvements
No manual wdio
hook implementation required anymore to setup wdi5
-> starting the tests is even more easy. Literally just three LOC.
Testing of standalone UI5 web-apps using the new wdio-ui5-service
module without dependencies
-> separation of concerns having two modules, faster dev cycles
Contributions
… welcome!
Note that we have just started a document for that containing a wishlist for wdi5
features =)