Good day-
Going along with the user.js I sent to the list a few days ago, this
Python module makes driving Selenium from Python a cinch.
All you need to do is instantiate SeleniumGateway with a socket-address
tuple. Then call the execute() method with the parts of your Selenese
command as arguments. Example:
s = SeleniumGateway(('127.0.0.1', 8080))
s.execute('type', 'id=InputField', 'The Text')
Now point your browser at your Selenium runner, which should be
requesting commands from http://localhost:8080/driver .
The return string from each Selenium command is returned by execute().
The SeleniumGateway still works if you modify your Selenese runner HTML
to submit queries with POST instead of GET, as we do. We find this works
much better when we expect to receive longer result strings or more
complicated ones.
I'd very much appreciate feedback on this approach and the user.js file
I sent. We hope to be able to work with others using this or similar
code.
--
paul
# SeleniumGateway
#
# Written by paul cannon at Novell, Inc. for the Selenium system.
from cgi import parse_qs
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from StringIO import StringIO
class SeleniumGatewayError(Exception): pass
class SeleniumRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
self.start_reply_then_postpone(parse_qs(self.rfile.read(
int(self.headers.getheader('content-length'))
)))
def do_GET(self):
qmark = self.path.find('?')
if qmark < 0:
querystr = ''
else:
querystr = self.path[qmark+1:]
self.start_reply_then_postpone(parse_qs(querystr))
def start_reply_then_postpone(self, queryvars):
result = queryvars.get('commandResult', [None])[0]
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.server.export_client_and_result(
self.save_wfile_for_later(),
result
)
def save_wfile_for_later(self):
"""Deviousness. Move the wfile stream and replace it with a fake
one, so the underlying SocketStream foo can close it and think it's
safely done. We won't reply to this request until a new command is
available.
"""
waiting_client = self.wfile
self.wfile = StringIO()
return waiting_client
def log_message(self, format, *args):
# throw away webserverish logs for now
pass
class SeleniumGateway:
def __init__(self, server_addr):
self.server_addr = server_addr
self.server = HTTPServer(server_addr, SeleniumRequestHandler)
self.server.export_client_and_result = self.acquire_client_and_result
if self.get_result() is not None: # should give None for first call
raise SeleniumGatewayError(
"Browser is not synchronized with SeleniumGateway"
)
@staticmethod
def buildselenese(selcmd, seltarget='', selvalue=''):
return '|%s|%s|%s|' % (selcmd, seltarget, selvalue)
def send_string(self, command):
self.waiting_client.write(command)
self.waiting_client.close()
del self.waiting_client
def get_result(self):
self.server.handle_request()
result = self.selenium_result
del self.selenium_result
return result
def execute(self, selcmd, seltarget='', selvalue=''):
self.send_string(self.buildselenese(selcmd, seltarget, selvalue))
return self.get_result()
def acquire_client_and_result(self, client, result):
self.waiting_client = client
self.selenium_result = result
_______________________________________________
Selenium-devel mailing list
[email protected]
http://lists.public.thoughtworks.org/mailman/listinfo/selenium-devel