EDUCAÇÃO E TECNOLOGIA

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.

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.

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.

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();

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>);

No support for suffixes

Unlike UIVeri5 or OPA, the suffix clause in the control locator is not supported and any interaction will target the root element of the control. This is problematic with controls that 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. This approach should be used wisely as it adds inherent dependency on the control internal structure that could change.

var search = browser.asControl({ selector: {    <control selector>    }
});
search.getWebElement().$('input[type=search]').setValue('<something>');

No concept of element lists

WDI5 does not support the concept of element lists ($$ in WDIO or element.all() in UIVeri5) so you can’t select a list of elements using control locator. A workaround is to find the root element, like the sap.m.List itself and get its aggregation with getItems(). Then you can filter the list with code and work with specific control.

Hard to recognise the common “Element not found” error

It is hard 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. 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.

No support for WDIO built in waiting

Technically, WDI5 simply adds the byControl() method to the browser instance. But WDI5 does not implement a WDIO custom selector strategy (browser.custom$()) and so the control locator is not included in the build in WDIO waiting that happens before interaction or assertion. This also means that, if necessary you should change the default timeout for WDI5 in its configuration instead of the default waitforTimeout.

Overall, WDIO + WDI5 is a very good choice for E2E testing of UI5 apps. It gives excellent TCO both in terms of ease of writing test as well as as reliable execution with minimum flakiness. There are certain limitations but when known, they could be easily mitigated.

Introduction of WDI5 on blogs.sap.com

Introduction of WDI at UI5Con 2020

WDI5 on github.com