Python Selenium click() doesn't work - python

I am trying to automate a web file downloading program with Selenium in Python. But I have some difficulties in clicking one particular button with Selenium: The program succeeds in leading to this url 'https://www.sec.gov/Archives/edgar/data/1467373/000119312510235847/0001193125-10-235847-index.htm', but it cannot click on the button of the first document (d10k.htm). The button is defined as 'formbuttonElement' in the following code and I tracked it by Xpath. In addition, I used both click() and .send_keys(Keys.SPACE) methods, but they didn't work.
Can someone have a look at this problem?
Thank you!
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import unittest
import os
class LoginTest(unittest.TestCase):
def setUp(self):
fp=webdriver.FirefoxProfile(r"C:\Users\sxc\AppData\Roaming\Mozilla\Firefox\Profiles\x5i7u4m7.profileToolsQA")
fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir", "D:\doc1")
fp.set_preference("pdfjs.disabled", True)
fp.set_preference("plugin.disable_full_page_plugin_for_types", "application/pdf")
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
self.driver=webdriver.Firefox(firefox_profile=fp)
self.driver.get("https://www.sec.gov/edgar/searchedgar/companysearch.html")
def test_Login(self):
driver=self.driver
cikID="cik"
searchButtonID="cik_find"
typeID="//*[#id='type']"
priorID="prior_to"
cik="00001467373"
Type="10-K"
prior="20101231"
search2button="//*[#id='contentDiv']/div[2]/form/table/tbody/tr/td[6]/input[1]"
documentsbuttonid="documentsbutton"
formbuttonxpath="(//a[contains(#href,'/Archives/edgar/data/')])[1]"
cikElement=WebDriverWait(driver,30).until(lambda driver:driver.find_element_by_id(cikID))
cikElement.clear()
cikElement.send_keys(cik)
searchButtonElement=WebDriverWait(driver,20).until(lambda driver:driver.find_element_by_id(searchButtonID))
searchButtonElement.click()
typeElement=WebDriverWait(driver,30).until(lambda driver:driver.find_element_by_xpath(typeID))
typeElement.clear()
typeElement.send_keys(Type)
priorElement=WebDriverWait(driver,30).until(lambda driver:driver.find_element_by_id(priorID))
priorElement.clear()
priorElement.send_keys(prior)
search2Element=WebDriverWait(driver,30).until(lambda driver:driver.find_element_by_xpath(search2button))
search2Element.send_keys(Keys.SPACE)
time.sleep(1)
documentsButtonElement=WebDriverWait(driver,20).until(lambda driver:driver.find_element_by_id(documentsbuttonid))
documentsButtonElement.click()
formElement=WebDriverWait(driver,30).until(lambda driver:driver.find_element_by_xpath(formbuttonxpath))
formElement.send_keys(Keys.SPACE)
def terdown(self):
self.driver.quit()
if __name__=='__main__':
unittest.main()

Try this line of code
driver.find_element_by_xpath('//a[text()="d10k.htm"]').click()

Related

How to click this button on this URL using selenium and Python?

from selenium import webdriver
from selenium.webdriver import ChromeOptions
from selenium.webdriver.common.keys import Keys
import configparser
from selenium.webdriver import ActionChains
import time
import os
class SeleniumConfig():
def __init__(self):
config = configparser.ConfigParser()
self.absolute = "C:\\Program Files (x86)\\chromedriver.exe"
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
self.driver = webdriver.Chrome(self.absolute, options=options)
def jupiter_1(self):
self.driver.get('http://jupiter.cloud.planittesting.com')
self.driver.find_element_by_id("nav-contact").click()
time.sleep(5)
form = self.driver.find_element_by_class_name(
"btn-contact btn btn-primary") # my issue seems to start at the submit button
time.sleep(5)
self.driver.quit()
I'm not sure why i'm not able to use the class name, as the inspection says it is
My error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn-contact btn btn-primary"}
(Session info: chrome=87.0.4280.141)
self.driver.find_element_by_css_selector(".btn-contact.btn.btn-primary")
Spaces in class names need to be replaced with . in order for proper xpathing.
Also try not to use time.sleep() and use the following to allow the page to load and for elements to be clickable.
wait = WebDriverWait(self.driver,10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn-contact.btn.btn-primary"))).click()
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
In my experience with selenium, the find_element_by_ can be a bit wonky and you sometimes have to try several reference techniques before one finally works. I'd recommend using the full Xpath as that seems to reliably work (it's drawback is that it is not as obvious to read in the code itself). You can get the xpath by inspecting the element in the html dev tool and just right click to copy it. An option for "copy full xpath" should show up somewhere.
With that in mind, you can try your code line to the following and see if it helps:
form = driver.find_element_by_xpath("/html/body/div[2]/div/form/div/a")
Hopefully that can at least point you in the right direction!
Nevermind i found the answer or a workaround =>
form = self.driver.find_element_by_link_text(
"Submit")
I use find_element_by_link_text to submit and it works.
Please use following relative xpath to click submit buttton
//a[#class='btn-contact btn btn-primary']

Python class to open and close website using Selenium

Trying to setup Chrome for the open / close a website. Now i can open it, But failed to close it.
Can anyone tell me why? Many thanks!
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class chromeSetup():
def __init__(self):
self.chrome_path = r'C:\XXXXX\chromedriver.exe'
def searchWeb(self, url="https://www.google.com.hk/"):
driver = webdriver.Chrome(self.chrome_path)
driver.get(url)
def close(self):
self.driver.close()
You are not making driver an instance attribute. Change searchWeb method like this:
def searchWeb(self, url="https://www.google.com.hk/"):
self.driver = webdriver.Chrome(self.chrome_path)
self.driver.get(url)

Cross-browser testing with Selenium and Python

