python chromedirver won't quit - python-3.x

[I am not good at English. Please understand. :
) ]
Sometimes even though using implicate timeout, chrome driver does not end.
To prevent this, I'm using the Timeout Decorator for Windows.
The timeout decorator works well,
But then, the Chrome driver not be shut down.
I also checked if it was the same object, but the object was the same.
What's the reason?
It seems to be using the timeout decorator...(the Chrome driver is also the latest version.)
self.driver.quit() <---- There is a problem with this method.
#timeout(10)
def driver_quit(self):
self.driver.quit()
#timeout(120)
def driver_get(self, url):
self.driver.get(url)
def call_url(self, url):
try:
self.driver_get(url)
except Exception as e:
try:
self.driver_quit()
except Exception as e:
pass
def timeout(timeout):
from threading import Thread
import functools
def deco(func):
#functools.wraps(func)
def wrapper(*args, **kwargs):
res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, timeout))]
def newFunc():
try:
res[0] = func(*args, **kwargs)
except Exception as e:
res[0] = e
t = Thread(target=newFunc)
t.daemon = True
try:
t.start()
t.join(timeout)
except Exception as je:
print('error starting thread')
raise je
ret = res[0]
if isinstance(ret, BaseException):
raise ret
return ret
return wrapper
return deco
=============== Modified code ===============
WebDriverException occurs on finally,
but Chamedriver shut down this line ==> driver.close().
def call_url(self, url):
try:
self.driver_get(url)
except:
try:
self.driver_quit()
except:
pass
finally:
self.driver.close()
self.driver.quit()

A workaround is to call both driver.quit() and driver.close().
To do so you can put the commands in a finally: statement.
You will wrap all your automation with a try: and except: then use the finally: statement at the end.
try:
# do my automated tasks
except:
pass
finally:
driver.close()
driver.quit()
EDIT
If you find this does not help you just report a bug to selenium and the webdriver maintainers.
Hope this helps you!

Related

Is this really encapsulated?

I wondered wheather it is actually impossible to make a protected python class, there always seems to be a way of getting around that, but i can't find one for this:
I attempted to code out this properly encapsulated class. Challenge:
Attempt setting somevalue to the value 69, without:
changing the code from line 1 - 32
polymorphism
from sbNative.debugtools import log # module not neccessary, only for logging and debugging purposes imported
from inspect import stack
import traceback
class Protected:
def __init__(self):
self._somevalue = "Unset"
log(self._somevalue)
def __setattr__(self, name, value):
if isinstance(stack()[1][0].f_locals.get("self"), Protected) or not name.startswith("_"):
super(Protected, self).__setattr__(name, value)
else:
raise AttributeError("Protected class from setting")
def __getattribute__(self, name):
if isinstance(stack()[1][0].f_locals.get("self"), Protected) or not name.startswith("_"):
return super(Protected, self).__getattribute__(name)
else:
raise AttributeError("Protected class from getting")
#property
def somevalue(self):
return self._somevalue
#somevalue.setter
def somevalue(self, value):
if value == 69:
raise ValueError(f"{value} is an illegal value.")
self._somevalue = value
log("Instantiates without a problem:")
p = Protected()
print("\n")
log("Fails because it is not allowed to set to this value:")
try:
p.somevalue = 69
except ValueError:
traceback.print_exc()
print("\n")
log("Fails because it attemps setting and getting directly:")
try:
p._somevalue = 69
except AttributeError:
traceback.print_exc()
print("")
try:
log(p._somevalue)
except AttributeError:
traceback.print_exc()
print("\n")
log("Succeeds because it is allowed to set and get this value:")
p.somevalue = 420
log(p.somevalue)
print("ⁿᶦᶜᵉ ˡᶦⁿᵉ ⁿᵘᵐᵇᵉʳ ᵇᵗʷ")

How to raise an error with decorator for unit testing?

