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 Selenium-devel@lists.public.thoughtworks.org http://lists.public.thoughtworks.org/mailman/listinfo/selenium-devel