Selecting form input with Selenium isn't working? - python

I was making an software which should connect to website using Selenium (firefox, python) and click "Yes" button. Here's page's source code (just that form part):
<div class="grid_24">
<div class="content_block">
<form action="" method="POST" class="fatform">
<p style="text-align:center;">
<input style="margin-right:50px;float:none;" type="submit" name="yes" value="da">
<input style="float:none;" type="submit" name="no" value="ne">
<input type="hidden" name="checkthis" value="lpftvqenq">
</p>
</form>
</div>
I was looking at Selenium Python Docs but I couldn't solve it by myself. So I'm here. I tried few types of selecting elements like this:
proxy(ip, port).find_element_by_name('yes').click()
form = proxy(ip, port).find_elements_by_class_name("fatform") #printing this gives nothing
proxy(ip, port).find_element_by_css_selector(".yes[value='da']").click()
All these examples (except form string which returns "") return NoSuchElementException.
Thanks in advance! :)

Why not search for the element by xpath instead? From my experience, the XPath generated by the Firebug add-in for Firefox works extremely well for me.
proxy(ip, port).find_element_by_xpath("xpath text").click()

You are using wrong selector.
. in css selector means class which is not the case here. Should look like
[name='yes'][value='da']
EDIT
Including explicit wait
WebDriverWait(proxy(ip, port), 10).until(
EC.find_element_by_css_selector((By.CSS_SELECTOR, "[name='yes'][value='da']"))
proxy(ip, port).find_element_by_css_selector("[name='yes'][value='da']").click()

Related

Searching inside element for another element with python and selenium

Lets say I have this kind of html
<form method post="some.page">
.
.
<span class="warning"
<img class"something_img" src="some.jpg" title="jpg title">
</span>
.
.
<p class="input">
<input class="input" type="submit" value="Click Here" name="action">
</p>
.
.
</form>
<form method post="some.page">
.
.
<p class="input">
<input class="input" type="submit" value="Click Here" name="action">
</p>
.
.
</form>
The jest is, the page is made out of lots of forms, but I need to locate only submit buttons in forms where the class "warning" exist and skip the inputs where it doesn't.. there can be a lot! of this forms some of them have the "warning" class and some of them don't and I need to click on the first that does have it... (script will than do it stuff, and come back when done to the main page where it again have to look for the input of form where the warning is...it will be on next form as script will solve the issue with old warning )
I'm not sure how to locate that reliably with selenium and python.
I would first filter out all the forms that don't have an element with the 'warning' class, and then get the submit button(s) in the valid forms via their XPaths:
# find all forms
forms = driver.find_elements_by_tag_name("form")
# create list of forms that only contain elements with 'warning' class
forms_with_warnings = [form for form in forms if len(form.find_elements_by_class_name("warning")) > 0]
# create list of buttons and fill it with found inputs in valid forms
buttons = []
for form in forms_with_warnings:
buttons.extend(form.find_elements_by_xpath('//input[type="submit"]'))
I hope something like this helps! You could also do the filtering via the filter function instead of a list comprehension; whatever you're more comfortable with.

Selenium (python) text deletes on its own

Selenium is able to find these elements and send_text to them, but right after the text is written it is automatically deleted. Am I calling .send_text() wrong, or am I finding the wrong element to interact with?
This is a popup frame dialog, but I can't seem to focus on the frame. I'm not even sure I need to as selenium still interacts with the text fields.
Here is the javascript:
<div class="control-group">
<label class="control-label">Patient ID</label>
<div class="controls">
<input data-ng-model="subject.Code" data-custom-error="Patient ID already exists in this center" class="ng-valid ng-dirty" data-original-title="" type="text">
<i class="required-field" style="top:inherit">*</i>
</div>
</div>
Here is one method I have been using:
patientID = 'testID'
driver.find_element_by_xpath("//input[#data-ng-model='subject.Code']").send_keys(patientID)
also,
driver.find_element_by_css_selector(".controls > input[data-ng-model='subject.Code']").send_keys(patientID)
As I said, both find the correct element and send text but the text is immediately deleted. Any ideas, I'm stuck.
I'm using firefox, but the same happens in chrome.
Have you checked if there is any javascript code in the page listening to changes to the input field and deleting its contents?

Python+Selenium Scrape Error: ElementNotVisibleException

I'm currently trying to use Selenium/Python/PhantomJS to scrape the results of the form below:
http://gis.vgsi.com/newhavenct/Sales.aspx
It looks like when I try to click on the search button, I get an ElementNotVisibleException error.
My code:
self.driver.find_element_by_id("MainContent_btnSearch").click()
After some digging online, it seems like the button may be hidden. Indeed, here is the relevant HTML code from the search page:
<input type="button" value="Search!" class="btn btn-primary searchTrigger" style="width: 200px;" />
<input type="submit" name="ctl00$MainContent$btnSearch" value="Search" id="MainContent_btnSearch" style="width: 200px; display: none;" />
<div id="MainContent_ctl00" style="display:none;">
</div>
I tried preceding my previous code with a click of the searchTrigger, but this is still not working:
self.driver.find_element_by_class_name("searchTrigger").click()
self.driver.find_element_by_id("MainContent_btnSearch").click()
Any advice would be greatly appreciated!
Requested element has attribute style="display:none;", so you need to make it visible
Try to use following code:
self.driver.execute_script('document.getElementById("MainContent_btnSearch").style.display="block";')
self.driver.find_element_by_id("MainContent_btnSearch").click()
A portion of the screen is not visible by Selenium. It may be that another element lies on top of the one you are trying to click.
For me what always works without spending hours searching for the cause is to click using Javascript:
self.driver.execute_script("arguments[0].click();", elt)
where elt is a WebElement - e.g. returned by find_element_by_id(.).
Make it a function and use wherever the problem occurs.
Edit: it is a generic answer for when it happens again, but in this particular case the other answer is probably correct.

Python mechanize click submit on multi submit form

I have to click on the first submit on a multi submit form. The submit code is as below:
<div class="grid ">
<div class="grid__item grid-u-2-10">
<label class="form__label">Auto-Fill:</label>
</div>
<div class="grid__item grid-u-8-10" id="autofill-button-container">
<input type="button" id="autofill" name="autofill" value="Auto-Fill" class="form__input" onclick="AutoFill();" /> Use AutoFill first, as it will replace everything below.
</div>
</div>
I tried:
br.open(url+"upload.php")
br.select_form(nr=7)
r = br.submit(label='Auto-Fill')
however it returns:
mechanize._form.ControlNotFoundError: no control matching kind 'clickable', label 'Auto-Fill'
Pls help.
you're trying to click the wrong button. The input-button action is what you need to go for. Assuming you're selecting the right form. If not br.select_form(nr=8)
Try:
br.submit(name=autofill)

python flask iframe and download

I have to perform two actions based on radio button selection, either download or view a document
<form method="post" action="{{ url_for('page_after_submit') }}">
<p> Your resume </p>
<div class="radio">
<label> <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked> Download document </label>
</div>
<div class="radio">
<label> <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2"> View document </label>
</div>
<input type="submit" />
</form>
My page_after_submit has this code...
#app.route(local.URL_PREFIX + '/page_after_submit/', methods=['POST'])
def after_submit():
if 'option1' == request.form['optionsRadios']:
return/redirect ("download from this url")
if 'option2' == request.form['optionsRadios']:
return/redirect ("view in this iframe")
return (Url_for('go back to submit page if you are here')
I know my form can only have one action which is '/page_after_submit/', what code (HTML or Python in flask) I need to complete rest of my actions ??? I tried to put the iframe tags with complete download file address in the redirect for option2 but doesn't work. I also want this iframe to pop up not open a new browser window. Plus for the download, don't know what to do specially different operating system may have different path for download directory.
My goal is to not have any javascript as well, don't know if it's possible or not. Thanks in advance.
You need to craft a different response depending on how they want to see the data.
Download File
If they choose option 1, you need to set the headers and response to allow the browser to trigger a file download. Here's how you can do something like that.
View File in Iframe
If they choose option 2, you need to return an HTML response which loads the file. This can be done in an Iframe if you'd like, but it's not necessary. Here's one possible way to do that, but many others exist.

Categories