I would like to do something in my unit testing before it fails and using decorator to do so
Here is my code :
import requests
import unittest
import test
class ExceptionHandler(object):
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
try:
self.f(*args, **kwargs)
except Exception as err:
print('do smth')
raise err
class Testing(unittest.TestCase):
#ExceptionHandler
def test_connection_200(self):
r = requests.get("http://www.google.com")
self.assertEqual(r.status_code, 400)
if __name__ == '__main__':
unittest.main(verbosity=2)
But it throws me an :
TypeError: test_connection_200() missing 1 required positional argument: 'self'
How can I do something when my test fail, then having the normal failing behavior of unitest?
Edit :
I would like to do something before my test fail like write a log and then continue the normal process of failing.
If possible with a decorator.
Edit bis the solution thanks to #Thymen :
import requests
import unittest
import test
class ExceptionHandler(object):
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
try:
self.f(*args, **kwargs)
except Exception as err:
print('do smth')
raise err
class Testing(unittest.TestCase):
def test_connection_200(self):
#ExceptionHandler
def test_connection_bis(self):
r = requests.get("https://www.google.com")
print(r.status_code)
self.assertEqual(r.status_code, 400)
test_connection_bis(self)
if __name__ == '__main__':
unittest.main(verbosity=2)
My comment may not have been clear, so hereby the solution in code
class Testing(unittest.TestCase):
def test_connection_200(self):
#ExceptionHandler
def test_connection():
r = requests.get("http://www.google.com")
self.assertEqual(r.status_code, 400)
with self.assertRaises(AssertionError):
test_connection()
The reason that this works is that there is no dependency on the call for the test (test_connection_200) , and the actual functionality that you are trying to test (the ExceptionHandler).
Edit
The line
with self.assertRaises(AssertionError):
test_connection()
Checks if test_connection() raises an AssertionError. If it does not raises this error, it will fail the test.
If you want the test to fail (because of the AssertionError), you can remove the with statement, and only call test_connection(). This will make the test fail directly.

Asyncio with threading no exception throwing

I have following code which will use asyncio and thread together. And the code works fine. But the problem is the code not throw exception some error happens.
import os
import time
from threading import Thread
import queue
import asyncio
def start_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
async def startProcess(name):
try:
#dfdf
print(' Started-----------> ',name)
while True:
print("Sleeping...",name)
time.sleep(5)
except Exception as e:
print('Caught exception in worker thread')
raise e
async def main_app():
loop1 = asyncio.new_event_loop()
process1_Tread = Thread(target=start_loop, args=(loop1,))
process1_Tread.start()
asyncio.run_coroutine_threadsafe(startProcess("Thread1"), loop1)
while True:
print("Sleeping main thread...")
time.sleep(5)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main_app())
finally:
print("Exit...")
For example if I add the line
try:
dfdf # to create exception
print(' Started-----------> ',name)
The thread not works but no error message shows. How can I enable if some error happens.
I resolved the problem by referring the answer here
Asyncio exception handler: not getting called until event loop thread stopped
Here is the full code
import os
import time
from threading import Thread
import queue
from pprint import pprint
import asyncio
def start_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
def exception_handler(loop, context):
print('Exception handler called')
pprint(context)
async def startProcess(name):
try:
dfdf
print(' Started-----------> ',name)
while True:
print("Sleeping...",name)
time.sleep(5)
return "Thread finish"
except Exception as e:
raise e
async def main_app():
loop1 = asyncio.new_event_loop()
loop1.set_exception_handler(exception_handler)
process1_Tread = Thread(target=start_loop, args=(loop1,))
process1_Tread.start()
fut = asyncio.run_coroutine_threadsafe(startProcess("Thread1"), loop1)
try:
print("success:", fut.result())
except:
print("exception:", fut.exception())
#consume signaling
while True:
print("Sleeping main thread...")
time.sleep(5)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main_app())
finally:
print("Exit...")

Try every line without exception prematurely breaking code

