Error while switching window in python selenium - python

I want to work with multiple windows and tabs using selenium and python.
I am getting below error during script execution:-
( code is mentioned at last)
{f625f26d-cfcf-442c-b9fc-5e96a199cd43}
C:\Python34\lib\site-packages\selenium-2.47.1- py3.4.egg\selenium\webdriver\remot
e\webdriver.py:525: DeprecationWarning: use driver.switch_to.window instead
warnings.warn("use driver.switch_to.window instead", DeprecationWarning)
{cad6e3cf-9062-408e-a6f1-11e98813dc6c}
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
class GoogleTabs(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def test_google_search_page(self):
driver = self.driver
driver.get("http://www.cdot.in")
window_before = driver.window_handles[0]
print (window_before)
driver.find_element_by_xpath("//a[#href='http://www.cdot.in/home.htm']").click()
window_after = driver.window_handles[1]
driver.switch_to_window(window_after)
print (window_after)
driver.find_element_by_link_text("ATM").click()
driver.switch_to_window(window_before)
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()

As the warning says
DeprecationWarning: use driver.switch_to.window instead
you'll need to change your
driver.switch_to_window
with
driver.switch_to.window
But think about it: it is a warning, not an error! Your code should work, it is just telling you that that method is deprecated.

You're getting a warning message, for new versions of selenium the method has changed.
Instead of using: driver.switch_to_window(window)
Try with: driver.switch_to.window
Where window is your variable.

I propose a very simple way to switch between windows without any hassles of playing with the handles yourself. https://gist.github.com/ab9-er/08c3ce7d2d5cdfa94bc7
def change_window(browser):
"""
Simple window switcher without the need of playing with ids.
#param browser: Current browser instance
"""
curr = browser.current_window_handle
all_handles = browser.window_handles
for handle in list(set([curr]) - set(all_handles)):
return browser.switch_to_window(handle)

Related

Webdriver.chrome not opening chrome

I'm working on an automation script and I'm trying to open a url in chrome, I have installed and imported selenium and downloaded the chrome driver and moved it to /usr/local/bin.
But when I try and run the script, the console is blank and then about a second later it displays 'Process finished with exit code 0' as if nothing happened. Below is my current code:
from selenium import webdriver
class Script():
def __init__(self):
self.driver = webdriver.Chrome(executable_path=r'/usr/local/bin/chromedriver')
def login(self):
self.driver.get('https://facebook.com')
The path is wrong here. It should be like below
webdriver.Chrome(executable_path=r'/usr/local/bin/chromedriver.exe')
Need to add .exe extension in the executable_path.
Also, make sure you are using correct Version of chrome driver for Google Chrome.
You are on linux system. You don't need the raw i.e. r switch. Your effective line of code will be:
self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver')
Does this work?
from config import keys
from selenium import webdriver
def order():
driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver')
driver.get('https://facebook.com')
print("here")
if __name__== '__main__':
order()
An exit code 0 means that ran without error. If an error occurs it would provide a non-zero argument. I would add a
from selenium import webdriver
class Script():
def __init__(self):
self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver')
def login(self):
self.driver.get('https://facebook.com')
print ('Opened facebook')
This should return with "Opened facebook" then 'Process finished with exit code 0'. I built something similar that will log a user into Facebook.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
class Script():
def __init__(self):
self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver')
def login(self):
self.driver.get('https://facebook.com')
print ('Opened facebook')
self.driver.implicitly_wait(30)
self.driver.get(k['product_url'])
print ('Opened facebook')
username_box = self.driver.find_element_by_id('email')
username_box.send_keys('EMAIL ADDRESS')
print ('Email Id entered')
password_box = self.driver.find_element_by_id('pass')
password_box.send_keys('password')
print ('Password entered')
login_box = self.driver.find_element_by_id('loginbutton')
login_box.click()
print('Logged In')

Implicitly_wait() missing 1 required positional argument

I'm studying selenium with python and in a tutorial I found the following code.
from selenium import webdriver
from time import gmtime, strftime
import unittest
#from builtins import classmethod
class RegisterNewUser(unittest.TestCase):
##classmethod
def setUp(self):
self.driver = webdriver.Firefox
self.driver.implicitly_wait(30)
self.driver.maximize_window()
# navigate to the application home page
self.driver.get("http://demo-store.seleniumacademy.com/")
def test_register_new_user(self):
driver = self.driver
pass
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main(verbosity=2)
It throw an error:
File "register_new_user.py", line 10, in setUp
self.driver.implicitly_wait(30)
TypeError: implicitly_wait() missing 1 required positional argument: 'time_to_wait'
I try to add the code commented out (classmethod) but doesn't change anything. Without the test_register_new_user doesn't give error.
I'm using python 3.6.4, selenium 3.141 (and geckodriver 0.23)
Your problem is one line above:
self.driver = webdriver.Firefox
This does not create a browser object. It just sets self.driver to the class webdriver.Firefox, which means that self.driver.implicitly_wait(30) is trying to use implicitly_wait in the static way, ie webdriver.Firefox.implicitly_wait(30), so it is missing the instance, ie webdriver.Firefox.implicitly_wait(an_actual_browser, 30).
You are missing ():
self.driver = webdriver.Firefox() # which will potentially ask for a path to
# firefox/geckodriver if it is not in PATH,
# but that is out of the scope of this question

How to pass Selenium WebDriver instances between functions in Python?

I have a function that handles logging into a website. I then return the webdriver instance so that I can pass it into another fucnction that actually handles getting the information that I need.
For some reason I have been unable to call my second function using the returned driver instance.
Was wondering if anyone had any insight into how I can pass a webdriver instance to another function? Thanks.
how I can pass a webdriver instance to another function?
You would return the instance from the first function and call the second function with it.
In the example below, I define 2 functions. A webdriver is instantiaterd inside func1, which returns the instance. Then I call func2, which takes a driver instance as an argument.
from selenium import webdriver
def func1():
driver = webdriver.Chrome()
driver.get('https://example.com')
return driver
def func2(driver):
return driver.title
if __name__ == '__main__':
driver = func1()
title = func2(driver)
print(title)
driver.quit()
This code will launch a browser (Chrome), navigate to a site (https://example.com), print the page title ("Example Domain"), and then quit the browser.
Alternatively, extending Corey Goldberg's answer. It is perfectly fine to simply pass a reference of the driver to all functions that use it.
from selenium import webdriver
def func1(driver):
driver.get('https://example.com')
def func2(driver):
return driver.title
if __name__ == '__main__':
driver = webdriver.Chrome()
func1(driver)
title = func2(driver)
print(title)
driver.quit()

Python Selenium click() doesn't work

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()

Wait for element to load when testing an iOS app using Appium and Python?

I am testing a native iOS app and need to wait for some elements to load in some of my testing. Appium is going too fast on some screens right now.
Can someone please point me to an example of using a WebDriverWait style of waiting for Appium iOS testing? There was a question that was answered for Ruby here: Wait for element to load when testing an iOS app using Appium and Ruby?. Looking for something similar in Python.
The Python client documentation doesn't seem to document the wait functions.
Thanks.
At the top of the test import these.
from appium 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
TL/DR is this should work, you may have to change self.driver to just driver in the wait = section depending on how you're doing things. Also, obviously change the By.XPath to whatever locator you're using:
wait = WebDriverWait(self.driver, 20)
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.XPATH,'//UIAApplication[1]/UIAWindow[1]/UIAButton[#text="example text"]')))
Or you could just tell the driver to use implicit waits.
self.driver.implicitly_wait(10)
myElement = driver.find_element_by_id("fakeid")
myElement.click()
Most of this is explained here.
Here's an example of using wait to log into an Android App (Haven't used it on ios but it should be the similar) using the default account selector then asserting the right text appeared. During the setup, I'm loading my desired capabilities from another file.
class TrainUpSmokeTests(unittest.TestCase):
def setUp(self):
desired_caps = desired_capabilities.get_desired_capabilities('app-debug.apk')
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
def tearDown(self):
self.driver.quit()
def example_test(self):
wd = self.driver
## Depending on how you're running the test the first variable may just be driver. Or in my case self.driver which I shortened above. The number is how many seconds it should wait before timing out.
wait = WebDriverWait(wd, 20)
## Waiting for account selector to be clickable.
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.XPATH,'//android.widget.CheckedTextView[#text="FakeEmail#example.com"]')))
## Locating test account and selecting it.
account = wd.find_element_by_android_uiautomator('text("FakeEmail#example.com")')
account.click()
ok_button = wd.find_element_by_android_uiautomator('text("OK")')
ok_button.click()
## Waiting for an Element on the home screen to be locatable.
currently_waiting_for = wait.until(EC.presence_of_element_located((By.XPATH,'//android.widget.RelativeLayout[#resource-id="com.name.app:id/overview"]')))
hero_headline = wd.find_element_by_android_uiautomator('new UiSelector().description("Example Header")')
self.assertIsNotNone(hero_headline)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TrainUpSmokeTests)
unittest.TextTestRunner(verbosity=2).run(suite)
It's a your testings a website using appium (instead of an app). Change the setup so self.driver opens a browser.
self.driver = webdriver.Firefox()
And then use By selectors like class, name, id, e.g. the example below.
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'search-results')))
This article also helped. Also if you don't know how to find xpaths, look into setting up uiautomatorviewer that comes with appium.
The python usage is:
driver.implicitly_wait(timeToWaitSec)
Selenium sourcecode(Py)
You can use WaitForElement class:
class WaitForElement:
#staticmethod
def wait(driver, id, time_out=100):
try:
WebDriverWait(driver, time_out).until(
lambda driver: driver.find_element(*id))
except TimeoutException:
print('Not able to find ID:' + id)
You can find all you need in selenium.webdriver.support.expected_conditions
Then from it you can do something like:
def wait_for_element_visible(self, by=By.XPATH, value=None, text=None, wait_time=20):
if text is not None:
value = value % text
wait = WebDriverWait(self.driver, wait_time)
return wait.until(EC.visibility_of_element_located((by, value)))
You can use implicitWait. Something like remoteWebDriver.implicitlyWait(time, timeUnit) This of course is for java. Something similar should be available for python.

Categories