selenium does not perform click operation - python-3.x

I am trying to get information from Kaggle, This task specific.
I would like to go in selenium over all the solutions.
I have this code:
main_window = driver.current_window_handle
elements = driver.find_element_by_class_name("sc-oUaSW").find_elements_by_xpath(".//li")
for element in elements:
ActionChains(driver).move_to_element(element).click().perform()
driver.switch_to.window(driver.window_handles[1])
WebDriverWait(driver, 10).until(EC.visibility_of_element_located(
(By.XPATH, "//a[#class='KernelViewerContext_KernelTitle-sc-rdaqnd chqxNN']")))
driver.close()
driver.switch_to.window(main_window)
it worked a few times, and then (clicked on the solution, opened the solution in a new tab, and closed this tab when I finished).
But now,
ActionChains(driver).move_to_element(element).click().perform()
does not click well on the element (when clicking on the element, a new tab should be opened)
What am I doing wrong?

Related

How to verify if a button from a page is really disabled in a chromedriver window on Python? Selenium related

I'm trying to automate a process on this page, and after several attempts, I still have not figured out why the code below print True when checking if the first_wallet_option button is enabled, here:
driver.get('https://opensea.io/') #go to the opensea main page.
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="__next"]/div/div[1]/nav/ul/div[2]/li/button'))) #wait for the wallet button to be enabled for clicking
wallet_button = driver.find_element(By.XPATH, '//*[#id="__next"]/div/div[1]/nav/ul/div[2]/li/button')
wallet_button.click() #click that wallet button
first_wallet_option = driver.find_element(By.XPATH, "/html/body/div[1]/div/aside[2]/div[2]/div/div[2]/ul/li[1]/button")
print(first_wallet_option.is_enabled())
What happens is that after the page has been loaded, the program clicks the wallet icon located at the top right corner of this page, and according to its html source, those buttons are clearly disabled at the moment it is done, as shown down below:
But, if I click twice the same wallet icon (one to close the aside element, and other to open it again), they get enabled:
So, I would like to learn how could I improve the code above to make sure it really detects when all of those 4 buttons (Metamask and the other 3) are enabled.
Ok, here it is:
First: The locators are not relative enough, so I took the freedom to refactor them.
Second: MetaMask is not a button as per DOM DOM Snapshot but the rest are. However, instead of relying on the buttons, I tried to rely on the li (which is common for all), and checking whether they are enabled or not.
Third: If you are trying to find if all the 4 elements are enabled, then you must use find_elements instead of find_element and then loop through the elements to check if each is enabled.
Please check if this works for you:
driver.get('https://opensea.io/') #go to the opensea main page.
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, "//*[#title='Wallet']"))) #wait for the wallet button to be enabled for clicking
wallet_button = driver.find_element(By.XPATH, "//*[#title='Wallet']")
wallet_button.click() #click that wallet button
wallet_options = driver.find_elements(By.XPATH, "//*[#data-testid='WalletSidebar--body']//li")
for wallet in wallet_options:
if wallet.is_enabled():
print(f"{wallet.text} is enabled")
else:
print(f"f{wallet.text} is not enabled")

How to close popover/popup by <a> element using Selenium

