Python Selenium can't change Select element value - python

I have a Select element with two options: Credit / Debit Card and Cash, with the former being the default. I have tried everything conventional and whatever else I can think of but I cannot change this value to Cash. My code as it stands is the following
pay_type_dropdown = driver.find_element_by_xpath(path_ending_in_select)
pay_type_dropdown.click()
# Have tried with and without clicking. Never seemed to make a difference.
pay_type_select = Select(pay_type_dropdown)
pay_type_select.select_by_visible_text('Cash')
But I have also tried select_by_value('CASH') - the option tag's value - and select_by_index(1), as well as
pay_type_dropdown = driver.find_element_by_xpath(path_ending_in_select)
pay_type_dropdown.click()
elems = pay_type_dropdown.find_elements_by_tag_name('option')
elems[1].click()
and
elems = pay_type_dropdown.find_elements_by_xpath(path_ending_in_select + '/option')
elems[1].click()
also to no avail. The drop box opens (if clicked on with the click() function) but no other value is selected. Nothing happens past that and there is no error. It is not in a separate frame as I am able to interact with everything else without having to shift into the correct frame. Any help would be much appreciated, thanks.
EDIT: This is the relevant HTML.
<div class="z-form-row" data-bind="visible: settings.tender.active, 'if': settings.tender.active">
<div class="z-form-field">
<label data-bind="_t: 'cart_options_payment_label'">I'll pay with:</label>
<select data-bind="value: settings.tender.selected, options: settings.tender.types, optionsText: 'label',
optionsValue: 'id', valueAllowUnset: true"><option selected="selected" value="CARD">Credit / Debit Card</option><option value="CASH">Cash</option></select>
</div>
<i class="z-row-icon z-icon-card" data-bind="css: tenderTypeIcon()"></i>
</div>

Related

how to change the value of the array when the user types a new value in reached form

i am working on my recommendation system,it works fine but
when the user searches for a book ,it gives title and image of the books,but when the user type some other title with reloading the file i ,it gives the correct book title but it loads the image of the pervious
searched book
here is my search route, which get book's title and its image
#app.route('/search',methods=['GET','POST'])
def search():
choice = request.args.get('search')
# removing all the characters except alphabets and numbers.
# passing the choice to the recommend() function
# passing the choice to the recommend() function
books = recommend(choice)
image=get_image()
# if rocommendation is a string and not list then it is else part of the
# recommend() function.
if type(books) == type('string'):
return render_template('read.html', book=books,image=image,s="oppps")
else:
return render_template('read.html', book=books,image=image)
here is my code to get the image, where i have defined img list gobally
for i in indices.flatten():
img.append(data[data.index == i]
['Image'].values[0])
return book_list
I can't understand why it gives the previous searched book's image,while it should display the current searched title image (But it works fine when i rerun the py file again)
here is my searched form
{% block body %}
<form action="{{url_for('search')}}" , class="navbar-form" role="search" ,method="POST">
<input type="text" placeholder="Search Books" class="search mb-3" name="search">
<button class="search-btn">Search</button>
</form>
{% endblock %}
can u pls help me out with this
Thanks you in Advance
I think you got some logic error in your code, but from posted piece it is not clear what exactly is your issue.
For example, how did you connect that data: title of the book and it's image:
books = recommend(choice) // here you get the book(s), based on **choice** variable
image=get_image() // but what did you based on when picking the image(s) from the list
I think more code would clarify this problem.

Get all text wrapped by THEN if condition

