diff options
author | Lars-Dominik Braun <lars@6xq.net> | 2018-11-14 18:40:28 +0100 |
---|---|---|
committer | Lars-Dominik Braun <lars@6xq.net> | 2018-11-14 18:40:28 +0100 |
commit | 20634f87124e0529f45db4e5e801f1bb5c6de32c (patch) | |
tree | 27f5307865f3a5188a71a7d14f1790bb021034a2 /crocoite/devtools.py | |
parent | f273341d6486f139eed073e4664b985209567e96 (diff) | |
download | crocoite-20634f87124e0529f45db4e5e801f1bb5c6de32c.tar.gz crocoite-20634f87124e0529f45db4e5e801f1bb5c6de32c.tar.bz2 crocoite-20634f87124e0529f45db4e5e801f1bb5c6de32c.zip |
Async chrome process startup
Move it to .devtools. Seems more fitting.
Diffstat (limited to 'crocoite/devtools.py')
-rw-r--r-- | crocoite/devtools.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/crocoite/devtools.py b/crocoite/devtools.py index 6e97ca3..9ce4333 100644 --- a/crocoite/devtools.py +++ b/crocoite/devtools.py @@ -252,3 +252,77 @@ class Tab: await ret.run () return ret +import os, time +from tempfile import mkdtemp +import shutil + +class Process: + """ Start Google Chrome listening on a random port """ + + __slots__ = ('binary', 'windowSize', 'p', 'userDataDir') + + def __init__ (self, binary='google-chrome-stable', windowSize=(1920, 1080)): + self.binary = binary + self.windowSize = windowSize + self.p = None + + async def __aenter__ (self): + assert self.p is None + self.userDataDir = mkdtemp () + args = [self.binary, + '--window-size={},{}'.format (*self.windowSize), + '--user-data-dir={}'.format (self.userDataDir), # use temporory user dir + '--no-default-browser-check', + '--no-first-run', # don’t show first run screen + '--disable-breakpad', # no error reports + '--disable-extensions', + '--disable-infobars', + '--disable-notifications', # no libnotify + '--headless', + '--disable-gpu', + '--hide-scrollbars', # hide scrollbars on screenshots + '--mute-audio', # don’t play any audio + '--remote-debugging-port=0', # pick a port. XXX: we may want to use --remote-debugging-pipe instead + '--homepage=about:blank', + 'about:blank'] + # start new session, so ^C does not affect subprocess + self.p = await asyncio.create_subprocess_exec (*args, + stdout=asyncio.subprocess.DEVNULL, + stderr=asyncio.subprocess.DEVNULL, + stdin=asyncio.subprocess.DEVNULL, + start_new_session=True) + port = None + # chrome writes its current active devtools port to a file. due to the + # sleep() this is rather ugly, but should work with all versions of the + # browser. + for i in range (100): + try: + with open (os.path.join (self.userDataDir, 'DevToolsActivePort'), 'r') as fd: + port = int (fd.readline ().strip ()) + break + except FileNotFoundError: + await asyncio.sleep (0.2) + if port is None: + raise Exception ('Chrome died on us.') + + return 'http://localhost:{}'.format (port) + + async def __aexit__ (self, *exc): + self.p.terminate () + await self.p.wait () + shutil.rmtree (self.userDataDir) + self.p = None + return False + +class Passthrough: + __slots__ = ('url') + + def __init__ (self, url): + self.url = url + + async def __aenter__ (self): + return self.url + + async def __aexit__ (self, *exc): + return False + |