def get_lines_matching_pattern(self, string, pattern, case_insensitive=False):
        """Returns lines of the given ``string`` that match the ``pattern``.

        The ``pattern`` is a _glob pattern_ where:
        | ``*``        | matches everything |
        | ``?``        | matches any single character |
        | ``[chars]``  | matches any character inside square brackets (e.g. ``[abc]`` matches either ``a``, ``b`` or ``c``) |
        | ``[!chars]`` | matches any character not inside square brackets |

        A line matches only if it matches the ``pattern`` fully.

        The match is case-sensitive by default, but giving ``case_insensitive``
        a true value makes it case-insensitive. The value is considered true
        if it is a non-empty string that is not equal to ``false`` or ``no``.
        If the value is not a string, its truth value is got directly in Python.

        Lines are returned as one string catenated back together with
        newlines. Possible trailing newline is never returned. The
        number of matching lines is automatically logged.

        Examples:
        | ${lines} = | Get Lines Matching Pattern | ${result} | Wild???? example |
        | ${ret} = | Get Lines Matching Pattern | ${ret} | FAIL: * | case_insensitive=true |

        See `Get Lines Matching Regexp` if you need more complex
        patterns and `Get Lines Containing String` if searching
        literal strings is enough.
        """
        if is_truthy(case_insensitive):
            pattern = pattern.lower()
            matches = lambda line: fnmatchcase(line.lower(), pattern)
        else:
            matches = lambda line: fnmatchcase(line, pattern)
        return self._get_matching_lines(string, matches)
def get_value_from_user(message, default_value='', hidden=False):
    """Pauses test execution and asks user to input a value.

    Value typed by the user, or the possible default value, is returned.
    Returning an empty value is fine, but pressing ``Cancel`` fails the keyword.

    ``message`` is the instruction shown in the dialog and ``default_value`` is
    the possible default value shown in the input field.

    If ``hidden`` is given a true value, the value typed by the user is hidden.
    ``hidden`` is considered true if it is a non-empty string not equal to
    ``false`` or ``no``, case-insensitively. If it is not a string, its truth
    value is got directly using same
    [http://docs.python.org/2/library/stdtypes.html#truth-value-testing|rules
    as in Python].

    Example:
    | ${username} = | Get Value From User | Input user name | default    |
    | ${password} = | Get Value From User | Input password  | hidden=yes |

    Possibility to hide the typed in value is new in Robot Framework 2.8.4.
    Considering strings ``false`` and ``no`` to be false is new in 2.9.
    """
    return _validate_user_input(
        InputDialog(message, default_value, is_truthy(hidden)))
    def get_lines_containing_string(self, string, pattern, case_insensitive=False):
        """Returns lines of the given ``string`` that contain the ``pattern``.

        The ``pattern`` is always considered to be a normal string, not a glob
        or regexp pattern. A line matches if the ``pattern`` is found anywhere
        on it.

        The match is case-sensitive by default, but giving ``case_insensitive``
        a true value makes it case-insensitive. The value is considered true
        if it is a non-empty string that is not equal to ``false`` or ``no``.
        If the value is not a string, its truth value is got directly in Python.

        Lines are returned as one string catenated back together with
        newlines. Possible trailing newline is never returned. The
        number of matching lines is automatically logged.

        Examples:
        | ${lines} = | Get Lines Containing String | ${result} | An example |
        | ${ret} =   | Get Lines Containing String | ${ret} | FAIL | case-insensitive |

        See `Get Lines Matching Pattern` and `Get Lines Matching Regexp`
        if you need more complex pattern matching.
        """
        if is_truthy(case_insensitive):
            pattern = pattern.lower()
            contains = lambda line: pattern in line.lower()
        else:
            contains = lambda line: pattern in line
        return self._get_matching_lines(string, contains)
Example #4
0
def _get_matches_in_iterable(iterable, pattern, case_insensitive=False,
                             whitespace_insensitive=False):
    if not is_string(pattern):
        raise TypeError("Pattern must be string, got '%s'." % type_name(pattern))
    regexp = False
    if pattern.startswith('regexp='):
        pattern = pattern[7:]
        regexp = True
    elif pattern.startswith('glob='):
        pattern = pattern[5:]
    matcher = Matcher(pattern,
                      caseless=is_truthy(case_insensitive),
                      spaceless=is_truthy(whitespace_insensitive),
                      regexp=regexp)
    return [string for string in iterable
            if is_string(string) and matcher.match(string)]