I'm trying to run this code to perform some action in Chrome and Firefox, but when I run the test runner Chrome starts and the test cases are failing in Chrome, then Firefox opens and test cases work just fine in Firefox.
I've tried for loop and a couple of things that didn't work.
Here's my code:
from selenium import webdriver as wd
import pytest
import time
Chrome=wd.Chrome(executable_path=r"C:\Chrome\chromedriver.exe")
Firefox=wd.Firefox(executable_path=r"C:\geckodriver\geckodriver.exe")
class TestLogin():
#pytest.fixture()
def setup1(self):
browsers=[Chrome, Firefox]
for i in browsers:
self.driver= i
i.get("https://www.python.org")
time.sleep(3)
yield
time.sleep(3)
self.driver.close()
def test_Python_website(self,setup1):
self.driver.find_element_by_id("downloads").click()
time.sleep(3)
Instead of explicit sleep's, you should wait for the element:
from selenium import webdriver as wd
from selenium.webdriver.support import expected_conditions as EC
import pytest
import time
Chrome=wd.Chrome(executable_path=r"C:\Chrome\chromedriver.exe")
Firefox=wd.Firefox(executable_path=r"C:\geckodriver\geckodriver.exe")
class TestLogin():
#pytest.fixture()
def setup1(self):
browsers = [Chrome, Firefox]
for i in browsers:
self.driver = i
i.get("https://www.python.org")
yield
self.driver.quit()
def test_Python_website(self, setup1):
wait = WebDriverWait(self.driver, 10)
downloads = wait.until(EC.element_to_be_clickable(By.ID, "downloads"))
downloads.click()
Note: You probably want self.driver.quite(), as this will close the window and cause the browser process to close down as well. The call to self.driver.close() will only close the window, but will leave the firefox.exe or chrome.exe process running in memory after the test finishes.

Why i am not able to capture screen shot of selectbox items using selenium-python?

I have a select box on my page. I click on it to expand it and all values are displayed. Now i take screenshot, but in screenshot, select box is not expanded. Please check.
Code:
import unittest
from selenium import webdriver
import datetime
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.common.exceptions import NoSuchElementException
from unittest import TestCase
import re
import time
import autoit
url="https://www.facebook.com"
class SprintTests(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.driver.maximize_window()
self.driver.get(url)
def test_offer_1(self):
a=self.driver.find_element_by_id("day")
a.click()
time.sleep(5)
self.driver.save_screenshot("res.jpg")
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)
Image generated by my code:
Expected Image:
With the given situation, it is expected to behave in this way.
When you perform save_screenshot on driver object, the driver object is now busy getting the screenshot for you instead of keeping the select menu open.
One possible solution is that you launch the save_screenshot method in different thread.

Python Selenium - getting 'ElementNotVisibleException' error while trying to click on link

All I am trying to do is: go to "http://news.google.com" and click on the "Technology" link on the side menu. Here's my code:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import unittest, time, re
class GoogleTech(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.google.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_googletech(self):
driver = self.driver
driver.get("http://news.google.com")
#driver.find_element_by_xpath("//div[#id='main-wrapper']/div[#id='main-pane']/div[#class='background']/div[#class='centered']/div[#id='nav-menu-wrapper']/div[#class='browse-sidebar']/ul[#id='anchorman-two-browse-nav']/li[#class='nav-item nv-en_us:tc']/a[contains(text(),'Technology')]").click()
#driver.find_element_by_xpath("//ul[#id='anchorman-two-browse-nav']/li/a[contains(text(),'Technology')]").click()
#driver.find_element_by_xpath("//ul[#id='anchorman-two-browse-nav']/li[#class='nav-item nv-en_us:tc']/a[contains(text(),'Technology')]").click()
#driver.find_element_by_xpath("html/body/div[3]/div[1]/div/div/div[2]/div/ul/li[6]/a").click()
#driver.find_element_by_link_text("Technology").click()
wait = WebDriverWait(driver, 10)
link = wait.until(EC.presence_of_element_located((By.XPATH, "//ul[#id='anchorman-two-browse-nav']/li/a[contains(text(),'Technology')]")))
link.click()
time.sleep(10)
...
I've tried many combinations (all the commented out lines plus more!), but still cannot get it to work. I've check to make sure that the element I am using does exists (using Element Inspector) before entering it into the code. But even the "find_element_by_link_text" is giving me a NoSuchElementException exception. Can someone please tell me what I am doing wrong?
UPDATE: After doing further tests, I now have a better understanding of when this error is occuring for the news.google.com page. So, basically, the side menu, that contains the "Technology" link, is set to scrollable (I believe this error is only happening because the link is in scrollable area). The error is show up if the browser (that the Selenium script opens up when you run it), does not show the "Technology" link ie. You have to maximize the browser or scroll down to see the link. You can test this error out yourself - when the test opens up the browser, quickly resize the browser window so that the "Technology" link is not showing, and the test will fail. If your initial browser window doesn't show "Technology" link when it first opens, it will fail unless you maximize the browser window or scroll down really quickly until the "Technology" link is displayed. The error can take two forms - if you are using the wait.until method, you will get a Timeoutexception. If you are not using the wait.until method, you will see the ElementNotVisibleException. I've tested in both Chrome and Firefox and for both, I am seeing this problem. I am new to Selenium, but I believe this is not normal behavior, can someone please confirm? If this normal, then can someone please tell me how I can make sure my test runs correctly each time?
I think you want to use element_to_be_clickable as your ExpectedCondition.
That means that your driver will keep polling Selenium until it finds that the element is visible and enabled source
Try the below solution
link = wait.until(EC.element_to_be_clickable((By.XPATH, "//ul[#id='anchorman-two-browse-nav']/li/a[contains(text(),'Technology')]")))
link.click()
time.sleep(10)

Categories