summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
authorAníbal Limón <anibal.limon@linux.intel.com>2016-07-19 16:49:10 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-07-20 10:38:52 +0100
commit1bf1e2c208ad137b9b91ca0687d6fb9486045dfd (patch)
tree272fb27138576c7e1a66dc75e723c1a7e700967a /bitbake/lib
parenta61eb1f844814daf525d1db250194ea186c35e71 (diff)
downloadpoky-1bf1e2c208ad137b9b91ca0687d6fb9486045dfd.tar.gz
bitbake: toaster-tests: add class SeleniumTestCaseBase for browser tests
In order to reuse the Selenium helper outside a Django environment (for functional testing), add a new module containing the base class SeleniumTestCaseBase, which only inherits unittest.TestCase Add a class SeleniumTestCase with multiple inheritance of StaticLiveServerTestCase and SeleniumTestCaseBase to prevent existing tests from breaking. (Bitbake rev: 1177b3f368d8b7f8557eb649adb2e327b6df801c) Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com> Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/toaster/tests/browser/selenium_helpers.py184
1 files changed, 3 insertions, 181 deletions
diff --git a/bitbake/lib/toaster/tests/browser/selenium_helpers.py b/bitbake/lib/toaster/tests/browser/selenium_helpers.py
index be1f037825..08711e4558 100644
--- a/bitbake/lib/toaster/tests/browser/selenium_helpers.py
+++ b/bitbake/lib/toaster/tests/browser/selenium_helpers.py
@@ -27,186 +27,8 @@
27Helper methods for creating Toaster Selenium tests which run within 27Helper methods for creating Toaster Selenium tests which run within
28the context of Django unit tests. 28the context of Django unit tests.
29""" 29"""
30
31import os
32import time
33
34from django.contrib.staticfiles.testing import StaticLiveServerTestCase 30from django.contrib.staticfiles.testing import StaticLiveServerTestCase
35from selenium import webdriver 31from tests.browser.selenium_helpers_base import SeleniumTestCaseBase
36from selenium.webdriver.support.ui import WebDriverWait
37from selenium.common.exceptions import NoSuchElementException, \
38 StaleElementReferenceException, TimeoutException
39
40def create_selenium_driver(browser='chrome'):
41 # set default browser string based on env (if available)
42 env_browser = os.environ.get('TOASTER_TESTS_BROWSER')
43 if env_browser:
44 browser = env_browser
45
46 if browser == 'chrome':
47 return webdriver.Chrome(
48 service_args=["--verbose", "--log-path=selenium.log"]
49 )
50 elif browser == 'firefox':
51 return webdriver.Firefox()
52 elif browser == 'ie':
53 return webdriver.Ie()
54 elif browser == 'phantomjs':
55 return webdriver.PhantomJS()
56 else:
57 msg = 'Selenium driver for browser %s is not available' % browser
58 raise RuntimeError(msg)
59
60class Wait(WebDriverWait):
61 """
62 Subclass of WebDriverWait with predetermined timeout and poll
63 frequency. Also deals with a wider variety of exceptions.
64 """
65 _TIMEOUT = 10
66 _POLL_FREQUENCY = 0.5
67
68 def __init__(self, driver):
69 super(Wait, self).__init__(driver, self._TIMEOUT, self._POLL_FREQUENCY)
70
71 def until(self, method, message=''):
72 """
73 Calls the method provided with the driver as an argument until the
74 return value is not False.
75 """
76
77 end_time = time.time() + self._timeout
78 while True:
79 try:
80 value = method(self._driver)
81 if value:
82 return value
83 except NoSuchElementException:
84 pass
85 except StaleElementReferenceException:
86 pass
87
88 time.sleep(self._poll)
89 if time.time() > end_time:
90 break
91
92 raise TimeoutException(message)
93
94 def until_not(self, method, message=''):
95 """
96 Calls the method provided with the driver as an argument until the
97 return value is False.
98 """
99
100 end_time = time.time() + self._timeout
101 while True:
102 try:
103 value = method(self._driver)
104 if not value:
105 return value
106 except NoSuchElementException:
107 return True
108 except StaleElementReferenceException:
109 pass
110
111 time.sleep(self._poll)
112 if time.time() > end_time:
113 break
114
115 raise TimeoutException(message)
116
117class SeleniumTestCase(StaticLiveServerTestCase):
118 """
119 NB StaticLiveServerTestCase is used as the base test case so that
120 static files are served correctly in a Selenium test run context; see
121 https://docs.djangoproject.com/en/1.9/ref/contrib/staticfiles/#specialized-test-case-to-support-live-testing
122 """
123
124 @classmethod
125 def setUpClass(cls):
126 """ Create a webdriver driver at the class level """
127
128 super(SeleniumTestCase, cls).setUpClass()
129
130 # instantiate the Selenium webdriver once for all the test methods
131 # in this test case
132 cls.driver = create_selenium_driver()
133 cls.driver.maximize_window()
134
135 @classmethod
136 def tearDownClass(cls):
137 """ Clean up webdriver driver """
138
139 cls.driver.quit()
140 super(SeleniumTestCase, cls).tearDownClass()
141
142 def get(self, url):
143 """
144 Selenium requires absolute URLs, so convert Django URLs returned
145 by resolve() or similar to absolute ones and get using the
146 webdriver instance.
147
148 url: a relative URL
149 """
150 abs_url = '%s%s' % (self.live_server_url, url)
151 self.driver.get(abs_url)
152
153 def find(self, selector):
154 """ Find single element by CSS selector """
155 return self.driver.find_element_by_css_selector(selector)
156
157 def find_all(self, selector):
158 """ Find all elements matching CSS selector """
159 return self.driver.find_elements_by_css_selector(selector)
160
161 def element_exists(self, selector):
162 """
163 Return True if one element matching selector exists,
164 False otherwise
165 """
166 return len(self.find_all(selector)) == 1
167
168 def focused_element(self):
169 """ Return the element which currently has focus on the page """
170 return self.driver.switch_to.active_element
171
172 def wait_until_present(self, selector):
173 """ Wait until element matching CSS selector is on the page """
174 is_present = lambda driver: self.find(selector)
175 msg = 'An element matching "%s" should be on the page' % selector
176 element = Wait(self.driver).until(is_present, msg)
177 return element
178
179 def wait_until_visible(self, selector):
180 """ Wait until element matching CSS selector is visible on the page """
181 is_visible = lambda driver: self.find(selector).is_displayed()
182 msg = 'An element matching "%s" should be visible' % selector
183 Wait(self.driver).until(is_visible, msg)
184 return self.find(selector)
185
186 def wait_until_focused(self, selector):
187 """ Wait until element matching CSS selector has focus """
188 is_focused = \
189 lambda driver: self.find(selector) == self.focused_element()
190 msg = 'An element matching "%s" should be focused' % selector
191 Wait(self.driver).until(is_focused, msg)
192 return self.find(selector)
193
194 def enter_text(self, selector, value):
195 """ Insert text into element matching selector """
196 # note that keyup events don't occur until the element is clicked
197 # (in the case of <input type="text"...>, for example), so simulate
198 # user clicking the element before inserting text into it
199 field = self.click(selector)
200
201 field.send_keys(value)
202 return field
203
204 def click(self, selector):
205 """ Click on element which matches CSS selector """
206 element = self.wait_until_visible(selector)
207 element.click()
208 return element
209 32
210 def get_page_source(self): 33class SeleniumTestCase(SeleniumTestCaseBase, StaticLiveServerTestCase):
211 """ Get raw HTML for the current page """ 34 pass
212 return self.driver.page_source