Example #5
0
    def get_lines_containing_string(self, string, pattern, case_insensitive=False):
        """Returns lines of the given ``string`` that contain the ``pattern``.

        The ``pattern`` is always considered to be a normal string, not a glob
        or regexp pattern. A line matches if the ``pattern`` is found anywhere
        on it.

        The match is case-sensitive by default, but giving ``case_insensitive``
        a true value makes it case-insensitive. The value is considered true
        if it is a non-empty string that is not equal to ``false``, ``none`` or
        ``no``. If the value is not a string, its truth value is got directly
        in Python. Considering ``none`` false is new in RF 3.0.3.

        Lines are returned as one string catenated back together with
        newlines. Possible trailing newline is never returned. The
        number of matching lines is automatically logged.

        Examples:
        | ${lines} = | Get Lines Containing String | ${result} | An example |
        | ${ret} =   | Get Lines Containing String | ${ret} | FAIL | case-insensitive |

        See `Get Lines Matching Pattern` and `Get Lines Matching Regexp`
        if you need more complex pattern matching.
        """
        if is_truthy(case_insensitive):
            pattern = pattern.lower()
            contains = lambda line: pattern in line.lower()
        else:
            contains = lambda line: pattern in line
        return self._get_matching_lines(string, contains)
Example #6
0
    def get_lines_matching_pattern(self, string, pattern, case_insensitive=False):
        """Returns lines of the given ``string`` that match the ``pattern``.

        The ``pattern`` is a _glob pattern_ where:
        | ``*``        | matches everything |
        | ``?``        | matches any single character |
        | ``[chars]``  | matches any character inside square brackets (e.g. ``[abc]`` matches either ``a``, ``b`` or ``c``) |
        | ``[!chars]`` | matches any character not inside square brackets |

        A line matches only if it matches the ``pattern`` fully.

        The match is case-sensitive by default, but giving ``case_insensitive``
        a true value makes it case-insensitive. The value is considered true
        if it is a non-empty string that is not equal to ``false``, ``none`` or
        ``no``. If the value is not a string, its truth value is got directly
        in Python. Considering ``none`` false is new in RF 3.0.3.

        Lines are returned as one string catenated back together with
        newlines. Possible trailing newline is never returned. The
        number of matching lines is automatically logged.

        Examples:
        | ${lines} = | Get Lines Matching Pattern | ${result} | Wild???? example |
        | ${ret} = | Get Lines Matching Pattern | ${ret} | FAIL: * | case_insensitive=true |

        See `Get Lines Matching Regexp` if you need more complex
        patterns and `Get Lines Containing String` if searching
        literal strings is enough.
        """
        if is_truthy(case_insensitive):
            pattern = pattern.lower()
            matches = lambda line: fnmatchcase(line.lower(), pattern)
        else:
            matches = lambda line: fnmatchcase(line, pattern)
        return self._get_matching_lines(string, matches)
Example #7
0
def get_value_from_user(message, default_value='', hidden=False):
    """Pauses test execution and asks user to input a value.

    Value typed by the user, or the possible default value, is returned.
    Returning an empty value is fine, but pressing ``Cancel`` fails the keyword.

    ``message`` is the instruction shown in the dialog and ``default_value`` is
    the possible default value shown in the input field.

    If ``hidden`` is given a true value, the value typed by the user is hidden.
    ``hidden`` is considered true if it is a non-empty string not equal to
    ``false`` or ``no``, case-insensitively. If it is not a string, its truth
    value is got directly using same
    [http://docs.python.org/2/library/stdtypes.html#truth-value-testing|rules
    as in Python].

    Example:
    | ${username} = | Get Value From User | Input user name | default    |
    | ${password} = | Get Value From User | Input password  | hidden=yes |

    Possibility to hide the typed in value is new in Robot Framework 2.8.4.
    Considering strings ``false`` and ``no`` to be false is new in 2.9.
    """
    return _validate_user_input(InputDialog(message, default_value,
                                            is_truthy(hidden)))
Example #8
0
 def __init__(self, cwd=None, shell=False, stdout=None, stderr=None,
              alias=None, env=None, **rest):
     self.cwd = self._get_cwd(cwd)
     self.stdout_stream = self._new_stream(stdout)
     self.stderr_stream = self._get_stderr(stderr, stdout, self.stdout_stream)
     self.shell = is_truthy(shell)
     self.alias = alias
     self.env = self._construct_env(env, rest)
