OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2013 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """PyAuto: Python Interface to Chromium's Automation Proxy. | 6 """PyAuto: Python Interface to Chromium's Automation Proxy. |
7 | 7 |
8 PyAuto uses swig to expose Automation Proxy interfaces to Python. | 8 PyAuto uses swig to expose Automation Proxy interfaces to Python. |
9 For complete documentation on the functionality available, | 9 For complete documentation on the functionality available, |
10 run pydoc on this file. | 10 run pydoc on this file. |
(...skipping 4478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4489 panel = {} | 4489 panel = {} |
4490 panels.append(panel) | 4490 panels.append(panel) |
4491 tab = browser['tabs'][0] | 4491 tab = browser['tabs'][0] |
4492 panel['incognito'] = browser['incognito'] | 4492 panel['incognito'] = browser['incognito'] |
4493 panel['renderer_pid'] = tab['renderer_pid'] | 4493 panel['renderer_pid'] = tab['renderer_pid'] |
4494 panel['title'] = self.GetActiveTabTitle(browser['index']) | 4494 panel['title'] = self.GetActiveTabTitle(browser['index']) |
4495 panel['url'] = tab['url'] | 4495 panel['url'] = tab['url'] |
4496 | 4496 |
4497 return panels | 4497 return panels |
4498 | 4498 |
4499 def RestoreOnline(self): | |
4500 """Returns the device from offline mode if GoOffline was used.""" | |
4501 | |
4502 assert PyUITest.IsChromeOS() | |
4503 | |
4504 # Restores etherent connection | |
4505 stdout, stderr = self.RunSuperuserActionOnChromeOS('TeardownBackchannel') | |
4506 | |
4507 if hasattr(self, 'bc_cellular_enabled') and self.bc_cellular_enabled: | |
4508 self.ToggleNetworkDevice('cellular', True) | |
4509 if hasattr(self, 'bc_wifi_enabled') and self.bc_wifi_enabled: | |
4510 self.ToggleNetworkDevice('wifi', True) | |
4511 | |
4512 assert 'RuntimeError' not in stderr, stderr | |
4513 | |
4514 def GoOffline(self): | |
4515 """Puts device in offline mode. | |
4516 | |
4517 The device is put into offline mode by disabling all network interfaces | |
4518 but keeping the the wired ethernet interface up and faking shill/flimflam | |
4519 into thinking there is no ethernet interface by renaming the interface. | |
4520 This is so we can keep ssh connections over the wired connection alive. | |
4521 """ | |
4522 assert PyUITest.IsChromeOS() | |
4523 net_info = self.GetNetworkInfo() | |
4524 self.bc_wifi_enabled = net_info.get('wifi_enabled') | |
4525 self.bc_cellular_enabled = net_info.get('cellular_enabled') | |
4526 | |
4527 if self.bc_cellular_enabled: | |
4528 self.ToggleNetworkDevice('cellular', False) | |
4529 if self.bc_wifi_enabled: | |
4530 self.ToggleNetworkDevice('wifi', False) | |
4531 | |
4532 stdout, stderr = self.RunSuperuserActionOnChromeOS('SetupBackchannel') | |
4533 assert 'RuntimeError' not in stderr, stderr | |
4534 | |
4535 def GetNetworkInfo(self): | 4499 def GetNetworkInfo(self): |
4536 """Get details about ethernet, wifi, and cellular networks on chromeos. | 4500 """Get details about ethernet, wifi, and cellular networks on chromeos. |
4537 | 4501 |
4538 Returns: | 4502 Returns: |
4539 A dictionary. | 4503 A dictionary. |
4540 Sample: | 4504 Sample: |
4541 { u'cellular_available': True, | 4505 { u'cellular_available': True, |
4542 u'cellular_enabled': False, | 4506 u'cellular_enabled': False, |
4543 u'connected_ethernet': u'/service/ethernet_abcd', | 4507 u'connected_ethernet': u'/service/ethernet_abcd', |
4544 u'connected_wifi': u'/service/wifi_abcd_1234_managed_none', | 4508 u'connected_wifi': u'/service/wifi_abcd_1234_managed_none', |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4589 | 4553 |
4590 # Remembered networks do not have /service/ prepended to the service path | 4554 # Remembered networks do not have /service/ prepended to the service path |
4591 # even though wifi_networks does. We want this prepended to allow for | 4555 # even though wifi_networks does. We want this prepended to allow for |
4592 # consistency and easy string comparison with wifi_networks. | 4556 # consistency and easy string comparison with wifi_networks. |
4593 remembered_wifi = {} | 4557 remembered_wifi = {} |
4594 network_info['remembered_wifi'] = dict([('/service/' + k, v) for k, v in | 4558 network_info['remembered_wifi'] = dict([('/service/' + k, v) for k, v in |
4595 network_info['remembered_wifi'].iteritems()]) | 4559 network_info['remembered_wifi'].iteritems()]) |
4596 | 4560 |
4597 return network_info | 4561 return network_info |
4598 | 4562 |
4599 def GetConnectedWifi(self): | |
4600 """Returns the SSID of the currently connected wifi network. | |
4601 | |
4602 Returns: | |
4603 The SSID of the connected network or None if we're not connected. | |
4604 """ | |
4605 service_list = self.GetNetworkInfo() | |
4606 connected_service_path = service_list.get('connected_wifi') | |
4607 if 'wifi_networks' in service_list and \ | |
4608 connected_service_path in service_list['wifi_networks']: | |
4609 return service_list['wifi_networks'][connected_service_path]['name'] | |
4610 | |
4611 def GetServicePath(self, ssid, encryption=None, timeout=30): | |
4612 """Waits until the SSID is observed and returns its service path. | |
4613 | |
4614 Args: | |
4615 ssid: String defining the SSID we are searching for. | |
4616 encryption: Encryption type of the network; either None to return the | |
4617 first instance of network that matches the ssid, '' for | |
4618 an empty network, 'PSK', 'WEP' or '8021X'. | |
4619 timeout: Duration to wait for ssid to appear. | |
4620 | |
4621 Returns: | |
4622 The service path or None if SSID does not exist after timeout period. | |
4623 """ | |
4624 def _GetServicePath(): | |
4625 service_list = self.GetNetworkInfo().get('wifi_networks', []) | |
4626 for service_path, service_obj in service_list.iteritems(): | |
4627 if not (isinstance(service_obj, dict) and | |
4628 'encryption' in service_obj and | |
4629 'name' in service_obj): | |
4630 continue | |
4631 | |
4632 service_encr = 'PSK' if service_obj['encryption'] in ['WPA', 'RSN']\ | |
4633 else service_obj['encryption'] | |
4634 | |
4635 if service_obj['name'] == ssid and \ | |
4636 (encryption == None or service_encr == encryption): | |
4637 return service_path | |
4638 self.NetworkScan() | |
4639 return None | |
4640 | |
4641 service_path = self.WaitUntil(_GetServicePath, timeout=timeout, | |
4642 retry_sleep=1, return_retval=True) | |
4643 return service_path or None | |
4644 | |
4645 def NetworkScan(self): | 4563 def NetworkScan(self): |
4646 """Causes ChromeOS to scan for available wifi networks. | 4564 """Causes ChromeOS to scan for available wifi networks. |
4647 | 4565 |
4648 Blocks until scanning is complete. | 4566 Blocks until scanning is complete. |
4649 | 4567 |
4650 Returns: | 4568 Returns: |
4651 The new list of networks obtained from GetNetworkInfo(). | 4569 The new list of networks obtained from GetNetworkInfo(). |
4652 | 4570 |
4653 Raises: | 4571 Raises: |
4654 pyauto_errors.JSONInterfaceError if the automation call returns an error. | 4572 pyauto_errors.JSONInterfaceError if the automation call returns an error. |
(...skipping 10 matching lines...) Expand all Loading... |
4665 Raises: | 4583 Raises: |
4666 pyauto_errors.JSONInterfaceError if the automation call returns an error. | 4584 pyauto_errors.JSONInterfaceError if the automation call returns an error. |
4667 """ | 4585 """ |
4668 cmd_dict = { | 4586 cmd_dict = { |
4669 'command': 'ToggleNetworkDevice', | 4587 'command': 'ToggleNetworkDevice', |
4670 'device': device, | 4588 'device': device, |
4671 'enable': enable, | 4589 'enable': enable, |
4672 } | 4590 } |
4673 return self._GetResultFromJSONRequest(cmd_dict, windex=None) | 4591 return self._GetResultFromJSONRequest(cmd_dict, windex=None) |
4674 | 4592 |
4675 PROXY_TYPE_DIRECT = 1 | |
4676 PROXY_TYPE_MANUAL = 2 | |
4677 PROXY_TYPE_PAC = 3 | |
4678 | |
4679 def WaitUntilWifiNetworkAvailable(self, ssid, timeout=60, is_hidden=False): | |
4680 """Waits until the given network is available. | |
4681 | |
4682 Routers that are just turned on may take up to 1 minute upon turning them | |
4683 on to broadcast their SSID. | |
4684 | |
4685 Args: | |
4686 ssid: SSID of the service we want to connect to. | |
4687 timeout: timeout (in seconds) | |
4688 | |
4689 Raises: | |
4690 Exception if timeout duration has been hit before wifi router is seen. | |
4691 | |
4692 Returns: | |
4693 True, when the wifi network is seen within the timout period. | |
4694 False, otherwise. | |
4695 """ | |
4696 def _GotWifiNetwork(): | |
4697 # Returns non-empty array if desired SSID is available. | |
4698 try: | |
4699 return [wifi for wifi in | |
4700 self.NetworkScan().get('wifi_networks', {}).values() | |
4701 if wifi.get('name') == ssid] | |
4702 except pyauto_errors.JSONInterfaceError: | |
4703 # Temporary fix until crosbug.com/14174 is fixed. | |
4704 # NetworkScan is only used in updating the list of networks so errors | |
4705 # thrown by it are not critical to the results of wifi tests that use | |
4706 # this method. | |
4707 return False | |
4708 | |
4709 # The hidden AP's will always be on, thus we will assume it is ready to | |
4710 # connect to. | |
4711 if is_hidden: | |
4712 return bool(_GotWifiNetwork()) | |
4713 | |
4714 return self.WaitUntil(_GotWifiNetwork, timeout=timeout, retry_sleep=1) | |
4715 | |
4716 def ResetProxySettingsOnChromeOS(self): | |
4717 """Public wrapper around proxysettings teardown functions.""" | |
4718 self.SetSharedProxies(False) | |
4719 proxy_dict = { | |
4720 'mode': 'direct' | |
4721 } | |
4722 self.SetProxySettingOnChromeOS(proxy_dict) | |
4723 | |
4724 def SetProxySettingOnChromeOS(self, proxy_config): | |
4725 """Set the proxy config of the current network. | |
4726 | |
4727 Owner must be logged in for these to persist. | |
4728 If user is not logged in or is logged in as non-owner or guest, | |
4729 proxy settings do not persist across browser restarts or login/logout. | |
4730 | |
4731 Args: | |
4732 proxy_config: A dictionary following the format described in | |
4733 prefs/proxy_config_dictionary.h. | |
4734 | |
4735 Raises: | |
4736 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4737 """ | |
4738 cmd_dict = { | |
4739 'command': 'SetProxySettings', | |
4740 'proxy_config': json.dumps(proxy_config) | |
4741 } | |
4742 return self._GetResultFromJSONRequest(cmd_dict, windex=None) | |
4743 | |
4744 def SetSharedProxies(self, value): | |
4745 """Allows proxies on the shared networks. | |
4746 | |
4747 Args: | |
4748 value: True/False to set and clear respectively. | |
4749 | |
4750 Raises: | |
4751 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4752 """ | |
4753 cmd_dict = { | |
4754 'command': 'SetSharedProxies', | |
4755 'value': value, | |
4756 } | |
4757 return self._GetResultFromJSONRequest(cmd_dict, windex=None) | |
4758 | |
4759 def ForgetAllRememberedNetworks(self): | 4593 def ForgetAllRememberedNetworks(self): |
4760 """Forgets all networks that the device has marked as remembered.""" | 4594 """Forgets all networks that the device has marked as remembered.""" |
4761 for service in self.GetNetworkInfo()['remembered_wifi']: | 4595 for service in self.GetNetworkInfo()['remembered_wifi']: |
4762 self.ForgetWifiNetwork(service) | 4596 self.ForgetWifiNetwork(service) |
4763 | 4597 |
4764 def ForgetWifiNetwork(self, service_path): | 4598 def ForgetWifiNetwork(self, service_path): |
4765 """Forget a remembered network by its service path. | 4599 """Forget a remembered network by its service path. |
4766 | 4600 |
4767 This function is equivalent to clicking the 'Forget Network' button in the | 4601 This function is equivalent to clicking the 'Forget Network' button in the |
4768 chrome://settings/internet page. This function does not indicate whether | 4602 chrome://settings/internet page. This function does not indicate whether |
(...skipping 10 matching lines...) Expand all Loading... |
4779 # Usually the service_path is prepended with '/service/', such as when the | 4613 # Usually the service_path is prepended with '/service/', such as when the |
4780 # service path is retrieved from GetNetworkInfo. ForgetWifiNetwork works | 4614 # service path is retrieved from GetNetworkInfo. ForgetWifiNetwork works |
4781 # only for service paths where this has already been stripped. | 4615 # only for service paths where this has already been stripped. |
4782 service_path = service_path.split('/service/')[-1] | 4616 service_path = service_path.split('/service/')[-1] |
4783 cmd_dict = { | 4617 cmd_dict = { |
4784 'command': 'ForgetWifiNetwork', | 4618 'command': 'ForgetWifiNetwork', |
4785 'service_path': service_path, | 4619 'service_path': service_path, |
4786 } | 4620 } |
4787 self._GetResultFromJSONRequest(cmd_dict, windex=None, timeout=50000) | 4621 self._GetResultFromJSONRequest(cmd_dict, windex=None, timeout=50000) |
4788 | 4622 |
4789 def ConnectToCellularNetwork(self): | |
4790 """Connects to the available cellular network. | |
4791 | |
4792 Blocks until connection succeeds or fails. | |
4793 | |
4794 Returns: | |
4795 An error string if an error occured. | |
4796 None otherwise. | |
4797 | |
4798 Raises: | |
4799 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4800 """ | |
4801 # Every device should only have one cellular network present, so we can | |
4802 # scan for it. | |
4803 cellular_networks = self.NetworkScan().get('cellular_networks', {}).keys() | |
4804 self.assertTrue(cellular_networks, 'Could not find cellular service.') | |
4805 service_path = cellular_networks[0] | |
4806 | |
4807 cmd_dict = { | |
4808 'command': 'ConnectToCellularNetwork', | |
4809 'service_path': service_path, | |
4810 } | |
4811 result = self._GetResultFromJSONRequest( | |
4812 cmd_dict, windex=None, timeout=50000) | |
4813 return result.get('error_string') | |
4814 | |
4815 def DisconnectFromCellularNetwork(self): | |
4816 """Disconnect from the connected cellular network. | |
4817 | |
4818 Blocks until disconnect is complete. | |
4819 | |
4820 Raises: | |
4821 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4822 """ | |
4823 cmd_dict = { | |
4824 'command': 'DisconnectFromCellularNetwork', | |
4825 } | |
4826 self._GetResultFromJSONRequest(cmd_dict, windex=None) | |
4827 | |
4828 def ConnectToWifiNetwork(self, service_path, password='', shared=True): | |
4829 """Connect to a wifi network by its service path. | |
4830 | |
4831 Blocks until connection succeeds or fails. | |
4832 | |
4833 Args: | |
4834 service_path: Flimflam path that defines the wifi network. | |
4835 password: Passphrase for connecting to the wifi network. | |
4836 shared: Boolean value specifying whether the network should be shared. | |
4837 | |
4838 Returns: | |
4839 An error string if an error occured. | |
4840 None otherwise. | |
4841 | |
4842 Raises: | |
4843 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4844 """ | |
4845 cmd_dict = { | |
4846 'command': 'ConnectToWifiNetwork', | |
4847 'service_path': service_path, | |
4848 'password': password, | |
4849 'shared': shared, | |
4850 } | |
4851 result = self._GetResultFromJSONRequest( | |
4852 cmd_dict, windex=None, timeout=50000) | |
4853 return result.get('error_string') | |
4854 | |
4855 def ConnectToHiddenWifiNetwork(self, ssid, security, password='', | 4623 def ConnectToHiddenWifiNetwork(self, ssid, security, password='', |
4856 shared=True, save_credentials=False): | 4624 shared=True, save_credentials=False): |
4857 """Connect to a wifi network by its service path. | 4625 """Connect to a wifi network by its service path. |
4858 | 4626 |
4859 Blocks until connection succeeds or fails. | 4627 Blocks until connection succeeds or fails. |
4860 | 4628 |
4861 Args: | 4629 Args: |
4862 ssid: The SSID of the network to connect to. | 4630 ssid: The SSID of the network to connect to. |
4863 security: The network's security type. One of: 'SECURITY_NONE', | 4631 security: The network's security type. One of: 'SECURITY_NONE', |
4864 'SECURITY_WEP', 'SECURITY_WPA', 'SECURITY_RSN', 'SECURITY_8021X' | 4632 'SECURITY_WEP', 'SECURITY_WPA', 'SECURITY_RSN', 'SECURITY_8021X' |
(...skipping 16 matching lines...) Expand all Loading... |
4881 'ssid': ssid, | 4649 'ssid': ssid, |
4882 'security': security, | 4650 'security': security, |
4883 'password': password, | 4651 'password': password, |
4884 'shared': shared, | 4652 'shared': shared, |
4885 'save_credentials': save_credentials, | 4653 'save_credentials': save_credentials, |
4886 } | 4654 } |
4887 result = self._GetResultFromJSONRequest( | 4655 result = self._GetResultFromJSONRequest( |
4888 cmd_dict, windex=None, timeout=50000) | 4656 cmd_dict, windex=None, timeout=50000) |
4889 return result.get('error_string') | 4657 return result.get('error_string') |
4890 | 4658 |
4891 def DisconnectFromWifiNetwork(self): | |
4892 """Disconnect from the connected wifi network. | |
4893 | |
4894 Blocks until disconnect is complete. | |
4895 | |
4896 Raises: | |
4897 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4898 """ | |
4899 cmd_dict = { | |
4900 'command': 'DisconnectFromWifiNetwork', | |
4901 } | |
4902 self._GetResultFromJSONRequest(cmd_dict, windex=None) | |
4903 | |
4904 def AddPrivateNetwork(self, | |
4905 hostname, | |
4906 service_name, | |
4907 provider_type, | |
4908 username, | |
4909 password, | |
4910 cert_id='', | |
4911 key=''): | |
4912 """Add and connect to a private network. | |
4913 | |
4914 Blocks until connection succeeds or fails. This is equivalent to | |
4915 'Add Private Network' in the network menu UI. | |
4916 | |
4917 Args: | |
4918 hostname: Server hostname for the private network. | |
4919 service_name: Service name that defines the private network. Do not | |
4920 add multiple services with the same name. | |
4921 provider_type: Types are L2TP_IPSEC_PSK and L2TP_IPSEC_USER_CERT. | |
4922 Provider type OPEN_VPN is not yet supported. | |
4923 Type names returned by GetPrivateNetworkInfo will | |
4924 also work. | |
4925 username: Username for connecting to the virtual network. | |
4926 password: Passphrase for connecting to the virtual network. | |
4927 cert_id: Certificate id for a L2TP_IPSEC_USER_CERT network. | |
4928 key: Pre-shared key for a L2TP_IPSEC_PSK network. | |
4929 | |
4930 Returns: | |
4931 An error string if an error occured. | |
4932 None otherwise. | |
4933 | |
4934 Raises: | |
4935 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4936 """ | |
4937 cmd_dict = { | |
4938 'command': 'AddPrivateNetwork', | |
4939 'hostname': hostname, | |
4940 'service_name': service_name, | |
4941 'provider_type': provider_type, | |
4942 'username': username, | |
4943 'password': password, | |
4944 'cert_id': cert_id, | |
4945 'key': key, | |
4946 } | |
4947 result = self._GetResultFromJSONRequest( | |
4948 cmd_dict, windex=None, timeout=50000) | |
4949 return result.get('error_string') | |
4950 | |
4951 def GetPrivateNetworkInfo(self): | |
4952 """Get details about private networks on chromeos. | |
4953 | |
4954 Returns: | |
4955 A dictionary including information about all remembered virtual networks | |
4956 as well as the currently connected virtual network, if any. | |
4957 Sample: | |
4958 { u'connected': u'/service/vpn_123_45_67_89_test_vpn'} | |
4959 u'/service/vpn_123_45_67_89_test_vpn': | |
4960 { u'username': u'vpn_user', | |
4961 u'name': u'test_vpn', | |
4962 u'hostname': u'123.45.67.89', | |
4963 u'key': u'abcde', | |
4964 u'cert_id': u'', | |
4965 u'password': u'zyxw123', | |
4966 u'provider_type': u'L2TP_IPSEC_PSK'}, | |
4967 u'/service/vpn_111_11_11_11_test_vpn2': | |
4968 { u'username': u'testerman', | |
4969 u'name': u'test_vpn2', | |
4970 u'hostname': u'111.11.11.11', | |
4971 u'key': u'fghijklm', | |
4972 u'cert_id': u'', | |
4973 u'password': u'789mnop', | |
4974 u'provider_type': u'L2TP_IPSEC_PSK'}, | |
4975 | |
4976 Raises: | |
4977 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4978 """ | |
4979 cmd_dict = { 'command': 'GetPrivateNetworkInfo' } | |
4980 return self._GetResultFromJSONRequest(cmd_dict, windex=None) | |
4981 | |
4982 def ConnectToPrivateNetwork(self, service_path): | |
4983 """Connect to a remembered private network by its service path. | |
4984 | |
4985 Blocks until connection succeeds or fails. The network must have been | |
4986 previously added with all necessary connection details. | |
4987 | |
4988 Args: | |
4989 service_path: Service name that defines the private network. | |
4990 | |
4991 Returns: | |
4992 An error string if an error occured. | |
4993 None otherwise. | |
4994 | |
4995 Raises: | |
4996 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
4997 """ | |
4998 cmd_dict = { | |
4999 'command': 'ConnectToPrivateNetwork', | |
5000 'service_path': service_path, | |
5001 } | |
5002 result = self._GetResultFromJSONRequest( | |
5003 cmd_dict, windex=None, timeout=50000) | |
5004 return result.get('error_string') | |
5005 | |
5006 def DisconnectFromPrivateNetwork(self): | |
5007 """Disconnect from the active private network. | |
5008 | |
5009 Expects a private network to be active. | |
5010 | |
5011 Raises: | |
5012 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
5013 """ | |
5014 cmd_dict = { | |
5015 'command': 'DisconnectFromPrivateNetwork', | |
5016 } | |
5017 return self._GetResultFromJSONRequest(cmd_dict, windex=None) | |
5018 | |
5019 def EnableSpokenFeedback(self, enabled): | 4659 def EnableSpokenFeedback(self, enabled): |
5020 """Enables or disables spoken feedback accessibility mode. | 4660 """Enables or disables spoken feedback accessibility mode. |
5021 | 4661 |
5022 Args: | 4662 Args: |
5023 enabled: Boolean value indicating the desired state of spoken feedback. | 4663 enabled: Boolean value indicating the desired state of spoken feedback. |
5024 | 4664 |
5025 Raises: | 4665 Raises: |
5026 pyauto_errors.JSONInterfaceError if the automation call returns an error. | 4666 pyauto_errors.JSONInterfaceError if the automation call returns an error. |
5027 """ | 4667 """ |
5028 cmd_dict = { | 4668 cmd_dict = { |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5941 successful = result.wasSuccessful() | 5581 successful = result.wasSuccessful() |
5942 if not successful: | 5582 if not successful: |
5943 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) | 5583 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) |
5944 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ | 5584 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ |
5945 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) | 5585 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) |
5946 sys.exit(not successful) | 5586 sys.exit(not successful) |
5947 | 5587 |
5948 | 5588 |
5949 if __name__ == '__main__': | 5589 if __name__ == '__main__': |
5950 Main() | 5590 Main() |
OLD | NEW |