Cross-browser testing with Selenium and Python - 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.

Related

Is it possible to make `pytest.fixture` open different pages for Selenium tests using for loop?

I'm trying to run tests using pytest and selenium. I wrote #pytest.fixture, so a fresh web page would open for each test. I would like to use for loop to run these tests for various pages, but when I run the code, the test is run only for the last element of pages, "men".
from selenium import webdriver
import pytest
import time
pages = ["what-is-new", "women", "men"]
for page in pages:
#pytest.fixture()
def driver():
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(f"https://magento.softwaretestingboard.com/{page}.html")
yield driver
driver.quit()
# Tests
def test_number_one(driver):
time.sleep(5)
pass
I wanted the test to be run for all pages defined in the list.
Is there any way to run these tests for all pages defined in the list?
You can parametrize the fixture. Something like below should work for your example:
from selenium import webdriver
import pytest
import time
pages = ["what-is-new", "women", "men"]
#pytest.fixture(params=pages)
def driver(request):
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(f"https://magento.softwaretestingboard.com/{request.param}.html")
yield driver
driver.quit()
def test_number_one(driver):
time.sleep(5)
pass

Selenium closing the brower alone after finishing all the function

I'm pretty new in programming so I might be an easy question, but I don't understand why the browsers opened by Selenium closes at the end of the code.
from lib2to3.pgen2 import driver
from selenium import webdriver
def Online_PLatform():
Driver = webdriver.Chrome()
Driver.get('https://elearningmarikina.ph/')
Gmail = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[1]/input')
Gmail.send_keys('958rectin#depedmarikina.com')
Pass = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[2]/input')
Pass.send_keys('33112')
Button = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[3]/button')
Button.click()
You can use 2 approaches in order to keep you driver open.
1.
Add the 'detach' option to your driver settings:
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
Simply add a delay at the end of your test code (less elegant approach but more simple)
from lib2to3.pgen2 import driver
from selenium import webdriver
import time
def Online_PLatform():
Driver = webdriver.Chrome()
Driver.get('https://elearningmarikina.ph/')
Gmail = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[1]/input')
Gmail.send_keys('958rectin#depedmarikina.com')
Pass = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[2]/input')
Pass.send_keys('33112')
Button = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[3]/button')
Button.click()
time.sleep(50)
This is because after the all functions, The code stops running and that's why selenium exits.
You can use the time module to delay.
import time
from lib2to3.pgen2 import driver
from selenium import webdriver
def Online_PLatform():
Driver = webdriver.Chrome()
Driver.get('https://elearningmarikina.ph/')
Gmail = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[1]/input')
Gmail.send_keys('958rectin#depedmarikina.com')
Pass = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[2]/input')
Pass.send_keys('33112')
Button = Driver.find_element_by_xpath('/html/body/div[1]/div/div/div[1]/div[2]/div/div/form/div[3]/button')
Button.click()
time.sleep(50) #---> 50 second delay

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

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

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.

Categories