Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """PyAuto: Python Interface to Chromium's Automation Proxy. | 7 """PyAuto: Python Interface to Chromium's Automation Proxy. |
| 8 | 8 |
| 9 PyAuto uses swig to expose Automation Proxy interfaces to Python. | 9 PyAuto uses swig to expose Automation Proxy interfaces to Python. |
| 10 For complete documentation on the functionality available, | 10 For complete documentation on the functionality available, |
| 11 run pydoc on this file. | 11 run pydoc on this file. |
| 12 | 12 |
| 13 Ref: http://dev.chromium.org/developers/testing/pyauto | 13 Ref: http://dev.chromium.org/developers/testing/pyauto |
| 14 | 14 |
| 15 | 15 |
| 16 Include the following in your PyAuto test script to make it run standalone. | 16 Include the following in your PyAuto test script to make it run standalone. |
| 17 | 17 |
| 18 from pyauto import Main | 18 from pyauto import Main |
| 19 | 19 |
| 20 if __name__ == '__main__': | 20 if __name__ == '__main__': |
| 21 Main() | 21 Main() |
| 22 | 22 |
| 23 This script can be used as an executable to fire off other scripts, similar | 23 This script can be used as an executable to fire off other scripts, similar |
| 24 to unittest.py | 24 to unittest.py |
| 25 python pyauto.py test_script | 25 python pyauto.py test_script |
| 26 """ | 26 """ |
| 27 | 27 |
| 28 import exceptions | |
|
Nirnimesh
2010/11/17 01:25:49
not needed. 'IndexError' is already in scope
kkania
2010/11/17 22:16:08
Done.
| |
| 28 import logging | 29 import logging |
| 29 import optparse | 30 import optparse |
| 30 import os | 31 import os |
| 31 import shutil | 32 import shutil |
| 32 import signal | 33 import signal |
| 33 import subprocess | 34 import subprocess |
| 34 import sys | 35 import sys |
| 35 import tempfile | 36 import tempfile |
| 36 import time | 37 import time |
| 37 import types | 38 import types |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 raise | 80 raise |
| 80 | 81 |
| 81 # Should go after sys.path is set appropriately | 82 # Should go after sys.path is set appropriately |
| 82 import bookmark_model | 83 import bookmark_model |
| 83 import download_info | 84 import download_info |
| 84 import history_info | 85 import history_info |
| 85 import omnibox_info | 86 import omnibox_info |
| 86 import plugins_info | 87 import plugins_info |
| 87 import prefs_info | 88 import prefs_info |
| 88 from pyauto_errors import JSONInterfaceError | 89 from pyauto_errors import JSONInterfaceError |
| 90 from pyauto_errors import NTPThumbnailNotShownError | |
| 89 import simplejson as json # found in third_party | 91 import simplejson as json # found in third_party |
| 90 | 92 |
| 91 | 93 |
| 92 class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): | 94 class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): |
| 93 """Base class for UI Test Cases in Python. | 95 """Base class for UI Test Cases in Python. |
| 94 | 96 |
| 95 A browser is created before executing each test, and is destroyed after | 97 A browser is created before executing each test, and is destroyed after |
| 96 each test irrespective of whether the test passed or failed. | 98 each test irrespective of whether the test passed or failed. |
| 97 | 99 |
| 98 You should derive from this class and create methods with 'test' prefix, | 100 You should derive from this class and create methods with 'test' prefix, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 @staticmethod | 192 @staticmethod |
| 191 def GetFileURLForDataPath(relative_path): | 193 def GetFileURLForDataPath(relative_path): |
| 192 """Get file:// url for the given path relative to the chrome test data dir. | 194 """Get file:// url for the given path relative to the chrome test data dir. |
| 193 | 195 |
| 194 Also quotes the url using urllib.quote(). | 196 Also quotes the url using urllib.quote(). |
| 195 """ | 197 """ |
| 196 return PyUITest.GetFileURLForPath( | 198 return PyUITest.GetFileURLForPath( |
| 197 os.path.join(PyUITest.DataDir(), relative_path)) | 199 os.path.join(PyUITest.DataDir(), relative_path)) |
| 198 | 200 |
| 199 @staticmethod | 201 @staticmethod |
| 202 def GetFileURLForDataPath(relative_path): | |
|
Nirnimesh
2010/11/17 01:25:49
this is still duplicated
kkania
2010/11/17 22:16:08
Done.
| |
| 203 """Get file:// url for the given path relative to the chrome test data dir. | |
| 204 | |
| 205 Also quotes the url using urllib.quote(). | |
| 206 """ | |
| 207 return PyUITest.GetFileURLForPath( | |
| 208 os.path.join(PyUITest.DataDir(), relative_path)) | |
| 209 | |
| 210 @staticmethod | |
| 200 def IsMac(): | 211 def IsMac(): |
| 201 """Are we on Mac?""" | 212 """Are we on Mac?""" |
| 202 return 'darwin' == sys.platform | 213 return 'darwin' == sys.platform |
| 203 | 214 |
| 204 @staticmethod | 215 @staticmethod |
| 205 def IsLinux(): | 216 def IsLinux(): |
| 206 """Are we on Linux? ChromeOS is linux too.""" | 217 """Are we on Linux? ChromeOS is linux too.""" |
| 207 return 'linux2' == sys.platform | 218 return 'linux2' == sys.platform |
| 208 | 219 |
| 209 @staticmethod | 220 @staticmethod |
| (...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1769 | 1780 |
| 1770 Raises: | 1781 Raises: |
| 1771 pyauto_errors.JSONInterfaceError if the automation call returns an error. | 1782 pyauto_errors.JSONInterfaceError if the automation call returns an error. |
| 1772 """ | 1783 """ |
| 1773 cmd_dict = { | 1784 cmd_dict = { |
| 1774 'command': 'DisableSyncForDatatypes', | 1785 'command': 'DisableSyncForDatatypes', |
| 1775 'datatypes': datatypes, | 1786 'datatypes': datatypes, |
| 1776 } | 1787 } |
| 1777 return self._GetResultFromJSONRequest(cmd_dict)['success'] | 1788 return self._GetResultFromJSONRequest(cmd_dict)['success'] |
| 1778 | 1789 |
| 1790 def GetNTPThumbnails(self): | |
| 1791 """Return a list of info about the sites in the NTP most visited section. | |
| 1792 SAMPLE: | |
| 1793 [{ u'title': u'Google', | |
| 1794 u'url': u'http://www.google.com', | |
| 1795 u'is_pinned': False}, | |
| 1796 { | |
| 1797 u'title': u'Yahoo', | |
| 1798 u'url': u'http://www.yahoo.com', | |
| 1799 u'is_pinned': True}] | |
| 1800 """ | |
| 1801 return self._GetNTPInfo()['most_visited'] | |
| 1802 | |
| 1803 def GetNTPThumbnailIndex(self, thumbnail): | |
| 1804 """Returns the index of the given NTP thumbnail, or -1 if it is not shown. | |
| 1805 | |
| 1806 Args: | |
| 1807 thumbnail: a thumbnail dict received from |GetNTPThumbnails| | |
| 1808 """ | |
| 1809 thumbnails = self.GetNTPThumbnails() | |
| 1810 for i in range(len(thumbnails)): | |
| 1811 if thumbnails[i]['url'] == thumbnail['url']: | |
| 1812 return i | |
| 1813 return -1 | |
| 1814 | |
| 1815 def MoveNTPThumbnail(self, thumbnail, new_index): | |
| 1816 """Moves the given thumbnail to a new index. The indices in the NTP Most | |
| 1817 Visited sites section look like: | |
| 1818 0 1 2 3 | |
| 1819 4 5 6 7 | |
| 1820 | |
| 1821 Args: | |
| 1822 thumbnail: a thumbnail dict received from |GetNTPThumbnails| | |
| 1823 new_index: the index to be moved to in the Most Visited sites section | |
| 1824 | |
| 1825 Raises: | |
| 1826 exceptions.IndexError if there is no thumbnail at the index | |
| 1827 | |
| 1828 Note: | |
|
Nirnimesh
2010/11/17 01:25:49
Move the note before Args:
kkania
2010/11/17 22:16:08
Done.
| |
| 1829 When a thumbnail is moved, it is automatically pinned | |
| 1830 """ | |
| 1831 if new_index < 0 or new_index >= len(self.GetNTPThumbnails()): | |
| 1832 raise exceptions.IndexError() | |
| 1833 self._CheckNTPThumbnailShown(thumbnail) | |
| 1834 cmd_dict = { | |
| 1835 'command': 'MoveNTPMostVisitedThumbnail', | |
| 1836 'url': thumbnail['url'], | |
| 1837 'index': new_index, | |
| 1838 'old_index': self.GetNTPThumbnailIndex(thumbnail) | |
| 1839 } | |
| 1840 self._GetResultFromJSONRequest(cmd_dict) | |
| 1841 | |
| 1842 def RemoveNTPThumbnail(self, thumbnail): | |
| 1843 """Removes the NTP thumbnail and returns true on success. | |
| 1844 | |
| 1845 Args: | |
| 1846 thumbnail: a thumbnail dict received from |GetNTPThumbnails| | |
| 1847 """ | |
| 1848 self._CheckNTPThumbnailShown(thumbnail) | |
| 1849 cmd_dict = { | |
| 1850 'command': 'RemoveNTPMostVisitedThumbnail', | |
| 1851 'url': thumbnail['url'] | |
| 1852 } | |
| 1853 self._GetResultFromJSONRequest(cmd_dict) | |
| 1854 | |
| 1855 def PinNTPThumbnail(self, thumbnail): | |
| 1856 """Pins the NTP thumbnail. | |
| 1857 | |
| 1858 Args: | |
| 1859 thumbnail: a thumbnail dict received from |GetNTPThumbnails| | |
| 1860 """ | |
| 1861 self._CheckNTPThumbnailShown(thumbnail) | |
| 1862 self.MoveNTPThumbnail(thumbnail, self.GetNTPThumbnailIndex(thumbnail)) | |
| 1863 | |
| 1864 def UnpinNTPThumbnail(self, thumbnail): | |
| 1865 """Unpins the NTP thumbnail and returns true on success. | |
| 1866 | |
| 1867 Args: | |
| 1868 thumbnail: a thumbnail dict received from |GetNTPThumbnails| | |
| 1869 """ | |
| 1870 self._CheckNTPThumbnailShown(thumbnail) | |
| 1871 cmd_dict = { | |
| 1872 'command': 'UnpinNTPMostVisitedThumbnail', | |
| 1873 'url': thumbnail['url'] | |
| 1874 } | |
| 1875 self._GetResultFromJSONRequest(cmd_dict) | |
| 1876 | |
| 1877 def IsNTPThumbnailPinned(self, thumbnail): | |
| 1878 """Returns whether the NTP thumbnail is pinned. | |
| 1879 | |
| 1880 Args: | |
| 1881 thumbnail: a thumbnail dict received from |GetNTPThumbnails| | |
| 1882 """ | |
| 1883 self._CheckNTPThumbnailShown(thumbnail) | |
| 1884 index = self.GetNTPThumbnailIndex(thumbnail) | |
| 1885 return self.GetNTPThumbnails()[index]['is_pinned'] | |
| 1886 | |
| 1887 def RestoreAllNTPThumbnails(self): | |
| 1888 """Restores all the removed NTP thumbnails. | |
| 1889 Note: | |
| 1890 the default thumbnails may come back into the Most Visited sites | |
| 1891 section after doing this | |
| 1892 """ | |
| 1893 cmd_dict = { | |
| 1894 'command': 'RestoreAllNTPMostVisitedThumbnails' | |
| 1895 } | |
| 1896 self._GetResultFromJSONRequest(cmd_dict) | |
| 1897 | |
| 1898 def CloseDefaultNTPThumbnails(self): | |
|
Nirnimesh
2010/11/17 01:25:49
s/Close/Remove/ ?
Where is it used?
kkania
2010/11/17 22:16:08
Renamed it, use it in a new test
| |
| 1899 """Closes all the default NTP thumbnails. These do not actually need to be | |
| 1900 showing to close. | |
| 1901 Note: | |
| 1902 using this method will make your test depend on the default thumbnail | |
| 1903 urls, which could easily change. Do not use this method unless | |
| 1904 necessary. | |
| 1905 """ | |
| 1906 cmd_dict = { 'command': 'RemoveNTPMostVisitedThumbnail' } | |
| 1907 cmd_dict['url'] = 'http://www.google.com/chrome/intl/en/welcome.html' | |
| 1908 self._GetResultFromJSONRequest(cmd_dict) | |
| 1909 cmd_dict['url'] = ('https://tools.google.com/chrome/intl/en/themes' | |
| 1910 '/index.html') | |
| 1911 self._GetResultFromJSONRequest(cmd_dict) | |
| 1912 | |
| 1913 def GetNTPRecentlyClosed(self): | |
| 1914 """Return a list of info about the items in the NTP recently closed section. | |
| 1915 SAMPLE: | |
| 1916 [{ | |
| 1917 u'type': u'tab', | |
| 1918 u'url': u'http://www.bing.com', | |
| 1919 u'title': u'Bing', | |
| 1920 u'timestamp': 2139082.03912, # Seconds since epoch (Jan 1, 1970) | |
| 1921 u'direction': u'ltr'}, | |
| 1922 { | |
| 1923 u'type': u'window', | |
| 1924 u'timestamp': 2130821.90812, | |
| 1925 u'tabs': [ | |
| 1926 { | |
| 1927 u'type': u'tab', | |
| 1928 u'url': u'http://www.cnn.com', | |
| 1929 u'title': u'CNN', | |
| 1930 u'timestamp': 2129082.12098, | |
| 1931 u'direction': u'ltr'}]}, | |
| 1932 { | |
| 1933 u'type': u'tab', | |
| 1934 u'url': u'http://www.altavista.com', | |
| 1935 u'title': u'Altavista', | |
| 1936 u'timestamp': 21390820.12903, | |
| 1937 u'direction': u'rtl'}] | |
| 1938 """ | |
| 1939 return self._GetNTPInfo()['recently_closed'] | |
| 1940 | |
| 1941 def _GetNTPInfo(self): | |
| 1942 """Get info about the NTP. This does not retrieve the actual info shown | |
| 1943 in a particular NTP, but the current data that would be used to display | |
| 1944 a NTP. | |
| 1945 | |
| 1946 This includes info about the most visited sites and the recently closed | |
| 1947 tabs and windows. | |
| 1948 | |
| 1949 TODO(kkania): Add info about apps. | |
| 1950 | |
| 1951 Returns: | |
| 1952 a dictionary containing info about NTP info. See details about the | |
| 1953 sections in their respective methods. | |
| 1954 | |
| 1955 SAMPLE: | |
| 1956 { u'most_visited': [ ... ], | |
| 1957 u'recently_closed': [ ... ] | |
| 1958 } | |
| 1959 | |
| 1960 Raises: | |
| 1961 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
| 1962 """ | |
| 1963 cmd_dict = { | |
| 1964 'command': 'GetNTPInfo', | |
| 1965 } | |
| 1966 return self._GetResultFromJSONRequest(cmd_dict) | |
| 1967 | |
| 1968 def _CheckNTPThumbnailShown(self, thumbnail): | |
| 1969 if self.GetNTPThumbnailIndex(thumbnail) == -1: | |
| 1970 raise NTPThumbnailNotShownError() | |
| 1971 | |
| 1972 | |
| 1779 class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite): | 1973 class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite): |
| 1780 """Base TestSuite for PyAuto UI tests.""" | 1974 """Base TestSuite for PyAuto UI tests.""" |
| 1781 | 1975 |
| 1782 def __init__(self, args): | 1976 def __init__(self, args): |
| 1783 pyautolib.PyUITestSuiteBase.__init__(self, args) | 1977 pyautolib.PyUITestSuiteBase.__init__(self, args) |
| 1784 | 1978 |
| 1785 # Figure out path to chromium binaries | 1979 # Figure out path to chromium binaries |
| 1786 browser_dir = os.path.normpath(os.path.dirname(pyautolib.__file__)) | 1980 browser_dir = os.path.normpath(os.path.dirname(pyautolib.__file__)) |
| 1787 logging.debug('Loading pyauto libs from %s', browser_dir) | 1981 logging.debug('Loading pyauto libs from %s', browser_dir) |
| 1788 self.Initialize(pyautolib.FilePath(browser_dir)) | 1982 self.Initialize(pyautolib.FilePath(browser_dir)) |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2077 if self._options.verbose: | 2271 if self._options.verbose: |
| 2078 verbosity = 2 | 2272 verbosity = 2 |
| 2079 result = PyAutoTextTestRuner(verbosity=verbosity).run(pyauto_suite) | 2273 result = PyAutoTextTestRuner(verbosity=verbosity).run(pyauto_suite) |
| 2080 del loaded_tests # Need to destroy test cases before the suite | 2274 del loaded_tests # Need to destroy test cases before the suite |
| 2081 del pyauto_suite | 2275 del pyauto_suite |
| 2082 sys.exit(not result.wasSuccessful()) | 2276 sys.exit(not result.wasSuccessful()) |
| 2083 | 2277 |
| 2084 | 2278 |
| 2085 if __name__ == '__main__': | 2279 if __name__ == '__main__': |
| 2086 Main() | 2280 Main() |
| OLD | NEW |