I am having trouble locking down an xpath on a website.
Normally I would just use wait for the path to be clickable and then use it like so:
wait.until(EC.element_to_be_clickable((By.XPATH, ('//input[#value="2~Replace#emailhere.com"]'))))
However the email Replace#emailhere.com changes every time based on what we specify. So I am going to have that in a variable like so: namevar = "Replace#emailhere.com"
But the 2- in front of the email is the row that the email appears on the wesbite. I want to try and find the input button on the website based on the email address alone since the row maybe different.
If I try this, it fails:
###Code above this###
testvar = "*-Replace#emailhere.com"
im_blacklistaddbutton = browser_options.browser.find_element_by_xpath(('//input[#value="'+testvar+'"]'))
im_blacklistaddbutton.send_keys(Keys.SPACE)
I get this failure:
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//input[#value="*-Replace#emailhere.com"]"}
Here is what the element structure is like:
<input type="checkbox" value="2~Replace#emailhere.com" name="uxLvwList_lstChk_0">
Here is a picture of what the webpage and element looks like:
Structure the predicate in your XPath expression to use the contains() function instead of an equality condition:
//input[contains(#value, '-Replace#emailhere.com')]
Related
I want to enter a value into a field
I find the element by:
driver.find_element_by_xpath('//*[#id="cell--gE-Ez1qtyIA"]')
And I do this to display the text and click:
driver.find_element_by_xpath('//*[#id="cell--gE-Ez1qtyIA"]').click()
driver.find_element_by_xpath('//*[#id="cell--gE-Ez1qtyIA"]').text
So far so good, but I use this code when I want to send a value to this field:
driver.find_element_by_xpath('//*[#id="cell--gE-Ez1qtyIA"]').send_keys('test')
Nothing happens and the field value does not change
Since we are unaware about the nature of the text box you are trying to access, there are some possibilities because of which you are facing this situation. The send_keys() works on all the text box which ever you use. Look for the points below and try applying it on the element:
The element is not extracted properly, try some other locator like id, name, css_selector.
The element is not ready to use, put some explicit wait and check for presence and visibility of element.
A sample code can be using explicit wait:
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_all_elements_located(("xpath", "//*[#id='cell--gE-Ez1qtyIA']")))
element.send_keys("test")
Try to use javascriptexecutor instead of sendkeys
WebDriver driver = new ChromeDriver();
JavascriptExecutor je = (JavascriptExecutor)driver;
je.executeScript("document.getElementById('IDofElement').setAttribute('value', 'your value here')");
After deployement id of elements are changed. So that can not select those element by id in selenium using python.
Suppose I want to find the below element in HTML.
<input class="o_form_input c_field-65 o_form_field o_form_required" id="o_field_input_22" type="text">
I can not use the element's class because there will be elements with the same class.
I would like to find element without using Xpath because if new fields are added in the development side then Xpath will be changed.
In that case you should not be locating your element by id (since it not steady).
For example you can use Xpath (other locators may also work):
login_form = driver.find_element_by_xpath("//form[#id='loginForm']")
or
username = driver.find_element_by_xpath("//form[#id='loginForm']/input[1]")
Now the only thing that you can't copy from this, is the xpath it self. That is specific to your website/html/DOM.
An easy way of getting a correct xpath is by inspecting elements using f12 and then right click on the element, go to copy and select [copy xpath]. You can than paste it into your code.
Let me know it this was helpfull!
I get an 'Element Not Visible Exception' when trying to click on a Search option on a webpage. The element is not hidden, and I have put a time.sleep(10) so the page has enough time to load. Please suggest why I am getting this error and how I can get around it.
I want to click on 'New Search' option in the code.
<a class="newsearch btn btn3d tbbtn" href="javascript:" style="position:static">
<div id="TBnewsearch"><img src="../../../../resources/images/mt_sprites.gif"
alt="New search" />
</div>
<span>New search</span>
</a>
Please find my code for clicking on it below :
time.sleep(10)
New_Search = browser.find_element_by_css_selector(' #Toolbar > table > tbody > tr > td.TBGroup.TBGroup1 > a.newsearch.btn.btn3d.tbbtn')
action2 = ActionChains(browser)
action2.move_to_element(New_Search).click()
action2.perform()
I've also tried doing a simple find and click on the element but get the same exception at the New_Search.click() step.
time.sleep(15)
New_Search = browser.find_element_by_xpath('//*[#id="Toolbar"]/table/tbody/tr/td[2]/a[1]')
New_Search.click()
I've tried using WebDriverWait as suggested by Debanjan below, but the expected condition isn't satisfied and I get a timeout exception.
time.sleep(15)
WebDriverWait(browser, 15).until(EC.visibility_of_element_located(browser.find_element_by_xpath('//*[#id="Toolbar"]/table/tbody/tr/td[2]/a[1]')));
New_Search.click()
Can you test these locators in the Dev tools and check if they are pointing to the right element on the page? In the console use $x() to test XPaths and $$() to test CSS selectors. If it returns 0, you know there's something wrong with your locator. If it returns 1, you are good to go. If it returns more than 1, you will need to verify that the element you are looking for is the first element returned. If it's not, you will need to craft a new locator. I have a feeling that your current locators is returning 2 nodes, out of which the first one is invisible.
Try to access the target element using that elements ancestors. Keep going one level up till you find a node that is uniquely identifiable and then use relative xpath (//) to traverse down to your element. You can also use ordinals/index to locate the element, but i would not recommend it as they will make your test brittle. If possible update the question with a bigger snippet of the HTML or the applications URL
I have a button
<input type="submit" class="button button_main" style="margin-left: 1.5rem;" value="something">
I cannot find it by id or name and need to submit a form.
I tried doing this:
Alternatively, WebDriver has the convenience method “submit” on every element. If you call this on an element within a form, WebDriver will walk up the DOM until it finds the enclosing form and then calls submit on that. If the element isn’t in a form, then the NoSuchElementException will be raised:
element.submit()
http://selenium-python.readthedocs.org/navigating.html
But that cannot find the submit selector either.
ideas?
There are many options here, to name a few:
If class alone is unique, you can use
driver.find_element_by_css_selector(".button_main").click()
If class + value combo is unique, you can use:
driver.find_element_by_css_selector(".button_main[value='something']").click()
You can also use xpath:
driver.find_element_by_xpath("//input[#type='submit' and #value='something']").click()
If none of those work (i.e. they are not identifying button uniquely), look at the elements above the button (for example <form) and provide the xpath in format:
driver.find_element_by_xpath("//unique_parent//input[#type="submit" and #value='something']").click()
i recommend xpath chrome extension, with it you will be able to get the path by running the extension and shift-clicking on the element you want this chrome extension https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl
You could try to find the element with an XPath expression or a CSS selector like input[type="button"], and then just click the element.
I'm using Selenium and coding with Python.
I'm trying to do the following: for a flight search website, under Flight 1's 'Enter routing code' text box, type 'AA'
This is the code that I have at the moment:
flight1_routing = driver.find_element_by_xpath(".//*[#id='ita_form_location_RouteLanguageTextBox_0']")
flight1_routing.clear()
flight1_origin.send_keys("AA")
But instead, I get this error message: "invalid element state: Element is not currently interactable and may not be manipulated". How can this be with a regular text field that is also not an autocomplete field, AFAIK?
if you get Element is not currently interactable check if the element is not disabled and its visible. if you want to hack it execute JS to enable it.
i visited the homepage id ita_form_location_RouteLanguageTextBox_0 doesnt exist also under flight one there's no Enter routing code. i can see the text box saying airport city or city name
Also if you have the id prefer to use find_element_by_id if not try to use css selector if you can rather than xpath. Its much cleaner.
Update
here's a working script:
As recomended above, the elements selected are not visible. what is actualy done, is that there's 5-6 different elements all hidden and when you click on show advanced route it picks 2 random ones and makes them visible.
So the id is not always the same. If you use the same id you will get a hidden element some times(because it picks random ids) so selenium is not able to deal with it. i made a selector that gets the 2 hidden elements
from selenium import webdriver
import selenium.webdriver.support.ui as ui
driver = webdriver.Firefox()
driver.get("http://matrix.itasoftware.com/")
#click on the multi tab
tab = driver.find_element_by_id("ita_layout_TabContainer_0_tablist_ita_form_multislice_MultiSliceForm_0").click()
#click on the advanced routes
advanced_routing=ui.WebDriverWait(driver, 10).until(
lambda driver : driver.find_element_by_id("sites_matrix_layout_RouteLanguageToggleLink_1")
)
advanced_routing.click()
#get all visible elements with id like ita_form_location_RouteLanguageTextBox. its similar to regex ita_form_location_RouteLanguageTextBox.*
element = ui.WebDriverWait(driver, 10).until(
lambda driver : driver.find_elements_by_css_selector("[id*=ita_form_multislice_MultiSliceRow] [id*=ita_form_location_RouteLanguageTextBox]")
)
element[0].send_keys("foo")
element[1].send_keys("bar")
import time
time.sleep(20)
Did you click into the correct tab first & enable advanced routing codes?? e.g.
#Go to right tab
driver.find_element_by_css_selector("div#ta_layout_TabContainer_0_tablist_ita_form_multislice_MultiSliceForm_0 > span").click()
#Enable routing
driver.find_element_by_css_selector("a.itaToggleLink").click()
#note I seem to get a different id to the one you're using, assuming its dynamic numbering so handling all cases
#if you know how the dynamic numbering works youmay be able to deduce a single id that will work for your test case
#Instead I'm going for finding all elements matching a pattern then searching through them, assuming only one will be visible
flight1_routings = driver.find_elements_by_css_selector("input[id^='ita_form_location_RouteLanguageTextBox_']")
#probably better finding it then using it separately, but I was feeling lazy sorry.
for route in flight1_routings:
if route.is_displayed():
route.clear()
route.send_keys("AA")
Also you can probably skip the .clear() call as it looks like the box starts with no text to overwrite.
Edit: Updated the enable routing toggling to handle not knowing the id, the class name stays the same, should work. Handling finding the input despite variable id as suggested by foo bar with the css selector, just then iterating over that list and checking if its on top