New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error trying to access shadowRoot elements on iOS #9733
Comments
I'm still stuck on this. If anyone has any advice on what else I could try to get more information, please let me know. |
I'm having the same problem. I ran the command: "document.querySelector("dropdown").shadowRoot" on the following:
I have tried Appium 1.7.1 and Appium 1.7.2. |
@ringles-icfi or anyone else. Did you ever come up with a good workaround for this issue? |
@mykola-mokhnach do you know why this is marked as third party? If so, who's issue do you think this is? I'd love to help find a solution to this issue. |
I think the problem has to do with javascript processing inside mobile safari. Appium is just acting as a proxy between your client code and the js engine. We'd appreciate it if you could help to find a proper solution. |
@mykola-mokhnach the interesting thing is that running these same commands on the device with remote debugging through Safari's developer tools doesn't throw this error. |
Can you try to add document.querySelector("dropdown").shadowRoot would become document.querySelector("dropdown").shadowRoot.host |
@imurchie thanks for your reply! You're thinking along the same lines as me, I tried this previously and again just now. The problem with using
Will just return you the
So using find_element at that point will just result in not being able to locate the element, because you're not in the shadowRoot |
Hmm. That makes sense. The problem is in the Selenium "atoms", which is how Appium injects JavaScript into the page context. When I remove the check that throw the error, the element available is like the following: { mode: 'open',
host: { ELEMENT: ':wdc:1531325564675' },
innerHTML: '\n <style>\n p {\n color: red;\n }\n </style>\n\n <p>Element with Shadow DOM</p>',
activeElement: null,
elementFromPoint: 'function elementFromPoint() {\n [native code]\n}',
elementsFromPoint: 'function elementsFromPoint() {\n [native code]\n}',
children:
[ { ELEMENT: ':wdc:1531325564676' },
{ ELEMENT: ':wdc:1531325564677' } ],
firstElementChild: { ELEMENT: ':wdc:1531325564676' },
lastElementChild: { ELEMENT: ':wdc:1531325564677' },
childElementCount: 2,
getElementById: 'function getElementById() {\n [native code]\n}',
prepend: 'function prepend() {\n [native code]\n}',
append: 'function append() {\n [native code]\n}',
querySelector: 'function querySelector() {\n [native code]\n}',
querySelectorAll: 'function querySelectorAll() {\n [native code]\n}',
nodeType: 11,
nodeName: '#document-fragment',
baseURI: 'http://localhost:4994/test/shadow',
isConnected: true,
ownerDocument: { ELEMENT: ':wdc:1531325564678' },
parentNode: null,
parentElement: null,
childNodes:
[ [ null, null, null, null, null, null, null ],
{ ELEMENT: ':wdc:1531325564676' },
[ null, null, null, null, null, null, null, null ],
{ ELEMENT: ':wdc:1531325564677' } ],
firstChild: [ null, null, null, null, null, null, null ],
lastChild: { ELEMENT: ':wdc:1531325564677' },
previousSibling: null,
nextSibling: null,
nodeValue: null,
textContent: '\n \n p {\n color: red;\n }\n \n\n Element with Shadow DOM',
getRootNode: 'function getRootNode() {\n [native code]\n}',
hasChildNodes: 'function hasChildNodes() {\n [native code]\n}',
normalize: 'function normalize() {\n [native code]\n}',
cloneNode: 'function cloneNode() {\n [native code]\n}',
isEqualNode: 'function isEqualNode() {\n [native code]\n}',
isSameNode: 'function isSameNode() {\n [native code]\n}',
compareDocumentPosition: 'function compareDocumentPosition() {\n [native code]\n}',
contains: 'function contains() {\n [native code]\n}',
lookupPrefix: 'function lookupPrefix() {\n [native code]\n}',
lookupNamespaceURI: 'function lookupNamespaceURI() {\n [native code]\n}',
isDefaultNamespace: 'function isDefaultNamespace() {\n [native code]\n}',
insertBefore: 'function insertBefore() {\n [native code]\n}',
appendChild: 'function appendChild() {\n [native code]\n}',
replaceChild: 'function replaceChild() {\n [native code]\n}',
removeChild: 'function removeChild() {\n [native code]\n}',
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12,
DOCUMENT_POSITION_DISCONNECTED: 1,
DOCUMENT_POSITION_PRECEDING: 2,
DOCUMENT_POSITION_FOLLOWING: 4,
DOCUMENT_POSITION_CONTAINS: 8,
DOCUMENT_POSITION_CONTAINED_BY: 16,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32,
addEventListener: 'function addEventListener() {\n [native code]\n}',
removeEventListener: 'function removeEventListener() {\n [native code]\n}',
dispatchEvent: 'function dispatchEvent() {\n [native code]\n}' } Perhaps it is possible to develop queries based on available properties or functions? |
@imurchie this is very interesting! Could you point me to where that check is at? I'm digging into Selenium for the first time, so any direction would be great! |
The check itself is happening here: https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/inject.js#L123-L126 |
Selenium atoms seem to have more issues with shadow-dom. e.g. SeleniumHQ/selenium#6399 I stumbled accross that when i wrote a custom By implementation that uses javascript to find elements inside a shadowroot. This custom By works in chromedriver but fails when run via Appium on an ios device (i guess chromedriver does not use these atoms because why not....) |
Has anyone found a work around to this? We haven't been able to find a way to execute selenium scripts on appium and IOS, where shadow doms are used. Our work around for lack of shadow dom support within selenium works fine on Chrome / Android with appium. |
Any news on this issue? Interacting with the elements via JS is not ideal as elements are not interacted as the user would do so it may give false positives when executing tests (element is interactuable with JS and not by the user). |
This has been fixed in version 1.16.0 |
We were excited to see this get fixed, but I just tried the exact steps from the original ticket and this issue is still happening with Appium 1.16.0. Maybe there is a different way I should be accessing the shadowRoot elements? |
Can someone provide an app in which this is a problem? |
Sorry for the delay. Yes, this is easily reproduced using the sample site at http://shop.polymer-project.org.
|
@imurchie This is still limiting our ability to work with shadowDoms on iOS. Is there any further news on this? Can we re-open this ticket since it really isn't fixed as stated. Or, should I just create a new ticket? |
@dyhopper Sorry, this slipped through my workload. I'll take a look at what is going on with your repro case. |
The error I'm seeing is
|
The latest beta of Appium (with |
Just wanted to check in on this situation and see if there has been any movement on interacting with Shadow elements. |
any update? |
Any update on this issue? |
The problem
Can't access elements under a shadowRoot on iOS real device.
We have an automation suite that runs on our Chrome app, and our Mac and Windows Electron apps using Selenium Webdriver. I'm hoping to use much of the same code on our Hybrid iOS app via Appium.
We use Polymer and thus have to access elements under shadowRoots.
On other platforms, we are doing this via
shadowElement = $driver.execute_script('return document.querySelector("blah_blah").shadowRoot')
el = shadowElement.find_element(:css => "#id_of_my_element")
This is not working in Appium. I'm getting a "Recursive object cannot be transferred" error.
Environment
Appium 1.7.1 (using Appium desktop app 1.2.7)
Mac OS 10.13
Xcode 9.1
iOS 11.1.2 on real iPad Air
Details
I believe I have the capabilities set up correctly, as I can switch to the web context and access the elements above the shadowRoot elements.
When running the sample code below I get the error: "[MJSONWP] Encountered internal error running command: Error: Error while executing atom: Recursive object cannot be transferred (status: 13)"
Link to Appium logs
https://gist.github.com/dyhopper1/0df126924abfd093ae02c80fc71a5fc4
Code To Reproduce Issue [ Good To Have ]
(Sample ruby code)
`capabilities =
{
"bundleId"=> "com.vernier.spectralanalysis",
"udid" => "1905da18d1c56349efb55ab04xxxxxxxxxxxxxxx",
"platformName" => "iOS",
"deviceName" => "iPad Air",
"platformVersion" => "11.1",
"xcodeOrgId" => "xxxxxxxxxx",
"xcodeSigningId" => "iPhone Developer",
"startIWDP" => true
}
$driver = Appium::Driver.new({:caps => capabilities}, false).start_driver
sleep 4
webview = $driver.available_contexts.last
$driver.set_context(webview) #works
el = $driver.execute_script('return document.querySelector("vst-sa-app")')
p el # just to prove the element was retrieved successfully. no problem.
#the following line results in error
shadowEl = $driver.execute_script('return document.querySelector("vst-sa-app").shadowRoot')
`
The text was updated successfully, but these errors were encountered: