1a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish# Use of this source code is governed by a BSD-style license that can be
3a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish# found in the LICENSE file.
4a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
568e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopalimport time
6a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
70e9d7590d936d20b2447c36600b90222bed5a6c1Kris Rambishfrom selenium.common.exceptions import NoSuchElementException
8a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambishfrom selenium.common.exceptions import TimeoutException as \
9a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    SeleniumTimeoutException
10570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambishfrom selenium.common.exceptions import WebDriverException
1198f937f35edc199093c46dd042d58bac84b5de57Kris Rambishfrom selenium.webdriver.support.ui import WebDriverWait
12a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
13a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambishclass WebDriverCoreHelpers(object):
14a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    """Base class for manipulating web pages using webdriver."""
15a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
16a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    def __init__(self):
17a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        super(WebDriverCoreHelpers, self).__init__()
18a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        self.driver = None
1998f937f35edc199093c46dd042d58bac84b5de57Kris Rambish        self.wait = WebDriverWait(self.driver, timeout=5)
20a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
2100b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
222057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal    def _check_for_alert_in_message(self, message, alert_handler):
232057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        """Check for an alert in error message and handle it.
242057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
252057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        @param message: The error message.
262057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        @param alert_handler: The handler method to call.
272057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
282057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        """
29ffa0bd485a9ac60494089ce92d6424ce07bfc866Kris Rambish        if (message.find('An open modal dialog blocked') != -1 and
30ffa0bd485a9ac60494089ce92d6424ce07bfc866Kris Rambish            message.find('unexpected alert open') != -1):
312057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal            alert = self.driver.switch_to_alert()
322057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal            alert_handler(alert)
332057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        else:
342057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal            raise RuntimeError(message)
352057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
362057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
37570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish    def _handle_alert(self, xpath, alert_handler):
38570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        """Calls the alert handler if there is an alert.
39570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish
402057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        @param xpath: The xpath that could raise the alert.
41afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: the handler method to call.
42afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
43570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        """
44570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        try:
45570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            self.driver.find_element_by_xpath(xpath)
46570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            return
47570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        except WebDriverException, e:
48570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            message = str(e)
49afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish            # The messages differ based on the webdriver version
50afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish            if (message.find('An open modal dialog blocked') == -1 and
51afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                message.find('unexpected alert open') == -1):
52570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                return
532057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal            self._handler(alert_handler)
542057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        # Sometimes routers put out multiple alert statements on the same page.
552057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        self._handle_alert(xpath, alert_handler)
562057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
572057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
582057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal    def _handler(self, alert_handler):
592057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        """Handles the alert.
602057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
612057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        @param alert_handler: The custom handler method to call.
622057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal
632057368d8619d01f7f6fa6ac70a3c0d89b238a0eDeepak Gopal        """
64570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        alert = self.driver.switch_to_alert()
65570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        if not alert_handler:
66570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            # The caller did not provide us with a handler, dismiss and raise.
67570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            try:
68570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                alert_text = alert.text
69570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            except WebDriverException:
70570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                # There is a bug in selenium where the alert object will exist
71570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                # but you can't get to the text object right away.
72570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                time.sleep(1)
73570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            alert_text = alert.text
74570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            alert.accept()
75570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish            raise RuntimeError('An alert was encountered and no handler was '
76570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                               'specified.  The text from the alert was: %s'
77570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                               % alert_text)
78570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        alert_handler(alert)
79570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish
8098f937f35edc199093c46dd042d58bac84b5de57Kris Rambish
8198f937f35edc199093c46dd042d58bac84b5de57Kris Rambish    def set_wait_time(self, time):
82afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        """Sets the wait time of webdriver commands.
83afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
84afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param time: the time to wait in seconds.
85afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
86afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        """
8798f937f35edc199093c46dd042d58bac84b5de57Kris Rambish        self.wait = WebDriverWait(self.driver, timeout=time)
8898f937f35edc199093c46dd042d58bac84b5de57Kris Rambish
8998f937f35edc199093c46dd042d58bac84b5de57Kris Rambish
9098f937f35edc199093c46dd042d58bac84b5de57Kris Rambish    def restore_default_wait_time(self):
91afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        """Restores the default webdriver wait time."""
9298f937f35edc199093c46dd042d58bac84b5de57Kris Rambish        self.wait = WebDriverWait(self.driver, timeout=5)
9398f937f35edc199093c46dd042d58bac84b5de57Kris Rambish
9498f937f35edc199093c46dd042d58bac84b5de57Kris Rambish
9568e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal    def wait_for_objects_by_id(self, element_ids, wait_time=5):
9668e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        """Wait for one of the element_ids to show up.
9768e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
9868e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        @param element_ids: A list of all the element ids to find.
9968e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        @param wait_time: The time to wait before giving up.
10068e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
10168e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        @return The id that was found first.
102afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
10368e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        """
10468e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        xpaths = []
10568e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        for element_id in element_ids:
10668e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal            xpaths.append('id("%s")' % element_id)
10768e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        xpath_found = self.wait_for_objects_by_xpath(xpaths, wait_time)
10868e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        for element_id in element_ids:
10968e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal            if element_id in xpath_found:
11068e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal                return element_id
11168e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
11268e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
11368e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal    def wait_for_objects_by_xpath(self, xpaths, wait_time=5):
11468e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        """Wait for one of the items in the xpath to show up.
11568e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
11668e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        @param xpaths: A list of all the xpath's of elements to find.
11768e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        @param wait_time: The time to wait before giving up.
11868e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
11968e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        @return The xpath that was found first.
120afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
12168e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        """
122bf3ec6d286f6c0119c9737849b3ade9c89a1e1c9Deepak Gopal        excpetion = None
12368e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        if wait_time < len(xpaths):
12468e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal            wait_time = len(xpaths)
12568e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        start_time = int(time.time())
12668e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        while (int(time.time()) - start_time) < wait_time:
12768e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal            for xpath in xpaths:
12868e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal                try:
129622f8a0572bba8d0d6f9459b7fda687e116ecd64Deepak Gopal                    element = self.wait_for_object_by_xpath(xpath,
130622f8a0572bba8d0d6f9459b7fda687e116ecd64Deepak Gopal                                                            wait_time=0.25)
131622f8a0572bba8d0d6f9459b7fda687e116ecd64Deepak Gopal                    if element and element.is_displayed():
13268e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal                        return xpath
133bf3ec6d286f6c0119c9737849b3ade9c89a1e1c9Deepak Gopal                except SeleniumTimeoutException, e:
134bf3ec6d286f6c0119c9737849b3ade9c89a1e1c9Deepak Gopal                    exception = str(e)
13568e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal                    pass
136bf3ec6d286f6c0119c9737849b3ade9c89a1e1c9Deepak Gopal        raise SeleniumTimeoutException(exception)
13768e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
13868e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal
139570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish    def click_button_by_id(self, element_id, alert_handler=None):
140a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Clicks a button by id.
141a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
142afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param element_id: the id of the button
143afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
144afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
145afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
146a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
147a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        xpath = 'id("%s")' % element_id
148570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        return self.click_button_by_xpath(xpath, alert_handler)
149a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
15000b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
151570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish    def click_button_by_xpath(self, xpath, alert_handler=None):
152a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Clicks a button by xpath.
153a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
154afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the button
155afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
156afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
157afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
158a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
159a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        button = self.wait_for_object_by_xpath(xpath)
160a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        button.click()
161570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        self._handle_alert(xpath, alert_handler)
162a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
16300b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
1646ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal    def get_url(self, page_url, page_title=None, element_xpath=None):
165afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        """Load page and check if the page loads completely, if not, reload.
16644b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal
167afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param page_url: The url to load.
168afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param page_title: The complete/partial title of the page after loaded.
1696ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal        @param element_xpath: The element that we search for to confirm that
1706ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal                              the page loaded.
17144b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal
17244b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal        """
17344b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal        self.driver.get(page_url)
17444b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal        if page_title:
17544b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal            try:
17644b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal                self.wait.until(lambda _: page_title in self.driver.title)
1776ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal            except SeleniumTimeoutException, e:
17844b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal                self.driver.get(page_url)
17944b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal                self.wait.until(lambda _: self.driver.title)
18044b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal            finally:
18144b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal                if not page_title in self.driver.title:
1826ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal                    raise WebDriverException('Page did not load. Expected %s in'
1836ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal                                             'title, but got %s as title.' %
1846ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal                                             (page_title, self.driver.title))
1856ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal        if element_xpath:
1866ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal            self.wait_for_object_by_xpath(element_xpath)
1876ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal
18844b8005fe5e4d21b22937de0218ecd60898f6ac7Deepak Gopal
18998f937f35edc199093c46dd042d58bac84b5de57Kris Rambish    def wait_for_object_by_id(self, element_id, wait_time=5):
190a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Waits for an element to become available; returns a reference to it.
191a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
192afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param element_id: the id of the element to wait for
193afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_time: the time to wait for the object
194afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
195afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns a reference to the element if found before a timeout.
196a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
197a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
198a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        xpath = 'id("%s")' % element_id
19998f937f35edc199093c46dd042d58bac84b5de57Kris Rambish        return self.wait_for_object_by_xpath(xpath, wait_time=wait_time)
200a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
20100b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
2024632e2dd15129b29fde2280578b61687941d891abmahadev    def wait_for_object_by_xpath_to_vanish(self, xpath, wait_time=5):
2034632e2dd15129b29fde2280578b61687941d891abmahadev        """Wait for the item in xpath to disappear from page.
2044632e2dd15129b29fde2280578b61687941d891abmahadev
2054632e2dd15129b29fde2280578b61687941d891abmahadev        @param xpath: The xpath of the object to wait on.
2064632e2dd15129b29fde2280578b61687941d891abmahadev        @param wait_time: The time to wait before giving up.
2074632e2dd15129b29fde2280578b61687941d891abmahadev
2084632e2dd15129b29fde2280578b61687941d891abmahadev        @return void or raise exception if object does not vanish.
2094632e2dd15129b29fde2280578b61687941d891abmahadev
2104632e2dd15129b29fde2280578b61687941d891abmahadev        """
2114632e2dd15129b29fde2280578b61687941d891abmahadev        start_time = int(time.time())
2124632e2dd15129b29fde2280578b61687941d891abmahadev        while (int(time.time()) - start_time) < wait_time:
2134632e2dd15129b29fde2280578b61687941d891abmahadev            if self.object_by_xpath_exist(xpath):
2144632e2dd15129b29fde2280578b61687941d891abmahadev                time.sleep(0.5)
2154632e2dd15129b29fde2280578b61687941d891abmahadev            else:
2164632e2dd15129b29fde2280578b61687941d891abmahadev                return
2174632e2dd15129b29fde2280578b61687941d891abmahadev        raise SeleniumTimeoutException('The object with xpath %s failed to'
2184632e2dd15129b29fde2280578b61687941d891abmahadev                                       ' vanish.' % xpath)
2194632e2dd15129b29fde2280578b61687941d891abmahadev
2204632e2dd15129b29fde2280578b61687941d891abmahadev
2214632e2dd15129b29fde2280578b61687941d891abmahadev    def wait_for_object_by_id_to_vanish(self, element_id, wait_time=5):
2224632e2dd15129b29fde2280578b61687941d891abmahadev        """Wait for the item in xpath to disappear from page.
2234632e2dd15129b29fde2280578b61687941d891abmahadev
2244632e2dd15129b29fde2280578b61687941d891abmahadev        @param element_id: The id of the object to wait on.
2254632e2dd15129b29fde2280578b61687941d891abmahadev        @param wait_time: The time to wait before giving up.
2264632e2dd15129b29fde2280578b61687941d891abmahadev
2274632e2dd15129b29fde2280578b61687941d891abmahadev        @return void or raise exception if object does not vanish.
2284632e2dd15129b29fde2280578b61687941d891abmahadev
2294632e2dd15129b29fde2280578b61687941d891abmahadev        """
2304632e2dd15129b29fde2280578b61687941d891abmahadev        xpath = 'id("%s")' % element_id
2314632e2dd15129b29fde2280578b61687941d891abmahadev        return self.wait_for_object_by_xpath_to_vanish(xpath,
2324632e2dd15129b29fde2280578b61687941d891abmahadev                                                       wait_time=wait_time)
2334632e2dd15129b29fde2280578b61687941d891abmahadev
2344632e2dd15129b29fde2280578b61687941d891abmahadev
235d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal    def object_by_id_exist(self, element_id):
236d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        """Finds if an object exist in this particular page.
237d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal
238afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param element_id: the id of the element to find
239afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
240afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns True if the element exists. False if the element does not.
241d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal
242d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        """
243d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        xpath = 'id("%s")' % element_id
244d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        return self.object_by_xpath_exist(xpath)
245d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal
24600b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
247d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal    def object_by_xpath_exist(self, xpath):
248d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        """Finds if an object exist in this particular page.
249d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal
250afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the element to find
251afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
252afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns True if the xpath exists. False if the xpath does not.
253d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal
254d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        """
255d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        try:
256d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal            self.wait_for_object_by_xpath(xpath)
257d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        except SeleniumTimeoutException:
258d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal            return False
259d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal        return True
260d1349e8ad62d1d57850f443ef701a7a1c0174916Deepak Gopal
26100b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
26298f937f35edc199093c46dd042d58bac84b5de57Kris Rambish    def wait_for_object_by_xpath(self, xpath, wait_time=5):
263a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Waits for an element to become available; returns a reference to it.
264a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
265afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the element to wait for
266afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_time: the time to wait for the object.
267afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
268afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns reference to the element if found before a timeout.
269a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
270a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
27198f937f35edc199093c46dd042d58bac84b5de57Kris Rambish        self.set_wait_time(wait_time)
272a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        try:
273a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            self.wait.until(lambda _: self.driver.find_element_by_xpath(xpath))
274c0df79a4e65435c7361b27f68da9b3bb9e22528cKris Rambish            element = self.driver.find_element_by_xpath(xpath)
2750e9d7590d936d20b2447c36600b90222bed5a6c1Kris Rambish        except (SeleniumTimeoutException, NoSuchElementException) as e:
276c0df79a4e65435c7361b27f68da9b3bb9e22528cKris Rambish            self.restore_default_wait_time()
277a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            raise SeleniumTimeoutException('Unable to find the object by '
278a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                                           'xpath: %s\n WebDriver exception: '
279a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                                           '%s' % (xpath, str(e)))
28098f937f35edc199093c46dd042d58bac84b5de57Kris Rambish        self.restore_default_wait_time()
281c0df79a4e65435c7361b27f68da9b3bb9e22528cKris Rambish        return element
282a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
2834f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
28400b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish    def item_in_popup_by_id_exist(self, item, element_id):
28500b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        """Returns if an item exists in a popup given a id
28600b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
287afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param item: name of the item
288afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param element_id: the id of the popup
289afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
290afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns True if the item exists; False otherwise.
29100b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
29200b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        """
2938238fdcf89535456a0be158a4f267611ae8b152aKris Rambish        xpath = 'id("%s")' % element_id
29468e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        return self.item_in_popup_by_xpath_exist(item, xpath)
29500b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
29600b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
29700b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish    def item_in_popup_by_xpath_exist(self, item, xpath):
29800b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        """Returns if an item exists in a popup given an xpath
29900b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
300afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param item: name of the item
301afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the popup
302afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
303afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns True if the item exists; False otherwise.
30400b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
30500b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        """
30600b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        if self.number_of_items_in_popup_by_xpath(xpath) == 0:
30700b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish            raise SeleniumTimeoutException('The popup at xpath %s has no items.'
3086ae2154014bbdd1806a39d6d014285eade182d52Deepak Gopal                                           % xpath)
30900b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        popup = self.driver.find_element_by_xpath(xpath)
31000b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        for option in popup.find_elements_by_tag_name('option'):
31100b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish            if option.text == item:
31200b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                return True
31300b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        return False
31400b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
31500b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
3164f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish    def number_of_items_in_popup_by_id(self, element_id, alert_handler=None):
3174f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        """Returns the number of items in a popup given the element ID.
3184f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
319afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param element_id: the html ID of the item
320afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
321afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
322afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
323afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns the number of items in the popup.
3244f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
3254f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        """
3264f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        xpath = 'id("%s")' % element_id
32768e5975ad49b7865dbd82a2915bef8db3e41b64bDeepak Gopal        return self.number_of_items_in_popup_by_xpath(xpath, alert_handler)
3284f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
3294f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
3304f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish    def number_of_items_in_popup_by_xpath(self, xpath, alert_handler=None):
3314f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        """Returns the number of items in a popup given a xpath
3324f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
333afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the popup
334afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
3354f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish                         must take one parameter, a webdriver alert object
3364f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
337afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @returns the number of items in the popup.
338afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
3394f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        """
3404f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        popup = self.driver.find_element_by_xpath(xpath)
3414f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        try:
3424f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish            self.wait.until(lambda _:
3434f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish                            len(popup.find_elements_by_tag_name('option')))
3444f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        except SeleniumTimeoutException, e:
3454f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish            return 0
3464f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        return len(popup.find_elements_by_tag_name('option'))
3474f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
3484f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish
349a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    def select_item_from_popup_by_id(self, item, element_id,
350570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                     wait_for_xpath=None, alert_handler=None):
351a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Selects an item from a popup, by passing the element ID.
352a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
353afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param item: the string of the item to select from the popup
354afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param element_id: the html ID of the item
355afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_for_xpath: an item to wait for before returning, if not
356afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                               specified the method does not wait.
357afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
358afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
359afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
360a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
361a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        xpath = 'id("%s")' % element_id
362570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        self.select_item_from_popup_by_xpath(item, xpath, wait_for_xpath,
363570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                             alert_handler)
364a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
36500b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
366570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish    def select_item_from_popup_by_xpath(self, item, xpath, wait_for_xpath=None,
367570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                        alert_handler=None):
368a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Selects an item from a popup, by passing the xpath of the popup.
369a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
370afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param item: the string of the item to select from the popup
371afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the popup
372afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_for_xpath: an item to wait for before returning, if not
373afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                               specified the method does not wait.
374afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
375afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
376afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
377a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
3784f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        if self.number_of_items_in_popup_by_xpath(xpath) == 0:
379a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            raise SeleniumTimeoutException('The popup at xpath %s has no items.'
38000b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                                           % xpath)
38100b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        if not self.item_in_popup_by_xpath_exist(item, xpath):
38200b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish            raise SeleniumTimeoutException('The popup at xpath %s does not '
38300b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                                           'contain the item %s.' % (xpath,
38400b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                                           item))
3854f65b523eac06131d4dd43ff9fc28a2623a0649bKris Rambish        popup = self.driver.find_element_by_xpath(xpath)
386a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        for option in popup.find_elements_by_tag_name('option'):
387a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            if option.text == item:
388a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                option.click()
389a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                break
390570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        self._handle_alert(xpath, alert_handler)
391a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        if wait_for_xpath:
392a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            self.wait_for_object_by_xpath(wait_for_xpath)
393a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
39400b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
395a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    def set_content_of_text_field_by_id(self, content, text_field_id,
39600b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                                        wait_for_xpath=None,
39700b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                                        abort_check=False):
398a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Sets the content of a textfield, by passing the element ID.
399a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
400afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param content: the content to apply to the textfield
401afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param text_field_id: the html ID of the textfield
402afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_for_xpath: an item to wait for before returning, if not
403afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                               specified the method does not wait.
404afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
405a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
406a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        xpath = 'id("%s")' % text_field_id
40700b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish        self.set_content_of_text_field_by_xpath(content, xpath,
4088e165861dca5dca1b7a344e911b368d835ca10c8Kris Rambish                                                wait_for_xpath=wait_for_xpath,
40900b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish                                                abort_check=abort_check)
41000b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
411a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
412a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    def set_content_of_text_field_by_xpath(self, content, xpath,
413a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                                           wait_for_xpath=None,
414a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                                           abort_check=False):
415a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Sets the content of a textfield, by passing the xpath.
416a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
417afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param content: the content to apply to the textfield
418afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the textfield
419afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_for_xpath: an item to wait for before returning, if not
420afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                               specified the method does not wait.
421afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param abort_check: do not get the current value before setting
422afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
423a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
424a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        # When we can get the value we know the text field is ready.
425a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        text_field = self.driver.find_element_by_xpath(xpath)
426a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        if text_field.get_attribute('type') != 'password' and not abort_check:
427a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            try:
428a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                self.wait.until(lambda _: text_field.get_attribute('value'))
429a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            except SeleniumTimeoutException, e:
430a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                raise SeleniumTimeoutException('Unable to obtain the value of '
431a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                                               'the text field %s.\nWebDriver '
432a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish                                               'exception:%s' % (xpath, str(e)))
433a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        text_field.clear()
434a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        text_field.send_keys(content)
435a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        if wait_for_xpath: self.wait_for_object_by_xpath(wait_for_xpath)
436a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
43700b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
438a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    def set_check_box_selected_by_id(self, check_box_id, selected=True,
439570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                     wait_for_xpath=None, alert_handler=None):
440a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Sets the state of a checkbox, by passing the ID.
441a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
442afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param check_box_id: the html id of the checkbox
443afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param selected: True to check the checkbox; False to uncheck it
444afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_for_xpath: an item to wait for before returning, if not
445afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                               specified the method does not wait.
446afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
447afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
448afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish
449a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
450a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        xpath = 'id("%s")' % check_box_id
451570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        self.set_check_box_selected_by_xpath(xpath, selected, wait_for_xpath,
452570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                             alert_handler)
453a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
45400b1beaed2e82b70b80b551276d38323c7ec6775Kris Rambish
455a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish    def set_check_box_selected_by_xpath(self, xpath, selected=True,
456570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                        wait_for_xpath=None,
457570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish                                        alert_handler=None):
458a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """Sets the state of a checkbox, by passing the xpath.
459a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish
460afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param xpath: the xpath of the checkbox
461afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param selected: True to check the checkbox; False to uncheck it
462afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param wait_for_xpath: an item to wait for before returning, if not
463afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                               specified the method does not wait.
464afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish        @param alert_handler: method invoked if an alert is detected. The method
465afb8f1f8ffc1e52b5b69c831cab66ab7469009ffKris Rambish                              must take one parameter, a webdriver alert object
466a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        """
467a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        check_box = self.wait_for_object_by_xpath(xpath)
468a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        value = check_box.get_attribute('value')
469a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        if (value == '1' and not selected) or (value == '0' and selected):
470a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            check_box.click()
471570972d932ee7b75ae1e48a8bbb34134067ccc36Kris Rambish        self._handle_alert(xpath, alert_handler)
472a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish        if wait_for_xpath:
473a795d34d0feaec631c812fc4fc1db9c735df4110Kris Rambish            self.wait_for_object_by_xpath(wait_for_xpath)
474