WebDriverException: Remote-webdriver with selenium grid in setup method in conftest.py - python

I am trying run my tests in Selenium Grid 4.2.1. I created hub and node with Google Chrome. My setup method is in conftest file in 'tests' folder. I used fixture in setup method and when I run my tests, the output is:
test setup failed
request = SubRequest 'setup' for Function test_properly_loggining_url
WebDriverException: Message: Unable to find handler for (POST) /session.
import pytest as pytest
import webdriver_manager.chrome
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
conftest.py
#pytest.fixture()
def setup(request):
grid_url = "http://192.168.88.189:5555"
driver = webdriver.Remote(grid_url, DesiredCapabilities.CHROME)
driver.maximize_window()
yield
driver.stop_client()
driver.close()
driver.quit()
test_file.py
#pytest.mark.usefixtures("setup")
class TestLogin:
def test_properly_loggining_url(self):
Login = HomePage(self.driver)
Login.properly_loggining()
assert Login.get_current_url() == Login.home_page
Do you have any idea how can I solve this problem?

Related

Pytest, selenium, fixture throws an error after the first test InvalidSessionIdException

I have a fixture file.
import pytest
from selenium.webdriver.chrome.options import Options as chrome_options
from driver.singleton_driver import WebDriver
#pytest.fixture
def get_chrome_options():
options = chrome_options()
options.add_argument('chrome')
options.add_argument('--start-maximized')
options.add_argument('--window-size=1920,1080')
options.add_argument('--incognito')
return options
#pytest.fixture
def get_webdriver(get_chrome_options):
options = get_chrome_options
driver = WebDriver(options).driver
return driver
#pytest.fixture(scope='function')
def setup(request, get_webdriver):
driver = get_webdriver
if request.cls is not None:
request.cls.driver = driver
yield driver
driver.close()
File with my tests
import pytest
#pytest.mark.usefixtures('setup')
class TestSteamPages:
def test_first(self):
self.driver.get('https://www.google.com/')
def test_second(self):
self.driver.get('https://www.google.com/')
As I understand it, after the first test, the function in the driver.close() fixture is triggered. But when the second test is run, the fixture does not restart the webdriver. An error
venv/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py:243: InvalidSessionIdException
============================================================================== short test summary info ==============================================================================
FAILED tests/test_first.py::TestSteamPages::test_second -
selenium.common.exceptions.InvalidSessionIdException: Message: invalid session id
ERROR tests/test_first.py::TestSteamPages::test_second - selenium.common.exceptions.InvalidSessionIdException: Message: invalid session id
For the driver, I use the Singleton pattern
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
class WebDriver:
class __WebDriver:
def __init__(self, options):
self.driver = webdriver.Chrome(options=options, service=ChromeService(ChromeDriverManager().install()))
driver = None
def __init__(self, options):
if not self.driver:
WebDriver.driver = WebDriver.__WebDriver(options=options).driver
The driver is not reinitialized because of the singleton. WebDriver.driver is initialized before first test, so in the next time setup is running if not self.driver is False, because self.driver is not None anymore.
If you want to initialize the WebDriver every test don't use singleton
#pytest.fixture
def get_webdriver(get_chrome_options):
options = get_chrome_options
driver = webdriver.Chrome(options=options, service=ChromeService(ChromeDriverManager().install()))
return driver
If you do want to initialize the WebDriver only once you can change fixtures scope to 'class' (for all tests in TestSteamPages) or even move it to conftest.py with scope 'session' for one driver instance for all the test. Note that in this case all the fixtures need to have scope='class'
#pytest.fixture(scope='class')
def setup(request, get_webdriver):
driver = get_webdriver
if request.cls is not None:
request.cls.driver = driver
yield driver
driver.close()

AttributeError: type object 'WebTablePage' has no attribute 'load' in selenium using pytest

