예제 #1
0
 def _get_row_by_locator_text(rows, locator, anchor):
     matches = []
     input_elements = []
     row_index = []
     anchor_text = None
     try:
         anchor = int(anchor) - 1
     except ValueError:
         anchor_text = anchor
     for index, row in enumerate(rows):
         row_content = row.text
         if locator == 'EMPTY' and row_content.strip() == '':
             return row, index
         input_elements = javascript.execute_javascript(
             'return arguments[0].querySelectorAll("input, textarea")', row)
         for elem in input_elements:
             row_content += str(
                 javascript.execute_javascript('return arguments[0].value',
                                               elem))
         if locator in row_content:
             if anchor_text and anchor_text in row_content:
                 return row, index
             row_index.append(index)
             matches.append(row)
     if matches and not anchor_text:
         return matches[anchor], row_index[anchor]
     raise QWebElementNotFoundError(
         'Row that includes texts {} and {} not found'.format(
             locator, anchor_text))
예제 #2
0
 def get_table_element_by_css(locator, anchor):
     table_element = javascript.execute_javascript(
         'return document.querySelectorAll(\'table[summary^="{0}"], '
         'table[name^="{0}"], table[title^="{0}"], th[title^="{0}"], '
         'tr[title^="{0}"], td[title^="{0}"]\')'.format(locator))
     if table_element:
         try:
             anchor = int(anchor) - 1
             if table_element[anchor].tag_name == 'table':
                 return table_element[anchor]
             table_element = javascript.execute_javascript(
                 'return arguments[0].closest("table")',
                 table_element[anchor])
             return table_element
         except (ValueError, TypeError):
             raise IndexError(
                 'Element found by it\'s attribute. When using CSS Selectors'  # pylint: disable=W0707
                 ' for finding table, anchor has to be index when anchor is not '
                 'related to separate locator element')
         except StaleElementReferenceException:
             logger.debug('Staling element..Retrying')
             return None
     try:
         locator_element = text.get_text_using_anchor(locator, anchor)
         table_element = javascript.execute_javascript(
             'return arguments[0].closest("table")', locator_element)
     except (ValueError, NoSuchElementException,
             StaleElementReferenceException):
         return None
     if table_element:
         return table_element
     return None
예제 #3
0
파일: window.py 프로젝트: qentinelqi/qweb
def open_window():
    r"""Open new tab.

    Uses javascript to do this so javascript has to be enabled.

    Examples
    --------
    .. code-block:: robotframework

        OpenWindow

    Related keywords
    ----------------
    \`CloseAllBrowsers\`, \`CloseBrowser\`, \`CloseOthers\`, \`GoTo\`,
    \`OpenBrowser\`, \`SwitchWindow\`
    """
    script = 'window.open()'
    javascript.execute_javascript(script)
    window_handles = window.get_window_handles()
    current_window_handle = window.get_current_window_handle()
    index = window_handles.index(current_window_handle)
    new_window_index = index + 1
    window.switch_to_window(window_handles[new_window_index])
    try:
        xhr.setup_xhr_monitor()
    except QWebDriverError:
        logger.debug('XHR monitor threw exception. Bypassing jQuery injection')
예제 #4
0
def checkbox_set(checkbox_element, locator_element, value, **kwargs):  # pylint: disable=unused-argument
    if checkbox.is_checked(checkbox_element) != value:
        try:
            checkbox_element.click()
        except WebDriverException:
            if locator_element:
                locator_element.click()
            else:
                javascript.execute_javascript(
                    "arguments[0].checked={}".format(
                        "true" if value else "false"), checkbox_element)
예제 #5
0
def _get_coordinates(web_element):
    x_diff = javascript.execute_javascript(
        'return window.outerWidth-window.innerWidth+screen.availLeft')
    y_diff = javascript.execute_javascript(
        'return window.outerHeight-window.innerHeight+screen.availTop')
    elem = javascript.execute_javascript(
        "return arguments[0].getBoundingClientRect()", web_element)
    logger.debug("coords: {0}".format(elem))
    y = elem['y']

    x_coord = web_element.location['x'] + x_diff + web_element.size['width'] / 2
    y_coord = y + y_diff + web_element.size['height'] / 2
    return x_coord, y_coord
예제 #6
0
파일: actions.py 프로젝트: qentinelqi/qweb
def scroll_dynamic_web_page(text_to_find, scroll_length, slow_mode, timeout):
    visible = None
    js_browser_height = "return window.innerHeight"
    height = javascript.execute_javascript(js_browser_height)  # Length of one scroll
    js_current_pos = "return window.pageYOffset;"
    js_scroll = 'window.scrollBy(0,{})'.format(scroll_length or height)
    current_pos = javascript.execute_javascript(js_current_pos)
    old_pos = None
    start = time.time()
    if not slow_mode:
        while not visible and old_pos != current_pos and time.time() < timeout + start:
            old_pos = javascript.execute_javascript(js_current_pos)
            javascript.execute_javascript(js_scroll)
            time.sleep(.5)
            current_pos = javascript.execute_javascript(js_current_pos)
            visible = internal_text.get_element_by_locator_text(text_to_find,
                                                                allow_non_existent=True)
            logger.info('\nOld pos: {}\nCurrent pos: {}\nVisible: {}'
                        .format(old_pos, current_pos, visible), also_console=True)
    else:
        logger.info('\nSlow mode is on, execution will only stop if the text "{}" is found or if '
                    'the timeout is reached.'.format(text_to_find), also_console=True)
        while not visible and time.time() < timeout + start:
            javascript.execute_javascript(js_scroll)
            time.sleep(.5)
            visible = internal_text.get_element_by_locator_text(text_to_find,
                                                                allow_non_existent=True)
            logger.info('\nVisible: {}'.format(visible), also_console=True)

    if visible:
        return True
    raise QWebTextNotFoundError('Could not find text "{}" after scrolling for {} pixels.'
                                .format(text_to_find, current_pos))
예제 #7
0
def execute_javascript(script, variable_name=None):
    """Execute javascript and save the result to suite variable.

    Examples
    --------
    .. code-block:: robotframework

        ExecuteJavascript   document.getElementsByTagName("p")[0].innerText="Write text";
        ExecuteJavascript   return document.title;     $TITLE

    Parameters
    ----------
    script : str
        Javascript code.
    variable_name : str
        Robot framework variable name without {}. (Default None)
    """
    output = javascript.execute_javascript(script)
    logger.info('Output of execution:\n{}'.format(output))
    if variable_name:
        try:
            BuiltIn().set_suite_variable(variable_name, output)
        except Exception as e:
            logger.warn(e.__str__())
            raise QWebValueError("Invalid variable syntax '{}'.".format(variable_name))
예제 #8
0
def use_frame(locator):
    """Make following keywords to use frame on a page.

    Examples
    --------
    .. code-block:: robotframework

        UseFrame    //iframe

    Parameters
    ----------
    locator : str
        Xpath expression without xpath= prefix or index (first = 1 etc.)

    Raises
    ------
    NoSuchFrameException
        If the frame is not found
    """
    frame.wait_page_loaded()
    try:
        index = int(locator) - 1
        webelement = javascript.execute_javascript(
            'document.querySelectorAll("iframe, frame")[{}]'.format(index))
    except ValueError:
        webelement = element.get_unique_element_by_xpath(locator)
    driver = browser.get_current_browser()
    try:
        driver.switch_to_frame(webelement)
    except NoSuchFrameException:
        raise NoSuchFrameException('No frame wound with xpath: {0}'.format(locator))
예제 #9
0
def setup_xhr_monitor():
    """Inject jQuery if needed and check if page is ready.

    Setup_xhr_monitor injects jQuery to page if there isn't one
    already.

    """
    try:
        js = """
        function inject(){
            if (typeof(jQuery) === "undefined"){
               var head = document.querySelector('head');
               var script = document.createElement('script');
               script.type = "text/javascript";
               script.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"
               head.appendChild(script);
               if (typeof(jQuery) === "undefined"){
                    return false;
               }
            }
            return true;
        }
        return inject()"""

        return javascript.execute_javascript(js)

    except (WebDriverException, JavascriptException) as e:
        raise QWebDriverError(e)  # pylint: disable=W0707
예제 #10
0
def get_element_to_click_from_list(active_list, index, **kwargs):
    if 'tag' in kwargs:
        element = javascript.execute_javascript(
            'return arguments[0].querySelector("{}")'.format(kwargs['tag']), active_list[index])
    else:
        element = active_list[index]
    return element
예제 #11
0
def scroll_first_scrollable_parent_element(locator, anchor, text_to_find,
                                           scroll_length, slow_mode, timeout):
    visible = None
    js_get_parent_element = """
        function getScrollParent(node) {
          if (node == null) {
            return null;
          }

          if (node.scrollHeight > node.clientHeight) {
            return node;
          } else {
            return getScrollParent(node.parentNode);
          }
        }
        return getScrollParent(arguments[0]);
    """
    js_element_position = "return arguments[0].scrollTop;"
    js_element_scroll = "arguments[0].scrollBy(0, {})".format(scroll_length
                                                              or '1000')
    web_element = internal_text.get_element_by_locator_text(locator, anchor)
    scrollable_element = javascript.execute_javascript(js_get_parent_element,
                                                       web_element)
    current_pos = javascript.execute_javascript(js_element_position,
                                                scrollable_element)
    old_pos = None
    start = time.time()
    if not slow_mode:
        while not visible and old_pos != current_pos and time.time(
        ) < timeout + start:
            old_pos = javascript.execute_javascript(js_element_position,
                                                    scrollable_element)
            javascript.execute_javascript(js_element_scroll,
                                          scrollable_element)
            time.sleep(.5)
            current_pos = javascript.execute_javascript(
                js_element_position, scrollable_element)
            visible = internal_text.get_element_by_locator_text(
                text_to_find, allow_non_existent=True)
            logger.info('Old pos: {}\nNew pos: {}\nVisible: {}'.format(
                old_pos, current_pos, visible),
                        also_console=True)
    else:
        logger.info(
            '\nSlow mode is on, execution will only stop if the text "{}" is found or if '
            'the timeout is reached.'.format(text_to_find),
            also_console=True)
        while not visible and time.time() < timeout + start:
            javascript.execute_javascript(js_element_scroll,
                                          scrollable_element)
            time.sleep(.5)
            visible = internal_text.get_element_by_locator_text(
                text_to_find, allow_non_existent=True)
            logger.info('\nVisible: {}'.format(visible), also_console=True)
    if visible:
        return
    raise QWebTextNotFoundError('Text {} not found.'.format(text_to_find))
예제 #12
0
def find_text(text):
    try:
        if javascript.execute_javascript(
                "return window.find('{}')".format(text.replace("\'", "\\'"))):
            return True
    except WebDriverException as e:
        logger.debug('Got webdriver exception from find text func: {}'.format(e))
    raise QWebElementNotFoundError('Text not found')
예제 #13
0
 def get_table_by_locator_table(locator, parent, child, level, index):
     if parent:
         script = ".parentElement.closest('table')" * int(level)
         parent_table = javascript.execute_javascript(
             "return arguments[0]{}".format(script), locator)
         if parent_table:
             if not child:
                 return parent_table
             locator = parent_table
         else:
             raise QWebElementNotFoundError('No parent table found')
     if child:
         script = ".querySelectorAll('table')[{}]".format(int(index) - 1)
         child_table = javascript.execute_javascript(
             "return arguments[0]{}".format(script), locator)
         if child_table:
             return child_table
         raise QWebElementNotFoundError('No child table found')
     raise QWebElementNotFoundError('Sub/parent table not found')
예제 #14
0
 def get_cell_by_locator(self, locator):
     rows = self.get_all_rows()
     for i, r in enumerate(rows):  # pylint: disable=unused-variable
         cells = self.get_cells_from_row(r)
         for index, c in enumerate(cells):
             cell_text = ""
             if c.text:
                 cell_text += c.text
             elif javascript.execute_javascript(
                     'return arguments[0].querySelector("input, textarea")',
                     c):
                 value = javascript.execute_javascript(
                     'return arguments[0].value', c)
                 if value:
                     cell_text += str(value)
             if locator in cell_text:
                 return index + 1
     raise QWebValueError(
         'Matching table cell not found for locator {}.'.format(locator))
예제 #15
0
 def write(self, input_element, input_text, **kwargs):
     """ Writes the given text using configured writer. """
     write = self._get_writer()
     # By clearing the input field with Javascript,
     # we avoid triggering focus events right after
     # clear and trigger them only on send_keys call.
     clear_key = self.check_key(kwargs.get('clear_key', self.clear_key))
     if not clear_key:
         if self.is_editable_text_element(input_element):
             javascript.execute_javascript('arguments[0].innerText=""', input_element)
         else:
             javascript.execute_javascript("arguments[0].value = \"\"", input_element)
     else:
         input_element.send_keys(clear_key)
     write(input_element, input_text)
     if 'check' not in kwargs:
         line_break = kwargs.get('key', self.check_key(self.line_break_key))
         if line_break:
             input_element.send_keys(line_break)
예제 #16
0
 def get_using_text_in_coordinates(self, coordinates, anchor):
     row_elem = None
     cell = None
     locator = coordinates.split('/')
     if locator[0].startswith('r?'):
         row_elem = self.get_row(locator[0][2:], anchor)
     else:
         row, _ = self._convert_coordinates(locator[0])
     if locator[1].startswith('c?'):
         column = self.get_cell_by_locator(locator[1][2:])
     else:
         _, column = self._convert_coordinates(locator[1])
     if row_elem:
         cell = javascript.execute_javascript(
             'return arguments[0].cells[{}]'.format(column - 1), row_elem)
     else:
         cell = javascript.execute_javascript(
             'return arguments[0].rows[{}].cells[{}]'.format(
                 row - 1, column - 1), self.table)
     return cell
예제 #17
0
파일: dropdown.py 프로젝트: qentinelqi/qweb
def get_dropdown_element_by_css_selector(locator, anchor, index, **kwargs):
    """Get Dropdown element using css selectors.
       Parameters
       ----------
       locator : str
           Label text or attribute that points to the dropdown.
           Looking for placeholder and commonly used tooltip-attributes first.
           If locator is label text, finds input element by it's for attribute.
           if for attribute is not available, then finds element by doing some
           DOM traversing.
       anchor : str
           Using if locator is not an XPath.
       index : int
           If multiple elements use index to pick correct one.
       Returns
       -------
       WebElement
   """
    dropdown_elements = []
    partial_matches = []
    css = 'select'
    if 'qweb_old' not in kwargs:
        full_matches, partial_matches = element.get_elements_by_css(
            locator, css, **kwargs)
        if full_matches:
            if index != 0:
                try:
                    return full_matches[index]
                except IndexError as e:
                    raise QWebInstanceDoesNotExistError(
                        f'Found {len(full_matches)} elements. Given index was {index}'
                    ) from e
            correct_element = text.get_element_using_anchor(
                full_matches, anchor)
            return correct_element
    try:
        locator_element = text.get_text_using_anchor(locator, anchor)
        # if this is option, return parent select immediately
        if locator_element.tag_name.lower() == "option":
            return javascript.execute_javascript(
                "return arguments[0].parentNode;", locator_element)
        dropdown_elements = list(
            dict.fromkeys(
                element.get_element_from_childnodes(locator_element, css, **
                                                    kwargs) + partial_matches))
    except QWebElementNotFoundError:
        logger.trace(
            'Element not found by visible text. Trying with partial match')
        dropdown_elements = partial_matches
    if dropdown_elements:
        return dropdown_elements[index]
    return None
예제 #18
0
파일: lists.py 프로젝트: qentinelqi/qweb
    def get_elements_by_locator_xpath_and_tag_name(locator, index=1, **kwargs):
        index = int(index) - 1
        if 'tag' in kwargs:
            tag_name = kwargs.get('tag')
        elif 'parent' in kwargs and kwargs['parent']:
            tag_name = kwargs['parent']
        elif 'child' in kwargs and kwargs['child']:
            tag_name = kwargs['child']
        else:
            tag_name = 'ul'
        if 'parent' in kwargs and kwargs['parent']:
            web_element = element.get_unique_element_by_xpath(locator)
            css = kwargs.get('parent')
            web_element = element.get_parent_list_element(web_element, css)
            if tag_name not in ["ul", "ol", "dl", "UL", "OL", "DL"]:
                web_element = javascript.execute_javascript(
                    'return arguments[0].querySelectorAll("{}")'.format(
                        tag_name), web_element)
            else:
                web_element = javascript.execute_javascript(
                    'return arguments[0].closest("{}").querySelectorAll("li, dt, dd")'
                    .format(tag_name), web_element)
        elif 'child' in kwargs and kwargs['child']:
            web_element = element.get_unique_element_by_xpath(locator)
            css = kwargs.get('child')
            web_element = element.get_element_from_childnodes(
                web_element, css, dom_traversing=False)[index]
            if tag_name not in ["ul", "ol", "dl", "UL", "OL", "DL"]:
                web_element = javascript.execute_javascript(
                    'return arguments[0].querySelectorAll("{}")'.format(
                        tag_name), web_element)
            else:
                web_element = javascript.execute_javascript(
                    'return arguments[0].closest("{}").querySelectorAll("li, dt, dd")'
                    .format(tag_name), web_element)
        else:
            web_element = element.get_webelements_in_active_area(locator)

        return web_element
예제 #19
0
파일: lists.py 프로젝트: qentinelqi/qweb
    def get_elements_by_locator_text_and_tag_name(locator,
                                                  anchor,
                                                  index=1,
                                                  **kwargs):
        index = int(index) - 1
        if 'tag' in kwargs:
            tag_name = kwargs.get('tag')
        elif 'parent' in kwargs and kwargs['parent']:
            tag_name = kwargs['parent']
        elif 'child' in kwargs and kwargs['child']:
            tag_name = kwargs['child']
        else:
            tag_name = 'ul'

        web_element = text.get_element_by_locator_text(locator, anchor)
        if 'parent' in kwargs and kwargs['parent']:
            tag = kwargs['parent']
            locator_element = element.get_parent_list_element(web_element, tag)
        elif 'child' in kwargs and kwargs['child']:
            tag = kwargs['child']
            locator_element = element.get_element_from_childnodes(
                web_element, tag, dom_traversing=False)[index]
            if tag_name not in ["ul", "ol", "dl", "UL", "OL", "DL"]:
                return locator_element
        else:
            locator_element = text.get_element_by_locator_text(locator, anchor)

        if tag_name not in ["ul", "ol", "dl", "UL", "OL", "DL"]:
            web_elements = javascript.execute_javascript(
                'return arguments[0].querySelectorAll("{}")'.format(tag_name),
                locator_element)
        else:
            web_elements = javascript.execute_javascript(
                'return arguments[0].closest("{}").querySelectorAll("li, dt, dd")'
                .format(tag_name), locator_element)
        return web_elements
예제 #20
0
파일: dragdrop.py 프로젝트: qentinelqi/qweb
def get_draggable_element(text, index, anchor):
    attribute_match = '[title^="{0}"][draggable="true"],[alt^="{0}"][draggable="true"],' \
                      '[tooltip^="{0}"][draggable="true"],' \
                      '[data-tooltip^="{0}"][draggable="true"],' \
                      '[data-icon^="{0}"][draggable="true"],' \
                      '[aria-label^="{0}"][draggable="true"],' \
                      '[title^="{0}"][class*="draggableCell"]'.format(text)
    web_elements = []
    matches = []
    if text.startswith('xpath=') or text.startswith('//'):
        web_element = element.get_unique_element_by_xpath(text)
        if web_element:
            return web_element
        raise QWebElementNotFoundError('Draggable element not found by locator {}'.format(text))
    try:
        index = int(index) - 1
    except ValueError as e:
        raise QWebValueError('Index needs to be number') from e
    web_elements = javascript.execute_javascript(
        'return document.querySelectorAll(\'{}\')'.format(attribute_match))
    if web_elements:
        return web_elements[index]
    web_elements = javascript.execute_javascript(
        'return document.querySelectorAll(\'[draggable="true"]\')')
    if web_elements:
        matches = _find_matches(web_elements, text)
        if matches:
            return matches[index]
        if text == 'index':
            logger.warn('Text is not matching to any draggable element. Found {} '
                        'draggable elements. Using index..'.format(len(web_elements)))
            return web_elements[index]
        web_elements = get_text_using_anchor(text, anchor)
        if web_elements:
            return web_elements
    raise QWebElementNotFoundError('Draggable element not found by locator {}'.format(text))
예제 #21
0
def is_visible(element):
    """Is the element interactable?

    Uses the display attribute to determine if form element is visible or
    not.

    Parameters
    ----------
    element : WebElement

    Returns
    -------
    bool
    """
    visibility = javascript.execute_javascript('return arguments[0].style.display', element)
    return bool(visibility.lower() != 'none')
