How can I pass argument as part of selenium webdriver command - python

I have below similar codes. The only difference is the browser I choose. I want to combine the duplicated codes into a function.
driver = webdriver.Chrome()
driver.get('http://www.google.ca')
driver.quit()
driver2 = webdriver.Firefox()
driver2.get('http://www.google.com')
time.sleep(2)
driver2.quit()
I wrote the below function but seems cannot pass the browser_name as part of the command. Any solution for this?
def go_to_baidu(browser_name):
driver = webdriver.browser_name()
driver.get('http://www.baidu.com')
time.sleep(2)
driver.quit()

Instead of passing a value like "Chrome" or "Firefox" to your function, pass webdriver.Chrome or webdriver.Firefox() (without the quotes) instead. The, change the first line of the function like so:
def go_to_baidu(browser_name):
driver = browser_name()
driver.get('http://www.baidu.com')
time.sleep(2)
driver.quit()
You then run it like this:
go_to_baidu(webdriver.Chrome)
for example.
Functions are objects in Python, and can be passed to other functions just as easily as strings, lists, dicts, etc. can.

Related

How can I define driver = webdriver.Firefox without automatically opening the browser?

Here's my code in a simplified way:
from selenium import webdriver
driver = webdriver.Firefox(executable_path=r"F:\geckodriver.exe")
class Acesso():
def __init__(self):
driver.get(link)
def scroll():
# Function
driver.click()
def url():
# driver.get("https://google.com")
Acesso()
Writing it this way makes the browser to open up as soon as I define my driver variable. Is there any way I can define the webdriver.Firefox() without automatically opening the browser? My goal here is that I want to define the driver variable inside my __init__ function so I can pass an argument to it. Something like this:
def __init__(self, agent):
self.agent = agent
driver = webdriver.Firefox(executable_path=r"F:\geckodriver.exe",firefox_profile=agent)
My issue is that writing it this way I can't use the driver variable in other functions and if I define the variable for each function the browser will open automatically at any function's call. Any solutions?
Try this: Create the driver variable but initialize it to None.
Then, in each function that uses it, check if it's None and if it is, then set it to Firefox(...) -- if it's not None, assume it's already set to the Firefox browser and proceed that way.
Then the browser should open the first function and stay open/be reused for the rest.
from selenium import webdriver
try:
fireFoxOptions = webdriver.FirefoxOptions()
fireFoxOptions.set_headless()
brower = webdriver.Firefox(firefox_options=fireFoxOptions, executable_path=r"F:\geckodriver.exe")
Found a solution setting the driver variable as global. Now I can define inside my function and still use it on other functions.

selenium webdriverwait does not reset timer in for loop | python

