def DevToolsConnectionForLocalBinary(flags): """Returns a DevToolsConnection context manager for a local binary. Args: flags: ([str]) List of flags to pass to the browser. Returns: A DevToolsConnection context manager. """ binary_filename = OPTIONS.local_binary profile_dir = OPTIONS.local_profile_dir using_temp_profile_dir = profile_dir is None if using_temp_profile_dir: profile_dir = tempfile.mkdtemp() flags.append('--user-data-dir=%s' % profile_dir) chrome_out = None if OPTIONS.local_noisy else file('/dev/null', 'w') process = subprocess.Popen( [binary_filename] + flags, shell=False, stderr=chrome_out) try: time.sleep(10) yield devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) finally: process.kill() if using_temp_profile_dir: shutil.rmtree(profile_dir)
def Go(self): self.devtools_connection = devtools_monitor.DevToolsConnection( device_setup.DEVTOOLS_HOSTNAME, device_setup.DEVTOOLS_PORT) self.page_track = PageTrack(self.devtools_connection) self.devtools_connection.SetUpMonitoring() self.devtools_connection.SendAndIgnoreResponse('Page.navigate', {'url': self.url}) self.devtools_connection.StartMonitoring() print self.page_track.GetEvents()
def Open(self): """Overridden connection creation.""" if self._wpr_attributes: assert self._wpr_attributes.chrome_env_override == {}, \ 'Remote controller doesn\'t support chrome environment variables.' package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' self._device.ForceStop(package_info.package) chrome_args = self._GetChromeArguments() logging.info( 'Launching %s with flags: %s' % (package_info.package, subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer(self._device, command_line_path, self._GetChromeArguments()): start_intent = intent.Intent(package=package_info.package, activity=package_info.activity, data='about:blank') self._device.adb.Logcat(clear=True, dump=True) self._device.StartActivity(start_intent, blocking=True) try: for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS): logging.info('Devtools connection attempt %d' % attempt_id) with device_setup.ForwardPort( self._device, 'tcp:%d' % OPTIONS.devtools_port, 'localabstract:chrome_devtools_remote'): try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) self._StartConnection(connection) except socket.error as e: if e.errno != errno.ECONNRESET: raise time.sleep( self. DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS) continue yield connection if self._slow_death: self._device.adb.Shell( 'am start com.google.android.launcher') time.sleep(self.TIME_TO_IDLE_SECONDS) break else: raise ChromeControllerInternalError( 'Failed to connect to Chrome devtools after {} ' 'attempts.'.format(self.DEVTOOLS_CONNECTION_ATTEMPTS)) except: logcat = ''.join( [l + '\n' for l in self._device.adb.Logcat(dump=True)]) raise ChromeControllerError(log=logcat) finally: self._device.ForceStop(package_info.package)
def Open(self): """Overridden connection creation.""" package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' self._device.KillAll(package_info.package, quiet=True) chrome_args = self._GetChromeArguments() logging.info( 'Launching %s with flags: %s' % (package_info.package, subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer(self._device, command_line_path, self._GetChromeArguments()): start_intent = intent.Intent(package=package_info.package, activity=package_info.activity, data='about:blank') self._device.StartActivity(start_intent, blocking=True) try: for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS + 1): if attempt_id == self.DEVTOOLS_CONNECTION_ATTEMPTS: raise RuntimeError( 'Failed to connect to chrome devtools after {} ' 'attempts.'.format(attempt_id)) logging.info('Devtools connection attempt %d' % attempt_id) with device_setup.ForwardPort( self._device, 'tcp:%d' % OPTIONS.devtools_port, 'localabstract:chrome_devtools_remote'): try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) self._StartConnection(connection) except socket.error as e: assert str(e).startswith( '[Errno 104] Connection reset by peer') time.sleep( self. DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS) continue logging.info('Devtools connection success') yield connection if self._slow_death: self._device.adb.Shell( 'am start com.google.android.launcher') time.sleep(self.TIME_TO_IDLE_SECONDS) break finally: self._device.KillAll(package_info.package, quiet=True)
def Open(self): """Override for connection context.""" chrome_cmd = [OPTIONS.local_binary] chrome_cmd.extend(self._GetChromeArguments()) chrome_cmd.append('--user-data-dir=%s' % self._profile_dir) chrome_cmd.extend(['--enable-logging=stderr', '--v=1']) # Navigates to about:blank for couples of reasons: # - To find the correct target descriptor at devtool connection; # - To avoid cache and WPR pollution by the NTP. chrome_cmd.append('about:blank') chrome_out = None if OPTIONS.local_noisy else file('/dev/null', 'w') environment = os.environ.copy() if self._headless: environment['DISPLAY'] = 'localhost:99' xvfb_process = subprocess.Popen( ['Xvfb', ':99', '-screen', '0', '1600x1200x24'], shell=False, stderr=chrome_out) logging.debug(subprocess.list2cmdline(chrome_cmd)) chrome_process = subprocess.Popen(chrome_cmd, shell=False, stderr=chrome_out, env=environment) connection = None try: time.sleep(10) process_result = chrome_process.poll() if process_result is not None: logging.error('Unexpected process exit: %s', process_result) else: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) self._StartConnection(connection) yield connection if self._slow_death: connection.Close() connection = None chrome_process.wait() finally: if connection: chrome_process.kill() if self._headless: xvfb_process.kill()
def _DevToolsConnectionOnDevice(device, flags): """Returns a DevToolsConnection context manager for a given device. Args: device: Device to connect to. flags: ([str]) List of flags. Returns: A DevToolsConnection context manager. """ package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' _SetUpDevice(device, package_info) with FlagReplacer(device, command_line_path, flags): start_intent = intent.Intent( package=package_info.package, activity=package_info.activity, data='about:blank') device.StartActivity(start_intent, blocking=True) time.sleep(2) with ForwardPort(device, 'tcp:%d' % OPTIONS.devtools_port, 'localabstract:chrome_devtools_remote'): yield devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port)
def Open(self): """Overridden connection creation.""" # Kill all existing Chrome instances. killed_count = LocalChromeController.KillChromeProcesses() if killed_count > 0: logging.warning('Killed existing Chrome instance.') chrome_cmd = [OPTIONS.LocalBinary('chrome')] chrome_cmd.extend(self._GetChromeArguments()) # Force use of simple cache. chrome_cmd.append('--use-simple-cache-backend=on') chrome_cmd.append('--user-data-dir=%s' % self._profile_dir) # Navigates to about:blank for couples of reasons: # - To find the correct target descriptor at devtool connection; # - To avoid cache and WPR pollution by the NTP. chrome_cmd.append('about:blank') tmp_log = \ tempfile.NamedTemporaryFile(prefix="chrome_controller_", suffix='.log') chrome_process = None try: chrome_env_override = self._chrome_env_override.copy() if self._wpr_attributes: chrome_env_override.update( self._wpr_attributes.chrome_env_override) chrome_env = os.environ.copy() chrome_env.update(chrome_env_override) # Launch Chrome. logging.info( common_util.GetCommandLineForLogging(chrome_cmd, chrome_env_override)) chrome_process = subprocess.Popen(chrome_cmd, stdout=tmp_log.file, stderr=tmp_log.file, env=chrome_env) # Attempt to connect to Chrome's devtools for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS): logging.info('Devtools connection attempt %d' % attempt_id) process_result = chrome_process.poll() if process_result is not None: raise ChromeControllerInternalError( 'Unexpected Chrome exit: {}'.format(process_result)) try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) break except socket.error as e: if e.errno != errno.ECONNREFUSED: raise time.sleep( self.DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS) else: raise ChromeControllerInternalError( 'Failed to connect to Chrome devtools after {} ' 'attempts.'.format(self.DEVTOOLS_CONNECTION_ATTEMPTS)) # Start and yield the devtool connection. self._StartConnection(connection) yield connection if self._slow_death: connection.Close() chrome_process.wait() chrome_process = None except ChromeControllerError._PASSTHROUGH_WHITE_LIST: raise except Exception: raise ChromeControllerError(log=open(tmp_log.name).read()) finally: if OPTIONS.local_noisy: sys.stderr.write(open(tmp_log.name).read()) del tmp_log if chrome_process: try: chrome_process.kill() except OSError: pass # Chrome is already dead.
def Open(self): """Overridden connection creation.""" if self._wpr_attributes: assert self._wpr_attributes.chrome_env_override == {}, \ 'Remote controller doesn\'t support chrome environment variables.' package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' self._device.ForceStop(package_info.package) chrome_args = self._GetChromeArguments() logging.info( 'Launching %s with flags: %s' % (package_info.package, subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer(self._device, command_line_path, self._GetChromeArguments()): self._DismissCrashDialogIfNeeded() start_intent = intent.Intent(package=package_info.package, activity=package_info.activity, data='about:blank') self._device.adb.Logcat(clear=True, dump=True) self._device.StartActivity(start_intent, blocking=True) try: for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS): logging.info('Devtools connection attempt %d' % attempt_id) # Adb forwarding does not provide a way to print the port number if # it is allocated atomically by the OS by passing port=0, but we need # dynamically allocated listening port here to handle parallel run on # different devices. host_side_port = _AllocateTcpListeningPort() logging.info( 'Allocated host sided listening port for devtools ' 'connection: %d', host_side_port) try: with device_setup.ForwardPort( self._device, 'tcp:%d' % host_side_port, 'localabstract:chrome_devtools_remote'): try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, host_side_port) self._StartConnection(connection) except socket.error as e: if e.errno != errno.ECONNRESET: raise time.sleep( self. DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS ) continue yield connection if self._slow_death: self._device.adb.Shell( 'am start com.google.android.launcher') time.sleep(self.TIME_TO_IDLE_SECONDS) break except device_errors.AdbCommandFailedError as error: _KNOWN_ADB_FORWARDER_FAILURES = [ 'cannot bind to socket: Address already in use', 'cannot rebind existing socket: Resource temporarily unavailable' ] for message in _KNOWN_ADB_FORWARDER_FAILURES: if message in error.message: break else: raise continue else: raise ChromeControllerInternalError( 'Failed to connect to Chrome devtools after {} ' 'attempts.'.format(self.DEVTOOLS_CONNECTION_ATTEMPTS)) except ChromeControllerError._PASSTHROUGH_WHITE_LIST: raise except Exception: logcat = ''.join( [l + '\n' for l in self._device.adb.Logcat(dump=True)]) raise ChromeControllerError(log=logcat) finally: self._device.ForceStop(package_info.package) self._DismissCrashDialogIfNeeded()