Example #9
0
def _verify_condition(condition, default_msg, msg, values=False):
    if condition:
        return
    if not msg:
        msg = default_msg
    elif is_truthy(values) and str(values).upper() != 'NO VALUES':
        msg += '\n' + default_msg
    raise AssertionError(msg)
Example #10
0
def _verify_condition(condition, default_msg, msg, values=False):
    if condition:
        return
    if not msg:
        msg = default_msg
    elif is_truthy(values) and str(values).upper() != 'NO VALUES':
        msg += '\n' + default_msg
    raise AssertionError(msg)
Example #11
0
def _get_matches_in_iterable(iterable,
                             pattern,
                             case_insensitive=False,
                             whitespace_insensitive=False):
    if not is_string(pattern):
        raise TypeError("Pattern must be string, got '%s'." %
                        type_name(pattern))
    regexp = False
    if pattern.startswith('regexp='):
        pattern = pattern[7:]
        regexp = True
    elif pattern.startswith('glob='):
        pattern = pattern[5:]
    matcher = Matcher(pattern,
                      caseless=is_truthy(case_insensitive),
                      spaceless=is_truthy(whitespace_insensitive),
                      regexp=regexp)
    return [
        string for string in iterable
        if is_string(string) and matcher.match(string)
    ]
Example #12
0
    def terminate_process(self, handle=None, kill=False):
        """Stops the process gracefully or forcefully.

        If ``handle`` is not given, uses the current `active process`.

        By default first tries to stop the process gracefully. If the process
        does not stop in 30 seconds, or ``kill`` argument is given a true value,
        (see `Boolean arguments`) kills the process forcefully. Stops also all
        the child processes of the originally started process.

        Waits for the process to stop after terminating it. Returns a `result
        object` containing information about the execution similarly as `Wait
        For Process`.

        On Unix-like machines graceful termination is done using ``TERM (15)``
        signal and killing using ``KILL (9)``. Use `Send Signal To Process`
        instead if you just want to send either of these signals without
        waiting for the process to stop.

        On Windows graceful termination is done using ``CTRL_BREAK_EVENT``
        event and killing using Win32 API function ``TerminateProcess()``.

        Examples:
        | ${result} =                 | Terminate Process |     |
        | Should Be Equal As Integers | ${result.rc}      | -15 | # On Unixes |
        | Terminate Process           | myproc            | kill=true |

        Limitations:
        - Graceful termination is not supported on Windows by Jython nor by
          Python versions prior to 2.7. Process is killed instead.
        - Stopping the whole process group is not supported by Jython at all
          nor by Python versions prior to 2.7 on Windows.
        - On Windows forceful kill only stops the main process, not possible
          child processes.

        Automatically killing the process if termination fails as well as
        returning a result object are new features in Robot Framework 2.8.2.
        Terminating also possible child processes, including using
        ``CTRL_BREAK_EVENT`` on Windows, is new in Robot Framework 2.8.5.
        """
        process = self._processes[handle]
        if not hasattr(process, 'terminate'):
            raise RuntimeError('Terminating processes is not supported '
                               'by this Python version.')
        terminator = self._kill if is_truthy(kill) else self._terminate
        try:
            terminator(process)
        except OSError:
            if not self._process_is_stopped(process, self.KILL_TIMEOUT):
                raise
            logger.debug('Ignored OSError because process was stopped.')
        return self._wait(process)
    def terminate_process(self, handle=None, kill=False):
        """Stops the process gracefully or forcefully.

        If ``handle`` is not given, uses the current `active process`.

        By default first tries to stop the process gracefully. If the process
        does not stop in 30 seconds, or ``kill`` argument is given a true value,
        (see `Boolean arguments`) kills the process forcefully. Stops also all
        the child processes of the originally started process.

        Waits for the process to stop after terminating it. Returns a `result
        object` containing information about the execution similarly as `Wait
        For Process`.

        On Unix-like machines graceful termination is done using ``TERM (15)``
        signal and killing using ``KILL (9)``. Use `Send Signal To Process`
        instead if you just want to send either of these signals without
        waiting for the process to stop.

        On Windows graceful termination is done using ``CTRL_BREAK_EVENT``
        event and killing using Win32 API function ``TerminateProcess()``.

        Examples:
        | ${result} =                 | Terminate Process |     |
        | Should Be Equal As Integers | ${result.rc}      | -15 | # On Unixes |
        | Terminate Process           | myproc            | kill=true |

        Limitations:
        - Graceful termination is not supported on Windows by Jython nor by
          Python versions prior to 2.7. Process is killed instead.
        - Stopping the whole process group is not supported by Jython at all
          nor by Python versions prior to 2.7 on Windows.
        - On Windows forceful kill only stops the main process, not possible
          child processes.

        Automatically killing the process if termination fails as well as
        returning a result object are new features in Robot Framework 2.8.2.
        Terminating also possible child processes, including using
        ``CTRL_BREAK_EVENT`` on Windows, is new in Robot Framework 2.8.5.
        """
        process = self._processes[handle]
        if not hasattr(process, 'terminate'):
            raise RuntimeError('Terminating processes is not supported '
                               'by this Python version.')
        terminator = self._kill if is_truthy(kill) else self._terminate
        try:
            terminator(process)
        except OSError:
            if not self._process_is_stopped(process, self.KILL_TIMEOUT):
                raise
            logger.debug('Ignored OSError because process was stopped.')
        return self._wait(process)
 def __init__(self,
              cwd=None,
              shell=False,
              stdout=None,
              stderr=None,
              alias=None,
              env=None,
              **rest):
     self.cwd = self._get_cwd(cwd)
     self.stdout_stream = self._new_stream(stdout)
     self.stderr_stream = self._get_stderr(stderr, stdout,
                                           self.stdout_stream)
     self.shell = is_truthy(shell)
     self.alias = alias
     self.env = self._construct_env(env, rest)
