ui5-community / wdi5

official UI5 end-to-end test framework for UI5 web-apps. wdi5 = Webdriver.IO + UI5 Test API
https://ui5-community.github.io/wdi5/
Apache License 2.0
102 stars 43 forks source link

Error thrown for complex UI5 Id #118

Closed nair-sumesh closed 2 years ago

nair-sumesh commented 2 years ago

Hi,

Some of the elements of the UI5 have complex id naming schema (separated with '.', '::',, '-','--'.) For such elements, I received below cryptic error. I am not sure how to read this error.

Error

[chrome 97.0.4692.71 windows #0-0] invalid selector: An invalid or illegal selector was specified
  (Session info: chrome=97.0.4692.71)
[chrome 97.0.4692.71 windows #0-0] Backtrace:
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x00316903+2517251]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002AF8E1+2095329]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B2848+1058888]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B4F44+1068868]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B4E0E+1068558]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B5070+1069168]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001DD1C2+1233346]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001DD63B+1234491]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x00207812+1406994]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001F650A+1336586]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x00205BBF+1399743]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001F639B+1336219]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001D27A7+1189799]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001D3609+1193481]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x004A5904+1577972]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x00550B97+2279047]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x003A6D09+534521]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x003A5DB9+530601]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002B4FF9+2117625]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002B98A8+2136232]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002B99E2+2136546]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002C3541+2176321]
[chrome 97.0.4692.71 windows #0-0]      BaseThreadInitThunk [0x774DFA29+25]
[chrome 97.0.4692.71 windows #0-0]      RtlGetAppContainerNamedObjectPath [0x77627A9E+286]
[chrome 97.0.4692.71 windows #0-0]      RtlGetAppContainerNamedObjectPath [0x77627A6E+238]
[chrome 97.0.4692.71 windows #0-0]      (No symbol) [0x00000000]
[chrome 97.0.4692.71 windows #0-0]

The Code

let oTableTitle = await browser.asControl({
            selector: {
                id: "xxxxxxxx.view::sap.suite.ui.generic.template.ListReport.view.ListReport::xMMMMMM--listReport-header"
            }
        });
let sTitle = await oTableTitle.getText();

Note:

using WDIO works with below code

const oTableTitle = $(`//*[contains(@id, "xMMMMMM--listReport-header-inner")]`) // wdio-native

However, when same done on WDI5 (i.e. appending -inner at the end of the id), gives an error

Error: [wdi5]call of _getControl() failed because of: Error: No DOM element found using the control selector {"id":{}}

code

 let oTableTitle = await browser.asControl({
            selector: {
                id: /xMMMMMM--listReport-header-inner$/
            }
        });
let sTitle = await oTableTitle.getText();
dominikfeininger commented 2 years ago

Hi, assuming your first code example successfully returns an UI5 control. I suggest to check if the -inner element is actually a UI5 control. Usually they are not.

nair-sumesh commented 2 years ago

Hi, assuming your first code example successfully returns an UI5 control. I suggest to check if the -inner None of the code ( I tried different permutations and combinations), returned a UI5 control.

What working for me is the native WDIO code ( which I believe is not UI5 control as such, its just a DOM element ).

vobu commented 2 years ago

Hi, assuming your first code example successfully returns an UI5 control. I suggest to check if the -inner None of the code ( I tried different permutations and combinations), returned a UI5 control.

What working for me is the native WDIO code ( which I believe is not UI5 control as such, its just a DOM element ).

yep, that's right. and given that, even when you could retrieve it in wdi5, what could you do with a non-UI5 element 😄 ? you're obviously trying to work with wdi5 on a FE app. we haven't really looked at how to cope from a wdi5-perspective with these auto-generated IDs. technically it doesn't make a difference, as visible UI5 elements in a view are selectable by wdi5. but from a best-practice POV, this is interesting. so i put in on the (hopefully soon public) roadmap and we'll get to it as part of the ongoing documentation effort. ok for you?

nair-sumesh commented 2 years ago

Ok for me, however almost all my apps are either FE or an hybrid, therefore, WDI5 will not be helpful until support for FE is not available.
I will wait till the feature is available.

WDI5 works for OVP FE apps. I was able to select a card header.

vobu commented 2 years ago

Ok for me, however almost all my apps are either FE or an hybrid, therefore, WDI5 will not be helpful until support for FE is not available. I will wait till the feature is available.

well, as i mentioned previously, there‘s no technical reason for wdi5 not to work with FE apps. it‘s just that we have no „recipe“ in the docs for it yet. following your selector attempt, loose the inner part of the id and properly aim for a valid UI5 control id and you should be good to go.

await browser.asControl({
  selector: {
    id: /xMMMMMM--some-table-id$/
  }
}).getTitle()

WDI5 works for OVP FE apps. I was able to select a card header.

proves my point above :)

norbip commented 2 years ago

for me it seems to fail anyhow I try to locate a button with a similar ID structure (with dots and colons as in an FE apps usually).

wdi5 finds the control via partial ID/escaped ID/other descriptors, but then wdio gets a findElement command (by wdi5 or not sure how) which fails:

[0-0] 2022-01-26T11:56:23.182Z INFO webdriver: COMMAND findElement("css selector", "#****::LineItem::StandardAction::Create")
[0-0] 2022-01-26T11:56:23.183Z INFO webdriver: [POST] http://localhost:9515/session/cea5d22fbef2fb97044672e9a6d7d1d5/element
[0-0] 2022-01-26T11:56:23.183Z INFO webdriver: DATA {
[0-0]   using: 'css selector',
[0-0]   value: '#****::LineItem::StandardAction::Create'
[0-0] }
[0-0] 2022-01-26T11:56:23.201Z DEBUG webdriver: request failed due to response error: invalid selector

with all of these locators:

browser.asControl({selector:{controlType: 'sap.m.Button', id: '***::LineItem::StandardAction::Create'}})
browser.asControl({selector:{controlType: 'sap.m.Button', properties: { text: 'Create' }}})
browser.asControl({selector:{controlType: 'sap.m.Button', id: /Create/}})

may help why OVP works: OVP does not use colons in generated IDs only hypens and dots which seem to be fine

vobu commented 2 years ago

may help why OVP works: OVP does not use colons in generated IDs only hypens and dots which seem to be fine

interesting. i'll flag this issue accordingly as enhancement.

btw: your regex selector...

browser.asControl({selector:{controlType: 'sap.m.Button', properties: { text: 'Create' }}})
browser.asControl({selector:{controlType: 'sap.m.Button', id: /Create/}})

...will never match the partial id string :LineItem::StandardAction::Create. this one should:

browser.asControl({selector:{controlType: 'sap.m.Button', id: /.*Create$/}})
nair-sumesh commented 2 years ago

Ok for me, however almost all my apps are either FE or an hybrid, therefore, WDI5 will not be helpful until support for FE is not available. I will wait till the feature is available.

well, as i mentioned previously, there‘s no technical reason for wdi5 not to work with FE apps. it‘s just that we have no „recipe“ in the docs for it yet. following your selector attempt, loose the inner part of the id and properly aim for a valid UI5 control id and you should be good to go.

await browser.asControl({
  selector: {
    id: /xMMMMMM--some-table-id$/
  }
}).getTitle()

WDI5 works for OVP FE apps. I was able to select a card header.

proves my point above :)

Loosing the inner part did not work

dominikfeininger commented 2 years ago

Error is thrown after retrieving the UI5 element when the webdriver representation is loaded additionally.

https://github.com/js-soft/wdi5/blob/dfd98bd1fd15e9774a7e8ed35c222b35252a68d7/wdio-ui5-service/src/lib/WDI5.js#L638

anyways ID is not supported see: https://webdriver.io/docs/selectors/#id-attribute

@vobu I suggest to investigate if we can switch to xPath webdriver selector

Testcase prepared: https://github.com/js-soft/wdi5/commit/33d5d3ffced1bc87b18754be3e90a15fe36388dd

vobu commented 2 years ago

let's look into sap.fe.test from https://sapui5.hana.ondemand.com/#/api/sap.fe.test - dev tutorial over at https://developers.sap.com/group.fiori-elements-mockserver-opa.html as aligned with the SAP colleagues, integration the "testing library" is worthwhile feat :)

dominikfeininger commented 2 years ago

TODO: @dominikfeininger add selector structure validation

dominikfeininger commented 2 years ago

https://github.com/js-soft/wdi5/pull/159

vobu commented 2 years ago

manual selection of a FE control is now possible with wdi5 0.9.x since #159 went in