I'm trying to find and click on a button inside the shadow DOM using Cypress.io.
I've tried various class names, with combinations of get/find and the .shadow() command.
I'm getting this error in Cypress:
"Timed out retrying after 4000ms: Expected the subject to host a
shadow root, but never found it."
Here is some code of the react app I'm testing (with the button id highlighted)
app code screenshot
Below is the latest Cy code I've tried.
cy.get('*[class^="MuiInputBase-input"]').shadow()
cy.find('div[id="search-clear"]')
.invoke('show')
.click()
The button I'm trying to find and click on (it becomes visible upon mouse-over).
button screenshot
Any ideas on how to target this element?
You have to chain .find(selector) after .shadow()
like:
cy.get('.MuiInputBase-input').shadow()
.find('#search-clear')
.invoke('show')
.click()
example in documentation
side note:
Why are you using *[class^="MuiInputBase-input"] and div[id="search-clear"]
instead of .MuiInputBase-input and #search-clear?
Related
I am trying to write a test for my application but it is currently failing. I'm not sure what the problem is but I have tried it with an WebDriverWait and even a time.sleep() but this has not solved the problem.
The failing part of the test looks like this:
form_2.find_element_by_css_selector('.btn-primary').click() # submits form_2 and changes page to next form
self.assertEqual(
self.get_current_url(),
self.live_server_url + reverse(
'activitygroupconfigstepkeycharacteristicfieldset_update', kwargs={'activitygroupconfig_pk': 1}
)
) # test to see if expected url is correct
# Fill out next form (i.e. Key Characteristics)
form_3 = self.driver.find_element_by_xpath('//form[#role="form"]')
form_3.find_element_by_css_selector(
'#div_id_activitygroupconfigstepkeycharacteristicfield_set-0-key_characteristic'
).click()
assert form_3.find_element_by_css_selector('.select2-container--open').is_displayed() is True # I'm getting this error: selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".select2-container--open"} here so the click clearly isn't working.
What should happen is that the element is clicked and then a new element is inserted into the DOM. But as the assertion is failing this clearly isn't happening. I have also done a print(self.driver.page_source) after the click and I can see that the element isn't being added so for some reason the click isn't being registered.
I thought that it may be due some custom jQuery scripts not being finished before the test takes place on the page but I added this:
def wait_script(self):
WebDriverWait(self.driver, 10).until(lambda s: s.execute_script("return jQuery.active == 0"))
after the page change and it returns True before the test begins, so I assume that means that all jQuery processes are complete, unless this doesn't take into account page specific custom functions?
Any help with this conundrum would be much appreciated.
After some digging I found that the focus element for the click was wrong. See: this stackoverflow answer which I adapted to work in my case:
form_3.find_element_by_id(
'id_activitygroupconfigstepkeycharacteristicfield_set-0-key_characteristic'
).find_element_by_xpath('..').click()
I am getting the following error from my webdriverIO selenium code when I try to run it:
Failed: unknown error: Element is not
clickable at point (389, 709). Other element would receive the click:
< html lang="en" >...< /html >
here's the relevant code:
const checkboxSelector =
getAttributeSelector('data-test', 'manual-checkbox');
browser.click(checkboxSelector);
How do I get rid of this error?
--- ADDITIONAL INFO ---
The test is being run with chromedriver:
var desktop = exports.desktop = [{
browser: 'Chrome',
os: 'Windows',
os_version: '7'
}];
Seems like the issue was that you needed to scroll to the appropriate element explicitly to click the button. Not sure why it's not automatic but it's an easy fix using browser.scroll(selector) (http://webdriver.io/api/utility/scroll.html).
const checkboxSelector =
getAttributeSelector('data-test', 'manual-checkbox');
browser.scroll(checkboxSelector);
browser.click(checkboxSelector);
Problem solved
Does your page potentially have hidden elements or multiple elements that you may be targeting with your selector? When I've seen this error, often times my single selector could behind the scenes be targeting another element. The message "Other element would receive the click" was often the key to indicating that it may have picked up multiple elements and the Element you had intended to click, was not what the script would have clicked.
You can test this by using your CSS Selector in the browser console with
$$('data-test')
If you see multiple elements returned, you may need to be more specific with your Selector to more precisely narrow down the one you intend to act on.
when running this command, I'm getting an error:
driver.find_element_by_link_text("Confirm").click()
selenium.common.exceptions.WebDriverException: Message: unknown error: Element ... is not clickable at point (67, 581). Other element would receive the click: `<div class="mfp-container mfp-ajax-holder mfp-s-loading">...</div>`
After searching answers on this issue, I've changed the above code to:
element = driver.find_element_by_link_text("Confirm").click()
driver.execute_script("arguments[0].click();", element)
For the first click it worked and then printed this error:
selenium.common.exceptions.WebDriverException: Message: unknown error: Cannot read property 'click' of null
The HTML code is:
Confirm
So this worked for me:
driver.find_element_by_link_text("Confirm").send_keys('\n')
Thanks to everybody :)
Try to search for the class:
driver.find_element_by_class("c-button js-close s-vgLeft0_5 c-button--blue").click()
If you look at the error message, you will see that another element is intercepting the click. I don't know for sure without looking at the page but generally it's something like a loader screen, popup, etc. that appears temporarily and then disappears. There is also the hint of one of the classes of the intercepting DIV, mfp-s-loading, that further makes me think it's some sort of loading popup. The problem here is that the script proceeds and tries to click the link faster than the popup loads and unloads. What I typically do in a situation like this is to wait for the popup to be invisible and then click the link.
The HTML of the popup is in the error message,
<div class="mfp-container mfp-ajax-holder mfp-s-loading">...</div>
So you can locate the element using a CSS selector like, div.mfp-s-loading, to wait for it to be invisible and then try your click.
Sometimes using Xpath is easier
Try:
driver.find_element_by_xpath(Xpath).click()
where Xpath should point to the object which you are planning to click
As part of automation testing, we want to inspect the element in a website which is made of using the Zebkit UI framework.
We are unable to find the element using zebra.ui
examples can be found here
Can someone help us on inspecting the element
Zebkit UI components are rendered on HTML5 Canvas. So they are not part of browser DOM tree what can be a problem for a test tool that expects DOM as an input. But it doesn't mean you cannot go over zebkit UI stuff to perform test cases.
First of all keep in mind zebkit components are a hierarchy/tree like DOM is. Every rendered on a canvas zebkit UI component has a related JS instance of appropriate class. There are number of API methods you can use to travel over UI components tree. These methods expect path (XPath-like) since path (from my point of view) is less "encrypted" way than CSS selector.
The API methods you probably need:
byPath(path [,callback]) - traversing UI components tree by the given path
var zcanvas = new zebkit.ui.zCanvas();
...
// travel over all UI components in tree
zcanvas.byPath("//*", function(comp) {
// perform test cases here
...
});
properties([path,] properties) applies the specified properties set to component or number of components requested by the given path
var zcanvas = new zebkit.ui.zCanvas();
...
// set color property to black value for all labels
zcanvas.properties("//zebkit.ui.Label", { color: "black" });
on([eventName], [path], handler) add listener method(s) for the given event (or all events) of the given component or components identified with the path:
var zcanvas = new zebkit.ui.zCanvas();
...
// register event listener for all found buttons
zcanvas.on("//zebkit.ui.Button", function (src) {
// handle button press event here
...
});
fire([eventName,] [path,] [argument]) fire the given event to the given component or to components identified with the path:
var zcanvas = new zebkit.ui.zCanvas();
...
// fire button pressed event to button with id equals "testButton"
zcanvas.fire("//[#id='testButton']");
...
// or the same with a shortcut
zcanvas.fire("#testButton");
I'm not sure I understand correctly your issue, but assume you cannot click right button on canvas to open context menu and select "Inspect element" option.
You can
press F12 in browser
switch to "Elements"/"HTML" tab
in search field (CTRL + F) print "canvas"/"<canvas" and press Enter
Continue pressing Enter until required canvas found (current element should be highlighted)
These controls are implemented using an HTML5 CANVAS tag. Selenium cannot see "inside" this tag because it doesn't contain HTML. It's like an app inside the page. From the page you linked, it looks like you should be able to use JS to access elements inside the control. When I've done things with CANVAS tags in the past, I generally find JS that does or returns what I want and then wrap that code in a function that I can call. It will work but you will likely have to do some research on Zebkit to find out what JS you will need to validate, etc. all the different things you will want to validate... and it may end up that you won't be able to validate some things.
note: a solution in either Selenium or API wrapper Splinter for Selenium is fine!
I have been having issues interacting with the iframes on Twitter.com using the Splinter API for Python.
For example,
with Browser('firefox', profile_preferences= proxySettings) as browser:
#...login and do other stuff here
browser.find_by_id('global-new-tweet-button').click()
this brings up a pop-up box to type in a tweet.
How do I interact with this new box using Splinter to:
1) fill in a message
2) click "tweet" (submit)
..programmatically of course.
I tried inspecting the element but it doesn't seem to be nested inside of an iframe however it targets an iframe. So I am not sure how to find/interact with the elements in this pop-up.
I tried manually typing in a message then clicking the tweet button programmatically:
browser.find_by_css('.btn.primary-btn.tweet-action.tweet-btn.js-tweet-btn').click()
..but I get the error:
ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Stacktrace:
at fxdriver.preconditions.visible (file:///var/folders/z1/8rqrglqn2dj8_yj1z2fv5j700000gn/T/tmppRsJvd/extensions/fxdriver#googlecode.com/components/command-processor.js:10092)
at DelayedCommand.prototype.checkPreconditions_ (file:///var/folders/z1/8rqrglqn2dj8_yj1z2fv5j700000gn/T/tmppRsJvd/extensions/fxdriver#googlecode.com/components/command-processor.js:12644)
at DelayedCommand.prototype.executeInternal_/h (file:///var/folders/z1/8rqrglqn2dj8_yj1z2fv5j700000gn/T/tmppRsJvd/extensions/fxdriver#googlecode.com/components/command-processor.js:12661)
at DelayedCommand.prototype.executeInternal_ (file:///var/folders/z1/8rqrglqn2dj8_yj1z2fv5j700000gn/T/tmppRsJvd/extensions/fxdriver#googlecode.com/components/command-processor.js:12666)
at DelayedCommand.prototype.execute/< (file:///var/folders/z1/8rqrglqn2dj8_yj1z2fv5j700000gn/T/tmppRsJvd/extensions/fxdriver#googlecode.com/components/command-processor.js:12608)
I strictly want to achieve my goal using Splinter so please do not offer alternatives, I know there are other ways.
Thank you in advance!
You primary problem seems to be that you are treating the results of browser.find_by_xxx as an element object, when in reality it is an element container object (i.e. a list of webdriver elements).
Writing to the field works for me if I reference the element explicitly:
In [51]: elems = browser.find_by_id('tweet-box-global')
In [52]: len(elems)
Out[52]: 1
In [53]: elems[0].fill("Splinter Example")
In [54]:
That will write "Splinter Example" into the field for me.
The button click is failing because your css path is returning a list of three elements, and you are implicitly clicking on the first, hidden element. In my testing, the element you actually want to click on is the second element in the list:
In [26]: elems = browser.find_by_css('.btn.primary-btn.tweet-action.tweet-btn.js-tweet-btn')
In [27]: len(elems)
Out[27]: 3
In [28]: elems[1].click()
In [29]:
When I explicitly click the second element it doesn't throw an error and the button is clicked.
If you add to the css path you can narrow the results to only the button in the visible modal:
In [42]: css_path = "div.modal-tweet-form-container button.btn.primary-btn"
In [43]: elems = browser.find_by_css(css_path)
In [44]: len(elems)
Out[44]: 1
In [45]: elems.click()
In [46]:
Note that no exception was thrown here.