Search code examples
python-3.xseleniumwebdrivercherrypyweb-development-server

Using selenium.webdriver for a more responsive Cherrypy development environment


I've been trying to use the selenium module to open a browser when the cherrypy server starts.

I want it to reload the page with cherrypy.Autoreload so i dont have to use the mouse.

As a cherrypy plugin, if it starts too early the server doesn't respond and it throws an error ending the session.

I need an after_server_start event or something. Any advice??


Solution

  • So i figured this out somewhat. I made a daemon server using cherryd:

    from selenium import webdriver
    import cherrypy,time,os,signal
    
    class CpIde():
        def __init__(self):pass
    
        @cherrypy.expose
        def index(self):return "hello there"
    
        @cherrypy.expose
        def open(self):
            if hasattr(self,'driver'):
                try:self.driver.quit()
                except:
                    self.driver.service.process.send_signal(signal.SIGTERM)
            self.driver=webdriver.Firefox()
            return "Opening FF"
    
        @cherrypy.expose 
        def start(self):
            try:
                self.driver.get('http://127.0.0.1:8080')
            except:pass
            finally:
                self.driver.execute_script("""
                document.body.innerHTML="Just one second"; 
                window.setTimeout(function(){window.location.reload(false)},300) """
    )
            return "starting FF"
    
        @cherrypy.expose
        def close(self):
            self.driver.quit()
            del self.driver
            return 'Closing FF'
    
        @cherrypy.expose 
        def refresh(self):
            self.driver.execute_script("""
                document.body.innerHTML="Just one second"; 
                window.setTimeout(function(){window.location.reload(false)},300) """)
            return "restarting"
    
    cherrypy.tree.mount(CpIde(),'/')
    

    Then i made a plugin that makes requests to it:

    import cherrypy,time,os
    from cherrypy.process import wspbus, plugins
    import requests as r
    
    
    def command(method):
        addr='http://127.0.0.1:3131/'
        r.get(addr+method)
    
    class CpIdePlugin(plugins.SimplePlugin):
        def __init__(self,bus):
            plugins.SimplePlugin.__init__(self,bus)
            self.bus.log('Init plug')
            DriveId=os.getenv('CherryDrive')
            self.running=False
            if DriveId:
                self.running=True
            else:
                command('open')
                os.putenv('CherryDrive','True')
    
    
        def start(self):
            self.bus.log('Running FF plugin')
            if self.running:
                self.refresh()
            else:
                command('start')
    
        def refresh(self):#need to make a channel i think
            self.bus.log("Reload via bus")
           command('refresh')
    

    It ties into my main app with:

    import cpideplugin
    class root:pass
    
    cherrypy.tree.mount(root(),"/")
    
    cpideplugin.CpIdePlugin(cherrypy.engine).subscribe()
    cherrypy.engine.start()#the pubsub engine
    cherrypy.server.start()#an html server channel on the engine
    cherrypy.engine.block()
    cpideplugin.command('close')
    

    This way the selenium driver doesn't refresh with the Autoreload and i can work freely from vim. This is not perfect code and i would appreciate any recommendations. Cheers