I am trying to open two different urls side by side.
First if opens url1 does some checks
Then it should open url2 and do some checks
Then it should closee both url1 and url2 after doing the tests
I have been able to open two url1 and url2 but the tearDown is closing only url2.
I want my tearDown to close both urls.
This is the code I have tried
class Login(unittest.TestCase):
site_url1 = "https://www.google.com/"
site_url2 = "https://www.facebook.com/"
def setUp(self):
# create a new Firefox session
self.browser = webdriver.Firefox()
browser = self.browser
browser.get(self.site_url1)
def more_loggin(self):
# create a new Firefox session
self.browser = webdriver.Firefox()
browser = self.browser
browser.get(self.site_url2)
def tearDown(self):
self.browser.quit()
Above code is only closing site_url2, I want it to close the other url as well.
Seems like the self.browser has value of site_url2 and hence is not able to close the other one.
How can I resolve it?
this is because you set self.browser every time you call setUp or more_loggin.
this means that if you call one function, let's say setUp() and then you call more_loggin, you lose the instance of Firefox which was created by setUp, and self.browser gets a new instance, created at the start of more_loggin.
when you call tearDown, only the last instance which is stored in self.browser will close, and all of the others will remain open.
I suggest you save all of the instances in a list, defined at the class-level, and then tearDown should iterate over every instance and close it.
class Login(unittest.TestCase):
instances = []
site_url1 = "https://www.google.com/"
site_url2 = "https://www.facebook.com/"
def openFirefox(self):
# create a new Firefox session
firefox = webdriver.Firefox()
# save session in instances
self.instances.append(firefox)
# return the session
return firefox
def setUp(self):
browser = self.openFirefox()
browser.open(self.site_url1)
def more_loggin(self):
browser = self.openFirefox()
browser.open(self.site_url2)
def tearDown(self):
for browser in self.instances:
# close every instance in instances
browser.quit()
Related
I am trying to save the cookies for my selenium automation script in order to avoid login process for future automation.
This is the original script which works fine
class SeleniumDriver(object):
def __init__(
self,
# chromedriver path
driver_path='chromedriver.exe',
# pickle file path to store cookies
cookies_file_path = 'cookies.pkl',
# list of websites to reuse cookies with
cookies_websites=["https://website.com"] # I would like to replace this website by an argument
):
self.driver_path = driver_path
self.cookies_file_path = cookies_file_path
self.cookies_websites = cookies_websites
#PREVIOUS VERSION WITH NORMAL CHROME chrome_options = webdriver.ChromeOptions()
chrome_options = uc.ChromeOptions()
#PREVIOUS VERSION WITH NORMAL CHROME self.driver = webdriver.Chrome(
self.driver = uc.Chrome(
executable_path=self.driver_path,
options=chrome_options
)
try:
# load cookies for given websites
cookies = pickle.load(open(self.cookies_file_path, "rb"))
for website in self.cookies_websites:
self.driver.get(website)
for cookie in cookies:
self.driver.add_cookie(cookie)
self.driver.refresh()
except Exception as e:
# it'll fail for the first time, when cookie file is not present
logger.error(str(e))
logger.error("ERROR : Error loading cookies")
def save_cookies(self):
# save cookies
cookies = self.driver.get_cookies()
pickle.dump(cookies, open(self.cookies_file_path, "wb"))
def close_all(self):
# close all open tabs
if len(self.driver.window_handles) < 1:
return
for window_handle in self.driver.window_handles[:]:
self.driver.switch_to.window(window_handle)
self.driver.close()
def quit(self):
self.save_cookies()
self.close_all()
self.driver.quit()
selenium_object = SeleniumDriver()
driver = selenium_object.driver
You can see in the code during the creation of object, the url of website "https://website.com" is used to create the cookies for this website.
If tomorrow, I use my script for "https://anotherwebsite.com", I would need to pass hthe website as arguments like this for example:
class SeleniumDriver(object,website): # the variable website is passed as argument in class creation
....
website="https://anotherwebsite.com"
selenium_object = SeleniumDriver(website)
My problem is I alsways have this error output:
NameError: name 'website' is not defined
Here is full code which doesn't work:
class SeleniumDriver(object,website):
def __init__(
self,
# chromedriver path
driver_path='chromedriver.exe',
# pickle file path to store cookies
cookies_file_path = 'cookies.pkl',
# list of websites to reuse cookies with
cookies_websites=[website]
):
self.driver_path = driver_path
self.cookies_file_path = cookies_file_path
self.cookies_websites = cookies_websites
#PREVIOUS VERSION WITH NORMAL CHROME chrome_options = webdriver.ChromeOptions()
chrome_options = uc.ChromeOptions()
#PREVIOUS VERSION WITH NORMAL CHROME self.driver = webdriver.Chrome(
self.driver = uc.Chrome(
executable_path=self.driver_path,
options=chrome_options
)
try:
# load cookies for given websites
cookies = pickle.load(open(self.cookies_file_path, "rb"))
for website in self.cookies_websites:
self.driver.get(website)
for cookie in cookies:
self.driver.add_cookie(cookie)
self.driver.refresh()
except Exception as e:
# it'll fail for the first time, when cookie file is not present
logger.error(str(e))
logger.error("ERROR : Error loading cookies")
def save_cookies(self):
# save cookies
cookies = self.driver.get_cookies()
pickle.dump(cookies, open(self.cookies_file_path, "wb"))
def close_all(self):
# close all open tabs
if len(self.driver.window_handles) < 1:
return
for window_handle in self.driver.window_handles[:]:
self.driver.switch_to.window(window_handle)
self.driver.close()
def quit(self):
self.save_cookies()
self.close_all()
self.driver.quit()
website="https://mywebsite.com"
selenium_object = SeleniumDriver(website)
driver = selenium_object.driver
When I run this code, I get this error output:
class SeleniumDriver(object,website):
NameError: name 'website' is not defined
I'm trying to build a program which opens Chrome pages one by one.
I'm using Selenium library.
My idea is to have different IP every time I open a new page.
I read about proxies but I'm not able to manage them.
Can you help me?
This is my code:
class myClass:
def __init__(self):
self.options = Options()
self.options.add_argument('--allow-running-insecure-content')
self.options.add_argument('--ignore-certificate-errors')
self.driver = webdriver.Chrome('./chromedriver',options = self.options)
def openBrowser(self):
self.chrome.get("http://whatismyipaddress.com")
def closeBrowser(self):
driver = self.driver
driver.close()
driver.quit()
if __name__ == "__main__":
#create object list
object = [myClass(i) for i in range(10)]
for i in range(10):
#open Chrome page
object[i].openBrowser()
# here I want to change IP and then I close the page before opening a new one
#close Chrome page
object[i].closeBrowser()
As title,
I want to practice encapsulation of programing, and I have a problem about the code I write.
The browser always automatically opens when I call the class(CrawlerSetting), and I guess which code causes the situation (browser = wb.Chrome(options=options)), but I have no idea how to avoid this situation.
Here is my code:
from selenium import webdriver as wb
class CrawlerSetting:
'''
Description:
chrome 84 version
'''
options = wb.ChromeOptions()
options.add_experimental_option('excludeSwitches', ["enable-automation"])
global browser
browser = wb.Chrome(options=options)
def __init__(self, target):
self.target = target
def open(self):
return browser.get(self.target)
def click_xpath(self, x_path):
submit_element = browser.find_element_by_xpath(x_path)
return submit_element.click()
It's my first time to ask question, if I have any format error . Plz tell me!
from selenium import webdriver
from time import sleep
filename = "log.txt"
myfile = open(filename, 'w')
class Search(object):
def __init__(self):
self.driver = webdriver.Chrome('chromedriver.exe')
# "This will open a new chrome instance without being logged in to the site"
self.driver.get("Site2")
sleep(2)
self.driver.find_element_by_xpath("/html/body/div[1]/div[4]/div/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[4]/div[1]/div[2]/div[1]/a").click()
sleep(2)
Texto = self.driver.find_element_by_xpath("/html/body/div[1]/div[4]/div/div/div[4]/div/div/div[1]/div[3]/div/article[1]/div/div[2]/div/div/div/article/div[1]").text
print(Texto)
myfile.write(Texto)
myfile.close()
sleep(10)
import re
Id = re.compile('[0-9]{9}')
Id2 = re.compile('[0-9]{4}')
DobMonth = re.compile('[0-9]{2}')
DobYear = re.compile('[0-9]{2}')
if Id.match(Texto) and Id2.match(Texto) and DobMonth.match(Texto) and DobYear.match(Texto):
print ("Matches")
else:
print("Not match")
sleep (20)
Search()
class BasicBot(object):
def __init__(self, username, pw):
self.driver = webdriver.Chrome('chromedriver.exe')
self.driver.get("site1")
sleep(2)
self.driver.find_element_by_xpath("/html/body/div[1]/div[1]/div/div/div/div[1]/a[1]/span").click()
sleep(2)
self.driver.find_element_by_xpath("//input[#name=\"login\"]")\
.send_keys(username)
self.driver.find_element_by_xpath("//input[#name=\"password\"]")\
.send_keys(pw)
self.driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/form/div[1]/dl/dd/div/div[2]/button').click()
sleep(2)
Search()
BasicBot('username',"password")
So the script runs BasicBot(usr,psswd) logs in to the site, and is supposed to go to a different site while logged in, then searches if X post matches the criteria given, if it does that's it if it does not, I should refresh the site and check again.
In the Search class, you start with creating a new chromedriver instance: self.driver = webdriver.Chrome('chromedriver.exe'), this is why it opens another window with a fresh state.
Instead, modify your Search class to
take an existing instance of webdriver.
open a new window by using script window.open instead of get:
class Search:
def __init__(self, driver):
self.driver = driver
# Open a new window
self.driver.execute_script("window.open('https://site2')")
sleep(2) # visually check to make sure it opened
# Switch to new window
self.driver.switch_to.window(self.driver.window_handles[-1])
# After this you can start doing self.driver.find_element_by_xpath and the rest
In the class BasicBot, modify the last line to pass the driver:
Search(self.driver)
Lastly, you can use refresh to refresh your site2:
else:
print("Not match")
sleep(20)
self.driver.refresh()
Hope, it helps. Good luck!
TL/DR: Right now it launches 2 browsers but only runs the test in 1. What am I missing?
So I'm trying to get selenium hub working on a mac (OS X 10.11.5). I installed with this, then launch hub in a terminal tab with:
selenium-standalone start -- -role hub
Then in another tab of terminal on same machine register a node.
selenium-standalone start -- -role node -hub http://localhost:4444/grid/register -port 5556
It shows up in console with 5 available firefox and chrome browsers.
So here's my code. In a file named globes.py I have this.
class globes:
def __init__(self, number):
self.number = number
base_url = "https://fake-example.com"
desired_cap = []
desired_cap.append ({'browserName':'chrome', 'javascriptEnabled':'true', 'version':'', 'platform':'ANY'})
desired_cap.append ({'browserName':'firefox', 'javascriptEnabled':'true', 'version':'', 'platform':'ANY'})
selenium_server_url = 'http://127.0.0.1:4444/wd/hub'
Right now I'm just trying to run a single test that looks like this.
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from globes import *
class HeroCarousel(unittest.TestCase):
def setUp(self):
for driver_instance in globes.desired_cap:
self.driver = webdriver.Remote(
command_executor=globes.selenium_server_url,
desired_capabilities=driver_instance)
self.verificationErrors = []
def test_hero_carousel(self):
driver = self.driver
driver.get(globes.base_url)
hero_carousel = driver.find_element(By.CSS_SELECTOR, 'div.carousel-featured')
try: self.assertTrue(hero_carousel.is_displayed())
except AssertionError, e: self.verificationErrors.append("home_test: Hero Carousel was not visible")
def tearDown(self):
self.driver.close()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
Right now it launches both Firefox and Chrome, but only runs the test in Firefox. Chrome opens and just sits on a blank page and doesn't close. So I figure there's something wrong with how I wrote the test. So what am I missing? I apologize if this is obvious but I'm just learning how to setup hub and just learned enough python to write selenium tests a couple weeks ago.
I think Hubs working as it launches both, but I did try adding a second node on the same machine on a different port and got the same thing. Just in case here's what hub prints out.
INFO - Got a request to create a new session: Capabilities [{browserName=chrome, javascriptEnabled=true, version=, platform=ANY}]
INFO - Available nodes: [http://192.168.2.1:5557]
INFO - Trying to create a new session on node http://192.168.2.1:5557
INFO - Trying to create a new session on test slot {seleniumProtocol=WebDriver, browserName=chrome, maxInstances=5, platform=MAC}
INFO - Got a request to create a new session: Capabilities [{browserName=firefox, javascriptEnabled=true, version=, platform=ANY}]
INFO - Available nodes: [http://192.168.2.1:5557]
INFO - Trying to create a new session on node http://192.168.2.1:5557
INFO - Trying to create a new session on test slot {seleniumProtocol=WebDriver, browserName=firefox, maxInstances=5, platform=MAC}
Forgive me if I am way off as I haven't actually worked with selenium, this answer is purely based on the issue related to only keeping the reference to the last created driver in setUp
Instead of keeping one self.driver you need to have a list of all drivers, lets say self.drivers, then when dealing with them instead of driver = self.driver you would do for driver in self.drivers: and indent all the relevent code into the for loop, something like this:
class HeroCarousel(unittest.TestCase):
def setUp(self):
self.drivers = [] #could make this with list comprehension
for driver_instance in globes.desired_cap:
driver = webdriver.Remote(
command_executor=globes.selenium_server_url,
desired_capabilities=driver_instance)
self.drivers.append(driver)
self.verificationErrors = []
def test_hero_carousel(self):
for driver in self.drivers:
driver.get(globes.base_url)
hero_carousel = driver.find_element(By.CSS_SELECTOR, 'div.carousel-featured')
try: self.assertTrue(hero_carousel.is_displayed())
except AssertionError, e: self.verificationErrors.append("home_test: Hero Carousel was not visible")
def tearDown(self):
for driver in self.drivers:
driver.close()
self.assertEqual([], self.verificationErrors)
You need to use self.driver.quit() because otherwise the browser will not quit and will only close the current window.
You will soon end-up with multiple browser running, and you will have to pay for them.