appium: isDisplayed and getAttribute always raise exception in W3C mode
The problem
client: selenium-java library, v3.8.1 and 3.14.0 (latest) connection to appium: direct or via grid-hub (reault is same) Appium version: 1.9.1, Communication protocol: W3C (does not reproduced on JSonWire mode from java-client side)
When I call element.isDisplayed() or element.getAttribute() I always get exception. Arrors are: “Original error: Argument to isShown must be of type Element (for isPresent)” Original error: a.getAttributeNode is not a function. (In ‘a.getAttributeNode(b)’, ‘a.getAttributeNode’ is undefined) for getAttribute.
After digging I find:
-
java-client and appium use W3C protocol for communication
-
selenium java client use atoms to emulate both those commands: isDisplayed.js and getAttribute.js (see W3CHttpCommandCodec). This cause issue on appiums side (actually atoms returns errors which then proxied to appium and client.
Then I tried to invoke endpoint “/session/{session id}/element/{element id}/displayed” directly (actually from browser address bar). In that case request was finished without any exception and returns “true”.
So in other words: when atom is sent by java-client for execution - we have Exception when atom invoked by appium - all is OK selenium-java has only 2commands which are exacuted via atoms and both them failed on appium side
I think appium-java client will have the same issue because it reuse W3CHttpCommandCodec from appium-java.
Other notes: (maybe they will help to localize issue)
- when java-client sends atom for execution it encodes web-element as json with 1 field only
{"element-6066-11e4-a52e-4f735466cecf": "5000"}
Which is different from executeScript() where there are 2 fields:{"element-6066-11e4-a52e-4f735466cecf": "5000", "ELEMENT": "5000"}
- selenium-java wraps atom function to:
return(<atom-function>).apply(null, arguments);
before isending over http, See here - As I can see from appium log (after ‘Sending javascript command")’ atom which was sent from java-client is wrapped by some function by appium. While atoms which are invoked bу appium are sent without additional wrapping.
Environment
- Appium version (or git revision) that exhibits the issue: 1.9.0
- Last Appium version that did not exhibit the issue (if applicable):
- Desktop OS/version used to run Appium: MacOS hight sierra
- Node.js version (unless using Appium.app|exe):
- Mobile platform/version under test: iOS 11.3, 11.4
- Real device or emulator/simulator: sim
- Appium CLI or Appium.app|exe: cli
Code To Reproduce Issue [ Good To Have ]
@Test public void isDisplayedTest() {
WebDriver wd = RemoteWebDriver
.builder() // requires web-driver v3.14
.url("http://ta-mac-01:4724/wd/hub")
.setCapability("platformName", "iOS")
.setCapability("browserName", "safari")
.setCapability("appium:automationName", "XCUITest")
.setCapability("appium:platformVersion", "11.4")
.setCapability("appium:deviceName", "iPhone 7")
.build();
wd.get("http://the-internet.herokuapp.com/");
WebElement title = wd.findElement(By.cssSelector("h1"));
// raise error: Original error: Argument to isShown must be of type Element
System.out.println(title.isDisplayed());
wd.quit();
}
Logs
https://gist.github.com/kool79/3c51849b098788f9036b78a0a7966e22
Here logs for isDisplayed with W3C protocol (failled), isDisplayed with JSonWire protocol and for executeScript command (just for refrence)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (7 by maintainers)
Update: after HUGE amount of tries found that everything is working fine for windows dektop version 1.2.7
@dpgraham
Hello, also having this issue, checked on pre-release
System.InvalidOperationException: An unknown server-side error occurred while processing the command. Original error: unknown error: a.getAttributeNode is not a function (Session info: chrome=69.0.3497.100) (Driver info: chromedriver=2.44.609538 (b655c5a60b0b544917107a59d4153d4bf78e1b90),platform=Windows NT 10.0.17134 x86_64)
Part of Appium logs below:
[W3C (1ae0f4cd)] Driver proxy active, passing request on via HTTP proxy [JSONWP Proxy] Matched ‘/wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/timeouts’ to command name ‘timeouts’ [Protocol Converter] Will send the following request bodies to /timeouts: [{“type”:“implicit”,“ms”:20000}] [JSONWP Proxy] Proxying [POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/timeouts] to [POST http://127.0.0.1:8000/wd/hub/session/85f3fd7612db735f7fc243113dbb6b4e/timeouts] with body: {“type”:“implicit”,“ms”:20000} [JSONWP Proxy] Got response with status 200: {“sessionId”:“85f3fd7612db735f7fc243113dbb6b4e”,“status”:0,“value”:null} [JSONWP Proxy] Replacing sessionId 85f3fd7612db735f7fc243113dbb6b4e with 1ae0f4cd-f3f5-4398-98e4-b13e63d29b94 [HTTP] <-- POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/timeouts 200 3 ms - 76 [HTTP] [HTTP] --> POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/element [HTTP] {“using”:“css selector”,“value”:“#ctrlLogin\$UserName”} [W3C (1ae0f4cd)] Driver proxy active, passing request on via HTTP proxy [JSONWP Proxy] Matched ‘/wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/element’ to command name ‘findElement’ [JSONWP Proxy] Proxying [POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/element] to [POST http://127.0.0.1:8000/wd/hub/session/85f3fd7612db735f7fc243113dbb6b4e/element] with body: {“using”:“css selector”,“value”:“#ctrlLogin\$UserName”} [JSONWP Proxy] Got response with status 200: {“sessionId”:“85f3fd7612db735f7fc243113dbb6b4e”,“status”:0,“value”:{“ELEMENT”:“0.2803925612846576-1”}} [JSONWP Proxy] Replacing sessionId 85f3fd7612db735f7fc243113dbb6b4e with 1ae0f4cd-f3f5-4398-98e4-b13e63d29b94 [HTTP] <-- POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/element 200 29 ms - 106 [HTTP] [HTTP] --> POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute/sync [HTTP] {“script”:"return (function(){return function(){var aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){if(b.get||b.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[c]=b.value)},ba="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global?global:this;\nfunction e(a,c){if©{for(var b=ba,d=a.split("."),f=0;fa||1342177279>>=1)b+=b;return d}});e("Math.sign",function(a){return a?a:function(a){a=Number(a);return!a||isNaN(a)?a:0 [W3C (1ae0f4cd)] Driver proxy active, passing request on via HTTP proxy [JSONWP Proxy] Matched ‘/wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute/sync’ to command name ‘execute’ [Protocol Converter] Rewrote the original URL ‘/wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute/sync’ to ‘/wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute’ for MJSONWP protocol [JSONWP Proxy] Proxying [POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute] to [POST http://127.0.0.1:8000/wd/hub/session/85f3fd7612db735f7fc243113dbb6b4e/execute] with body: {“script”:"return (function(){return function(){var aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){if(b.get||b.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[c]=b.value)},ba="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global?global:this;\nfunction e(a,c){if©{for(var b=ba,d=a.split("."),f=0;fa||1342177279>>=1)b+=b;return d}});e("Math.sign",function(a){return a?a:function(a){a=Number(a);return!a||isNaN(a)?a:0 [JSONWP Proxy] Got response with status 200: {“sessionId”:“85f3fd7612db735f7fc243113dbb6b4e”,“status”:13,“value”:{“message”:“unknown error: a.getAttributeNode is not a function\n (Session info: chrome=69.0.3497.100)\n (Driver info: chromedriver=2.44.609538 (b655c5a60b0b544917107a59d4153d4bf78e1b90),platform=Windows NT 10.0.17134 x86_64)”}} [JSONWP Proxy] Got an unexpected response: {“sessionId”:“85f3fd7612db735f7fc243113dbb6b4e”,“status”:13,“value”:{“message”:“unknown error: a.getAttributeNode is not a function\n (Session info: chrome=69.0.3497.100)\n (Driver info: chromedriver=2.44.609538 (b655c5a60b0b544917107a59d4153d4bf78e1b90),platform=Windows NT 10.0.17134 x86_64)”}} [W3C (1ae0f4cd)] Encountered internal error running command: ProxyRequestError: Could not proxy command to remote server. Original error: The request to /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute has failed [W3C (1ae0f4cd)] at JWProxy.proxy (C:\Users\Dmitry_Leontiev\AppData\Local\Programs\Appium\resources\app\node_modules\appium-base-driver\lib\jsonwp-proxy\proxy.js:180:13) [MJSONWP] Matched JSONWP error code 13 to UnknownError [HTTP] <-- POST /wd/hub/session/1ae0f4cd-f3f5-4398-98e4-b13e63d29b94/execute/sync 500 26 ms - 1213
Long story short Selenium devs are trying to patch W3C requirements on the client level, which is, probably, ok for browsers, but does not work for mobile at all. Aa you can see above the client just calls
/execute
API without invoking the original endpoint.I also don’t really like this workaround, but there is no other way for us. We have a bunch of pull requests to selenium, which are waiting in the queue for more that one year, so we must keep our workarounds to make the lib working.
@kool79
Yes, add
forceMjsonwp: true
to your desired capabilities