summaryrefslogtreecommitdiff
path: root/crocoite/devtools.py
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2018-11-14 18:40:28 +0100
committerLars-Dominik Braun <lars@6xq.net>2018-11-14 18:40:28 +0100
commit20634f87124e0529f45db4e5e801f1bb5c6de32c (patch)
tree27f5307865f3a5188a71a7d14f1790bb021034a2 /crocoite/devtools.py
parentf273341d6486f139eed073e4664b985209567e96 (diff)
downloadcrocoite-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.py74
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
+