Example #15
0
    def send_signal_to_process(self, signal, handle=None, group=False):
        """Sends the given ``signal`` to the specified process.

        If ``handle`` is not given, uses the current `active process`.

        Signal can be specified either as an integer as a signal name. In the
        latter case it is possible to give the name both with or without ``SIG``
        prefix, but names are case-sensitive. For example, all the examples
        below send signal ``INT (2)``:

        | Send Signal To Process | 2      |        | # Send to active process |
        | Send Signal To Process | INT    |        |                          |
        | Send Signal To Process | SIGINT | myproc | # Send to named process  |

        This keyword is only supported on Unix-like machines, not on Windows.
        What signals are supported depends on the system. For a list of
        existing signals on your system, see the Unix man pages related to
        signal handling (typically ``man signal`` or ``man 7 signal``).

        By default sends the signal only to the parent process, not to possible
        child processes started by it. Notice that when `running processes in
        shell`, the shell is the parent process and it depends on the system
        does the shell propagate the signal to the actual started process.

        To send the signal to the whole process group, ``group`` argument can
        be set to any true value (see `Boolean arguments`). This is not
        supported by Jython, however.

        New in Robot Framework 2.8.2. Support for ``group`` argument is new
        in Robot Framework 2.8.5.
        """
        if os.sep == '\\':
            raise RuntimeError('This keyword does not work on Windows.')
        process = self._processes[handle]
        signum = self._get_signal_number(signal)
        logger.info('Sending signal %s (%d).' % (signal, signum))
        if is_truthy(group) and hasattr(os, 'killpg'):
            os.killpg(process.pid, signum)
        elif hasattr(process, 'send_signal'):
            process.send_signal(signum)
        else:
            raise RuntimeError('Sending signals is not supported '
                               'by this Python version.')
    def send_signal_to_process(self, signal, handle=None, group=False):
        """Sends the given ``signal`` to the specified process.

        If ``handle`` is not given, uses the current `active process`.

        Signal can be specified either as an integer as a signal name. In the
        latter case it is possible to give the name both with or without ``SIG``
        prefix, but names are case-sensitive. For example, all the examples
        below send signal ``INT (2)``:

        | Send Signal To Process | 2      |        | # Send to active process |
        | Send Signal To Process | INT    |        |                          |
        | Send Signal To Process | SIGINT | myproc | # Send to named process  |

        This keyword is only supported on Unix-like machines, not on Windows.
        What signals are supported depends on the system. For a list of
        existing signals on your system, see the Unix man pages related to
        signal handling (typically ``man signal`` or ``man 7 signal``).

        By default sends the signal only to the parent process, not to possible
        child processes started by it. Notice that when `running processes in
        shell`, the shell is the parent process and it depends on the system
        does the shell propagate the signal to the actual started process.

        To send the signal to the whole process group, ``group`` argument can
        be set to any true value (see `Boolean arguments`). This is not
        supported by Jython, however.

        New in Robot Framework 2.8.2. Support for ``group`` argument is new
        in Robot Framework 2.8.5.
        """
        if os.sep == '\\':
            raise RuntimeError('This keyword does not work on Windows.')
        process = self._processes[handle]
        signum = self._get_signal_number(signal)
        logger.info('Sending signal %s (%d).' % (signal, signum))
        if is_truthy(group) and hasattr(os, 'killpg'):
            os.killpg(process.pid, signum)
        elif hasattr(process, 'send_signal'):
            process.send_signal(signum)
        else:
            raise RuntimeError('Sending signals is not supported '
                               'by this Python version.')
