Bad status line exception while opening a page on django development server - python

I am executing selenium test cases via Proboscis, for good reporting of test results. I have the following test case written
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from proboscis import test
import unittest
driver = webdriver.Firefox()
#test(groups=["unit","login"])
class UI_test(unittest.TestCase):
def test_SuccessfulErrorMsgOnEmptyUserName(self):
driver.get("http://127.0.0.1:7999/login/")
username_input = driver.find_element_by_id("id_email")
username_input.send_keys('')
password_input = driver.find_element_by_id("id_password")
password_input.send_keys('bill3')
driver.find_element_by_xpath('//input[#value = "Log In"]').click()
driver.implicitly_wait(3)
driver.find_element_by_class_name("error-login")
driver.close()
def run_tests():
from proboscis import TestProgram
# from tests import unit
# Run Proboscis and exit.
TestProgram().run_and_exit()
if __name__ == '__main__':
run_tests()
What could be causing the BadStatusLine exception in this code?

Looks like a duplicate of Python/Django "BadStatusLine" error but i can't flag due to this question having a bounty. According to this answer, a BadStatusLine exception is likely caused by an empty response, as in there being no status line at all.
According to this answer, the server formally tells the client there is no more data, instead of simply causing a connection reset or rude timeout.

Related

Python Selenium: Quitting a browser instance outside of original function

I started learning python + selenium a few days ago, and am struggling to quit the browser outside of my bbdc_check function. My goal is whenever I interrupt bbdc_check or it encounters an error, I would like to quit the existing browser to start from scratch.
I keep encountering errors with quitting the browser. The error message for driver.quit() is "TypeError: quit() missing 1 required positional argument: 'self'".
I have a nagging suspicion that I'm supposed to use a class here, which I tried loosely off this solution, but still could not get it to work. Any ideas are appreciated, thank you.
FYI, date_a and date_b are not defined here because I deleted a bunch of code redundant to this issue. Assume that line of code works.
import selenium
from selenium import webdriver
import time
import sys
breakloop = 0
def bbdc_check():
global breakloop
driver = webdriver.Chrome(r'C:\<some dir>\chromedriver.exe')
driver.get('<a website>')
# A bunch of code here to compare 2 different dates
if (date_a < date_b):
breakloop = 1
else:
driver.quit()
time.sleep(600)
# The main while-loop to run the programme
while breakloop == 0:
try:
bbdc_check()
# If I manually interrupt, kill the programme
except KeyboardInterrupt:
driver = webdriver.Chrome
driver.quit()
sys.exit()
# If programme encounters error, try again from scratch
except:
driver = webdriver.Chrome
driver.quit()
time.sleep(30)
Seems you are creating new object of driver in each blocks as well as your function bbdc_check(). Create a single driver instance and use the same.

Test fails when run in parallel in python selenium via pytest xdist but works well in sequence