I am using python3.8.5 & selenium3.141.0 to automate login processes. To am locating login buttons with css selectors, but in my testing, the selectors can change (i'm a little fuzzy on this - something dynamic to do with how the page loads??).
My current solution for this is iterate over a list of css selectors that I have observed (they do repeat):
driver = webdriver.Chrome(options=options)
success = True
errorMSG = ""
for loginClickID in paper.loginClickID:
wait = WebDriverWait(driver, 12)
try:
wait.until(
EC.presence_of_element_located(By.CSS_SELECTOR, loginClickID)
)
except Exception as e:
log("\nFailed to see click-to-login element: " + loginClickID + "\nHTML output shown below:\n\n" + driver.page_source)
success = False
errorMSG = e
if not success:
response = driver.page_source
driver.quit()
return f"{paper.brand} login_fail\nLoginClickID: {loginClickID}\nNot found in:\n{response}\n{errorMSG}\n"
I am creating a new WebDriverWait() object for each iteration of the loop. However, when I debug the code and step over it manually, the second time I enter the loop the wait.until() method exits immediately, without even throwing an exception (which is very strange, right?) and exiting the loop completely (the css selector list has 2 elements)
My thought is that somehow the wait.until() timer is not reseting?
I've tried reloading the page using driver.refresh(), and sleeping the python code using time.sleep(1) in the except: section in that hope that might help rest things - it has not...
I've included all my ChromeDriver options for context:
options = Options()
# options.add_argument("--headless")
options.add_argument("window-size=1400,1500")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("enable-automation")
options.add_argument("--disable-infobars")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("start-maximized")
options.add_argument("--disable-browser-side-navigation")
I am using:
Google Chrome 80.0.3987.106
&
ChromeDriver 80.0.3987.106
Any Suggestions?
Why use
css selectors
Which are obvious dynamic, as you say - they change..
Why don't you use Xpath?
xpath_email = "//input[#type='email']"
xpath_password = "//input[#type='password']"
driver.find_element_by_xpath(xpath_email)
time.sleep(1)
driver.find_element_by_xpath(xapth_password)
These are obviously, generic xpaths, but you can find them on whatever login page you are, and change accordingly.
This way, no matter whatever the test case, your logic will work.

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

Google chrome closes immediately after being launched with selenium

I am on Mac OS X using selenium with python 3.6.3.
This code runs fine, opens google chrome and chrome stays open.:
chrome_options = Options()
chrome_options.binary_location="../Google Chrome"
chrome_options.add_argument("disable-infobars");
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("http://www.google.com/")
But with the code wrapped inside a function, the browser terminates immediately after opening the page:
def launchBrowser():
chrome_options = Options()
chrome_options.binary_location="../Google Chrome"
chrome_options.add_argument("disable-infobars");
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("http://www.google.com/")
launchBrowser()
I want to use the same code inside a function while keeping the browser open.
Just simply add:
while(True):
pass
To the end of your function. It will be like this:
def launchBrowser():
chrome_options = Options()
chrome_options.binary_location="../Google Chrome"
chrome_options.add_argument("disable-infobars");
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("http://www.google.com/")
while(True):
pass
launchBrowser()
My guess is that the driver gets garbage collected, in C++ the objects inside a function (or class) get destroyed when out of context. Python doesn´t work quite the same way but its a garbage collected language. Objects will be collected once they are no longer referenced.
To solve your problem you could pass the object reference as an argument, or return it.
def launchBrowser():
chrome_options = Options()
chrome_options.binary_location="../Google Chrome"
chrome_options.add_argument("start-maximized");
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("http://www.google.com/")
return driver
driver = launchBrowser()
To make the borwser stay open I am doing this:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def browser_function():
driver_path = "path/to/chromedriver"
chr_options = Options()
chr_options.add_experimental_option("detach", True)
chr_driver = webdriver.Chrome(driver_path, options=chr_options)
chr_driver.get("https://target_website.com")
The browser is automatically disposed once the variable of the driver is out of scope.
So, to avoid quitting the browser, you need to set the instance of the driver on a global variable:
Dim driver As New ChromeDriver
Private Sub Use_Chrome()
driver.Get "https://www.google.com"
' driver.Quit
End Sub
This is somewhat old, but the answers on here didn't solve the issue. A little googling got me here
http://chromedriver.chromium.org/getting-started
The test code here uses sleep to keep the browser open. I'm not sure if there are better options, so I will update this as I learn.
import time
from selenium import webdriver
driver = webdriver.Chrome('/path/to/chromedriver') # Optional argument, if not specified will search path.
driver.get('http://www.google.com/xhtml');
time.sleep(5) # Let the user actually see something!
search_box = driver.find_element_by_name('q')
search_box.send_keys('ChromeDriver')
search_box.submit()
time.sleep(5) # Let the user actually see something!
driver.quit()
My solution is to define the driver in the init function first, then it won't close up the browser even the actional
To whom has the same issue, just set the driver to global, simple as following:
global driver
driver.get("http://www.google.com/")
This resolved the problem on my side, hope this could be helpful
Adding experimental options detach true works here:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(options=options)
As per the code block you shared there can be 3 possible solutions as follows :
In the binary_location you have to change the .. to . (. denotes Project Workspace)
In the binary_location you have to change the .. to /myspace/chrome (Absolute Chrome Binary)
While initiating the driver, add the switch executable_path :
driver = webdriver.Chrome(chrome_options=options, executable_path=r'/your_path/chromedriver')
def createSession():
**global driver**
driver = webdriver.Chrome(chrome_driver_path)
driver.maximize_window()
driver.get("https://google.com")
return driver
To prevent this from happening, ensure your driver variable is defined outside your function or as a global variable, to prevent it from being garbage collected immediately after the function completes execution.
In the example above, this could mean something like:
driver = webdriver.Chrome(chrome_options=get_options())
def get_options():
chrome_options = Options()
chrome_options.binary_location="../Google Chrome"
chrome_options.add_argument("disable-infobars")
return chrome_options
def launchBrowser():
driver.get("http://www.google.com/")
launchBrowser()
Hi the below solutions worked for me Please have a try these.
Solution 1 : of Google chrome closes automatically after launching using Selenium Web Driver.
Check the Version of the Chrome Browser driver exe file and google chrome version you are having, if the driver is not compatible then selenium-web driver browser terminates just after selenium-web driver opening, try by matching the driver version according to your chrome version
The reason why the browser closes is because the program ends and the driver variable is garbage collected after the last line of code. For the second code in the post, it doesn't matter whether you use it in a function or in global scope. After the last statement is interpreted, the driver variable is garbage collected and the browser terminates from program termination.
Solutions:
Set chrome options
Use the time module
Use an infinite loop at the end of your program to delay program closure
You can simply add:-
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(options=options)

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