Python 3 Selenium Run Multiple Browsers Simultaneously - python

I'm currently trying to run multiple browsers at the same time with Selenium.
All processes start but don't execute passed functions correctly.
My Code:
from multiprocessing import Pool
# function that creates driver
driver = self.create_driver()
pool.apply_async(launcher.launch_browser, driver)
The launch_browser function is a different Python script that is supposed to run but only a Browser window is opened. (yes, I imported the external script as a module)

You can simply open new browser windows the same way you open the first one, with the same or different browsers:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
class Bot:
def __init__(self):
self.firstBrowser = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
self.secondBrowser = webdriver.Firefox()
def gotopage(self):
self.firstBrowser.get("https://www.google.com/")
self.secondBrowser.get("https://stackoverflow.com/")
bot = Bot()
bot.gotopage()

Related

Multiple test cases in one Selenium web driver instance

I am fairly new to programming so please be patient, but to the point.
I am creating few test cases using Selenium Web Driver, I have to check functionality of webpage to which I have to login using password and later with SMS code that I receive on my phone. I want to do this ONE TIME ONLY, so I want to use ONE instance of Web Driver for all my test cases (I know it is not recommended, but it will save a lot of time and sending 30 SMS, code from SMS is entered manually via Terminal).
My code looks something like this:
import time
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
class LoginTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Safari()
def test_LoginIn(self):
browser = self.browser
(Here I am looking for buttons and clicking on them)
def test_MyDevices(self):
browser.find_element_by_xpath('Some XPATH').click()
if __name__ == '__main__':
unittest.main()
And here is my problem after performing test_LoginIn I want to start another test test_MyDevices because MyDevice tab is right after logging in on the same page as first test is ended, but I can't because next test want to create new Web Driver Instance instead of doing test in the same instance.
In current version I receive this error:
Error after running script
I read a lot about this issue but couldn't find any satisfactory answer.
I'd be grateful for your help.
You can use the same instance of the webdriver for all of your tests. You will just need to instantiate the webdriver once, and then use it throughout your tests.

Selenium window closes instantly when "requests" module is imported

I'm trying to use Selenium and Beautiful Soup together with Python but having a rather strange issue - Selenium window stays opened only if requests module is not imported, otherwise it stays opened for like 1 second and closes.Important thing is that this only happens when I create the class in another file - when I create the class in the same file it stays opened normally.
Below are the two versions of code - 1st one where window stays opened, 2nd one where window instantly closes:
1: WORKS
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from test import Watcher
service = Service("C:\Program Files (x86)\Development\chromedriver.exe")
driver = webdriver.Chrome(service=service)
tw = Watcher(driver)
tw.open_browser()
# OTHER FILE CALLED test
class Watcher:
def __init__(self, driver):
self.driver = driver
def open_browser(self):
self.driver.get("https://www.google.com")
2: CLOSES
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from test import Watcher
import requests
service = Service("C:\Program Files (x86)\Development\chromedriver.exe")
driver = webdriver.Chrome(service=service)
tw = Watcher(driver)
tw.open_browser()
# OTHER FILE CALLED test
class Watcher:
def __init__(self, driver):
self.driver = driver
def open_browser(self):
self.driver.get("https://www.google.com")
I'm wondering if this has something to do with the Keep-Alive and Connection Pooling in urllib3, even though the requests module is not used in the program code.
When your program terminates, the HTTP connections are released and the browser window closes.
Add this and you'll see that the browser window stays open until the program has finished running. The program simply terminates perfectly normally with no errors.
from time import sleep
for _ in range(10):
sleep(1)
[Edit] I have a solution!
detach (Boolean) — whether browser is closed when the driver is sent the quit command.
See Class: Selenium::WebDriver::Chrome::Options
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from watcher import Watcher
import requests
service = Service("C:\Program Files (x86)\Development\chromedriver.exe")
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(service=service, options=options)
tw = Watcher(driver)
tw.open_browser()

Two chrome windows and unexpected quit after running selenium chromedriver