I would like to write a single try-except statement that is able to run multiple try statements without the code breaking.
s = "hello, this is a string."
Using the above string as an example:
ls = []
try:
ls.append(s.split())
ls.append(s.str.split()) # expected error
ls.append(s.split(","))
ls.append(s.split("i"))
except:
pass
Above is what I tried originally but the code stops by the second try-statement.
ls = []
try:
ls.append(s.split())
except:
pass
try:
ls.append(s.str.split()) # expected error
except:
pass
try:
ls.append(s.split(","))
except:
pass
try:
ls.append(s.split("i"))
except:
pass
Eventually, I was able to get all my strings appended to the list with the above code. Is there a better way of doing this than writing individual try-except statements?
From my understanding, when an error occurs in a try statement, it will immediately go to the except statement which is why your code doesn't execute after the second try statement.
Though there are probably better solutions to your question, here is my attempt for your problem:
ls = []
char=[' ',',','i']
for i in char:
try:
ls.append(s.split(i))
ls.append(s.str.split(i))
except:
pass
print(ls)
You can use the fuckit module.
Wrap your code in a function with #fuckit decorator:
import fuckit
#fuckit
def func():
code a
code b #if b fails, it should ignore, and go to c.
code c #if c fails, go to d
code d
Or you can try this :
def a():
try: # a code
except: pass # or raise
else: return True
def b():
try: # b code
except: pass # or raise
else: return True
def c():
try: # c code
except: pass # or raise
else: return True
def d():
try: # d code
except: pass # or raise
else: return True
def main():
try:
a() and b() or c() or d()
except:
pass

GeneratorExit issue in Tornado

I'm currently getting this error. I'm confused because from what I can tell Generator Exit just gets called whenever a generator finishes, but I have a ton of other Generators inheriting this class that do not call this error. Am I setting the Generator up properly? or is there some implicit code I'm not taking into account that is calling close()?
"error": "Traceback (most recent call last):\n File \"/stashboard/source/stashboard/checkers.py\", line 29, in run\n yield self.check()\nGeneratorExit\n",
the code where this yield statement is called:
class Checker():
def __init__(self, event, frequency, params):
self.event = event
self.frequency = frequency
self.params = params
#gen.coroutine
def run(self):
""" Run check method every <frequency> seconds
"""
while True:
try:
yield self.check()
except GeneratorExit:
logging.info("EXCEPTION")
raise GeneratorExit
except:
data = {
'status': events.STATUS_ERROR,
'error': traceback.format_exc()
}
yield self.save(data)
yield gen.sleep(self.frequency)
#gen.coroutine
def check(self):
pass
#gen.coroutine
def save(self, data):
yield events.save(self.event, data)
and this is the code that is inheriting from it:
class PostgreChecker(Checker):
# checks list of Post
formatter = 'stashboard.formatters.PostgreFormatter'
def __init__(self, event, frequency, params):
super().__init__(event, frequency, params)
self.clients = []
for DB in configuration["postgre"]:
# setup and create connections to PG servers.
postgreUri = queries.uri(DB["host"], DB["port"], DB["dbName"],
DB["userName"], DB["password"])
# creates actual link to DB
client = queries.TornadoSession(postgreUri)
# starts connection
client.host = DB["host"]
self.clients.append(client)
#gen.coroutine
def check(self):
for client in self.clients:
try:
yield client.validate()
self.save({'host': client.host,
'status': events.STATUS_OK})
except (ConnectionError, AutoReconnect, ConnectionFailure):
self.save({'host': client.host,
'status': events.STATUS_FAIL})
Tornado never calls close() on your generators, but the garbage collector does (starting in Python 3.4 I think). How is checker.run() called? Use IOLoop.spawn_callback() for fire-and-forget coroutines; this will keep a reference to them and allow them to keep running indefinitely.
the specific issue here was that my db cursors were not automatically re-connecting. I was using the queries library, but switched over to momoko and the issue is gone

Resources