Able to select "I'm Feeling Lucky" but cannot click it - python

I am trying to write a simple program to open up chrome, go to Google, and click on "I'm Feeling Lucky." I see that it acts as if the cursor is placed over the icon, but it will not perform a click.
driver.get("https://www.google.com")
element = WebDriverWait(driver, 20) \
.until(EC.visibility_of_element_located((By.ID, "gbqfbb")))
element.click()
No errors occur in the code, but it will not click the element.

I cannot find that ID either.
here's what worked for me using css_selector
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from appium.webdriver.common.mobileby import, By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://www.google.com")
element = WebDriverWait(driver, 20) \
.until(EC.visibility_of_any_elements_located((By. CSS_SELECTOR, '[name="btnI"][type="submit"]')))[0]
element.click()
I suggest to use visibility_of_any_elements_located over visibility_of_element_located. The reason is that the selector finds two elements. One visible and one that is not.
When using visibility_of_element_located it will use find_element and it will get the element that is not visible.
When using visibility_of_any_elements_located it will use find_elements and it will get both elements. it will loop through all elements and if one or more are visible it will return it right away.

Where you get that ID? When I visit the site, I don't see an element with that ID. It's possible that Google has some sort of way of manipulating this to make it harder for people to automate this process. It's possible that Google doesn't want you doing this.
Either way, you should be able to select the element by something else:
driver.get("https://www.google.com")
element = WebDriverWait(driver, 20) \
.until(EC.visibility_of_element_located((By. CSS_SELECTOR, '[jsaction="sf.lck"]')))
element.click()

driver.findElement(By.xpath("//div[#class='FPdoLc lJ9FBc']//following::input[#class='RNmpXc']")).click();

Related

Xpath locator unable to detect the element