예제 #22
0
def is_readonly(element):
    """Is the element interactable?

    Uses the readonly attribute to determine if form element is enabled or
    not.

    Parameters
    ----------
    element : WebElement

    Returns
    -------
    bool
    """
    return util.par2bool(javascript.execute_javascript(
        'return arguments[0].hasAttribute("readonly")', element))
예제 #23
0
def check_frames(driver, **kwargs):
    visible_frames = []
    frames = javascript.execute_javascript(
        'return document.querySelectorAll("iframe, frame")')
    frames += driver.find_elements_by_xpath("//iframe|//frame")
    visible_only = kwargs.get('visibility', True)
    if not visible_only:
        return frames
    frames_obj = javascript.get_visibility(list(dict.fromkeys(frames)))
    for frame in frames_obj:
        offset = frame.get('offset')
        if offset:
            visible_frames.append(frame.get('elem'))
    if visible_frames:
        logger.debug('Found {} visible frames'.format(len(visible_frames)))
    return visible_frames
예제 #24
0
    def get_texts(self, locator):
        """Return texts that are containing locator.

    Examples
    --------
    .. code-block:: robotframework

        GetTexts          ITEM-

    Parameters
    ----------
    locator : str
       Text that we are searching for

    Returns
    -------
    list : List of found texts
        """
        js = """var web_elements = function(locator){
                    var matches = [];
                    var text = "";
                    var elems = document.querySelectorAll('button, a');
                    for (var i = 0; i < elems.length; i++) {
                        if(elems[i].tagName.toLowerCase() === 'input'){
                            text = elems[i].value;
                        }
                        else {
                            text = elems[i].innerText;
                        }
                        if (text.trim().includes(locator)){
                            matches.push(elems[i]);
                        }
                    }
                    return matches;
                }
                return(web_elements('""" + locator.replace("\'",
                                                           "\\'") + """'));"""
        text_elements = javascript.execute_javascript(js)
        texts = list()
        for e in text_elements:
            texts.append(e.text)
            self.QWeb.verify_text(e.text)
        logger.debug('Found texts: {}'.format(texts))
        return texts
예제 #25
0
 def _convert_coordinates(self, coordinate_str):
     """Return row and column from coordinate string."""
     try:
         row = int(re.findall('r([+-]?[0-9]+)', coordinate_str)[0])
         if row < 0:
             row = int(self.get_row('//last', self.anchor)) + (row + 1)
     except IndexError:
         row = None
     try:
         col = int(re.findall('c([+-]?[0-9]+)', coordinate_str)[0])
         if col < 0:
             row_index = row - 1
             col = int(
                 javascript.execute_javascript(
                     ' return arguments[0].rows[{0}].cells.length'.format(
                         row_index), self.table)) + (col + 1)
     except IndexError:
         col = None
     return row, col
예제 #26
0
파일: checkbox.py 프로젝트: qentinelqi/qweb
def is_checked(checkbox_element):
    """Is checkbox checked.

    Parameters
    ----------
    checkbox_element : WebElement

    Returns
    -------
    bool
    """
    js = """
        var checked = function(el) {
            if (el.hasAttribute("aria-checked")) {
                return el.attributes["aria-checked"].value;
                console.log(el.attributes["aria-checked"].value);
            }
            return el.checked;
        }
        return checked(arguments[0]);
        """
    checked = util.par2bool(javascript.execute_javascript(
        js, checkbox_element))
    return bool(checked)
예제 #27
0
 def is_editable_text_element(input_element):
     if javascript.execute_javascript(
             'return arguments[0].getAttribute("contenteditable") == "true"',
             input_element):
         return True
     return False
예제 #28
0
def get_parent_element(web_element, tag):
    web_element = javascript.execute_javascript(
        'return arguments[0].closest(\'{}\')'.format(tag), web_element)
    if web_element:
        return web_element
    raise QWebElementNotFoundError('Parent with tag {} not found.'.format(tag))
예제 #29
0
def get_jquery_ready():
    jqueries_ready = javascript.execute_javascript(
        'return window.jQuery.active === 0;')
    return jqueries_ready
예제 #30
0
def get_ready_state():
    ready_state = javascript.execute_javascript(
        'return document.readyState === "complete"')
    logger.debug('Readystate = {}'.format(ready_state))
    return ready_state