Interacting with iFrames Using Splinter/Selenium [Python] - javascript

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.

Related

Cannot find a button inside the shadow DOM using Cypress.io

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?

WebdriverIO browser.click gives error "Other element would receive the click". How do I fix?

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.

Selenium Webdriver with Python: Element is not clickable & Cannot read property 'click' of null

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

Inserting a popup DOM node into WYSIWYG

I am trying to add a clickable div to the sceditor. The basic requirement is to use a wysiwyg and programmatically add an element into the editor, which can display a popup when the user clicks on it.
To do this I use:
var text = "<div onClick='editdiv(this)'>"+name+"</div>";▓
$('.sceditor').sceditor('instance').insert(text);
This inserts the div into the editor but when I click on it, I get an error saying editdiv is not defined. Whereas editdiv is a function present inside the javascript same javascript file which runs the above code.
Can someone please tell me what am I doing wrong and/or a way to achieve what I want? Thanks!
What you want is impossible to get without drawbacks.
Events can only be caught inside an active browsing instance (I think that's the name). Everything inside a contentEditable=true" is not an active browsing instance
Based on that, You need to terminate the contentEditable and make a new one inside. For example (code not tested):
var text = "<div contentEditable='false' onclick='editdiv(this)'><div contentEditable='true'>"+name+"</div></div>";
$('.sceditor').sceditor('instance').insert(text);
That should make that click event work as expected

Get javascript loaded content

Let's say I have a button on a page, if clicked it adds a div popup.
How can I access the div's content through JavaScript? Is this possible? I've tried searching the page with jQuery selectors but I did not find the div popup.
I have a bookmarklet that is similar to what follows:
javascript:(function() {
alert($('newDivId').val());
})();
...suppose that newDivId is the id of the newly created div, if I execute that code by clicking on the bookmarklet I get an error saying that val() cannot be invoked on a null object.
I do not have access to the page source; do you have any suggestion?
$('#id_of_div').html()
OR
$('.class_of_div').html()
OR
$('#id_of_div_parent div').html()
ETC.
If that doesn't work, you might be trying to select it before it has been full inserted into the DOM. Be sure it's fully loaded before you try to access it.

Categories