I am trying to select a button using selenium however i believe i am doing something wrong while writing my xpath can anyone please help me on this i need to select the currency Euro.
link :- https://www.booking.com/
Locator which i want to select
Locator which i have written
USD = self.find_element_by_xpath(f"//a[contains(text(),'selected_currency='Euro']")
USD.click()
The below xpath
//a[contains(#href,'EUR') and starts-with(#class,'bui-list')]
is present two times in HTML DOM.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
In case you would like to select the first one which is in Suggest for you, there is no need to do anything with respect to XPath.
#pmadhu answer is misleading, since why would anyone look for first index in XPath when using with Selenium ? If there are multiple matching node, Selenium is always going to pick up the first element, So it really does not make any sense to me that why would someone use [1]
Nevertheless,
to click on Suggest for you EURO :
try:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#href,'EUR') and starts-with(#class,'bui-list')]"))).click()
except:
pass
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
In case you are looking to click on second matching node for EUR,
in that case it make sense to use index 2.
XPath would look something like this :
(//a[contains(#href,'EUR') and starts-with(#class,'bui-list')])[2]
The text you are looking for: selected_currency='EUR' is in the data-modal-header-async-url-param parameter of the a tag. You should run the contains on that.
Edit:
Locator: //a[contains(#data-modal-header-async-url-param, 'selected_currency=EUR')]
As already explained, selected_currency=EUR is in the attribute - data-modal-header-async-url-param.
However you can select the required option, with below code.
The xpath for the EUR option can be - //div[contains(text(),'EUR')]. Since it highlights 2 elements in the DOM using this xpath- (//div[contains(text(),'EUR')])[1]. Its important to find unique locators. Link to refer
# Imports required for Explicit wait
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver.get("https://www.booking.com/")
wait = WebDriverWait(driver,30)
# Click on Choose currency option
wait.until(EC.element_to_be_clickable((By.XPATH,"//span[#class='bui-button__text']/span[contains(text(),'INR')]"))).click()
# Click on the EUR option.
euro_option = wait.until(EC.element_to_be_clickable((By.XPATH,"(//div[contains(text(),'EUR')])[1]")))
euro_option.click()

using Selenium in Python to click on the right checkbox

I am very new to using selenium but I cannot find way around a very simple task.
I need to be able to click on the element that specifies bedrooms: 2.
I have used I don't know how many references by xpath, by id, by name, by class but selenium just won't find the element. I also have tried to browse the internet but could not find solutions that help me.
Here's the sanpshot
For instance: using
driver.find_element_by_id('agatha_bedrooms1588844814480_advancedSearch1').click()
This won't work. Selenium cannot find the element. It seems that this element is within another element but I don't understand how to access it.
Could you help me please?
Thanks a lot to you.
G
The ids seem to be dynamically generated, in which case you cannot rely on them. Try with this xpath:
driver.find_element_by_xpath("//*[#name='bedrooms' and #value='2']/following::label").click()
Although it is generally good practice to work with waits. So something like:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[#name='bedrooms' and #value='2']/following::label"))).click()
Ensure to have these imports for the wait to work
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
Thanks a lot, after multiple and multiple trials I could get around that way:
elemt = driver.find_element_by_xpath("//*#name='bedrooms']").find_element_by_xpath("//[#value='2']")
idvar = elemt.get_attribute("id")
elemt2 = driver.find_element_by_xpath("//label[#for='" + idvar + "']")
elemt2.click()
It seems that the checkbox was hidden under the label (?!) so that Selenium did not want to click on it.
If the checkbox is inside of an iframe, do this:
# basically just select the iframe any way you want
frame = driver.find_element_by_css_selector("iframe")
driver.switch_to.frame(frame)
driver.find_element_by_id('agatha_bedrooms1588844814480_advancedSearch1').click()
edit:
I've found solution. Kinda ugly but works lol
element = driver.find_elements_by_css_selector("input[name=bedrooms][value='2']")[0]
element.find_element_by_xpath("..").click()
You can try this xpath. hope its helps:
//*[#name='bedrooms']/following::*/*[text()='2']

Python Selenium - Attempting to write wait condition for when text changes in table element

I am attempting to write a selenium script to search for terms on a webpage, then select them from a table.
The table is dynamic and changes when elements are entered into the search field. Typically when I have written selenium code in the past, I have just used wait statements to wait for some element on the page to load before continuing. With this, I specifically need to wait until the element I am looking for to appear in the table, and then to select it.
Here is what I currently have written, where tableElement is the table I attempting to search through, and userID is the input I am hoping to find:
tableElement = self.driver.find_element_by_xpath(
'X-PATH_TO_ELEMENT')
ui.WebDriverWait(self.driver, 15).until(
EC.text_to_be_present_in_element(
tableElement, userID)
)
When running this code, I receive the following error message:
find_element() argument after * must be an iterable, not WebElement
As far as I am aware, this should be the correct syntax for the method I am attempting to call. Any help would be appreciated! Please let me know if I need to elaborate on any details.
Expcted condition are basically used with find_element and find_elements.
In your code you have provided web element to EC instead of locator.
you can use below code to use EC in your code :
WebDriverWait(driver, 30).until(
EC.visibility_of_all_elements_located((By.XPATH, "xpath of your element")))
Note: you have to add below importss to your solution:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

ElementClickInterceptedException while trying to click a checkbox within surveymonkey.com through Selenium and Python

I'm playing around with a mini-challenge that's been set to automate a form response on survey monkey, I've set up a dummy survey for the purpose of this example.
Essentially, selenium is unable to click the box due to an error with a button display obscuring it.
ElementClickInterceptedException: Message: Element input id="234136539_1601280849" class="checkbox-button-input " name="234136539[]" type="checkbox"> is not clickable at point (237.5,345.5) because another element span class="checkbox-button-display "> obscures it
I've looked at this question which is Java specific, and I can't quite get my head around how I go about getting past this, I've tried implicit waits, clicking on the box around it but a little lost where to begin without learning Java.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get('https://www.surveymonkey.com/r/L9DJGXR')
vote_check = driver.find_element_by_id('234136539_1601280849')
vote_check.click()
This code should replicate the problem with the dummy survey.
Right-click on the checkbox next to "Me" and choose Inspect... what element is selected? The SPAN. That's because the SPAN overlaps the INPUT you want to click. That's what that error is telling you. You are trying to click on an element that is covered by another element. Selenium can't "see" the page to see that the element underneath is not really obscured.
The solution is to click either the SPAN that was in the error or the LABEL. It doesn't really matter which you do, both will work. Two CSS selectors are below
[id='234136539_1601280849'] + label // clicks the LABEL
^ has this ID
^ '+' means sibling
^ LABEL tag
[id='234136539_1601280849'] + label > span // clicks the SPAN
everything is the same as above until...
^ '>' means child
^ SPAN tag
To click the second check box associated with text Me you have to induce WebDriverWait for the element to be clickable and you can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox(executable_path=r'C:\Utility\BrowserDrivers\geckodriver.exe')
driver.get('https://www.surveymonkey.com/r/L9DJGXR')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='question-body clearfix notranslate ']//following::label[2]"))).click()
Browser Snapshot:

Check whether element is clickable in selenium

I'm able to verify whether or not an element exists and whether or not it is displayed, but can't seem to find a way to see whether it is 'clickable' (Not talking about disabled).
Problem is that often when filling a webform, the element i want may be overlayed with a div while it loads. The div itself is rather hard to detect as it's id, name and even the css is flexible. Hence i'm trying to detect whether or not a input field can be 'clicked' or 'filled'. When the overlaying div is present, the field cannot be filled by a regular user (As the div would overlay the input field and not allow the user to fill it) but it can be filled by selenium. I want to prevent that and only allow selenium to fill it once the user can also fill it.
You can wait for the element to be clickable:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain")
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "myDynamicElement"))
)
Or, you can follow the EAFP principle and catch an exception being raised by click():
from selenium.common.exceptions import WebDriverException
try:
element.click()
except WebDriverException:
print "Element is not clickable"
You can use webElement.isEnabled() and webElement.isDisplayed() methods before performing any operation on the input field...
I hope this will solve you problem...
Else, you can also put a loop to check above 2 conditions and if those are true you can specify the input text and again you can find the same element and you can get the text of the webelement and compare that text with the text you entered. If those matches you can come out of the loop.
to click an (for selenium) unreachable element i alwas use:
public void clickElement(WebElement el) throws InterruptedException {
((JavascriptExecutor) driver).executeScript("arguments[0].click();", el);
}

Categories