When I run the below code with
pytest .\tests\GET\test_setupFunc.py
it works perfectly
i.e. setup(my_fixture) function run once then test_one and test_two
if i run it parallely using pytest-xdist using this
pytest .\tests\GET\test_setupFunc.py -n=2
it fails
i think my_fixture is being called by both test since i have setup the scope="session" that function should be shared.
once that function is run successfully, I want parallelism should get trigger
========== short test summary info =========
ERROR tests\GET\test_setupFunc.py::test_one - selenium.common.exceptions.WebDriverException: Message: unknown error:
Could not remove old devtools port file. Perhaps t...
please do replace yourusername with your username of system in addarguement code step in case you plan to run it
'''
import pytest
import logging
logging.basicConfig(format='%(message)s')
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
#pytest.fixture(autouse=True, scope='session')
def my_fixture():
logging.warning('setup function')
print(" i will be called only once i am one time")
options = webdriver.ChromeOptions()
options.add_argument('--profile-directory=Default')
options.add_argument("--user-data-dir=c:\\Users\\yourUserName\\AppData\\Local\\Google\\Chrome\\User Data")
driver=webdriver.Chrome(ChromeDriverManager().install(), options=options)
driver.get("https://gmail.com")
driver.quit()
def test_one():
logging.warning('test_a')
print(" i am first function")
def test_two():
logging.warning('test_b')
print(" i am second function")
Also to note if I remove selenium related steps and just keep print statements it works fine
Expected Result
setup method is called once
2 methods should be called once setup ran successfully once
pytest-parallel does not support python 3.9 yet tried that as well

Exception triggered in EventFiringWebDriver when debugging in PyCharm

Debugging Selenium script with EventFiringWebDriver in PyCharm, cause exception to be logged:
'WebDriver' object has no attribute '__len__'
It slows down IDE but do not break (stop) the script.
Here is full code:
from selenium import webdriver
from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver
from selenium.webdriver.support.events import AbstractEventListener
class ScreenshotListener(AbstractEventListener):
def on_exception(self, exception, driver):
print(exception)
driver = webdriver.Chrome('chromedriver.exe')
ef_driver = EventFiringWebDriver(driver, ScreenshotListener())
ef_driver.get('https://google.com/')
title = ef_driver.title
driver.quit()
assert "Google", title
When I run attached script in standard mode everything is OK.
But running with PyCharm Debug (here is output from beginning of Debug console):
C:\Pro\selenium-debug\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 59668 --file C:/Pro/selenium-debug/simple_test.py
I get those exceptions (every time when I call ef_driver):
'WebDriver' object has no attribute '__len__'
'WebDriver' object has no attribute '__len__'
It not stopping the script, it just cause debugger to be slow (it updates driver and focus is set to the browser).
Any idea why it is triggered and logged?
Bonus: Running debugging in console with pdb is OK, so this looks like strictly PyCharm Debug connected thing
Looks like PyCharm debug checks if an object has a __len__ attribute:
elif hasattr(v, "__len__")
and the object WebDriver has no __len__.
A solution could be (from the link below) to warp with try\catch:
try:
if is_numeric_container(type_qualifier, typeName, v):
xml_shape = ' shape="%s"' % make_valid_xml_value(str(v.shape))
elif hasattr(v, "__len__") and not is_string(v):
try:
xml_shape = ' shape="%s"' % make_valid_xml_value("%s" % str(len(v)))
except:
pass
except KeyError:
pass
Please check this track:
https://youtrack.jetbrains.com/issue/PY-39954

Python Selenium: How to check whether the WebDriver did quit()?

I want to control whether my WebDriver quit but I can't find a method for that. (It seems that in Java there's a way to do it)
from selenium import webdriver
driver = webdriver.Firefox()
driver.quit()
driver # <selenium.webdriver.firefox.webdriver.WebDriver object at 0x108424850>
driver is None # False
I also explored the attributes of WebDriver but I can't locate any specific method to get information on the driver status. Also checking the session id:
driver.session_id # u'7c171019-b24d-5a4d-84ef-9612856af71b'
If you would explore the source code of the python-selenium driver, you would see what the quit() method of the firefox driver is doing:
def quit(self):
"""Quits the driver and close every associated window."""
try:
RemoteWebDriver.quit(self)
except (http_client.BadStatusLine, socket.error):
# Happens if Firefox shutsdown before we've read the response from
# the socket.
pass
self.binary.kill()
try:
shutil.rmtree(self.profile.path)
if self.profile.tempfolder is not None:
shutil.rmtree(self.profile.tempfolder)
except Exception as e:
print(str(e))
There are things you can rely on here: checking for the profile.path to exist or checking the binary.process status. It could work, but you can also see that there are only "external calls" and there is nothing changing on the python-side that would help you indicate that quit() was called.
In other words, you need to make an external call to check the status:
>>> from selenium.webdriver.remote.command import Command
>>> driver.execute(Command.STATUS)
{u'status': 0, u'name': u'getStatus', u'value': {u'os': {u'version': u'unknown', u'arch': u'x86_64', u'name': u'Darwin'}, u'build': {u'time': u'unknown', u'version': u'unknown', u'revision': u'unknown'}}}
>>> driver.quit()
>>> driver.execute(Command.STATUS)
Traceback (most recent call last):
...
socket.error: [Errno 61] Connection refused
You can put it under the try/except and make a reusable function:
import httplib
import socket
from selenium.webdriver.remote.command import Command
def get_status(driver):
try:
driver.execute(Command.STATUS)
return "Alive"
except (socket.error, httplib.CannotSendRequest):
return "Dead"
Usage:
>>> driver = webdriver.Firefox()
>>> get_status(driver)
'Alive'
>>> driver.quit()
>>> get_status(driver)
'Dead'
Another approach would be to make your custom Firefox webdriver and set the session_id to None in quit():
class MyFirefox(webdriver.Firefox):
def quit(self):
webdriver.Firefox.quit(self)
self.session_id = None
Then, you can simply check the session_id value:
>>> driver = MyFirefox()
>>> print driver.session_id
u'69fe0923-0ba1-ee46-8293-2f849c932f43'
>>> driver.quit()
>>> print driver.session_id
None
I ran into the same problem and tried returning the title - this worked for me using chromedriver...
from selenium.common.exceptions import WebDriverException
try:
driver.title
print(True)
except WebDriverException:
print(False)
suggested methods above didn't work for me on selenium version 3.141.0
dir(driver.service) found a few useful options
driver.session_id
driver.service.process
driver.service.assert_process_still_running()
driver.service.assert_process_still_running
I found this SO question when I had a problem with closing an already closed driver, in my case a try catch around the driver.close() worked for my purposes.
try:
driver.close()
print("driver successfully closed.")
except Exception as e:
print("driver already closed.")
also:
import selenium
help(selenium)
to check selenium version number
This work for me:
from selenium import webdriver
driver = webdriver.Chrome()
print( driver.service.is_connectable()) # print True
driver.quit()
print( driver.service.is_connectable()) # print False
How about executing a driver command and checking for an exception:
import httplib, socket
try:
driver.quit()
except httplib.CannotSendRequest:
print "Driver did not terminate"
except socket.error:
print "Driver did not terminate"
else:
print "Driver terminated"
it works in java, checked on FF
((RemoteWebDriver)driver).getSessionId() == null
There is this function:
if driver.service.isconnectible():
print('Good to go')
In my case, I needed to detect whether the browser interface was closed - regardless - chromedriver's status. As such, none of the answers here worked, and I just decided to go for the obvious:
from selenium.common.exceptions import WebDriverException
try:
driver.current_url
print('Selenium is running')
except WebDriverException:
print('Selenium was closed')
Even though it's a bit of a hack, it's served my purposes perfectly.
''''python
def closedriver():
global drivername
drivername.quit()
global driveron
driveron=False
''''
this function "closedriver" uses a global variable named "drivername" and global bool variable named "driveron",you may just pass a current driver as parameter but
NOTE: driveron must be global to store the state of driver being 'on' or 'off'.
''''python
def closedriver(drivername):
global driveron
try:
drivername.quit()
except:
pass
driveron=False
''''
and when you start a new driver, just use a check
global driveron
if not driveron:
driver=webdriver.Chrome()

Selenium2Library code completion in PyCharm

I'm experimenting with creating a basic library extension for Robot Framework using Python, and I'm using PyCharm as the editor. For libraries imported directly code completion is working fine, but in this case I'm importing the Selenium2Library indirectly via a method:
def get_current_browser():
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
return browser
Which I call from other methods with something like
driver = get_current_browser()
This successfully grabs the webdriver browser instance from Robot Framework and lets me do as I please, but I don't get code hints when I go to edit a 'driver' variable. Is there way I can get hints in this scenario?
Here's the code in full:
from robot.libraries.BuiltIn import BuiltIn
from Selenium2Library.keywords.keywordgroup import KeywordGroup
import logging
def get_current_browser():
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
return browser
class MyLibrary(KeywordGroup):
def get_title_via_python(self):
driver = get_current_browser()
title = driver.title
logging.warn("checking title %s" % title)
return title
Try adding a docstring to your function to help PyCharm.
from selenium.webdriver import Remote # Remote imported only for code completion
def get_current_browser():
"""
:rtype: Remote
"""
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
return browser
More at http://www.jetbrains.com/pycharm/webhelp/type-hinting-in-pycharm.html

Categories

Resources