All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base
@ 2016-07-12 19:56 Aníbal Limón
  2016-07-12 19:56 ` [PATCH 2/2] toaster/tests: browser add class SeleniumTestCaseBase Aníbal Limón
  2016-07-14 13:25 ` [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Smith, Elliot
  0 siblings, 2 replies; 4+ messages in thread
From: Aníbal Limón @ 2016-07-12 19:56 UTC (permalink / raw)
  To: toaster; +Cc: libertad.gonzalez.de.la.cruz

Do the raname in order to reuse selenium helper outside django
environment.

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
---
 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 <input type="text"...>, 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 <input type="text"...>, 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



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] toaster/tests: browser add class SeleniumTestCaseBase
  2016-07-12 19:56 [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Aníbal Limón
@ 2016-07-12 19:56 ` Aníbal Limón
  2016-07-14 13:25 ` [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Smith, Elliot
  1 sibling, 0 replies; 4+ messages in thread
From: Aníbal Limón @ 2016-07-12 19:56 UTC (permalink / raw)
  To: toaster; +Cc: libertad.gonzalez.de.la.cruz

Add a new module with base class SeleniumTestCaseBase only
with inherit of unittest.TestCase for reuse selenium helper
in functional testing of Toaster outside django environment.

Add class SeleniumTestCase with multiple inherit of
StaticLiveServerTestCase and SeleniumTestCaseBase for don't
broke things.

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
---
 lib/toaster/tests/browser/selenium_helpers.py      | 40 ++++++++++++++++++++++
 lib/toaster/tests/browser/selenium_helpers_base.py | 11 +++---
 2 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 lib/toaster/tests/browser/selenium_helpers.py

diff --git a/lib/toaster/tests/browser/selenium_helpers.py b/lib/toaster/tests/browser/selenium_helpers.py
new file mode 100644
index 0000000..ddb43fd
--- /dev/null
+++ b/lib/toaster/tests/browser/selenium_helpers.py
@@ -0,0 +1,40 @@
+#! /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
+
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
+from tests.browser.selenium_helpers_base import SeleniumTestCaseBase
+
+"""
+Helper methods for creating Toaster Selenium tests which run within
+the context of Django unit tests.
+"""
+
+class SeleniumTestCase(SeleniumTestCaseBase, 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
+    """
+    pass
diff --git a/lib/toaster/tests/browser/selenium_helpers_base.py b/lib/toaster/tests/browser/selenium_helpers_base.py
index 54db2e8..8785a60 100644
--- a/lib/toaster/tests/browser/selenium_helpers_base.py
+++ b/lib/toaster/tests/browser/selenium_helpers_base.py
@@ -24,14 +24,13 @@
 # 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.
+Base helper methods for creating Toaster Selenium tests.
 """
 
 import os
 import time
+import unittest
 
-from django.contrib.staticfiles.testing import StaticLiveServerTestCase
 from selenium import webdriver
 from selenium.webdriver.support.ui import WebDriverWait
 from selenium.common.exceptions import NoSuchElementException, \
@@ -114,7 +113,7 @@ class Wait(WebDriverWait):
 
         raise TimeoutException(message)
 
-class SeleniumTestCase(StaticLiveServerTestCase):
+class SeleniumTestCaseBase(unittest.TestCase):
     """
     NB StaticLiveServerTestCase is used as the base test case so that
     static files are served correctly in a Selenium test run context; see
@@ -125,7 +124,7 @@ class SeleniumTestCase(StaticLiveServerTestCase):
     def setUpClass(cls):
         """ Create a webdriver driver at the class level """
 
-        super(SeleniumTestCase, cls).setUpClass()
+        super(SeleniumTestCaseBase, cls).setUpClass()
 
         # instantiate the Selenium webdriver once for all the test methods
         # in this test case
@@ -137,7 +136,7 @@ class SeleniumTestCase(StaticLiveServerTestCase):
         """ Clean up webdriver driver """
 
         cls.driver.quit()
-        super(SeleniumTestCase, cls).tearDownClass()
+        super(SeleniumTestCaseBase, cls).tearDownClass()
 
     def get(self, url):
         """
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base
  2016-07-12 19:56 [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Aníbal Limón
  2016-07-12 19:56 ` [PATCH 2/2] toaster/tests: browser add class SeleniumTestCaseBase Aníbal Limón
@ 2016-07-14 13:25 ` Smith, Elliot
  2016-07-14 15:55   ` Aníbal Limón
  1 sibling, 1 reply; 4+ messages in thread
From: Smith, Elliot @ 2016-07-14 13:25 UTC (permalink / raw)
  To: Aníbal Limón; +Cc: libertad.gonzalez.de.la.cruz, toaster

[-- Attachment #1: Type: text/plain, Size: 17825 bytes --]

On 12 July 2016 at 20:56, Aníbal Limón <anibal.limon@linux.intel.com> 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.

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 <anibal.limon@linux.intel.com>
> ---
>  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 <input type="text"...>, 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 <input type="text"...>, 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
>
>


-- 
Elliot Smith
Software Engineer
Intel Open Source Technology Centre

[-- Attachment #2: Type: text/html, Size: 22544 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base
  2016-07-14 13:25 ` [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Smith, Elliot
@ 2016-07-14 15:55   ` Aníbal Limón
  0 siblings, 0 replies; 4+ messages in thread
From: Aníbal Limón @ 2016-07-14 15:55 UTC (permalink / raw)
  To: Smith, Elliot; +Cc: libertad.gonzalez.de.la.cruz, toaster

[-- Attachment #1: Type: text/plain, Size: 18646 bytes --]



On 07/14/2016 08:25 AM, Smith, Elliot wrote:
> On 12 July 2016 at 20:56, Aníbal Limón <anibal.limon@linux.intel.com> 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 <anibal.limon@linux.intel.com>
>> ---
>>  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 <input type="text"...>, 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 <input type="text"...>, 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
>>
>>
> 
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-07-14 15:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-12 19:56 [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Aníbal Limón
2016-07-12 19:56 ` [PATCH 2/2] toaster/tests: browser add class SeleniumTestCaseBase Aníbal Limón
2016-07-14 13:25 ` [PATCH 1/2] toaster/tests: browser rename selenium_helpers to selenium_helpers_base Smith, Elliot
2016-07-14 15:55   ` Aníbal Limón

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.