On 07/14/2016 08:25 AM, Smith, Elliot wrote: > On 12 July 2016 at 20:56, Aníbal Limón wrote: > >> Do the raname in order to reuse selenium helper outside django >> environment. >> > > Hello Anibal. > > I'm not able to apply the first patch. I get a message about > > "Reversed (or previously applied) patch detected! Assume -R?" > > Regardless of whether I treat it as reversed or not, I can't apply it. > > Could you pleas resubmit the patches, based on toaster-next? I think it > would also be reasonable to merge the two patches together, as it's pretty > easy to see what's going on. I rebased the patches upon [1], also i merge into one patch [2], sending again... Thanks for look into it, alimon [1] http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/log/?h=toaster-next [2] http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/commit/?h=alimon/toaster&id=255f5da0627adae331fe6fe6b6936569479bd4cb > > Also note that we tend to create the patches relative to the root of a poky > checkout, rather than relative to the bitbake directory, though this is a > minor issue. > > Cheers. > Elliot > > >> >> Signed-off-by: Aníbal Limón >> --- >> lib/toaster/tests/browser/selenium_helpers.py | 205 >> --------------------- >> lib/toaster/tests/browser/selenium_helpers_base.py | 205 >> +++++++++++++++++++++ >> 2 files changed, 205 insertions(+), 205 deletions(-) >> delete mode 100644 lib/toaster/tests/browser/selenium_helpers.py >> create mode 100644 lib/toaster/tests/browser/selenium_helpers_base.py >> >> diff --git a/lib/toaster/tests/browser/selenium_helpers.py >> b/lib/toaster/tests/browser/selenium_helpers.py >> deleted file mode 100644 >> index 54db2e8..0000000 >> --- a/lib/toaster/tests/browser/selenium_helpers.py >> +++ /dev/null >> @@ -1,205 +0,0 @@ >> -#! /usr/bin/env python >> -# ex:ts=4:sw=4:sts=4:et >> -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- >> -# >> -# BitBake Toaster Implementation >> -# >> -# Copyright (C) 2013-2016 Intel Corporation >> -# >> -# This program is free software; you can redistribute it and/or modify >> -# it under the terms of the GNU General Public License version 2 as >> -# published by the Free Software Foundation. >> -# >> -# This program is distributed in the hope that it will be useful, >> -# but WITHOUT ANY WARRANTY; without even the implied warranty of >> -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> -# GNU General Public License for more details. >> -# >> -# You should have received a copy of the GNU General Public License along >> -# with this program; if not, write to the Free Software Foundation, Inc., >> -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >> -# >> -# The Wait class and some of SeleniumDriverHelper and SeleniumTestCase are >> -# modified from Patchwork, released under the same licence terms as >> Toaster: >> -# >> https://github.com/dlespiau/patchwork/blob/master/patchwork/tests.browser.py >> - >> -""" >> -Helper methods for creating Toaster Selenium tests which run within >> -the context of Django unit tests. >> -""" >> - >> -import os >> -import time >> - >> -from django.contrib.staticfiles.testing import StaticLiveServerTestCase >> -from selenium import webdriver >> -from selenium.webdriver.support.ui import WebDriverWait >> -from selenium.common.exceptions import NoSuchElementException, \ >> - StaleElementReferenceException, TimeoutException >> - >> -def create_selenium_driver(browser='chrome'): >> - # set default browser string based on env (if available) >> - env_browser = os.environ.get('TOASTER_TESTS_BROWSER') >> - if env_browser: >> - browser = env_browser >> - >> - if browser == 'chrome': >> - return webdriver.Chrome( >> - service_args=["--verbose", "--log-path=selenium.log"] >> - ) >> - elif browser == 'firefox': >> - return webdriver.Firefox() >> - elif browser == 'ie': >> - return webdriver.Ie() >> - elif browser == 'phantomjs': >> - return webdriver.PhantomJS() >> - else: >> - msg = 'Selenium driver for browser %s is not available' % browser >> - raise RuntimeError(msg) >> - >> -class Wait(WebDriverWait): >> - """ >> - Subclass of WebDriverWait with predetermined timeout and poll >> - frequency. Also deals with a wider variety of exceptions. >> - """ >> - _TIMEOUT = 10 >> - _POLL_FREQUENCY = 0.5 >> - >> - def __init__(self, driver): >> - super(Wait, self).__init__(driver, self._TIMEOUT, >> self._POLL_FREQUENCY) >> - >> - def until(self, method, message=''): >> - """ >> - Calls the method provided with the driver as an argument until the >> - return value is not False. >> - """ >> - >> - end_time = time.time() + self._timeout >> - while True: >> - try: >> - value = method(self._driver) >> - if value: >> - return value >> - except NoSuchElementException: >> - pass >> - except StaleElementReferenceException: >> - pass >> - >> - time.sleep(self._poll) >> - if time.time() > end_time: >> - break >> - >> - raise TimeoutException(message) >> - >> - def until_not(self, method, message=''): >> - """ >> - Calls the method provided with the driver as an argument until the >> - return value is False. >> - """ >> - >> - end_time = time.time() + self._timeout >> - while True: >> - try: >> - value = method(self._driver) >> - if not value: >> - return value >> - except NoSuchElementException: >> - return True >> - except StaleElementReferenceException: >> - pass >> - >> - time.sleep(self._poll) >> - if time.time() > end_time: >> - break >> - >> - raise TimeoutException(message) >> - >> -class SeleniumTestCase(StaticLiveServerTestCase): >> - """ >> - NB StaticLiveServerTestCase is used as the base test case so that >> - static files are served correctly in a Selenium test run context; see >> - >> https://docs.djangoproject.com/en/1.9/ref/contrib/staticfiles/#specialized-test-case-to-support-live-testing >> - """ >> - >> - @classmethod >> - def setUpClass(cls): >> - """ Create a webdriver driver at the class level """ >> - >> - super(SeleniumTestCase, cls).setUpClass() >> - >> - # instantiate the Selenium webdriver once for all the test methods >> - # in this test case >> - cls.driver = create_selenium_driver() >> - cls.driver.maximize_window() >> - >> - @classmethod >> - def tearDownClass(cls): >> - """ Clean up webdriver driver """ >> - >> - cls.driver.quit() >> - super(SeleniumTestCase, cls).tearDownClass() >> - >> - def get(self, url): >> - """ >> - Selenium requires absolute URLs, so convert Django URLs returned >> - by resolve() or similar to absolute ones and get using the >> - webdriver instance. >> - >> - url: a relative URL >> - """ >> - abs_url = '%s%s' % (self.live_server_url, url) >> - self.driver.get(abs_url) >> - >> - def find(self, selector): >> - """ Find single element by CSS selector """ >> - return self.driver.find_element_by_css_selector(selector) >> - >> - def find_all(self, selector): >> - """ Find all elements matching CSS selector """ >> - return self.driver.find_elements_by_css_selector(selector) >> - >> - def focused_element(self): >> - """ Return the element which currently has focus on the page """ >> - return self.driver.switch_to.active_element >> - >> - def wait_until_present(self, selector): >> - """ Wait until element matching CSS selector is on the page """ >> - is_present = lambda driver: self.find(selector) >> - msg = 'An element matching "%s" should be on the page' % selector >> - element = Wait(self.driver).until(is_present, msg) >> - return element >> - >> - def wait_until_visible(self, selector): >> - """ Wait until element matching CSS selector is visible on the >> page """ >> - is_visible = lambda driver: self.find(selector).is_displayed() >> - msg = 'An element matching "%s" should be visible' % selector >> - Wait(self.driver).until(is_visible, msg) >> - return self.find(selector) >> - >> - def wait_until_focused(self, selector): >> - """ Wait until element matching CSS selector has focus """ >> - is_focused = \ >> - lambda driver: self.find(selector) == self.focused_element() >> - msg = 'An element matching "%s" should be focused' % selector >> - Wait(self.driver).until(is_focused, msg) >> - return self.find(selector) >> - >> - def enter_text(self, selector, value): >> - """ Insert text into element matching selector """ >> - # note that keyup events don't occur until the element is clicked >> - # (in the case of , for example), so >> simulate >> - # user clicking the element before inserting text into it >> - field = self.click(selector) >> - >> - field.send_keys(value) >> - return field >> - >> - def click(self, selector): >> - """ Click on element which matches CSS selector """ >> - element = self.wait_until_visible(selector) >> - element.click() >> - return element >> - >> - def get_page_source(self): >> - """ Get raw HTML for the current page """ >> - return self.driver.page_source >> diff --git a/lib/toaster/tests/browser/selenium_helpers_base.py >> b/lib/toaster/tests/browser/selenium_helpers_base.py >> new file mode 100644 >> index 0000000..54db2e8 >> --- /dev/null >> +++ b/lib/toaster/tests/browser/selenium_helpers_base.py >> @@ -0,0 +1,205 @@ >> +#! /usr/bin/env python >> +# ex:ts=4:sw=4:sts=4:et >> +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- >> +# >> +# BitBake Toaster Implementation >> +# >> +# Copyright (C) 2013-2016 Intel Corporation >> +# >> +# This program is free software; you can redistribute it and/or modify >> +# it under the terms of the GNU General Public License version 2 as >> +# published by the Free Software Foundation. >> +# >> +# This program is distributed in the hope that it will be useful, >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +# GNU General Public License for more details. >> +# >> +# You should have received a copy of the GNU General Public License along >> +# with this program; if not, write to the Free Software Foundation, Inc., >> +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >> +# >> +# The Wait class and some of SeleniumDriverHelper and SeleniumTestCase are >> +# modified from Patchwork, released under the same licence terms as >> Toaster: >> +# >> https://github.com/dlespiau/patchwork/blob/master/patchwork/tests.browser.py >> + >> +""" >> +Helper methods for creating Toaster Selenium tests which run within >> +the context of Django unit tests. >> +""" >> + >> +import os >> +import time >> + >> +from django.contrib.staticfiles.testing import StaticLiveServerTestCase >> +from selenium import webdriver >> +from selenium.webdriver.support.ui import WebDriverWait >> +from selenium.common.exceptions import NoSuchElementException, \ >> + StaleElementReferenceException, TimeoutException >> + >> +def create_selenium_driver(browser='chrome'): >> + # set default browser string based on env (if available) >> + env_browser = os.environ.get('TOASTER_TESTS_BROWSER') >> + if env_browser: >> + browser = env_browser >> + >> + if browser == 'chrome': >> + return webdriver.Chrome( >> + service_args=["--verbose", "--log-path=selenium.log"] >> + ) >> + elif browser == 'firefox': >> + return webdriver.Firefox() >> + elif browser == 'ie': >> + return webdriver.Ie() >> + elif browser == 'phantomjs': >> + return webdriver.PhantomJS() >> + else: >> + msg = 'Selenium driver for browser %s is not available' % browser >> + raise RuntimeError(msg) >> + >> +class Wait(WebDriverWait): >> + """ >> + Subclass of WebDriverWait with predetermined timeout and poll >> + frequency. Also deals with a wider variety of exceptions. >> + """ >> + _TIMEOUT = 10 >> + _POLL_FREQUENCY = 0.5 >> + >> + def __init__(self, driver): >> + super(Wait, self).__init__(driver, self._TIMEOUT, >> self._POLL_FREQUENCY) >> + >> + def until(self, method, message=''): >> + """ >> + Calls the method provided with the driver as an argument until the >> + return value is not False. >> + """ >> + >> + end_time = time.time() + self._timeout >> + while True: >> + try: >> + value = method(self._driver) >> + if value: >> + return value >> + except NoSuchElementException: >> + pass >> + except StaleElementReferenceException: >> + pass >> + >> + time.sleep(self._poll) >> + if time.time() > end_time: >> + break >> + >> + raise TimeoutException(message) >> + >> + def until_not(self, method, message=''): >> + """ >> + Calls the method provided with the driver as an argument until the >> + return value is False. >> + """ >> + >> + end_time = time.time() + self._timeout >> + while True: >> + try: >> + value = method(self._driver) >> + if not value: >> + return value >> + except NoSuchElementException: >> + return True >> + except StaleElementReferenceException: >> + pass >> + >> + time.sleep(self._poll) >> + if time.time() > end_time: >> + break >> + >> + raise TimeoutException(message) >> + >> +class SeleniumTestCase(StaticLiveServerTestCase): >> + """ >> + NB StaticLiveServerTestCase is used as the base test case so that >> + static files are served correctly in a Selenium test run context; see >> + >> https://docs.djangoproject.com/en/1.9/ref/contrib/staticfiles/#specialized-test-case-to-support-live-testing >> + """ >> + >> + @classmethod >> + def setUpClass(cls): >> + """ Create a webdriver driver at the class level """ >> + >> + super(SeleniumTestCase, cls).setUpClass() >> + >> + # instantiate the Selenium webdriver once for all the test methods >> + # in this test case >> + cls.driver = create_selenium_driver() >> + cls.driver.maximize_window() >> + >> + @classmethod >> + def tearDownClass(cls): >> + """ Clean up webdriver driver """ >> + >> + cls.driver.quit() >> + super(SeleniumTestCase, cls).tearDownClass() >> + >> + def get(self, url): >> + """ >> + Selenium requires absolute URLs, so convert Django URLs returned >> + by resolve() or similar to absolute ones and get using the >> + webdriver instance. >> + >> + url: a relative URL >> + """ >> + abs_url = '%s%s' % (self.live_server_url, url) >> + self.driver.get(abs_url) >> + >> + def find(self, selector): >> + """ Find single element by CSS selector """ >> + return self.driver.find_element_by_css_selector(selector) >> + >> + def find_all(self, selector): >> + """ Find all elements matching CSS selector """ >> + return self.driver.find_elements_by_css_selector(selector) >> + >> + def focused_element(self): >> + """ Return the element which currently has focus on the page """ >> + return self.driver.switch_to.active_element >> + >> + def wait_until_present(self, selector): >> + """ Wait until element matching CSS selector is on the page """ >> + is_present = lambda driver: self.find(selector) >> + msg = 'An element matching "%s" should be on the page' % selector >> + element = Wait(self.driver).until(is_present, msg) >> + return element >> + >> + def wait_until_visible(self, selector): >> + """ Wait until element matching CSS selector is visible on the >> page """ >> + is_visible = lambda driver: self.find(selector).is_displayed() >> + msg = 'An element matching "%s" should be visible' % selector >> + Wait(self.driver).until(is_visible, msg) >> + return self.find(selector) >> + >> + def wait_until_focused(self, selector): >> + """ Wait until element matching CSS selector has focus """ >> + is_focused = \ >> + lambda driver: self.find(selector) == self.focused_element() >> + msg = 'An element matching "%s" should be focused' % selector >> + Wait(self.driver).until(is_focused, msg) >> + return self.find(selector) >> + >> + def enter_text(self, selector, value): >> + """ Insert text into element matching selector """ >> + # note that keyup events don't occur until the element is clicked >> + # (in the case of , for example), so >> simulate >> + # user clicking the element before inserting text into it >> + field = self.click(selector) >> + >> + field.send_keys(value) >> + return field >> + >> + def click(self, selector): >> + """ Click on element which matches CSS selector """ >> + element = self.wait_until_visible(selector) >> + element.click() >> + return element >> + >> + def get_page_source(self): >> + """ Get raw HTML for the current page """ >> + return self.driver.page_source >> -- >> 2.1.4 >> >> > >