html code
<div class=media>
<div class=11></div>
<div class=22></div>
<div class=media-content>
yes, this is the text<BR>
that i want to compare below
multiple line
</div>
</div>
<div class=media>
<div class=11></div>
<div class=22></div>
<div class=media-content>
and i want to compare above text multiple line
then if both same, i wanna break the loop
But it is not work
</div>
</div>
Succeeded to select first element (was checked by chropath)
driver.find_elements_by_xpath('//div[#class="media"][last()]//div[#class="media-content"]')
Succeeded to select second element (was checked by chropath)
driver.find_elements_by_xpath('//div[#class="media"][last()-1]//div[#class="media-content"]')
But both text was NOT same but always TRUE then break.
if driver.find_elements_by_xpath('//div[#class="media"][last()]//div[#class="media-content"]').gettext() == driver.find_elements_by_xpath('//div[#class="media"][last()-1]//div[#class="media-content"]').gettext():
break
Yes, it is not work.
I wanna compare the text(multi line) in both first and second element(#class=media-content)
If both multi-lined text was same, i wanna stop the loop.
But both text was NOT same as you see, but always become TRUE then STOPPED(break)
I am succeed to select item (*with last[], last[]-1)
But i don't why it works wrong.....
Is there anybody to troubleshoot my newbie code?
//text(), .gettext(), .text()
Try the below code.
items1=[item.text for item in driver.find_elements_by_xpath('//div[#class="media"][last()-1]//div[#class="media-content"]')]
items2=[item.text for item in driver.find_elements_by_xpath('//div[#class="media"][last()]//div[#class="media-content"]')]
if items1==items2:
print("pass")
else:
print("fail")
For me anser is (in case if where are more then one div[#class="media-content"] elements in singal div[#class="media"] node):
media_last = driver.find_elements_by_xpath('//div[#class="media"][last()]//div[#class="media-content"]')
media_last = [a.gettext() for a in media_last]
media_not_last =driver.find_elements_by_xpath('//div[#class="media"][last()-1]//div[#class="media-content"]')
media_not_last = [a.gettext() for a in media_not_last]
if media_last == media_not_last:
break
you can't get method gettext at the array of elements
or if you want get jast a singl element use find_element_by_xpath method
I tested the following using your html and I get the behaviour you expect:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(r'file:///<path to local html file>') # Used local html file for testing purposes
el1 = driver.find_elements_by_xpath('//div[#class="media"][last()]//div[#class="media-content"]')
el2 = driver.find_elements_by_xpath('//div[#class="media"][last()-1]//div[#class="media-content"]')
if el1[0].text == el2[0].text:
print('Yes')
else:
print('No')
One thing to understand is that driver.find_elements_by_path() returns a list object. So even though it appears you are targeting specific elements in your page, they are stored in list objects and you should refer to them that way if you wish to access the text of the elements.

How do I get checkbox "on" using Python Flask without causing a 400 bad request error?

I've got a form which is submitting a post request to Flask. It all works perfectly except when a checkbox is not ticked which causes a 400 error unless I have a try: except: catch for each option.
The challenge is that I have a lot of checkboxes and it seems like there would be a better way than just having a dozen try: except: checks.
Is there a more Pythonic way of doing this please?
Currently the HTML looks like this:
<div class="control">
<label class="checkbox">
<input name="option_1" type="checkbox">
Option 1
</label>
</div>
My Python code looks like:
try:
print(request.form['option_1'])
except:
print("option_1 not selected")
When a key might not exist, use .get(...) instead of accessing it directly, for example:
print(request.form.get('option_1'))
Thanks to Janos for the explanation, whoop only prints if the box is ticked with no error if it's not there.
if request.form.get('option_1'):
print('whoop')

Python - Selenium - Get Parent Class

I have a website http://demoqa.com/registration/
I have been trying to verify that when a user clicks on and then clicks off a required field such as username or phone number that the error "required field" appears when no data has been entered.
Does anyone have any idea how to verify this? I was thinking
phone = self.driver.find_element_by_xpath("//div[contains(.,'Phone Number')]")
and then from that using something like getError = phone.find_element_by_xpath() and using the (..) to try and move up to the parent class, but with no luck!
I thought it would have been easy but all the elements have the same class name. I suppose I could check for the text "this field is required" but I'd like to keep it neat and write a method so I can use it on each of the fields.
I've spent alot of today searching for it and trying different thing, so any help or ideas would be great.
Thanks!
Other Info:
I can tell you what happens before and after i click the field. My best guess at attacking this issue would be to verify the class name of the field "phone number" and then once clicked off, verify that the class name has changed. As you can see on top is before a click off and below is when the required field text appears
<div class="fieldset">
<label class="" for="phone_9">Phone Number</label>
<input id="phone_9" class="input_fields piereg_validate[required,custom[phone_international]]" type="text" value="" placeholder="" name="phone_9">
</div>
<div class="fieldset error">
<label class="" for="phone_9">Phone Number</label>
<input id="phone_9" class="input_fields
piereg_validate[required,custom[phone_international]]" type="text" value=""
placeholder="" name="phone_9">
<div class="legend_txt">
<span class="legend error">* This field is required</span>
</div>
</div>
I have my solution *i think
seeing how the "div class name" changes when the required message appears I have a solution. I first find the element, get it's parents name by going up one level using the (..), i verify it's as it should be named "fieldset". I think trigger the error message, and repeat the process but make sure the "fieldset" has changed to "fieldset error"
getElementBase = self.driver.find_element_by_id('phone_9')
getElementClassRoot = getElementBase.find_element_by_xpath('..')
getElementClassRootName = getElementClassRoot.get_attribute('class')
Try to use below piece of code:
from selenium.common.exceptions import NoSuchElementException
error = "* This field is required"
phone = driver.find_element_by_xpath("//div[label='Phone Number']")
phone_input = phone.find_element_by_tag_name("input")
phone_label = phone.find_element_by_tag_name("label")
phone_input.click()
phone_label.click()
try:
phone.find_element_by_xpath(".//span[#class='legend error' and .='%s']" % error)
except NoSuchElementException:
print("No error displayed")
This should allow you to click inside input, outside input and check that error appears
If you need to make an assertion:
result = True
try:
phone.find_element_by_xpath(".//span[#class='legend error' and .='%s']" % error)
except NoSuchElementException:
result = False
assert result, "No error displayed"

Google Fusion Maps Info Window Dynamic Templating

I'm doing some web scraping with Python and the last step is to use Google Fusion maps, but as somebody who has never touched any CSS styling before, I have no idea how to do something probably incredibly simple: hide a column title in the info window if it's blank. Not all the data have entries in my Amenities column, so I would like that to be gone from the info window if it's blank.
I've read this (https://support.google.com/fusiontables/answer/3081246?hl=en&ref_topic=2575652), but it's complete gibberish to me at this stage.
This is the default HTML they provide for the info window (with my data):
<div class='googft-info-window'>
<b>Location:</b> {Location}<br>
<b>Movie Title:</b> {Movie Title}<br>
<b>Date:</b> {Date}<br>
<b>Amenities:</b> {Amenities}
</div>
This shot in the dark didn't work:
<div class='googft-info-window'>
<b>Location:</b> {Location}<br>
<b>Movie Title:</b> {Movie Title}<br>
<b>Date:</b> {Date}<br>
<b>{if Amenities.value}
Amenities:
{/if}Amenities:</b> {Amenities}<br>
</div>
This question isn't related to CSS, try this:
{template .contents}
<div class='googft-info-window'>
<b>Location:</b> {$data.value.Location}<br/>
<b>Movie Title:</b> {$data.value['Movie Title']}<br/>
<b>Date:</b> {$data.value.Date}<br/>
{if $data.value.Amenities}
<b>Amenities:</b>{$data.value.Amenities}<br/>
{/if}
</div>
{/template}

Categories