1#  Copyright 2008-2015 Nokia Networks
2#  Copyright 2016-     Robot Framework Foundation
3#
4#  Licensed under the Apache License, Version 2.0 (the "License");
5#  you may not use this file except in compliance with the License.
6#  You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10#  Unless required by applicable law or agreed to in writing, software
11#  distributed under the License is distributed on an "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#  See the License for the specific language governing permissions and
14#  limitations under the License.
15
16"""A test library providing dialogs for interacting with users.
17
18``Dialogs`` is Robot Framework's standard library that provides means
19for pausing the test execution and getting input from users. The
20dialogs are slightly different depending on whether tests are run on
21Python, IronPython or Jython but they provide the same functionality.
22
23Long lines in the provided messages are wrapped automatically. If you want
24to wrap lines manually, you can add newlines using the ``\\n`` character
25sequence.
26
27The library has a known limitation that it cannot be used with timeouts
28on Python. Support for IronPython was added in Robot Framework 2.9.2.
29"""
30
31from robot.version import get_version
32from robot.utils import IRONPYTHON, JYTHON, is_truthy
33
34if JYTHON:
35    from .dialogs_jy import MessageDialog, PassFailDialog, InputDialog, SelectionDialog, MultipleSelectionDialog
36elif IRONPYTHON:
37    from .dialogs_ipy import MessageDialog, PassFailDialog, InputDialog, SelectionDialog, MultipleSelectionDialog
38else:
39    from .dialogs_py import MessageDialog, PassFailDialog, InputDialog, SelectionDialog, MultipleSelectionDialog
40
41
42__version__ = get_version()
43__all__ = ['execute_manual_step', 'get_value_from_user',
44           'get_selection_from_user', 'pause_execution', 'get_selections_from_user']
45
46
47def pause_execution(message='Test execution paused. Press OK to continue.'):
48    """Pauses test execution until user clicks ``Ok`` button.
49
50    ``message`` is the message shown in the dialog.
51    """
52    MessageDialog(message).show()
53
54
55def execute_manual_step(message, default_error=''):
56    """Pauses test execution until user sets the keyword status.
57
58    User can press either ``PASS`` or ``FAIL`` button. In the latter case execution
59    fails and an additional dialog is opened for defining the error message.
60
61    ``message`` is the instruction shown in the initial dialog and
62    ``default_error`` is the default value shown in the possible error message
63    dialog.
64    """
65    if not _validate_user_input(PassFailDialog(message)):
66        msg = get_value_from_user('Give error message:', default_error)
67        raise AssertionError(msg)
68
69
70def get_value_from_user(message, default_value='', hidden=False):
71    """Pauses test execution and asks user to input a value.
72
73    Value typed by the user, or the possible default value, is returned.
74    Returning an empty value is fine, but pressing ``Cancel`` fails the keyword.
75
76    ``message`` is the instruction shown in the dialog and ``default_value`` is
77    the possible default value shown in the input field.
78
79    If ``hidden`` is given a true value, the value typed by the user is hidden.
80    ``hidden`` is considered true if it is a non-empty string not equal to
81    ``false``, ``none`` or ``no``, case-insensitively. If it is not a string,
82    its truth value is got directly using same
83    [http://docs.python.org/library/stdtypes.html#truth|rules as in Python].
84
85    Example:
86    | ${username} = | Get Value From User | Input user name | default    |
87    | ${password} = | Get Value From User | Input password  | hidden=yes |
88
89    Considering strings ``false`` and ``no`` to be false is new in RF 2.9
90    and considering string ``none`` false is new in RF 3.0.3.
91    """
92    return _validate_user_input(InputDialog(message, default_value,
93                                            is_truthy(hidden)))
94
95
96def get_selection_from_user(message, *values):
97    """Pauses test execution and asks user to select a value.
98
99    The selected value is returned. Pressing ``Cancel`` fails the keyword.
100
101    ``message`` is the instruction shown in the dialog and ``values`` are
102    the options given to the user.
103
104    Example:
105    | ${user} = | Get Selection From User | Select user | user1 | user2 | admin |
106    """
107    return _validate_user_input(SelectionDialog(message, values))
108
109
110def get_selections_from_user(message, *values):
111    """Pauses test execution and asks user to select multiple values.
112
113    The selected values are returned as a list. Selecting no values is OK
114    and in that case the returned list is empty. Pressing ``Cancel`` fails
115    the keyword.
116
117    ``message`` is the instruction shown in the dialog and ``values`` are
118    the options given to the user.
119
120    Example:
121    | ${users} = | Get Selections From User | Select users | user1 | user2 | admin |
122
123    New in Robot Framework 3.1.
124    """
125    return _validate_user_input(MultipleSelectionDialog(message, values))
126
127
128def _validate_user_input(dialog):
129    value = dialog.show()
130    if value is None:
131        raise RuntimeError('No value provided by user.')
132    return value
133