Example #17
0
    def get_lines_matching_regexp(self, string, pattern, partial_match=False):
        """Returns lines of the given ``string`` that match the regexp ``pattern``.

        See `BuiltIn.Should Match Regexp` for more information about
        Python regular expression syntax in general and how to use it
        in Robot Framework test data in particular.

        By default lines match only if they match the pattern fully, but
        partial matching can be enabled by giving the ``partial_match``
        argument a true value. The value is considered true
        if it is a non-empty string that is not equal to ``false``, ``none`` or
        ``no``. If the value is not a string, its truth value is got directly
        in Python. Considering ``none`` false is new in RF 3.0.3.

        If the pattern is empty, it matches only empty lines by default.
        When partial matching is enabled, empty pattern matches all lines.

        Notice that to make the match case-insensitive, you need to prefix
        the pattern with case-insensitive flag ``(?i)``.

        Lines are returned as one string concatenated back together with
        newlines. Possible trailing newline is never returned. The
        number of matching lines is automatically logged.

        Examples:
        | ${lines} = | Get Lines Matching Regexp | ${result} | Reg\\\\w{3} example |
        | ${lines} = | Get Lines Matching Regexp | ${result} | Reg\\\\w{3} example | partial_match=true |
        | ${ret} =   | Get Lines Matching Regexp | ${ret}    | (?i)FAIL: .* |

        See `Get Lines Matching Pattern` and `Get Lines Containing
        String` if you do not need full regular expression powers (and
        complexity).

        ``partial_match`` argument is new in Robot Framework 2.9. In earlier
         versions exact match was always required.
        """
        if not is_truthy(partial_match):
            pattern = '^%s$' % pattern
        return self._get_matching_lines(string, re.compile(pattern).search)
Example #18
0
    def get_lines_matching_regexp(self, string, pattern, partial_match=False):
        """Returns lines of the given ``string`` that match the regexp ``pattern``.

        See `BuiltIn.Should Match Regexp` for more information about
        Python regular expression syntax in general and how to use it
        in Robot Framework test data in particular.

        By default lines match only if they match the pattern fully, but
        partial matching can be enabled by giving the ``partial_match``
        argument a true value. The value is considered true
        if it is a non-empty string that is not equal to ``false``, ``none`` or
        ``no``. If the value is not a string, its truth value is got directly
        in Python. Considering ``none`` false is new in RF 3.0.3.

        If the pattern is empty, it matches only empty lines by default.
        When partial matching is enabled, empty pattern matches all lines.

        Notice that to make the match case-insensitive, you need to prefix
        the pattern with case-insensitive flag ``(?i)``.

        Lines are returned as one string concatenated back together with
        newlines. Possible trailing newline is never returned. The
        number of matching lines is automatically logged.

        Examples:
        | ${lines} = | Get Lines Matching Regexp | ${result} | Reg\\\\w{3} example |
        | ${lines} = | Get Lines Matching Regexp | ${result} | Reg\\\\w{3} example | partial_match=true |
        | ${ret} =   | Get Lines Matching Regexp | ${ret}    | (?i)FAIL: .* |

        See `Get Lines Matching Pattern` and `Get Lines Containing
        String` if you do not need full regular expression powers (and
        complexity).

        ``partial_match`` argument is new in Robot Framework 2.9. In earlier
         versions exact match was always required.
        """
        if not is_truthy(partial_match):
            pattern = '^%s$' % pattern
        return self._get_matching_lines(string, re.compile(pattern).search)
Example #19
0
 def _get_result_attributes(self, result, *includes):
     attributes = (result.rc, result.stdout, result.stderr,
                   result.stdout_path, result.stderr_path)
     includes = (is_truthy(incl) for incl in includes)
     return tuple(attr for attr, incl in zip(attributes, includes) if incl)
 def _get_result_attributes(self, result, *includes):
     attributes = (result.rc, result.stdout, result.stderr,
                   result.stdout_path, result.stderr_path)
     includes = (is_truthy(incl) for incl in includes)
     return tuple(attr for attr, incl in zip(attributes, includes) if incl)