I'm working on a webscraper for https://www.grailed.com/designers/jordan-brand/hi-top-sneakers. When the page has opened a popup for login comes up. Searching through the web design I can locate the X element to close the browser like so: temp = WebDriverWait(driver, 10).until(ec.visibility_of_element_located((By.CLASS_NAME, 'close'))). If I go more into this there is an and element. I have tried using .click() on the element (with class 'close'), as well as the SVG and path elements. None of these close the box, and there is no button or other element of this kind for the X. What can I do to close this popover? I'm not sure if I need to find a button-ish element to click, but I can't find one like that. I've looked at a couple of questions and articles (https://stackoverflow.com/questions/61923909/trying-to-close-popover-python-selenium-glassdoor, https://sqa.stackexchange.com/questions/5310/how-to-close-pop-up-window-in-selenium-webdriver, https://saucelabs.com/resources/articles/the-selenium-click-command) but can't find a solution.
You can do double click with actions for resolving this problem
WebDriverWait(driver, 20).until(ec.visibility_of_element_located((By.XPATH,
'//a[#class = 'close']/*[name()='svg']')))
close = driver.find_element_by_xpath("//a[#class = 'close']/*[name()='svg']")
actionChains = ActionChains(driver)
actionChains.double_click(close).perform()
And the Java code for this:
new WebDriverWait(driver, 20)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[#class = 'close']/*[name()='svg']")));
WebElement close = driver.findElement(By.xpath("//a[#class = 'close']/*[name()='svg']"));
Actions action = new Actions(driver);
action.doubleClick(close).build().perform();
I actually just ran into the same issue myself. The above solution didn't work for me, so I'll post what I did here:
Essentially, I clicked by the coordinates instead of by trying to find the button element.
Note: some webpages don't display the popup until you try to click something else, so I had to first attempt to click another element. If you need to do that, make sure to wait a second or so for the popup to load.
Then, you can do the rest via ActionChain:
elem = driver.find_element_by_class_name("CLASSNAME")
ac = ActionChains(driver)
ac.move_to_element(elem).click().perform()
You'll want to encase this in a try-except block for extra safety.
Credit to Dirk Bergstrom for providing part of the solution here: Clicking at coordinates without identifying element

Scrolling down with Python Selenium on part of the web page

So I have a web page where a part of the page is a user list. A user can scroll down this list, but scrolling only works if the mouse pointer is located above this list. Keys like page down or end do not work.
I can locate the element using Selenium and Xpath without any issue, but I don't know how to perform the scrolling in selenium as it only works when the focus is on that specific web element.
I've tried sending keys like page down and end or code like
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Anybody got any ideas?
Because you mentioned you can locate the element, you could try scrolling to the specific element, instead of using document.body.scrollHeight as your scroll target.
element = driver.find_element(someLocatorHere)
driver.execute_script("arguments[0].scrollIntoView(true);", element)
Hope this helps a bit.
Scrolling can be achieved in two different ways.
Javascript
elementId = driver.find_element_by_id("elementId")
driver.execute_script("arguments[0].scrollIntoView();", elementId)
Action class
actions = ActionChains(driver)
actions.move_to_element(elementId).perform()

Selenium Scroll down on Newly Opened Body

I am working with Selenium python, and would like to scroll down on a page after clicking an element. Clicking the element gives a pop-up menu, and then when I try some scrolling methods they scroll on the original page.
I have selected the body of the new element that has appeared and tried this:
from selenium import webdriver
from selenium import Keys
driver = webdriver.get(url)
button = driver.find_element_by_xpath(pathto)
button.click()
body = driver.find_element_by_css('body')
body.send_keys(Keys.PAGE_DOWN)
This does not actually do anything as is. However, if I first manually click on the new popup element before doing body.send_keys(Keys.PAGE_DOWN), it does scroll.
One way I have resolved this is using ActionChains to right click on the body before scrolling down. Directly using .click() on the body does not work as it clicks a link in the body.
Are there any better ways to do this? In particular, I am somewhat afraid that the right click menu that opens up when I use my current method may mess with the rest of the scraping. Is there at least a method to guarantee that it does not interfere? Another solution could be somehow "selecting" or clicking on the body element within selenium, so are there any suggestions for this?
You could try using END key instead of DOWN key. It's worth a shot:
from selenium.webdriver.common.keys import Keys
driver = webdriver.get(url)
button = driver.find_element_by_xpath(pathto)
button.click()
driver.find_element_by_tag_name('body').send_keys(Keys.END)
You also may need to click the pop-up in order to focus it first:
from selenium.webdriver.common.keys import Keys
driver = webdriver.get(url)
button = driver.find_element_by_xpath(pathto)
button.click()
# click popup menu to get it into focus
popup_menu = driver.find_element_by_xpath(pathToPopupMenu)
popup_menu.click()
driver.find_element_by_tag_name('body').send_keys(Keys.END)

Cannot execute if else statement code when checking button is enabled

I'm trying to check the button on indeed.com after you click apply job, but my code doesn't seem to work.
The first if to check if the continue button is enabled if not, then it will close the page, switch to the main window and apply for the next job. The if else inside the if statement to check if there another continue button, it will close the page and switch to main window if not click on apply button to finish and close the page then switch to main window.
Sorry, I cannot post pictures yet so I have to link them.
Here's the picture after you hit apply job
https://imgur.com/FzITw8q
Here's the picture if there another continue button
https://imgur.com/iJMFqp8
Here's the picture if there's no continue button and only apply button https://imgur.com/62KMUwY
And the last one https://imgur.com/ls4mwEi
# Click on continue button if there any
if WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((By.XPATH,'//*[#id="form-action-continue"]'))).is_enabled():
WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((By.XPATH,'//*[#id="form-action-continue"]'))).click()
if WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((By.XPATH,'//*[#id="form-action-continue"]'))).is_enabled():
self.driver.close()
self.driver.switch_to.window(main)
else:
WebDriverWait(self.driver, 30).until(EC.presence_of_element_located((By.XPATH,'//*[#id="form-action-submit"]'))).click()
self.driver.close()
self.driver.switch_to.window(main)
#If no button close the window and switch to main window
else:
self.driver.close()
self.driver.switch_to.window(main)
I also tried is_displayed() but it doesn't work at all.
First, I am wondering how you are calling isEnabled() on WebDriverWait. This will just wait for an element until it is located and won't return its WebElement. Hence, when you apply is enabled in line 1, 2 and 3, it throws an error.
First assign that element to one variable, and call that variable in WebDriverWait. Once element is located/ waited until element located by WebDriverWait, use click or is enabled methods using variable instead of WebDriverWait.

Resources