I have 3 files in my project: main.py, g_webdriver.py, and whatever.py. They look like this:
main.py:
import g_webdriver
import whatever
g_webdriver.run_chrome('https://stackoverflow.com')
g_webdriver.py:
from selenium import webdriver
driver = webdriver.Chrome()
def run_chrome(url:str):
driver.get(url)
driver.maximize_window()
whatever.py:
from selenium import webdriver
driver = webdriver.Chrome()
If I run my main.py file, selenium opens two separate chrome windows: one with loaded stackoveflow website and one blank with data:, in url bar. Of course I want open only one window. How to fix this? Also I must mention that I tried to get rid of driver variable and open my chrome directly by webdriver.Chrome() but this approach doesn't work either because it opens two separate windows (one with loaded page and one blank) like in the first one and after a few seconds closing comes.
When you run main, python imports g_webdriver and executes all code from that file including the line:
driver = webdriver.Chrome()
That's when the first window is opened.
Then python imports whatever and again runs driver = webdriver.Chrome(), so you get another separate window. webdriver.Chrome() always creates a new window.
At this point 2 windows are opened with blank pages and you open stackoverflow in g_webdriver.driver.
You could extract opening Chrome window to another file and import the one shared driver to both files:
chrome_window.py:
from selenium import webdriver
driver = webdriver.Chrome()
g_webdriver.py:
from selenium import webdriver
from chrome_window import driver
def run_chrome(url:str):
driver.get(url)
driver.maximize_window()
whatever.py:
from chrome_window import driver

How do I wait until a webpage is loaded before opening another tab

I've made this little python script to automate opening the websites I need in the morning, take a look `
Required Modules
import webbrowser
Open the websites
`webbrowser.get('firefox').open_new_tab('https://www.netflix.com')
webbrowser.get('firefox').open_new_tab('https://www.facebook.com')
webbrowser.get('firefox').open_new_tab('https://www.udemy.com') `
And I don't know how to wait until the webpage is loaded before opening the next one (in another tab), any help?
You could take the approach as mentioned at How to wait for the page to fully load using webbrowser method? and check for a certain element in the page manually.
Another options would be to import time and call it after opening each tab time.sleep(5) which waits for 5 seconds before running the next line of code.
import webbrowser
from time import sleep
links = ['https://www.netflix.com', 'https://www.facebook.com', 'https://www.udemy.com']
for link in links:
webbrowser.get('firefox').open_new_tab(link)
sleep(5)
Selenium Implementation:
Note: This implemenetation opens your URL's in multiple windows rather than a single window and multiple tabs.
I will be using the chrome driver which you can install at https://chromedriver.chromium.org/downloads
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_experimental_option("detach", True) #this is just to keep the windows open even after the script is done running.
urls = ['https://www.netflix.com', 'https://www.facebook.com', 'https://www.udemy.com']
def open_url(url):
driver = webdriver.Chrome(executable_path=os.path.abspath('chromedriver'), chrome_options=chrome_options)
# I've assumed the chromedriver is installed in the same directory as the script. If not, mention the path to the chromedriver executable here.
driver.get(url)
for url in urls:
open_url(url)

How to launch a Chromium application using Chromedriver?

Is it possible to port this python code to work in Robot Framework?
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
chrome_options = Options()
chrome_options.binary_location = 'C:/Program Files (x86)/MyApp.exe'
driver = webdriver.Chrome('C:/Program Files (x86)/chromedriver.exe', chrome_options=chrome_options)
I'm trying to create a chrome webdriver in robot that sends my selenium calls to my chromium application. Is it possible?
I create a python Library see code below but it just launches my app and closes it. I want to be able to make selenium/robot calls to it.
Code for myLibrary.py
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from robot.libraries.BuiltIn import BuiltIn
def pas_webdriver_instance():
se2lib = BuiltIn().get_library_instance('ExtendedSelenium2Library')
chrome_options = Options()
chrome_options.binary_location = 'C:/Program Files (x86)/myapp.exe'
driver = webdriver.Chrome('C:/Program Files (x86)/chromedriver.exe', chrome_options=chrome_options)
You could simply expand Selenium2Library and use your Python code directly. To expand Selenium2Library you can either make a new class that inherits the original library, or get the runnung library's instance on runtime.
Or, if you absolutely want to port this into Robot Framework, you can try out this keyword:
Open Chrome
[Arguments] ${url} ${binary_path}
${chrome_options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys, selenium.webdriver
Call Method ${chrome_options} binary_location ${binary_path}
Create Webdriver Chrome chrome_options=${chrome_options}
Go To ${url}
Edit: To answer your question in comments,
That depends on the version of Selenium2Library you're using since the library got reworked heavily in it's last version, but if you're using versions prior to it's version 3, you can see an example of expansion that gets an instance here (see the property _s2l), and an example of class inheritance here (see the declaration of the class).
I haven't looked into expanding the last version of SeleniumLibrary yet so I couldn't tell you for this particular case. Retrieving the library's instance on runtime should still work fine though.

Categories