summaryrefslogtreecommitdiff
path: root/openstack_dashboard/test/integration_tests/basewebobject.py
blob: f4207b0ceb72f35b4e41ac6c8748e847c348d68a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
import contextlib
import unittest

import selenium.common.exceptions as Exceptions
from selenium.webdriver.common import by
from selenium.webdriver.remote import webelement
import selenium.webdriver.support.ui as Support
from selenium.webdriver.support import wait


class BaseWebObject(unittest.TestCase):
    """Base class for all web objects."""
    _spinner_locator = (by.By.CSS_SELECTOR, '.modal-body > .loader')

    def __init__(self, driver, conf):
        self.driver = driver
        self.conf = conf
        self.explicit_wait = self.conf.selenium.explicit_wait

    def _is_element_present(self, *locator):
        with self.waits_disabled():
            try:
                self._get_element(*locator)
                return True
            except Exceptions.NoSuchElementException:
                return False

    def _is_element_visible(self, *locator):
        try:
            return self._get_element(*locator).is_displayed()
        except (Exceptions.NoSuchElementException,
                Exceptions.ElementNotVisibleException):
            return False

    def _is_element_displayed(self, element):
        if element is None:
            return False
        try:
            if isinstance(element, webelement.WebElement):
                return element.is_displayed()
            else:
                return element.src_elem.is_displayed()
        except (Exceptions.ElementNotVisibleException,
                Exceptions.StaleElementReferenceException):
            return False

    def _is_text_visible(self, element, text, strict=True):
        if not hasattr(element, 'text'):
            return False
        if strict:
            return element.text == text
        else:
            return text in element.text

    def _get_element(self, *locator):
        return self.driver.find_element(*locator)

    def _get_elements(self, *locator):
        return self.driver.find_elements(*locator)

    def _fill_field_element(self, data, field_element):
        field_element.clear()
        field_element.send_keys(data)
        return field_element

    def _select_dropdown(self, value, element):
        select = Support.Select(element)
        select.select_by_visible_text(value)

    def _select_dropdown_by_value(self, value, element):
        select = Support.Select(element)
        select.select_by_value(value)

    def _get_dropdown_options(self, element):
        select = Support.Select(element)
        return select.options

    def _turn_off_implicit_wait(self):
        self.driver.implicitly_wait(0)

    def _turn_on_implicit_wait(self):
        self.driver.implicitly_wait(self.conf.selenium.implicit_wait)

    def _wait_until(self, predicate, timeout=None, poll_frequency=0.5):
        """Wait until the value returned by predicate is not False.

        It also returns when the timeout is elapsed.
        'predicate' takes the driver as argument.
        """
        if not timeout:
            timeout = self.explicit_wait
        return wait.WebDriverWait(self.driver, timeout, poll_frequency).until(
            predicate)

    def _wait_till_text_present_in_element(self, element, texts, timeout=None):
        """Waiting for a text to appear in a certain element.

        Most frequent usage is actually to wait for a _different_ element
        with a different text to appear in place of an old element.
        So a way to avoid capturing stale element reference should be provided
        for this use case.

        Better to wrap getting entity status cell in a lambda
        to avoid problems with cell being replaced with totally different
        element by Javascript
        """
        if not isinstance(texts, (list, tuple)):
            texts = (texts,)

        def predicate(_):
            elt = element() if hasattr(element, '__call__') else element
            for text in texts:
                if self._is_text_visible(elt, text):
                    return text
            return False

        return self._wait_until(predicate, timeout)

    def _wait_till_element_visible(self, locator, timeout=None):
        self._wait_until(lambda x: self._is_element_visible(*locator), timeout)

    def _wait_till_element_disappears(self, element, timeout=None):
        self._wait_until(lambda x: not self._is_element_displayed(element),
                         timeout)

    @contextlib.contextmanager
    def waits_disabled(self):
        try:
            self._turn_off_implicit_wait()
            yield
        finally:
            self._turn_on_implicit_wait()

    def wait_till_element_disappears(self, element_getter):
        with self.waits_disabled():
            try:
                self._wait_till_element_disappears(element_getter())
            except Exceptions.NoSuchElementException:
                # NOTE(mpavlase): This is valid state. When request completes
                # even before Selenium get a chance to get the spinner element,
                # it will raise the NoSuchElementException exception.
                pass

    def wait_until_element_is_visible(self, locator):
        with self.waits_disabled():
            try:
                self._wait_till_element_visible(locator)
            except Exceptions.NoSuchElementException:
                pass

    def wait_till_spinner_disappears(self):
        def getter():
            return self.driver.find_element(*self._spinner_locator)
        self.wait_till_element_disappears(getter)