I am trying to automate some selenium case in python, for the following special case, my current code does not work. As we could see from the following UI. In the first page, there is a "Client Interfaces" section, and it is meant to select from the dropdown list.
And when user is to click the dropdown list, it is listing bunch of checkboxes, where user needs to make further selections.
Now here is my code:
dropdwon_xpath = "..."
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.XPATH, dropdown_xpath))).click()
# The XPATH of "Client Interfaces" is: ".../div/div[1]/div"
# The XPATH of the lte1 checkbox is: ".../div/div[2]/div/div[1]/div/label"
# And here is my customized XPAH of lte1 bases on the location of "Client Interfaces".
lte1_checkbox = "//div[.='Client Interfaces']/ancestor::div[1]/following-sibling::div[1]/div[2]/div[1]/div/input"
WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.XPATH, lte1_checkbox ))).click()
But it never works. During the runtime, I do see the dropdown happens, but it did not do any further selection on those checkboxes. Any suggestions what I could try ?
Thanks,
Chun
Here is the screenshot of the html layout for this area:
I don't have answer yet, and I just want to give extra inputs for what I have found.
I have tried the xpath Arundeep Chohan suggested as such:
//div[#class='col-4'][.//div[.='Client Interfaces']]/following-sibling::div[1]/div[2]/div[1]/div/input
and the issue stays. I believe both of Arundeep's and mine should be working. And I have purposely tried following code to check at what point it become "invisible" during the execution time.
BY = By.XPATH
point1 = "//div[#class='col-4'][.//div[.='Client Interfaces']]/following-sibling::div[1]"
point2 = "//div[#class='col-4'][.//div[.='Client Interfaces']]/following-sibling::div[1]/div[2]"
point3 = "//div[#class='col-4'][.//div[.='Client Interfaces']]/following-sibling::div[1]/div[2]/div[1]"
point4 = "//div[#class='col-4'][.//div[.='Client Interfaces']]/following-sibling::div[1]/div[2]/div[1]/div/input"
WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((BY,point1))).is_displayed()
WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((BY,point2))).is_displayed()
WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((BY,point3))).is_displayed()
WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((BY,point4))).is_displayed()
What I have found is, point1 still visible, but since point2, it becomes "invisible", although the dropdown already happened. And I guess that is why my original script is kind of "disoriented". Those "div[2]/div[1]/div/input" are actually from those checkbox pieces after the dropdown happens.
Thanks,
Chun
Related
My goal is to get an element within a dropdown menu that needs to be clicked in order to appear using python selenium. Also, it seems that before the click, hovering is necessary.
I tried to click the dropdown menu like this:
element = wait().until(EC.presence_of_element_located((By.CLASS_NAME, "c-topmenu c-topmenu--create c-topmenu--userbar tw-inline-flex")))
element.click()
def wait():
return WebDriverWait(driver, 30)
And tried to use hovering:
Hover = ActionChains(driver).move_to_element(element)
Hover.click().build().perform()
Still, I get a TimeoutException and can't figure out a solution.
The website komoot looks like this before clicking the dropdown menu:
The website komoot looks like this after expanding it:
Ok here is how i was able to get this working.
after the login i grapped the wrapper element from the link with:
more_menu_wrapper = driver.find_element_by_css_selector("div[data-test-id='more_menu']")
after that i could click the desired element with:
more_menu_wrapper.find_element_by_tag_name("a").click()
You are using a wrong locator.
In case of multiple class names you should use css_selector or XPath, not by class name.
Also, here you have an unique attribute of data-test-id, you should use it.
Also, you should wait for element visibility or clickability, not just for element presence.
So your code could be:
element = wait().until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div[data-test-id='more_menu']")))
I want to click the configuration button, which leads to discord profile information,
Guys, I want to click on the gear at the bottom, how can I do this? This is my code:
option = Options()
option.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=option)
driver.get("https://discord.com/channels/395582581124497408/395582581124497412")
wait = WebDriverWait(driver, 5)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.item'))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#contents-18-Yxp"))).click()
Can anyone help me with this problem?
you can click it with this code:
driver.find_element_by_css_selector('div'[aria-label="User settings"]').click()
Find the ID of that button, then use driver.find_element_by_id("ID").click()
You should read this tutorial https://www.geeksforgeeks.org/click-element-method-selenium-python/
First, you must get an identifier for your element, for example:
class
xpath
css selector
... etc
then drive.find_element_by_(class, xpath, ...)(string).click()
Example:
driver.find_element_by_xpath('(//*[#class="contents-18-Yxp"])[7]')
this is the identifier for the settings section, you can copy it, note that this xpath can be changed if the discoed is updated, the solution is easy, just with the same way get the new xpath and paste it instead of the old one.
with the same Technique, find the user profile identifier, and paste it and remember .click()
I'm coding my first "bot" with python and webdriver
I would like to loop until a specific button shows up on the website. My idea is to check if the button is available. If not, sleep for a minute, reload, and check again. But I dont know the right syntax as this element seems too complicated for me.
Does anyone have a tip?
Edit: When the product is sold out, this button does not exist on the product page. I guess enabled/disabled won't work here, because the button does not exist if the product is unavailable. I guess I need to check, if the button exists.
You can use WebDriverWait in python selenium to wait till the element is loaded. Or you can use javascript to check if the element exists in the DOM or not:
buttons = document.getElementsByClassName("mu-button mu-button--type_alternative add-to-cart");
if (buttons.length == 0) {
# it doesn't exist
} else
{
# do something
}
Full documentation: https://selenium-python.readthedocs.io/waits.html
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
I'm trying to click on a button that is only visible when hovering over it.
move_to_element doesn't seem to work and I get this error when trying to click ElementNotVisibleException: Message: element not visible
My code is:
full_screen_elem = driver.find_element_by_xpath(
'//*[#id="grid"]/div[2]/div[1]/article/div[3]/a')
hover = ActionChains(driver).move_to_element(full_screen_elem)
hover.perform()
full_screen_elem.click()
I've also tried this:
driver.execute_script('arguments[0].click();', full_screen_elem)
But it also doesn't work.
What else can I try?
Try and make it visible using Javascript.
I assume the style-attribute of your element is set to hidden. You must set this to visible.
You can do this as following:
driver.execute_script('document.getElementById("element").style.visibility = "visible";);
Then you can interact with the element.
Be sure to double check the syntax from above script because I am a little rusty :)
So I am trying to fill out a form on this site. Every time I try to click the submit button at the end, using what I believe is the correct id, it just gives me an error. Here is a code snippet:
from selenium import webdriver
thePassword = "asdf123"
print("Desired name: ")
name = raw_input()
print("Desired Last Name: ")
userLastName = raw_input()
browser = webdriver.Firefox()
browser.get('https://www.panerabread.com/en-us/mypanera/registration-page.html')
firstName = browser.find_element_by_id('join_first_name')
firstName.send_keys(name)
lastName = browser.find_element_by_id('join_last_name')
lastName.send_keys(userLastName)
emailElem = browser.find_element_by_id('join_email')
emailElem.send_keys("asdafasda" + "#gmail.com")
emailConfirm = browser.find_element_by_id("join_confirm_email")
emailConfirm.send_keys("asdafasda" + "#gmail.com")
password = browser.find_element_by_id("join_password")
password.send_keys("thePassword")
passwordConfirm = browser.find_element_by_id("join_confirm_password")
passwordConfirm.send_keys("thePassword")
phoneA = browser.find_element_by_id("phone_number_a")
phoneA.send_keys("231")
phoneB = browser.find_element_by_id("phone_number_b")
phoneB.send_keys("123")
phoneC = browser.find_element_by_id("phone_number_c")
phoneC.send_keys("2310")
tos = browser.find_element_by_id("join_i_agree")
tos.click()
browser.execute_script("$('#join_password').get(0).scrollIntoView();")
#browser.implicitly_wait(10)
# And then perform the click
browser.find_element_by_id("join_card_not_available").click()
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
print "Your email is: " + "asdafasda" + "#gmail.com"
print "Your password is: " + thePassword
My question is, how can I submit the form at the end of my script?
Edit: There is no error. The problem is that it doesn't click the button I want it to at all. I tried running the below code on a seperate file and it worked, however when you run it with this entire script it does not work.
This was a weird one... it took me a minute to figure out what was going on. The problem is that there are actually two elements that have that id on the page (which is a no-no according to the HTML standard... but alas it happens). One on the bottom of the page that you are looking at and another on the Sign In popup. If you click the Sign In button at the top of the page, you will see the (first) Sign In button on the popup. Because it is hidden, your code wouldn't click on it. Anyway... to the solution.
There are a few ways you can handle this, any of them valid. I would do this.
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
What this is doing is using a CSS selector to get all the elements with ID=join-now-primary. The CSS selector is #join-now-primary which means id (#) of join-now-primary. Because it uses .find_elements (plural), it will get both. We then use [1] to get the 2nd element (0-based index, so 1 is the 2nd) and then click on it.
EDIT
My guess is that it's a timing issue that is causing the code to work on its own but not in your script. Put a breakpoint on the first line and step through each line and make sure that it executes. Does it work? If I were to guess again... it's likely the line right before the Join Now click. That click has an animation that closes the credit card picture. I would wait for that section to become invisible using the code below
element = WebDriverWait(browser, 5).until(EC.invisibility_of_element_located(By.ID('panera-card-section')))
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
You didn't really ask a question but it's likely you need to look at the WebElement class's methods and properties.
Looks like the button might not be in the visible portion of the window based on your code.
WebElement Has a property call that scrolls until an element moves into view.
If an element is not visible by Selenium definition, it is not clickable.
Even though you use the guts of the page to drive it, selenium wants to pretend it is testing human like interaction and so provides an artificial constraint.
You can bypass that by executing JavaScript click() on the element.