I am trying to simulate in selenium when two input types are left blank and when the input field gets unfocused it will return an invalid message. What I want to do is get both of this invalid message that has the same span classname.
Here is my python code:
fn_input = driver.find_element(By.XPATH, "//input[#name='fn']")
fn_input.send_keys('')
ln_input = driver.find_element(By.XPATH, "//input[#name='ln']")
ln_input.send_keys('')
driver.find_element_by_id('submit_search').click()
time.sleep(5)
fn_error_field = driver.find_element_by_class_name('formfield__message')
Above code works fine for finding the invalid message for fn_input. My question is how do I get the second invalid message for ln_input?
HTML:
<div class="formfield formfield--notification formfield--column-view">
<div class="formfield__label">First name</div>
<div class="formfield__input-wrapper">
<input
name="fn"
id="fn"
type="text"
class="input formfield__input"
value=""
/><span
class="formfield__icon-secondary icon-close icon-color-notification"
></span
><span class="formfield__message">Invalid field</span>
</div>
</div>
<div
class="formfield formfield--notification formfield--column-view capitalized"
>
<div class="formfield__label">Last Name</div>
<div class="formfield__input-wrapper">
<input
name="ln"
id="ln"
type="text"
class="input formfield__input"
value=""
/><span
class="formfield__icon-secondary icon-close icon-color-notification"
></span
><span class="formfield__message">Invalid field</span>
</div>
</div>
<button id="submit_search" type="button" class="button button--primary">
</i>submit
</button>
There are several ways to achieve this.
Collect your element use list with .find_elements_*:
elements = driver.find_elements_by_class_name('formfield__message')
#for second element
elements[1].text
Use following xpath with following-sibling:
element = driver.find_element_by_xpath('//input[#name="ln"]//following-sibling::span[#class="formfield__message"]')
XPath Axes
If you have locators with same name you need to use findelements in selenium
List<WebElement> Selects=driver.findElements(By.Xpath("//input[#name='ln']"));
// if you want select 2 nd element use below line
Selects.get(1).click();
Related
I have following html:
<div class=‘content active’>
<div>
<div class=‘var’>
<div class=‘field var-field’>
<label>Interface Name</label>
<div class=‘ui input’>
<input type=‘input’ placeholder=‘.*’ value> ==$0
</div>
</div>
</div>
</div>
<div>
<div class=‘var’>
<div class=‘field var-field’>
<label>Neighbor Id</label>
<div class=‘ui input’>
<input type=‘input’ placeholder=‘.*’ value> ==$0
</div>
</div>
</div>
</div>
</div>
I need to send text to the text box with label: Interface Name.
Is there a way to uniquely write the xpath to send the text to the textbox.
Note that the only way to identify uniquely is wrt the label. The other fields in the tag is same for both.
I tried using AND operator. No luck.
Please help me out here.
Try this :
//label[text()='Interface Name']/following-sibling::div/child::input
To send text to the <input> element with respect to the <label> tag you can create a function as follows :
def test_me(myText):
driver.find_element_by_xpath("//label[.='" + myText + "']//following::div[1]/input").send_keys("hello")
Now, you can call this function from anywhere within your script as follows :
test_me("Interface Name")
# or
test_me("Neighbor Id")
You can use this XPATH :- //*[text()='Interface Name']/following-sibling::div/input"
Below is the element in DOM.
<div style="float:left;width: 40px">
<label class="radio inline">
<input id="formData99991:Select" class="sample" data-ng-model="sampletId" size="" name="formData99991Select" sample-value="true" style="" value="1234" checked="checked" type="radio"/>
A
</label>
</div>
I tried with //input[contains(#id,'formData99991:Select') and contains(text(),'A')] but it doesn't work.
There are multiple similar elements on the web page and I need to identify each element with combo of id and text.
You can try with following x-path,
//label[contains(.,'A')]/input[#id="formData99991:Select"]
I am trying to write a code which lets me select the gender of my choice (let's use female as an example). The element as below. Please note that the ID keep changes so I cannot use css selector with the ID.
Please advise which method to use in selenium.
Thanks!
<div id="557f72b0-c612-428a-a77e-eb0841869ddb" class="nike-unite-gender-buttons gender nike-unite-component">
<div class="shim"></div>
<div class="error"></div>
<input type="hidden" id="40d664f0-e498-4fa2-8a6f-7d9fc75cfe01" value="" name="gender" data-componentname="gender">
<ul data-componentname="gender">
<li id="222f5bc2-171e-450e-8182-8e15c8d9f47b" class="">
<input type="button">
<span>Male</span>
</li>
<li id="6c6098bb-fc9f-497e-8551-0ae6bb8a235c" class="">
<input type="button">
<span>Female</span>
<</li>
</ul>
<div class="tip">Please select a gender.</div>
</div>
First, locate the gender container by the class names:
gender_container = browser.find_by_css('.nike-unite-gender-buttons.gender').first
Then, locate the button by the following text inside the span element:
female = gender_container.find_by_xpath('.//li[span = "Female"]/input').first
female.click()
Or, you may try finding the element by text directly:
browser.find_by_text('Female').first.click()
I am either receiving an error or nothing is being parsed/written with the following code:
soup = BeautifulSoup(browser.page_source, 'html.parser')
userinfo = soup.find_all("div", attrs={"class": "fieldWrapper"})
rows = userinfo.find_all(attrs="value")
with open('testfile1.csv', 'w') as outfile:
writer = csv.writer(outfile)
writer.writerow(rows)
rows = userinfo.find_all(attrs="value")
AttributeError: 'ResultSet' object has no attribute 'find_all'
So I tried a for loop with print just to test it, but that returns nothing while the program runs successfully:
userinfo = soup.find_all("div", attrs={"class": "fieldWrapper"})
for row in userinfo:
rows = row.find_all(attrs="value")
print(rows)
This is the html I am trying to parse. I am trying to return the text from the value attributes:
<div class="controlHolder">
<div id="usernameWrapper" class="fieldWrapper">
<span class="styled">Username:</span>
<div class="theField">
<input name="ctl00$cleanMainPlaceHolder$tbUsername" type="text" value="username" maxlength="16" id="ctl00_cleanMainPlaceHolder_tbUsername" disabled="disabled" tabindex="1" class="textbox longTextBox">
<input type="hidden" name="ctl00$cleanMainPlaceHolder$hdnUserName" id="ctl00_cleanMainPlaceHolder_hdnUserName" value="AAubrey">
</div>
</div>
<div id="fullNameWrapper" class="fieldWrapper">
<span class="styled">Full Name:</span>
<div class="theField">
<input name="ctl00$cleanMainPlaceHolder$tbFullName" type="text" value="Full Name" maxlength="50" id="ctl00_cleanMainPlaceHolder_tbFullName" tabindex="2" class="textbox longTextBox">
<input type="hidden" name="ctl00$cleanMainPlaceHolder$hdnFullName" id="ctl00_cleanMainPlaceHolder_hdnFullName" value="Anthony Aubrey">
</div>
</div>
<div id="emailWrapper" class="fieldWrapper">
<span class="styled">Email:</span>
<div class="theField">
<input name="ctl00$cleanMainPlaceHolder$tbEmail" type="text" value="email#email.com" maxlength="60" id="ctl00_cleanMainPlaceHolder_tbEmail" tabindex="3" class="textbox longTextBox">
<input type="hidden" name="ctl00$cleanMainPlaceHolder$hdnEmail" id="ctl00_cleanMainPlaceHolder_hdnEmail" value="aaubrey#bankatunited.com">
<span id="ctl00_cleanMainPlaceHolder_validateEmail" style="color:Red;display:none;">Invalid E-Mail</span>
</div>
</div>
<div id="commentWrapper" class="fieldWrapper">
<span class="styled">Comment:</span>
<div class="theField">
<textarea name="ctl00$cleanMainPlaceHolder$tbComment" rows="2" cols="20" id="ctl00_cleanMainPlaceHolder_tbComment" tabindex="4" class="textbox longTextBox"></textarea>
<input type="hidden" name="ctl00$cleanMainPlaceHolder$hdnComment" id="ctl00_cleanMainPlaceHolder_hdnComment">
</div>
</div>
Your first error stems from the fact that find_all returns a ResultSet, which is more or less a list: you would have to iterate through the elements of userinfo and call find_all on those instead.
For your second issue, I'm pretty sure when attrs is passed a string, it searches for elements with that string as its class. The html you provided contains no elements with class value, so it makes sense that nothing would get printed out. You can access an element's value with .get('value')
To print out the value of the text inputs, the following code should work.
(The try/except is just so the script doesn't crash if a text input isn't found)
for field_wrapper in soup.find_all("div", attrs={"class": "fieldWrapper"}):
try:
print(field_wrapper.find("input", attrs={"type": "text"}).get('value'))
except:
continue
I have a little problem. I am writing an automatic test, that has to go to webpage, enter some keys to search, then go to advanced search options, choose one from a list and search. The point is, that I have absolutely no idea on how to locate element on a list. It looks like this: http://www.e-podroznik.pl/public/searcherFinal.do. If you click on "więcej opcji" you'll se a list of options about journey. My question: how to locate element on this expanded "więcej opcji"-list using python selenium? I have tried everything, from find_element_by* to execute_script; nothing works. I get errors like 'unable to locate element', 'compound not permitted' etc.
The HTML:
<div class="advanced-searcher dNone more-options" style="display: block;">
<label class="lblDepartureArrival"></label>
<label class="lblRadio frmButtonFlat lblDeparture"></label>
<label class="lblRadio frmButtonFlat lblDeparture"></label>
<span class="lblOmmit"></span>
<label class="lblCaptionCarrierType"></label>
<label class="lblCarrierType lblCheckbox frmButtonFlat carrierType-bus"></label>
<label class="lblCarrierType lblCheckbox frmButtonFlat carrierType-rail"></label>
<label class="lblCarrierType lblCheckbox frmButtonFlat carrierType-aut"></label>
<label class="lblCarrierType lblCheckbox frmButtonFlat carrierType-city"></label>
<label class="lblCaptionJourneyMode"></label>
<span class=""></span>
<span class=""></span>
<span class=""></span>
<label class="lblSort">
<span class="fldCaption">
Sortuj według:
</span>
<span class="fldContainer">
<select id="sortTypeV_1399324651976" name="formCompositeSearchingResults.formCompositeSearcherFinalH.sortTypeV" style="display: none;">
<option selected="selected" value="departure"></option>
<option value="time"></option>
<option value="price"></option>
</select>
<span class="frmDropdown"></span>
</span>
</label>
<a class="lnkSwitchSearcherType" title="Wyszukiwarka zaawansowana" href="/public/searcher.do?method=task&advanced=false"></a>
</div>
I specifically need to expand list:
"<select id="sortTypeV_1399324651976" name="formCompositeSearchingResults.formCompositeSearcherFinalH.sortTypeV" style="display: none;">" and then click "<option value="time"></option>
This doesn't work:
def do_the_advanced_search(self):
self.driver.find_element_by_xpath('//*[#id="frm_1399323992507"]/fieldset/div/div[2]/label[3]').click()
time.sleep(3)
neither this:
self.driver.execute_script("document.getElementById('sortTypeV_1399324651976').style=='display: inline block';")
Thanks for any help.
To expand the part that contains the dropdown, you can use this:
self.driver.find_element_by_css_selector("a>span.imageSprite.sprite-label-left").click()
Then you can use execute_script to set the value:
self.driver.execute_script("document.getElementsByClassName('current').value = 'Najkrótszy czas';")
The select itself is hidden via style=display:none; so it cannot be manipulated directly.