def __init__( self: "SeleniumTestability", ctx: SeleniumLibrary, automatic_wait: bool = True, timeout: str = "30 seconds", error_on_timeout: bool = True, automatic_injection: bool = True, ) -> None: LibraryComponent.__init__(self, ctx) self.logger = get_logger("SeleniumTestability") self.logger.debug("__init__({},{},{},{},{})".format(ctx, automatic_wait, timeout, error_on_timeout, automatic_injection)) self.el = ElementKeywords(ctx) self.CWD = abspath(dirname(__file__)) self.js_bundle = join(self.CWD, "js", "testability.js") self.ctx.event_firing_webdriver = TestabilityListener self.ctx.testability_settings = {"testability": self} self.automatic_wait = is_truthy(automatic_wait) self.automatic_injection = is_truthy(automatic_injection) self.error_on_timeout = is_truthy(error_on_timeout) self.timeout = timeout # type: ignore self.hidden_elements = {} # type: Dict[str, str] self.browser_warn_shown = False self.empty_log_warn_shown = False self.ff_log_pos = {} # type: Dict[str, int] self.testability_config = None # type: OptionalDictType
def test_is_truthy_and_is_falsy(self): for item in [True, 1, [False], unittest.TestCase, 'foo', 'True']: assert_true(is_truthy(item) is True) assert_true(is_falsy(item) is False) for item in [False, 0, [], None, 'False', 'FALSE', 'No', 'nO', '']: assert_true(is_truthy(item) is False) assert_true(is_falsy(item) is True)
def get_groups(self, recursive=True, path=None, group=None, **kwargs): """Return a list of groups in the open KeePass database matching the given arguments The ``recursive`` argument can be set ``True`` this enables recursive searching, default value is False.\n The ``path`` argument sets the path which the groups should match, default value is None.\n The ``group`` argument has to match an existing Group is supplied only entries which are a direct child will be searched, default value is None. See ``Get Groups`` for information about selecting a group \n See the `Entries and Groups` section for more information about Entries and Groups.\n *Additional arguments:* - The ``history`` argument can be set to ``True`` to include history groups in the search, default value is False. - The ``first`` argument can be set ``True`` this has the effect that only the first match will be returned, default value is False. - The ``regex`` argument can be set to ``True`` this enables regular expression searching, default value is False. - The ``flags`` argument can be set to modify the regular expression search, default value is None. See the `Regular expression` section for more information about about the ``regex`` and ``flags`` syntax. - The ``name`` argument can be given to search matching names, default value is None. - The ``notes`` argument sets the notes which the groups should match, default value is None. - The ``uuid`` argument sets the uuid which the groups should match, default value is None. Example: | @{groups}= | `Get Groups` | name=.*group | notes=^.{0}$ | regex=True | | ${groups}= | `Get Groups` | name=.*group | notes=^.{0}$ | regex=True | first=True | | ${group}= | `Get Groups By Name` | subgroup | first=True | | @{groups}= | `Get Groups` | subgroup2 | group=${group} | """ if self.database is None: raise DatabaseNotLoaded('No KeePass Database loaded.') else: if 'regex' in kwargs: kwargs['regex'] = is_truthy(kwargs['regex']) if 'first' in kwargs: kwargs['first'] = is_truthy(kwargs['first']) return self.database.find_groups(recursive, path, group, **kwargs)
def __init__(self, parameters: DotDict, data_handler, *user_args, **user_options): self._sudo_expected = is_truthy(user_options.pop('sudo', False)) self._sudo_password_expected = is_truthy( user_options.pop('sudo_password', False)) super().__init__(parameters, data_handler, *user_args, **user_options) self._execution_counter = 0 self._ssh = SSHLibrary()
def test_is_truthy_falsy(self): for item in [True, 1, [False], unittest.TestCase, 'truE', 'fOo']: for item in self._strings_also_in_different_cases(item): assert_true(is_truthy(item) is True) assert_true(is_falsy(item) is False) for item in [False, 0, [], None, '', 'faLse', 'nO', 'nOne']: for item in self._strings_also_in_different_cases(item): assert_true(is_truthy(item) is False) assert_true(is_falsy(item) is True)
def _run_process(self, command, *arguments, **configuration): expected_rc = int(configuration.pop('expected_rc', 0)) token = configuration.pop('token', 'process') merged_output = is_truthy(configuration.pop('merged_output', True)) input = configuration.pop('input', None) if input and not isinstance(input, bytes): input = input.encode() tty = is_truthy(configuration.pop('tty', False)) redirection = configuration.pop('redirection', None) # For compatibility with Process.run_process() timeout = configuration.pop('timeout', None) on_timeout = configuration.pop('on_timeout', 'terminate') if redirection and not tty: raise ValueError('Cannot use "redirection" without "tty"') with ExitStack() as stack: if merged_output: stdout = stack.enter_context(_Attachment(token + '-output.txt')).path stderr = 'STDOUT' else: stdout = stack.enter_context(_Attachment(token + '-stdout.txt')).path stderr = stack.enter_context(_Attachment(token + '-stderr.txt')).path if tty: joined = shlex.join((command, ) + arguments) if redirection: joined += ' ' + redirection command = 'script' arguments = list() arguments += ['--return'] arguments += ['--quiet'] arguments += ['--echo', 'never', '--log-out', '/dev/null'] arguments += ['--command', joined] process = Process() handle = process.start_process(command, *arguments, **configuration, stdout=str(stdout), stderr=str(stderr)) if input: process_object = process.get_process_object(handle) process_object.stdin.write(input) process_object.stdin.close() result = process.wait_for_process(handle, timeout, on_timeout) if result.rc != expected_rc: raise AssertionError( 'Process exited with unexpected code {}'.format(result.rc)) return result
def stop_gif_recording(self): self._stop_thread() if is_truthy(self.embed): self._embed_screenshot(self.path, self.embed_width) if is_truthy(self.optimize): frames = [] for frame in ImageSequence.Iterator(Image.open(self.path)): frame = frame.copy() frames.append(frame) frames[0].save(self.path, save_all=True, append_images=frames[1:], optimize=True) return self.path
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)]
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)
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``, ``none`` 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 RF 2.9 and considering string ``none`` false is new in RF 3.0.3. """ return _validate_user_input( InputDialog(message, default_value, is_truthy(hidden)))
def __init__(self, screenshot_module, screenshot_directory, fps, display_cursor): Client.__init__(self) self.screenshot_module = screenshot_module self._given_screenshot_dir = _norm_path(screenshot_directory) self.display_cursor = is_truthy(display_cursor) self._stop_condition = threading.Event() self.alias = None try: if not fps: with suppress_stderr(): if is_pygtk(self.screenshot_module): width, height = _take_gtk_screen_size(monitor=1) self.fps = benchmark_recording_performance_gtk( width, height, 1, monitor=1) else: with mss() as sct: width = int(sct.grab(sct.monitors[1]).width) height = int(sct.grab(sct.monitors[1]).height) self.fps = self.benchmark_recording_performance( width, height, 1, monitor=1) else: self.fps = int(fps) except ValueError: raise ValueError('The fps argument must be of type integer.')
def _verify_string_value(self, expected, actual, case_sensitive=True): # pylint: disable=no-self-use case_sensitive = is_truthy(case_sensitive) expected_value = expected if case_sensitive else expected.upper() actual_value = actual if case_sensitive else actual.upper() if expected_value != actual_value: raise AssertionError("Expected value {}, but found {}".format( expected, actual))
def drag_and_drop(self: "SeleniumTestability", locator: LocatorType, target: LocatorType, html5: bool = False) -> None: """Drags element identified by ``locator`` into ``target`` element. The ``locator`` argument is the locator of the dragged element and the ``target`` is the locator of the target. See the `Locating elements` section for details about the locator syntax. ``html5`` parameter is optional and if provided, `drag_and_drop`will utilize javascript to trigger the suitable events ensuring that html5 applications receive the right events Example: | `Drag And Drop` | css:div#element | css:div.target | True | """ html5 = is_truthy(html5) if not html5: self.el.drag_and_drop(locator, target) else: from_element = self.el.find_element(locator) to_element = self.el.find_element(target) self.ctx.driver.execute_script(JS_LOOKUP["dragdrop"], from_element, to_element)
def take_partial_screenshot(self, name, format, quality, left, top, width, height, embed, embed_width, monitor, save_to_disk): left = int(left) top = int(top) width = int(width) height = int(height) format = (format or self._format).lower() quality = quality or self._quality if is_pygtk(self.screenshot_module): format = 'jpeg' if format == 'jpg' else format if format == 'png': quality = _compression_value_conversion(quality) path = self._save_screenshot_path(name, format) path = _take_partial_gtk_screenshot(path, format, quality, left, top, width, height, monitor) else: try: original_image = self._take_screenshot_client(name, format, quality, monitor) image = Image.open(original_image) right = left + width bottom = top + height box = (left, top, right, bottom) cropped_image = image.crop(box) os.remove(original_image) path = self._save_screenshot_path(basename=name, format=format) cropped_image.save(path, format) except IOError: raise IOError('File not found.') except RuntimeError: raise RuntimeError('Taking screenshot failed.') except SystemError: raise SystemError("Top and left parameters must be lower than screen resolution.") if is_truthy(embed): self._embed_screenshot(path, embed_width, save_to_disk) return path
def wait_for_testability_ready( self: "SeleniumTestability", timeout: OptionalStrType = None, error_on_timeout: OptionalBoolType = None ) -> None: """ Explicitly waits until testability is ready or timeout happens. Parameters: - ``timeout`` Amount of time to wait until giving up for testability to be ready. Robot framework timestring - ``error_on_timeout`` if timeout occurs, should we throw an error Both parameters are optional, if not provided, default values from plugin initialization time are used. """ local_timeout = self.timeout if timeout is not None: local_timeout = timestr_to_secs(timeout) local_error_on_timeout = self.error_on_timeout if error_on_timeout is not None: local_error_on_timeout = is_truthy(error_on_timeout) try: WebDriverWait(self.ctx.driver, local_timeout, 0.15, ignored_exceptions=[TimeoutException]).until( lambda x: self.ctx.driver.execute_async_script(JS_LOOKUP["wait_for_testability"]) ) except TimeoutException: if local_error_on_timeout: raise TimeoutException("Timed out waiting for testability ready callback to trigger.") except Exception as e: self.warn(e)
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_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)
def add_port(self, port_locator, open=True, make_current=False, **kwargs): """ Adds new port with specified locator. port_locator may be in (traditional) port name or url format. If `open` has false value, the port is closed immediately. Parameters given in kwargs will override those library defaults initialized on import. If make_current has truth value, the opened port is set to current port. Note that if there's only one port in the library instance, it will always be current port, regardless of make_current's value. Fails if specified port_locator is already used in this library instance. Returns created port instance. """ if port_locator in [None, '', '_']: asserts.fail('Invalid port locator.') elif port_locator in self._ports: asserts.fail('Port already exists.') serial_kw = dict( (k, type(v)(kwargs.get(k, v))) for k, v in self._defaults.items()) # try url first, then port name try: port = serial_for_url(port_locator, **serial_kw) except (AttributeError, ValueError): port = Serial(port_locator, **serial_kw) asserts.assert_not_none(port, 'Port initialization failed.') self._ports[port_locator] = port if port.is_open and (is_truthy(open) is False): port.close() if self._current_port_locator is None or make_current: self._current_port_locator = port_locator return port
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)
def test_falsy_values(self): class AlwaysFalse(object): __bool__ = __nonzero__ = lambda self: False falsy_strings = ['', 'faLse', 'nO', 'nOne', 'oFF', '0'] for item in falsy_strings + [False, None, 0, [], {}, AlwaysFalse()]: for item in self._strings_also_in_different_cases(item): assert_true(is_truthy(item) is False) assert_true(is_falsy(item) is True)
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)
def __init__(self, cwd=None, shell=False, stdout=None, stderr=None, output_encoding='CONSOLE', 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.output_encoding = output_encoding self.env = self._construct_env(env, rest)
def open_proxy_browser(self, url=None, browser='chrome', proxy_options=None, alias=None): index = self.drivers.get_index(alias) if index: self.info('Using existing browser from index %s.' % index) self.manager.switch_browser(alias) if is_truthy(url): self.manager.go_to(url) return index return self._make_new_browser(url, browser, proxy_options, alias)
def get_data_from_source(self): dtype = object if is_truthy(getattr(self, "preserve_xls_types", False)) else str data_frame = self.read_data_frame_from_file(dtype) self._analyse_header(list(data_frame)) for row_index, row in enumerate(data_frame.values.tolist()): try: self._read_data_from_table(row) except Exception as e: e.row = row_index + 1 raise e return self.data_table
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 open_proxy_browser(self, url=None, browser='chrome', proxy_options=None, alias=None): """Open Browser. The ``url`` is the address you wish to open the browser with. https://google.com The ``browser`` argument is the browser type you wish to run. Chrome or Firefox ``proxy_settings`` parameter is optional and if provided, it must be a dictionary. Optional Settings: If the site you are testing uses a self-signed certificate then you must set the verify_ssl option to False ``` { 'verify_ssl': False } ``` The number of seconds Selenium Wire should wait before timing out requests. ``` { 'connection_timeout': None # Never timeout } ``` If the site you are testing sits behind a proxy server you can tell Selenium Wire about that proxy server in the options you pass to the webdriver instance. The configuration takes the following format: ``` { 'proxy': { 'http': 'http://*****:*****@host:port', 'https': 'https://*****:*****@host:port', 'no_proxy': 'localhost,127.0.0.1,dev_server:8080' } } ``` Example: | `Open Proxy Browser` | https://duckduckgo.com | Chrome | ${proxy_dict_options} """ index = self.drivers.get_index(alias) if index: self.info('Using existing browser from index %s.' % index) self.manager.switch_browser(alias) if is_truthy(url): self.manager.go_to(url) return index return self._make_new_browser(url, browser, proxy_options, alias)
def take_screenshots_on_failure(self, status): """Disables or enables automatic screenshot capturing on failure. ``status`` is the desired state (True/False) of automatic screenshot on failure. Boolean values are evaluated in the same way as the Robot Framework BuiltIn library does, see [http://robotframework.org/robotframework | the documentation of BuiltIn] for details. WhiteLibrary automatically takes a screenshot on failure unless it is disabled with this keyword. """ if is_truthy(status): self.state.screenshots_enabled = True else: self.state.screenshots_enabled = False
def _make_new_browser(self, url, browser, proxy_options, alias=None): driver = self._make_proxy_driver(browser, proxy_options) driver = self._wrap_event_firing_webdriver(driver) index = self.ctx.register_driver(driver, alias) if is_truthy(url): try: driver.get(url) except Exception: self.debug("Opened browser with session id %s but failed to open url '%s'." % ( driver.session_id, url)) raise self.debug('Opened browser with session id %s.' % driver.session_id) return index
def stop_gif_recording(self): self._close_threads() path = self._save_screenshot_path(basename=self.name, format='gif') self.frames[0].save(path, save_all=True, append_images=self.frames[1:], duration=125, optimize=True, loop=0) if is_truthy(self.embed): self._embed_screenshot(path, self.embed_width) self.frames = [] return path
def _init(self): output_location = BuiltIn().get_variable_value('${OUTPUT_DIR}') db.DataHandlerService().init(os.path.join(output_location, self.location), self.file_name, self.cumulative) level = BuiltIn().get_variable_value('${LOG LEVEL}') logger.setLevel(level) rel_log_file_path = os.path.join(self.location, self.file_name) abs_log_file_path = os.path.join(output_location, self.location, self.file_name) logger.set_file_handler(abs_log_file_path) if is_truthy(self._log_to_db): db.TableSchemaService().register_table(db.tables.log()) logger.addHandler(db.services.SQLiteHandler()) db.DataHandlerService().start() logger.warn(f'<a href="{rel_log_file_path}">{self.file_name}</a>', html=True)
def _create_env(self, close_security_dialogs=False, remote_port=0, dir_path=None, custom=None): agent_command = '-javaagent:"%s"=127.0.0.1:%s' % (RemoteSwingLibrary.AGENT_PATH, RemoteSwingLibrary.PORT) if int(remote_port): agent_command += ':APPORT=%s' % remote_port if custom: agent_command += ':CUSTOM=%s' % custom if RemoteSwingLibrary.DEBUG: agent_command += ':DEBUG' if _tobool(close_security_dialogs): agent_command += ':CLOSE_SECURITY_DIALOGS' if is_truthy(dir_path): dir_path = os.path.abspath(dir_path) agent_command += ':DIR_PATH:%s' % dir_path self._agent_command = agent_command logger.info(agent_command)
def _port(self, port_locator=None, fail=True): """ Lookup port by name. If port_locator is None or string '_', current port is returned. If specified port is not found, exception is raised when fail is True, otherwise None is returned silently. """ if port_locator in [None, '_']: port_locator = self._current_port_locator port = self._ports.get(port_locator, None) if port is None and is_truthy(fail) is True: asserts.fail('No such port.') return port
def __init__(self, method: Callable, command=None, **user_options): self.variable_setter = user_options.pop('variable_setter', None) if self.variable_setter: assert isinstance(self.variable_setter, Variable), "Variable setter type error" self.variable_getter = user_options.pop('variable_getter', None) if self.variable_getter: assert isinstance(self.variable_getter, Variable), "Variable getter vtype error" self.parser: Parser = user_options.pop('parser', None) self._sudo_expected = is_truthy(user_options.pop('sudo', False)) self._sudo_password_expected = is_truthy( user_options.pop('sudo_password', False)) self._start_in_folder = user_options.pop('start_in_folder', None) # self._alias = user_options.pop('alias', None) self._ssh_options = dict( _normalize_method_arguments(method.__name__, **user_options)) self._result_template = _ExecutionResult(**self._ssh_options) if self.parser: assert isinstance( self.parser, Parser ), f"Parser type error [Error type: {type(self.parser).__name__}]" self._method = method self._command = command
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 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)
def test_truthy_values(self): for item in [True, 1, [False], unittest.TestCase, 'truE', 'whatEver']: for item in self._strings_also_in_different_cases(item): assert_true(is_truthy(item) is True) assert_true(is_falsy(item) is False)
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)