I am learning selenium in python with pytest, I am facing this below error. I have searched this error all over the internet and tried all the possible advice, but nothing is working.
I am just trying to load the website, it is opening the browser but failing with this error. I don't know what i am missing, Any lead would be helpful.
FAILED Tests/test_webtable.py::test_webtablepage - AttributeError: type object 'WebTablePage' has no attribute 'load'
Code
Page Object Class(webtablepage.py) under pages folder.
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
class WebTablePage:
#URL
URL = 'https://demoqa.com/webtables'
#Intializers
def __init__(self,browser):
browser = self.browser
def load(self,browser):
self.browser.get(self.URL)
Pytest fixture(conftest.py) under Tests folder.
import pytest
import selenium.webdriver
#pytest.fixture
def browser():
#initialize the chrome instance
driver = selenium.webdriver.Chrome()
#Making the Driver wait for 10 seconds to load elements
driver.implicitly_wait(10)
#Return the webdriver instances for the setup
yield driver
#Quit the webdriver instances for the cleanup
driver.quit()
Test function (test_webtable.py) under Tests folder
from Pages.webtablepage import WebTablePage
def test_webtablepage(browser):
Webtable_page = WebTablePage
# Given the demoa qa Webtables page
Webtable_page.load()
The WebTablePage constructor is called incorrectly. It must be called with the browser argument.
Change this:
def test_webtablepage(browser):
Webtable_page = WebTablePage
To this:
def test_webtablepage(browser):
Webtable_page = WebTablePage(browser)
Change the
Webtable_page = WebTablePage
to
Webtable_page = WebTablePage()

Python selenium - How to run a Selenium Python Unittest

I'm having an issue with running python selenium for the first time :
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unittest
class segfam(unittest.TestCase):
def setUp(self):
self.driver=webdriver.chrome("/Users/tomersegal/Downloads/chromedriver")
def test_blabla(self):
driver=self.driver
driver.get("https://www.google.co.il/")
assert "Google" in driver.title
This is my error :
Ran 0 tests in 0.000s
OK
Launching unittests with arguments python -m unittest discover -s /Users/tomersegal/PycharmProjects/pythonProject1 -t /Users/tomersegal/PycharmProjects/pythonProject1 in /Users/tomersegal/PycharmProjects/pythonProject1
Process finished with exit code 0
Empty suite
As you are using unittest framework you have to call it from the __main__ function as:
if __name__ == "__main__":
unittest.main()
So your effective code block will be:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unittest
class segfam(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Chrome("/Users/tomersegal/Downloads/chromedriver")
def test_blabla(self):
driver=self.driver
driver.get("https://www.google.co.il/")
assert "Google" in driver.title
if __name__ == "__main__":
unittest.main()
PS: Note the change of chrome to Chrome
References
You can find a couple of relevant detailed discussions in:
Python + WebDriver -- No browser launched while using unittest module
What is unittest in selenium Python?

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

Defining the path to a module in Windows (Where the module is the test file being run)

I'm trying to run a simple automated test script. My code looks like:
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import os
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
gecko = os.path.normpath(os.path.join(os.path.dirname(__file__), 'geckodriver'))
binary = FirefoxBinary('C:\Program Files (x86)\Mozilla Firefox\Firefox.exe')
driver = webdriver.Firefox(firefox_binary=binary, executable_path=gecko+'.exe')
class PythonOrgSearch(unittest.TestCase):
def setUp(self):
self.driver = driver
def test_search_in_python_org(self):
driver = self.driver
driver.get("http://www.python.org")
self.assertIn("Python", driver.title)
elem = driver.find_element_by_name("q")
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
When I run it, I get the error:
Error while finding module specification for 'test_file.py' (AttributeError: module 'test_file' has no attribute 'path')
I have been searching all over stack overflow for how to resolve this or define a path. I am new to Windows operating systems and unit testing so I'm very lost on how to resolve this. If you have any insight, it would be much appreciated.

Categories