From b52f47c30af6a96e07b8b29f859eb2c3d156d888 Mon Sep 17 00:00:00 2001 From: Nithya Mani Date: Mon, 5 Sep 2022 19:00:20 +0530 Subject: [PATCH 1/2] updated code --- .gitignore | 8 +- Jenkinsfile | 2 +- app/test/Appium_android.robot | 3 +- app/test/Appium_ios.robot | 2 + app/test/appium-screenshot-1.png | Bin 180198 -> 0 bytes app/test/parallel/Suite1_App.robot | 1 - libspecs/AppiumLibrary_44335e8.libspec | 1369 ------ libspecs/BuiltIn.libspec | 2923 ------------- libspecs/Collections.libspec | 911 ---- libspecs/DateTime.libspec | 512 --- libspecs/Dialogs.libspec | 112 - libspecs/Easter.libspec | 15 - libspecs/OperatingSystem.libspec | 1150 ------ libspecs/Process.libspec | 637 --- libspecs/Reserved.libspec | 87 - libspecs/Screenshot.libspec | 132 - libspecs/SeleniumLibrary_104a884.libspec | 3676 ----------------- libspecs/String.libspec | 722 ---- libspecs/Telnet.libspec | 744 ---- libspecs/XML.libspec | 1365 ------ libspecs/browserstack.local_f74ac98.libspec | 7 - red.xml | 13 - web/test/parallel/0-selenium-screenshot-1.png | Bin 236112 -> 0 bytes 23 files changed, 10 insertions(+), 14381 deletions(-) delete mode 100644 app/test/appium-screenshot-1.png delete mode 100644 libspecs/AppiumLibrary_44335e8.libspec delete mode 100644 libspecs/BuiltIn.libspec delete mode 100644 libspecs/Collections.libspec delete mode 100644 libspecs/DateTime.libspec delete mode 100644 libspecs/Dialogs.libspec delete mode 100644 libspecs/Easter.libspec delete mode 100644 libspecs/OperatingSystem.libspec delete mode 100644 libspecs/Process.libspec delete mode 100644 libspecs/Reserved.libspec delete mode 100644 libspecs/Screenshot.libspec delete mode 100644 libspecs/SeleniumLibrary_104a884.libspec delete mode 100644 libspecs/String.libspec delete mode 100644 libspecs/Telnet.libspec delete mode 100644 libspecs/XML.libspec delete mode 100644 libspecs/browserstack.local_f74ac98.libspec delete mode 100644 red.xml delete mode 100644 web/test/parallel/0-selenium-screenshot-1.png diff --git a/.gitignore b/.gitignore index 66768f8..8262605 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ -<<<<<<< HEAD -======= *.html *.xml pabot_results/ .DS_Store .pabotsuitenames ->>>>>>> 3cc58ce6db279811ff4b164f3dc5afca4d15c153 +*.jpg +*.project +*.png +libspecs/ +.DS_Store \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index 7659e6a..2cee130 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,7 +3,7 @@ node { stage('Preparation') { // for display purposes //pass login properties([parameters([credentials(credentialType: 'com.browserstack.automate.ci.jenkins.BrowserStackCredentials', defaultValue: '', description: '', name: 'BROWSERSTACK_USERNAME', required: true), choice(choices: ['single', 'local', 'parallel - testsuite level', 'parallel - testcase level', 'appium_android', 'appium_ios', 'appium parallel'], description: 'Included Automate and App-Automate tests', name: 'Command')])]) - git changelog: false, poll: false, url: 'https://github.com/nithyamn/bs-robot-framework.git' + git changelog: false, poll: false, url: 'https://github.com/BrowserStackCE/bstack-robot-framework.git' } stage('Initiate tests on BrowserStack') { browserstack(credentialsId: "${params.BROWSERSTACK_USERNAME}",localConfig: [localOptions: '', localPath: '']) { diff --git a/app/test/Appium_android.robot b/app/test/Appium_android.robot index dcfcd9a..3f65fb8 100644 --- a/app/test/Appium_android.robot +++ b/app/test/Appium_android.robot @@ -5,7 +5,7 @@ Library Process *** Variables *** ${USERNAME} %{BROWSERSTACK_USERNAME} #Can specify BrowserStack Username directly instead of Environment variable. ${ACCESS_KEY} %{BROWSERSTACK_ACCESS_KEY} #Can specify BrowserStack Accesskey directly instead of Environment variable. -${REMOTE_URL} http://${USERNAME}:${ACCESS_KEY}@hub-cloud.browserstack.com/wd/hub +${REMOTE_URL} http://${USERNAME}:${ACCESS_KEY}@hub-cloud.browserstack.com/wd/hub *** Test Cases *** Appium Test on BrowserStack @@ -21,6 +21,7 @@ Appium Test on BrowserStack Close Application + # Upload app programatically # ${AppUrl} Run Process curl -u "${USERNAME}:${ACCESS_KEY}" -X POST "https://api-cloud.browserstack.com/app-automate/upload" -F "file\=@${APP_PATH}" shell=true alias=AppUpload # ${AppData} Evaluate json.loads("""${AppUrl.stdout}""") json # Log ${AppUrl.stdout} diff --git a/app/test/Appium_ios.robot b/app/test/Appium_ios.robot index be5699c..1fbe347 100644 --- a/app/test/Appium_ios.robot +++ b/app/test/Appium_ios.robot @@ -16,6 +16,8 @@ Appium Test on BrowserStack Click Element accessibility_id=OK Close Application + + # Upload app programatically # ${AppUrl} Run Process curl -u "${USERNAME}:${ACCESS_KEY}" -X POST "https://api-cloud.browserstack.com/app-automate/upload" -F "file\=@${APP_PATH}" shell=true alias=AppUpload # ${AppData} Evaluate json.loads("""${AppUrl.stdout}""") json # Log ${AppUrl.stdout} diff --git a/app/test/appium-screenshot-1.png b/app/test/appium-screenshot-1.png deleted file mode 100644 index 3346af9f495911a15981732840ecd04acb536136..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180198 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�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

a-0bBcSl}18w)t-c<4yIq}#j> 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π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%0ATZk8Pwu) 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 i(o`I2 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 PgqNitqbyw|X%zf_#AGzK diff --git a/app/test/parallel/Suite1_App.robot b/app/test/parallel/Suite1_App.robot index 043cd6b..46fb21e 100644 --- a/app/test/parallel/Suite1_App.robot +++ b/app/test/parallel/Suite1_App.robot @@ -6,7 +6,6 @@ Library Process ${USERNAME} %{BROWSERSTACK_USERNAME} #Can specify BrowserStack Username directly instead of Environment variable. ${ACCESS_KEY} %{BROWSERSTACK_ACCESS_KEY} #Can specify BrowserStack Accesskey directly instead of Environment variable. ${REMOTE_URL} http://${USERNAME}:${ACCESS_KEY}@hub-cloud.browserstack.com/wd/hub -${APP_PATH} /Users/nithyamani/Desktop/APPS/WikipediaSample.apk *** Test Cases *** Appium Test on BrowserStack diff --git a/libspecs/AppiumLibrary_44335e8.libspec b/libspecs/AppiumLibrary_44335e8.libspec deleted file mode 100644 index 86e352c..0000000 --- a/libspecs/AppiumLibrary_44335e8.libspec +++ /dev/null @@ -1,1369 +0,0 @@ - - -1.5.0.4 -global -yes -AppiumLibrary is a Mobile App testing library for Robot Framework. - -= Locating or specifying elements = - -All keywords in AppiumLibrary that need to find an element on the page -take an argument, either a ``locator`` or a ``webelement``. ``locator`` -is a string that describes how to locate an element using a syntax -specifying different location strategies. ``webelement`` is a variable that -holds a WebElement instance, which is a representation of the element. - -== Using locators == - -By default, when a locator is provided, it is matched against the key attributes -of the particular element type. For iOS and Android, key attribute is ``id`` for -all elements and locating elements is easy using just the ``id``. For example: - -| Click Element id=my_element - -New in AppiumLibrary 1.4, ``id`` and ``xpath`` are not required to be specified, -however ``xpath`` should start with ``//`` else just use ``xpath`` locator as explained below. - -For example: - -| Click Element my_element -| Wait Until Page Contains Element //*[@type="android.widget.EditText"] - - -Appium additionally supports some of the [https://w3c.github.io/webdriver/webdriver-spec.html|Mobile JSON Wire Protocol] locator strategies. -It is also possible to specify the approach AppiumLibrary should take -to find an element by specifying a lookup strategy with a locator -prefix. Supported strategies are: - -| *Strategy* | *Example* | *Description* | *Note* | -| identifier | Click Element `|` identifier=my_element | Matches by @id attribute | | -| id | Click Element `|` id=my_element | Matches by @resource-id attribute | | -| accessibility_id | Click Element `|` accessibility_id=button3 | Accessibility options utilize. | | -| xpath | Click Element `|` xpath=//UIATableView/UIATableCell/UIAButton | Matches with arbitrary XPath | | -| class | Click Element `|` class=UIAPickerWheel | Matches by class | | -| android | Click Element `|` android=UiSelector().description('Apps') | Matches by Android UI Automator | | -| ios | Click Element `|` ios=.buttons().withName('Apps') | Matches by iOS UI Automation | | -| nsp | Click Element `|` nsp=name=="login" | Matches by iOSNsPredicate | Check PR: #196 | -| css | Click Element `|` css=.green_button | Matches by css in webview | | -| name | Click Element `|` name=my_element | Matches by @name attribute | *Only valid* for Selendroid | - -== Using webelements == - -Starting with version 1.4 of the AppiumLibrary, one can pass an argument -that contains a WebElement instead of a string locator. To get a WebElement, -use the new `Get WebElements` or `Get WebElement` keyword. - -For example: -| @{elements} Get Webelements class=UIAButton -| Click Element @{elements}[2] - - -timeout=5 -run_on_failure=Capture Page Screenshot - -AppiumLibrary can be imported with optional arguments. - -``timeout`` is the default timeout used to wait for all waiting actions. -It can be later set with `Set Appium Timeout`. - -``run_on_failure`` specifies the name of a keyword (from any available -libraries) to execute when a AppiumLibrary keyword fails. - -By default `Capture Page Screenshot` will be used to take a screenshot of the current page. -Using the value `No Operation` will disable this feature altogether. See -`Register Keyword To Run On Failure` keyword for more information about this -functionality. - -Examples: -| Library | AppiumLibrary | 10 | # Sets default timeout to 10 seconds | -| Library | AppiumLibrary | timeout=10 | run_on_failure=No Operation | # Sets default timeout to 10 seconds and does nothing on failure | - - - - - -seconds=5 - -Puts the application in the background on the device for a certain -duration. - - - - - -filename=None - -Takes a screenshot of the current page and embeds it into the log. - -`filename` argument specifies the name of the file to write the -screenshot into. If no `filename` is given, the screenshot is saved into file -`appium-screenshot-<counter>.png` under the directory where -the Robot Framework log file is written into. The `filename` is -also considered relative to the same directory, if it is not -given in absolute format. - -`css` can be used to modify how the screenshot is taken. By default -the bakground color is changed to avoid possible problems with -background leaking when the page layout is somehow broken. - - - - - -locator - -Clears the text field identified by `locator`. - -See `introduction` for details about locating elements. - - - - - -x=0 -y=0 -duration=100 - -Click on a point - - - - - -index_or_name - -Click button - - - - - -locator - -Click element identified by `locator`. - -Key attributes for arbitrary elements are `index` and `name`. See -`introduction` for details about locating elements. - - - - - -coordinate_X -coordinate_Y - -click element at a certain coordinate - - - - - -text -exact_match=False - -Click text identified by ``text``. - -By default tries to click first text involves given ``text``, if you would -like to click exactly matching text, then set ``exact_match`` to `True`. - -If there are multiple use of ``text`` and you do not want first one, -use `locator` with `Get Web Elements` instead. - - - - - - -Closes all open applications. - -This keyword is meant to be used in test or suite teardown to -make sure all the applications are closed before the test execution -finishes. - -After this keyword, the application indices returned by `Open Application` -are reset and start from `1`. - - - - - - -Closes the current application and also close webdriver session. - - - - - -locator -attr_name -match_pattern -regexp=False - -Verify that an attribute of an element matches the expected criteria. - -The element is identified by _locator_. See `introduction` for details -about locating elements. If more than one element matches, the first element is selected. - -The _attr_name_ is the name of the attribute within the selected element. - -The _match_pattern_ is used for the matching, if the match_pattern is -- boolean or 'True'/'true'/'False'/'false' String then a boolean match is applied -- any other string is cause a string match - -The _regexp_ defines whether the string match is done using regular expressions (i.e. BuiltIn Library's -[http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Should%20Match%20Regexp|Should -Match Regexp] or string pattern match (i.e. BuiltIn Library's -[http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Should%20Match|Should -Match]) - - -Examples: - -| Element Attribute Should Match | xpath = //*[contains(@text,'foo')] | text | *foobar | -| Element Attribute Should Match | xpath = //*[contains(@text,'foo')] | text | f.*ar | regexp = True | -| Element Attribute Should Match | xpath = //*[contains(@text,'foo')] | enabled | True | - -| 1. is a string pattern match i.e. the 'text' attribute should end with the string 'foobar' -| 2. is a regular expression match i.e. the regexp 'f.*ar' should be within the 'text' attribute -| 3. is a boolead match i.e. the 'enabled' attribute should be True - - -_*NOTE: *_ -On Android the supported attribute names are hard-coded in the -[https://github.com/appium/appium/blob/master/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/AndroidElement.java|AndroidElement] -Class's getBoolAttribute() and getStringAttribute() methods. -Currently supported (appium v1.4.11): -_contentDescription, text, className, resourceId, enabled, checkable, checked, clickable, focusable, focused, longClickable, scrollable, selected, displayed_ - - -_*NOTE: *_ -Some attributes can be evaluated in two different ways e.g. these evaluate the same thing: - -| Element Attribute Should Match | xpath = //*[contains(@text,'example text')] | name | txt_field_name | -| Element Name Should Be | xpath = //*[contains(@text,'example text')] | txt_field_name | | - - - - - -locator -expected - - - - - - - -locator -loglevel=INFO - -Verifies that element identified with locator is disabled. - -Key attributes for arbitrary elements are `id` and `name`. See -`introduction` for details about locating elements. - - - - - -locator -loglevel=INFO - -Verifies that element identified with locator is enabled. - -Key attributes for arbitrary elements are `id` and `name`. See -`introduction` for details about locating elements. - - - - - -locator -loglevel=INFO - -Verifies that element identified with locator is visible. - -Key attributes for arbitrary elements are `id` and `name`. See -`introduction` for details about locating elements. - -New in AppiumLibrary 1.4.5 - - - - - -locator -expected -message= - -Verifies element identified by ``locator`` contains text ``expected``. - -If you wish to assert an exact (not a substring) match on the text -of the element, use `Element Text Should Be`. - -Key attributes for arbitrary elements are ``id`` and ``xpath``. ``message`` can be used to override the default error message. - -New in AppiumLibrary 1.4. - - - - - -locator -expected -message= - -Verifies element identified by ``locator`` does not contain text ``expected``. - -``message`` can be used to override the default error message. -See `Element Should Contain Text` for more details. - - - - - -locator -expected -message= - -Verifies element identified by ``locator`` exactly contains text ``expected``. - -In contrast to `Element Should Contain Text`, this keyword does not try -a substring match but an exact match on the element identified by ``locator``. - -``message`` can be used to override the default error message. - -New in AppiumLibrary 1.4. - - - - - -locator -expected - - - - - - - -command -*args - -Execute ADB shell commands - -Android only. - -- _command_ - The ABD shell command -- _args_ - Arguments to send to command - -Returns the exit code of ADB shell. - -Requires server flag --relaxed-security to be set on Appium server. - - - - - -script - -Inject a snippet of Async-JavaScript into the page for execution in the -context of the currently selected frame (Web context only). - -The executed script is assumed to be asynchronous and must signal that is done by -invoking the provided callback, which is always provided as the final argument to the -function. - -The value to this callback will be returned to the client. - - -New in AppiumLibrary 1.5 - - - - - -script - -Inject a snippet of JavaScript into the page for execution in the -context of the currently selected frame (Web context only). - -The executed script is assumed to be synchronous and the result -of evaluating the script is returned to the client. - -New in AppiumLibrary 1.5 - - - - - - -Retrieves the current activity on the device. - -Android only. - - - - - - -Returns the current session ID as a reference - - - - - - -Gets the timeout in seconds that is used by various keywords. - -See `Set Appium Timeout` for an explanation. - - - - - -capability_name - -Return the desired capability value by desired capability name - - - - - - -Get available contexts. - - - - - - -Get current context. - - - - - -locator -attribute - -Get element attribute using given attribute: name, value,... - -Examples: - -| Get Element Attribute | locator | name | -| Get Element Attribute | locator | value | - - - - - -locator - -Get element location - -Key attributes for arbitrary elements are `id` and `name`. See -`introduction` for details about locating elements. - - - - - -locator - -Get element size - -Key attributes for arbitrary elements are `id` and `name`. See -`introduction` for details about locating elements. - - - - - -xpath - -Returns number of elements matching ``xpath`` - -One should not use the `xpath=` prefix for 'xpath'. XPath is assumed. - -| *Correct:* | -| ${count} | Get Matching Xpath Count | //android.view.View[@text='Test'] | -| Incorrect: | -| ${count} | Get Matching Xpath Count | xpath=//android.view.View[@text='Test'] | - -If you wish to assert the number of matching elements, use -`Xpath Should Match X Times`. - -New in AppiumLibrary 1.4. - - - - - - -Returns an integer bitmask specifying the network connection type. - -Android only. - -See `set network connection status` for more details. - - - - - - -Returns the entire source of the current page. - - - - - -locator - -Get element text (for hybrid and mobile browser use `xpath` locator, others might cause problem) - -Example: - -| ${text} | Get Text | //*[contains(@text,'foo')] | - -New in AppiumLibrary 1.4. - - - - - -locator - -Returns the first [http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement|WebElement] object matching ``locator``. - -Example: -| ${element} | Get Webelement | id=my_element | -| Click Element | ${element} | | - -New in AppiumLibrary 1.4. - - - - - -locator - -Returns list of [http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement|WebElement] objects matching ``locator``. - -Example: -| @{elements} | Get Webelements | id=my_element | -| Click Element | @{elements}[2] | | - -This keyword was changed in AppiumLibrary 1.4 in following ways: -- Name is changed from `Get Elements` to current one. -- Deprecated argument ``fail_on_error``, use `Run Keyword and Ignore Error` if necessary. - -New in AppiumLibrary 1.4. - - - - - - -Get current device height. - -Example: -| ${width} | Get Window Height | -| ${height} | Get Window Height | -| Click A Point | ${width | ${height} | - -New in AppiumLibrary 1.4.5 - - - - - - -Get current device width. - -Example: -| ${width} | Get Window Height | -| ${height} | Get Window Height | -| Click A Point | ${width | ${height} | - -New in AppiumLibrary 1.4.5 - - - - - - -Goes one step backward in the browser history. - - - - - -url - -Opens URL in default web browser. - -Example: -| Open Application | http://localhost:4755/wd/hub | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | browserName=Safari | -| Go To URL | http://m.webapp.com | - - - - - -key_name=None - -Hides the software keyboard on the device. (optional) In iOS, use `key_name` to press -a particular key, ex. `Done`. In Android, no parameters are used. - - - - - -locator -text - -Types the given password into text field identified by `locator`. - -Difference between this keyword and `Input Text` is that this keyword -does not log the given password. See `introduction` for details about -locating elements. - - - - - -locator -text - -Types the given `text` into text field identified by `locator`. - -See `introduction` for details about locating elements. - - - - - -locator -text - -Sets the given value into text field identified by `locator`. This is an IOS only keyword, input value makes use of set_value - -See `introduction` for details about locating elements. - - - - - -app_path -app_package - -Install App via Appium - -Android only. - -- app_path - path to app -- app_package - package of install app to verify - - - - - - -Set the device orientation to LANDSCAPE - - - - - - -Launch application. Application can be launched while Appium session running. -This keyword can be used to launch application during test case or between test cases. - -This keyword works while `Open Application` has a test running. This is good practice to `Launch Application` -and `Quit Application` between test cases. As Suite Setup is `Open Application`, `Test Setup` can be used to `Launch Application` - -Example (syntax is just a representation, refer to RF Guide for usage of Setup/Teardown): -| [Setup Suite] | -| | Open Application | http://localhost:4723/wd/hub | platformName=Android | deviceName=192.168.56.101:5555 | app=${CURDIR}/demoapp/OrangeDemoApp.apk | -| [Test Setup] | -| | Launch Application | -| | | <<<test execution>>> | -| | | <<<test execution>>> | -| [Test Teardown] | -| | Quit Application | -| [Suite Teardown] | -| | Close Application | - -See `Quit Application` for quiting application but keeping Appium sesion running. - -New in AppiumLibrary 1.4.6 - - - - - -seconds=5 - -Lock the device for a certain period of time. iOS only. - - - - - -loglevel=INFO - -Logs and returns the entire html source of the current page or frame. - -The `loglevel` argument defines the used log level. Valid log levels are -`WARN`, `INFO` (default), `DEBUG`, `TRACE` and `NONE` (no logging). - - - - - -locator -duration=1000 - -Long press the element with optional duration - - - - - -keycode -metastate=None - -Sends a long press of keycode to the device. - -Android only. - -See `press keycode` for more details. - - - - - -remote_url -alias=None -**kwargs - -Opens a new application to given Appium server. -Capabilities of appium server, Android and iOS, -Please check https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/server-args.md -| *Option* | *Man.* | *Description* | -| remote_url | Yes | Appium server url | -| alias | no | alias | - -Examples: -| Open Application | http://localhost:4723/wd/hub | alias=Myapp1 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app | -| Open Application | http://localhost:4723/wd/hub | platformName=Android | platformVersion=4.2.2 | deviceName=192.168.56.101:5555 | app=${CURDIR}/demoapp/OrangeDemoApp.apk | appPackage=com.netease.qa.orangedemo | appActivity=MainActivity | - - - - - -locator -loglevel=INFO - -Verifies that current page contains `locator` element. - -If this keyword fails, it automatically logs the page source -using the log level specified with the optional `loglevel` argument. -Giving `NONE` as level disables logging. - - - - - -text -loglevel=INFO - -Verifies that current page contains `text`. - -If this keyword fails, it automatically logs the page source -using the log level specified with the optional `loglevel` argument. -Giving `NONE` as level disables logging. - - - - - -locator -loglevel=INFO - -Verifies that current page not contains `locator` element. - -If this keyword fails, it automatically logs the page source -using the log level specified with the optional `loglevel` argument. -Giving `NONE` as level disables logging. - - - - - -text -loglevel=INFO - -Verifies that current page not contains `text`. - -If this keyword fails, it automatically logs the page source -using the log level specified with the optional `loglevel` argument. -Giving `NONE` as level disables logging. - - - - - -locator -percent=200% -steps=1 - -Pinch in on an element a certain amount. - - - - - - -Set the device orientation to PORTRAIT - - - - - -keycode -metastate=None - -Sends a press of keycode to the device. - -Android only. - -Possible keycodes & meta states can be found in -http://developer.android.com/reference/android/view/KeyEvent.html - -Meta state describe the pressed state of key modifiers such as -Shift, Ctrl & Alt keys. The Meta State is an integer in which each -bit set to 1 represents a pressed meta key. - -For example -- META_SHIFT_ON = 1 -- META_ALT_ON = 2 - -| metastate=1 --> Shift is pressed -| metastate=2 --> Alt is pressed -| metastate=3 --> Shift+Alt is pressed - - - _keycode- - the keycode to be sent to the device - - _metastate- - status of the meta keys - - - - - -path -decode=False - -Retrieves the file at `path` and return it's content. - -Android only. - - - _path_ - the path to the file on the device - - _decode_ - True/False decode the data (base64) before returning it (default=False) - - - - - -path -decode=False - -Retrieves a folder at `path`. Returns the folder's contents zipped. - -Android only. - - - _path_ - the path to the folder on the device - - _decode_ - True/False decode the data (base64) before returning it (default=False) - - - - - -path -data -encode=False - -Puts the data in the file specified as `path`. - -Android only. - - - _path_ - the path on the device - - _data_ - data to be written to the file - - _encode_ - True/False encode the data as base64 before writing it to the file (default=False) - - - - - - -Quit application. Application can be quit while Appium session is kept alive. -This keyword can be used to close application during test case or between test cases. - -See `Launch Application` for an explanation. - -New in AppiumLibrary 1.4.6 - - - - - -keyword - -Sets the keyword to execute when a AppiumLibrary keyword fails. - -`keyword_name` is the name of a keyword (from any available -libraries) that will be executed if a AppiumLibrary keyword fails. -It is not possible to use a keyword that requires arguments. -Using the value "Nothing" will disable this feature altogether. - -The initial keyword to use is set in `importing`, and the -keyword that is used by default is `Capture Page Screenshot`. -Taking a screenshot when something failed is a very useful -feature, but notice that it can slow down the execution. - -This keyword returns the name of the previously registered -failure keyword. It can be used to restore the original -value later. - -Example: -| Register Keyword To Run On Failure | Log Source | # Run `Log Source` on failure. | -| ${previous kw}= | Register Keyword To Run On Failure | Nothing | # Disables run-on-failure functionality and stores the previous kw name in a variable. | -| Register Keyword To Run On Failure | ${previous kw} | # Restore to the previous keyword. | - -This run-on-failure functionality only works when running tests on Python/Jython 2.4 -or newer and it does not work on IronPython at all. - - - - - -application_id - -Removes the application that is identified with an application id - -Example: -| Remove Application | com.netease.qa.orangedemo | - - - - - - -Reset application. Open Application can be reset while Appium session is kept alive. - - - - - -start_locator -end_locator - -Scrolls from one element to another -Key attributes for arbitrary elements are `id` and `name`. See -`introduction` for details about locating elements. - - - - - -locator - -Scrolls down to element - - - - - -locator - -Scrolls up to element - - - - - -seconds - -Sets the timeout in seconds used by various keywords. - -There are several `Wait ...` keywords that take timeout as an -argument. All of these timeout arguments are optional. The timeout -used by all of them can be set globally using this keyword. - -The previous timeout value is returned by this keyword and can -be used to set the old value back later. The default timeout -is 5 seconds, but it can be altered in `importing`. - -Example: -| ${orig timeout} = | Set Appium Timeout | 15 seconds | -| Open page that loads slowly | -| Set Appium Timeout | ${orig timeout} | - - - - - -latitude -longitude -altitude=10 - -Set location - -- _latitute_ -- _longitude_ -- _altitude_ = 10 [optional] - -Android only. -New in AppiumLibrary 1.5 - - - - - -connectionStatus - -Sets the network connection Status. - -Android only. - -Possible values: - | =Value= | =Alias= | =Data= | =Wifi= | =Airplane Mode= | - | 0 | (None) | 0 | 0 | 0 | - | 1 | (Airplane Mode) | 0 | 0 | 1 | - | 2 | (Wifi only) | 0 | 1 | 0 | - | 4 | (Data only) | 1 | 0 | 0 | - | 6 | (All network on) | 1 | 1 | 0 | - - - - - - -Shake the device - - - - - -appPackage -appActivity -**opts - -Opens an arbitrary activity during a test. If the activity belongs to -another application, that application is started and the activity is opened. - -Android only. - -- _appPackage_ - The package containing the activity to start. -- _appActivity_ - The activity to start. -- _appWaitPackage_ - Begin automation after this package starts (optional). -- _appWaitActivity_ - Begin automation after this activity starts (optional). -- _intentAction_ - Intent to start (opt_ional). -- _intentCategory_ - Intent category to start (optional). -- _intentFlags_ - Flags to send to the intent (optional). -- _optionalIntentArguments_ - Optional arguments to the intent (optional). -- _dontStopAppOnReset_ - Should the app be stopped on reset (optional)? - - - - - -start_x -start_y -offset_x -offset_y -duration=1000 - -Swipe from one point to another point, for an optional duration. - -Args: - - start_x - x-coordinate at which to start - - start_y - y-coordinate at which to start - - offset_x - x-coordinate distance from start_x at which to stop - - offset_y - y-coordinate distance from start_y at which to stop - - duration - (optional) time to take the swipe, in ms. - -Usage: -| Swipe | 500 | 100 | 100 | 0 | 1000 | - -_*NOTE: *_ -Android 'Swipe' is not working properly, use ``offset_x`` and ``offset_y`` as if these are destination points. - - - - - -start_x -start_y -end_x -end_y -duration=1000 - -Swipe from one percent of the screen to another percent, for an optional duration. -Normal swipe fails to scale for different screen resolutions, this can be avoided using percent. - -Args: - - start_x - x-percent at which to start - - start_y - y-percent at which to start - - end_x - x-percent distance from start_x at which to stop - - end_y - y-percent distance from start_y at which to stop - - duration - (optional) time to take the swipe, in ms. - -Usage: -| Swipe By Percent | 90 | 50 | 10 | 50 | # Swipes screen from right to left. | - -_*NOTE: *_ -This also considers swipe acts different between iOS and Android. - -New in AppiumLibrary 1.4.5 - - - - - -index_or_alias - -Switches the active application by index or alias. - -`index_or_alias` is either application index (an integer) or alias -(a string). Index is got as the return value of `Open Application`. - -This keyword returns the index of the previous active application, -which can be used to switch back to that application later. - -Example: -| ${appium1}= | Open Application | http://localhost:4723/wd/hub | alias=MyApp1 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app | -| ${appium2}= | Open Application | http://localhost:4755/wd/hub | alias=MyApp2 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app | -| Click Element | sendHello | # Executed on appium running at localhost:4755 | -| Switch Application | ${appium1} | # Switch using index | -| Click Element | ackHello | # Executed on appium running at localhost:4723 | -| Switch Application | MyApp2 | # Switch using alias | -| Page Should Contain Text | ackHello Received | # Executed on appium running at localhost:4755 | - - - - - -context_name - -Switch to a new context - - - - - -locator -x_offset=None -y_offset=None -count=1 - -Tap element identified by ``locator``. - -Args: -- ``x_offset`` - (optional) x coordinate to tap, relative to the top left corner of the element. -- ``y_offset`` - (optional) y coordinate. If y is used, x must also be set, and vice versa -- ``count`` - can be used for multiple times of tap on that element - - - - - -text -exact_match=False -loglevel=INFO - -Verifies that element identified with text is visible. - -New in AppiumLibrary 1.4.5 - - - - - - -Toggle Touch ID enrolled state on iOS Simulator - -New in AppiumLibrary 1.5 - - - - - -match=True - -Simulate Touch ID on iOS Simulator - -`match` (boolean) whether the simulated fingerprint is valid (default true) - -New in AppiumLibrary 1.5 - - - - - -activity -timeout -interval=1 - -Wait for an activity: block until target activity presents -or time out. - -Android only. - - - _activity_ - target activity - - _timeout_ - max wait time, in seconds - - _interval_ - sleep interval between retries, in seconds - - - - - -locator -timeout=None -error=None - -Waits until element specified with `locator` is visible. - -Fails if `timeout` expires before the element is visible. See -`introduction` for more information about `timeout` and its -default value. - -`error` can be used to override the default error message. - -See also `Wait Until Page Contains`, `Wait Until Page Contains -Element`, `Wait For Condition` and BuiltIn keyword `Wait Until Keyword -Succeeds`. - - - - - -text -timeout=None -error=None - -Waits until `text` appears on current page. - -Fails if `timeout` expires before the text appears. See -`introduction` for more information about `timeout` and its -default value. - -`error` can be used to override the default error message. - -See also `Wait Until Page Does Not Contain`, -`Wait Until Page Contains Element`, -`Wait Until Page Does Not Contain Element` and -BuiltIn keyword `Wait Until Keyword Succeeds`. - - - - - -locator -timeout=None -error=None - -Waits until element specified with `locator` appears on current page. - -Fails if `timeout` expires before the element appears. See -`introduction` for more information about `timeout` and its -default value. - -`error` can be used to override the default error message. - -See also `Wait Until Page Contains`, -`Wait Until Page Does Not Contain` -`Wait Until Page Does Not Contain Element` -and BuiltIn keyword `Wait Until Keyword Succeeds`. - - - - - -text -timeout=None -error=None - -Waits until `text` disappears from current page. - -Fails if `timeout` expires before the `text` disappears. See -`introduction` for more information about `timeout` and its -default value. - -`error` can be used to override the default error message. - -See also `Wait Until Page Contains`, -`Wait Until Page Contains Element`, -`Wait Until Page Does Not Contain Element` and -BuiltIn keyword `Wait Until Keyword Succeeds`. - - - - - -locator -timeout=None -error=None - -Waits until element specified with `locator` disappears from current page. - -Fails if `timeout` expires before the element disappears. See -`introduction` for more information about `timeout` and its -default value. - -`error` can be used to override the default error message. - -See also `Wait Until Page Contains`, -`Wait Until Page Does Not Contain`, -`Wait Until Page Contains Element` and -BuiltIn keyword `Wait Until Keyword Succeeds`. - - - - - -xpath -count -error=None -loglevel=INFO - -Verifies that the page contains the given number of elements located by the given ``xpath``. - -One should not use the `xpath=` prefix for 'xpath'. XPath is assumed. - -| *Correct:* | -| Xpath Should Match X Times | //android.view.View[@text='Test'] | 1 | -| Incorrect: | -| Xpath Should Match X Times | xpath=//android.view.View[@text='Test'] | 1 | - -``error`` can be used to override the default error message. - -See `Log Source` for explanation about ``loglevel`` argument. - -New in AppiumLibrary 1.4. - - - - - -locator -percent=200% -steps=1 - -Zooms in on an element a certain amount. - - - - diff --git a/libspecs/BuiltIn.libspec b/libspecs/BuiltIn.libspec deleted file mode 100644 index 21605b8..0000000 --- a/libspecs/BuiltIn.libspec +++ /dev/null @@ -1,2923 +0,0 @@ - - -3.1.2 -global -yes -An always available standard library with often needed keywords. - -``BuiltIn`` is Robot Framework's standard library that provides a set -of generic keywords needed often. It is imported automatically and -thus always available. The provided keywords can be used, for example, -for verifications (e.g. `Should Be Equal`, `Should Contain`), -conversions (e.g. `Convert To Integer`) and for various other purposes -(e.g. `Log`, `Sleep`, `Run Keyword If`, `Set Global Variable`). - -== Table of contents == - -- `HTML error messages` -- `Evaluating expressions` -- `Boolean arguments` -- `Pattern matching` -- `Multiline string comparison` -- `String representations` -- `Shortcuts` -- `Keywords` - -= HTML error messages = - -Many of the keywords accept an optional error message to use if the keyword -fails, and it is possible to use HTML in these messages by prefixing them -with ``*HTML*``. See `Fail` keyword for a usage example. Notice that using -HTML in messages is not limited to BuiltIn library but works with any -error message. - -= Evaluating expressions = - -Many keywords, such as `Evaluate`, `Run Keyword If` and `Should Be True`, -accept an expression that is evaluated in Python. These expressions are -evaluated using Python's -[http://docs.python.org/library/functions.html#eval|eval] function so -that all Python built-ins like ``len()`` and ``int()`` are available. -`Evaluate` allows configuring the execution namespace with custom modules, -and other keywords have [http://docs.python.org/library/os.html|os] -and [http://docs.python.org/library/sys.html|sys] modules available -automatically. - -Examples: -| `Run Keyword If` | os.sep == '/' | Log | Not on Windows | -| ${random int} = | `Evaluate` | random.randint(0, 5) | modules=random | - -When a variable is used in the expressing using the normal ``${variable}`` -syntax, its value is replaces before the expression is evaluated. This -means that the value used in the expression will be the string -representation of the variable value, not the variable value itself. -This is not a problem with numbers and other objects that have a string -representation that can be evaluated directly, but with other objects -the behavior depends on the string representation. Most importantly, -strings must always be quoted, and if they can contain newlines, they must -be triple quoted. - -Examples: -| `Should Be True` | ${rc} < 10 | Return code greater than 10 | -| `Run Keyword If` | '${status}' == 'PASS' | Log | Passed | -| `Run Keyword If` | 'FAIL' in '''${output}''' | Log | Output contains FAIL | - -Starting from Robot Framework 2.9, variables themselves are automatically -available in the evaluation namespace. They can be accessed using special -variable syntax without the curly braces like ``$variable``. These -variables should never be quoted, and in fact they are not even replaced -inside strings. - -Examples: -| `Should Be True` | $rc < 10 | Return code greater than 10 | -| `Run Keyword If` | $status == 'PASS' | `Log` | Passed | -| `Run Keyword If` | 'FAIL' in $output | `Log` | Output contains FAIL | -| `Should Be True` | len($result) > 1 and $result[1] == 'OK' | - -Using the ``$variable`` syntax slows down expression evaluation a little. -This should not typically matter, but should be taken into account if -complex expressions are evaluated often and there are strict time -constrains. - -Notice that instead of creating complicated expressions, it is often better -to move the logic into a test library. That eases maintenance and can also -enhance execution speed. - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is an empty string or equal to ``FALSE``, ``NONE``, ``NO``, ``OFF`` or -``0``, case-insensitively. Keywords verifying something that allow dropping -actual and expected values from the possible error message also consider -string ``no values`` to be false. Other strings are considered true unless -the keyword documentation explicitly states otherwise, and other argument -types are tested using the same -[http://docs.python.org/library/stdtypes.html#truth|rules as in Python]. - -True examples: -| `Should Be Equal` | ${x} | ${y} | Custom error | values=True | # Strings are generally true. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=yes | # Same as the above. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=${TRUE} | # Python ``True`` is true. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=${42} | # Numbers other than 0 are true. | - -False examples: -| `Should Be Equal` | ${x} | ${y} | Custom error | values=False | # String ``false`` is false. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=no | # Also string ``no`` is false. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=${EMPTY} | # Empty string is false. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=${FALSE} | # Python ``False`` is false. | -| `Should Be Equal` | ${x} | ${y} | Custom error | values=no values | # ``no values`` works with ``values`` argument | - -Considering string ``NONE`` false is new in Robot Framework 3.0.3 and -considering also ``OFF`` and ``0`` false is new in Robot Framework 3.1. - -= Pattern matching = - -Many keywords accepts arguments as either glob or regular expression -patterns. - -== Glob patterns == - -Some keywords, for example `Should Match`, support so called -[http://en.wikipedia.org/wiki/Glob_(programming)|glob patterns] where: - -| ``*`` | matches any string, even an empty string | -| ``?`` | matches any single character | -| ``[chars]`` | matches one character in the bracket | -| ``[!chars]`` | matches one character not in the bracket | -| ``[a-z]`` | matches one character from the range in the bracket | -| ``[!a-z]`` | matches one character not from the range in the bracket | - -Unlike with glob patterns normally, path separator characters ``/`` and -``\`` and the newline character ``\n`` are matches by the above -wildcards. - -Support for brackets like ``[abc]`` and ``[!a-z]`` is new in -Robot Framework 3.1 - -== Regular expressions == - -Some keywords, for example `Should Match Regexp`, support -[http://en.wikipedia.org/wiki/Regular_expression|regular expressions] -that are more powerful but also more complicated that glob patterns. -The regular expression support is implemented using Python's -[http://docs.python.org/library/re.html|re module] and its documentation -should be consulted for more information about the syntax. - -Because the backslash character (``\``) is an escape character in -Robot Framework test data, possible backslash characters in regular -expressions need to be escaped with another backslash like ``\\d\\w+``. -Strings that may contain special characters but should be handled -as literal strings, can be escaped with the `Regexp Escape` keyword. - -= Multiline string comparison = - -`Should Be Equal` and `Should Be Equal As Strings` report the failures using -[http://en.wikipedia.org/wiki/Diff_utility#Unified_format|unified diff -format] if both strings have more than two lines. New in Robot Framework -2.9.1. - -Example: -| ${first} = | `Catenate` | SEPARATOR=\n | Not in second | Same | Differs | Same | -| ${second} = | `Catenate` | SEPARATOR=\n | Same | Differs2 | Same | Not in first | -| `Should Be Equal` | ${first} | ${second} | - -Results in the following error message: - -| Multiline strings are different: -| --- first -| +++ second -| @@ -1,4 +1,4 @@ -| -Not in second -| Same -| -Differs -| +Differs2 -| Same -| +Not in first - -= String representations = - -Several keywords log values explicitly (e.g. `Log`) or implicitly (e.g. -`Should Be Equal` when there are failures). By default keywords log values -using "human readable" string representation, which means that strings -like ``Hello`` and numbers like ``42`` are logged as-is. Most of the time -this is the desired behavior, but there are some problems as well: - -- It is not possible to see difference between different objects that - have same string representation like string ``42`` and integer ``42``. - `Should Be Equal` and some other keywords add the type information to - the error message in these cases, though. - -- Non-printable characters such as the null byte are not visible. - -- Trailing whitespace is not visible. - -- Different newlines (``\r\n`` on Windows, ``\n`` elsewhere) cannot - be separated from each others. - -- There are several Unicode characters that are different but look the - same. One example is the Latin ``a`` (``\u0061``) and the Cyrillic - ``а`` (``\u0430``). Error messages like ``a != а`` are - not very helpful. - -- Some Unicode characters can be represented using - [https://en.wikipedia.org/wiki/Unicode_equivalence|different forms]. - For example, ``ä`` can be represented either as a single code point - ``\u00e4`` or using two code points ``\u0061`` and ``\u0308`` combined - together. Such forms are considered canonically equivalent, but strings - containing them are not considered equal when compared in Python. Error - messages like ``ä != ä`` are not that helpful either. - -- Containers such as lists and dictionaries are formatted into a single - line making it hard to see individual items they contain. - -To overcome the above problems, some keywords such as `Log` and -`Should Be Equal` have an optional ``formatter`` argument that can be -used to configure the string representation. The supported values are -``str`` (default), ``repr``, and ``ascii`` that work similarly as -[https://docs.python.org/library/functions.html|Python built-in functions] -with same names. More detailed semantics are explained below. - -The ``formatter`` argument is new in Robot Framework 3.1.2. - -== str == - -Use the "human readable" string representation. Equivalent to using -``str()`` in Python 3 and ``unicode()`` in Python 2. This is the default. - -== repr == - -Use the "machine readable" string representation. Similar to using -``repr()`` in Python, which means that strings like ``Hello`` are logged -like ``'Hello'``, newlines and non-printable characters are escaped like -``\n`` and ``\x00``, and so on. Non-ASCII characters are shown as-is -like ``ä`` in Python 3 and in escaped format like ``\xe4`` in Python 2. -Use ``ascii`` to always get the escaped format. - -There are also some enhancements compared to the standard ``repr()``: -- Bigger lists, dictionaries and other containers are pretty-printed so - that there is one item per row. -- On Python 2 the ``u`` prefix is omitted with Unicode strings and - the ``b`` prefix is added to byte strings. - -== ascii == - -Same as using ``ascii()`` in Python 3 or ``repr()`` in Python 2 where -``ascii()`` does not exist. Similar to using ``repr`` explained above -but with the following differences: - -- On Python 3 non-ASCII characters are escaped like ``\xe4`` instead of - showing them as-is like ``ä``. This makes it easier to see differences - between Unicode characters that look the same but are not equal. This - is how ``repr()`` works in Python 2. -- On Python 2 just uses the standard ``repr()`` meaning that Unicode - strings get the ``u`` prefix and no ``b`` prefix is added to byte - strings. -- Containers are not pretty-printed. - - -object -method_name -*args -**kwargs - -Calls the named method of the given object with the provided arguments. - -The possible return value from the method is returned and can be -assigned to a variable. Keyword fails both if the object does not have -a method with the given name or if executing the method raises an -exception. - -Support for ``**kwargs`` is new in Robot Framework 2.9. Since that -possible equal signs in other arguments must be escaped with a -backslash like ``\=``. - -Examples: -| Call Method | ${hashtable} | put | myname | myvalue | -| ${isempty} = | Call Method | ${hashtable} | isEmpty | | -| Should Not Be True | ${isempty} | | | | -| ${value} = | Call Method | ${hashtable} | get | myname | -| Should Be Equal | ${value} | myvalue | | | -| Call Method | ${object} | kwargs | name=value | foo=bar | -| Call Method | ${object} | positional | escaped\=equals | - - - - - -*items - -Catenates the given items together and returns the resulted string. - -By default, items are catenated with spaces, but if the first item -contains the string ``SEPARATOR=<sep>``, the separator ``<sep>`` is -used instead. Items are converted into strings when necessary. - -Examples: -| ${str1} = | Catenate | Hello | world | | -| ${str2} = | Catenate | SEPARATOR=--- | Hello | world | -| ${str3} = | Catenate | SEPARATOR= | Hello | world | -=> -| ${str1} = 'Hello world' -| ${str2} = 'Hello---world' -| ${str3} = 'Helloworld' - - - - - -*messages - -Displays the given messages in the log file as keyword arguments. - -This keyword does nothing with the arguments it receives, but as they -are visible in the log, this keyword can be used to display simple -messages. Given arguments are ignored so thoroughly that they can even -contain non-existing variables. If you are interested about variable -values, you can use the `Log` or `Log Many` keywords. - - - - - - -Skips the current for loop iteration and continues from the next. - -Skips the remaining keywords in the current for loop iteration and -continues from the next one. Can be used directly in a for loop or -in a keyword that the loop uses. - -Example: -| :FOR | ${var} | IN | @{VALUES} | -| | Run Keyword If | '${var}' == 'CONTINUE' | Continue For Loop | -| | Do Something | ${var} | - -See `Continue For Loop If` to conditionally continue a for loop without -using `Run Keyword If` or other wrapper keywords. - - - - - -condition - -Skips the current for loop iteration if the ``condition`` is true. - -A wrapper for `Continue For Loop` to continue a for loop based on -the given condition. The condition is evaluated using the same -semantics as with `Should Be True` keyword. - -Example: -| :FOR | ${var} | IN | @{VALUES} | -| | Continue For Loop If | '${var}' == 'CONTINUE' | -| | Do Something | ${var} | - - - - - -item -base=None -prefix=None -length=None - -Converts the given item to a binary string. - -The ``item``, with an optional ``base``, is first converted to an -integer using `Convert To Integer` internally. After that it -is converted to a binary number (base 2) represented as a -string such as ``1011``. - -The returned value can contain an optional ``prefix`` and can be -required to be of minimum ``length`` (excluding the prefix and a -possible minus sign). If the value is initially shorter than -the required length, it is padded with zeros. - -Examples: -| ${result} = | Convert To Binary | 10 | | | # Result is 1010 | -| ${result} = | Convert To Binary | F | base=16 | prefix=0b | # Result is 0b1111 | -| ${result} = | Convert To Binary | -2 | prefix=B | length=4 | # Result is -B0010 | - -See also `Convert To Integer`, `Convert To Octal` and `Convert To Hex`. - - - - - -item - -Converts the given item to Boolean true or false. - -Handles strings ``True`` and ``False`` (case-insensitive) as expected, -otherwise returns item's -[http://docs.python.org/library/stdtypes.html#truth|truth value] -using Python's ``bool()`` method. - - - - - -input -input_type=text - -Converts the given ``input`` to bytes according to the ``input_type``. - -Valid input types are listed below: - -- ``text:`` Converts text to bytes character by character. All - characters with ordinal below 256 can be used and are converted to - bytes with same values. Many characters are easiest to represent - using escapes like ``\x00`` or ``\xff``. Supports both Unicode - strings and bytes. - -- ``int:`` Converts integers separated by spaces to bytes. Similarly as - with `Convert To Integer`, it is possible to use binary, octal, or - hex values by prefixing the values with ``0b``, ``0o``, or ``0x``, - respectively. - -- ``hex:`` Converts hexadecimal values to bytes. Single byte is always - two characters long (e.g. ``01`` or ``FF``). Spaces are ignored and - can be used freely as a visual separator. - -- ``bin:`` Converts binary values to bytes. Single byte is always eight - characters long (e.g. ``00001010``). Spaces are ignored and can be - used freely as a visual separator. - -In addition to giving the input as a string, it is possible to use -lists or other iterables containing individual characters or numbers. -In that case numbers do not need to be padded to certain length and -they cannot contain extra spaces. - -Examples (last column shows returned bytes): -| ${bytes} = | Convert To Bytes | hyvä | | # hyv\xe4 | -| ${bytes} = | Convert To Bytes | \xff\x07 | | # \xff\x07 | -| ${bytes} = | Convert To Bytes | 82 70 | int | # RF | -| ${bytes} = | Convert To Bytes | 0b10 0x10 | int | # \x02\x10 | -| ${bytes} = | Convert To Bytes | ff 00 07 | hex | # \xff\x00\x07 | -| ${bytes} = | Convert To Bytes | 5246212121 | hex | # RF!!! | -| ${bytes} = | Convert To Bytes | 0000 1000 | bin | # \x08 | -| ${input} = | Create List | 1 | 2 | 12 | -| ${bytes} = | Convert To Bytes | ${input} | int | # \x01\x02\x0c | -| ${bytes} = | Convert To Bytes | ${input} | hex | # \x01\x02\x12 | - -Use `Encode String To Bytes` in ``String`` library if you need to -convert text to bytes using a certain encoding. - - - - - -item -base=None -prefix=None -length=None -lowercase=False - -Converts the given item to a hexadecimal string. - -The ``item``, with an optional ``base``, is first converted to an -integer using `Convert To Integer` internally. After that it -is converted to a hexadecimal number (base 16) represented as -a string such as ``FF0A``. - -The returned value can contain an optional ``prefix`` and can be -required to be of minimum ``length`` (excluding the prefix and a -possible minus sign). If the value is initially shorter than -the required length, it is padded with zeros. - -By default the value is returned as an upper case string, but the -``lowercase`` argument a true value (see `Boolean arguments`) turns -the value (but not the given prefix) to lower case. - -Examples: -| ${result} = | Convert To Hex | 255 | | | # Result is FF | -| ${result} = | Convert To Hex | -10 | prefix=0x | length=2 | # Result is -0x0A | -| ${result} = | Convert To Hex | 255 | prefix=X | lowercase=yes | # Result is Xff | - -See also `Convert To Integer`, `Convert To Binary` and `Convert To Octal`. - - - - - -item -base=None - -Converts the given item to an integer number. - -If the given item is a string, it is by default expected to be an -integer in base 10. There are two ways to convert from other bases: - -- Give base explicitly to the keyword as ``base`` argument. - -- Prefix the given string with the base so that ``0b`` means binary - (base 2), ``0o`` means octal (base 8), and ``0x`` means hex (base 16). - The prefix is considered only when ``base`` argument is not given and - may itself be prefixed with a plus or minus sign. - -The syntax is case-insensitive and possible spaces are ignored. - -Examples: -| ${result} = | Convert To Integer | 100 | | # Result is 100 | -| ${result} = | Convert To Integer | FF AA | 16 | # Result is 65450 | -| ${result} = | Convert To Integer | 100 | 8 | # Result is 64 | -| ${result} = | Convert To Integer | -100 | 2 | # Result is -4 | -| ${result} = | Convert To Integer | 0b100 | | # Result is 4 | -| ${result} = | Convert To Integer | -0x100 | | # Result is -256 | - -See also `Convert To Number`, `Convert To Binary`, `Convert To Octal`, -`Convert To Hex`, and `Convert To Bytes`. - - - - - -item -precision=None - -Converts the given item to a floating point number. - -If the optional ``precision`` is positive or zero, the returned number -is rounded to that number of decimal digits. Negative precision means -that the number is rounded to the closest multiple of 10 to the power -of the absolute precision. If a number is equally close to a certain -precision, it is always rounded away from zero. - -Examples: -| ${result} = | Convert To Number | 42.512 | | # Result is 42.512 | -| ${result} = | Convert To Number | 42.512 | 1 | # Result is 42.5 | -| ${result} = | Convert To Number | 42.512 | 0 | # Result is 43.0 | -| ${result} = | Convert To Number | 42.512 | -1 | # Result is 40.0 | - -Notice that machines generally cannot store floating point numbers -accurately. This may cause surprises with these numbers in general -and also when they are rounded. For more information see, for example, -these resources: - -- http://docs.python.org/tutorial/floatingpoint.html -- http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition - -If you want to avoid possible problems with floating point numbers, -you can implement custom keywords using Python's -[http://docs.python.org/library/decimal.html|decimal] or -[http://docs.python.org/library/fractions.html|fractions] modules. - -If you need an integer number, use `Convert To Integer` instead. - - - - - -item -base=None -prefix=None -length=None - -Converts the given item to an octal string. - -The ``item``, with an optional ``base``, is first converted to an -integer using `Convert To Integer` internally. After that it -is converted to an octal number (base 8) represented as a -string such as ``775``. - -The returned value can contain an optional ``prefix`` and can be -required to be of minimum ``length`` (excluding the prefix and a -possible minus sign). If the value is initially shorter than -the required length, it is padded with zeros. - -Examples: -| ${result} = | Convert To Octal | 10 | | | # Result is 12 | -| ${result} = | Convert To Octal | -F | base=16 | prefix=0 | # Result is -017 | -| ${result} = | Convert To Octal | 16 | prefix=oct | length=4 | # Result is oct0020 | - -See also `Convert To Integer`, `Convert To Binary` and `Convert To Hex`. - - - - - -item - -Converts the given item to a Unicode string. - -Strings are also [http://www.macchiato.com/unicode/nfc-faq| -NFC normalized]. - -Use `Encode String To Bytes` and `Decode Bytes To String` keywords -in ``String`` library if you need to convert between Unicode and byte -strings using different encodings. Use `Convert To Bytes` if you just -want to create byte strings. - - - - - -*items - -Creates and returns a dictionary based on the given ``items``. - -Items are typically given using the ``key=value`` syntax same way as -``&{dictionary}`` variables are created in the Variable table. Both -keys and values can contain variables, and possible equal sign in key -can be escaped with a backslash like ``escaped\=key=value``. It is -also possible to get items from existing dictionaries by simply using -them like ``&{dict}``. - -Alternatively items can be specified so that keys and values are given -separately. This and the ``key=value`` syntax can even be combined, -but separately given items must be first. If same key is used multiple -times, the last value has precedence. - -The returned dictionary is ordered, and values with strings as keys -can also be accessed using a convenient dot-access syntax like -``${dict.key}``. Technically the returned dictionary is Robot -Framework's own ``DotDict`` instance. If there is a need, it can be -converted into a regular Python ``dict`` instance by using the -`Convert To Dictionary` keyword from the Collections library. - -Examples: -| &{dict} = | Create Dictionary | key=value | foo=bar | | | # key=value syntax | -| Should Be True | ${dict} == {'key': 'value', 'foo': 'bar'} | -| &{dict2} = | Create Dictionary | key | value | foo | bar | # separate key and value | -| Should Be Equal | ${dict} | ${dict2} | -| &{dict} = | Create Dictionary | ${1}=${2} | &{dict} | foo=new | | # using variables | -| Should Be True | ${dict} == {1: 2, 'key': 'value', 'foo': 'new'} | -| Should Be Equal | ${dict.key} | value | | | | # dot-access | - -This keyword was changed in Robot Framework 2.9 in many ways: -- Moved from the Collections library to BuiltIn. -- Support also non-string keys in ``key=value`` syntax. -- Returned dictionary is ordered and dot-accessible (i.e. ``DotDict``). -- Old syntax to give keys and values separately was deprecated, but - deprecation was later removed in RF 3.0.1. - - - - - -*items - -Returns a list containing given items. - -The returned list can be assigned both to ``${scalar}`` and ``@{list}`` -variables. - -Examples: -| @{list} = | Create List | a | b | c | -| ${scalar} = | Create List | a | b | c | -| ${ints} = | Create List | ${1} | ${2} | ${3} | - - - - - -expression -modules=None -namespace=None - -Evaluates the given expression in Python and returns the results. - -``expression`` is evaluated in Python as explained in `Evaluating -expressions`. - -``modules`` argument can be used to specify a comma separated -list of Python modules to be imported and added to the evaluation -namespace. - -``namespace`` argument can be used to pass a custom evaluation -namespace as a dictionary. Possible ``modules`` are added to this -namespace. - -Variables used like ``${variable}`` are replaced in the expression -before evaluation. Variables are also available in the evaluation -namespace and can be accessed using special syntax ``$variable``. -This is a new feature in Robot Framework 2.9 and it is explained more -thoroughly in `Evaluating expressions`. - -Examples (expecting ``${result}`` is 3.14): -| ${status} = | Evaluate | 0 < ${result} < 10 | # Would also work with string '3.14' | -| ${status} = | Evaluate | 0 < $result < 10 | # Using variable itself, not string representation | -| ${random} = | Evaluate | random.randint(0, sys.maxint) | modules=random, sys | -| ${ns} = | Create Dictionary | x=${4} | y=${2} | -| ${result} = | Evaluate | x*10 + y | namespace=${ns} | -=> -| ${status} = True -| ${random} = <random integer> -| ${result} = 42 - - - - - - -Stops executing the enclosing for loop. - -Exits the enclosing for loop and continues execution after it. -Can be used directly in a for loop or in a keyword that the loop uses. - -Example: -| :FOR | ${var} | IN | @{VALUES} | -| | Run Keyword If | '${var}' == 'EXIT' | Exit For Loop | -| | Do Something | ${var} | - -See `Exit For Loop If` to conditionally exit a for loop without -using `Run Keyword If` or other wrapper keywords. - - - - - -condition - -Stops executing the enclosing for loop if the ``condition`` is true. - -A wrapper for `Exit For Loop` to exit a for loop based on -the given condition. The condition is evaluated using the same -semantics as with `Should Be True` keyword. - -Example: -| :FOR | ${var} | IN | @{VALUES} | -| | Exit For Loop If | '${var}' == 'EXIT' | -| | Do Something | ${var} | - - - - - -msg=None -*tags - -Fails the test with the given message and optionally alters its tags. - -The error message is specified using the ``msg`` argument. -It is possible to use HTML in the given error message, similarly -as with any other keyword accepting an error message, by prefixing -the error with ``*HTML*``. - -It is possible to modify tags of the current test case by passing tags -after the message. Tags starting with a hyphen (e.g. ``-regression``) -are removed and others added. Tags are modified using `Set Tags` and -`Remove Tags` internally, and the semantics setting and removing them -are the same as with these keywords. - -Examples: -| Fail | Test not ready | | | # Fails with the given message. | -| Fail | *HTML*<b>Test not ready</b> | | | # Fails using HTML in the message. | -| Fail | Test not ready | not-ready | | # Fails and adds 'not-ready' tag. | -| Fail | OS not supported | -regression | | # Removes tag 'regression'. | -| Fail | My message | tag | -t* | # Removes all tags starting with 't' except the newly added 'tag'. | - -See `Fatal Error` if you need to stop the whole test execution. - - - - - -msg=None - -Stops the whole test execution. - -The test or suite where this keyword is used fails with the provided -message, and subsequent tests fail with a canned message. -Possible teardowns will nevertheless be executed. - -See `Fail` if you only want to stop one test case unconditionally. - - - - - -item1 -item2 - -Returns and logs how many times ``item2`` is found from ``item1``. - -This keyword works with Python strings and lists and all objects -that either have ``count`` method or can be converted to Python lists. - -Example: -| ${count} = | Get Count | ${some item} | interesting value | -| Should Be True | 5 < ${count} < 10 | - - - - - -item - -Returns and logs the length of the given item as an integer. - -The item can be anything that has a length, for example, a string, -a list, or a mapping. The keyword first tries to get the length with -the Python function ``len``, which calls the item's ``__len__`` method -internally. If that fails, the keyword tries to call the item's -possible ``length`` and ``size`` methods directly. The final attempt is -trying to get the value of the item's ``length`` attribute. If all -these attempts are unsuccessful, the keyword fails. - -Examples: -| ${length} = | Get Length | Hello, world! | | -| Should Be Equal As Integers | ${length} | 13 | -| @{list} = | Create List | Hello, | world! | -| ${length} = | Get Length | ${list} | | -| Should Be Equal As Integers | ${length} | 2 | - -See also `Length Should Be`, `Should Be Empty` and `Should Not Be -Empty`. - - - - - -name=None -all=False - -Returns the currently active instance of the specified test library. - -This keyword makes it easy for test libraries to interact with -other test libraries that have state. This is illustrated by -the Python example below: - -| from robot.libraries.BuiltIn import BuiltIn -| -| def title_should_start_with(expected): -| seleniumlib = BuiltIn().get_library_instance('SeleniumLibrary') -| title = seleniumlib.get_title() -| if not title.startswith(expected): -| raise AssertionError("Title '%s' did not start with '%s'" -| % (title, expected)) - -It is also possible to use this keyword in the test data and -pass the returned library instance to another keyword. If a -library is imported with a custom name, the ``name`` used to get -the instance must be that name and not the original library name. - -If the optional argument ``all`` is given a true value, then a -dictionary mapping all library names to instances will be returned. -This feature is new in Robot Framework 2.9.2. - -Example: -| &{all libs} = | Get library instance | all=True | - - - - - -format=timestamp -time_=NOW - -Returns the given time in the requested format. - -*NOTE:* DateTime library contains much more flexible keywords for -getting the current date and time and for date and time handling in -general. - -How time is returned is determined based on the given ``format`` -string as follows. Note that all checks are case-insensitive. - -1) If ``format`` contains the word ``epoch``, the time is returned - in seconds after the UNIX epoch (1970-01-01 00:00:00 UTC). - The return value is always an integer. - -2) If ``format`` contains any of the words ``year``, ``month``, - ``day``, ``hour``, ``min``, or ``sec``, only the selected parts are - returned. The order of the returned parts is always the one - in the previous sentence and the order of words in ``format`` - is not significant. The parts are returned as zero-padded - strings (e.g. May -> ``05``). - -3) Otherwise (and by default) the time is returned as a - timestamp string in the format ``2006-02-24 15:08:31``. - -By default this keyword returns the current local time, but -that can be altered using ``time`` argument as explained below. -Note that all checks involving strings are case-insensitive. - -1) If ``time`` is a number, or a string that can be converted to - a number, it is interpreted as seconds since the UNIX epoch. - This documentation was originally written about 1177654467 - seconds after the epoch. - -2) If ``time`` is a timestamp, that time will be used. Valid - timestamp formats are ``YYYY-MM-DD hh:mm:ss`` and - ``YYYYMMDD hhmmss``. - -3) If ``time`` is equal to ``NOW`` (default), the current local - time is used. - -4) If ``time`` is equal to ``UTC``, the current time in - [http://en.wikipedia.org/wiki/Coordinated_Universal_Time|UTC] - is used. - -5) If ``time`` is in the format like ``NOW - 1 day`` or ``UTC + 1 hour - 30 min``, the current local/UTC time plus/minus the time - specified with the time string is used. The time string format - is described in an appendix of Robot Framework User Guide. - -Examples (expecting the current local time is 2006-03-29 15:06:21): -| ${time} = | Get Time | | | | -| ${secs} = | Get Time | epoch | | | -| ${year} = | Get Time | return year | | | -| ${yyyy} | ${mm} | ${dd} = | Get Time | year,month,day | -| @{time} = | Get Time | year month day hour min sec | | | -| ${y} | ${s} = | Get Time | seconds and year | | -=> -| ${time} = '2006-03-29 15:06:21' -| ${secs} = 1143637581 -| ${year} = '2006' -| ${yyyy} = '2006', ${mm} = '03', ${dd} = '29' -| @{time} = ['2006', '03', '29', '15', '06', '21'] -| ${y} = '2006' -| ${s} = '21' - -Examples (expecting the current local time is 2006-03-29 15:06:21 and -UTC time is 2006-03-29 12:06:21): -| ${time} = | Get Time | | 1177654467 | # Time given as epoch seconds | -| ${secs} = | Get Time | sec | 2007-04-27 09:14:27 | # Time given as a timestamp | -| ${year} = | Get Time | year | NOW | # The local time of execution | -| @{time} = | Get Time | hour min sec | NOW + 1h 2min 3s | # 1h 2min 3s added to the local time | -| @{utc} = | Get Time | hour min sec | UTC | # The UTC time of execution | -| ${hour} = | Get Time | hour | UTC - 1 hour | # 1h subtracted from the UTC time | -=> -| ${time} = '2007-04-27 09:14:27' -| ${secs} = 27 -| ${year} = '2006' -| @{time} = ['16', '08', '24'] -| @{utc} = ['12', '06', '21'] -| ${hour} = '11' - - - - - -name -default=None - -Returns variable value or ``default`` if the variable does not exist. - -The name of the variable can be given either as a normal variable name -(e.g. ``${NAME}``) or in escaped format (e.g. ``\${NAME}``). Notice -that the former has some limitations explained in `Set Suite Variable`. - -Examples: -| ${x} = | Get Variable Value | ${a} | default | -| ${y} = | Get Variable Value | ${a} | ${b} | -| ${z} = | Get Variable Value | ${z} | | -=> -| ${x} gets value of ${a} if ${a} exists and string 'default' otherwise -| ${y} gets value of ${a} if ${a} exists and value of ${b} otherwise -| ${z} is set to Python None if it does not exist previously - -See `Set Variable If` for another keyword to set variables dynamically. - - - - - -no_decoration=False - -Returns a dictionary containing all variables in the current scope. - -Variables are returned as a special dictionary that allows accessing -variables in space, case, and underscore insensitive manner similarly -as accessing variables in the test data. This dictionary supports all -same operations as normal Python dictionaries and, for example, -Collections library can be used to access or modify it. Modifying the -returned dictionary has no effect on the variables available in the -current scope. - -By default variables are returned with ``${}``, ``@{}`` or ``&{}`` -decoration based on variable types. Giving a true value (see `Boolean -arguments`) to the optional argument ``no_decoration`` will return -the variables without the decoration. This option is new in Robot -Framework 2.9. - -Example: -| ${example_variable} = | Set Variable | example value | -| ${variables} = | Get Variables | | -| Dictionary Should Contain Key | ${variables} | \${example_variable} | -| Dictionary Should Contain Key | ${variables} | \${ExampleVariable} | -| Set To Dictionary | ${variables} | \${name} | value | -| Variable Should Not Exist | \${name} | | | -| ${no decoration} = | Get Variables | no_decoration=Yes | -| Dictionary Should Contain Key | ${no decoration} | example_variable | - - - - - -name -*args - -Imports a library with the given name and optional arguments. - -This functionality allows dynamic importing of libraries while tests -are running. That may be necessary, if the library itself is dynamic -and not yet available when test data is processed. In a normal case, -libraries should be imported using the Library setting in the Setting -table. - -This keyword supports importing libraries both using library -names and physical paths. When paths are used, they must be -given in absolute format or found from -[http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#pythonpath-jythonpath-and-ironpythonpath| -search path]. Forward slashes can be used as path separators in all -operating systems. - -It is possible to pass arguments to the imported library and also -named argument syntax works if the library supports it. ``WITH NAME`` -syntax can be used to give a custom name to the imported library. - -Examples: -| Import Library | MyLibrary | -| Import Library | ${CURDIR}/../Library.py | arg1 | named=arg2 | -| Import Library | ${LIBRARIES}/Lib.java | arg | WITH NAME | JavaLib | - - - - - -path - -Imports a resource file with the given path. - -Resources imported with this keyword are set into the test suite scope -similarly when importing them in the Setting table using the Resource -setting. - -The given path must be absolute or found from -[http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#pythonpath-jythonpath-and-ironpythonpath| -search path]. Forward slashes can be used as path separator regardless -the operating system. - -Examples: -| Import Resource | ${CURDIR}/resource.txt | -| Import Resource | ${CURDIR}/../resources/resource.html | -| Import Resource | found_from_pythonpath.robot | - - - - - -path -*args - -Imports a variable file with the given path and optional arguments. - -Variables imported with this keyword are set into the test suite scope -similarly when importing them in the Setting table using the Variables -setting. These variables override possible existing variables with -the same names. This functionality can thus be used to import new -variables, for example, for each test in a test suite. - -The given path must be absolute or found from -[http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#pythonpath-jythonpath-and-ironpythonpath| -search path]. Forward slashes can be used as path separator regardless -the operating system. - -Examples: -| Import Variables | ${CURDIR}/variables.py | | | -| Import Variables | ${CURDIR}/../vars/env.py | arg1 | arg2 | -| Import Variables | file_from_pythonpath.py | | | - - - - - -name -msg=None - -Fails unless the given keyword exists in the current scope. - -Fails also if there are more than one keywords with the same name. -Works both with the short name (e.g. ``Log``) and the full name -(e.g. ``BuiltIn.Log``). - -The default error message can be overridden with the ``msg`` argument. - -See also `Variable Should Exist`. - - - - - -item -length -msg=None - -Verifies that the length of the given item is correct. - -The length of the item is got using the `Get Length` keyword. The -default error message can be overridden with the ``msg`` argument. - - - - - -message -level=INFO -html=False -console=False -repr=False -formatter=str - -Logs the given message with the given level. - -Valid levels are TRACE, DEBUG, INFO (default), HTML, WARN, and ERROR. -Messages below the current active log level are ignored. See -`Set Log Level` keyword and ``--loglevel`` command line option -for more details about setting the level. - -Messages logged with the WARN or ERROR levels will be automatically -visible also in the console and in the Test Execution Errors section -in the log file. - -If the ``html`` argument is given a true value (see `Boolean -arguments`), the message will be considered HTML and special characters -such as ``<`` are not escaped. For example, logging -``<img src="image.png">`` creates an image when ``html`` is true, but -otherwise the message is that exact string. An alternative to using -the ``html`` argument is using the HTML pseudo log level. It logs -the message as HTML using the INFO level. - -If the ``console`` argument is true, the message will be written to -the console where test execution was started from in addition to -the log file. This keyword always uses the standard output stream -and adds a newline after the written message. Use `Log To Console` -instead if either of these is undesirable, - -The ``formatter`` argument controls how to format the string -representation of the message. Possible values are ``str`` (default), -``repr`` and ``ascii``, and they work similarly to Python built-in -functions with same names. When using ``repr``, bigger lists, -dictionaries and other containers are also pretty-printed so that -there is one item per row. For more details see `String -representations`. This is a new feature in Robot Framework 3.1.2. - -The old way to control string representation was using the ``repr`` -argument, and ``repr=True`` is still equivalent to using -``formatter=repr``. The ``repr`` argument will be deprecated in the -future, though, and using ``formatter`` is thus recommended. - -Examples: -| Log | Hello, world! | | | # Normal INFO message. | -| Log | Warning, world! | WARN | | # Warning. | -| Log | <b>Hello</b>, world! | html=yes | | # INFO message as HTML. | -| Log | <b>Hello</b>, world! | HTML | | # Same as above. | -| Log | <b>Hello</b>, world! | DEBUG | html=true | # DEBUG as HTML. | -| Log | Hello, console! | console=yes | | # Log also to the console. | -| Log | Null is \x00 | formatter=repr | | # Log ``'Null is \x00'``. | - -See `Log Many` if you want to log multiple messages in one go, and -`Log To Console` if you only want to write to the console. - - - - - -*messages - -Logs the given messages as separate entries using the INFO level. - -Supports also logging list and dictionary variable items individually. - -Examples: -| Log Many | Hello | ${var} | -| Log Many | @{list} | &{dict} | - -See `Log` and `Log To Console` keywords if you want to use alternative -log levels, use HTML, or log to the console. - - - - - -message -stream=STDOUT -no_newline=False - -Logs the given message to the console. - -By default uses the standard output stream. Using the standard error -stream is possibly by giving the ``stream`` argument value ``STDERR`` -(case-insensitive). - -By default appends a newline to the logged message. This can be -disabled by giving the ``no_newline`` argument a true value (see -`Boolean arguments`). - -Examples: -| Log To Console | Hello, console! | | -| Log To Console | Hello, stderr! | STDERR | -| Log To Console | Message starts here and is | no_newline=true | -| Log To Console | continued without newline. | | - -This keyword does not log the message to the normal log file. Use -`Log` keyword, possibly with argument ``console``, if that is desired. - - - - - -level=INFO - -Logs all variables in the current scope with given log level. - - - - - - -Does absolutely nothing. - - - - - -message -*tags - -Skips rest of the current test, setup, or teardown with PASS status. - -This keyword can be used anywhere in the test data, but the place where -used affects the behavior: - -- When used in any setup or teardown (suite, test or keyword), passes - that setup or teardown. Possible keyword teardowns of the started - keywords are executed. Does not affect execution or statuses - otherwise. -- When used in a test outside setup or teardown, passes that particular - test case. Possible test and keyword teardowns are executed. - -Possible continuable failures before this keyword is used, as well as -failures in executed teardowns, will fail the execution. - -It is mandatory to give a message explaining why execution was passed. -By default the message is considered plain text, but starting it with -``*HTML*`` allows using HTML formatting. - -It is also possible to modify test tags passing tags after the message -similarly as with `Fail` keyword. Tags starting with a hyphen -(e.g. ``-regression``) are removed and others added. Tags are modified -using `Set Tags` and `Remove Tags` internally, and the semantics -setting and removing them are the same as with these keywords. - -Examples: -| Pass Execution | All features available in this version tested. | -| Pass Execution | Deprecated test. | deprecated | -regression | - -This keyword is typically wrapped to some other keyword, such as -`Run Keyword If`, to pass based on a condition. The most common case -can be handled also with `Pass Execution If`: - -| Run Keyword If | ${rc} < 0 | Pass Execution | Negative values are cool. | -| Pass Execution If | ${rc} < 0 | Negative values are cool. | - -Passing execution in the middle of a test, setup or teardown should be -used with care. In the worst case it leads to tests that skip all the -parts that could actually uncover problems in the tested application. -In cases where execution cannot continue do to external factors, -it is often safer to fail the test case and make it non-critical. - - - - - -condition -message -*tags - -Conditionally skips rest of the current test, setup, or teardown with PASS status. - -A wrapper for `Pass Execution` to skip rest of the current test, -setup or teardown based the given ``condition``. The condition is -evaluated similarly as with `Should Be True` keyword, and ``message`` -and ``*tags`` have same semantics as with `Pass Execution`. - -Example: -| :FOR | ${var} | IN | @{VALUES} | -| | Pass Execution If | '${var}' == 'EXPECTED' | Correct value was found | -| | Do Something | ${var} | - - - - - -*patterns - -Returns each argument string escaped for use as a regular expression. - -This keyword can be used to escape strings to be used with -`Should Match Regexp` and `Should Not Match Regexp` keywords. - -Escaping is done with Python's ``re.escape()`` function. - -Examples: -| ${escaped} = | Regexp Escape | ${original} | -| @{strings} = | Regexp Escape | @{strings} | - - - - - -name_or_instance - -Rechecks what keywords the specified library provides. - -Can be called explicitly in the test data or by a library itself -when keywords it provides have changed. - -The library can be specified by its name or as the active instance of -the library. The latter is especially useful if the library itself -calls this keyword as a method. - -New in Robot Framework 2.9. - - - - - -*tags - -Removes given ``tags`` from the current test or all tests in a suite. - -Tags can be given exactly or using a pattern with ``*``, ``?`` and -``[chars]`` acting as wildcards. See the `Glob patterns` section -for more information. - -This keyword can affect either one test case or all test cases in a -test suite similarly as `Set Tags` keyword. - -The current tags are available as a built-in variable ``@{TEST TAGS}``. - -Example: -| Remove Tags | mytag | something-* | ?ython | - -See `Set Tags` if you want to add certain tags and `Fail` if you want -to fail the test case after setting and/or removing tags. - - - - - -repeat -name -*args - -Executes the specified keyword multiple times. - -``name`` and ``args`` define the keyword that is executed similarly as -with `Run Keyword`. ``repeat`` specifies how many times (as a count) or -how long time (as a timeout) the keyword should be executed. - -If ``repeat`` is given as count, it specifies how many times the -keyword should be executed. ``repeat`` can be given as an integer or -as a string that can be converted to an integer. If it is a string, -it can have postfix ``times`` or ``x`` (case and space insensitive) -to make the expression more explicit. - -If ``repeat`` is given as timeout, it must be in Robot Framework's -time format (e.g. ``1 minute``, ``2 min 3 s``). Using a number alone -(e.g. ``1`` or ``1.5``) does not work in this context. - -If ``repeat`` is zero or negative, the keyword is not executed at -all. This keyword fails immediately if any of the execution -rounds fails. - -Examples: -| Repeat Keyword | 5 times | Go to Previous Page | -| Repeat Keyword | ${var} | Some Keyword | arg1 | arg2 | -| Repeat Keyword | 2 minutes | Some Keyword | arg1 | arg2 | - -Specifying ``repeat`` as a timeout is new in Robot Framework 3.0. - - - - - -text - -Replaces variables in the given text with their current values. - -If the text contains undefined variables, this keyword fails. -If the given ``text`` contains only a single variable, its value is -returned as-is and it can be any object. Otherwise this keyword -always returns a string. - -Example: - -The file ``template.txt`` contains ``Hello ${NAME}!`` and variable -``${NAME}`` has the value ``Robot``. - -| ${template} = | Get File | ${CURDIR}/template.txt | -| ${message} = | Replace Variables | ${template} | -| Should Be Equal | ${message} | Hello Robot! | - - - - - -*return_values - -Returns from the enclosing user keyword. - -This keyword can be used to return from a user keyword with PASS status -without executing it fully. It is also possible to return values -similarly as with the ``[Return]`` setting. For more detailed information -about working with the return values, see the User Guide. - -This keyword is typically wrapped to some other keyword, such as -`Run Keyword If` or `Run Keyword If Test Passed`, to return based -on a condition: - -| Run Keyword If | ${rc} < 0 | Return From Keyword | -| Run Keyword If Test Passed | Return From Keyword | - -It is possible to use this keyword to return from a keyword also inside -a for loop. That, as well as returning values, is demonstrated by the -`Find Index` keyword in the following somewhat advanced example. -Notice that it is often a good idea to move this kind of complicated -logic into a test library. - -| ***** Variables ***** -| @{LIST} = foo baz -| -| ***** Test Cases ***** -| Example -| ${index} = Find Index baz @{LIST} -| Should Be Equal ${index} ${1} -| ${index} = Find Index non existing @{LIST} -| Should Be Equal ${index} ${-1} -| -| ***** Keywords ***** -| Find Index -| [Arguments] ${element} @{items} -| ${index} = Set Variable ${0} -| :FOR ${item} IN @{items} -| \ Run Keyword If '${item}' == '${element}' Return From Keyword ${index} -| \ ${index} = Set Variable ${index + 1} -| Return From Keyword ${-1} # Also [Return] would work here. - -The most common use case, returning based on an expression, can be -accomplished directly with `Return From Keyword If`. See also -`Run Keyword And Return` and `Run Keyword And Return If`. - - - - - -condition -*return_values - -Returns from the enclosing user keyword if ``condition`` is true. - -A wrapper for `Return From Keyword` to return based on the given -condition. The condition is evaluated using the same semantics as -with `Should Be True` keyword. - -Given the same example as in `Return From Keyword`, we can rewrite the -`Find Index` keyword as follows: - -| ***** Keywords ***** -| Find Index -| [Arguments] ${element} @{items} -| ${index} = Set Variable ${0} -| :FOR ${item} IN @{items} -| \ Return From Keyword If '${item}' == '${element}' ${index} -| \ ${index} = Set Variable ${index + 1} -| Return From Keyword ${-1} # Also [Return] would work here. - -See also `Run Keyword And Return` and `Run Keyword And Return If`. - - - - - -name -*args - -Executes the given keyword with the given arguments. - -Because the name of the keyword to execute is given as an argument, it -can be a variable and thus set dynamically, e.g. from a return value of -another keyword or from the command line. - - - - - -name -*args - -Runs the keyword and continues execution even if a failure occurs. - -The keyword name and arguments work as with `Run Keyword`. - -Example: -| Run Keyword And Continue On Failure | Fail | This is a stupid example | -| Log | This keyword is executed | - -The execution is not continued if the failure is caused by invalid syntax, -timeout, or fatal exception. -Since Robot Framework 2.9, variable errors are caught by this keyword. - - - - - -expected_error -name -*args - -Runs the keyword and checks that the expected error occurred. - -The keyword to execute and its arguments are specified using ``name`` -and ``*args`` exactly like with `Run Keyword`. - -The expected error must be given in the same format as in Robot -Framework reports. By default it is interpreted as a glob pattern -with ``*``, ``?`` and ``[chars]`` as wildcards, but starting from -Robot Framework 3.1 that can be changed by using various prefixes -explained in the table below. Prefixes are case-sensitive and they -must be separated from the actual message with a colon and an -optional space like ``PREFIX: Message`` or ``PREFIX:Message``. - -| = Prefix = | = Explanation = | -| ``EQUALS`` | Exact match. Especially useful if the error contains glob wildcards. | -| ``STARTS`` | Error must start with the specified error. | -| ``REGEXP`` | Regular expression match. | -| ``GLOB`` | Same as the default behavior. | - -See the `Pattern matching` section for more information about glob -patterns and regular expressions. - -If the expected error occurs, the error message is returned and it can -be further processed or tested if needed. If there is no error, or the -error does not match the expected error, this keyword fails. - -Examples: -| Run Keyword And Expect Error | My error | Keyword | arg | -| Run Keyword And Expect Error | ValueError: * | Some Keyword | -| Run Keyword And Expect Error | STARTS: ValueError: | Some Keyword | -| Run Keyword And Expect Error | EQUALS:No match for '//input[@type="text"]' | -| ... | Find Element | //input[@type="text"] | -| ${msg} = | Run Keyword And Expect Error | * | -| ... | Keyword | arg1 | arg2 | -| Log To Console | ${msg} | - -Errors caused by invalid syntax, timeouts, or fatal exceptions are not -caught by this keyword. -Since Robot Framework 2.9, variable errors are caught by this keyword. - - - - - -name -*args - -Runs the given keyword with the given arguments and ignores possible error. - -This keyword returns two values, so that the first is either string -``PASS`` or ``FAIL``, depending on the status of the executed keyword. -The second value is either the return value of the keyword or the -received error message. See `Run Keyword And Return Status` If you are -only interested in the execution status. - -The keyword name and arguments work as in `Run Keyword`. See -`Run Keyword If` for a usage example. - -Errors caused by invalid syntax, timeouts, or fatal exceptions are not -caught by this keyword. Otherwise this keyword itself never fails. -Since Robot Framework 2.9, variable errors are caught by this keyword. - - - - - -name -*args - -Runs the specified keyword and returns from the enclosing user keyword. - -The keyword to execute is defined with ``name`` and ``*args`` exactly -like with `Run Keyword`. After running the keyword, returns from the -enclosing user keyword and passes possible return value from the -executed keyword further. Returning from a keyword has exactly same -semantics as with `Return From Keyword`. - -Example: -| `Run Keyword And Return` | `My Keyword` | arg1 | arg2 | -| # Above is equivalent to: | -| ${result} = | `My Keyword` | arg1 | arg2 | -| `Return From Keyword` | ${result} | | | - -Use `Run Keyword And Return If` if you want to run keyword and return -based on a condition. - - - - - -condition -name -*args - -Runs the specified keyword and returns from the enclosing user keyword. - -A wrapper for `Run Keyword And Return` to run and return based on -the given ``condition``. The condition is evaluated using the same -semantics as with `Should Be True` keyword. - -Example: -| `Run Keyword And Return If` | ${rc} > 0 | `My Keyword` | arg1 | arg2 | -| # Above is equivalent to: | -| `Run Keyword If` | ${rc} > 0 | `Run Keyword And Return` | `My Keyword ` | arg1 | arg2 | - -Use `Return From Keyword If` if you want to return a certain value -based on a condition. - - - - - -name -*args - -Runs the given keyword with given arguments and returns the status as a Boolean value. - -This keyword returns Boolean ``True`` if the keyword that is executed -succeeds and ``False`` if it fails. This is useful, for example, in -combination with `Run Keyword If`. If you are interested in the error -message or return value, use `Run Keyword And Ignore Error` instead. - -The keyword name and arguments work as in `Run Keyword`. - -Example: -| ${passed} = | `Run Keyword And Return Status` | Keyword | args | -| `Run Keyword If` | ${passed} | Another keyword | - -Errors caused by invalid syntax, timeouts, or fatal exceptions are not -caught by this keyword. Otherwise this keyword itself never fails. - - - - - -condition -name -*args - -Runs the given keyword with the given arguments, if ``condition`` is true. - -The given ``condition`` is evaluated in Python as explained in -`Evaluating expressions`, and ``name`` and ``*args`` have same -semantics as with `Run Keyword`. - -Example, a simple if/else construct: -| ${status} | ${value} = | `Run Keyword And Ignore Error` | `My Keyword` | -| `Run Keyword If` | '${status}' == 'PASS' | `Some Action` | arg | -| `Run Keyword Unless` | '${status}' == 'PASS' | `Another Action` | - -In this example, only either `Some Action` or `Another Action` is -executed, based on the status of `My Keyword`. Instead of `Run Keyword -And Ignore Error` you can also use `Run Keyword And Return Status`. - -Variables used like ``${variable}``, as in the examples above, are -replaced in the expression before evaluation. Variables are also -available in the evaluation namespace and can be accessed using special -syntax ``$variable``. This is a new feature in Robot Framework 2.9 -and it is explained more thoroughly in `Evaluating expressions`. - -Example: -| `Run Keyword If` | $result is None or $result == 'FAIL' | `Keyword` | - -This keyword supports also optional ELSE and ELSE IF branches. Both -of them are defined in ``*args`` and must use exactly format ``ELSE`` -or ``ELSE IF``, respectively. ELSE branches must contain first the -name of the keyword to execute and then its possible arguments. ELSE -IF branches must first contain a condition, like the first argument -to this keyword, and then the keyword to execute and its possible -arguments. It is possible to have ELSE branch after ELSE IF and to -have multiple ELSE IF branches. Nested `Run Keyword If` usage is not -supported when using ELSE and/or ELSE IF branches. - -Given previous example, if/else construct can also be created like this: -| ${status} | ${value} = | `Run Keyword And Ignore Error` | `My Keyword` | -| `Run Keyword If` | '${status}' == 'PASS' | `Some Action` | arg | ELSE | `Another Action` | - -The return value of this keyword is the return value of the actually -executed keyword or Python ``None`` if no keyword was executed (i.e. -if ``condition`` was false). Hence, it is recommended to use ELSE -and/or ELSE IF branches to conditionally assign return values from -keyword to variables (see `Set Variable If` if you need to set fixed -values conditionally). This is illustrated by the example below: - -| ${var1} = | `Run Keyword If` | ${rc} == 0 | `Some keyword returning a value` | -| ... | ELSE IF | 0 < ${rc} < 42 | `Another keyword` | -| ... | ELSE IF | ${rc} < 0 | `Another keyword with args` | ${rc} | arg2 | -| ... | ELSE | `Final keyword to handle abnormal cases` | ${rc} | -| ${var2} = | `Run Keyword If` | ${condition} | `Some keyword` | - -In this example, ${var2} will be set to ``None`` if ${condition} is -false. - -Notice that ``ELSE`` and ``ELSE IF`` control words must be used -explicitly and thus cannot come from variables. If you need to use -literal ``ELSE`` and ``ELSE IF`` strings as arguments, you can escape -them with a backslash like ``\ELSE`` and ``\ELSE IF``. - -Python's [http://docs.python.org/library/os.html|os] and -[http://docs.python.org/library/sys.html|sys] modules are -automatically imported when evaluating the ``condition``. -Attributes they contain can thus be used in the condition: - -| `Run Keyword If` | os.sep == '/' | `Unix Keyword` | -| ... | ELSE IF | sys.platform.startswith('java') | `Jython Keyword` | -| ... | ELSE | `Windows Keyword` | - - - - - -name -*args - -Runs the given keyword with the given arguments, if all critical tests passed. - -This keyword can only be used in suite teardown. Trying to use it in -any other place will result in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - - - - - -name -*args - -Runs the given keyword with the given arguments, if all tests passed. - -This keyword can only be used in a suite teardown. Trying to use it -anywhere else results in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - - - - - -name -*args - -Runs the given keyword with the given arguments, if any critical tests failed. - -This keyword can only be used in a suite teardown. Trying to use it -anywhere else results in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - - - - - -name -*args - -Runs the given keyword with the given arguments, if one or more tests failed. - -This keyword can only be used in a suite teardown. Trying to use it -anywhere else results in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - - - - - -name -*args - -Runs the given keyword with the given arguments, if the test failed. - -This keyword can only be used in a test teardown. Trying to use it -anywhere else results in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - -Prior to Robot Framework 2.9 failures in test teardown itself were -not detected by this keyword. - - - - - -name -*args - -Runs the given keyword with the given arguments, if the test passed. - -This keyword can only be used in a test teardown. Trying to use it -anywhere else results in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - -Prior to Robot Framework 2.9 failures in test teardown itself were -not detected by this keyword. - - - - - -name -*args - -Runs the given keyword if either a test or a keyword timeout has occurred. - -This keyword can only be used in a test teardown. Trying to use it -anywhere else results in an error. - -Otherwise, this keyword works exactly like `Run Keyword`, see its -documentation for more details. - - - - - -condition -name -*args - -Runs the given keyword with the given arguments if ``condition`` is false. - -See `Run Keyword If` for more information and an example. Notice that -this keyword does not support ``ELSE`` or ``ELSE IF`` branches like -`Run Keyword If` does, though. - - - - - -*keywords - -Executes all the given keywords in a sequence. - -This keyword is mainly useful in setups and teardowns when they need -to take care of multiple actions and creating a new higher level user -keyword would be an overkill. - -By default all arguments are expected to be keywords to be executed. - -Examples: -| `Run Keywords` | `Initialize database` | `Start servers` | `Clear logs` | -| `Run Keywords` | ${KW 1} | ${KW 2} | -| `Run Keywords` | @{KEYWORDS} | - -Keywords can also be run with arguments using upper case ``AND`` as -a separator between keywords. The keywords are executed so that the -first argument is the first keyword and proceeding arguments until -the first ``AND`` are arguments to it. First argument after the first -``AND`` is the second keyword and proceeding arguments until the next -``AND`` are its arguments. And so on. - -Examples: -| `Run Keywords` | `Initialize database` | db1 | AND | `Start servers` | server1 | server2 | -| `Run Keywords` | `Initialize database` | ${DB NAME} | AND | `Start servers` | @{SERVERS} | AND | `Clear logs` | -| `Run Keywords` | ${KW} | AND | @{KW WITH ARGS} | - -Notice that the ``AND`` control argument must be used explicitly and -cannot itself come from a variable. If you need to use literal ``AND`` -string as argument, you can either use variables or escape it with -a backslash like ``\AND``. - - - - - -name -*values - -Makes a variable available globally in all tests and suites. - -Variables set with this keyword are globally available in all -subsequent test suites, test cases and user keywords. Also variables -in variable tables are overridden. Variables assigned locally based -on keyword return values or by using `Set Test Variable` and -`Set Suite Variable` override these variables in that scope, but -the global value is not changed in those cases. - -In practice setting variables with this keyword has the same effect -as using command line options ``--variable`` and ``--variablefile``. -Because this keyword can change variables everywhere, it should be -used with care. - -See `Set Suite Variable` for more information and examples. - - - - - -*search_order - -Sets the resolution order to use when a name matches multiple keywords. - -The library search order is used to resolve conflicts when a keyword -name in the test data matches multiple keywords. The first library -(or resource, see below) containing the keyword is selected and that -keyword implementation used. If the keyword is not found from any library -(or resource), test executing fails the same way as when the search -order is not set. - -When this keyword is used, there is no need to use the long -``LibraryName.Keyword Name`` notation. For example, instead of -having - -| MyLibrary.Keyword | arg | -| MyLibrary.Another Keyword | -| MyLibrary.Keyword | xxx | - -you can have - -| Set Library Search Order | MyLibrary | -| Keyword | arg | -| Another Keyword | -| Keyword | xxx | - -This keyword can be used also to set the order of keywords in different -resource files. In this case resource names must be given without paths -or extensions like: - -| Set Library Search Order | resource | another_resource | - -*NOTE:* -- The search order is valid only in the suite where this keywords is used. -- Keywords in resources always have higher priority than - keywords in libraries regardless the search order. -- The old order is returned and can be used to reset the search order later. -- Library and resource names in the search order are both case and space - insensitive. - - - - - -level - -Sets the log threshold to the specified level and returns the old level. - -Messages below the level will not logged. The default logging level is -INFO, but it can be overridden with the command line option -``--loglevel``. - -The available levels: TRACE, DEBUG, INFO (default), WARN, ERROR and NONE (no -logging). - - - - - -doc -append=False -top=False - -Sets documentation for the current test suite. - -By default the possible existing documentation is overwritten, but -this can be changed using the optional ``append`` argument similarly -as with `Set Test Message` keyword. - -This keyword sets the documentation of the current suite by default. -If the optional ``top`` argument is given a true value (see `Boolean -arguments`), the documentation of the top level suite is altered -instead. - -The documentation of the current suite is available as a built-in -variable ``${SUITE DOCUMENTATION}``. - - - - - -name -value -append=False -top=False - -Sets metadata for the current test suite. - -By default possible existing metadata values are overwritten, but -this can be changed using the optional ``append`` argument similarly -as with `Set Test Message` keyword. - -This keyword sets the metadata of the current suite by default. -If the optional ``top`` argument is given a true value (see `Boolean -arguments`), the metadata of the top level suite is altered instead. - -The metadata of the current suite is available as a built-in variable -``${SUITE METADATA}`` in a Python dictionary. Notice that modifying this -variable directly has no effect on the actual metadata the suite has. - - - - - -name -*values - -Makes a variable available everywhere within the scope of the current suite. - -Variables set with this keyword are available everywhere within the -scope of the currently executed test suite. Setting variables with this -keyword thus has the same effect as creating them using the Variable -table in the test data file or importing them from variable files. - -Possible child test suites do not see variables set with this keyword -by default. Starting from Robot Framework 2.9, that can be controlled -by using ``children=<option>`` as the last argument. If the specified -``<option>`` is a non-empty string or any other value considered true -in Python, the variable is set also to the child suites. Parent and -sibling suites will never see variables set with this keyword. - -The name of the variable can be given either as a normal variable name -(e.g. ``${NAME}``) or in escaped format as ``\${NAME}`` or ``$NAME``. -Variable value can be given using the same syntax as when variables -are created in the Variable table. - -If a variable already exists within the new scope, its value will be -overwritten. Otherwise a new variable is created. If a variable already -exists within the current scope, the value can be left empty and the -variable within the new scope gets the value within the current scope. - -Examples: -| Set Suite Variable | ${SCALAR} | Hello, world! | -| Set Suite Variable | ${SCALAR} | Hello, world! | children=true | -| Set Suite Variable | @{LIST} | First item | Second item | -| Set Suite Variable | &{DICT} | key=value | foo=bar | -| ${ID} = | Get ID | -| Set Suite Variable | ${ID} | - -To override an existing value with an empty value, use built-in -variables ``${EMPTY}``, ``@{EMPTY}`` or ``&{EMPTY}``: - -| Set Suite Variable | ${SCALAR} | ${EMPTY} | -| Set Suite Variable | @{LIST} | @{EMPTY} | -| Set Suite Variable | &{DICT} | &{EMPTY} | - -*NOTE:* If the variable has value which itself is a variable (escaped -or not), you must always use the escaped format to set the variable: - -Example: -| ${NAME} = | Set Variable | \${var} | -| Set Suite Variable | ${NAME} | value | # Sets variable ${var} | -| Set Suite Variable | \${NAME} | value | # Sets variable ${NAME} | - -This limitation applies also to `Set Test Variable`, `Set Global -Variable`, `Variable Should Exist`, `Variable Should Not Exist` and -`Get Variable Value` keywords. - - - - - -*tags - -Adds given ``tags`` for the current test or all tests in a suite. - -When this keyword is used inside a test case, that test gets -the specified tags and other tests are not affected. - -If this keyword is used in a suite setup, all test cases in -that suite, recursively, gets the given tags. It is a failure -to use this keyword in a suite teardown. - -The current tags are available as a built-in variable ``@{TEST TAGS}``. - -See `Remove Tags` if you want to remove certain tags and `Fail` if -you want to fail the test case after setting and/or removing tags. - - - - - -name -*values - -Makes a variable available everywhere within the scope of the current task. - -This is an alias for `Set Test Variable` that is more applicable when -creating tasks, not tests. New in RF 3.1. - - - - - -doc -append=False - -Sets documentation for the current test case. - -By default the possible existing documentation is overwritten, but -this can be changed using the optional ``append`` argument similarly -as with `Set Test Message` keyword. - -The current test documentation is available as a built-in variable -``${TEST DOCUMENTATION}``. This keyword can not be used in suite -setup or suite teardown. - - - - - -message -append=False - -Sets message for the current test case. - -If the optional ``append`` argument is given a true value (see `Boolean -arguments`), the given ``message`` is added after the possible earlier -message by joining the messages with a space. - -In test teardown this keyword can alter the possible failure message, -but otherwise failures override messages set by this keyword. Notice -that in teardown the message is available as a built-in variable -``${TEST MESSAGE}``. - -It is possible to use HTML format in the message by starting the message -with ``*HTML*``. - -Examples: -| Set Test Message | My message | | -| Set Test Message | is continued. | append=yes | -| Should Be Equal | ${TEST MESSAGE} | My message is continued. | -| Set Test Message | `*`HTML`*` <b>Hello!</b> | | - -This keyword can not be used in suite setup or suite teardown. - - - - - -name -*values - -Makes a variable available everywhere within the scope of the current test. - -Variables set with this keyword are available everywhere within the -scope of the currently executed test case. For example, if you set a -variable in a user keyword, it is available both in the test case level -and also in all other user keywords used in the current test. Other -test cases will not see variables set with this keyword. - -See `Set Suite Variable` for more information and examples. - - - - - -*values - -Returns the given values which can then be assigned to a variables. - -This keyword is mainly used for setting scalar variables. -Additionally it can be used for converting a scalar variable -containing a list to a list variable or to multiple scalar variables. -It is recommended to use `Create List` when creating new lists. - -Examples: -| ${hi} = | Set Variable | Hello, world! | -| ${hi2} = | Set Variable | I said: ${hi} | -| ${var1} | ${var2} = | Set Variable | Hello | world | -| @{list} = | Set Variable | ${list with some items} | -| ${item1} | ${item2} = | Set Variable | ${list with 2 items} | - -Variables created with this keyword are available only in the -scope where they are created. See `Set Global Variable`, -`Set Test Variable` and `Set Suite Variable` for information on how to -set variables so that they are available also in a larger scope. - - - - - -condition -*values - -Sets variable based on the given condition. - -The basic usage is giving a condition and two values. The -given condition is first evaluated the same way as with the -`Should Be True` keyword. If the condition is true, then the -first value is returned, and otherwise the second value is -returned. The second value can also be omitted, in which case -it has a default value None. This usage is illustrated in the -examples below, where ``${rc}`` is assumed to be zero. - -| ${var1} = | Set Variable If | ${rc} == 0 | zero | nonzero | -| ${var2} = | Set Variable If | ${rc} > 0 | value1 | value2 | -| ${var3} = | Set Variable If | ${rc} > 0 | whatever | | -=> -| ${var1} = 'zero' -| ${var2} = 'value2' -| ${var3} = None - -It is also possible to have 'else if' support by replacing the -second value with another condition, and having two new values -after it. If the first condition is not true, the second is -evaluated and one of the values after it is returned based on -its truth value. This can be continued by adding more -conditions without a limit. - -| ${var} = | Set Variable If | ${rc} == 0 | zero | -| ... | ${rc} > 0 | greater than zero | less then zero | -| | -| ${var} = | Set Variable If | -| ... | ${rc} == 0 | zero | -| ... | ${rc} == 1 | one | -| ... | ${rc} == 2 | two | -| ... | ${rc} > 2 | greater than two | -| ... | ${rc} < 0 | less than zero | - -Use `Get Variable Value` if you need to set variables -dynamically based on whether a variable exist or not. - - - - - -item -msg=None - -Verifies that the given item is empty. - -The length of the item is got using the `Get Length` keyword. The -default error message can be overridden with the ``msg`` argument. - - - - - -first -second -msg=None -values=True -ignore_case=False -formatter=str - -Fails if the given objects are unequal. - -Optional ``msg``, ``values`` and ``formatter`` arguments specify how -to construct the error message if this keyword fails: - -- If ``msg`` is not given, the error message is ``<first> != <second>``. -- If ``msg`` is given and ``values`` gets a true value (default), - the error message is ``<msg>: <first> != <second>``. -- If ``msg`` is given and ``values`` gets a false value (see - `Boolean arguments`), the error message is simply ``<msg>``. -- ``formatter`` controls how to format the values. Possible values are - ``str`` (default), ``repr`` and ``ascii``, and they work similarly - as Python built-in functions with same names. See `String - representations` for more details. - -If ``ignore_case`` is given a true value (see `Boolean arguments`) and -both arguments are strings, comparison is done case-insensitively. -If both arguments are multiline strings, this keyword uses -`multiline string comparison`. - -Examples: -| Should Be Equal | ${x} | expected | -| Should Be Equal | ${x} | expected | Custom error message | -| Should Be Equal | ${x} | expected | Custom message | values=False | -| Should Be Equal | ${x} | expected | ignore_case=True | formatter=repr | - -``ignore_case`` and ``formatter`` are new features in Robot Framework -3.0.1 and 3.1.2, respectively. - - - - - -first -second -msg=None -values=True -base=None - -Fails if objects are unequal after converting them to integers. - -See `Convert To Integer` for information how to convert integers from -other bases than 10 using ``base`` argument or ``0b/0o/0x`` prefixes. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``. - -Examples: -| Should Be Equal As Integers | 42 | ${42} | Error message | -| Should Be Equal As Integers | ABCD | abcd | base=16 | -| Should Be Equal As Integers | 0b1011 | 11 | - - - - - -first -second -msg=None -values=True -precision=6 - -Fails if objects are unequal after converting them to real numbers. - -The conversion is done with `Convert To Number` keyword using the -given ``precision``. - -Examples: -| Should Be Equal As Numbers | ${x} | 1.1 | | # Passes if ${x} is 1.1 | -| Should Be Equal As Numbers | 1.123 | 1.1 | precision=1 | # Passes | -| Should Be Equal As Numbers | 1.123 | 1.4 | precision=0 | # Passes | -| Should Be Equal As Numbers | 112.3 | 75 | precision=-2 | # Passes | - -As discussed in the documentation of `Convert To Number`, machines -generally cannot store floating point numbers accurately. Because of -this limitation, comparing floats for equality is problematic and -a correct approach to use depends on the context. This keyword uses -a very naive approach of rounding the numbers before comparing them, -which is both prone to rounding errors and does not work very well if -numbers are really big or small. For more information about comparing -floats, and ideas on how to implement your own context specific -comparison algorithm, see -http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/. - -If you want to avoid possible problems with floating point numbers, -you can implement custom keywords using Python's -[http://docs.python.org/library/decimal.html|decimal] or -[http://docs.python.org/library/fractions.html|fractions] modules. - -See `Should Not Be Equal As Numbers` for a negative version of this -keyword and `Should Be Equal` for an explanation on how to override -the default error message with ``msg`` and ``values``. - - - - - -first -second -msg=None -values=True -ignore_case=False -formatter=str - -Fails if objects are unequal after converting them to strings. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg``, ``values`` and ``formatter``. - -If ``ignore_case`` is given a true value (see `Boolean arguments`), -comparison is done case-insensitively. If both arguments are -multiline strings, this keyword uses `multiline string comparison`. - -Strings are always [http://www.macchiato.com/unicode/nfc-faq| -NFC normalized]. - -``ignore_case`` and ``formatter`` are new features in Robot Framework -3.0.1 and 3.1.2, respectively. - - - - - -condition -msg=None - -Fails if the given condition is not true. - -If ``condition`` is a string (e.g. ``${rc} < 10``), it is evaluated as -a Python expression as explained in `Evaluating expressions` and the -keyword status is decided based on the result. If a non-string item is -given, the status is got directly from its -[http://docs.python.org/library/stdtypes.html#truth|truth value]. - -The default error message (``<condition> should be true``) is not very -informative, but it can be overridden with the ``msg`` argument. - -Examples: -| Should Be True | ${rc} < 10 | -| Should Be True | '${status}' == 'PASS' | # Strings must be quoted | -| Should Be True | ${number} | # Passes if ${number} is not zero | -| Should Be True | ${list} | # Passes if ${list} is not empty | - -Variables used like ``${variable}``, as in the examples above, are -replaced in the expression before evaluation. Variables are also -available in the evaluation namespace and can be accessed using special -syntax ``$variable``. This is a new feature in Robot Framework 2.9 -and it is explained more thoroughly in `Evaluating expressions`. - -Examples: -| Should Be True | $rc < 10 | -| Should Be True | $status == 'PASS' | # Expected string must be quoted | - -`Should Be True` automatically imports Python's -[http://docs.python.org/library/os.html|os] and -[http://docs.python.org/library/sys.html|sys] modules that contain -several useful attributes: - -| Should Be True | os.linesep == '\n' | # Unixy | -| Should Be True | os.linesep == '\r\n' | # Windows | -| Should Be True | sys.platform == 'darwin' | # OS X | -| Should Be True | sys.platform.startswith('java') | # Jython | - - - - - -container -item -msg=None -values=True -ignore_case=False - -Fails if ``container`` does not contain ``item`` one or more times. - -Works with strings, lists, and anything that supports Python's ``in`` -operator. - -See `Should Be Equal` for an explanation on how to override the default -error message with arguments ``msg`` and ``values``. - -If ``ignore_case`` is given a true value (see `Boolean arguments`) and -compared items are strings, it indicates that comparison should be -case-insensitive. If the ``container`` is a list-like object, string -items in it are compared case-insensitively. New option in Robot -Framework 3.0.1. - -Examples: -| Should Contain | ${output} | PASS | -| Should Contain | ${some list} | value | msg=Failure! | values=False | -| Should Contain | ${some list} | value | ignore_case=True | - - - - - -container -*items -**configuration - -Fails if ``container`` does not contain any of the ``*items``. - -Works with strings, lists, and anything that supports Python's ``in`` -operator. - -Supports additional configuration parameters ``msg``, ``values`` -and ``ignore_case``, which have exactly the same semantics as arguments -with same names have with `Should Contain`. These arguments must -always be given using ``name=value`` syntax after all ``items``. - -Note that possible equal signs in ``items`` must be escaped with -a backslash (e.g. ``foo\=bar``) to avoid them to be passed in -as ``**configuration``. - -Examples: -| Should Contain Any | ${string} | substring 1 | substring 2 | -| Should Contain Any | ${list} | item 1 | item 2 | item 3 | -| Should Contain Any | ${list} | item 1 | item 2 | item 3 | ignore_case=True | -| Should Contain Any | ${list} | @{items} | msg=Custom message | values=False | - -New in Robot Framework 3.0.1. - - - - - -item1 -item2 -count -msg=None -ignore_case=False - -Fails if ``item1`` does not contain ``item2`` ``count`` times. - -Works with strings, lists and all objects that `Get Count` works -with. The default error message can be overridden with ``msg`` and -the actual count is always logged. - -If ``ignore_case`` is given a true value (see `Boolean arguments`) and -compared items are strings, it indicates that comparison should be -case-insensitive. If the ``item1`` is a list-like object, string -items in it are compared case-insensitively. New option in Robot -Framework 3.0.1. - -Examples: -| Should Contain X Times | ${output} | hello | 2 | -| Should Contain X Times | ${some list} | value | 3 | ignore_case=True | - - - - - -str1 -str2 -msg=None -values=True -ignore_case=False - -Fails if the string ``str1`` does not end with the string ``str2``. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``, as well as for semantics -of the ``ignore_case`` option. - - - - - -string -pattern -msg=None -values=True -ignore_case=False - -Fails if the given ``string`` does not match the given ``pattern``. - -Pattern matching is similar as matching files in a shell with -``*``, ``?`` and ``[chars]`` acting as wildcards. See the -`Glob patterns` section for more information. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``, as well as for semantics -of the ``ignore_case`` option. - - - - - -string -pattern -msg=None -values=True - -Fails if ``string`` does not match ``pattern`` as a regular expression. - -See the `Regular expressions` section for more information about -regular expressions and how to use then in Robot Framework test data. - -Notice that the given pattern does not need to match the whole string. -For example, the pattern ``ello`` matches the string ``Hello world!``. -If a full match is needed, the ``^`` and ``$`` characters can be used -to denote the beginning and end of the string, respectively. -For example, ``^ello$`` only matches the exact string ``ello``. - -Possible flags altering how the expression is parsed (e.g. -``re.IGNORECASE``, ``re.MULTILINE``) must be embedded to the -pattern like ``(?im)pattern``. The most useful flags are ``i`` -(case-insensitive), ``m`` (multiline mode), ``s`` (dotall mode) -and ``x`` (verbose). - -If this keyword passes, it returns the portion of the string that -matched the pattern. Additionally, the possible captured groups are -returned. - -See the `Should Be Equal` keyword for an explanation on how to override -the default error message with the ``msg`` and ``values`` arguments. - -Examples: -| Should Match Regexp | ${output} | \\d{6} | # Output contains six numbers | -| Should Match Regexp | ${output} | ^\\d{6}$ | # Six numbers and nothing more | -| ${ret} = | Should Match Regexp | Foo: 42 | (?i)foo: \\d+ | -| ${match} | ${group1} | ${group2} = | -| ... | Should Match Regexp | Bar: 43 | (Foo|Bar): (\\d+) | -=> -| ${ret} = 'Foo: 42' -| ${match} = 'Bar: 43' -| ${group1} = 'Bar' -| ${group2} = '43' - - - - - -item -msg=None - -Verifies that the given item is not empty. - -The length of the item is got using the `Get Length` keyword. The -default error message can be overridden with the ``msg`` argument. - - - - - -first -second -msg=None -values=True -ignore_case=False - -Fails if the given objects are equal. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``. - -If ``ignore_case`` is given a true value (see `Boolean arguments`) and -both arguments are strings, comparison is done case-insensitively. -New option in Robot Framework 3.0.1. - - - - - -first -second -msg=None -values=True -base=None - -Fails if objects are equal after converting them to integers. - -See `Convert To Integer` for information how to convert integers from -other bases than 10 using ``base`` argument or ``0b/0o/0x`` prefixes. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``. - -See `Should Be Equal As Integers` for some usage examples. - - - - - -first -second -msg=None -values=True -precision=6 - -Fails if objects are equal after converting them to real numbers. - -The conversion is done with `Convert To Number` keyword using the -given ``precision``. - -See `Should Be Equal As Numbers` for examples on how to use -``precision`` and why it does not always work as expected. See also -`Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``. - - - - - -first -second -msg=None -values=True -ignore_case=False - -Fails if objects are equal after converting them to strings. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``. - -If ``ignore_case`` is given a true value (see `Boolean arguments`), -comparison is done case-insensitively. - -Strings are always [http://www.macchiato.com/unicode/nfc-faq| -NFC normalized]. - -``ignore_case`` is a new feature in Robot Framework 3.0.1. - - - - - -condition -msg=None - -Fails if the given condition is true. - -See `Should Be True` for details about how ``condition`` is evaluated -and how ``msg`` can be used to override the default error message. - - - - - -container -item -msg=None -values=True -ignore_case=False - -Fails if ``container`` contains ``item`` one or more times. - -Works with strings, lists, and anything that supports Python's ``in`` -operator. - -See `Should Be Equal` for an explanation on how to override the default -error message with arguments ``msg`` and ``values``. ``ignore_case`` -has exactly the same semantics as with `Should Contain`. - -Examples: -| Should Not Contain | ${some list} | value | -| Should Not Contain | ${output} | FAILED | ignore_case=True | - - - - - -container -*items -**configuration - -Fails if ``container`` contains one or more of the ``*items``. - -Works with strings, lists, and anything that supports Python's ``in`` -operator. - -Supports additional configuration parameters ``msg``, ``values`` -and ``ignore_case``, which have exactly the same semantics as arguments -with same names have with `Should Contain`. These arguments must -always be given using ``name=value`` syntax after all ``items``. - -Note that possible equal signs in ``items`` must be escaped with -a backslash (e.g. ``foo\=bar``) to avoid them to be passed in -as ``**configuration``. - -Examples: -| Should Not Contain Any | ${string} | substring 1 | substring 2 | -| Should Not Contain Any | ${list} | item 1 | item 2 | item 3 | -| Should Not Contain Any | ${list} | item 1 | item 2 | item 3 | ignore_case=True | -| Should Not Contain Any | ${list} | @{items} | msg=Custom message | values=False | - -New in Robot Framework 3.0.1. - - - - - -str1 -str2 -msg=None -values=True -ignore_case=False - -Fails if the string ``str1`` ends with the string ``str2``. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``, as well as for semantics -of the ``ignore_case`` option. - - - - - -string -pattern -msg=None -values=True -ignore_case=False - -Fails if the given ``string`` matches the given ``pattern``. - -Pattern matching is similar as matching files in a shell with -``*``, ``?`` and ``[chars]`` acting as wildcards. See the -`Glob patterns` section for more information. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``, as well as for semantics -of the ``ignore_case`` option. - - - - - -string -pattern -msg=None -values=True - -Fails if ``string`` matches ``pattern`` as a regular expression. - -See `Should Match Regexp` for more information about arguments. - - - - - -str1 -str2 -msg=None -values=True -ignore_case=False - -Fails if the string ``str1`` starts with the string ``str2``. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``, as well as for semantics -of the ``ignore_case`` option. - - - - - -str1 -str2 -msg=None -values=True -ignore_case=False - -Fails if the string ``str1`` does not start with the string ``str2``. - -See `Should Be Equal` for an explanation on how to override the default -error message with ``msg`` and ``values``, as well as for semantics -of the ``ignore_case`` option. - - - - - -time_ -reason=None - -Pauses the test executed for the given time. - -``time`` may be either a number or a time string. Time strings are in -a format such as ``1 day 2 hours 3 minutes 4 seconds 5milliseconds`` or -``1d 2h 3m 4s 5ms``, and they are fully explained in an appendix of -Robot Framework User Guide. Optional `reason` can be used to explain why -sleeping is necessary. Both the time slept and the reason are logged. - -Examples: -| Sleep | 42 | -| Sleep | 1.5 | -| Sleep | 2 minutes 10 seconds | -| Sleep | 10s | Wait for a reply | - - - - - -name -msg=None - -Fails unless the given variable exists within the current scope. - -The name of the variable can be given either as a normal variable name -(e.g. ``${NAME}``) or in escaped format (e.g. ``\${NAME}``). Notice -that the former has some limitations explained in `Set Suite Variable`. - -The default error message can be overridden with the ``msg`` argument. - -See also `Variable Should Not Exist` and `Keyword Should Exist`. - - - - - -name -msg=None - -Fails if the given variable exists within the current scope. - -The name of the variable can be given either as a normal variable name -(e.g. ``${NAME}``) or in escaped format (e.g. ``\${NAME}``). Notice -that the former has some limitations explained in `Set Suite Variable`. - -The default error message can be overridden with the ``msg`` argument. - -See also `Variable Should Exist` and `Keyword Should Exist`. - - - - - -retry -retry_interval -name -*args - -Runs the specified keyword and retries if it fails. - -``name`` and ``args`` define the keyword that is executed similarly -as with `Run Keyword`. How long to retry running the keyword is -defined using ``retry`` argument either as timeout or count. -``retry_interval`` is the time to wait before trying to run the -keyword again after the previous run has failed. - -If ``retry`` is given as timeout, it must be in Robot Framework's -time format (e.g. ``1 minute``, ``2 min 3 s``, ``4.5``) that is -explained in an appendix of Robot Framework User Guide. If it is -given as count, it must have ``times`` or ``x`` postfix (e.g. -``5 times``, ``10 x``). ``retry_interval`` must always be given in -Robot Framework's time format. - -If the keyword does not succeed regardless of retries, this keyword -fails. If the executed keyword passes, its return value is returned. - -Examples: -| Wait Until Keyword Succeeds | 2 min | 5 sec | My keyword | argument | -| ${result} = | Wait Until Keyword Succeeds | 3x | 200ms | My keyword | - -All normal failures are caught by this keyword. Errors caused by -invalid syntax, test or keyword timeouts, or fatal exceptions (caused -e.g. by `Fatal Error`) are not caught. - -Running the same keyword multiple times inside this keyword can create -lots of output and considerably increase the size of the generated -output files. It is possible to remove unnecessary keywords from -the outputs using ``--RemoveKeywords WUKS`` command line option. - -Support for specifying ``retry`` as a number of times to retry is -a new feature in Robot Framework 2.9. -Since Robot Framework 2.9, variable errors are caught by this keyword. - - - - diff --git a/libspecs/Collections.libspec b/libspecs/Collections.libspec deleted file mode 100644 index 7045e69..0000000 --- a/libspecs/Collections.libspec +++ /dev/null @@ -1,911 +0,0 @@ - - -3.1.2 -global -yes -A test library providing keywords for handling lists and dictionaries. - -``Collections`` is Robot Framework's standard library that provides a -set of keywords for handling Python lists and dictionaries. This -library has keywords, for example, for modifying and getting -values from lists and dictionaries (e.g. `Append To List`, `Get -From Dictionary`) and for verifying their contents (e.g. `Lists -Should Be Equal`, `Dictionary Should Contain Value`). - -= Related keywords in BuiltIn = - -Following keywords in the BuiltIn library can also be used with -lists and dictionaries: - -| = Keyword Name = | = Applicable With = | = Comment = | -| `Create List` | lists | -| `Create Dictionary` | dicts | Was in Collections until RF 2.9. | -| `Get Length` | both | -| `Length Should Be` | both | -| `Should Be Empty` | both | -| `Should Not Be Empty` | both | -| `Should Contain` | both | -| `Should Not Contain` | both | -| `Should Contain X Times` | lists | -| `Should Not Contain X Times` | lists | -| `Get Count` | lists | - -= Using with list-like and dictionary-like objects = - -List keywords that do not alter the given list can also be used -with tuples, and to some extend also with other iterables. -`Convert To List` can be used to convert tuples and other iterables -to Python ``list`` objects. - -Similarly dictionary keywords can, for most parts, be used with other -mappings. `Convert To Dictionary` can be used if real Python ``dict`` -objects are needed. - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is an empty string or equal to ``FALSE``, ``NONE``, ``NO``, ``OFF`` or -``0``, case-insensitively. Keywords verifying something that allow dropping -actual and expected values from the possible error message also consider -string ``no values`` to be false. Other strings are considered true -regardless their value, and other argument types are tested using the same -[http://docs.python.org/library/stdtypes.html#truth|rules as in Python]. - -True examples: -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=True | # Strings are generally true. | -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=yes | # Same as the above. | -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=${TRUE} | # Python ``True`` is true. | -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=${42} | # Numbers other than 0 are true. | - -False examples: -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=False | # String ``false`` is false. | -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=no | # Also string ``no`` is false. | -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=${EMPTY} | # Empty string is false. | -| `Should Contain Match` | ${list} | ${pattern} | case_insensitive=${FALSE} | # Python ``False`` is false. | -| `Lists Should Be Equal` | ${x} | ${y} | Custom error | values=no values | # ``no values`` works with ``values`` argument | - -Considering string ``NONE`` false is new in Robot Framework 3.0.3 and -considering also ``OFF`` and ``0`` false is new in Robot Framework 3.1. - -= Data in examples = - -List related keywords use variables in format ``${Lx}`` in their examples. -They mean lists with as many alphabetic characters as specified by ``x``. -For example, ``${L1}`` means ``['a']`` and ``${L3}`` means -``['a', 'b', 'c']``. - -Dictionary keywords use similar ``${Dx}`` variables. For example, ``${D1}`` -means ``{'a': 1}`` and ``${D3}`` means ``{'a': 1, 'b': 2, 'c': 3}``. - - -list_ -*values - -Adds ``values`` to the end of ``list``. - -Example: -| Append To List | ${L1} | xxx | | | -| Append To List | ${L2} | x | y | z | -=> -| ${L1} = ['a', 'xxx'] -| ${L2} = ['a', 'b', 'x', 'y', 'z'] - - - - - -*lists - -Combines the given ``lists`` together and returns the result. - -The given lists are not altered by this keyword. - -Example: -| ${x} = | Combine List | ${L1} | ${L2} | | -| ${y} = | Combine List | ${L1} | ${L2} | ${L1} | -=> -| ${x} = ['a', 'a', 'b'] -| ${y} = ['a', 'a', 'b', 'a'] -| ${L1} and ${L2} are not changed. - - - - - -item - -Converts the given ``item`` to a Python ``dict`` type. - -Mainly useful for converting other mappings to normal dictionaries. -This includes converting Robot Framework's own ``DotDict`` instances -that it uses if variables are created using the ``&{var}`` syntax. - -Use `Create Dictionary` from the BuiltIn library for constructing new -dictionaries. - -New in Robot Framework 2.9. - - - - - -item - -Converts the given ``item`` to a Python ``list`` type. - -Mainly useful for converting tuples and other iterable to lists. -Use `Create List` from the BuiltIn library for constructing new lists. - - - - - -dictionary -deepcopy=False - -Returns a copy of the given dictionary. - -The ``deepcopy`` argument controls should the returned dictionary be -a [https://docs.python.org/library/copy.html|shallow or deep copy]. -By default returns a shallow copy, but that can be changed by giving -``deepcopy`` a true value (see `Boolean arguments`). This is a new -option in Robot Framework 3.1.2. Earlier versions always returned -shallow copies. - -The given dictionary is never altered by this keyword. - - - - - -list_ -deepcopy=False - -Returns a copy of the given list. - -If the optional ``deepcopy`` is given a true value, the returned -list is a deep copy. New option in Robot Framework 3.1.2. - -The given list is never altered by this keyword. - - - - - -list_ -value -start=0 -end=None - -Returns the number of occurrences of the given ``value`` in ``list``. - -The search can be narrowed to the selected sublist by the ``start`` and -``end`` indexes having the same semantics as with `Get Slice From List` -keyword. The given list is never altered by this keyword. - -Example: -| ${x} = | Count Values In List | ${L3} | b | -=> -| ${x} = 1 -| ${L3} is not changed - - - - - -dict1 -dict2 -msg=None -values=True - -Fails if the given dictionaries are not equal. - -First the equality of dictionaries' keys is checked and after that all -the key value pairs. If there are differences between the values, those -are listed in the error message. The types of the dictionaries do not -need to be same. - -See `Lists Should Be Equal` for more information about configuring -the error message with ``msg`` and ``values`` arguments. - - - - - -dictionary -key -value -msg=None - -An item of ``key`` / ``value`` must be found in a ``dictionary``. - -Value is converted to unicode for comparison. - -Use the ``msg`` argument to override the default error message. - - - - - -dictionary -key -msg=None - -Fails if ``key`` is not found from ``dictionary``. - -Use the ``msg`` argument to override the default error message. - - - - - -dict1 -dict2 -msg=None -values=True - -Fails unless all items in ``dict2`` are found from ``dict1``. - -See `Lists Should Be Equal` for more information about configuring -the error message with ``msg`` and ``values`` arguments. - - - - - -dictionary -value -msg=None - -Fails if ``value`` is not found from ``dictionary``. - -Use the ``msg`` argument to override the default error message. - - - - - -dictionary -key -msg=None - -Fails if ``key`` is found from ``dictionary``. - -Use the ``msg`` argument to override the default error message. - - - - - -dictionary -value -msg=None - -Fails if ``value`` is found from ``dictionary``. - -Use the ``msg`` argument to override the default error message. - - - - - -dictionary -sort_keys=True - -Returns items of the given ``dictionary`` as a list. - -Uses `Get Dictionary Keys` to get keys and then returns corresponding -items. By default keys are sorted and items returned in that order, -but this can be changed by giving ``sort_keys`` a false value (see -`Boolean arguments`). Notice that with Python 3.5 and earlier -dictionary order is undefined unless using ordered dictionaries. - -Items are returned as a flat list so that first item is a key, -second item is a corresponding value, third item is the second key, -and so on. - -The given ``dictionary`` is never altered by this keyword. - -Example: -| ${sorted} = | Get Dictionary Items | ${D3} | -| ${unsorted} = | Get Dictionary Items | ${D3} | sort_keys=False | -=> -| ${sorted} = ['a', 1, 'b', 2, 'c', 3] -| ${unsorted} = ['b', 2, 'a', 1, 'c', 3] # Order depends on Python version. - -``sort_keys`` is a new option in Robot Framework 3.1.2. Earlier items -were always sorted based on keys. - - - - - -dictionary -sort_keys=True - -Returns keys of the given ``dictionary`` as a list. - -By default keys are returned in sorted order (assuming they are -sortable), but they can be returned in the original order by giving -``sort_keys`` a false value (see `Boolean arguments`). Notice that -with Python 3.5 and earlier dictionary order is undefined unless using -ordered dictionaries. - -The given ``dictionary`` is never altered by this keyword. - -Example: -| ${sorted} = | Get Dictionary Keys | ${D3} | -| ${unsorted} = | Get Dictionary Keys | ${D3} | sort_keys=False | -=> -| ${sorted} = ['a', 'b', 'c'] -| ${unsorted} = ['b', 'a', 'c'] # Order depends on Python version. - -``sort_keys`` is a new option in Robot Framework 3.1.2. Earlier keys -were always sorted. - - - - - -dictionary -sort_keys=True - -Returns values of the given ``dictionary`` as a list. - -Uses `Get Dictionary Keys` to get keys and then returns corresponding -values. By default keys are sorted and values returned in that order, -but this can be changed by giving ``sort_keys`` a false value (see -`Boolean arguments`). Notice that with Python 3.5 and earlier -dictionary order is undefined unless using ordered dictionaries. - -The given ``dictionary`` is never altered by this keyword. - -Example: -| ${sorted} = | Get Dictionary Values | ${D3} | -| ${unsorted} = | Get Dictionary Values | ${D3} | sort_keys=False | -=> -| ${sorted} = [1, 2, 3] -| ${unsorted} = [2, 1, 3] # Order depends on Python version. - -``sort_keys`` is a new option in Robot Framework 3.1.2. Earlier values -were always sorted based on keys. - - - - - -dictionary -key - -Returns a value from the given ``dictionary`` based on the given ``key``. - -If the given ``key`` cannot be found from the ``dictionary``, this -keyword fails. - -The given dictionary is never altered by this keyword. - -Example: -| ${value} = | Get From Dictionary | ${D3} | b | -=> -| ${value} = 2 - - - - - -list_ -index - -Returns the value specified with an ``index`` from ``list``. - -The given list is never altered by this keyword. - -Index ``0`` means the first position, ``1`` the second, and so on. -Similarly, ``-1`` is the last position, ``-2`` the second last, and so on. -Using an index that does not exist on the list causes an error. -The index can be either an integer or a string that can be converted -to an integer. - -Examples (including Python equivalents in comments): -| ${x} = | Get From List | ${L5} | 0 | # L5[0] | -| ${y} = | Get From List | ${L5} | -2 | # L5[-2] | -=> -| ${x} = 'a' -| ${y} = 'd' -| ${L5} is not changed - - - - - -list_ -value -start=0 -end=None - -Returns the index of the first occurrence of the ``value`` on the list. - -The search can be narrowed to the selected sublist by the ``start`` and -``end`` indexes having the same semantics as with `Get Slice From List` -keyword. In case the value is not found, -1 is returned. The given list -is never altered by this keyword. - -Example: -| ${x} = | Get Index From List | ${L5} | d | -=> -| ${x} = 3 -| ${L5} is not changed - - - - - -list -pattern -case_insensitive=False -whitespace_insensitive=False - -Returns the count of matches to ``pattern`` in ``list``. - -For more information on ``pattern``, ``case_insensitive``, and -``whitespace_insensitive``, see `Should Contain Match`. - -Examples: -| ${count}= | Get Match Count | ${list} | a* | # ${count} will be the count of strings beginning with 'a' | -| ${count}= | Get Match Count | ${list} | regexp=a.* | # ${matches} will be the count of strings beginning with 'a' (regexp version) | -| ${count}= | Get Match Count | ${list} | a* | case_insensitive=${True} | # ${matches} will be the count of strings beginning with 'a' or 'A' | - - - - - -list -pattern -case_insensitive=False -whitespace_insensitive=False - -Returns a list of matches to ``pattern`` in ``list``. - -For more information on ``pattern``, ``case_insensitive``, and -``whitespace_insensitive``, see `Should Contain Match`. - -Examples: -| ${matches}= | Get Matches | ${list} | a* | # ${matches} will contain any string beginning with 'a' | -| ${matches}= | Get Matches | ${list} | regexp=a.* | # ${matches} will contain any string beginning with 'a' (regexp version) | -| ${matches}= | Get Matches | ${list} | a* | case_insensitive=${True} | # ${matches} will contain any string beginning with 'a' or 'A' | - - - - - -list_ -start=0 -end=None - -Returns a slice of the given list between ``start`` and ``end`` indexes. - -The given list is never altered by this keyword. - -If both ``start`` and ``end`` are given, a sublist containing values -from ``start`` to ``end`` is returned. This is the same as -``list[start:end]`` in Python. To get all items from the beginning, -use 0 as the start value, and to get all items until and including -the end, use ``None`` (default) as the end value. - -Using ``start`` or ``end`` not found on the list is the same as using -the largest (or smallest) available index. - -Examples (incl. Python equivalents in comments): -| ${x} = | Get Slice From List | ${L5} | 2 | 4 | # L5[2:4] | -| ${y} = | Get Slice From List | ${L5} | 1 | | # L5[1:None] | -| ${z} = | Get Slice From List | ${L5} | | -2 | # L5[0:-2] | -=> -| ${x} = ['c', 'd'] -| ${y} = ['b', 'c', 'd', 'e'] -| ${z} = ['a', 'b', 'c'] -| ${L5} is not changed - - - - - -list_ -index -value - -Inserts ``value`` into ``list`` to the position specified with ``index``. - -Index ``0`` adds the value into the first position, ``1`` to the second, -and so on. Inserting from right works with negative indices so that -``-1`` is the second last position, ``-2`` third last, and so on. Use -`Append To List` to add items to the end of the list. - -If the absolute value of the index is greater than -the length of the list, the value is added at the end -(positive index) or the beginning (negative index). An index -can be given either as an integer or a string that can be -converted to an integer. - -Example: -| Insert Into List | ${L1} | 0 | xxx | -| Insert Into List | ${L2} | ${-1} | xxx | -=> -| ${L1} = ['xxx', 'a'] -| ${L2} = ['a', 'xxx', 'b'] - - - - - -dictionary -*keys - -Keeps the given ``keys`` in the ``dictionary`` and removes all other. - -If the given ``key`` cannot be found from the ``dictionary``, it -is ignored. - -Example: -| Keep In Dictionary | ${D5} | b | x | d | -=> -| ${D5} = {'b': 2, 'd': 4} - - - - - -list1 -list2 -msg=None -values=True - -Fails if not all of the elements in ``list2`` are found in ``list1``. - -The order of values and the number of values are not taken into -account. - -See `Lists Should Be Equal` for more information about configuring -the error message with ``msg`` and ``values`` arguments. - - - - - -list_ -value -msg=None - -Fails if the ``value`` is not found from ``list``. - -Use the ``msg`` argument to override the default error message. - - - - - -list_ -msg=None - -Fails if any element in the ``list`` is found from it more than once. - -The default error message lists all the elements that were found -from the ``list`` multiple times, but it can be overridden by giving -a custom ``msg``. All multiple times found items and their counts are -also logged. - -This keyword works with all iterables that can be converted to a list. -The original iterable is never altered. - - - - - -list_ -value -msg=None - -Fails if the ``value`` is found from ``list``. - -Use the ``msg`` argument to override the default error message. - - - - - -list1 -list2 -msg=None -values=True -names=None - -Fails if given lists are unequal. - -The keyword first verifies that the lists have equal lengths, and then -it checks are all their values equal. Possible differences between the -values are listed in the default error message like ``Index 4: ABC != -Abc``. The types of the lists do not need to be the same. For example, -Python tuple and list with same content are considered equal. - -The error message can be configured using ``msg`` and ``values`` -arguments: -- If ``msg`` is not given, the default error message is used. -- If ``msg`` is given and ``values`` gets a value considered true - (see `Boolean arguments`), the error message starts with the given - ``msg`` followed by a newline and the default message. -- If ``msg`` is given and ``values`` is not given a true value, - the error message is just the given ``msg``. - -Optional ``names`` argument can be used for naming the indices shown in -the default error message. It can either be a list of names matching -the indices in the lists or a dictionary where keys are indices that -need to be named. It is not necessary to name all of the indices. When -using a dictionary, keys can be either integers or strings that can be -converted to integers. - -Examples: -| ${names} = | Create List | First Name | Family Name | Email | -| Lists Should Be Equal | ${people1} | ${people2} | names=${names} | -| ${names} = | Create Dictionary | 0=First Name | 2=Email | -| Lists Should Be Equal | ${people1} | ${people2} | names=${names} | - -If the items in index 2 would differ in the above examples, the error -message would contain a row like ``Index 2 (email): name@foo.com != -name@bar.com``. - - - - - -dictionary -level=INFO - -Logs the size and contents of the ``dictionary`` using given ``level``. - -Valid levels are TRACE, DEBUG, INFO (default), and WARN. - -If you only want to log the size, use keyword `Get Length` from -the BuiltIn library. - - - - - -list_ -level=INFO - -Logs the length and contents of the ``list`` using given ``level``. - -Valid levels are TRACE, DEBUG, INFO (default), and WARN. - -If you only want to the length, use keyword `Get Length` from -the BuiltIn library. - - - - - -dictionary -key -default= - -Pops the given ``key`` from the ``dictionary`` and returns its value. - -By default the keyword fails if the given ``key`` cannot be found from -the ``dictionary``. If optional ``default`` value is given, it will be -returned instead of failing. - -Example: -| ${val}= | Pop From Dictionary | ${D3} | b | -=> -| ${val} = 2 -| ${D3} = {'a': 1, 'c': 3} - -New in Robot Framework 2.9.2. - - - - - -list_ - -Returns a list without duplicates based on the given ``list``. - -Creates and returns a new list that contains all items in the given -list so that one item can appear only once. Order of the items in -the new list is the same as in the original except for missing -duplicates. Number of the removed duplicates is logged. - - - - - -dictionary -*keys - -Removes the given ``keys`` from the ``dictionary``. - -If the given ``key`` cannot be found from the ``dictionary``, it -is ignored. - -Example: -| Remove From Dictionary | ${D3} | b | x | y | -=> -| ${D3} = {'a': 1, 'c': 3} - - - - - -list_ -index - -Removes and returns the value specified with an ``index`` from ``list``. - -Index ``0`` means the first position, ``1`` the second and so on. -Similarly, ``-1`` is the last position, ``-2`` the second last, and so on. -Using an index that does not exist on the list causes an error. -The index can be either an integer or a string that can be converted -to an integer. - -Example: -| ${x} = | Remove From List | ${L2} | 0 | -=> -| ${x} = 'a' -| ${L2} = ['b'] - - - - - -list_ -*values - -Removes all occurrences of given ``values`` from ``list``. - -It is not an error if a value does not exist in the list at all. - -Example: -| Remove Values From List | ${L4} | a | c | e | f | -=> -| ${L4} = ['b', 'd'] - - - - - -list_ - -Reverses the given list in place. - -Note that the given list is changed and nothing is returned. Use -`Copy List` first, if you need to keep also the original order. - -| Reverse List | ${L3} | -=> -| ${L3} = ['c', 'b', 'a'] - - - - - -list_ -index -value - -Sets the value of ``list`` specified by ``index`` to the given ``value``. - -Index ``0`` means the first position, ``1`` the second and so on. -Similarly, ``-1`` is the last position, ``-2`` second last, and so on. -Using an index that does not exist on the list causes an error. -The index can be either an integer or a string that can be converted to -an integer. - -Example: -| Set List Value | ${L3} | 1 | xxx | -| Set List Value | ${L3} | -1 | yyy | -=> -| ${L3} = ['a', 'xxx', 'yyy'] - - - - - -dictionary -*key_value_pairs -**items - -Adds the given ``key_value_pairs`` and ``items`` to the ``dictionary``. - -Giving items as ``key_value_pairs`` means giving keys and values -as separate arguments: - -| Set To Dictionary | ${D1} | key | value | second | ${2} | -=> -| ${D1} = {'a': 1, 'key': 'value', 'second': 2} - -| Set To Dictionary | ${D1} | key=value | second=${2} | - -The latter syntax is typically more convenient to use, but it has -a limitation that keys must be strings. - -If given keys already exist in the dictionary, their values are updated. - - - - - -list -pattern -msg=None -case_insensitive=False -whitespace_insensitive=False - -Fails if ``pattern`` is not found in ``list``. - -By default, pattern matching is similar to matching files in a shell -and is case-sensitive and whitespace-sensitive. In the pattern syntax, -``*`` matches to anything and ``?`` matches to any single character. You -can also prepend ``glob=`` to your pattern to explicitly use this pattern -matching behavior. - -If you prepend ``regexp=`` to your pattern, your pattern will be used -according to the Python -[http://docs.python.org/library/re.html|re module] regular expression -syntax. Important note: Backslashes are an escape character, and must -be escaped with another backslash (e.g. ``regexp=\\d{6}`` to search for -``\d{6}``). See `BuiltIn.Should Match Regexp` for more details. - -If ``case_insensitive`` is given a true value (see `Boolean arguments`), -the pattern matching will ignore case. - -If ``whitespace_insensitive`` is given a true value (see `Boolean -arguments`), the pattern matching will ignore whitespace. - -Non-string values in lists are ignored when matching patterns. - -Use the ``msg`` argument to override the default error message. - -See also ``Should Not Contain Match``. - -Examples: -| Should Contain Match | ${list} | a* | | | # Match strings beginning with 'a'. | -| Should Contain Match | ${list} | regexp=a.* | | | # Same as the above but with regexp. | -| Should Contain Match | ${list} | regexp=\\d{6} | | | # Match strings containing six digits. | -| Should Contain Match | ${list} | a* | case_insensitive=True | | # Match strings beginning with 'a' or 'A'. | -| Should Contain Match | ${list} | ab* | whitespace_insensitive=yes | | # Match strings beginning with 'ab' with possible whitespace ignored. | -| Should Contain Match | ${list} | ab* | whitespace_insensitive=true | case_insensitive=true | # Same as the above but also ignore case. | - - - - - -list -pattern -msg=None -case_insensitive=False -whitespace_insensitive=False - -Fails if ``pattern`` is found in ``list``. - -Exact opposite of `Should Contain Match` keyword. See that keyword -for information about arguments and usage in general. - - - - - -list_ - -Sorts the given list in place. - -Sorting fails if items in the list are not comparable with each others. -On Python 2 most objects are comparable, but on Python 3 comparing, -for example, strings with numbers is not possible. - -Note that the given list is changed and nothing is returned. Use -`Copy List` first, if you need to keep also the original order. - - - - diff --git a/libspecs/DateTime.libspec b/libspecs/DateTime.libspec deleted file mode 100644 index 59e2981..0000000 --- a/libspecs/DateTime.libspec +++ /dev/null @@ -1,512 +0,0 @@ - - -3.1.2 -global -yes -A test library for handling date and time values. - -``DateTime`` is a Robot Framework standard library that supports creating and -converting date and time values (e.g. `Get Current Date`, `Convert Time`), -as well as doing simple calculations with them (e.g. `Subtract Time From Date`, -`Add Time To Time`). It supports dates and times in various formats, and can -also be used by other libraries programmatically. - -= Table of Contents = - -- `Terminology` -- `Date formats` -- `Time formats` -- `Millisecond handling` -- `Programmatic usage` -- `Shortcuts` -- `Keywords` - -= Terminology = - -In the context of this library, ``date`` and ``time`` generally have following -meanings: - -- ``date``: An entity with both date and time components but without any - timezone information. For example, ``2014-06-11 10:07:42``. -- ``time``: A time interval. For example, ``1 hour 20 minutes`` or ``01:20:00``. - -This terminology differs from what Python's standard -[http://docs.python.org/library/datetime.html|datetime] module uses. -Basically its -[http://docs.python.org/library/datetime.html#datetime-objects|datetime] and -[http://docs.python.org/library/datetime.html#timedelta-objects|timedelta] -objects match ``date`` and ``time`` as defined by this library. - -= Date formats = - -Dates can given to and received from keywords in `timestamp`, `custom -timestamp`, `Python datetime` and `epoch time` formats. These formats are -discussed thoroughly in subsequent sections. - -Input format is determined automatically based on the given date except when -using custom timestamps, in which case it needs to be given using -``date_format`` argument. Default result format is timestamp, but it can -be overridden using ``result_format`` argument. - -== Timestamp == - -If a date is given as a string, it is always considered to be a timestamp. -If no custom formatting is given using ``date_format`` argument, the timestamp -is expected to be in [http://en.wikipedia.org/wiki/ISO_8601|ISO 8601] like -format ``YYYY-MM-DD hh:mm:ss.mil``, where any non-digit character can be used -as a separator or separators can be omitted altogether. Additionally, -only the date part is mandatory, all possibly missing time components are -considered to be zeros. - -Dates can also be returned in the same ``YYYY-MM-DD hh:mm:ss.mil`` format by -using ``timestamp`` value with ``result_format`` argument. This is also the -default format that keywords returning dates use. Milliseconds can be excluded -using ``exclude_millis`` as explained in `Millisecond handling` section. - -Examples: -| ${date1} = | Convert Date | 2014-06-11 10:07:42.000 | -| ${date2} = | Convert Date | 20140611 100742 | result_format=timestamp | -| Should Be Equal | ${date1} | ${date2} | -| ${date} = | Convert Date | 20140612 12:57 | exclude_millis=yes | -| Should Be Equal | ${date} | 2014-06-12 12:57:00 | - -== Custom timestamp == - -It is possible to use custom timestamps in both input and output. -The custom format is same as accepted by Python's -[http://docs.python.org/library/datetime.html#strftime-strptime-behavior| -datatime.strptime] function. For example, the default timestamp discussed -in the previous section would match ``%Y-%m-%d %H:%M:%S.%f``. - -When using a custom timestamp in input, it must be specified using -``date_format`` argument. The actual input value must be a string that matches -the specified format exactly. When using a custom timestamp in output, it must -be given using ``result_format`` argument. - -Examples: -| ${date} = | Convert Date | 28.05.2014 12:05 | date_format=%d.%m.%Y %H:%M | -| Should Be Equal | ${date} | 2014-05-28 12:05:00.000 | -| ${date} = | Convert Date | ${date} | result_format=%d.%m.%Y | -| Should Be Equal | ${date} | 28.05.2014 | - -Notice that locale aware directives like ``%b`` do not work correctly with -Jython on non-English locales: http://bugs.jython.org/issue2285 - -== Python datetime == - -Python's standard -[http://docs.python.org/library/datetime.html#datetime-objects|datetime] -objects can be used both in input and output. In input they are recognized -automatically, and in output it is possible to get them by giving ``datetime`` -value to ``result_format`` argument. - -One nice benefit with datetime objects is that they have different time -components available as attributes that can be easily accessed using the -extended variable syntax. - -Examples: -| ${datetime} = | Convert Date | 2014-06-11 10:07:42.123 | datetime | -| Should Be Equal As Integers | ${datetime.year} | 2014 | -| Should Be Equal As Integers | ${datetime.month} | 6 | -| Should Be Equal As Integers | ${datetime.day} | 11 | -| Should Be Equal As Integers | ${datetime.hour} | 10 | -| Should Be Equal As Integers | ${datetime.minute} | 7 | -| Should Be Equal As Integers | ${datetime.second} | 42 | -| Should Be Equal As Integers | ${datetime.microsecond} | 123000 | - -== Epoch time == - -Epoch time is the time in seconds since the -[http://en.wikipedia.org/wiki/Unix_time|UNIX epoch] i.e. 00:00:00.000 (UTC) -1 January 1970. To give a date in epoch time, it must be given as a number -(integer or float), not as a string. To return a date in epoch time, -it is possible to use ``epoch`` value with ``result_format`` argument. -Epoch time is returned as a floating point number. - -Notice that epoch time itself is independent on timezones and thus same -around the world at a certain time. What local time a certain epoch time -matches obviously then depends on the timezone. For example, examples below -were tested in Finland but verifications would fail on other timezones. - -Examples: -| ${date} = | Convert Date | ${1000000000} | -| Should Be Equal | ${date} | 2001-09-09 04:46:40.000 | -| ${date} = | Convert Date | 2014-06-12 13:27:59.279 | epoch | -| Should Be Equal | ${date} | ${1402568879.279} | - -== Earliest supported date == - -The earliest date that is supported depends on the date format and to some -extend on the platform: - -- Timestamps support year 1900 and above. -- Python datetime objects support year 1 and above. -- Epoch time supports 1970 and above on Windows with Python and IronPython. -- On other platforms epoch time supports 1900 and above or even earlier. - -Prior to Robot Framework 2.9.2, all formats had same limitation as epoch time -has nowadays. - -= Time formats = - -Similarly as dates, times can be given to and received from keywords in -various different formats. Supported formats are `number`, `time string` -(verbose and compact), `timer string` and `Python timedelta`. - -Input format for time is always determined automatically based on the input. -Result format is number by default, but it can be customised using -``result_format`` argument. - -== Number == - -Time given as a number is interpreted to be seconds. It can be given -either as an integer or a float, or it can be a string that can be converted -to a number. - -To return a time as a number, ``result_format`` argument must have value -``number``, which is also the default. Returned number is always a float. - -Examples: -| ${time} = | Convert Time | 3.14 | -| Should Be Equal | ${time} | ${3.14} | -| ${time} = | Convert Time | ${time} | result_format=number | -| Should Be Equal | ${time} | ${3.14} | - -== Time string == - -Time strings are strings in format like ``1 minute 42 seconds`` or ``1min 42s``. -The basic idea of this format is having first a number and then a text -specifying what time that number represents. Numbers can be either -integers or floating point numbers, the whole format is case and space -insensitive, and it is possible to add a minus prefix to specify negative -times. The available time specifiers are: - -- ``days``, ``day``, ``d`` -- ``hours``, ``hour``, ``h`` -- ``minutes``, ``minute``, ``mins``, ``min``, ``m`` -- ``seconds``, ``second``, ``secs``, ``sec``, ``s`` -- ``milliseconds``, ``millisecond``, ``millis``, ``ms`` - -When returning a time string, it is possible to select between ``verbose`` -and ``compact`` representations using ``result_format`` argument. The verbose -format uses long specifiers ``day``, ``hour``, ``minute``, ``second`` and -``millisecond``, and adds ``s`` at the end when needed. The compact format uses -shorter specifiers ``d``, ``h``, ``min``, ``s`` and ``ms``, and even drops -the space between the number and the specifier. - -Examples: -| ${time} = | Convert Time | 1 minute 42 seconds | -| Should Be Equal | ${time} | ${102} | -| ${time} = | Convert Time | 4200 | verbose | -| Should Be Equal | ${time} | 1 hour 10 minutes | -| ${time} = | Convert Time | - 1.5 hours | compact | -| Should Be Equal | ${time} | - 1h 30min | - -== Timer string == - -Timer string is a string given in timer like format ``hh:mm:ss.mil``. In this -format both hour and millisecond parts are optional, leading and trailing -zeros can be left out when they are not meaningful, and negative times can -be represented by adding a minus prefix. - -To return a time as timer string, ``result_format`` argument must be given -value ``timer``. Timer strings are by default returned in full ``hh:mm:ss.mil`` -format, but milliseconds can be excluded using ``exclude_millis`` as explained -in `Millisecond handling` section. - -Examples: -| ${time} = | Convert Time | 01:42 | -| Should Be Equal | ${time} | ${102} | -| ${time} = | Convert Time | 01:10:00.123 | -| Should Be Equal | ${time} | ${4200.123} | -| ${time} = | Convert Time | 102 | timer | -| Should Be Equal | ${time} | 00:01:42.000 | -| ${time} = | Convert Time | -101.567 | timer | exclude_millis=yes | -| Should Be Equal | ${time} | -00:01:42 | - -== Python timedelta == - -Python's standard -[http://docs.python.org/library/datetime.html#datetime.timedelta|timedelta] -objects are also supported both in input and in output. In input they are -recognized automatically, and in output it is possible to receive them by -giving ``timedelta`` value to ``result_format`` argument. - -Examples: -| ${timedelta} = | Convert Time | 01:10:02.123 | timedelta | -| Should Be Equal | ${timedelta.total_seconds()} | ${4202.123} | - -= Millisecond handling = - -This library handles dates and times internally using the precision of the -given input. With `timestamp`, `time string`, and `timer string` result -formats seconds are, however, rounded to millisecond accuracy. Milliseconds -may also be included even if there would be none. - -All keywords returning dates or times have an option to leave milliseconds out -by giving a true value to ``exclude_millis`` argument. If the argument is given -as a string, it is considered true unless it is empty or case-insensitively -equal to ``false``, ``none`` or ``no``. Other argument types are tested using -same [http://docs.python.org/library/stdtypes.html#truth|rules as in -Python]. Notice that prior to Robot Framework 2.9, all strings except -the empty string were considered true, and that considering ``none`` false is -new in Robot Framework 3.0.3. - -When milliseconds are excluded, seconds in returned dates and times are -rounded to the nearest full second. With `timestamp` and `timer string` -result formats, milliseconds will also be removed from the returned string -altogether. - -Examples: -| ${date} = | Convert Date | 2014-06-11 10:07:42 | -| Should Be Equal | ${date} | 2014-06-11 10:07:42.000 | -| ${date} = | Convert Date | 2014-06-11 10:07:42.500 | exclude_millis=yes | -| Should Be Equal | ${date} | 2014-06-11 10:07:43 | -| ${dt} = | Convert Date | 2014-06-11 10:07:42.500 | datetime | exclude_millis=yes | -| Should Be Equal | ${dt.second} | ${43} | -| Should Be Equal | ${dt.microsecond} | ${0} | -| ${time} = | Convert Time | 102 | timer | exclude_millis=false | -| Should Be Equal | ${time} | 00:01:42.000 | | -| ${time} = | Convert Time | 102.567 | timer | exclude_millis=true | -| Should Be Equal | ${time} | 00:01:43 | | - -= Programmatic usage = - -In addition to be used as normal library, this library is intended to -provide a stable API for other libraries to use if they want to support -same date and time formats as this library. All the provided keywords -are available as functions that can be easily imported: - -| from robot.libraries.DateTime import convert_time -| -| def example_keyword(timeout): -| seconds = convert_time(timeout) -| # ... - -Additionally helper classes ``Date`` and ``Time`` can be used directly: - -| from robot.libraries.DateTime import Date, Time -| -| def example_keyword(date, interval): -| date = Date(date).convert('datetime') -| interval = Time(interval).convert('number') -| # ... - - -date -time -result_format=timestamp -exclude_millis=False -date_format=None - -Adds time to date and returns the resulting date. - -Arguments: -- ``date:`` Date to add time to in one of the supported - `date formats`. -- ``time:`` Time that is added in one of the supported - `time formats`. -- ``result_format:`` Format of the returned date. -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. -- ``date_format:`` Possible `custom timestamp` format of ``date``. - -Examples: -| ${date} = | Add Time To Date | 2014-05-28 12:05:03.111 | 7 days | -| Should Be Equal | ${date} | 2014-06-04 12:05:03.111 | | -| ${date} = | Add Time To Date | 2014-05-28 12:05:03.111 | 01:02:03:004 | -| Should Be Equal | ${date} | 2014-05-28 13:07:06.115 | - - - - - -time1 -time2 -result_format=number -exclude_millis=False - -Adds time to another time and returns the resulting time. - -Arguments: -- ``time1:`` First time in one of the supported `time formats`. -- ``time2:`` Second time in one of the supported `time formats`. -- ``result_format:`` Format of the returned time. -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. - -Examples: -| ${time} = | Add Time To Time | 1 minute | 42 | -| Should Be Equal | ${time} | ${102} | -| ${time} = | Add Time To Time | 3 hours 5 minutes | 01:02:03 | timer | exclude_millis=yes | -| Should Be Equal | ${time} | 04:07:03 | - - - - - -date -result_format=timestamp -exclude_millis=False -date_format=None - -Converts between supported `date formats`. - -Arguments: -- ``date:`` Date in one of the supported `date formats`. -- ``result_format:`` Format of the returned date. -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. -- ``date_format:`` Specifies possible `custom timestamp` format. - -Examples: -| ${date} = | Convert Date | 20140528 12:05:03.111 | -| Should Be Equal | ${date} | 2014-05-28 12:05:03.111 | -| ${date} = | Convert Date | ${date} | epoch | -| Should Be Equal | ${date} | ${1401267903.111} | -| ${date} = | Convert Date | 5.28.2014 12:05 | exclude_millis=yes | date_format=%m.%d.%Y %H:%M | -| Should Be Equal | ${date} | 2014-05-28 12:05:00 | - - - - - -time -result_format=number -exclude_millis=False - -Converts between supported `time formats`. - -Arguments: -- ``time:`` Time in one of the supported `time formats`. -- ``result_format:`` Format of the returned time. -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. - -Examples: -| ${time} = | Convert Time | 10 seconds | -| Should Be Equal | ${time} | ${10} | -| ${time} = | Convert Time | 1:00:01 | verbose | -| Should Be Equal | ${time} | 1 hour 1 second | -| ${time} = | Convert Time | ${3661.5} | timer | exclude_milles=yes | -| Should Be Equal | ${time} | 01:01:02 | - - - - - -time_zone=local -increment=0 -result_format=timestamp -exclude_millis=False - -Returns current local or UTC time with an optional increment. - -Arguments: -- ``time_zone:`` Get the current time on this time zone. Currently only - ``local`` (default) and ``UTC`` are supported. -- ``increment:`` Optional time increment to add to the returned date in - one of the supported `time formats`. Can be negative. -- ``result_format:`` Format of the returned date (see `date formats`). -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. - -Examples: -| ${date} = | Get Current Date | -| Should Be Equal | ${date} | 2014-06-12 20:00:58.946 | -| ${date} = | Get Current Date | UTC | -| Should Be Equal | ${date} | 2014-06-12 17:00:58.946 | -| ${date} = | Get Current Date | increment=02:30:00 | -| Should Be Equal | ${date} | 2014-06-12 22:30:58.946 | -| ${date} = | Get Current Date | UTC | - 5 hours | -| Should Be Equal | ${date} | 2014-06-12 12:00:58.946 | -| ${date} = | Get Current Date | result_format=datetime | -| Should Be Equal | ${date.year} | ${2014} | -| Should Be Equal | ${date.month} | ${6} | - - - - - -date1 -date2 -result_format=number -exclude_millis=False -date1_format=None -date2_format=None - -Subtracts date from another date and returns time between. - -Arguments: -- ``date1:`` Date to subtract another date from in one of the - supported `date formats`. -- ``date2:`` Date that is subtracted in one of the supported - `date formats`. -- ``result_format:`` Format of the returned time (see `time formats`). -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. -- ``date1_format:`` Possible `custom timestamp` format of ``date1``. -- ``date2_format:`` Possible `custom timestamp` format of ``date2``. - - Examples: -| ${time} = | Subtract Date From Date | 2014-05-28 12:05:52 | 2014-05-28 12:05:10 | -| Should Be Equal | ${time} | ${42} | -| ${time} = | Subtract Date From Date | 2014-05-28 12:05:52 | 2014-05-27 12:05:10 | verbose | -| Should Be Equal | ${time} | 1 day 42 seconds | - - - - - -date -time -result_format=timestamp -exclude_millis=False -date_format=None - -Subtracts time from date and returns the resulting date. - -Arguments: -- ``date:`` Date to subtract time from in one of the supported - `date formats`. -- ``time:`` Time that is subtracted in one of the supported - `time formats`. -- ``result_format:`` Format of the returned date. -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. -- ``date_format:`` Possible `custom timestamp` format of ``date``. - -Examples: -| ${date} = | Subtract Time From Date | 2014-06-04 12:05:03.111 | 7 days | -| Should Be Equal | ${date} | 2014-05-28 12:05:03.111 | -| ${date} = | Subtract Time From Date | 2014-05-28 13:07:06.115 | 01:02:03:004 | -| Should Be Equal | ${date} | 2014-05-28 12:05:03.111 | - - - - - -time1 -time2 -result_format=number -exclude_millis=False - -Subtracts time from another time and returns the resulting time. - -Arguments: -- ``time1:`` Time to subtract another time from in one of - the supported `time formats`. -- ``time2:`` Time to subtract in one of the supported `time formats`. -- ``result_format:`` Format of the returned time. -- ``exclude_millis:`` When set to any true value, rounds and drops - milliseconds as explained in `millisecond handling`. - -Examples: -| ${time} = | Subtract Time From Time | 00:02:30 | 100 | -| Should Be Equal | ${time} | ${50} | -| ${time} = | Subtract Time From Time | ${time} | 1 minute | compact | -| Should Be Equal | ${time} | - 10s | - - - - diff --git a/libspecs/Dialogs.libspec b/libspecs/Dialogs.libspec deleted file mode 100644 index 26f83b6..0000000 --- a/libspecs/Dialogs.libspec +++ /dev/null @@ -1,112 +0,0 @@ - - -3.1.2 -global -yes -A test library providing dialogs for interacting with users. - -``Dialogs`` is Robot Framework's standard library that provides means -for pausing the test execution and getting input from users. The -dialogs are slightly different depending on whether tests are run on -Python, IronPython or Jython but they provide the same functionality. - -Long lines in the provided messages are wrapped automatically. If you want -to wrap lines manually, you can add newlines using the ``\n`` character -sequence. - -The library has a known limitation that it cannot be used with timeouts -on Python. Support for IronPython was added in Robot Framework 2.9.2. - - -message -default_error= - -Pauses test execution until user sets the keyword status. - -User can press either ``PASS`` or ``FAIL`` button. In the latter case execution -fails and an additional dialog is opened for defining the error message. - -``message`` is the instruction shown in the initial dialog and -``default_error`` is the default value shown in the possible error message -dialog. - - - - - -message -*values - -Pauses test execution and asks user to select a value. - -The selected value is returned. Pressing ``Cancel`` fails the keyword. - -``message`` is the instruction shown in the dialog and ``values`` are -the options given to the user. - -Example: -| ${user} = | Get Selection From User | Select user | user1 | user2 | admin | - - - - - -message -*values - -Pauses test execution and asks user to select multiple values. - -The selected values are returned as a list. Selecting no values is OK -and in that case the returned list is empty. Pressing ``Cancel`` fails -the keyword. - -``message`` is the instruction shown in the dialog and ``values`` are -the options given to the user. - -Example: -| ${users} = | Get Selections From User | Select users | user1 | user2 | admin | - -New in Robot Framework 3.1. - - - - - -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/library/stdtypes.html#truth|rules as in Python]. - -Example: -| ${username} = | Get Value From User | Input user name | default | -| ${password} = | Get Value From User | Input password | hidden=yes | - -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. - - - - - -message=Test execution paused. Press OK to continue. - -Pauses test execution until user clicks ``Ok`` button. - -``message`` is the message shown in the dialog. - - - - diff --git a/libspecs/Easter.libspec b/libspecs/Easter.libspec deleted file mode 100644 index 62dcc47..0000000 --- a/libspecs/Easter.libspec +++ /dev/null @@ -1,15 +0,0 @@ - - - -global -yes -Documentation for library ``Easter``. - - -who - - - - - - diff --git a/libspecs/OperatingSystem.libspec b/libspecs/OperatingSystem.libspec deleted file mode 100644 index 81ef82f..0000000 --- a/libspecs/OperatingSystem.libspec +++ /dev/null @@ -1,1150 +0,0 @@ - - -3.1.2 -global -yes -A test library providing keywords for OS related tasks. - -``OperatingSystem`` is Robot Framework's standard library that -enables various operating system related tasks to be performed in -the system where Robot Framework is running. It can, among other -things, execute commands (e.g. `Run`), create and remove files and -directories (e.g. `Create File`, `Remove Directory`), check -whether files or directories exists or contain something -(e.g. `File Should Exist`, `Directory Should Be Empty`) and -manipulate environment variables (e.g. `Set Environment Variable`). - -== Table of contents == - -- `Path separators` -- `Pattern matching` -- `Tilde expansion` -- `Boolean arguments` -- `Example` -- `Shortcuts` -- `Keywords` - -= Path separators = - -Because Robot Framework uses the backslash (``\``) as an escape character -in the test data, using a literal backslash requires duplicating it like -in ``c:\\path\\file.txt``. That can be inconvenient especially with -longer Windows paths, and thus all keywords expecting paths as arguments -convert forward slashes to backslashes automatically on Windows. This also -means that paths like ``${CURDIR}/path/file.txt`` are operating system -independent. - -Notice that the automatic path separator conversion does not work if -the path is only a part of an argument like with `Run` and `Start Process` -keywords. In these cases the built-in variable ``${/}`` that contains -``\`` or ``/``, depending on the operating system, can be used instead. - -= Pattern matching = - -Some keywords allow their arguments to be specified as -[http://en.wikipedia.org/wiki/Glob_(programming)|glob patterns] where: - -| ``*`` | matches any string, even an empty string | -| ``?`` | matches any single character | -| ``[chars]`` | matches one character in the bracket | -| ``[!chars]`` | matches one character not in the bracket | -| ``[a-z]`` | matches one character from the range in the bracket | -| ``[!a-z]`` | matches one character not from the range in the bracket | - -Unless otherwise noted, matching is case-insensitive on -case-insensitive operating systems such as Windows. - -Starting from Robot Framework 2.9.1, globbing is not done if the given path -matches an existing file even if it would contain a glob pattern. - -= Tilde expansion = - -Paths beginning with ``~`` or ``~username`` are expanded to the current or -specified user's home directory, respectively. The resulting path is -operating system dependent, but typically e.g. ``~/robot`` is expanded to -``C:\Users\<user>\robot`` on Windows and ``/home/<user>/robot`` on -Unixes. - -The ``~username`` form does not work on Jython. - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is an empty string or equal to ``FALSE``, ``NONE``, ``NO``, ``OFF`` or -``0``, case-insensitively. Other strings are considered true regardless -their value, and other argument types are tested using the same -[http://docs.python.org/library/stdtypes.html#truth|rules as in Python]. - -True examples: -| `Remove Directory` | ${path} | recursive=True | # Strings are generally true. | -| `Remove Directory` | ${path} | recursive=yes | # Same as the above. | -| `Remove Directory` | ${path} | recursive=${TRUE} | # Python ``True`` is true. | -| `Remove Directory` | ${path} | recursive=${42} | # Numbers other than 0 are true. | - -False examples: -| `Remove Directory` | ${path} | recursive=False | # String ``false`` is false. | -| `Remove Directory` | ${path} | recursive=no | # Also string ``no`` is false. | -| `Remove Directory` | ${path} | recursive=${EMPTY} | # Empty string is false. | -| `Remove Directory` | ${path} | recursive=${FALSE} | # Python ``False`` is false. | - -Considering string ``NONE`` false is new in Robot Framework 3.0.3 and -considering also ``OFF`` and ``0`` false is new in Robot Framework 3.1. - -= Example = - -| =Setting= | =Value= | -| Library | OperatingSystem | - -| =Variable= | =Value= | -| ${PATH} | ${CURDIR}/example.txt | - -| =Test Case= | =Action= | =Argument= | =Argument= | -| Example | Create File | ${PATH} | Some text | -| | File Should Exist | ${PATH} | | -| | Copy File | ${PATH} | ~/file.txt | -| | ${output} = | Run | ${TEMPDIR}${/}script.py arg | - - -name -*values -**config - -Appends given ``values`` to environment variable ``name``. - -If the environment variable already exists, values are added after it, -and otherwise a new environment variable is created. - -Values are, by default, joined together using the operating system -path separator (``;`` on Windows, ``:`` elsewhere). This can be changed -by giving a separator after the values like ``separator=value``. No -other configuration parameters are accepted. - -Examples (assuming ``NAME`` and ``NAME2`` do not exist initially): -| Append To Environment Variable | NAME | first | | -| Should Be Equal | %{NAME} | first | | -| Append To Environment Variable | NAME | second | third | -| Should Be Equal | %{NAME} | first${:}second${:}third | -| Append To Environment Variable | NAME2 | first | separator=- | -| Should Be Equal | %{NAME2} | first | | -| Append To Environment Variable | NAME2 | second | separator=- | -| Should Be Equal | %{NAME2} | first-second | - - - - - -path -content -encoding=UTF-8 - -Appends the given content to the specified file. - -If the file exists, the given text is written to its end. If the file -does not exist, it is created. - -Other than not overwriting possible existing files, this keyword works -exactly like `Create File`. See its documentation for more details -about the usage. - -Note that special encodings ``SYSTEM`` and ``CONSOLE`` only work -with this keyword starting from Robot Framework 3.1.2. - - - - - -source -destination - -Copies the source directory into the destination. - -If the destination exists, the source is copied under it. Otherwise -the destination directory and the possible missing intermediate -directories are created. - - - - - -source -destination - -Copies the source file into the destination. - -Source must be a path to an existing file or a glob pattern (see -`Pattern matching`) that matches exactly one file. How the -destination is interpreted is explained below. - -1) If the destination is an existing file, the source file is copied -over it. - -2) If the destination is an existing directory, the source file is -copied into it. A possible file with the same name as the source is -overwritten. - -3) If the destination does not exist and it ends with a path -separator (``/`` or ``\``), it is considered a directory. That -directory is created and a source file copied into it. -Possible missing intermediate directories are also created. - -4) If the destination does not exist and it does not end with a path -separator, it is considered a file. If the path to the file does not -exist, it is created. - -The resulting destination path is returned since Robot Framework 2.9.2. - -See also `Copy Files`, `Move File`, and `Move Files`. - - - - - -*sources_and_destination - -Copies specified files to the target directory. - -Source files can be given as exact paths and as glob patterns (see -`Pattern matching`). At least one source must be given, but it is -not an error if it is a pattern that does not match anything. - -Last argument must be the destination directory. If the destination -does not exist, it will be created. - -Examples: -| Copy Files | ${dir}/file1.txt | ${dir}/file2.txt | ${dir2} | -| Copy Files | ${dir}/file-*.txt | ${dir2} | | - -See also `Copy File`, `Move File`, and `Move Files`. - - - - - -path -pattern=None - -Wrapper for `Count Items In Directory` returning only directory count. - - - - - -path -pattern=None - -Wrapper for `Count Items In Directory` returning only file count. - - - - - -path -pattern=None - -Returns and logs the number of all items in the given directory. - -The argument ``pattern`` has the same semantics as with `List Directory` -keyword. The count is returned as an integer, so it must be checked e.g. -with the built-in keyword `Should Be Equal As Integers`. - - - - - -path -content - -Creates a binary file with the given content. - -If content is given as a Unicode string, it is first converted to bytes -character by character. All characters with ordinal below 256 can be -used and are converted to bytes with same values. Using characters -with higher ordinal is an error. - -Byte strings, and possible other types, are written to the file as is. - -If the directory for the file does not exist, it is created, along -with missing intermediate directories. - -Examples: -| Create Binary File | ${dir}/example.png | ${image content} | -| Create Binary File | ${path} | \x01\x00\xe4\x00 | - -Use `Create File` if you want to create a text file using a certain -encoding. `File Should Not Exist` can be used to avoid overwriting -existing files. - - - - - -path - -Creates the specified directory. - -Also possible intermediate directories are created. Passes if the -directory already exists, but fails if the path exists and is not -a directory. - - - - - -path -content= -encoding=UTF-8 - -Creates a file with the given content and encoding. - -If the directory where the file is created does not exist, it is -automatically created along with possible missing intermediate -directories. Possible existing file is overwritten. - -On Windows newline characters (``\n``) in content are automatically -converted to Windows native newline sequence (``\r\n``). - -See `Get File` for more information about possible ``encoding`` values, -including special values ``SYSTEM`` and ``CONSOLE``. - -Examples: -| Create File | ${dir}/example.txt | Hello, world! | | -| Create File | ${path} | Hyv\xe4 esimerkki | Latin-1 | -| Create File | /tmp/foo.txt | 3\nlines\nhere\n | SYSTEM | - -Use `Append To File` if you want to append to an existing file -and `Create Binary File` if you need to write bytes without encoding. -`File Should Not Exist` can be used to avoid overwriting existing -files. - -The support for ``SYSTEM`` and ``CONSOLE`` encodings is new in Robot -Framework 3.0. Automatically converting ``\n`` to ``\r\n`` on -Windows is new in Robot Framework 3.1. - - - - - -path -msg=None - -Fails unless the specified directory is empty. - -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails unless the given path points to an existing directory. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails if the specified directory is empty. - -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails if the given path points to an existing file. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -The default error message can be overridden with the ``msg`` argument. - - - - - -path - -Deletes all the content from the given directory. - -Deletes both files and sub-directories, but the specified directory -itself if not removed. Use `Remove Directory` if you want to remove -the whole directory. - - - - - -name -msg=None - -Fails if the specified environment variable is not set. - -The default error message can be overridden with the ``msg`` argument. - - - - - -name -msg=None - -Fails if the specified environment variable is set. - -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails unless the specified file is empty. - -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails unless the given ``path`` points to an existing file. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails if the specified directory is empty. - -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails if the given path points to an existing file. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -The default error message can be overridden with the ``msg`` argument. - - - - - -path - -Returns the contents of a specified file. - -This keyword reads the specified file and returns the contents as is. -See also `Get File`. - - - - - -name -default=None - -Returns the value of an environment variable with the given name. - -If no such environment variable is set, returns the default value, if -given. Otherwise fails the test case. - -Returned variables are automatically decoded to Unicode using -the system encoding. - -Note that you can also access environment variables directly using -the variable syntax ``%{ENV_VAR_NAME}``. - - - - - - -Returns currently available environment variables as a dictionary. - -Both keys and values are decoded to Unicode using the system encoding. -Altering the returned dictionary has no effect on the actual environment -variables. - - - - - -path -encoding=UTF-8 -encoding_errors=strict - -Returns the contents of a specified file. - -This keyword reads the specified file and returns the contents. -Line breaks in content are converted to platform independent form. -See also `Get Binary File`. - -``encoding`` defines the encoding of the file. The default value is -``UTF-8``, which means that UTF-8 and ASCII encoded files are read -correctly. In addition to the encodings supported by the underlying -Python implementation, the following special encoding values can be -used: - -- ``SYSTEM``: Use the default system encoding. -- ``CONSOLE``: Use the console encoding. Outside Windows this is same - as the system encoding. - -``encoding_errors`` argument controls what to do if decoding some bytes -fails. All values accepted by ``decode`` method in Python are valid, but -in practice the following values are most useful: - -- ``strict``: Fail if characters cannot be decoded (default). -- ``ignore``: Ignore characters that cannot be decoded. -- ``replace``: Replace characters that cannot be decoded with - a replacement character. - -Support for ``SYSTEM`` and ``CONSOLE`` encodings in Robot Framework 3.0. - - - - - -path - -Returns and logs file size as an integer in bytes. - - - - - -path -format=timestamp - -Returns the last modification time of a file or directory. - -How time is returned is determined based on the given ``format`` -string as follows. Note that all checks are case-insensitive. -Returned time is also automatically logged. - -1) If ``format`` contains the word ``epoch``, the time is returned - in seconds after the UNIX epoch. The return value is always - an integer. - -2) If ``format`` contains any of the words ``year``, ``month``, - ``day``, ``hour``, ``min`` or ``sec``, only the selected parts are - returned. The order of the returned parts is always the one - in the previous sentence and the order of the words in - ``format`` is not significant. The parts are returned as - zero-padded strings (e.g. May -> ``05``). - -3) Otherwise, and by default, the time is returned as a - timestamp string in the format ``2006-02-24 15:08:31``. - -Examples (when the modified time of ``${CURDIR}`` is -2006-03-29 15:06:21): -| ${time} = | Get Modified Time | ${CURDIR} | -| ${secs} = | Get Modified Time | ${CURDIR} | epoch | -| ${year} = | Get Modified Time | ${CURDIR} | return year | -| ${y} | ${d} = | Get Modified Time | ${CURDIR} | year,day | -| @{time} = | Get Modified Time | ${CURDIR} | year,month,day,hour,min,sec | -=> -- ${time} = '2006-03-29 15:06:21' -- ${secs} = 1143637581 -- ${year} = '2006' -- ${y} = '2006' & ${d} = '29' -- @{time} = ['2006', '03', '29', '15', '06', '21'] - - - - - -path -pattern -encoding=UTF-8 -encoding_errors=strict - -Returns the lines of the specified file that match the ``pattern``. - -This keyword reads a file from the file system using the defined -``path``, ``encoding`` and ``encoding_errors`` similarly as `Get File`. -A difference is that only the lines that match the given ``pattern`` are -returned. Lines are returned as a single string catenated back together -with newlines and the number of matched lines is automatically logged. -Possible trailing newline is never returned. - -A line matches if it contains the ``pattern`` anywhere in it and -it *does not need to match the pattern fully*. The pattern -matching syntax is explained in `introduction`, and in this -case matching is case-sensitive. - -Examples: -| ${errors} = | Grep File | /var/log/myapp.log | ERROR | -| ${ret} = | Grep File | ${CURDIR}/file.txt | [Ww]ildc??d ex*ple | - -If more complex pattern matching is needed, it is possible to use -`Get File` in combination with String library keywords like `Get -Lines Matching Regexp`. - - - - - -base -*parts - -Joins the given path part(s) to the given base path. - -The path separator (``/`` or ``\``) is inserted when needed and -the possible absolute paths handled as expected. The resulted -path is also normalized. - -Examples: -| ${path} = | Join Path | my | path | -| ${p2} = | Join Path | my/ | path/ | -| ${p3} = | Join Path | my | path | my | file.txt | -| ${p4} = | Join Path | my | /path | -| ${p5} = | Join Path | /my/path/ | .. | path2 | -=> -- ${path} = 'my/path' -- ${p2} = 'my/path' -- ${p3} = 'my/path/my/file.txt' -- ${p4} = '/path' -- ${p5} = '/my/path2' - - - - - -base -*paths - -Joins given paths with base and returns resulted paths. - -See `Join Path` for more information. - -Examples: -| @{p1} = | Join Paths | base | example | other | | -| @{p2} = | Join Paths | /my/base | /example | other | | -| @{p3} = | Join Paths | my/base | example/path/ | other | one/more | -=> -- @{p1} = ['base/example', 'base/other'] -- @{p2} = ['/example', '/my/base/other'] -- @{p3} = ['my/base/example/path', 'my/base/other', 'my/base/one/more'] - - - - - -path -pattern=None -absolute=False - -Wrapper for `List Directory` that returns only directories. - - - - - -path -pattern=None -absolute=False - -Returns and logs items in a directory, optionally filtered with ``pattern``. - -File and directory names are returned in case-sensitive alphabetical -order, e.g. ``['A Name', 'Second', 'a lower case name', 'one more']``. -Implicit directories ``.`` and ``..`` are not returned. The returned -items are automatically logged. - -File and directory names are returned relative to the given path -(e.g. ``'file.txt'``) by default. If you want them be returned in -absolute format (e.g. ``'/home/robot/file.txt'``), give the ``absolute`` -argument a true value (see `Boolean arguments`). - -If ``pattern`` is given, only items matching it are returned. The pattern -matching syntax is explained in `introduction`, and in this case -matching is case-sensitive. - -Examples (using also other `List Directory` variants): -| @{items} = | List Directory | ${TEMPDIR} | -| @{files} = | List Files In Directory | /tmp | *.txt | absolute | -| ${count} = | Count Files In Directory | ${CURDIR} | ??? | - - - - - -path -pattern=None -absolute=False - -Wrapper for `List Directory` that returns only files. - - - - - -level=INFO - -Logs all environment variables using the given log level. - -Environment variables are also returned the same way as with -`Get Environment Variables` keyword. - - - - - -path -encoding=UTF-8 -encoding_errors=strict - -Wrapper for `Get File` that also logs the returned file. - -The file is logged with the INFO level. If you want something else, -just use `Get File` and the built-in keyword `Log` with the desired -level. - -See `Get File` for more information about ``encoding`` and -``encoding_errors`` arguments. - - - - - -source -destination - -Moves the source directory into a destination. - -Uses `Copy Directory` keyword internally, and ``source`` and -``destination`` arguments have exactly same semantics as with -that keyword. - - - - - -source -destination - -Moves the source file into the destination. - -Arguments have exactly same semantics as with `Copy File` keyword. -Destination file path is returned since Robot Framework 2.9.2. - -If the source and destination are on the same filesystem, rename -operation is used. Otherwise file is copied to the destination -filesystem and then removed from the original filesystem. - -See also `Move Files`, `Copy File`, and `Copy Files`. - - - - - -*sources_and_destination - -Moves specified files to the target directory. - -Arguments have exactly same semantics as with `Copy Files` keyword. - -See also `Move File`, `Copy File`, and `Copy Files`. - - - - - -path -case_normalize=False - -Normalizes the given path. - -- Collapses redundant separators and up-level references. -- Converts ``/`` to ``\`` on Windows. -- Replaces initial ``~`` or ``~user`` by that user's home directory. - The latter is not supported on Jython. -- If ``case_normalize`` is given a true value (see `Boolean arguments`) - on Windows, converts the path to all lowercase. New in Robot - Framework 3.1. - -Examples: -| ${path1} = | Normalize Path | abc/ | -| ${path2} = | Normalize Path | abc/../def | -| ${path3} = | Normalize Path | abc/./def//ghi | -| ${path4} = | Normalize Path | ~robot/stuff | -=> -- ${path1} = 'abc' -- ${path2} = 'def' -- ${path3} = 'abc/def/ghi' -- ${path4} = '/home/robot/stuff' - -On Windows result would use ``\`` instead of ``/`` and home directory -would be different. - - - - - -path -recursive=False - -Removes the directory pointed to by the given ``path``. - -If the second argument ``recursive`` is given a true value (see -`Boolean arguments`), the directory is removed recursively. Otherwise -removing fails if the directory is not empty. - -If the directory pointed to by the ``path`` does not exist, the keyword -passes, but it fails, if the ``path`` points to a file. - - - - - -*names - -Deletes the specified environment variable. - -Does nothing if the environment variable is not set. - -It is possible to remove multiple variables by passing them to this -keyword as separate arguments. - - - - - -path - -Removes a file with the given path. - -Passes if the file does not exist, but fails if the path does -not point to a regular file (e.g. it points to a directory). - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -If the path is a pattern, all files matching it are removed. - - - - - -*paths - -Uses `Remove File` to remove multiple files one-by-one. - -Example: -| Remove Files | ${TEMPDIR}${/}foo.txt | ${TEMPDIR}${/}bar.txt | ${TEMPDIR}${/}zap.txt | - - - - - -command - -Runs the given command in the system and returns the output. - -The execution status of the command *is not checked* by this -keyword, and it must be done separately based on the returned -output. If the execution return code is needed, either `Run -And Return RC` or `Run And Return RC And Output` can be used. - -The standard error stream is automatically redirected to the standard -output stream by adding ``2>&1`` after the executed command. This -automatic redirection is done only when the executed command does not -contain additional output redirections. You can thus freely forward -the standard error somewhere else, for example, like -``my_command 2>stderr.txt``. - -The returned output contains everything written into the standard -output or error streams by the command (unless either of them -is redirected explicitly). Many commands add an extra newline -(``\n``) after the output to make it easier to read in the -console. To ease processing the returned output, this possible -trailing newline is stripped by this keyword. - -Examples: -| ${output} = | Run | ls -lhF /tmp | -| Log | ${output} | -| ${result} = | Run | ${CURDIR}${/}tester.py arg1 arg2 | -| Should Not Contain | ${result} | FAIL | -| ${stdout} = | Run | /opt/script.sh 2>/tmp/stderr.txt | -| Should Be Equal | ${stdout} | TEST PASSED | -| File Should Be Empty | /tmp/stderr.txt | - -*TIP:* `Run Process` keyword provided by the -[http://robotframework.org/robotframework/latest/libraries/Process.html| -Process library] supports better process configuration and is generally -recommended as a replacement for this keyword. - - - - - -command - -Runs the given command in the system and returns the return code. - -The return code (RC) is returned as a positive integer in -range from 0 to 255 as returned by the executed command. On -some operating systems (notable Windows) original return codes -can be something else, but this keyword always maps them to -the 0-255 range. Since the RC is an integer, it must be -checked e.g. with the keyword `Should Be Equal As Integers` -instead of `Should Be Equal` (both are built-in keywords). - -Examples: -| ${rc} = | Run and Return RC | ${CURDIR}${/}script.py arg | -| Should Be Equal As Integers | ${rc} | 0 | -| ${rc} = | Run and Return RC | /path/to/example.rb arg1 arg2 | -| Should Be True | 0 < ${rc} < 42 | - -See `Run` and `Run And Return RC And Output` if you need to get the -output of the executed command. - -*TIP:* `Run Process` keyword provided by the -[http://robotframework.org/robotframework/latest/libraries/Process.html| -Process library] supports better process configuration and is generally -recommended as a replacement for this keyword. - - - - - -command - -Runs the given command in the system and returns the RC and output. - -The return code (RC) is returned similarly as with `Run And Return RC` -and the output similarly as with `Run`. - -Examples: -| ${rc} | ${output} = | Run and Return RC and Output | ${CURDIR}${/}mytool | -| Should Be Equal As Integers | ${rc} | 0 | -| Should Not Contain | ${output} | FAIL | -| ${rc} | ${stdout} = | Run and Return RC and Output | /opt/script.sh 2>/tmp/stderr.txt | -| Should Be True | ${rc} > 42 | -| Should Be Equal | ${stdout} | TEST PASSED | -| File Should Be Empty | /tmp/stderr.txt | - -*TIP:* `Run Process` keyword provided by the -[http://robotframework.org/robotframework/latest/libraries/Process.html| -Process library] supports better process configuration and is generally -recommended as a replacement for this keyword. - - - - - -name -value - -Sets an environment variable to a specified value. - -Values are converted to strings automatically. Set variables are -automatically encoded using the system encoding. - - - - - -path -mtime - -Sets the file modification and access times. - -Changes the modification and access times of the given file to -the value determined by ``mtime``. The time can be given in -different formats described below. Note that all checks -involving strings are case-insensitive. Modified time can only -be set to regular files. - -1) If ``mtime`` is a number, or a string that can be converted - to a number, it is interpreted as seconds since the UNIX - epoch (1970-01-01 00:00:00 UTC). This documentation was - originally written about 1177654467 seconds after the epoch. - -2) If ``mtime`` is a timestamp, that time will be used. Valid - timestamp formats are ``YYYY-MM-DD hh:mm:ss`` and - ``YYYYMMDD hhmmss``. - -3) If ``mtime`` is equal to ``NOW``, the current local time is used. - -4) If ``mtime`` is equal to ``UTC``, the current time in - [http://en.wikipedia.org/wiki/Coordinated_Universal_Time|UTC] - is used. - -5) If ``mtime`` is in the format like ``NOW - 1 day`` or ``UTC + 1 - hour 30 min``, the current local/UTC time plus/minus the time - specified with the time string is used. The time string format - is described in an appendix of Robot Framework User Guide. - -Examples: -| Set Modified Time | /path/file | 1177654467 | # Time given as epoch seconds | -| Set Modified Time | /path/file | 2007-04-27 9:14:27 | # Time given as a timestamp | -| Set Modified Time | /path/file | NOW | # The local time of execution | -| Set Modified Time | /path/file | NOW - 1 day | # 1 day subtracted from the local time | -| Set Modified Time | /path/file | UTC + 1h 2min 3s | # 1h 2min 3s added to the UTC time | - - - - - -path -msg=None - -Fails unless the given path (file or directory) exists. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -The default error message can be overridden with the ``msg`` argument. - - - - - -path -msg=None - -Fails if the given path (file or directory) exists. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -The default error message can be overridden with the ``msg`` argument. - - - - - -path - -Splits the extension from the given path. - -The given path is first normalized (e.g. possible trailing -path separators removed, special directories ``..`` and ``.`` -removed). The base path and extension are returned as separate -components so that the dot used as an extension separator is -removed. If the path contains no extension, an empty string is -returned for it. Possible leading and trailing dots in the file -name are never considered to be extension separators. - -Examples: -| ${path} | ${ext} = | Split Extension | file.extension | -| ${p2} | ${e2} = | Split Extension | path/file.ext | -| ${p3} | ${e3} = | Split Extension | path/file | -| ${p4} | ${e4} = | Split Extension | p1/../p2/file.ext | -| ${p5} | ${e5} = | Split Extension | path/.file.ext | -| ${p6} | ${e6} = | Split Extension | path/.file | -=> -- ${path} = 'file' & ${ext} = 'extension' -- ${p2} = 'path/file' & ${e2} = 'ext' -- ${p3} = 'path/file' & ${e3} = '' -- ${p4} = 'p2/file' & ${e4} = 'ext' -- ${p5} = 'path/.file' & ${e5} = 'ext' -- ${p6} = 'path/.file' & ${e6} = '' - - - - - -path - -Splits the given path from the last path separator (``/`` or ``\``). - -The given path is first normalized (e.g. a possible trailing -path separator is removed, special directories ``..`` and ``.`` -removed). The parts that are split are returned as separate -components. - -Examples: -| ${path1} | ${dir} = | Split Path | abc/def | -| ${path2} | ${file} = | Split Path | abc/def/ghi.txt | -| ${path3} | ${d2} = | Split Path | abc/../def/ghi/ | -=> -- ${path1} = 'abc' & ${dir} = 'def' -- ${path2} = 'abc/def' & ${file} = 'ghi.txt' -- ${path3} = 'def' & ${d2} = 'ghi' - - - - - -path - -Emulates the UNIX touch command. - -Creates a file, if it does not exist. Otherwise changes its access and -modification times to the current time. - -Fails if used with the directories or the parent directory of the given -file does not exist. - - - - - -path -timeout=1 minute - -Waits until the given file or directory is created. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -If the path is a pattern, the keyword returns when an item matching -it is created. - -The optional ``timeout`` can be used to control the maximum time of -waiting. The timeout is given as a timeout string, e.g. in a format -``15 seconds``, ``1min 10s`` or just ``10``. The time string format is -described in an appendix of Robot Framework User Guide. - -If the timeout is negative, the keyword is never timed-out. The keyword -returns immediately, if the path already exists. - - - - - -path -timeout=1 minute - -Waits until the given file or directory is removed. - -The path can be given as an exact path or as a glob pattern. -The pattern matching syntax is explained in `introduction`. -If the path is a pattern, the keyword waits until all matching -items are removed. - -The optional ``timeout`` can be used to control the maximum time of -waiting. The timeout is given as a timeout string, e.g. in a format -``15 seconds``, ``1min 10s`` or just ``10``. The time string format is -described in an appendix of Robot Framework User Guide. - -If the timeout is negative, the keyword is never timed-out. The keyword -returns immediately, if the path does not exist in the first place. - - - - diff --git a/libspecs/Process.libspec b/libspecs/Process.libspec deleted file mode 100644 index 2bedb8f..0000000 --- a/libspecs/Process.libspec +++ /dev/null @@ -1,637 +0,0 @@ - - -3.1.2 -global -yes -Robot Framework test library for running processes. - -This library utilizes Python's -[http://docs.python.org/library/subprocess.html|subprocess] -module and its -[http://docs.python.org/library/subprocess.html#popen-constructor|Popen] -class. - -The library has following main usages: - -- Running processes in system and waiting for their completion using - `Run Process` keyword. -- Starting processes on background using `Start Process`. -- Waiting started process to complete using `Wait For Process` or - stopping them with `Terminate Process` or `Terminate All Processes`. - -== Table of contents == - -- `Specifying command and arguments` -- `Process configuration` -- `Active process` -- `Result object` -- `Boolean arguments` -- `Example` -- `Shortcuts` -- `Keywords` - -= Specifying command and arguments = - -Both `Run Process` and `Start Process` accept the command to execute and -all arguments passed to the command as separate arguments. This makes usage -convenient and also allows these keywords to automatically escape possible -spaces and other special characters in commands and arguments. Notice that -if a command accepts options that themselves accept values, these options -and their values must be given as separate arguments. - -When `running processes in shell`, it is also possible to give the whole -command to execute as a single string. The command can then contain -multiple commands to be run together. When using this approach, the caller -is responsible on escaping. - -Examples: -| `Run Process` | ${tools}${/}prog.py | argument | second arg with spaces | -| `Run Process` | java | -jar | ${jars}${/}example.jar | --option | value | -| `Run Process` | prog.py "one arg" && tool.sh | shell=yes | cwd=${tools} | - -Possible non-string arguments are converted to strings automatically. - -= Process configuration = - -`Run Process` and `Start Process` keywords can be configured using -optional ``**configuration`` keyword arguments. Configuration arguments -must be given after other arguments passed to these keywords and must -use syntax like ``name=value``. Available configuration arguments are -listed below and discussed further in sections afterwards. - -| = Name = | = Explanation = | -| shell | Specifies whether to run the command in shell or not. | -| cwd | Specifies the working directory. | -| env | Specifies environment variables given to the process. | -| env:<name> | Overrides the named environment variable(s) only. | -| stdout | Path of a file where to write standard output. | -| stderr | Path of a file where to write standard error. | -| output_encoding | Encoding to use when reading command outputs. | -| alias | Alias given to the process. | - -Note that because ``**configuration`` is passed using ``name=value`` syntax, -possible equal signs in other arguments passed to `Run Process` and -`Start Process` must be escaped with a backslash like ``name\=value``. -See `Run Process` for an example. - -== Running processes in shell == - -The ``shell`` argument specifies whether to run the process in a shell or -not. By default shell is not used, which means that shell specific commands, -like ``copy`` and ``dir`` on Windows, are not available. You can, however, -run shell scripts and batch files without using a shell. - -Giving the ``shell`` argument any non-false value, such as ``shell=True``, -changes the program to be executed in a shell. It allows using the shell -capabilities, but can also make the process invocation operating system -dependent. Having a shell between the actually started process and this -library can also interfere communication with the process such as stopping -it and reading its outputs. Because of these problems, it is recommended -to use the shell only when absolutely necessary. - -When using a shell it is possible to give the whole command to execute -as a single string. See `Specifying command and arguments` section for -examples and more details in general. - -== Current working directory == - -By default the child process will be executed in the same directory -as the parent process, the process running tests, is executed. This -can be changed by giving an alternative location using the ``cwd`` argument. -Forward slashes in the given path are automatically converted to -backslashes on Windows. - -`Standard output and error streams`, when redirected to files, -are also relative to the current working directory possibly set using -the ``cwd`` argument. - -Example: -| `Run Process` | prog.exe | cwd=${ROOT}/directory | stdout=stdout.txt | - -== Environment variables == - -By default the child process will get a copy of the parent process's -environment variables. The ``env`` argument can be used to give the -child a custom environment as a Python dictionary. If there is a need -to specify only certain environment variable, it is possible to use the -``env:<name>=<value>`` format to set or override only that named variables. -It is also possible to use these two approaches together. - -Examples: -| `Run Process` | program | env=${environ} | -| `Run Process` | program | env:http_proxy=10.144.1.10:8080 | env:PATH=%{PATH}${:}${PROGDIR} | -| `Run Process` | program | env=${environ} | env:EXTRA=value | - -== Standard output and error streams == - -By default processes are run so that their standard output and standard -error streams are kept in the memory. This works fine normally, -but if there is a lot of output, the output buffers may get full and -the program can hang. Additionally on Jython, everything written to -these in-memory buffers can be lost if the process is terminated. - -To avoid the above mentioned problems, it is possible to use ``stdout`` -and ``stderr`` arguments to specify files on the file system where to -redirect the outputs. This can also be useful if other processes or -other keywords need to read or manipulate the outputs somehow. - -Given ``stdout`` and ``stderr`` paths are relative to the `current working -directory`. Forward slashes in the given paths are automatically converted -to backslashes on Windows. - -As a special feature, it is possible to redirect the standard error to -the standard output by using ``stderr=STDOUT``. - -Regardless are outputs redirected to files or not, they are accessible -through the `result object` returned when the process ends. Commands are -expected to write outputs using the console encoding, but `output encoding` -can be configured using the ``output_encoding`` argument if needed. - -Examples: -| ${result} = | `Run Process` | program | stdout=${TEMPDIR}/stdout.txt | stderr=${TEMPDIR}/stderr.txt | -| `Log Many` | stdout: ${result.stdout} | stderr: ${result.stderr} | -| ${result} = | `Run Process` | program | stderr=STDOUT | -| `Log` | all output: ${result.stdout} | - -Note that the created output files are not automatically removed after -the test run. The user is responsible to remove them if needed. - -== Output encoding == - -Executed commands are, by default, expected to write outputs to the -`standard output and error streams` using the encoding used by the -system console. If the command uses some other encoding, that can be -configured using the ``output_encoding`` argument. This is especially -useful on Windows where the console uses a different encoding than rest -of the system, and many commands use the general system encoding instead -of the console encoding. - -The value used with the ``output_encoding`` argument must be a valid -encoding and must match the encoding actually used by the command. As a -convenience, it is possible to use strings ``CONSOLE`` and ``SYSTEM`` -to specify that the console or system encoding is used, respectively. -If produced outputs use different encoding then configured, values got -through the `result object` will be invalid. - -Examples: -| `Start Process` | program | output_encoding=UTF-8 | -| `Run Process` | program | stdout=${path} | output_encoding=SYSTEM | - -The support to set output encoding is new in Robot Framework 3.0. - -== Alias == - -A custom name given to the process that can be used when selecting the -`active process`. - -Examples: -| `Start Process` | program | alias=example | -| `Run Process` | python | -c | print 'hello' | alias=hello | - -= Active process = - -The test library keeps record which of the started processes is currently -active. By default it is latest process started with `Start Process`, -but `Switch Process` can be used to select a different one. Using -`Run Process` does not affect the active process. - -The keywords that operate on started processes will use the active process -by default, but it is possible to explicitly select a different process -using the ``handle`` argument. The handle can be the identifier returned by -`Start Process` or an ``alias`` explicitly given to `Start Process` or -`Run Process`. - -= Result object = - -`Run Process`, `Wait For Process` and `Terminate Process` keywords return a -result object that contains information about the process execution as its -attributes. The same result object, or some of its attributes, can also -be get using `Get Process Result` keyword. Attributes available in the -object are documented in the table below. - -| = Attribute = | = Explanation = | -| rc | Return code of the process as an integer. | -| stdout | Contents of the standard output stream. | -| stderr | Contents of the standard error stream. | -| stdout_path | Path where stdout was redirected or ``None`` if not redirected. | -| stderr_path | Path where stderr was redirected or ``None`` if not redirected. | - -Example: -| ${result} = | `Run Process` | program | -| `Should Be Equal As Integers` | ${result.rc} | 0 | -| `Should Match` | ${result.stdout} | Some t?xt* | -| `Should Be Empty` | ${result.stderr} | | -| ${stdout} = | `Get File` | ${result.stdout_path} | -| `Should Be Equal` | ${stdout} | ${result.stdout} | -| `File Should Be Empty` | ${result.stderr_path} | | - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is an empty string or equal to ``FALSE``, ``NONE``, ``NO``, ``OFF`` or -``0``, case-insensitively. Other strings are considered true regardless -their value, and other argument types are tested using the same -[http://docs.python.org/library/stdtypes.html#truth|rules as in Python]. - -True examples: -| `Terminate Process` | kill=True | # Strings are generally true. | -| `Terminate Process` | kill=yes | # Same as the above. | -| `Terminate Process` | kill=${TRUE} | # Python ``True`` is true. | -| `Terminate Process` | kill=${42} | # Numbers other than 0 are true. | - -False examples: -| `Terminate Process` | kill=False | # String ``false`` is false. | -| `Terminate Process` | kill=no | # Also string ``no`` is false. | -| `Terminate Process` | kill=${EMPTY} | # Empty string is false. | -| `Terminate Process` | kill=${FALSE} | # Python ``False`` is false. | - -Considering string ``NONE`` false is new in Robot Framework 3.0.3 and -considering also ``OFF`` and ``0`` false is new in Robot Framework 3.1. - -= Example = - -| ***** Settings ***** -| Library Process -| Suite Teardown `Terminate All Processes` kill=True -| -| ***** Test Cases ***** -| Example -| `Start Process` program arg1 arg2 alias=First -| ${handle} = `Start Process` command.sh arg | command2.sh shell=True cwd=/path -| ${result} = `Run Process` ${CURDIR}/script.py -| `Should Not Contain` ${result.stdout} FAIL -| `Terminate Process` ${handle} -| ${result} = `Wait For Process` First -| `Should Be Equal As Integers` ${result.rc} 0 - - -handle=None - -Returns the process ID (pid) of the process as an integer. - -If ``handle`` is not given, uses the current `active process`. - -Notice that the pid is not the same as the handle returned by -`Start Process` that is used internally by this library. - - - - - -handle=None - -Return the underlying ``subprocess.Popen`` object. - -If ``handle`` is not given, uses the current `active process`. - - - - - -handle=None -rc=False -stdout=False -stderr=False -stdout_path=False -stderr_path=False - -Returns the specified `result object` or some of its attributes. - -The given ``handle`` specifies the process whose results should be -returned. If no ``handle`` is given, results of the current `active -process` are returned. In either case, the process must have been -finishes before this keyword can be used. In practice this means -that processes started with `Start Process` must be finished either -with `Wait For Process` or `Terminate Process` before using this -keyword. - -If no other arguments than the optional ``handle`` are given, a whole -`result object` is returned. If one or more of the other arguments -are given any true value, only the specified attributes of the -`result object` are returned. These attributes are always returned -in the same order as arguments are specified in the keyword signature. -See `Boolean arguments` section for more details about true and false -values. - -Examples: -| Run Process | python | -c | print 'Hello, world!' | alias=myproc | -| # Get result object | | | -| ${result} = | Get Process Result | myproc | -| Should Be Equal | ${result.rc} | ${0} | -| Should Be Equal | ${result.stdout} | Hello, world! | -| Should Be Empty | ${result.stderr} | | -| # Get one attribute | | | -| ${stdout} = | Get Process Result | myproc | stdout=true | -| Should Be Equal | ${stdout} | Hello, world! | -| # Multiple attributes | | | -| ${stdout} | ${stderr} = | Get Process Result | myproc | stdout=yes | stderr=yes | -| Should Be Equal | ${stdout} | Hello, world! | -| Should Be Empty | ${stderr} | | - -Although getting results of a previously executed process can be handy -in general, the main use case for this keyword is returning results -over the remote library interface. The remote interface does not -support returning the whole result object, but individual attributes -can be returned without problems. - - - - - -handle=None - -Checks is the process running or not. - -If ``handle`` is not given, uses the current `active process`. - -Returns ``True`` if the process is still running and ``False`` otherwise. - - - - - -*args - -Joins arguments into one command line string. - -In resulting command line string arguments are delimited with a space, -arguments containing spaces are surrounded with quotes, and possible -quotes are escaped with a backslash. - -If this keyword is given only one argument and that is a list like -object, then the values of that list are joined instead. - -Example: -| ${cmd} = | Join Command Line | --option | value with spaces | -| Should Be Equal | ${cmd} | --option "value with spaces" | - -New in Robot Framework 2.9.2. - - - - - -handle=None -error_message=Process is not running. - -Verifies that the process is running. - -If ``handle`` is not given, uses the current `active process`. - -Fails if the process has stopped. - - - - - -handle=None -error_message=Process is running. - -Verifies that the process is not running. - -If ``handle`` is not given, uses the current `active process`. - -Fails if the process is still running. - - - - - -command -*arguments -**configuration - -Runs a process and waits for it to complete. - -``command`` and ``*arguments`` specify the command to execute and -arguments passed to it. See `Specifying command and arguments` for -more details. - -``**configuration`` contains additional configuration related to -starting processes and waiting for them to finish. See `Process -configuration` for more details about configuration related to starting -processes. Configuration related to waiting for processes consists of -``timeout`` and ``on_timeout`` arguments that have same semantics as -with `Wait For Process` keyword. By default there is no timeout, and -if timeout is defined the default action on timeout is ``terminate``. - -Returns a `result object` containing information about the execution. - -Note that possible equal signs in ``*arguments`` must be escaped -with a backslash (e.g. ``name\=value``) to avoid them to be passed in -as ``**configuration``. - -Examples: -| ${result} = | Run Process | python | -c | print 'Hello, world!' | -| Should Be Equal | ${result.stdout} | Hello, world! | -| ${result} = | Run Process | ${command} | stderr=STDOUT | timeout=10s | -| ${result} = | Run Process | ${command} | timeout=1min | on_timeout=continue | -| ${result} = | Run Process | java -Dname\=value Example | shell=True | cwd=${EXAMPLE} | - -This keyword does not change the `active process`. - - - - - -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. - - - - - -args -escaping=False - -Splits command line string into a list of arguments. - -String is split from spaces, but argument surrounded in quotes may -contain spaces in them. If ``escaping`` is given a true value, then -backslash is treated as an escape character. It can escape unquoted -spaces, quotes inside quotes, and so on, but it also requires using -double backslashes when using Windows paths. - -Examples: -| @{cmd} = | Split Command Line | --option "value with spaces" | -| Should Be True | $cmd == ['--option', 'value with spaces'] | - -New in Robot Framework 2.9.2. - - - - - -command -*arguments -**configuration - -Starts a new process on background. - -See `Specifying command and arguments` and `Process configuration` -for more information about the arguments, and `Run Process` keyword -for related examples. - -Makes the started process new `active process`. Returns an identifier -that can be used as a handle to activate the started process if needed. - -Processes are started so that they create a new process group. This -allows sending signals to and terminating also possible child -processes. This is not supported on Jython. - - - - - -handle - -Makes the specified process the current `active process`. - -The handle can be an identifier returned by `Start Process` or -the ``alias`` given to it explicitly. - -Example: -| Start Process | prog1 | alias=process1 | -| Start Process | prog2 | alias=process2 | -| # currently active process is process2 | -| Switch Process | process1 | -| # now active process is process1 | - - - - - -kill=False - -Terminates all still running processes started by this library. - -This keyword can be used in suite teardown or elsewhere to make -sure that all processes are stopped, - -By default tries to terminate processes gracefully, but can be -configured to forcefully kill them immediately. See `Terminate Process` -that this keyword uses internally for more details. - - - - - -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 when using Jython. - Process is killed instead. -- Stopping the whole process group is not supported when using Jython. -- On Windows forceful kill only stops the main process, not possible - child processes. - - - - - -handle=None -timeout=None -on_timeout=continue - -Waits for the process to complete or to reach the given timeout. - -The process to wait for must have been started earlier with -`Start Process`. If ``handle`` is not given, uses the current -`active process`. - -``timeout`` defines the maximum time to wait for the process. It can be -given in -[http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#time-format| -various time formats] supported by Robot Framework, for example, ``42``, -``42 s``, or ``1 minute 30 seconds``. - -``on_timeout`` defines what to do if the timeout occurs. Possible values -and corresponding actions are explained in the table below. Notice -that reaching the timeout never fails the test. - -| = Value = | = Action = | -| continue | The process is left running (default). | -| terminate | The process is gracefully terminated. | -| kill | The process is forcefully stopped. | - -See `Terminate Process` keyword for more details how processes are -terminated and killed. - -If the process ends before the timeout or it is terminated or killed, -this keyword returns a `result object` containing information about -the execution. If the process is left running, Python ``None`` is -returned instead. - -Examples: -| # Process ends cleanly | | | -| ${result} = | Wait For Process | example | -| Process Should Be Stopped | example | | -| Should Be Equal As Integers | ${result.rc} | 0 | -| # Process does not end | | | -| ${result} = | Wait For Process | timeout=42 secs | -| Process Should Be Running | | | -| Should Be Equal | ${result} | ${NONE} | -| # Kill non-ending process | | | -| ${result} = | Wait For Process | timeout=1min 30s | on_timeout=kill | -| Process Should Be Stopped | | | -| Should Be Equal As Integers | ${result.rc} | -9 | - - - - diff --git a/libspecs/Reserved.libspec b/libspecs/Reserved.libspec deleted file mode 100644 index 30d889d..0000000 --- a/libspecs/Reserved.libspec +++ /dev/null @@ -1,87 +0,0 @@ - - - -global -yes -Documentation for library ``Reserved``. - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - - -*varargs - - - - - - diff --git a/libspecs/Screenshot.libspec b/libspecs/Screenshot.libspec deleted file mode 100644 index 09033ae..0000000 --- a/libspecs/Screenshot.libspec +++ /dev/null @@ -1,132 +0,0 @@ - - -3.1.2 -test suite -yes -Test library for taking screenshots on the machine where tests are run. - -Notice that successfully taking screenshots requires tests to be run with -a physical or virtual display. - -= Using with Python = - -How screenshots are taken when using Python depends on the operating -system. On OSX screenshots are taken using the built-in ``screencapture`` -utility. On other operating systems you need to have one of the following -tools or Python modules installed. You can specify the tool/module to use -when `importing` the library. If no tool or module is specified, the first -one found will be used. - -- wxPython :: http://wxpython.org :: Required also by RIDE so many Robot - Framework users already have this module installed. -- PyGTK :: http://pygtk.org :: This module is available by default on most - Linux distributions. -- Pillow :: http://python-pillow.github.io :: - Only works on Windows. Also the original PIL package is supported. -- Scrot :: http://en.wikipedia.org/wiki/Scrot :: Not used on Windows. - Install with ``apt-get install scrot`` or similar. - -Using ``screencapture`` on OSX and specifying explicit screenshot module -are new in Robot Framework 2.9.2. The support for using ``scrot`` is new -in Robot Framework 3.0. - -= Using with Jython and IronPython = - -With Jython and IronPython this library uses APIs provided by JVM and .NET -platforms, respectively. These APIs are always available and thus no -external modules are needed. - -= Where screenshots are saved = - -By default screenshots are saved into the same directory where the Robot -Framework log file is written. If no log is created, screenshots are saved -into the directory where the XML output file is written. - -It is possible to specify a custom location for screenshots using -``screenshot_directory`` argument when `importing` the library and -using `Set Screenshot Directory` keyword during execution. It is also -possible to save screenshots using an absolute path. - - -screenshot_directory=None -screenshot_module=None - -Configure where screenshots are saved. - -If ``screenshot_directory`` is not given, screenshots are saved into -same directory as the log file. The directory can also be set using -`Set Screenshot Directory` keyword. - -``screenshot_module`` specifies the module or tool to use when using -this library on Python outside OSX. Possible values are ``wxPython``, -``PyGTK``, ``PIL`` and ``scrot``, case-insensitively. If no value is -given, the first module/tool found is used in that order. See `Using -with Python` for more information. - -Examples (use only one of these): -| =Setting= | =Value= | =Value= | -| Library | Screenshot | | -| Library | Screenshot | ${TEMPDIR} | -| Library | Screenshot | screenshot_module=PyGTK | - -Specifying explicit screenshot module is new in Robot Framework 2.9.2. - - - - - -path - -Sets the directory where screenshots are saved. - -It is possible to use ``/`` as a path separator in all operating -systems. Path to the old directory is returned. - -The directory can also be set in `importing`. - - - - - -name=screenshot -width=800px - -Takes a screenshot in JPEG format and embeds it into the log file. - -Name of the file where the screenshot is stored is derived from the -given ``name``. If the ``name`` ends with extension ``.jpg`` or -``.jpeg``, the screenshot will be stored with that exact name. -Otherwise a unique name is created by adding an underscore, a running -index and an extension to the ``name``. - -The name will be interpreted to be relative to the directory where -the log file is written. It is also possible to use absolute paths. -Using ``/`` as a path separator works in all operating systems. - -``width`` specifies the size of the screenshot in the log file. - -Examples: (LOGDIR is determined automatically by the library) -| Take Screenshot | | | # LOGDIR/screenshot_1.jpg (index automatically incremented) | -| Take Screenshot | mypic | | # LOGDIR/mypic_1.jpg (index automatically incremented) | -| Take Screenshot | ${TEMPDIR}/mypic | | # /tmp/mypic_1.jpg (index automatically incremented) | -| Take Screenshot | pic.jpg | | # LOGDIR/pic.jpg (always uses this file) | -| Take Screenshot | images/login.jpg | 80% | # Specify both name and width. | -| Take Screenshot | width=550px | | # Specify only width. | - -The path where the screenshot is saved is returned. - - - - - -name=screenshot - -Takes a screenshot and links it from the log file. - -This keyword is otherwise identical to `Take Screenshot` but the saved -screenshot is not embedded into the log file. The screenshot is linked -so it is nevertheless easily available. - - - - diff --git a/libspecs/SeleniumLibrary_104a884.libspec b/libspecs/SeleniumLibrary_104a884.libspec deleted file mode 100644 index 7e33dc1..0000000 --- a/libspecs/SeleniumLibrary_104a884.libspec +++ /dev/null @@ -1,3676 +0,0 @@ - - -4.3.0 -global -yes -SeleniumLibrary is a web testing library for Robot Framework. - -This document explains how to use keywords provided by SeleniumLibrary. -For information about installation, support, and more, please visit the -[https://github.com/robotframework/SeleniumLibrary|project pages]. -For more information about Robot Framework, see http://robotframework.org. - -SeleniumLibrary uses the Selenium WebDriver modules internally to -control a web browser. See http://seleniumhq.org for more information -about Selenium in general and SeleniumLibrary README.rst -[https://github.com/robotframework/SeleniumLibrary#browser-drivers|Browser drivers chapter] -for more details about WebDriver binary installation. - -== Table of contents == - -- `Locating elements` -- `Browser and Window` -- `Timeouts, waits, and delays` -- `Run-on-failure functionality` -- `Boolean arguments` -- `EventFiringWebDriver` -- `Thread support` -- `Plugins` -- `Importing` -- `Shortcuts` -- `Keywords` - -= Locating elements = - -All keywords in SeleniumLibrary that need to interact with an element -on a web page take an argument typically named ``locator`` that specifies -how to find the element. Most often the locator is given as a string -using the locator syntax described below, but `using WebElements` is -possible too. - -== Locator syntax == - -SeleniumLibrary supports finding elements based on different strategies -such as the element id, XPath expressions, or CSS selectors. The strategy -can either be explicitly specified with a prefix or the strategy can be -implicit. - -=== Default locator strategy === - -By default, locators are considered to use the keyword specific default -locator strategy. All keywords support finding elements based on ``id`` -and ``name`` attributes, but some keywords support additional attributes -or other values that make sense in their context. For example, `Click -Link` supports the ``href`` attribute and the link text and addition -to the normal ``id`` and ``name``. - -Examples: - -| `Click Element` | example | # Match based on ``id`` or ``name``. | -| `Click Link` | example | # Match also based on link text and ``href``. | -| `Click Button` | example | # Match based on ``id``, ``name`` or ``value``. | - -If a locator accidentally starts with a prefix recognized as `explicit -locator strategy` or `implicit XPath strategy`, it is possible to use -the explicit ``default`` prefix to enable the default strategy. - -Examples: - -| `Click Element` | name:foo | # Find element with name ``foo``. | -| `Click Element` | default:name:foo | # Use default strategy with value ``name:foo``. | -| `Click Element` | //foo | # Find element using XPath ``//foo``. | -| `Click Element` | default: //foo | # Use default strategy with value ``//foo``. | - -=== Explicit locator strategy === - -The explicit locator strategy is specified with a prefix using either -syntax ``strategy:value`` or ``strategy=value``. The former syntax -is preferred because the latter is identical to Robot Framework's -[http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#named-argument-syntax| -named argument syntax] and that can cause problems. Spaces around -the separator are ignored, so ``id:foo``, ``id: foo`` and ``id : foo`` -are all equivalent. - -Locator strategies that are supported by default are listed in the table -below. In addition to them, it is possible to register `custom locators`. - -| = Strategy = | = Match based on = | = Example = | -| id | Element ``id``. | ``id:example`` | -| name | ``name`` attribute. | ``name:example`` | -| identifier | Either ``id`` or ``name``. | ``identifier:example`` | -| class | Element ``class``. | ``class:example`` | -| tag | Tag name. | ``tag:div`` | -| xpath | XPath expression. | ``xpath://div[@id="example"]`` | -| css | CSS selector. | ``css:div#example`` | -| dom | DOM expression. | ``dom:document.images[5]`` | -| link | Exact text a link has. | ``link:The example`` | -| partial link | Partial link text. | ``partial link:he ex`` | -| sizzle | Sizzle selector deprecated. | ``sizzle:div.example`` | -| jquery | jQuery expression. | ``jquery:div.example`` | -| default | Keyword specific default behavior. | ``default:example`` | - -See the `Default locator strategy` section below for more information -about how the default strategy works. Using the explicit ``default`` -prefix is only necessary if the locator value itself accidentally -matches some of the explicit strategies. - -Different locator strategies have different pros and cons. Using ids, -either explicitly like ``id:foo`` or by using the `default locator -strategy` simply like ``foo``, is recommended when possible, because -the syntax is simple and locating elements by id is fast for browsers. -If an element does not have an id or the id is not stable, other -solutions need to be used. If an element has a unique tag name or class, -using ``tag``, ``class`` or ``css`` strategy like ``tag:h1``, -``class:example`` or ``css:h1.example`` is often an easy solution. In -more complex cases using XPath expressions is typically the best -approach. They are very powerful but a downside is that they can also -get complex. - -Examples: - -| `Click Element` | id:foo | # Element with id 'foo'. | -| `Click Element` | css:div#foo h1 | # h1 element under div with id 'foo'. | -| `Click Element` | xpath: //div[@id="foo"]//h1 | # Same as the above using XPath, not CSS. | -| `Click Element` | xpath: //*[contains(text(), "example")] | # Element containing text 'example'. | - -*NOTE:* - -- The ``strategy:value`` syntax is only supported by SeleniumLibrary 3.0 - and newer. -- Using the ``sizzle`` strategy or its alias ``jquery`` requires that - the system under test contains the jQuery library. -- Prior to SeleniumLibrary 3.0, table related keywords only supported - ``xpath``, ``css`` and ``sizzle/jquery`` strategies. - -=== Implicit XPath strategy === - -If the locator starts with ``//`` or ``(//``, the locator is considered -to be an XPath expression. In other words, using ``//div`` is equivalent -to using explicit ``xpath://div``. - -Examples: - -| `Click Element` | //div[@id="foo"]//h1 | -| `Click Element` | (//div)[2] | - -The support for the ``(//`` prefix is new in SeleniumLibrary 3.0. - -== Using WebElements == - -In addition to specifying a locator as a string, it is possible to use -Selenium's WebElement objects. This requires first getting a WebElement, -for example, by using the `Get WebElement` keyword. - -| ${elem} = | `Get WebElement` | id:example | -| `Click Element` | ${elem} | | - -== Custom locators == - -If more complex lookups are required than what is provided through the -default locators, custom lookup strategies can be created. Using custom -locators is a two part process. First, create a keyword that returns -a WebElement that should be acted on: - -| Custom Locator Strategy | [Arguments] | ${browser} | ${locator} | ${tag} | ${constraints} | -| | ${element}= | Execute Javascript | return window.document.getElementById('${locator}'); | -| | [Return] | ${element} | - -This keyword is a reimplementation of the basic functionality of the -``id`` locator where ``${browser}`` is a reference to a WebDriver -instance and ``${locator}`` is the name of the locator strategy. To use -this locator, it must first be registered by using the -`Add Location Strategy` keyword: - -| `Add Location Strategy` | custom | Custom Locator Strategy | - -The first argument of `Add Location Strategy` specifies the name of -the strategy and it must be unique. After registering the strategy, -the usage is the same as with other locators: - -| `Click Element` | custom:example | - -See the `Add Location Strategy` keyword for more details. - -= Browser and Window = - -There is different conceptual meaning when SeleniumLibrary talks -about windows or browsers. This chapter explains those differences. - -== Browser == - -When `Open Browser` or `Create WebDriver` keyword is called, it -will create a new Selenium WebDriver instance by using the -[https://www.seleniumhq.org/docs/03_webdriver.jsp|Selenium WebDriver] -API. In SeleniumLibrary terms, a new browser is created. It is -possible to start multiple independent browsers (Selenium Webdriver -instances) at the same time, by calling `Open Browser` or -`Create WebDriver` multiple times. These browsers are usually -independent of each other and do not share data like cookies, -sessions or profiles. Typically when the browser starts, it -creates a single window which is shown to the user. - -== Window == - -Windows are the part of a browser that loads the web site and presents -it to the user. All content of the site is the content of the window. -Windows are children of a browser. In SeleniumLibrary browser is a -synonym for WebDriver instance. One browser may have multiple -windows. Windows can appear as tabs, as separate windows or pop-ups with -different position and size. Windows belonging to the same browser -typically share the sessions detail, like cookies. If there is a -need to separate sessions detail, example login with two different -users, two browsers (Selenium WebDriver instances) must be created. -New windows can be opened example by the application under test or -by example `Execute Javascript` keyword: - -| `Execute Javascript` window.open() # Opens a new window with location about:blank - -The example below opens multiple browsers and windows, -to demonstrate how the different keywords can be used to interact -with browsers, and windows attached to these browsers. - -Structure: -| BrowserA -| Window 1 (location=https://robotframework.org/) -| Window 2 (location=https://robocon.io/) -| Window 3 (location=https://github.com/robotframework/) -| -| BrowserB -| Window 1 (location=https://github.com/) - -Example: -| `Open Browser` | https://robotframework.org | ${BROWSER} | alias=BrowserA | # BrowserA with first window is opened. | -| `Execute Javascript` | window.open() | | | # In BrowserA second window is opened. | -| `Switch Window` | locator=NEW | | | # Switched to second window in BrowserA | -| `Go To` | https://robocon.io | | | # Second window navigates to robocon site. | -| `Execute Javascript` | window.open() | | | # In BrowserA third window is opened. | -| ${handle} | `Switch Window` | locator=NEW | | # Switched to third window in BrowserA | -| `Go To` | https://github.com/robotframework/ | | | # Third windows goes to robot framework github site. | -| `Open Browser` | https://github.com | ${BROWSER} | alias=BrowserB | # BrowserB with first windows is opened. | -| ${location} | `Get Location` | | | # ${location} is: https://www.github.com | -| `Switch Window` | ${handle} | browser=BrowserA | | # BrowserA second windows is selected. | -| ${location} | `Get Location` | | | # ${location} = https://robocon.io/ | -| @{locations 1} | `Get Locations` | | | # By default, lists locations under the currectly active browser (BrowserA). | -| @{locations 2} | `Get Locations` | browser=ALL | | # By using browser=ALL argument keyword list all locations from all browsers. | - -The above example, @{locations 1} contains the following items: -https://robotframework.org/, https://robocon.io/ and -https://github.com/robotframework/'. The @{locations 2} -contains the following items: https://robotframework.org/, -https://robocon.io/, https://github.com/robotframework/' -and 'https://github.com/. - -= Timeouts, waits, and delays = - -This section discusses different ways how to wait for elements to -appear on web pages and to slow down execution speed otherwise. -It also explains the `time format` that can be used when setting various -timeouts, waits, and delays. - -== Timeout == - -SeleniumLibrary contains various keywords that have an optional -``timeout`` argument that specifies how long these keywords should -wait for certain events or actions. These keywords include, for example, -``Wait ...`` keywords and keywords related to alerts. Additionally -`Execute Async Javascript`. Although it does not have ``timeout``, -argument, uses a timeout to define how long asynchronous JavaScript -can run. - -The default timeout these keywords use can be set globally either by -using the `Set Selenium Timeout` keyword or with the ``timeout`` argument -when `importing` the library. See `time format` below for supported -timeout syntax. - -== Implicit wait == - -Implicit wait specifies the maximum time how long Selenium waits when -searching for elements. It can be set by using the `Set Selenium Implicit -Wait` keyword or with the ``implicit_wait`` argument when `importing` -the library. See [https://www.seleniumhq.org/docs/04_webdriver_advanced.jsp| -Selenium documentation] for more information about this functionality. - -See `time format` below for supported syntax. - -== Selenium speed == - -Selenium execution speed can be slowed down globally by using `Set -Selenium speed` keyword. This functionality is designed to be used for -demonstrating or debugging purposes. Using it to make sure that elements -appear on a page is not a good idea. The above-explained timeouts -and waits should be used instead. - -See `time format` below for supported syntax. - -== Time format == - -All timeouts and waits can be given as numbers considered seconds -(e.g. ``0.5`` or ``42``) or in Robot Framework's time syntax -(e.g. ``1.5 seconds`` or ``1 min 30 s``). For more information about -the time syntax see the -[http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#time-format|Robot Framework User Guide]. - -= Run-on-failure functionality = - -SeleniumLibrary has a handy feature that it can automatically execute -a keyword if any of its own keywords fails. By default, it uses the -`Capture Page Screenshot` keyword, but this can be changed either by -using the `Register Keyword To Run On Failure` keyword or with the -``run_on_failure`` argument when `importing` the library. It is -possible to use any keyword from any imported library or resource file. - -The run-on-failure functionality can be disabled by using a special value -``NOTHING`` or anything considered false (see `Boolean arguments`) -such as ``NONE``. - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is either empty or case-insensitively equal to ``false``, ``no``, ``off``, - ``0`` or ``none``. Other strings are considered true regardless of their value and -other argument types are tested using the same -[https://docs.python.org/3/library/stdtypes.html#truth-value-testing|rules as in Python]. - -True examples: - -| `Set Screenshot Directory` | ${RESULTS} | persist=True | # Strings are generally true. | -| `Set Screenshot Directory` | ${RESULTS} | persist=yes | # Same as the above. | -| `Set Screenshot Directory` | ${RESULTS} | persist=${TRUE} | # Python True is true. | -| `Set Screenshot Directory` | ${RESULTS} | persist=${42} | # Numbers other than 0 are true. | - -False examples: - -| `Set Screenshot Directory` | ${RESULTS} | persist=False | # String false is false. | -| `Set Screenshot Directory` | ${RESULTS} | persist=no | # Also string no is false. | -| `Set Screenshot Directory` | ${RESULTS} | persist=NONE | # String NONE is false. | -| `Set Screenshot Directory` | ${RESULTS} | persist=${EMPTY} | # Empty string is false. | -| `Set Screenshot Directory` | ${RESULTS} | persist=${FALSE} | # Python False is false. | -| `Set Screenshot Directory` | ${RESULTS} | persist=${NONE} | # Python None is false. | - -Note that prior to SeleniumLibrary 3.0, all non-empty strings, including -``false``, ``no`` and ``none``, were considered true. Starting from -SeleniumLibrary 4.0, strings ``0`` and ``off`` are considered as false. - -= EventFiringWebDriver = - -The SeleniumLibrary offers support for -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.event_firing_webdriver.html#module-selenium.webdriver.support.event_firing_webdriver|EventFiringWebDriver]. -See the Selenium and SeleniumLibrary -[https://github.com/robotframework/SeleniumLibrary/blob/master/docs/extending/extending.rst#EventFiringWebDriver|EventFiringWebDriver support] -documentation for further details. - -EventFiringWebDriver is new in SeleniumLibrary 4.0 - -= Thread support = - -SeleniumLibrary is not thread-safe. This is mainly due because the underlying -[https://github.com/SeleniumHQ/selenium/wiki/Frequently-Asked-Questions#q-is-webdriver-thread-safe| -Selenium tool is not thread-safe] within one browser/driver instance. -Because of the limitation in the Selenium side, the keywords or the -API provided by the SeleniumLibrary is not thread-safe. - -= Plugins = - -SeleniumLibrary offers plugins as a way to modify and add library keywords and modify some of the internal -functionality without creating a new library or hacking the source code. See -[https://github.com/robotframework/SeleniumLibrary/blob/master/docs/extending/extending.rst#Plugins|plugin API] -documentation for further details. - -Plugin API is new SeleniumLibrary 4.0 - - -timeout=5.0 -implicit_wait=0.0 -run_on_failure=Capture Page Screenshot -screenshot_root_directory=None -plugins=None -event_firing_webdriver=None - -SeleniumLibrary can be imported with several optional arguments. - -- ``timeout``: - Default value for `timeouts` used with ``Wait ...`` keywords. -- ``implicit_wait``: - Default value for `implicit wait` used when locating elements. -- ``run_on_failure``: - Default action for the `run-on-failure functionality`. -- ``screenshot_root_directory``: - Path to folder where possible screenshots are created or EMBED. - See `Set Screenshot Directory` keyword for further details about EMBED. - If not given, the directory where the log file is written is used. -- ``plugins``: - Allows extending the SeleniumLibrary with external Python classes. -- ``event_firing_webdriver``: - Class for wrapping Selenium with - [https://seleniumhq.github.io/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.event_firing_webdriver.html#module-selenium.webdriver.support.event_firing_webdriver|EventFiringWebDriver] - - - - - -name -value -path=None -domain=None -secure=None -expiry=None - -Adds a cookie to your current session. - -``name`` and ``value`` are required, ``path``, ``domain``, ``secure`` -and ``expiry`` are optional. Expiry supports the same formats as -the [http://robotframework.org/robotframework/latest/libraries/DateTime.html|DateTime] -library or an epoch timestamp. - -Example: -| `Add Cookie` | foo | bar | | -| `Add Cookie` | foo | bar | domain=example.com | -| `Add Cookie` | foo | bar | expiry=2027-09-28 16:21:35 | # Expiry as timestamp. | -| `Add Cookie` | foo | bar | expiry=1822137695 | # Expiry as epoch seconds. | - -Prior to SeleniumLibrary 3.0 setting expiry did not work. - - - - - -strategy_name -strategy_keyword -persist=False - -Adds a custom location strategy. - -See `Custom locators` for information on how to create and use -custom strategies. `Remove Location Strategy` can be used to -remove a registered strategy. - -Location strategies are automatically removed after leaving the -current scope by default. Setting ``persist`` to a true value (see -`Boolean arguments`) will cause the location strategy to stay -registered throughout the life of the test. - - - - - -text= -action=ACCEPT -timeout=None - -Verifies that an alert is present and by default, accepts it. - -Fails if no alert is present. If ``text`` is a non-empty string, -then it is used to verify alert's message. The alert is accepted -by default, but that behavior can be controlled by using the -``action`` argument same way as with `Handle Alert`. - -``timeout`` specifies how long to wait for the alert to appear. -If it is not given, the global default `timeout` is used instead. - -``action`` and ``timeout`` arguments are new in SeleniumLibrary 3.0. -In earlier versions, the alert was always accepted and a timeout was -hardcoded to one second. - - - - - -action=ACCEPT -timeout=0 - -Verifies that no alert is present. - -If the alert actually exists, the ``action`` argument determines -how it should be handled. By default, the alert is accepted, but -it can be also dismissed or left open the same way as with the -`Handle Alert` keyword. - -``timeout`` specifies how long to wait for the alert to appear. -By default, is not waited for the alert at all, but a custom time can -be given if alert may be delayed. See the `time format` section -for information about the syntax. - -New in SeleniumLibrary 3.0. - - - - - -locator -id - -Assigns a temporary ``id`` to the element specified by ``locator``. - -This is mainly useful if the locator is complicated and/or slow XPath -expression and it is needed multiple times. Identifier expires when -the page is reloaded. - -See the `Locating elements` section for details about the locator -syntax. - -Example: -| `Assign ID to Element` | //ul[@class='example' and ./li[contains(., 'Stuff')]] | my id | -| `Page Should Contain Element` | my id | - - - - - -locator -filename=selenium-element-screenshot-{index}.png - -Captures a screenshot from the element identified by ``locator`` and embeds it into log file. - -See `Capture Page Screenshot` for details about ``filename`` argument. -See the `Locating elements` section for details about the locator -syntax. - -An absolute path to the created element screenshot is returned. - -Support for capturing the screenshot from an element has limited support -among browser vendors. Please check the browser vendor driver documentation -does the browser support capturing a screenshot from an element. - -New in SeleniumLibrary 3.3. Support for EMBED is new in SeleniumLibrary 4.2. - -Examples: -| `Capture Element Screenshot` | id:image_id | | -| `Capture Element Screenshot` | id:image_id | ${OUTPUTDIR}/id_image_id-1.png | -| `Capture Element Screenshot` | id:image_id | EMBED | - - - - - -filename=selenium-screenshot-{index}.png - -Takes a screenshot of the current page and embeds it into a log file. - -``filename`` argument specifies the name of the file to write the -screenshot into. The directory where screenshots are saved can be -set when `importing` the library or by using the `Set Screenshot -Directory` keyword. If the directory is not configured, screenshots -are saved to the same directory where Robot Framework's log file is -written. - -If ``filename`` equals to EMBED (case insensitive), then screenshot -is embedded as Base64 image to the log.html. In this case file is not -created in the filesystem. - -Starting from SeleniumLibrary 1.8, if ``filename`` contains marker -``{index}``, it will be automatically replaced with an unique running -index, preventing files to be overwritten. Indices start from 1, -and how they are represented can be customized using Python's -[https://docs.python.org/3/library/string.html#format-string-syntax| -format string syntax]. - -An absolute path to the created screenshot file is returned or if -``filename`` equals to EMBED, word `EMBED` is returned. - -Support for EMBED is new in SeleniumLibrary 4.2 - -Examples: -| `Capture Page Screenshot` | | -| `File Should Exist` | ${OUTPUTDIR}/selenium-screenshot-1.png | -| ${path} = | `Capture Page Screenshot` | -| `File Should Exist` | ${OUTPUTDIR}/selenium-screenshot-2.png | -| `File Should Exist` | ${path} | -| `Capture Page Screenshot` | custom_name.png | -| `File Should Exist` | ${OUTPUTDIR}/custom_name.png | -| `Capture Page Screenshot` | custom_with_index_{index}.png | -| `File Should Exist` | ${OUTPUTDIR}/custom_with_index_1.png | -| `Capture Page Screenshot` | formatted_index_{index:03}.png | -| `File Should Exist` | ${OUTPUTDIR}/formatted_index_001.png | -| `Capture Page Screenshot` | EMBED | -| `File Should Not Exist` | EMBED | - - - - - -locator - -Verifies checkbox ``locator`` is selected/checked. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Verifies checkbox ``locator`` is not selected/checked. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -file_path - -Inputs the ``file_path`` into the file input field ``locator``. - -This keyword is most often used to input files into upload forms. -The keyword does not check ``file_path`` is the file or folder -available on the machine where tests are executed. If the ``file_path`` -points at a file and when using Selenium Grid, Selenium will -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.command.html?highlight=upload#selenium.webdriver.remote.command.Command.UPLOAD_FILE|magically], -transfer the file from the machine where the tests are executed -to the Selenium Grid node where the browser is running. -Then Selenium will send the file path, from the nodes file -system, to the browser. - -That ``file_path`` is not checked, is new in SeleniumLibrary 4.0. - -Example: -| `Choose File` | my_upload_field | ${CURDIR}/trades.csv | - - - - - -locator - -Clears the value of the text-input-element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -modifier=False - -Clicks the button identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, buttons are -searched using ``id``, ``name``, and ``value``. - -See the `Click Element` keyword for details about the -``modifier`` argument. - -The ``modifier`` argument is new in SeleniumLibrary 3.3 - - - - - -locator -modifier=False -action_chain=False - -Click the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -The ``modifier`` argument can be used to pass -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys|Selenium Keys] -when clicking the element. The `+` can be used as a separator -for different Selenium Keys. The `CTRL` is internally translated to -the `CONTROL` key. The ``modifier`` is space and case insensitive, example -"alt" and " aLt " are supported formats to -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys.ALT|ALT key] -. If ``modifier`` does not match to Selenium Keys, keyword fails. - -If ``action_chain`` argument is true, see `Boolean arguments` for more -details on how to set boolean argument, then keyword uses ActionChain -based click instead of the <web_element>.click() function. If both -``action_chain`` and ``modifier`` are defined, the click will be -performed using ``modifier`` and ``action_chain`` will be ignored. - -Example: -| Click Element | id:button | | # Would click element without any modifiers. | -| Click Element | id:button | CTRL | # Would click element with CTLR key pressed down. | -| Click Element | id:button | CTRL+ALT | # Would click element with CTLR and ALT keys pressed down. | -| Click Element | id:button | action_chain=True | # Clicks the button using an Selenium ActionChains | - -The ``modifier`` argument is new in SeleniumLibrary 3.2 -The ``action_chain`` argument is new in SeleniumLibrary 4.1 - - - - - -locator -xoffset -yoffset - -Click the element ``locator`` at ``xoffset/yoffset``. - -The Cursor is moved and the center of the element and x/y coordinates are -calculated from that point. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -modifier=False - -Clicks an image identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, images are searched -using ``id``, ``name``, ``src`` and ``alt``. - -See the `Click Element` keyword for details about the -``modifier`` argument. - -The ``modifier`` argument is new in SeleniumLibrary 3.3 - - - - - -locator -modifier=False - -Clicks a link identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, links are searched -using ``id``, ``name``, ``href`` and the link text. - -See the `Click Element` keyword for details about the -``modifier`` argument. - -The ``modifier`` argument is new in SeleniumLibrary 3.3 - - - - - - -Closes all open browsers and resets the browser cache. - -After this keyword, new indexes returned from `Open Browser` keyword -are reset to 1. - -This keyword should be used in test or suite teardown to make sure -all browsers are closed. - - - - - - -Closes the current browser. - - - - - - -Closes currently opened and selected browser window/tab. - - - - - -locator - -Will cover elements identified by ``locator`` with a blue div without breaking page layout. - -See the `Locating elements` section for details about the locator -syntax. - -New in SeleniumLibrary 3.3.0 - -Example: -|`Cover Element` | css:div#container | - - - - - -driver_name -alias=None -kwargs={} -**init_kwargs - -Creates an instance of Selenium WebDriver. - -Like `Open Browser`, but allows passing arguments to the created -WebDriver instance directly. This keyword should only be used if -the functionality provided by `Open Browser` is not adequate. - -``driver_name`` must be a WebDriver implementation name like Firefox, -Chrome, Ie, Opera, Safari, PhantomJS, or Remote. - -The initialized WebDriver can be configured either with a Python -dictionary ``kwargs`` or by using keyword arguments ``**init_kwargs``. -These arguments are passed directly to WebDriver without any -processing. See [https://seleniumhq.github.io/selenium/docs/api/py/api.html| -Selenium API documentation] for details about the supported arguments. - -Examples: -| # Use proxy with Firefox | | | | -| ${proxy}= | `Evaluate` | selenium.webdriver.Proxy() | modules=selenium, selenium.webdriver | -| ${proxy.http_proxy}= | `Set Variable` | localhost:8888 | | -| `Create Webdriver` | Firefox | proxy=${proxy} | | -| # Use proxy with PhantomJS | | | | -| ${service args}= | `Create List` | --proxy=192.168.132.104:8888 | | -| `Create Webdriver` | PhantomJS | service_args=${service args} | | - -Returns the index of this browser instance which can be used later to -switch back to it. Index starts from 1 and is reset back to it when -`Close All Browsers` keyword is used. See `Switch Browser` for an -example. - - - - - -text -loglevel=TRACE - -Verifies that the current frame contains ``text``. - -See `Page Should Contain` for an explanation about the ``loglevel`` -argument. - -Prior to SeleniumLibrary 3.0 this keyword was named -`Current Frame Contains`. - - - - - -text -loglevel=TRACE - -Verifies that the current frame does not contain ``text``. - -See `Page Should Contain` for an explanation about the ``loglevel`` -argument. - - - - - - -Deletes all cookies. - - - - - -name - -Deletes the cookie matching ``name``. - -If the cookie is not found, nothing happens. - - - - - -locator - -Double clicks the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -target - -Drags the element identified by ``locator`` into the ``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. - -Example: -| `Drag And Drop` | css:div#element | css:div.target | - - - - - -locator -xoffset -yoffset - -Drags the element identified with ``locator`` by ``xoffset/yoffset``. - -See the `Locating elements` section for details about the locator -syntax. - -The element will be moved by ``xoffset`` and ``yoffset``, each of which -is a negative or positive number specifying the offset. - -Example: -| `Drag And Drop By Offset` | myElem | 50 | -35 | # Move myElem 50px right and 35px down | - - - - - -locator -attribute -expected -message=None - -Verifies element identified by ``locator`` contains expected attribute value. - -See the `Locating elements` section for details about the locator -syntax. - -Example: -`Element Attribute Value Should Be` | css:img | href | value - -New in SeleniumLibrary 3.2. - - - - - -locator - -Verifies that element identified by ``locator`` is disabled. - -This keyword considers also elements that are read-only to be -disabled. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Verifies that element identified by ``locator`` is enabled. - -This keyword considers also elements that are read-only to be -disabled. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Verifies that element identified by ``locator`` is focused. - -See the `Locating elements` section for details about the locator -syntax. - -New in SeleniumLibrary 3.0. - - - - - -locator -message=None - -Verifies that the element identified by ``locator`` is visible. - -Herein, visible means that the element is logically visible, not -optically visible in the current browser viewport. For example, -an element that carries ``display:none`` is not logically visible, -so using this keyword on that element would fail. - -See the `Locating elements` section for details about the locator -syntax. - -The ``message`` argument can be used to override the default error -message. - - - - - -locator -expected -message=None -ignore_case=False - -Verifies that element ``locator`` contains text ``expected``. - -See the `Locating elements` section for details about the locator -syntax. - -The ``message`` argument can be used to override the default error -message. - -The ``ignore_case`` argument can be set to True to compare case -insensitive, default is False. New in SeleniumLibrary 3.1. - -``ignore_case`` argument is new in SeleniumLibrary 3.1. - -Use `Element Text Should Be` if you want to match the exact text, -not a substring. - - - - - -locator -message=None - -Verifies that the element identified by ``locator`` is NOT visible. - -Passes if the element does not exists. See `Element Should Be Visible` -for more information about visibility and supported arguments. - - - - - -locator -expected -message=None -ignore_case=False - -Verifies that element ``locator`` does not contain text ``expected``. - -See the `Locating elements` section for details about the locator -syntax. - -The ``message`` argument can be used to override the default error -message. - -The ``ignore_case`` argument can be set to True to compare case -insensitive, default is False. - -``ignore_case`` argument new in SeleniumLibrary 3.1. - - - - - -locator -expected -message=None -ignore_case=False - -Verifies that element ``locator`` contains exact the text ``expected``. - -See the `Locating elements` section for details about the locator -syntax. - -The ``message`` argument can be used to override the default error -message. - -The ``ignore_case`` argument can be set to True to compare case -insensitive, default is False. - -``ignore_case`` argument is new in SeleniumLibrary 3.1. - -Use `Element Should Contain` if a substring match is desired. - - - - - -locator -not_expected -message=None -ignore_case=False - -Verifies that element ``locator`` does not contain exact the text ``not_expected``. - -See the `Locating elements` section for details about the locator -syntax. - -The ``message`` argument can be used to override the default error -message. - -The ``ignore_case`` argument can be set to True to compare case -insensitive, default is False. - -New in SeleniumLibrary 3.1.1 - - - - - -*code - -Executes asynchronous JavaScript code with possible arguments. - -Similar to `Execute Javascript` except that scripts executed with -this keyword must explicitly signal they are finished by invoking the -provided callback. This callback is always injected into the executed -function as the last argument. - -Scripts must complete within the script timeout or this keyword will -fail. See the `Timeout` section for more information. - -Starting from SeleniumLibrary 3.2 it is possible to provide JavaScript -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html#selenium.webdriver.remote.webdriver.WebDriver.execute_async_script| -arguments] as part of ``code`` argument. See `Execute Javascript` for -more details. - -Examples: -| `Execute Async JavaScript` | var callback = arguments[arguments.length - 1]; window.setTimeout(callback, 2000); | -| `Execute Async JavaScript` | ${CURDIR}/async_js_to_execute.js | -| ${result} = | `Execute Async JavaScript` | -| ... | var callback = arguments[arguments.length - 1]; | -| ... | function answer(){callback("text");}; | -| ... | window.setTimeout(answer, 2000); | -| `Should Be Equal` | ${result} | text | - - - - - -*code - -Executes the given JavaScript code with possible arguments. - -``code`` may be divided into multiple cells in the test data and -``code`` may contain multiple lines of code and arguments. In that case, -the JavaScript code parts are concatenated together without adding -spaces and optional arguments are separated from ``code``. - -If ``code`` is a path to an existing file, the JavaScript -to execute will be read from that file. Forward slashes work as -a path separator on all operating systems. - -The JavaScript executes in the context of the currently selected -frame or window as the body of an anonymous function. Use ``window`` -to refer to the window of your application and ``document`` to refer -to the document object of the current frame or window, e.g. -``document.getElementById('example')``. - -This keyword returns whatever the executed JavaScript code returns. -Return values are converted to the appropriate Python types. - -Starting from SeleniumLibrary 3.2 it is possible to provide JavaScript -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html#selenium.webdriver.remote.webdriver.WebDriver.execute_script| -arguments] as part of ``code`` argument. The JavaScript code and -arguments must be separated with `JAVASCRIPT` and `ARGUMENTS` markers -and must be used exactly with this format. If the Javascript code is -first, then the `JAVASCRIPT` marker is optional. The order of -`JAVASCRIPT` and `ARGUMENTS` markers can be swapped, but if `ARGUMENTS` -is the first marker, then `JAVASCRIPT` marker is mandatory. It is only -allowed to use `JAVASCRIPT` and `ARGUMENTS` markers only one time in the -``code`` argument. - -Examples: -| `Execute JavaScript` | window.myFunc('arg1', 'arg2') | -| `Execute JavaScript` | ${CURDIR}/js_to_execute.js | -| `Execute JavaScript` | alert(arguments[0]); | ARGUMENTS | 123 | -| `Execute JavaScript` | ARGUMENTS | 123 | JAVASCRIPT | alert(arguments[0]); | - - - - - -locator -text -loglevel=TRACE - -Verifies that frame identified by ``locator`` contains ``text``. - -See the `Locating elements` section for details about the locator -syntax. - -See `Page Should Contain` for an explanation about the ``loglevel`` -argument. - - - - - - -Returns a list containing ids of all links found in current page. - -If a link has no id, an empty string will be in the list instead. - - - - - - -Returns aliases of all active browser that has an alias as NormalizedDict. -The dictionary contains the aliases as keys and the index as value. -This can be accessed as dictionary ``${aliases.key}`` or as list ``@{aliases}[0]``. - -Example: -| `Open Browser` | https://example.com | alias=BrowserA | | -| `Open Browser` | https://example.com | alias=BrowserB | | -| &{aliases} | `Get Browser Aliases` | | # &{aliases} = { BrowserA=1|BrowserB=2 } | -| `Log` | ${aliases.BrowserA} | | # logs ``1`` | -| FOR | ${alias} | IN | @{aliases} | -| | `Log` | ${alias} | # logs ``BrowserA`` and ``BrowserB`` | -| END | | | | - -See `Switch Browser` for more information and examples. - -New in SeleniumLibrary 4.0 - - - - - - -Returns index of all active browser as list. - -Example: -| @{browser_ids}= | Get Browser Ids | | | -| FOR | ${id} | IN | @{browser_ids} | -| | @{window_titles}= | Get Window Titles | browser=${id} | -| | Log | Browser ${id} has these windows: ${window_titles} | | -| END | | | | - -See `Switch Browser` for more information and examples. - -New in SeleniumLibrary 4.0 - - - - - -name - -Returns information of cookie with ``name`` as an object. - -If no cookie is found with ``name``, keyword fails. The cookie object -contains details about the cookie. Attributes available in the object -are documented in the table below. - -| = Attribute = | = Explanation = | -| name | The name of a cookie. | -| value | Value of the cookie. | -| path | Indicates a URL path, for example ``/``. | -| domain | The domain, the cookie is visible to. | -| secure | When true, the cookie is only used with HTTPS connections. | -| httpOnly | When true, the cookie is not accessible via JavaScript. | -| expiry | Python datetime object indicating when the cookie expires. | -| extra | Possible attributes outside of the WebDriver specification | - -See the -[https://w3c.github.io/webdriver/#cookies|WebDriver specification] -for details about the cookie information. -Notice that ``expiry`` is specified as a -[https://docs.python.org/3/library/datetime.html#datetime.datetime|datetime object], -not as seconds since Unix Epoch like WebDriver natively does. - -In some cases, example when running a browser in the cloud, it is possible that -the cookie contains other attributes than is defined in the -[https://w3c.github.io/webdriver/#cookies|WebDriver specification]. -These other attributes are available in an ``extra`` attribute in the cookie -object and it contains a dictionary of the other attributes. The ``extra`` -attribute is new in SeleniumLibrary 4.0. - -Example: -| `Add Cookie` | foo | bar | -| ${cookie} = | `Get Cookie` | foo | -| `Should Be Equal` | ${cookie.name} | bar | -| `Should Be Equal` | ${cookie.value} | foo | -| `Should Be True` | ${cookie.expiry.year} > 2017 | - -New in SeleniumLibrary 3.0. - - - - - -as_dict=False - -Returns all cookies of the current page. - -If ``as_dict`` argument evaluates as false, see `Boolean arguments` -for more details, then cookie information is returned as -a single string in format ``name1=value1; name2=value2; name3=value3``. -When ``as_dict`` argument evaluates as true, cookie information -is returned as Robot Framework dictionary format. The string format -can be used, for example, for logging purposes or in headers when -sending HTTP requests. The dictionary format is helpful when -the result can be passed to requests library's Create Session -keyword's optional cookies parameter. - -The `` as_dict`` argument is new in SeleniumLibrary 3.3 - - - - - -locator -attribute - -Returns the value of ``attribute`` from the element ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -Example: -| ${id}= | `Get Element Attribute` | css:h1 | id | - -Passing attribute name as part of the ``locator`` was removed -in SeleniumLibrary 3.2. The explicit ``attribute`` argument -should be used instead. - - - - - -locator - -Returns the number of elements matching ``locator``. - -If you wish to assert the number of matching elements, use -`Page Should Contain Element` with ``limit`` argument. Keyword will -always return an integer. - -Example: -| ${count} = | `Get Element Count` | name:div_name | -| `Should Be True` | ${count} > 2 | | - -New in SeleniumLibrary 3.0. - - - - - -locator - -Returns width and height of the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -Both width and height are returned as integers. - -Example: -| ${width} | ${height} = | `Get Element Size` | css:div#container | - - - - - -locator - -Returns the horizontal position of the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -The position is returned in pixels off the left side of the page, -as an integer. - -See also `Get Vertical Position`. - - - - - -locator -values=False - -Returns all labels or values of selection list ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -Returns visible labels by default, but values can be returned by -setting the ``values`` argument to a true value (see `Boolean -arguments`). - -Example: -| ${labels} = | `Get List Items` | mylist | | -| ${values} = | `Get List Items` | css:#example select | values=True | - -Support to return values is new in SeleniumLibrary 3.0. - - - - - - -Returns the current browser window URL. - - - - - -browser=CURRENT - -Returns and logs URLs of all windows of the selected browser. - -*Browser Scope:* - -The ``browser`` argument specifies the browser that shall return -its windows information. - -- ``browser`` can be ``index_or_alias`` like in `Switch Browser`. - -- If ``browser`` is ``CURRENT`` (default, case-insensitive) - the currently active browser is selected. - -- If ``browser`` is ``ALL`` (case-insensitive) - the window information of all windows of all opened browsers are returned. - - - - - -locator - -Returns the label of selected option from selection list ``locator``. - -If there are multiple selected options, the label of the first option -is returned. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Returns labels of selected options from selection list ``locator``. - -Starting from SeleniumLibrary 3.0, returns an empty list if there -are no selections. In earlier versions, this caused an error. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Returns the value of selected option from selection list ``locator``. - -If there are multiple selected options, the value of the first option -is returned. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Returns values of selected options from selection list ``locator``. - -Starting from SeleniumLibrary 3.0, returns an empty list if there -are no selections. In earlier versions, this caused an error. - -See the `Locating elements` section for details about the locator -syntax. - - - - - - -Gets the implicit wait value used by Selenium. - -The value is returned as a human-readable string like ``1 second``. - -See the `Implicit wait` section above for more information. - - - - - - -Gets the delay that is waited after each Selenium command. - -The value is returned as a human-readable string like ``1 second``. - -See the `Selenium Speed` section above for more information. - - - - - - -Gets the timeout that is used by various keywords. - -The value is returned as a human-readable string like ``1 second``. - -See the `Timeout` section above for more information. - - - - - - -Returns the currently active browser session id. - -New in SeleniumLibrary 3.2 - - - - - - -Returns the entire HTML source of the current page or frame. - - - - - -locator -row -column -loglevel=TRACE - -Returns contents of a table cell. - -The table is located using the ``locator`` argument and its cell -found using ``row`` and ``column``. See the `Locating elements` -section for details about the locator syntax. - -Both row and column indexes start from 1, and header and footer -rows are included in the count. It is possible to refer to rows -and columns from the end by using negative indexes so that -1 -is the last row/column, -2 is the second last, and so on. - -All ``<th>`` and ``<td>`` elements anywhere in the table are -considered to be cells. - -See `Page Should Contain` for an explanation about the ``loglevel`` -argument. - - - - - -locator - -Returns the text value of the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - - -Returns the title of the current page. - - - - - -locator - -Returns the value attribute of the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Returns the vertical position of the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -The position is returned in pixels off the top of the page, -as an integer. - -See also `Get Horizontal Position`. - - - - - -locator - -Returns the first WebElement matching the given ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Returns a list of WebElement objects matching the ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -Starting from SeleniumLibrary 3.0, the keyword returns an empty -list if there are no matching elements. In previous releases, the -keyword failed in this case. - - - - - -browser=CURRENT - -Returns all child window handles of the selected browser as a list. - -Can be used as a list of windows to exclude with `Select Window`. - -How to select the ``browser`` scope of this keyword, see `Get Locations`. - -Prior to SeleniumLibrary 3.0, this keyword was named `List Windows`. - - - - - -browser=CURRENT - -Returns and logs id attributes of all windows of the selected browser. - -How to select the ``browser`` scope of this keyword, see `Get Locations`. - - - - - -browser=CURRENT - -Returns and logs names of all windows of the selected browser. - -How to select the ``browser`` scope of this keyword, see `Get Locations`. - - - - - - -Returns current window position. - -The position is relative to the top left corner of the screen. Returned -values are integers. See also `Set Window Position`. - -Example: -| ${x} | ${y}= | `Get Window Position` | - - - - - -inner=False - -Returns current window width and height as integers. - -See also `Set Window Size`. - -If ``inner`` parameter is set to True, keyword returns -HTML DOM window.innerWidth and window.innerHeight properties. -See `Boolean arguments` for more details on how to set boolean -arguments. The ``inner`` is new in SeleniumLibrary 4.0. - -Example: -| ${width} | ${height}= | `Get Window Size` | | -| ${width} | ${height}= | `Get Window Size` | True | - - - - - -browser=CURRENT - -Returns and logs titles of all windows of the selected browser. - -How to select the ``browser`` scope of this keyword, see `Get Locations`. - - - - - - -Simulates the user clicking the back button on their browser. - - - - - -url - -Navigates the current browser window to the provided ``url``. - - - - - -action=ACCEPT -timeout=None - -Handles the current alert and returns its message. - -By default, the alert is accepted, but this can be controlled -with the ``action`` argument that supports the following -case-insensitive values: - -- ``ACCEPT``: Accept the alert i.e. press ``Ok``. Default. -- ``DISMISS``: Dismiss the alert i.e. press ``Cancel``. -- ``LEAVE``: Leave the alert open. - -The ``timeout`` argument specifies how long to wait for the alert -to appear. If it is not given, the global default `timeout` is used -instead. - -Examples: -| Handle Alert | | | # Accept alert. | -| Handle Alert | action=DISMISS | | # Dismiss alert. | -| Handle Alert | timeout=10 s | | # Use custom timeout and accept alert. | -| Handle Alert | DISMISS | 1 min | # Use custom timeout and dismiss alert. | -| ${message} = | Handle Alert | | # Accept alert and get its message. | -| ${message} = | Handle Alert | LEAVE | # Leave alert open and get its message. | - -New in SeleniumLibrary 3.0. - - - - - -locator -password -clear=True - -Types the given password into the text field identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. See `Input Text` for ``clear`` argument details. - -Difference compared to `Input Text` is that this keyword does not -log the given password on the INFO level. Notice that if you use -the keyword like - -| Input Password | password_field | password | - -the password is shown as a normal keyword argument. A way to avoid -that is using variables like - -| Input Password | password_field | ${PASSWORD} | - -Please notice that Robot Framework logs all arguments using -the TRACE level and tests must not be executed using level below -DEBUG if the password should not be logged in any format. - -The `clear` argument is new in SeleniumLibrary 4.0. Hiding password -logging from Selenium logs is new in SeleniumLibrary 4.2. - - - - - -locator -text -clear=True - -Types the given ``text`` into the text field identified by ``locator``. - -When ``clear`` is true, the input element is cleared before -the text is typed into the element. When false, the previous text -is not cleared from the element. Use `Input Password` if you -do not want the given ``text`` to be logged. - -If [https://github.com/SeleniumHQ/selenium/wiki/Grid2|Selenium Grid] -is used and the ``text`` argument points to a file in the file system, -then this keyword prevents the Selenium to transfer the file to the -Selenium Grid hub. Instead, this keyword will send the ``text`` string -as is to the element. If a file should be transferred to the hub and -upload should be performed, please use `Choose File` keyword. - -See the `Locating elements` section for details about the locator -syntax. See the `Boolean arguments` section how Boolean values are -handled. - -Disabling the file upload the Selenium Grid node and the `clear` -argument are new in SeleniumLibrary 4.0 - - - - - -text -action=ACCEPT -timeout=None - -Types the given ``text`` into an input field in an alert. - -The alert is accepted by default, but that behavior can be controlled -by using the ``action`` argument same way as with `Handle Alert`. - -``timeout`` specifies how long to wait for the alert to appear. -If it is not given, the global default `timeout` is used instead. - -New in SeleniumLibrary 3.0. - - - - - -locator -*expected - -Verifies selection list ``locator`` has ``expected`` options selected. - -It is possible to give expected options both as visible labels and -as values. Starting from SeleniumLibrary 3.0, mixing labels and -values is not possible. Order of the selected options is not -validated. - -If no expected options are given, validates that the list has -no selections. A more explicit alternative is using `List Should -Have No Selections`. - -See the `Locating elements` section for details about the locator -syntax. - -Examples: -| `List Selection Should Be` | gender | Female | | -| `List Selection Should Be` | interests | Test Automation | Python | - - - - - -locator - -Verifies selection list ``locator`` has no options selected. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -url -message=None - -Verifies that the current URL is exactly ``url``. - -The ``url`` argument contains the exact url that should exist in browser. - -The ``message`` argument can be used to override the default error -message. - -``message`` argument is new in SeleniumLibrary 3.2.0. - - - - - -expected -message=None - -Verifies that the current URL contains ``expected``. - -The ``expected`` argument contains the expected value in url. - -The ``message`` argument can be used to override the default error -message. - -``message`` argument is new in SeleniumLibrary 3.2.0. - - - - - -locator -x -message=None -loglevel=TRACE - -*DEPRECATED in SeleniumLibrary 4.0.*, use `Page Should Contain Element` with ``limit`` argument instead. - - - - - - -Logs and returns the current browser window URL. - - - - - -loglevel=INFO - -Logs and returns the HTML source of the current page or frame. - -The ``loglevel`` argument defines the used log level. Valid log -levels are ``WARN``, ``INFO`` (default), ``DEBUG``, ``TRACE`` -and ``NONE`` (no logging). - - - - - - -Logs and returns the title of the current page. - - - - - - -Maximizes current browser window. - - - - - -locator - -Simulates pressing the left mouse button on the element ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -The element is pressed without releasing the mouse button. - -See also the more specific keywords `Mouse Down On Image` and -`Mouse Down On Link`. - - - - - -locator - -Simulates a mouse down event on an image identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, images are searched -using ``id``, ``name``, ``src`` and ``alt``. - - - - - -locator - -Simulates a mouse down event on a link identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, links are searched -using ``id``, ``name``, ``href`` and the link text. - - - - - -locator - -Simulates moving the mouse away from the element ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Simulates hovering the mouse over the element ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Simulates releasing the left mouse button on the element ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -url=None -browser=firefox -alias=None -remote_url=False -desired_capabilities=None -ff_profile_dir=None -options=None -service_log_path=None -executable_path=None - -Opens a new browser instance to the optional ``url``. - -The ``browser`` argument specifies which browser to use. The -supported browsers are listed in the table below. The browser names -are case-insensitive and some browsers have multiple supported names. - -| = Browser = | = Name(s) = | -| Firefox | firefox, ff | -| Google Chrome | googlechrome, chrome, gc | -| Headless Firefox | headlessfirefox | -| Headless Chrome | headlesschrome | -| Internet Explorer | internetexplorer, ie | -| Edge | edge | -| Safari | safari | -| Opera | opera | -| Android | android | -| Iphone | iphone | -| PhantomJS | phantomjs | -| HTMLUnit | htmlunit | -| HTMLUnit with Javascript | htmlunitwithjs | - -To be able to actually use one of these browsers, you need to have -a matching Selenium browser driver available. See the -[https://github.com/robotframework/SeleniumLibrary#browser-drivers| -project documentation] for more details. Headless Firefox and -Headless Chrome are new additions in SeleniumLibrary 3.1.0 -and require Selenium 3.8.0 or newer. - -After opening the browser, it is possible to use optional -``url`` to navigate the browser to the desired address. - -Optional ``alias`` is an alias given for this browser instance and -it can be used for switching between browsers. When same ``alias`` -is given with two `Open Browser` keywords, the first keyword will -open a new browser, but the second one will switch to the already -opened browser and will not open a new browser. The ``alias`` -definition overrules ``browser`` definition. When same ``alias`` -is used but a different ``browser`` is defined, then switch to -a browser with same alias is done and new browser is not opened. -An alternative approach for switching is using an index returned -by this keyword. These indices start from 1, are incremented when new -browsers are opened, and reset back to 1 when `Close All Browsers` -is called. See `Switch Browser` for more information and examples. - -Optional ``remote_url`` is the URL for a -[https://github.com/SeleniumHQ/selenium/wiki/Grid2|Selenium Grid]. - -Optional ``desired_capabilities`` can be used to configure, for example, -logging preferences for a browser or a browser and operating system -when using [http://saucelabs.com|Sauce Labs]. Desired capabilities can -be given either as a Python dictionary or as a string in the format -``key1:value1,key2:value2``. -[https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities| -Selenium documentation] lists possible capabilities that can be -enabled. - -Optional ``ff_profile_dir`` is the path to the Firefox profile -directory if you wish to overwrite the default profile Selenium -uses. Notice that prior to SeleniumLibrary 3.0, the library -contained its own profile that was used by default. The -``ff_profile_dir`` can also be an instance of the -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_firefox/selenium.webdriver.firefox.firefox_profile.html|selenium.webdriver.FirefoxProfile] -. As a third option, it is possible to use `FirefoxProfile` methods -and attributes to define the profile using methods and attributes -in the same way as with ``options`` argument. Example: It is possible -to use FirefoxProfile `set_preference` to define different -profile settings. See ``options`` argument documentation in below -how to handle backslash escaping. - -Optional ``options`` argument allows defining browser specific -Selenium options. Example for Chrome, the ``options`` argument -allows defining the following -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_chrome/selenium.webdriver.chrome.options.html#selenium.webdriver.chrome.options.Options|methods and attributes] -and for Firefox these -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_firefox/selenium.webdriver.firefox.options.html?highlight=firefox#selenium.webdriver.firefox.options.Options|methods and attributes] -are available. Please note that not all browsers, supported by the -SeleniumLibrary, have Selenium options available. Therefore please -consult the Selenium documentation which browsers do support -the Selenium options. If ``browser`` argument is `android` then -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_chrome/selenium.webdriver.chrome.options.html#selenium.webdriver.chrome.options.Options|Chrome options] -is used. Selenium options are also supported, when ``remote_url`` -argument is used. - -The SeleniumLibrary ``options`` argument accepts Selenium -options in two different formats: as a string and as Python object -which is an instance of the Selenium options class. - -The string format allows defining Selenium options methods -or attributes and their arguments in Robot Framework test data. -The method and attributes names are case and space sensitive and -must match to the Selenium options methods and attributes names. -When defining a method, it must be defined in a similar way as in -python: method name, opening parenthesis, zero to many arguments -and closing parenthesis. If there is a need to define multiple -arguments for a single method, arguments must be separated with -comma, just like in Python. Example: `add_argument("--headless")` -or `add_experimental_option("key", "value")`. Attributes are -defined in a similar way as in Python: attribute name, equal sign, -and attribute value. Example, `headless=True`. Multiple methods -and attributes must be separated by a semicolon. Example: -`add_argument("--headless");add_argument("--start-maximized")`. - -Arguments allow defining Python data types and arguments are -evaluated by using Python -[https://docs.python.org/3/library/ast.html#ast.literal_eval|ast.literal_eval]. -Strings must be quoted with single or double quotes, example "value" -or 'value'. It is also possible to define other Python builtin -data types, example `True` or `None`, by not using quotes -around the arguments. - -The string format is space friendly. Usually, spaces do not alter -the defining methods or attributes. There are two exceptions. -In some Robot Framework test data formats, two or more spaces are -considered as cell separator and instead of defining a single -argument, two or more arguments may be defined. Spaces in string -arguments are not removed and are left as is. Example -`add_argument ( "--headless" )` is same as -`add_argument("--headless")`. But `add_argument(" --headless ")` is -not same same as `add_argument ( "--headless" )`, because -spaces inside of quotes are not removed. Please note that if -options string contains backslash, example a Windows OS path, -the backslash needs escaping both in Robot Framework data and -in Python side. This means single backslash must be writen using -four backslash characters. Example, Windows path: -"C:\path\to\profile" must be written as -"C:\\\\path\\\to\\\\profile". Another way to write -backslash is use Python -[https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals|raw strings] -and example write: r"C:\\path\\to\\profile". - -As last format, ``options`` argument also supports receiving -the Selenium options as Python class instance. In this case, the -instance is used as-is and the SeleniumLibrary will not convert -the instance to other formats. -For example, if the following code return value is saved to -`${options}` variable in the Robot Framework data: -| options = webdriver.ChromeOptions() -| options.add_argument('--disable-dev-shm-usage') -| return options - -Then the `${options}` variable can be used as an argument to -``options``. - -Example the ``options`` argument can be used to launch Chomium-based -applications which utilize the -[https://bitbucket.org/chromiumembedded/cef/wiki/UsingChromeDriver|Chromium Embedded Framework] -. To lauch Chomium-based application, use ``options`` to define -`binary_location` attribute and use `add_argument` method to define -`remote-debugging-port` port for the application. Once the browser -is opened, the test can interact with the embedded web-content of -the system under test. - -Optional ``service_log_path`` argument defines the name of the -file where to write the browser driver logs. If the -``service_log_path`` argument contain a marker ``{index}``, it -will be automatically replaced with unique running -index preventing files to be overwritten. Indices start's from 1, -and how they are represented can be customized using Python's -[https://docs.python.org/3/library/string.html#format-string-syntax| -format string syntax]. - -Optional ``executable_path`` argument defines the path to the driver -executable, example to a chromedriver or a geckodriver. If not defined -it is assumed the executable is in the -[https://en.wikipedia.org/wiki/PATH_(variable)|$PATH]. - -Examples: -| `Open Browser` | http://example.com | Chrome | | -| `Open Browser` | http://example.com | Firefox | alias=Firefox | -| `Open Browser` | http://example.com | Edge | remote_url=http://127.0.0.1:4444/wd/hub | -| `Open Browser` | about:blank | | | -| `Open Browser` | browser=Chrome | | | - -Alias examples: -| ${1_index} = | `Open Browser` | http://example.com | Chrome | alias=Chrome | # Opens new browser because alias is new. | -| ${2_index} = | `Open Browser` | http://example.com | Firefox | | # Opens new browser because alias is not defined. | -| ${3_index} = | `Open Browser` | http://example.com | Chrome | alias=Chrome | # Switches to the browser with Chrome alias. | -| ${4_index} = | `Open Browser` | http://example.com | Chrome | alias=${1_index} | # Switches to the browser with Chrome alias. | -| Should Be Equal | ${1_index} | ${3_index} | | | | -| Should Be Equal | ${1_index} | ${4_index} | | | | -| Should Be Equal | ${2_index} | ${2} | | | | - -Example when using -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver_chrome/selenium.webdriver.chrome.options.html#selenium.webdriver.chrome.options.Options|Chrome options] -method: -| `Open Browser` | http://example.com | Chrome | options=add_argument("--disable-popup-blocking"); add_argument("--ignore-certificate-errors") | # Sting format. | -| ${options} = | Get Options | | | # Selenium options instance. | -| `Open Browser` | http://example.com | Chrome | options=${options} | | -| `Open Browser` | None | Chrome | options=binary_location="/path/to/binary";add_argument("remote-debugging-port=port") | # Start Chomium-based application. | -| `Open Browser` | None | Chrome | options=binary_location=r"C:\\path\\to\\binary" | # Windows OS path escaping. | - -Example for FirefoxProfile -| `Open Browser` | http://example.com | Firefox | ff_profile_dir=/path/to/profile | # Using profile from disk. | -| `Open Browser` | http://example.com | Firefox | ff_profile_dir=${FirefoxProfile_instance} | # Using instance of FirefoxProfile. | -| `Open Browser` | http://example.com | Firefox | ff_profile_dir=set_preference("key", "value");set_preference("other", "setting") | # Defining profile using FirefoxProfile mehtods. | - -If the provided configuration options are not enough, it is possible -to use `Create Webdriver` to customize browser initialization even -more. - -Applying ``desired_capabilities`` argument also for local browser is -new in SeleniumLibrary 3.1. - -Using ``alias`` to decide, is the new browser opened is new -in SeleniumLibrary 4.0. The ``options`` and ``service_log_path`` -are new in SeleniumLibrary 4.0. Support for ``ff_profile_dir`` -accepting an instance of the `selenium.webdriver.FirefoxProfile` -and support defining FirefoxProfile with methods and -attributes are new in SeleniumLibrary 4.0. - -Making ``url`` optional is new in SeleniumLibrary 4.1. - -The ``executable_path`` argument is new in SeleniumLibrary 4.2. - - - - - -locator - -Opens the context menu on the element identified by ``locator``. - - - - - -text -loglevel=TRACE - -Verifies that current page contains ``text``. - -If this keyword fails, it automatically logs the page source -using the log level specified with the optional ``loglevel`` -argument. Valid log levels are ``DEBUG``, ``INFO`` (default), -``WARN``, and ``NONE``. If the log level is ``NONE`` or below -the current active log level the source will not be logged. - - - - - -locator -message=None -loglevel=TRACE - -Verifies button ``locator`` is found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, buttons are -searched using ``id``, ``name``, and ``value``. - - - - - -locator -message=None -loglevel=TRACE - -Verifies checkbox ``locator`` is found from the current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -message=None -loglevel=TRACE -limit=None - -Verifies that element ``locator`` is found on the current page. - -See the `Locating elements` section for details about the locator -syntax. - -The ``message`` argument can be used to override the default error -message. - -The ``limit`` argument can used to define how many elements the -page should contain. When ``limit`` is ``None`` (default) page can -contain one or more elements. When limit is a number, page must -contain same number of elements. - -See `Page Should Contain` for an explanation about the ``loglevel`` -argument. - -Examples assumes that locator matches to two elements. -| `Page Should Contain Element` | div_name | limit=1 | # Keyword fails. | -| `Page Should Contain Element` | div_name | limit=2 | # Keyword passes. | -| `Page Should Contain Element` | div_name | limit=none | # None is considered one or more. | -| `Page Should Contain Element` | div_name | | # Same as above. | - -The ``limit`` argument is new in SeleniumLibrary 3.0. - - - - - -locator -message=None -loglevel=TRACE - -Verifies image identified by ``locator`` is found from current page. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, images are searched -using ``id``, ``name``, ``src`` and ``alt``. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - - - - - -locator -message=None -loglevel=TRACE - -Verifies link identified by ``locator`` is found from current page. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, links are searched -using ``id``, ``name``, ``href`` and the link text. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - - - - - -locator -message=None -loglevel=TRACE - -Verifies selection list ``locator`` is found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -message=None -loglevel=TRACE - -Verifies radio button ``locator`` is found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, radio buttons are -searched using ``id``, ``name`` and ``value``. - - - - - -locator -message=None -loglevel=TRACE - -Verifies text field ``locator`` is found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -text -loglevel=TRACE - -Verifies the current page does not contain ``text``. - -See `Page Should Contain` for an explanation about the ``loglevel`` -argument. - - - - - -locator -message=None -loglevel=TRACE - -Verifies button ``locator`` is not found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, buttons are -searched using ``id``, ``name``, and ``value``. - - - - - -locator -message=None -loglevel=TRACE - -Verifies checkbox ``locator`` is not found from the current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -message=None -loglevel=TRACE - -Verifies that element ``locator`` is found on the current page. - -See the `Locating elements` section for details about the locator -syntax. - -See `Page Should Contain` for an explanation about ``message`` and -``loglevel`` arguments. - - - - - -locator -message=None -loglevel=TRACE - -Verifies image identified by ``locator`` is found from current page. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, images are searched -using ``id``, ``name``, ``src`` and ``alt``. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - - - - - -locator -message=None -loglevel=TRACE - -Verifies link identified by ``locator`` is not found from current page. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, links are searched -using ``id``, ``name``, ``href`` and the link text. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - - - - - -locator -message=None -loglevel=TRACE - -Verifies selection list ``locator`` is not found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -message=None -loglevel=TRACE - -Verifies radio button ``locator`` is not found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. When using the default locator strategy, radio buttons are -searched using ``id``, ``name`` and ``value``. - - - - - -locator -message=None -loglevel=TRACE - -Verifies text field ``locator`` is not found from current page. - -See `Page Should Contain Element` for an explanation about ``message`` -and ``loglevel`` arguments. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -key - -*DEPRECATED in SeleniumLibrary 4.0.* use `Press Keys` instead. - - - - - -locator=None -*keys - -Simulates the user pressing key(s) to an element or on the active browser. - -If ``locator`` evaluates as false, see `Boolean arguments` for more -details, then the ``keys`` are sent to the currently active browser. -Otherwise element is searched and ``keys`` are send to the element -identified by the ``locator``. In later case, keyword fails if element -is not found. See the `Locating elements` section for details about -the locator syntax. - -``keys`` arguments can contain one or many strings, but it can not -be empty. ``keys`` can also be a combination of -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html|Selenium Keys] -and strings or a single Selenium Key. If Selenium Key is combined -with strings, Selenium key and strings must be separated by the -`+` character, like in `CONTROL+c`. Selenium Keys -are space and case sensitive and Selenium Keys are not parsed -inside of the string. Example AALTO, would send string `AALTO` -and `ALT` not parsed inside of the string. But `A+ALT+O` would -found Selenium ALT key from the ``keys`` argument. It also possible -to press many Selenium Keys down at the same time, example -'ALT+ARROW_DOWN`. - -If Selenium Keys are detected in the ``keys`` argument, keyword -will press the Selenium Key down, send the strings and - then release the Selenium Key. If keyword needs to send a Selenium -Key as a string, then each character must be separated with -`+` character, example `E+N+D`. - -`CTRL` is alias for -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys.CONTROL|Selenium CONTROL] -and ESC is alias for -[https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys.ESCAPE|Selenium ESCAPE] - -New in SeleniumLibrary 3.3 - -Examples: -| `Press Keys` | text_field | AAAAA | | # Sends string "AAAAA" to element. | -| `Press Keys` | None | BBBBB | | # Sends string "BBBBB" to currently active browser. | -| `Press Keys` | text_field | E+N+D | | # Sends string "END" to element. | -| `Press Keys` | text_field | XXX | YY | # Sends strings "XXX" and "YY" to element. | -| `Press Keys` | text_field | XXX+YY | | # Same as above. | -| `Press Keys` | text_field | ALT+ARROW_DOWN | | # Pressing "ALT" key down, then pressing ARROW_DOWN and then releasing both keys. | -| `Press Keys` | text_field | ALT | ARROW_DOWN | # Pressing "ALT" key and then pressing ARROW_DOWN. | -| `Press Keys` | text_field | CTRL+c | | # Pressing CTRL key down, sends string "c" and then releases CTRL key. | -| `Press Keys` | button | RETURN | | # Pressing "ENTER" key to element. | - - - - - -group_name -value - -Verifies radio button group ``group_name`` is set to ``value``. - -``group_name`` is the ``name`` of the radio button group. - - - - - -group_name - -Verifies radio button group ``group_name`` has no selection. - -``group_name`` is the ``name`` of the radio button group. - - - - - -keyword - -Sets the keyword to execute, when a SeleniumLibrary keyword fails. - -``keyword`` is the name of a keyword that will be executed if a -SeleniumLibrary keyword fails. It is possible to use any available -keyword, including user keywords or keywords from other libraries, -but the keyword must not take any arguments. - -The initial keyword to use is set when `importing` the library, and -the keyword that is used by default is `Capture Page Screenshot`. -Taking a screenshot when something failed is a very useful -feature, but notice that it can slow down the execution. - -It is possible to use string ``NOTHING`` or ``NONE``, -case-insensitively, as well as Python ``None`` to disable this -feature altogether. - -This keyword returns the name of the previously registered -failure keyword or Python ``None`` if this functionality was -previously disabled. The return value can be always used to -restore the original value later. - -Example: -| `Register Keyword To Run On Failure` | Log Source | -| ${previous kw}= | `Register Keyword To Run On Failure` | NONE | -| `Register Keyword To Run On Failure` | ${previous kw} | - -Changes in SeleniumLibrary 3.0: -- Possible to use string ``NONE`` or Python ``None`` to disable the - functionality. -- Return Python ``None`` when the functionality was disabled earlier. - In previous versions special value ``No Keyword`` was returned and - it could not be used to restore the original state. - - - - - - -Simulates user reloading page. - - - - - -strategy_name - -Removes a previously added custom location strategy. - -See `Custom locators` for information on how to create and use -custom strategies. - - - - - -locator - -Scrolls the element identified by ``locator`` into view. - -See the `Locating elements` section for details about the locator -syntax. - -New in SeleniumLibrary 3.2.0 - - - - - -locator - -Selects all options from multi-selection list ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Selects the checkbox identified by ``locator``. - -Does nothing if checkbox is already selected. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator - -Sets frame identified by ``locator`` as the current frame. - -See the `Locating elements` section for details about the locator -syntax. - -Works both with frames and iframes. Use `Unselect Frame` to cancel -the frame selection and return to the main frame. - -Example: -| `Select Frame` | top-frame | # Select frame with id or name 'top-frame' | -| `Click Link` | example | # Click link 'example' in the selected frame | -| `Unselect Frame` | | # Back to main frame. | -| `Select Frame` | //iframe[@name='xxx'] | # Select frame using xpath | - - - - - -locator -*indexes - -Selects options from selection list ``locator`` by ``indexes``. - -Indexes of list options start from 0. - -If more than one option is given for a single-selection list, -the last value will be selected. With multi-selection lists all -specified options are selected, but possible old selections are -not cleared. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -*labels - -Selects options from selection list ``locator`` by ``labels``. - -If more than one option is given for a single-selection list, -the last value will be selected. With multi-selection lists all -specified options are selected, but possible old selections are -not cleared. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -*values - -Selects options from selection list ``locator`` by ``values``. - -If more than one option is given for a single-selection list, -the last value will be selected. With multi-selection lists all -specified options are selected, but possible old selections are -not cleared. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -group_name -value - -Sets the radio button group ``group_name`` to ``value``. - -The radio button to be selected is located by two arguments: -- ``group_name`` is the name of the radio button group. -- ``value`` is the ``id`` or ``value`` attribute of the actual - radio button. - -Examples: -| `Select Radio Button` | size | XL | -| `Select Radio Button` | contact | email | - - - - - -locator=MAIN -timeout=None - -DEPRECATED in SeleniumLibrary 4.0. , use `Switch Window` instead. - - - - - -value - -Sets the implicit wait value used by Selenium. - -Same as `Set Selenium Implicit Wait` but only affects the current -browser. - - - - - -locator - -Sets the focus to the element identified by ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -Prior to SeleniumLibrary 3.0 this keyword was named `Focus`. - - - - - -path - -Sets the directory for captured screenshots. - -``path`` argument specifies the absolute path to a directory where -the screenshots should be written to. If the directory does not -exist, it will be created. The directory can also be set when -`importing` the library. If it is not configured anywhere, -screenshots are saved to the same directory where Robot Framework's -log file is written. - -If ``path`` equals to EMBED (case insensitive) and -`Capture Page Screenshot` or `capture Element Screenshot` keywords -filename argument is not changed from the default value, then -the page or element screenshot is embedded as Base64 image to -the log.html. - -The previous value is returned and can be used to restore -the original value later if needed. - -Returning the previous value is new in SeleniumLibrary 3.0. -The persist argument was removed in SeleniumLibrary 3.2 and -EMBED is new in SeleniumLibrary 4.2. - - - - - -value - -Sets the implicit wait value used by Selenium. - -The value can be given as a number that is considered to be -seconds or as a human-readable string like ``1 second``. -The previous value is returned and can be used to restore -the original value later if needed. - -This keyword sets the implicit wait for all opened browsers. -Use `Set Browser Implicit Wait` to set it only to the current -browser. - -See the `Implicit wait` section above for more information. - -Example: -| ${orig wait} = | `Set Selenium Implicit Wait` | 10 seconds | -| `Perform AJAX call that is slow` | -| `Set Selenium Implicit Wait` | ${orig wait} | - - - - - -value - -Sets the delay that is waited after each Selenium command. - -The value can be given as a number that is considered to be -seconds or as a human-readable string like ``1 second``. -The previous value is returned and can be used to restore -the original value later if needed. - -See the `Selenium Speed` section above for more information. - -Example: -| `Set Selenium Speed` | 0.5 seconds | - - - - - -value - -Sets the timeout that is used by various keywords. - -The value can be given as a number that is considered to be -seconds or as a human-readable string like ``1 second``. -The previous value is returned and can be used to restore -the original value later if needed. - -See the `Timeout` section above for more information. - -Example: -| ${orig timeout} = | `Set Selenium Timeout` | 15 seconds | -| `Open page that loads slowly` | -| `Set Selenium Timeout` | ${orig timeout} | - - - - - -x -y - -Sets window position using ``x`` and ``y`` coordinates. - -The position is relative to the top left corner of the screen, -but some browsers exclude possible task bar set by the operating -system from the calculation. The actual position may thus be -different with different browsers. - -Values can be given using strings containing numbers or by using -actual numbers. See also `Get Window Position`. - -Example: -| `Set Window Position` | 100 | 200 | - - - - - -width -height -inner=False - -Sets current windows size to given ``width`` and ``height``. - -Values can be given using strings containing numbers or by using -actual numbers. See also `Get Window Size`. - -Browsers have a limit on their minimum size. Trying to set them -smaller will cause the actual size to be bigger than the requested -size. - -If ``inner`` parameter is set to True, keyword sets the necessary -window width and height to have the desired HTML DOM _window.innerWidth_ -and _window.innerHeight_. See `Boolean arguments` for more details on how to set boolean -arguments. - -The ``inner`` argument is new since SeleniumLibrary 4.0. - -This ``inner`` argument does not support Frames. If a frame is selected, -switch to default before running this. - -Example: -| `Set Window Size` | 800 | 600 | | -| `Set Window Size` | 800 | 600 | True | - - - - - -locator -event - -Simulates ``event`` on the element identified by ``locator``. - -This keyword is useful if element has ``OnEvent`` handler that -needs to be explicitly invoked. - -See the `Locating elements` section for details about the locator -syntax. - -Prior to SeleniumLibrary 3.0 this keyword was named `Simulate`. - - - - - -locator=None - -Submits a form identified by ``locator``. - -If ``locator`` is not given, first form on the page is submitted. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -index_or_alias - -Switches between active browsers using ``index_or_alias``. - -Indices are returned by the `Open Browser` keyword and aliases can -be given to it explicitly. Indices start from 1. - -Example: -| `Open Browser` | http://google.com | ff | -| `Location Should Be` | http://google.com | | -| `Open Browser` | http://yahoo.com | ie | alias=second | -| `Location Should Be` | http://yahoo.com | | -| `Switch Browser` | 1 | # index | -| `Page Should Contain` | I'm feeling lucky | | -| `Switch Browser` | second | # alias | -| `Page Should Contain` | More Yahoo! | | -| `Close All Browsers` | | | - -Above example expects that there was no other open browsers when -opening the first one because it used index ``1`` when switching to -it later. If you are not sure about that, you can store the index -into a variable as below. - -| ${index} = | `Open Browser` | http://google.com | -| # Do something ... | | | -| `Switch Browser` | ${index} | | - - - - - -locator=MAIN -timeout=None -browser=CURRENT - -Switches to browser window matching ``locator``. - -If the window is found, all subsequent commands use the selected -window, until this keyword is used again. If the window is not -found, this keyword fails. The previous windows handle is returned -and can be used to switch back to it later. - -Notice that alerts should be handled with -`Handle Alert` or other alert related keywords. - -The ``locator`` can be specified using different strategies somewhat -similarly as when `locating elements` on pages. - -- By default, the ``locator`` is matched against window handle, name, - title, and URL. Matching is done in that order and the first - matching window is selected. - -- The ``locator`` can specify an explicit strategy by using the format - ``strategy:value`` (recommended) or ``strategy=value``. Supported - strategies are ``name``, ``title``, and ``url``. These matches windows - using their name, title, or URL, respectively. Additionally, ``default`` - can be used to explicitly use the default strategy explained above. - -- If the ``locator`` is ``NEW`` (case-insensitive), the latest - opened window is selected. It is an error if this is the same - as the current window. - -- If the ``locator`` is ``MAIN`` (default, case-insensitive), - the main window is selected. - -- If the ``locator`` is ``CURRENT`` (case-insensitive), nothing is - done. This effectively just returns the current window handle. - -- If the ``locator`` is not a string, it is expected to be a list - of window handles _to exclude_. Such a list of excluded windows - can be got from `Get Window Handles` before doing an action that - opens a new window. - -The ``timeout`` is used to specify how long keyword will poll to select -the new window. The ``timeout`` is new in SeleniumLibrary 3.2. - -Example: -| `Click Link` | popup1 | | # Open new window | -| `Switch Window` | example | | # Select window using default strategy | -| `Title Should Be` | Pop-up 1 | | -| `Click Button` | popup2 | | # Open another window | -| ${handle} = | `Switch Window` | NEW | # Select latest opened window | -| `Title Should Be` | Pop-up 2 | | -| `Switch Window` | ${handle} | | # Select window using handle | -| `Title Should Be` | Pop-up 1 | | -| `Switch Window` | MAIN | | # Select the main window | -| `Title Should Be` | Main | | -| ${excludes} = | `Get Window Handles` | | # Get list of current windows | -| `Click Link` | popup3 | | # Open one more window | -| `Switch Window` | ${excludes} | | # Select window using excludes | -| `Title Should Be` | Pop-up 3 | | - -The ``browser`` argument allows with ``index_or_alias`` to implicitly switch to -a specific browser when switching to a window. See `Switch Browser` - -- If the ``browser`` is ``CURRENT`` (case-insensitive), no other browser is - selected. - -*NOTE:* - -- The ``strategy:value`` syntax is only supported by SeleniumLibrary - 3.0 and newer. -- Prior to SeleniumLibrary 3.0 matching windows by name, title - and URL was case-insensitive. -- Earlier versions supported aliases ``None``, ``null`` and the - empty string for selecting the main window, and alias ``self`` - for selecting the current window. Support for these aliases was - removed in SeleniumLibrary 3.2. - - - - - -locator -row -column -expected -loglevel=TRACE - -Verifies table cell contains text ``expected``. - -See `Get Table Cell` that this keyword uses internally for -an explanation about accepted arguments. - - - - - -locator -column -expected -loglevel=TRACE - -Verifies table column contains text ``expected``. - -The table is located using the ``locator`` argument and its column -found using ``column``. See the `Locating elements` section for -details about the locator syntax. - -Column indexes start from 1. It is possible to refer to columns -from the end by using negative indexes so that -1 is the last column, --2 is the second last, and so on. - -If a table contains cells that span multiple columns, those merged -cells count as a single column. - -See `Page Should Contain Element` for an explanation about the -``loglevel`` argument. - - - - - -locator -expected -loglevel=TRACE - -Verifies table footer contains text ``expected``. - -Any ``<td>`` element inside ``<tfoot>`` element is considered to -be part of the footer. - -The table is located using the ``locator`` argument. See the -`Locating elements` section for details about the locator syntax. - -See `Page Should Contain Element` for an explanation about the -``loglevel`` argument. - - - - - -locator -expected -loglevel=TRACE - -Verifies table header contains text ``expected``. - -Any ``<th>`` element anywhere in the table is considered to be -part of the header. - -The table is located using the ``locator`` argument. See the -`Locating elements` section for details about the locator syntax. - -See `Page Should Contain Element` for an explanation about the -``loglevel`` argument. - - - - - -locator -row -expected -loglevel=TRACE - -Verifies that table row contains text ``expected``. - -The table is located using the ``locator`` argument and its column -found using ``column``. See the `Locating elements` section for -details about the locator syntax. - -Row indexes start from 1. It is possible to refer to rows -from the end by using negative indexes so that -1 is the last row, --2 is the second last, and so on. - -If a table contains cells that span multiple rows, a match -only occurs for the uppermost row of those merged cells. - -See `Page Should Contain Element` for an explanation about the -``loglevel`` argument. - - - - - -locator -expected -loglevel=TRACE - -Verifies table contains text ``expected``. - -The table is located using the ``locator`` argument. See the -`Locating elements` section for details about the locator syntax. - -See `Page Should Contain Element` for an explanation about the -``loglevel`` argument. - - - - - -locator -expected -message=None - -Verifies text area ``locator`` contains text ``expected``. - -``message`` can be used to override default error message. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -expected -message=None - -Verifies text area ``locator`` has exactly text ``expected``. - -``message`` can be used to override default error message. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -expected -message=None - -Verifies text field ``locator`` contains text ``expected``. - -``message`` can be used to override the default error message. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -expected -message=None - -Verifies text field ``locator`` has exactly text ``expected``. - -``message`` can be used to override default error message. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -title -message=None - -Verifies that the current page title equals ``title``. - -The ``message`` argument can be used to override the default error -message. - -``message`` argument is new in SeleniumLibrary 3.1. - - - - - -locator - -Unselects all options from multi-selection list ``locator``. - -See the `Locating elements` section for details about the locator -syntax. - -New in SeleniumLibrary 3.0. - - - - - -locator - -Removes the selection of checkbox identified by ``locator``. - -Does nothing if the checkbox is not selected. - -See the `Locating elements` section for details about the locator -syntax. - - - - - - -Sets the main frame as the current frame. - -In practice cancels the previous `Select Frame` call. - - - - - -locator -*indexes - -Unselects options from selection list ``locator`` by ``indexes``. - -Indexes of list options start from 0. This keyword works only with -multi-selection lists. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -*labels - -Unselects options from selection list ``locator`` by ``labels``. - -This keyword works only with multi-selection lists. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -locator -*values - -Unselects options from selection list ``locator`` by ``values``. - -This keyword works only with multi-selection lists. - -See the `Locating elements` section for details about the locator -syntax. - - - - - -condition -timeout=None -error=None - -Waits until ``condition`` is true or ``timeout`` expires. - -The condition can be arbitrary JavaScript expression but it -must return a value to be evaluated. See `Execute JavaScript` for -information about accessing content on pages. - -Fails if the timeout expires before the condition becomes true. See -the `Timeouts` section for more information about using timeouts -and their default value. - -``error`` can be used to override the default error message. - -Examples: -| `Wait For Condition` | return document.title == "New Title" | -| `Wait For Condition` | return jQuery.active == 0 | -| `Wait For Condition` | style = document.querySelector('h1').style; return style.background == "red" && style.color == "white" | - - - - - -locator -text -timeout=None -error=None - -Waits until the element ``locator`` contains ``text``. - -Fails if ``timeout`` expires before the text appears. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - - - - - -locator -text -timeout=None -error=None - -Waits until the element ``locator`` does not contain ``text``. - -Fails if ``timeout`` expires before the text disappears. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - - - - - -locator -timeout=None -error=None - -Waits until the element ``locator`` is enabled. - -Element is considered enabled if it is not disabled nor read-only. - -Fails if ``timeout`` expires before the element is enabled. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - -Considering read-only elements to be disabled is a new feature -in SeleniumLibrary 3.0. - - - - - -locator -timeout=None -error=None - -Waits until the element ``locator`` is not visible. - -Fails if ``timeout`` expires before the element is not visible. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - - - - - -locator -timeout=None -error=None - -Waits until the element ``locator`` is visible. - -Fails if ``timeout`` expires before the element is visible. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - - - - - -expected -timeout=None -message=None - -Waits until the current URL contains ``expected``. - -The ``expected`` argument contains the expected value in url. - -Fails if ``timeout`` expires before the location contains. See -the `Timeouts` section for more information about using timeouts -and their default value. - -The ``message`` argument can be used to override the default error -message. - -New in SeleniumLibrary 4.0 - - - - - -location -timeout=None -message=None - -Waits until the current URL does not contains ``location``. - -The ``location`` argument contains value not expected in url. - -Fails if ``timeout`` expires before the location not contains. See -the `Timeouts` section for more information about using timeouts -and their default value. - -The ``message`` argument can be used to override the default error -message. - -New in SeleniumLibrary 4.3 - - - - - -expected -timeout=None -message=None - -Waits until the current URL is ``expected``. - -The ``expected`` argument is the expected value in url. - -Fails if ``timeout`` expires before the location is. See -the `Timeouts` section for more information about using timeouts -and their default value. - -The ``message`` argument can be used to override the default error -message. - -New in SeleniumLibrary 4.0 - - - - - -location -timeout=None -message=None - -Waits until the current URL is not ``location``. - -The ``location`` argument is the unexpected value in url. - -Fails if ``timeout`` expires before the location is not. See -the `Timeouts` section for more information about using timeouts -and their default value. - -The ``message`` argument can be used to override the default error -message. - -New in SeleniumLibrary 4.3 - - - - - -text -timeout=None -error=None - -Waits until ``text`` appears on the current page. - -Fails if ``timeout`` expires before the text appears. See -the `Timeouts` section for more information about using timeouts -and their default value. - -``error`` can be used to override the default error message. - - - - - -locator -timeout=None -error=None - -Waits until the element ``locator`` appears on the current page. - -Fails if ``timeout`` expires before the element appears. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - - - - - -text -timeout=None -error=None - -Waits until ``text`` disappears from the current page. - -Fails if ``timeout`` expires before the text disappears. See -the `Timeouts` section for more information about using timeouts -and their default value. - -``error`` can be used to override the default error message. - - - - - -locator -timeout=None -error=None - -Waits until the element ``locator`` disappears from the current page. - -Fails if ``timeout`` expires before the element disappears. See -the `Timeouts` section for more information about using timeouts and -their default value and the `Locating elements` section for details -about the locator syntax. - -``error`` can be used to override the default error message. - - - - diff --git a/libspecs/String.libspec b/libspecs/String.libspec deleted file mode 100644 index e36e617..0000000 --- a/libspecs/String.libspec +++ /dev/null @@ -1,722 +0,0 @@ - - -3.1.2 -global -yes -A test library for string manipulation and verification. - -``String`` is Robot Framework's standard library for manipulating -strings (e.g. `Replace String Using Regexp`, `Split To Lines`) and -verifying their contents (e.g. `Should Be String`). - -Following keywords from ``BuiltIn`` library can also be used with strings: - -- `Catenate` -- `Get Length` -- `Length Should Be` -- `Should (Not) Be Empty` -- `Should (Not) Be Equal (As Strings/Integers/Numbers)` -- `Should (Not) Match (Regexp)` -- `Should (Not) Contain` -- `Should (Not) Start With` -- `Should (Not) End With` -- `Convert To String` -- `Convert To Bytes` - - -string - -Converts string to lowercase. - -Examples: -| ${str1} = | Convert To Lowercase | ABC | -| ${str2} = | Convert To Lowercase | 1A2c3D | -| Should Be Equal | ${str1} | abc | -| Should Be Equal | ${str2} | 1a2c3d | - - - - - -string - -Converts string to uppercase. - -Examples: -| ${str1} = | Convert To Uppercase | abc | -| ${str2} = | Convert To Uppercase | 1a2C3d | -| Should Be Equal | ${str1} | ABC | -| Should Be Equal | ${str2} | 1A2C3D | - - - - - -bytes -encoding -errors=strict - -Decodes the given ``bytes`` to a Unicode string using the given ``encoding``. - -``errors`` argument controls what to do if decoding some bytes fails. -All values accepted by ``decode`` method in Python are valid, but in -practice the following values are most useful: - -- ``strict``: fail if characters cannot be decoded (default) -- ``ignore``: ignore characters that cannot be decoded -- ``replace``: replace characters that cannot be decoded with - a replacement character - -Examples: -| ${string} = | Decode Bytes To String | ${bytes} | UTF-8 | -| ${string} = | Decode Bytes To String | ${bytes} | ASCII | errors=ignore | - -Use `Encode String To Bytes` if you need to convert Unicode strings to -byte strings, and `Convert To String` in ``BuiltIn`` if you need to -convert arbitrary objects to Unicode strings. - - - - - -string -encoding -errors=strict - -Encodes the given Unicode ``string`` to bytes using the given ``encoding``. - -``errors`` argument controls what to do if encoding some characters fails. -All values accepted by ``encode`` method in Python are valid, but in -practice the following values are most useful: - -- ``strict``: fail if characters cannot be encoded (default) -- ``ignore``: ignore characters that cannot be encoded -- ``replace``: replace characters that cannot be encoded with - a replacement character - -Examples: -| ${bytes} = | Encode String To Bytes | ${string} | UTF-8 | -| ${bytes} = | Encode String To Bytes | ${string} | ASCII | errors=ignore | - -Use `Convert To Bytes` in ``BuiltIn`` if you want to create bytes based -on character or integer sequences. Use `Decode Bytes To String` if you -need to convert byte strings to Unicode strings and `Convert To String` -in ``BuiltIn`` if you need to convert arbitrary objects to Unicode. - - - - - -string -marker - -Returns contents of the ``string`` before the first occurrence of ``marker``. - -If the ``marker`` is not found, whole string is returned. - -See also `Fetch From Right`, `Split String` and `Split String -From Right`. - - - - - -string -marker - -Returns contents of the ``string`` after the last occurrence of ``marker``. - -If the ``marker`` is not found, whole string is returned. - -See also `Fetch From Left`, `Split String` and `Split String -From Right`. - - - - - -template -*positional -**named - -Formats a ``template`` using the given ``positional`` and ``named`` arguments. - -The template can be either be a string or an absolute path to -an existing file. In the latter case the file is read and its contents -are used as the template. If the template file contains non-ASCII -characters, it must be encoded using UTF-8. - -The template is formatted using Python's -[https://docs.python.org/library/string.html#format-string-syntax|format -string syntax]. Placeholders are marked using ``{}`` with possible -field name and format specification inside. Literal curly braces -can be inserted by doubling them like `{{` and `}}`. - -Examples: -| ${to} = | Format String | To: {} <{}> | ${user} | ${email} | -| ${to} = | Format String | To: {name} <{email}> | name=${name} | email=${email} | -| ${to} = | Format String | To: {user.name} <{user.email}> | user=${user} | -| ${xx} = | Format String | {:*^30} | centered | -| ${yy} = | Format String | {0:{width}{base}} | ${42} | base=X | width=10 | -| ${zz} = | Format String | ${CURDIR}/template.txt | positional | named=value | - -New in Robot Framework 3.1. - - - - - -length=8 -chars=[LETTERS][NUMBERS] - -Generates a string with a desired ``length`` from the given ``chars``. - -The population sequence ``chars`` contains the characters to use -when generating the random string. It can contain any -characters, and it is possible to use special markers -explained in the table below: - -| = Marker = | = Explanation = | -| ``[LOWER]`` | Lowercase ASCII characters from ``a`` to ``z``. | -| ``[UPPER]`` | Uppercase ASCII characters from ``A`` to ``Z``. | -| ``[LETTERS]`` | Lowercase and uppercase ASCII characters. | -| ``[NUMBERS]`` | Numbers from 0 to 9. | - -Examples: -| ${ret} = | Generate Random String | -| ${low} = | Generate Random String | 12 | [LOWER] | -| ${bin} = | Generate Random String | 8 | 01 | -| ${hex} = | Generate Random String | 4 | [NUMBERS]abcdef | - - - - - -string -line_number - -Returns the specified line from the given ``string``. - -Line numbering starts from 0 and it is possible to use -negative indices to refer to lines from the end. The line is -returned without the newline character. - -Examples: -| ${first} = | Get Line | ${string} | 0 | -| ${2nd last} = | Get Line | ${string} | -2 | - -Use `Split To Lines` if all lines are needed. - - - - - -string - -Returns and logs the number of lines in the given string. - - - - - -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. - - - - - -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. - - - - - -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. - - - - - -string -pattern -*groups - -Returns a list of all non-overlapping matches in the given string. - -``string`` is the string to find matches from and ``pattern`` is the -regular expression. 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. - -If no groups are used, the returned list contains full matches. If one -group is used, the list contains only contents of that group. If -multiple groups are used, the list contains tuples that contain -individual group contents. All groups can be given as indexes (starting -from 1) and named groups also as names. - -Examples: -| ${no match} = | Get Regexp Matches | the string | xxx | -| ${matches} = | Get Regexp Matches | the string | t.. | -| ${one group} = | Get Regexp Matches | the string | t(..) | 1 | -| ${named group} = | Get Regexp Matches | the string | t(?P<name>..) | name | -| ${two groups} = | Get Regexp Matches | the string | t(.)(.) | 1 | 2 | -=> -| ${no match} = [] -| ${matches} = ['the', 'tri'] -| ${one group} = ['he', 'ri'] -| ${named group} = ['he', 'ri'] -| ${two groups} = [('h', 'e'), ('r', 'i')] - -New in Robot Framework 2.9. - - - - - -string -start -end=None - -Returns a substring from ``start`` index to ``end`` index. - -The ``start`` index is inclusive and ``end`` is exclusive. -Indexing starts from 0, and it is possible to use -negative indices to refer to characters from the end. - -Examples: -| ${ignore first} = | Get Substring | ${string} | 1 | | -| ${ignore last} = | Get Substring | ${string} | | -1 | -| ${5th to 10th} = | Get Substring | ${string} | 4 | 10 | -| ${first two} = | Get Substring | ${string} | | 1 | -| ${last two} = | Get Substring | ${string} | -2 | | - - - - - -string -*removables - -Removes all ``removables`` from the given ``string``. - -``removables`` are used as literal strings. Each removable will be -matched to a temporary string from which preceding removables have -been already removed. See second example below. - -Use `Remove String Using Regexp` if more powerful pattern matching is -needed. If only a certain number of matches should be removed, -`Replace String` or `Replace String Using Regexp` can be used. - -A modified version of the string is returned and the original -string is not altered. - -Examples: -| ${str} = | Remove String | Robot Framework | work | -| Should Be Equal | ${str} | Robot Frame | -| ${str} = | Remove String | Robot Framework | o | bt | -| Should Be Equal | ${str} | R Framewrk | - - - - - -string -*patterns - -Removes ``patterns`` from the given ``string``. - -This keyword is otherwise identical to `Remove String`, but -the ``patterns`` to search for are considered to be a regular -expression. See `Replace String Using Regexp` for more information -about the regular expression syntax. That keyword can also be -used if there is a need to remove only a certain number of -occurrences. - - - - - -string -search_for -replace_with -count=-1 - -Replaces ``search_for`` in the given ``string`` with ``replace_with``. - -``search_for`` is used as a literal string. See `Replace String -Using Regexp` if more powerful pattern matching is needed. -If you need to just remove a string see `Remove String`. - -If the optional argument ``count`` is given, only that many -occurrences from left are replaced. Negative ``count`` means -that all occurrences are replaced (default behaviour) and zero -means that nothing is done. - -A modified version of the string is returned and the original -string is not altered. - -Examples: -| ${str} = | Replace String | Hello, world! | world | tellus | -| Should Be Equal | ${str} | Hello, tellus! | | | -| ${str} = | Replace String | Hello, world! | l | ${EMPTY} | count=1 | -| Should Be Equal | ${str} | Helo, world! | | | - - - - - -string -pattern -replace_with -count=-1 - -Replaces ``pattern`` in the given ``string`` with ``replace_with``. - -This keyword is otherwise identical to `Replace String`, but -the ``pattern`` to search for is considered to be a regular -expression. 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. - -If you need to just remove a string see `Remove String Using Regexp`. - -Examples: -| ${str} = | Replace String Using Regexp | ${str} | 20\\d\\d-\\d\\d-\\d\\d | <DATE> | -| ${str} = | Replace String Using Regexp | ${str} | (Hello|Hi) | ${EMPTY} | count=1 | - - - - - -item -msg=None - -Fails if the given ``item`` is not a byte string. - -Use `Should Be Unicode String` if you want to verify the ``item`` is a -Unicode string, or `Should Be String` if both Unicode and byte strings -are fine. See `Should Be String` for more details about Unicode strings -and byte strings. - -The default error message can be overridden with the optional -``msg`` argument. - - - - - -string -msg=None - -Fails if the given ``string`` is not in lowercase. - -For example, ``'string'`` and ``'with specials!'`` would pass, and -``'String'``, ``''`` and ``' '`` would fail. - -The default error message can be overridden with the optional -``msg`` argument. - -See also `Should Be Uppercase` and `Should Be Titlecase`. - - - - - -item -msg=None - -Fails if the given ``item`` is not a string. - -With Python 2, except with IronPython, this keyword passes regardless -is the ``item`` a Unicode string or a byte string. Use `Should Be -Unicode String` or `Should Be Byte String` if you want to restrict -the string type. Notice that with Python 2, except with IronPython, -``'string'`` creates a byte string and ``u'unicode'`` must be used to -create a Unicode string. - -With Python 3 and IronPython, this keyword passes if the string is -a Unicode string but fails if it is bytes. Notice that with both -Python 3 and IronPython, ``'string'`` creates a Unicode string, and -``b'bytes'`` must be used to create a byte string. - -The default error message can be overridden with the optional -``msg`` argument. - - - - - -string -msg=None - -Fails if given ``string`` is not title. - -``string`` is a titlecased string if there is at least one -character in it, uppercase characters only follow uncased -characters and lowercase characters only cased ones. - -For example, ``'This Is Title'`` would pass, and ``'Word In UPPER'``, -``'Word In lower'``, ``''`` and ``' '`` would fail. - -The default error message can be overridden with the optional -``msg`` argument. - -See also `Should Be Uppercase` and `Should Be Lowercase`. - - - - - -item -msg=None - -Fails if the given ``item`` is not a Unicode string. - -Use `Should Be Byte String` if you want to verify the ``item`` is a -byte string, or `Should Be String` if both Unicode and byte strings -are fine. See `Should Be String` for more details about Unicode -strings and byte strings. - -The default error message can be overridden with the optional -``msg`` argument. - - - - - -string -msg=None - -Fails if the given ``string`` is not in uppercase. - -For example, ``'STRING'`` and ``'WITH SPECIALS!'`` would pass, and -``'String'``, ``''`` and ``' '`` would fail. - -The default error message can be overridden with the optional -``msg`` argument. - -See also `Should Be Titlecase` and `Should Be Lowercase`. - - - - - -item -msg=None - -Fails if the given ``item`` is a string. - -See `Should Be String` for more details about Unicode strings and byte -strings. - -The default error message can be overridden with the optional -``msg`` argument. - - - - - -string -separator=None -max_split=-1 - -Splits the ``string`` using ``separator`` as a delimiter string. - -If a ``separator`` is not given, any whitespace string is a -separator. In that case also possible consecutive whitespace -as well as leading and trailing whitespace is ignored. - -Split words are returned as a list. If the optional -``max_split`` is given, at most ``max_split`` splits are done, and -the returned list will have maximum ``max_split + 1`` elements. - -Examples: -| @{words} = | Split String | ${string} | -| @{words} = | Split String | ${string} | ,${SPACE} | -| ${pre} | ${post} = | Split String | ${string} | :: | 1 | - -See `Split String From Right` if you want to start splitting -from right, and `Fetch From Left` and `Fetch From Right` if -you only want to get first/last part of the string. - - - - - -string -separator=None -max_split=-1 - -Splits the ``string`` using ``separator`` starting from right. - -Same as `Split String`, but splitting is started from right. This has -an effect only when ``max_split`` is given. - -Examples: -| ${first} | ${rest} = | Split String | ${string} | - | 1 | -| ${rest} | ${last} = | Split String From Right | ${string} | - | 1 | - - - - - -string - -Splits the given ``string`` to characters. - -Example: -| @{characters} = | Split String To Characters | ${string} | - - - - - -string -start=0 -end=None - -Splits the given string to lines. - -It is possible to get only a selection of lines from ``start`` -to ``end`` so that ``start`` index is inclusive and ``end`` is -exclusive. Line numbering starts from 0, and it is possible to -use negative indices to refer to lines from the end. - -Lines are returned without the newlines. The number of -returned lines is automatically logged. - -Examples: -| @{lines} = | Split To Lines | ${manylines} | | | -| @{ignore first} = | Split To Lines | ${manylines} | 1 | | -| @{ignore last} = | Split To Lines | ${manylines} | | -1 | -| @{5th to 10th} = | Split To Lines | ${manylines} | 4 | 10 | -| @{first two} = | Split To Lines | ${manylines} | | 1 | -| @{last two} = | Split To Lines | ${manylines} | -2 | | - -Use `Get Line` if you only need to get a single line. - - - - - -string -mode=both -characters=None - -Remove leading and/or trailing whitespaces from the given string. - -``mode`` is either ``left`` to remove leading characters, ``right`` to -remove trailing characters, ``both`` (default) to remove the -characters from both sides of the string or ``none`` to return the -unmodified string. - -If the optional ``characters`` is given, it must be a string and the -characters in the string will be stripped in the string. Please note, -that this is not a substring to be removed but a list of characters, -see the example below. - -Examples: -| ${stripped}= | Strip String | ${SPACE}Hello${SPACE} | | -| Should Be Equal | ${stripped} | Hello | | -| ${stripped}= | Strip String | ${SPACE}Hello${SPACE} | mode=left | -| Should Be Equal | ${stripped} | Hello${SPACE} | | -| ${stripped}= | Strip String | aabaHelloeee | characters=abe | -| Should Be Equal | ${stripped} | Hello | | - -New in Robot Framework 3.0. - - - - diff --git a/libspecs/Telnet.libspec b/libspecs/Telnet.libspec deleted file mode 100644 index 25e70e8..0000000 --- a/libspecs/Telnet.libspec +++ /dev/null @@ -1,744 +0,0 @@ - - -3.1.2 -test suite -yes -A test library providing communication over Telnet connections. - -``Telnet`` is Robot Framework's standard library that makes it possible to -connect to Telnet servers and execute commands on the opened connections. - -== Table of contents == - -- `Connections` -- `Writing and reading` -- `Configuration` -- `Terminal emulation` -- `Logging` -- `Time string format` -- `Boolean arguments` -- `Importing` -- `Shortcuts` -- `Keywords` - -= Connections = - -The first step of using ``Telnet`` is opening a connection with `Open -Connection` keyword. Typically the next step is logging in with `Login` -keyword, and in the end the opened connection can be closed with `Close -Connection`. - -It is possible to open multiple connections and switch the active one -using `Switch Connection`. `Close All Connections` can be used to close -all the connections, which is especially useful in suite teardowns to -guarantee that all connections are always closed. - -= Writing and reading = - -After opening a connection and possibly logging in, commands can be -executed or text written to the connection for other reasons using `Write` -and `Write Bare` keywords. The main difference between these two is that -the former adds a [#Configuration|configurable newline] after the text -automatically. - -After writing something to the connection, the resulting output can be -read using `Read`, `Read Until`, `Read Until Regexp`, and `Read Until -Prompt` keywords. Which one to use depends on the context, but the latest -one is often the most convenient. - -As a convenience when running a command, it is possible to use `Execute -Command` that simply uses `Write` and `Read Until Prompt` internally. -`Write Until Expected Output` is useful if you need to wait until writing -something produces a desired output. - -Written and read text is automatically encoded/decoded using a -[#Configuration|configured encoding]. - -The ANSI escape codes, like cursor movement and color codes, are -normally returned as part of the read operation. If an escape code occurs -in middle of a search pattern it may also prevent finding the searched -string. `Terminal emulation` can be used to process these -escape codes as they would be if a real terminal would be in use. - -= Configuration = - -Many aspects related the connections can be easily configured either -globally or per connection basis. Global configuration is done when -[#Importing|library is imported], and these values can be overridden per -connection by `Open Connection` or with setting specific keywords -`Set Timeout`, `Set Newline`, `Set Prompt`, `Set Encoding`, -`Set Default Log Level` and `Set Telnetlib Log Level`. - -Values of ``environ_user``, ``window_size``, ``terminal_emulation``, and -``terminal_type`` can not be changed after opening the connection. - -== Timeout == - -Timeout defines how long is the maximum time to wait when reading -output. It is used internally by `Read Until`, `Read Until Regexp`, -`Read Until Prompt`, and `Login` keywords. The default value is 3 seconds. - -== Connection Timeout == - -Connection Timeout defines how long is the maximum time to wait when -opening the telnet connection. It is used internally by `Open Connection`. -The default value is the system global default timeout. - -New in Robot Framework 2.9.2. - -== Newline == - -Newline defines which line separator `Write` keyword should use. The -default value is ``CRLF`` that is typically used by Telnet connections. - -Newline can be given either in escaped format using ``\n`` and ``\r`` or -with special ``LF`` and ``CR`` syntax. - -Examples: -| `Set Newline` | \n | -| `Set Newline` | CRLF | - -== Prompt == - -Often the easiest way to read the output of a command is reading all -the output until the next prompt with `Read Until Prompt`. It also makes -it easier, and faster, to verify did `Login` succeed. - -Prompt can be specified either as a normal string or a regular expression. -The latter is especially useful if the prompt changes as a result of -the executed commands. Prompt can be set to be a regular expression -by giving ``prompt_is_regexp`` argument a true value (see `Boolean -arguments`). - -Examples: -| `Open Connection` | lolcathost | prompt=$ | -| `Set Prompt` | (> |# ) | prompt_is_regexp=true | - -== Encoding == - -To ease handling text containing non-ASCII characters, all written text is -encoded and read text decoded by default. The default encoding is UTF-8 -that works also with ASCII. Encoding can be disabled by using a special -encoding value ``NONE``. This is mainly useful if you need to get the bytes -received from the connection as-is. - -Notice that when writing to the connection, only Unicode strings are -encoded using the defined encoding. Byte strings are expected to be already -encoded correctly. Notice also that normal text in test data is passed to -the library as Unicode and you need to use variables to use bytes. - -It is also possible to configure the error handler to use if encoding or -decoding characters fails. Accepted values are the same that encode/decode -functions in Python strings accept. In practice the following values are -the most useful: - -- ``ignore``: ignore characters that cannot be encoded (default) -- ``strict``: fail if characters cannot be encoded -- ``replace``: replace characters that cannot be encoded with a replacement - character - -Examples: -| `Open Connection` | lolcathost | encoding=Latin1 | encoding_errors=strict | -| `Set Encoding` | ISO-8859-15 | -| `Set Encoding` | errors=ignore | - -== Default log level == - -Default log level specifies the log level keywords use for `logging` unless -they are given an explicit log level. The default value is ``INFO``, and -changing it, for example, to ``DEBUG`` can be a good idea if there is lot -of unnecessary output that makes log files big. - -== Terminal type == - -By default the Telnet library does not negotiate any specific terminal type -with the server. If a specific terminal type, for example ``vt100``, is -desired, the terminal type can be configured in `importing` and with -`Open Connection`. - -== Window size == - -Window size for negotiation with the server can be configured when -`importing` the library and with `Open Connection`. - -== USER environment variable == - -Telnet protocol allows the ``USER`` environment variable to be sent when -connecting to the server. On some servers it may happen that there is no -login prompt, and on those cases this configuration option will allow still -to define the desired username. The option ``environ_user`` can be used in -`importing` and with `Open Connection`. - -= Terminal emulation = - -Telnet library supports terminal -emulation with [http://pyte.readthedocs.io|Pyte]. Terminal emulation -will process the output in a virtual screen. This means that ANSI escape -codes, like cursor movements, and also control characters, like -carriage returns and backspaces, have the same effect on the result as they -would have on a normal terminal screen. For example the sequence -``acdc\x1b[3Dbba`` will result in output ``abba``. - -Terminal emulation is taken into use by giving ``terminal_emulation`` -argument a true value (see `Boolean arguments`) either in the library -initialization or with `Open Connection`. - -As Pyte approximates vt-style terminal, you may also want to set the -terminal type as ``vt100``. We also recommend that you increase the window -size, as the terminal emulation will break all lines that are longer than -the window row length. - -When terminal emulation is used, the `newline` and `encoding` can not be -changed anymore after opening the connection. - -Examples: -| `Open Connection` | lolcathost | terminal_emulation=True | terminal_type=vt100 | window_size=400x100 | - -As a prerequisite for using terminal emulation, you need to have Pyte -installed. Due to backwards incompatible changes in Pyte, different -Robot Framework versions support different Pyte versions: - -- Pyte 0.6 and newer are supported by Robot Framework 3.0.3. - Latest Pyte version can be installed (or upgraded) with - ``pip install --upgrade pyte``. -- Pyte 0.5.2 and older are supported by Robot Framework 3.0.2 and earlier. - Pyte 0.5.2 can be installed with ``pip install pyte==0.5.2``. - -= Logging = - -All keywords that read something log the output. These keywords take the -log level to use as an optional argument, and if no log level is specified -they use the [#Configuration|configured] default value. - -The valid log levels to use are ``TRACE``, ``DEBUG``, ``INFO`` (default), -and ``WARN``. Levels below ``INFO`` are not shown in log files by default -whereas warnings are shown more prominently. - -The [http://docs.python.org/library/telnetlib.html|telnetlib module] -used by this library has a custom logging system for logging content it -sends and receives. By default these messages are written using ``TRACE`` -level, but the level is configurable with the ``telnetlib_log_level`` -option either in the library initialization, to the `Open Connection` -or by using the `Set Telnetlib Log Level` keyword to the active -connection. Special level ``NONE`` con be used to disable the logging -altogether. - -= Time string format = - -Timeouts and other times used must be given as a time string using format -like ``15 seconds`` or ``1min 10s``. If the timeout is given as just -a number, for example, ``10`` or ``1.5``, it is considered to be seconds. -The time string format is described in more detail in an appendix of -[http://robotframework.org/robotframework/#user-guide|Robot Framework User Guide]. - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is an empty string or equal to ``FALSE``, ``NONE``, ``NO``, ``OFF`` or -``0``, case-insensitively. Other strings are considered true regardless -their value, and other argument types are tested using the same -[http://docs.python.org/library/stdtypes.html#truth|rules as in Python]. - -True examples: -| `Open Connection` | lolcathost | terminal_emulation=True | # Strings are generally true. | -| `Open Connection` | lolcathost | terminal_emulation=yes | # Same as the above. | -| `Open Connection` | lolcathost | terminal_emulation=${TRUE} | # Python ``True`` is true. | -| `Open Connection` | lolcathost | terminal_emulation=${42} | # Numbers other than 0 are true. | - -False examples: -| `Open Connection` | lolcathost | terminal_emulation=False | # String ``false`` is false. | -| `Open Connection` | lolcathost | terminal_emulation=no | # Also string ``no`` is false. | -| `Open Connection` | lolcathost | terminal_emulation=${EMPTY} | # Empty string is false. | -| `Open Connection` | lolcathost | terminal_emulation=${FALSE} | # Python ``False`` is false. | - -Considering string ``NONE`` false is new in Robot Framework 3.0.3 and -considering also ``OFF`` and ``0`` false is new in Robot Framework 3.1. - - -timeout=3 seconds -newline=CRLF -prompt=None -prompt_is_regexp=False -encoding=UTF-8 -encoding_errors=ignore -default_log_level=INFO -window_size=None -environ_user=None -terminal_emulation=False -terminal_type=None -telnetlib_log_level=TRACE -connection_timeout=None - -Telnet library can be imported with optional configuration parameters. - -Configuration parameters are used as default values when new -connections are opened with `Open Connection` keyword. They can also be -overridden after opening the connection using the `Set ...` `keywords`. -See these keywords as well as `Configuration`, `Terminal emulation` and -`Logging` sections above for more information about these parameters -and their possible values. - -See `Time string format` and `Boolean arguments` sections for -information about using arguments accepting times and Boolean values, -respectively. - -Examples (use only one of these): -| = Setting = | = Value = | = Value = | = Value = | = Value = | = Comment = | -| Library | Telnet | | | | # default values | -| Library | Telnet | 5 seconds | | | # set only timeout | -| Library | Telnet | newline=LF | encoding=ISO-8859-1 | | # set newline and encoding using named arguments | -| Library | Telnet | prompt=$ | | | # set prompt | -| Library | Telnet | prompt=(> |# ) | prompt_is_regexp=yes | | # set prompt as a regular expression | -| Library | Telnet | terminal_emulation=True | terminal_type=vt100 | window_size=400x100 | # use terminal emulation with defined window size and terminal type | -| Library | Telnet | telnetlib_log_level=NONE | | | # disable logging messages from the underlying telnetlib | - - - - - - -Closes all open connections and empties the connection cache. - -If multiple connections are opened, this keyword should be used in -a test or suite teardown to make sure that all connections are closed. -It is not an error is some of the connections have already been closed -by `Close Connection`. - -After this keyword, new indexes returned by `Open Connection` -keyword are reset to 1. - - - - - -loglevel=None - -Closes the current Telnet connection. - -Remaining output in the connection is read, logged, and returned. -It is not an error to close an already closed connection. - -Use `Close All Connections` if you want to make sure all opened -connections are closed. - -See `Logging` section for more information about log levels. - - - - - -command -loglevel=None -strip_prompt=False - -Executes the given ``command`` and reads, logs, and returns everything until the prompt. - -This keyword requires the prompt to be [#Configuration|configured] -either in `importing` or with `Open Connection` or `Set Prompt` keyword. - -This is a convenience keyword that uses `Write` and `Read Until Prompt` -internally. Following two examples are thus functionally identical: - -| ${out} = | `Execute Command` | pwd | - -| `Write` | pwd | -| ${out} = | `Read Until Prompt` | - -See `Logging` section for more information about log levels and `Read -Until Prompt` for more information about the ``strip_prompt`` parameter. - - - - - -username -password -login_prompt=login: -password_prompt=Password: -login_timeout=1 second -login_incorrect=Login incorrect - -Logs in to the Telnet server with the given user information. - -This keyword reads from the connection until the ``login_prompt`` is -encountered and then types the given ``username``. Then it reads until -the ``password_prompt`` and types the given ``password``. In both cases -a newline is appended automatically and the connection specific -timeout used when waiting for outputs. - -How logging status is verified depends on whether a prompt is set for -this connection or not: - -1) If the prompt is set, this keyword reads the output until the prompt -is found using the normal timeout. If no prompt is found, login is -considered failed and also this keyword fails. Note that in this case -both ``login_timeout`` and ``login_incorrect`` arguments are ignored. - -2) If the prompt is not set, this keywords sleeps until ``login_timeout`` -and then reads all the output available on the connection. If the -output contains ``login_incorrect`` text, login is considered failed -and also this keyword fails. - -See `Configuration` section for more information about setting -newline, timeout, and prompt. - - - - - -host -alias=None -port=23 -timeout=None -newline=None -prompt=None -prompt_is_regexp=False -encoding=None -encoding_errors=None -default_log_level=None -window_size=None -environ_user=None -terminal_emulation=None -terminal_type=None -telnetlib_log_level=None -connection_timeout=None - -Opens a new Telnet connection to the given host and port. - -The ``timeout``, ``newline``, ``prompt``, ``prompt_is_regexp``, -``encoding``, ``default_log_level``, ``window_size``, ``environ_user``, -``terminal_emulation``, ``terminal_type`` and ``telnetlib_log_level`` -arguments get default values when the library is [#Importing|imported]. -Setting them here overrides those values for the opened connection. -See `Configuration`, `Terminal emulation` and `Logging` sections for -more information about these parameters and their possible values. - -Possible already opened connections are cached and it is possible to -switch back to them using `Switch Connection` keyword. It is possible to -switch either using explicitly given ``alias`` or using index returned -by this keyword. Indexing starts from 1 and is reset back to it by -`Close All Connections` keyword. - - - - - -loglevel=None - -Reads everything that is currently available in the output. - -Read output is both returned and logged. See `Logging` section for more -information about log levels. - - - - - -expected -loglevel=None - -Reads output until ``expected`` text is encountered. - -Text up to and including the match is returned and logged. If no match -is found, this keyword fails. How much to wait for the output depends -on the [#Configuration|configured timeout]. - -See `Logging` section for more information about log levels. Use -`Read Until Regexp` if more complex matching is needed. - - - - - -loglevel=None -strip_prompt=False - -Reads output until the prompt is encountered. - -This keyword requires the prompt to be [#Configuration|configured] -either in `importing` or with `Open Connection` or `Set Prompt` keyword. - -By default, text up to and including the prompt is returned and logged. -If no prompt is found, this keyword fails. How much to wait for the -output depends on the [#Configuration|configured timeout]. - -If you want to exclude the prompt from the returned output, set -``strip_prompt`` to a true value (see `Boolean arguments`). If your -prompt is a regular expression, make sure that the expression spans the -whole prompt, because only the part of the output that matches the -regular expression is stripped away. - -See `Logging` section for more information about log levels. - - - - - -*expected - -Reads output until any of the ``expected`` regular expressions match. - -This keyword accepts any number of regular expressions patterns or -compiled Python regular expression objects as arguments. Text up to -and including the first match to any of the regular expressions is -returned and logged. If no match is found, this keyword fails. How much -to wait for the output depends on the [#Configuration|configured timeout]. - -If the last given argument is a [#Logging|valid log level], it is used -as ``loglevel`` similarly as with `Read Until` keyword. - -See the documentation of -[http://docs.python.org/library/re.html|Python re module] -for more information about the supported regular expression syntax. -Notice that possible backslashes need to be escaped in Robot Framework -test data. - -Examples: -| `Read Until Regexp` | (#|$) | -| `Read Until Regexp` | first_regexp | second_regexp | -| `Read Until Regexp` | \\d{4}-\\d{2}-\\d{2} | DEBUG | - - - - - -level - -Sets the default log level used for `logging` in the current connection. - -The old default log level is returned and can be used to restore the -log level later. - -See `Configuration` section for more information about global and -connection specific configuration. - - - - - -encoding=None -errors=None - -Sets the encoding to use for `writing and reading` in the current connection. - -The given ``encoding`` specifies the encoding to use when written/read -text is encoded/decoded, and ``errors`` specifies the error handler to -use if encoding/decoding fails. Either of these can be omitted and in -that case the old value is not affected. Use string ``NONE`` to disable -encoding altogether. - -See `Configuration` section for more information about encoding and -error handlers, as well as global and connection specific configuration -in general. - -The old values are returned and can be used to restore the encoding -and the error handler later. See `Set Prompt` for a similar example. - -If terminal emulation is used, the encoding can not be changed on an open -connection. - - - - - -newline - -Sets the newline used by `Write` keyword in the current connection. - -The old newline is returned and can be used to restore the newline later. -See `Set Timeout` for a similar example. - -If terminal emulation is used, the newline can not be changed on an open -connection. - -See `Configuration` section for more information about global and -connection specific configuration. - - - - - -prompt -prompt_is_regexp=False - -Sets the prompt used by `Read Until Prompt` and `Login` in the current connection. - -If ``prompt_is_regexp`` is given a true value (see `Boolean arguments`), -the given ``prompt`` is considered to be a regular expression. - -The old prompt is returned and can be used to restore the prompt later. - -Example: -| ${prompt} | ${regexp} = | `Set Prompt` | $ | -| `Do Something` | -| `Set Prompt` | ${prompt} | ${regexp} | - -See the documentation of -[http://docs.python.org/library/re.html|Python re module] -for more information about the supported regular expression syntax. -Notice that possible backslashes need to be escaped in Robot Framework -test data. - -See `Configuration` section for more information about global and -connection specific configuration. - - - - - -level - -Sets the log level used for `logging` in the underlying ``telnetlib``. - -Note that ``telnetlib`` can be very noisy thus using the level ``NONE`` -can shutdown the messages generated by this library. - - - - - -timeout - -Sets the timeout used for waiting output in the current connection. - -Read operations that expect some output to appear (`Read Until`, `Read -Until Regexp`, `Read Until Prompt`, `Login`) use this timeout and fail -if the expected output does not appear before this timeout expires. - -The ``timeout`` must be given in `time string format`. The old timeout -is returned and can be used to restore the timeout later. - -Example: -| ${old} = | `Set Timeout` | 2 minute 30 seconds | -| `Do Something` | -| `Set Timeout` | ${old} | - -See `Configuration` section for more information about global and -connection specific configuration. - - - - - -index_or_alias - -Switches between active connections using an index or an alias. - -Aliases can be given to `Open Connection` keyword which also always -returns the connection index. - -This keyword returns the index of previous active connection. - -Example: -| `Open Connection` | myhost.net | | | -| `Login` | john | secret | | -| `Write` | some command | | | -| `Open Connection` | yourhost.com | 2nd conn | | -| `Login` | root | password | | -| `Write` | another cmd | | | -| ${old index}= | `Switch Connection` | 1 | # index | -| `Write` | something | | | -| `Switch Connection` | 2nd conn | | # alias | -| `Write` | whatever | | | -| `Switch Connection` | ${old index} | | # back to original | -| [Teardown] | `Close All Connections` | | | - -The example above expects that there were no other open -connections when opening the first one, because it used index -``1`` when switching to the connection later. If you are not -sure about that, you can store the index into a variable as -shown below. - -| ${index} = | `Open Connection` | myhost.net | -| `Do Something` | | | -| `Switch Connection` | ${index} | | - - - - - -text -loglevel=None - -Writes the given text plus a newline into the connection. - -The newline character sequence to use can be [#Configuration|configured] -both globally and per connection basis. The default value is ``CRLF``. - -This keyword consumes the written text, until the added newline, from -the output and logs and returns it. The given text itself must not -contain newlines. Use `Write Bare` instead if either of these features -causes a problem. - -*Note:* This keyword does not return the possible output of the executed -command. To get the output, one of the `Read ...` `keywords` must be -used. See `Writing and reading` section for more details. - -See `Logging` section for more information about log levels. - - - - - -text - -Writes the given text, and nothing else, into the connection. - -This keyword does not append a newline nor consume the written text. -Use `Write` if these features are needed. - - - - - -character - -Writes the given control character into the connection. - -The control character is prepended with an IAC (interpret as command) -character. - -The following control character names are supported: BRK, IP, AO, AYT, -EC, EL, NOP. Additionally, you can use arbitrary numbers to send any -control character. - -Example: -| Write Control Character | BRK | # Send Break command | -| Write Control Character | 241 | # Send No operation command | - - - - - -text -expected -timeout -retry_interval -loglevel=None - -Writes the given ``text`` repeatedly, until ``expected`` appears in the output. - -``text`` is written without appending a newline and it is consumed from -the output before trying to find ``expected``. If ``expected`` does not -appear in the output within ``timeout``, this keyword fails. - -``retry_interval`` defines the time to wait ``expected`` to appear before -writing the ``text`` again. Consuming the written ``text`` is subject to -the normal [#Configuration|configured timeout]. - -Both ``timeout`` and ``retry_interval`` must be given in `time string -format`. See `Logging` section for more information about log levels. - -Example: -| Write Until Expected Output | ps -ef| grep myprocess\r\n | myprocess | -| ... | 5 s | 0.5 s | - -The above example writes command ``ps -ef | grep myprocess\r\n`` until -``myprocess`` appears in the output. The command is written every 0.5 -seconds and the keyword fails if ``myprocess`` does not appear in -the output in 5 seconds. - - - - diff --git a/libspecs/XML.libspec b/libspecs/XML.libspec deleted file mode 100644 index 0ac73f9..0000000 --- a/libspecs/XML.libspec +++ /dev/null @@ -1,1365 +0,0 @@ - - -3.1.2 -global -yes -Robot Framework test library for verifying and modifying XML documents. - -As the name implies, _XML_ is a test library for verifying contents of XML -files. In practice it is a pretty thin wrapper on top of Python's -[http://docs.python.org/library/xml.etree.elementtree.html|ElementTree XML API]. - -The library has the following main usages: - -- Parsing an XML file, or a string containing XML, into an XML element - structure and finding certain elements from it for for further analysis - (e.g. `Parse XML` and `Get Element` keywords). -- Getting text or attributes of elements - (e.g. `Get Element Text` and `Get Element Attribute`). -- Directly verifying text, attributes, or whole elements - (e.g `Element Text Should Be` and `Elements Should Be Equal`). -- Modifying XML and saving it (e.g. `Set Element Text`, `Add Element` - and `Save XML`). - -== Table of contents == - -- `Parsing XML` -- `Using lxml` -- `Example` -- `Finding elements with xpath` -- `Element attributes` -- `Handling XML namespaces` -- `Boolean arguments` -- `Pattern matching` -- `Shortcuts` -- `Keywords` - -= Parsing XML = - -XML can be parsed into an element structure using `Parse XML` keyword. -It accepts both paths to XML files and strings that contain XML. The -keyword returns the root element of the structure, which then contains -other elements as its children and their children. Possible comments and -processing instructions in the source XML are removed. - -XML is not validated during parsing even if has a schema defined. How -possible doctype elements are handled otherwise depends on the used XML -module and on the platform. The standard ElementTree strips doctypes -altogether but when `using lxml` they are preserved when XML is saved. - -The element structure returned by `Parse XML`, as well as elements -returned by keywords such as `Get Element`, can be used as the ``source`` -argument with other keywords. In addition to an already parsed XML -structure, other keywords also accept paths to XML files and strings -containing XML similarly as `Parse XML`. Notice that keywords that modify -XML do not write those changes back to disk even if the source would be -given as a path to a file. Changes must always saved explicitly using -`Save XML` keyword. - -When the source is given as a path to a file, the forward slash character -(``/``) can be used as the path separator regardless the operating system. -On Windows also the backslash works, but it the test data it needs to be -escaped by doubling it (``\\``). Using the built-in variable ``${/}`` -naturally works too. - -= Using lxml = - -By default this library uses Python's standard -[http://docs.python.org/library/xml.etree.elementtree.html|ElementTree] -module for parsing XML, but it can be configured to use -[http://lxml.de|lxml] module instead when `importing` the library. -The resulting element structure has same API regardless which module -is used for parsing. - -The main benefits of using lxml is that it supports richer xpath syntax -than the standard ElementTree and enables using `Evaluate Xpath` keyword. -It also preserves the doctype and possible namespace prefixes saving XML. - -= Example = - -The following simple example demonstrates parsing XML and verifying its -contents both using keywords in this library and in _BuiltIn_ and -_Collections_ libraries. How to use xpath expressions to find elements -and what attributes the returned elements contain are discussed, with -more examples, in `Finding elements with xpath` and `Element attributes` -sections. - -In this example, as well as in many other examples in this documentation, -``${XML}`` refers to the following example XML document. In practice -``${XML}`` could either be a path to an XML file or it could contain the XML -itself. - -| <example> -| <first id="1">text</first> -| <second id="2"> -| <child/> -| </second> -| <third> -| <child>more text</child> -| <second id="child"/> -| <child><grandchild/></child> -| </third> -| <html> -| <p> -| Text with <b>bold</b> and <i>italics</i>. -| </p> -| </html> -| </example> - -| ${root} = | `Parse XML` | ${XML} | | | -| `Should Be Equal` | ${root.tag} | example | | | -| ${first} = | `Get Element` | ${root} | first | | -| `Should Be Equal` | ${first.text} | text | | | -| `Dictionary Should Contain Key` | ${first.attrib} | id | | -| `Element Text Should Be` | ${first} | text | | | -| `Element Attribute Should Be` | ${first} | id | 1 | | -| `Element Attribute Should Be` | ${root} | id | 1 | xpath=first | -| `Element Attribute Should Be` | ${XML} | id | 1 | xpath=first | - -Notice that in the example three last lines are equivalent. Which one to -use in practice depends on which other elements you need to get or verify. -If you only need to do one verification, using the last line alone would -suffice. If more verifications are needed, parsing the XML with `Parse XML` -only once would be more efficient. - -= Finding elements with xpath = - -ElementTree, and thus also this library, supports finding elements using -xpath expressions. ElementTree does not, however, support the full xpath -standard. The supported xpath syntax is explained below and -[https://docs.python.org/library/xml.etree.elementtree.html#xpath-support| -ElementTree documentation] provides more details. In the examples -``${XML}`` refers to the same XML structure as in the earlier example. - -If lxml support is enabled when `importing` the library, the whole -[http://www.w3.org/TR/xpath/|xpath 1.0 standard] is supported. -That includes everything listed below but also lot of other useful -constructs. - -== Tag names == - -When just a single tag name is used, xpath matches all direct child -elements that have that tag name. - -| ${elem} = | `Get Element` | ${XML} | third | -| `Should Be Equal` | ${elem.tag} | third | | -| @{children} = | `Get Elements` | ${elem} | child | -| `Length Should Be` | ${children} | 2 | | - -== Paths == - -Paths are created by combining tag names with a forward slash (``/``). For -example, ``parent/child`` matches all ``child`` elements under ``parent`` -element. Notice that if there are multiple ``parent`` elements that all -have ``child`` elements, ``parent/child`` xpath will match all these -``child`` elements. - -| ${elem} = | `Get Element` | ${XML} | second/child | -| `Should Be Equal` | ${elem.tag} | child | | -| ${elem} = | `Get Element` | ${XML} | third/child/grandchild | -| `Should Be Equal` | ${elem.tag} | grandchild | | - -== Wildcards == - -An asterisk (``*``) can be used in paths instead of a tag name to denote -any element. - -| @{children} = | `Get Elements` | ${XML} | */child | -| `Length Should Be` | ${children} | 3 | | - -== Current element == - -The current element is denoted with a dot (``.``). Normally the current -element is implicit and does not need to be included in the xpath. - -== Parent element == - -The parent element of another element is denoted with two dots (``..``). -Notice that it is not possible to refer to the parent of the current -element. - -| ${elem} = | `Get Element` | ${XML} | */second/.. | -| `Should Be Equal` | ${elem.tag} | third | | - -== Search all sub elements == - -Two forward slashes (``//``) mean that all sub elements, not only the -direct children, are searched. If the search is started from the current -element, an explicit dot is required. - -| @{elements} = | `Get Elements` | ${XML} | .//second | -| `Length Should Be` | ${elements} | 2 | | -| ${b} = | `Get Element` | ${XML} | html//b | -| `Should Be Equal` | ${b.text} | bold | | - -== Predicates == - -Predicates allow selecting elements using also other criteria than tag -names, for example, attributes or position. They are specified after the -normal tag name or path using syntax ``path[predicate]``. The path can have -wildcards and other special syntax explained earlier. What predicates -the standard ElementTree supports is explained in the table below. - -| = Predicate = | = Matches = | = Example = | -| @attrib | Elements with attribute ``attrib``. | second[@id] | -| @attrib="value" | Elements with attribute ``attrib`` having value ``value``. | *[@id="2"] | -| position | Elements at the specified position. Position can be an integer (starting from 1), expression ``last()``, or relative expression like ``last() - 1``. | third/child[1] | -| tag | Elements with a child element named ``tag``. | third/child[grandchild] | - -Predicates can also be stacked like ``path[predicate1][predicate2]``. -A limitation is that possible position predicate must always be first. - -= Element attributes = - -All keywords returning elements, such as `Parse XML`, and `Get Element`, -return ElementTree's -[http://docs.python.org/library/xml.etree.elementtree.html#element-objects|Element objects]. -These elements can be used as inputs for other keywords, but they also -contain several useful attributes that can be accessed directly using -the extended variable syntax. - -The attributes that are both useful and convenient to use in the test -data are explained below. Also other attributes, including methods, can -be accessed, but that is typically better to do in custom libraries than -directly in the test data. - -The examples use the same ``${XML}`` structure as the earlier examples. - -== tag == - -The tag of the element. - -| ${root} = | `Parse XML` | ${XML} | -| `Should Be Equal` | ${root.tag} | example | - -== text == - -The text that the element contains or Python ``None`` if the element has no -text. Notice that the text _does not_ contain texts of possible child -elements nor text after or between children. Notice also that in XML -whitespace is significant, so the text contains also possible indentation -and newlines. To get also text of the possible children, optionally -whitespace normalized, use `Get Element Text` keyword. - -| ${1st} = | `Get Element` | ${XML} | first | -| `Should Be Equal` | ${1st.text} | text | | -| ${2nd} = | `Get Element` | ${XML} | second/child | -| `Should Be Equal` | ${2nd.text} | ${NONE} | | -| ${p} = | `Get Element` | ${XML} | html/p | -| `Should Be Equal` | ${p.text} | \n${SPACE*6}Text with${SPACE} | - -== tail == - -The text after the element before the next opening or closing tag. Python -``None`` if the element has no tail. Similarly as with ``text``, also -``tail`` contains possible indentation and newlines. - -| ${b} = | `Get Element` | ${XML} | html/p/b | -| `Should Be Equal` | ${b.tail} | ${SPACE}and${SPACE} | - -== attrib == - -A Python dictionary containing attributes of the element. - -| ${2nd} = | `Get Element` | ${XML} | second | -| `Should Be Equal` | ${2nd.attrib['id']} | 2 | | -| ${3rd} = | `Get Element` | ${XML} | third | -| `Should Be Empty` | ${3rd.attrib} | | | - -= Handling XML namespaces = - -ElementTree and lxml handle possible namespaces in XML documents by adding -the namespace URI to tag names in so called Clark Notation. That is -inconvenient especially with xpaths, and by default this library strips -those namespaces away and moves them to ``xmlns`` attribute instead. That -can be avoided by passing ``keep_clark_notation`` argument to `Parse XML` -keyword. Alternatively `Parse XML` supports stripping namespace information -altogether by using ``strip_namespaces`` argument. The pros and cons of -different approaches are discussed in more detail below. - -== How ElementTree handles namespaces == - -If an XML document has namespaces, ElementTree adds namespace information -to tag names in [http://www.jclark.com/xml/xmlns.htm|Clark Notation] -(e.g. ``{http://ns.uri}tag``) and removes original ``xmlns`` attributes. -This is done both with default namespaces and with namespaces with a prefix. -How it works in practice is illustrated by the following example, where -``${NS}`` variable contains this XML document: - -| <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" -| xmlns="http://www.w3.org/1999/xhtml"> -| <xsl:template match="/"> -| <html></html> -| </xsl:template> -| </xsl:stylesheet> - -| ${root} = | `Parse XML` | ${NS} | keep_clark_notation=yes | -| `Should Be Equal` | ${root.tag} | {http://www.w3.org/1999/XSL/Transform}stylesheet | -| `Element Should Exist` | ${root} | {http://www.w3.org/1999/XSL/Transform}template/{http://www.w3.org/1999/xhtml}html | -| `Should Be Empty` | ${root.attrib} | - -As you can see, including the namespace URI in tag names makes xpaths -really long and complex. - -If you save the XML, ElementTree moves namespace information back to -``xmlns`` attributes. Unfortunately it does not restore the original -prefixes: - -| <ns0:stylesheet xmlns:ns0="http://www.w3.org/1999/XSL/Transform"> -| <ns0:template match="/"> -| <ns1:html xmlns:ns1="http://www.w3.org/1999/xhtml"></ns1:html> -| </ns0:template> -| </ns0:stylesheet> - -The resulting output is semantically same as the original, but mangling -prefixes like this may still not be desirable. Notice also that the actual -output depends slightly on ElementTree version. - -== Default namespace handling == - -Because the way ElementTree handles namespaces makes xpaths so complicated, -this library, by default, strips namespaces from tag names and moves that -information back to ``xmlns`` attributes. How this works in practice is -shown by the example below, where ``${NS}`` variable contains the same XML -document as in the previous example. - -| ${root} = | `Parse XML` | ${NS} | -| `Should Be Equal` | ${root.tag} | stylesheet | -| `Element Should Exist` | ${root} | template/html | -| `Element Attribute Should Be` | ${root} | xmlns | http://www.w3.org/1999/XSL/Transform | -| `Element Attribute Should Be` | ${root} | xmlns | http://www.w3.org/1999/xhtml | xpath=template/html | - -Now that tags do not contain namespace information, xpaths are simple again. - -A minor limitation of this approach is that namespace prefixes are lost. -As a result the saved output is not exactly same as the original one in -this case either: - -| <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform"> -| <template match="/"> -| <html xmlns="http://www.w3.org/1999/xhtml"></html> -| </template> -| </stylesheet> - -Also this output is semantically same as the original. If the original XML -had only default namespaces, the output would also look identical. - -== Namespaces when using lxml == - -This library handles namespaces same way both when `using lxml` and when -not using it. There are, however, differences how lxml internally handles -namespaces compared to the standard ElementTree. The main difference is -that lxml stores information about namespace prefixes and they are thus -preserved if XML is saved. Another visible difference is that lxml includes -namespace information in child elements got with `Get Element` if the -parent element has namespaces. - -== Stripping namespaces altogether == - -Because namespaces often add unnecessary complexity, `Parse XML` supports -stripping them altogether by using ``strip_namespaces=True``. When this -option is enabled, namespaces are not shown anywhere nor are they included -if XML is saved. - -== Attribute namespaces == - -Attributes in XML documents are, by default, in the same namespaces as -the element they belong to. It is possible to use different namespaces -by using prefixes, but this is pretty rare. - -If an attribute has a namespace prefix, ElementTree will replace it with -Clark Notation the same way it handles elements. Because stripping -namespaces from attributes could cause attribute conflicts, this library -does not handle attribute namespaces at all. Thus the following example -works the same way regardless how namespaces are handled. - -| ${root} = | `Parse XML` | <root id="1" ns:id="2" xmlns:ns="http://my.ns"/> | -| `Element Attribute Should Be` | ${root} | id | 1 | -| `Element Attribute Should Be` | ${root} | {http://my.ns}id | 2 | - -= Boolean arguments = - -Some keywords accept arguments that are handled as Boolean values true or -false. If such an argument is given as a string, it is considered false if -it is an empty string or equal to ``FALSE``, ``NONE``, ``NO``, ``OFF`` or -``0``, case-insensitively. Other strings are considered true regardless -their value, and other argument types are tested using the same -[http://docs.python.org/library/stdtypes.html#truth|rules as in Python]. - -True examples: -| `Parse XML` | ${XML} | keep_clark_notation=True | # Strings are generally true. | -| `Parse XML` | ${XML} | keep_clark_notation=yes | # Same as the above. | -| `Parse XML` | ${XML} | keep_clark_notation=${TRUE} | # Python ``True`` is true. | -| `Parse XML` | ${XML} | keep_clark_notation=${42} | # Numbers other than 0 are true. | - -False examples: -| `Parse XML` | ${XML} | keep_clark_notation=False | # String ``false`` is false. | -| `Parse XML` | ${XML} | keep_clark_notation=no | # Also string ``no`` is false. | -| `Parse XML` | ${XML} | keep_clark_notation=${EMPTY} | # Empty string is false. | -| `Parse XML` | ${XML} | keep_clark_notation=${FALSE} | # Python ``False`` is false. | - -Considering string ``NONE`` false is new in Robot Framework 3.0.3 and -considering also ``OFF`` and ``0`` false is new in Robot Framework 3.1. - -== Pattern matching == - -Some keywords, for example `Elements Should Match`, support so called -[http://en.wikipedia.org/wiki/Glob_(programming)|glob patterns] where: - -| ``*`` | matches any string, even an empty string | -| ``?`` | matches any single character | -| ``[chars]`` | matches one character in the bracket | -| ``[!chars]`` | matches one character not in the bracket | -| ``[a-z]`` | matches one character from the range in the bracket | -| ``[!a-z]`` | matches one character not from the range in the bracket | - -Unlike with glob patterns normally, path separator characters ``/`` and -``\`` and the newline character ``\n`` are matches by the above -wildcards. - -Support for brackets like ``[abc]`` and ``[!a-z]`` is new in -Robot Framework 3.1 - - -use_lxml=False - -Import library with optionally lxml mode enabled. - -By default this library uses Python's standard -[http://docs.python.org/library/xml.etree.elementtree.html|ElementTree] -module for parsing XML. If ``use_lxml`` argument is given a true value -(see `Boolean arguments`), the library will use [http://lxml.de|lxml] -module instead. See `Using lxml` section for benefits provided by lxml. - -Using lxml requires that the lxml module is installed on the system. -If lxml mode is enabled but the module is not installed, this library -will emit a warning and revert back to using the standard ElementTree. - - - - - -source -element -index=None -xpath=. - -Adds a child element to the specified element. - -The element to whom to add the new element is specified using ``source`` -and ``xpath``. They have exactly the same semantics as with `Get Element` -keyword. The resulting XML structure is returned, and if the ``source`` -is an already parsed XML structure, it is also modified in place. - -The ``element`` to add can be specified as a path to an XML file or -as a string containing XML, or it can be an already parsed XML element. -The element is copied before adding so modifying either the original -or the added element has no effect on the other -. -The element is added as the last child by default, but a custom index -can be used to alter the position. Indices start from zero (0 = first -position, 1 = second position, etc.), and negative numbers refer to -positions at the end (-1 = second last position, -2 = third last, etc.). - -Examples using ``${XML}`` structure from `Example`: -| Add Element | ${XML} | <new id="x"><c1/></new> | -| Add Element | ${XML} | <c2/> | xpath=new | -| Add Element | ${XML} | <c3/> | index=1 | xpath=new | -| ${new} = | Get Element | ${XML} | new | -| Elements Should Be Equal | ${new} | <new id="x"><c1/><c3/><c2/></new> | - -Use `Remove Element` or `Remove Elements` to remove elements. - - - - - -source -xpath=. -clear_tail=False - -Clears the contents of the specified element. - -The element to clear is specified using ``source`` and ``xpath``. They -have exactly the same semantics as with `Get Element` keyword. -The resulting XML structure is returned, and if the ``source`` is -an already parsed XML structure, it is also modified in place. - -Clearing the element means removing its text, attributes, and children. -Element's tail text is not removed by default, but that can be changed -by giving ``clear_tail`` a true value (see `Boolean arguments`). See -`Element attributes` section for more information about tail in -general. - -Examples using ``${XML}`` structure from `Example`: -| Clear Element | ${XML} | xpath=first | -| ${first} = | Get Element | ${XML} | xpath=first | -| Elements Should Be Equal | ${first} | <first/> | -| Clear Element | ${XML} | xpath=html/p/b | clear_tail=yes | -| Element Text Should Be | ${XML} | Text with italics. | xpath=html/p | normalize_whitespace=yes | -| Clear Element | ${XML} | -| Elements Should Be Equal | ${XML} | <example/> | - -Use `Remove Element` to remove the whole element. - - - - - -source -xpath=. - -Returns a copy of the specified element. - -The element to copy is specified using ``source`` and ``xpath``. They -have exactly the same semantics as with `Get Element` keyword. - -If the copy or the original element is modified afterwards, the changes -have no effect on the other. - -Examples using ``${XML}`` structure from `Example`: -| ${elem} = | Get Element | ${XML} | xpath=first | -| ${copy1} = | Copy Element | ${elem} | -| ${copy2} = | Copy Element | ${XML} | xpath=first | -| Set Element Text | ${XML} | new text | xpath=first | -| Set Element Attribute | ${copy1} | id | new | -| Elements Should Be Equal | ${elem} | <first id="1">new text</first> | -| Elements Should Be Equal | ${copy1} | <first id="new">text</first> | -| Elements Should Be Equal | ${copy2} | <first id="1">text</first> | - - - - - -source -name -expected -xpath=. -message=None - -Verifies that the specified attribute is ``expected``. - -The element whose attribute is verified is specified using ``source`` -and ``xpath``. They have exactly the same semantics as with -`Get Element` keyword. - -The keyword passes if the attribute ``name`` of the element is equal to -the ``expected`` value, and otherwise it fails. The default error -message can be overridden with the ``message`` argument. - -To test that the element does not have a certain attribute, Python -``None`` (i.e. variable ``${NONE}``) can be used as the expected value. -A cleaner alternative is using `Element Should Not Have Attribute`. - -Examples using ``${XML}`` structure from `Example`: -| Element Attribute Should Be | ${XML} | id | 1 | xpath=first | -| Element Attribute Should Be | ${XML} | id | ${NONE} | | - -See also `Element Attribute Should Match` and `Get Element Attribute`. - - - - - -source -name -pattern -xpath=. -message=None - -Verifies that the specified attribute matches ``expected``. - -This keyword works exactly like `Element Attribute Should Be` except -that the expected value can be given as a pattern that the attribute of -the element must match. - -Pattern matching is similar as matching files in a shell with -``*``, ``?`` and ``[chars]`` acting as wildcards. See the -`Pattern matching` section for more information. - -Examples using ``${XML}`` structure from `Example`: -| Element Attribute Should Match | ${XML} | id | ? | xpath=first | -| Element Attribute Should Match | ${XML} | id | c*d | xpath=third/second | - - - - - -source -xpath=. -message=None - -Verifies that one or more element match the given ``xpath``. - -Arguments ``source`` and ``xpath`` have exactly the same semantics as -with `Get Elements` keyword. Keyword passes if the ``xpath`` matches -one or more elements in the ``source``. The default error message can -be overridden with the ``message`` argument. - -See also `Element Should Not Exist` as well as `Get Element Count` -that this keyword uses internally. - - - - - -source -xpath=. -message=None - -Verifies that no element match the given ``xpath``. - -Arguments ``source`` and ``xpath`` have exactly the same semantics as -with `Get Elements` keyword. Keyword fails if the ``xpath`` matches any -element in the ``source``. The default error message can be overridden -with the ``message`` argument. - -See also `Element Should Exist` as well as `Get Element Count` -that this keyword uses internally. - - - - - -source -name -xpath=. -message=None - -Verifies that the specified element does not have attribute ``name``. - -The element whose attribute is verified is specified using ``source`` -and ``xpath``. They have exactly the same semantics as with -`Get Element` keyword. - -The keyword fails if the specified element has attribute ``name``. The -default error message can be overridden with the ``message`` argument. - -Examples using ``${XML}`` structure from `Example`: -| Element Should Not Have Attribute | ${XML} | id | -| Element Should Not Have Attribute | ${XML} | xxx | xpath=first | - -See also `Get Element Attribute`, `Get Element Attributes`, -`Element Text Should Be` and `Element Text Should Match`. - - - - - -source -expected -xpath=. -normalize_whitespace=False -message=None - -Verifies that the text of the specified element is ``expected``. - -The element whose text is verified is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. - -The text to verify is got from the specified element using the same -logic as with `Get Element Text`. This includes optional whitespace -normalization using the ``normalize_whitespace`` option. - -The keyword passes if the text of the element is equal to the -``expected`` value, and otherwise it fails. The default error message -can be overridden with the ``message`` argument. Use `Element Text -Should Match` to verify the text against a pattern instead of an exact -value. - -Examples using ``${XML}`` structure from `Example`: -| Element Text Should Be | ${XML} | text | xpath=first | -| Element Text Should Be | ${XML} | ${EMPTY} | xpath=second/child | -| ${paragraph} = | Get Element | ${XML} | xpath=html/p | -| Element Text Should Be | ${paragraph} | Text with bold and italics. | normalize_whitespace=yes | - - - - - -source -pattern -xpath=. -normalize_whitespace=False -message=None - -Verifies that the text of the specified element matches ``expected``. - -This keyword works exactly like `Element Text Should Be` except that -the expected value can be given as a pattern that the text of the -element must match. - -Pattern matching is similar as matching files in a shell with -``*``, ``?`` and ``[chars]`` acting as wildcards. See the -`Pattern matching` section for more information. - -Examples using ``${XML}`` structure from `Example`: -| Element Text Should Match | ${XML} | t??? | xpath=first | -| ${paragraph} = | Get Element | ${XML} | xpath=html/p | -| Element Text Should Match | ${paragraph} | Text with * and *. | normalize_whitespace=yes | - - - - - -source -xpath=. -encoding=None - -Returns the string representation of the specified element. - -The element to convert to a string is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. - -By default the string is returned as Unicode. If ``encoding`` argument -is given any value, the string is returned as bytes in the specified -encoding. The resulting string never contains the XML declaration. - -See also `Log Element` and `Save XML`. - - - - - -source -expected -exclude_children=False -normalize_whitespace=False - -Verifies that the given ``source`` element is equal to ``expected``. - -Both ``source`` and ``expected`` can be given as a path to an XML file, -as a string containing XML, or as an already parsed XML element -structure. See `introduction` for more information about parsing XML in -general. - -The keyword passes if the ``source`` element and ``expected`` element -are equal. This includes testing the tag names, texts, and attributes -of the elements. By default also child elements are verified the same -way, but this can be disabled by setting ``exclude_children`` to a -true value (see `Boolean arguments`). - -All texts inside the given elements are verified, but possible text -outside them is not. By default texts must match exactly, but setting -``normalize_whitespace`` to a true value makes text verification -independent on newlines, tabs, and the amount of spaces. For more -details about handling text see `Get Element Text` keyword and -discussion about elements' `text` and `tail` attributes in the -`introduction`. - -Examples using ``${XML}`` structure from `Example`: -| ${first} = | Get Element | ${XML} | first | -| Elements Should Be Equal | ${first} | <first id="1">text</first> | -| ${p} = | Get Element | ${XML} | html/p | -| Elements Should Be Equal | ${p} | <p>Text with <b>bold</b> and <i>italics</i>.</p> | normalize_whitespace=yes | -| Elements Should Be Equal | ${p} | <p>Text with</p> | exclude | normalize | - -The last example may look a bit strange because the ``<p>`` element -only has text ``Text with``. The reason is that rest of the text -inside ``<p>`` actually belongs to the child elements. This includes -the ``.`` at the end that is the `tail` text of the ``<i>`` element. - -See also `Elements Should Match`. - - - - - -source -expected -exclude_children=False -normalize_whitespace=False - -Verifies that the given ``source`` element matches ``expected``. - -This keyword works exactly like `Elements Should Be Equal` except that -texts and attribute values in the expected value can be given as -patterns. - -Pattern matching is similar as matching files in a shell with -``*``, ``?`` and ``[chars]`` acting as wildcards. See the -`Pattern matching` section for more information. - -Examples using ``${XML}`` structure from `Example`: -| ${first} = | Get Element | ${XML} | first | -| Elements Should Match | ${first} | <first id="?">*</first> | - -See `Elements Should Be Equal` for more examples. - - - - - -source -expression -context=. - -Evaluates the given xpath expression and returns results. - -The element in which context the expression is executed is specified -using ``source`` and ``context`` arguments. They have exactly the same -semantics as ``source`` and ``xpath`` arguments have with `Get Element` -keyword. - -The xpath expression to evaluate is given as ``expression`` argument. -The result of the evaluation is returned as-is. - -Examples using ``${XML}`` structure from `Example`: -| ${count} = | Evaluate Xpath | ${XML} | count(third/*) | -| Should Be Equal | ${count} | ${3} | -| ${text} = | Evaluate Xpath | ${XML} | string(descendant::second[last()]/@id) | -| Should Be Equal | ${text} | child | -| ${bold} = | Evaluate Xpath | ${XML} | boolean(preceding-sibling::*[1] = 'bold') | context=html/p/i | -| Should Be Equal | ${bold} | ${True} | - -This keyword works only if lxml mode is taken into use when `importing` -the library. - - - - - -source -xpath=. - -Returns the child elements of the specified element as a list. - -The element whose children to return is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. - -All the direct child elements of the specified element are returned. -If the element has no children, an empty list is returned. - -Examples using ``${XML}`` structure from `Example`: -| ${children} = | Get Child Elements | ${XML} | | -| Length Should Be | ${children} | 4 | | -| ${children} = | Get Child Elements | ${XML} | xpath=first | -| Should Be Empty | ${children} | | | - - - - - -source -xpath=. - -Returns an element in the ``source`` matching the ``xpath``. - -The ``source`` can be a path to an XML file, a string containing XML, or -an already parsed XML element. The ``xpath`` specifies which element to -find. See the `introduction` for more details about both the possible -sources and the supported xpath syntax. - -The keyword fails if more, or less, than one element matches the -``xpath``. Use `Get Elements` if you want all matching elements to be -returned. - -Examples using ``${XML}`` structure from `Example`: -| ${element} = | Get Element | ${XML} | second | -| ${child} = | Get Element | ${element} | child | - -`Parse XML` is recommended for parsing XML when the whole structure -is needed. It must be used if there is a need to configure how XML -namespaces are handled. - -Many other keywords use this keyword internally, and keywords modifying -XML are typically documented to both to modify the given source and -to return it. Modifying the source does not apply if the source is -given as a string. The XML structure parsed based on the string and -then modified is nevertheless returned. - - - - - -source -name -xpath=. -default=None - -Returns the named attribute of the specified element. - -The element whose attribute to return is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. - -The value of the attribute ``name`` of the specified element is returned. -If the element does not have such element, the ``default`` value is -returned instead. - -Examples using ``${XML}`` structure from `Example`: -| ${attribute} = | Get Element Attribute | ${XML} | id | xpath=first | -| Should Be Equal | ${attribute} | 1 | | | -| ${attribute} = | Get Element Attribute | ${XML} | xx | xpath=first | default=value | -| Should Be Equal | ${attribute} | value | | | - -See also `Get Element Attributes`, `Element Attribute Should Be`, -`Element Attribute Should Match` and `Element Should Not Have Attribute`. - - - - - -source -xpath=. - -Returns all attributes of the specified element. - -The element whose attributes to return is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. - -Attributes are returned as a Python dictionary. It is a copy of the -original attributes so modifying it has no effect on the XML structure. - -Examples using ``${XML}`` structure from `Example`: -| ${attributes} = | Get Element Attributes | ${XML} | first | -| Dictionary Should Contain Key | ${attributes} | id | | -| ${attributes} = | Get Element Attributes | ${XML} | third | -| Should Be Empty | ${attributes} | | | - -Use `Get Element Attribute` to get the value of a single attribute. - - - - - -source -xpath=. - -Returns and logs how many elements the given ``xpath`` matches. - -Arguments ``source`` and ``xpath`` have exactly the same semantics as -with `Get Elements` keyword that this keyword uses internally. - -See also `Element Should Exist` and `Element Should Not Exist`. - - - - - -source -xpath=. -normalize_whitespace=False - -Returns all text of the element, possibly whitespace normalized. - -The element whose text to return is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. - -This keyword returns all the text of the specified element, including -all the text its children and grandchildren contain. If the element -has no text, an empty string is returned. The returned text is thus not -always the same as the `text` attribute of the element. - -By default all whitespace, including newlines and indentation, inside -the element is returned as-is. If ``normalize_whitespace`` is given -a true value (see `Boolean arguments`), then leading and trailing -whitespace is stripped, newlines and tabs converted to spaces, and -multiple spaces collapsed into one. This is especially useful when -dealing with HTML data. - -Examples using ``${XML}`` structure from `Example`: -| ${text} = | Get Element Text | ${XML} | first | -| Should Be Equal | ${text} | text | | -| ${text} = | Get Element Text | ${XML} | second/child | -| Should Be Empty | ${text} | | | -| ${paragraph} = | Get Element | ${XML} | html/p | -| ${text} = | Get Element Text | ${paragraph} | normalize_whitespace=yes | -| Should Be Equal | ${text} | Text with bold and italics. | - -See also `Get Elements Texts`, `Element Text Should Be` and -`Element Text Should Match`. - - - - - -source -xpath - -Returns a list of elements in the ``source`` matching the ``xpath``. - -The ``source`` can be a path to an XML file, a string containing XML, or -an already parsed XML element. The ``xpath`` specifies which element to -find. See the `introduction` for more details. - -Elements matching the ``xpath`` are returned as a list. If no elements -match, an empty list is returned. Use `Get Element` if you want to get -exactly one match. - -Examples using ``${XML}`` structure from `Example`: -| ${children} = | Get Elements | ${XML} | third/child | -| Length Should Be | ${children} | 2 | | -| ${children} = | Get Elements | ${XML} | first/child | -| Should Be Empty | ${children} | | | - - - - - -source -xpath -normalize_whitespace=False - -Returns text of all elements matching ``xpath`` as a list. - -The elements whose text to return is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Elements` -keyword. - -The text of the matched elements is returned using the same logic -as with `Get Element Text`. This includes optional whitespace -normalization using the ``normalize_whitespace`` option. - -Examples using ``${XML}`` structure from `Example`: -| @{texts} = | Get Elements Texts | ${XML} | third/child | -| Length Should Be | ${texts} | 2 | | -| Should Be Equal | @{texts}[0] | more text | | -| Should Be Equal | @{texts}[1] | ${EMPTY} | | - - - - - -source -level=INFO -xpath=. - -Logs the string representation of the specified element. - -The element specified with ``source`` and ``xpath`` is first converted -into a string using `Element To String` keyword internally. The -resulting string is then logged using the given ``level``. - -The logged string is also returned. - - - - - -source -keep_clark_notation=False -strip_namespaces=False - -Parses the given XML file or string into an element structure. - -The ``source`` can either be a path to an XML file or a string -containing XML. In both cases the XML is parsed into ElementTree -[http://docs.python.org/library/xml.etree.elementtree.html#element-objects|element structure] -and the root element is returned. Possible comments and processing -instructions in the source XML are removed. - -As discussed in `Handling XML namespaces` section, this keyword, by -default, removes namespace information ElementTree has added to tag -names and moves it into ``xmlns`` attributes. This typically eases -handling XML documents with namespaces considerably. If you do not -want that to happen, or want to avoid the small overhead of going -through the element structure when your XML does not have namespaces, -you can disable this feature by giving ``keep_clark_notation`` argument -a true value (see `Boolean arguments`). - -If you want to strip namespace information altogether so that it is -not included even if XML is saved, you can give a true value to -``strip_namespaces`` argument. This functionality is new in Robot -Framework 3.0.2. - -Examples: -| ${root} = | Parse XML | <root><child/></root> | -| ${xml} = | Parse XML | ${CURDIR}/test.xml | keep_clark_notation=True | -| ${xml} = | Parse XML | ${CURDIR}/test.xml | strip_namespaces=True | - -Use `Get Element` keyword if you want to get a certain element and not -the whole structure. See `Parsing XML` section for more details and -examples. - - - - - -source -xpath= -remove_tail=False - -Removes the element matching ``xpath`` from the ``source`` structure. - -The element to remove from the ``source`` is specified with ``xpath`` -using the same semantics as with `Get Element` keyword. The resulting -XML structure is returned, and if the ``source`` is an already parsed -XML structure, it is also modified in place. - -The keyword fails if ``xpath`` does not match exactly one element. -Use `Remove Elements` to remove all matched elements. - -Element's tail text is not removed by default, but that can be changed -by giving ``remove_tail`` a true value (see `Boolean arguments`). See -`Element attributes` section for more information about `tail` in -general. - -Examples using ``${XML}`` structure from `Example`: -| Remove Element | ${XML} | xpath=second | -| Element Should Not Exist | ${XML} | xpath=second | -| Remove Element | ${XML} | xpath=html/p/b | remove_tail=yes | -| Element Text Should Be | ${XML} | Text with italics. | xpath=html/p | normalize_whitespace=yes | - - - - - -source -name -xpath=. - -Removes attribute ``name`` from the specified element. - -The element whose attribute to remove is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. The resulting XML structure is returned, and if the ``source`` -is an already parsed XML structure, it is also modified in place. - -It is not a failure to remove a non-existing attribute. Use `Remove -Element Attributes` to remove all attributes and `Set Element Attribute` -to set them. - -Examples using ``${XML}`` structure from `Example`: -| Remove Element Attribute | ${XML} | id | xpath=first | -| Element Should Not Have Attribute | ${XML} | id | xpath=first | - -Can only remove an attribute from a single element. Use `Remove Elements -Attribute` to remove an attribute of multiple elements in one call. - - - - - -source -xpath=. - -Removes all attributes from the specified element. - -The element whose attributes to remove is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. The resulting XML structure is returned, and if the ``source`` -is an already parsed XML structure, it is also modified in place. - -Use `Remove Element Attribute` to remove a single attribute and -`Set Element Attribute` to set them. - -Examples using ``${XML}`` structure from `Example`: -| Remove Element Attributes | ${XML} | xpath=first | -| Element Should Not Have Attribute | ${XML} | id | xpath=first | - -Can only remove attributes from a single element. Use `Remove Elements -Attributes` to remove all attributes of multiple elements in one call. - - - - - -source -xpath= -remove_tail=False - -Removes all elements matching ``xpath`` from the ``source`` structure. - -The elements to remove from the ``source`` are specified with ``xpath`` -using the same semantics as with `Get Elements` keyword. The resulting -XML structure is returned, and if the ``source`` is an already parsed -XML structure, it is also modified in place. - -It is not a failure if ``xpath`` matches no elements. Use `Remove -Element` to remove exactly one element. - -Element's tail text is not removed by default, but that can be changed -by using ``remove_tail`` argument similarly as with `Remove Element`. - -Examples using ``${XML}`` structure from `Example`: -| Remove Elements | ${XML} | xpath=*/child | -| Element Should Not Exist | ${XML} | xpath=second/child | -| Element Should Not Exist | ${XML} | xpath=third/child | - - - - - -source -name -xpath=. - -Removes attribute ``name`` from the specified elements. - -Like `Remove Element Attribute` but removes the attribute of all -elements matching the given ``xpath``. - - - - - -source -xpath=. - -Removes all attributes from the specified elements. - -Like `Remove Element Attributes` but removes all attributes of all -elements matching the given ``xpath``. - - - - - -source -path -encoding=UTF-8 - -Saves the given element to the specified file. - -The element to save is specified with ``source`` using the same -semantics as with `Get Element` keyword. - -The file where the element is saved is denoted with ``path`` and the -encoding to use with ``encoding``. The resulting file always contains -the XML declaration. - -The resulting XML file may not be exactly the same as the original: -- Comments and processing instructions are always stripped. -- Possible doctype and namespace prefixes are only preserved when - `using lxml`. -- Other small differences are possible depending on the ElementTree - or lxml version. - -Use `Element To String` if you just need a string representation of -the element. - - - - - -source -name -value -xpath=. - -Sets attribute ``name`` of the specified element to ``value``. - -The element whose attribute to set is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. The resulting XML structure is returned, and if the ``source`` -is an already parsed XML structure, it is also modified in place. - -It is possible to both set new attributes and to overwrite existing. -Use `Remove Element Attribute` or `Remove Element Attributes` for -removing them. - -Examples using ``${XML}`` structure from `Example`: -| Set Element Attribute | ${XML} | attr | value | -| Element Attribute Should Be | ${XML} | attr | value | -| Set Element Attribute | ${XML} | id | new | xpath=first | -| Element Attribute Should Be | ${XML} | id | new | xpath=first | - -Can only set an attribute of a single element. Use `Set Elements -Attribute` to set an attribute of multiple elements in one call. - - - - - -source -tag -xpath=. - -Sets the tag of the specified element. - -The element whose tag to set is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. The resulting XML structure is returned, and if the ``source`` -is an already parsed XML structure, it is also modified in place. - -Examples using ``${XML}`` structure from `Example`: -| Set Element Tag | ${XML} | newTag | -| Should Be Equal | ${XML.tag} | newTag | -| Set Element Tag | ${XML} | xxx | xpath=second/child | -| Element Should Exist | ${XML} | second/xxx | -| Element Should Not Exist | ${XML} | second/child | - -Can only set the tag of a single element. Use `Set Elements Tag` to set -the tag of multiple elements in one call. - - - - - -source -text=None -tail=None -xpath=. - -Sets text and/or tail text of the specified element. - -The element whose text to set is specified using ``source`` and -``xpath``. They have exactly the same semantics as with `Get Element` -keyword. The resulting XML structure is returned, and if the ``source`` -is an already parsed XML structure, it is also modified in place. - -Element's text and tail text are changed only if new ``text`` and/or -``tail`` values are given. See `Element attributes` section for more -information about `text` and `tail` in general. - -Examples using ``${XML}`` structure from `Example`: -| Set Element Text | ${XML} | new text | xpath=first | -| Element Text Should Be | ${XML} | new text | xpath=first | -| Set Element Text | ${XML} | tail=& | xpath=html/p/b | -| Element Text Should Be | ${XML} | Text with bold&italics. | xpath=html/p | normalize_whitespace=yes | -| Set Element Text | ${XML} | slanted | !! | xpath=html/p/i | -| Element Text Should Be | ${XML} | Text with bold&slanted!! | xpath=html/p | normalize_whitespace=yes | - -Can only set the text/tail of a single element. Use `Set Elements Text` -to set the text/tail of multiple elements in one call. - - - - - -source -name -value -xpath=. - -Sets attribute ``name`` of the specified elements to ``value``. - -Like `Set Element Attribute` but sets the attribute of all elements -matching the given ``xpath``. - - - - - -source -tag -xpath=. - -Sets the tag of the specified elements. - -Like `Set Element Tag` but sets the tag of all elements matching -the given ``xpath``. - - - - - -source -text=None -tail=None -xpath=. - -Sets text and/or tail text of the specified elements. - -Like `Set Element Text` but sets the text or tail of all elements -matching the given ``xpath``. - - - - diff --git a/libspecs/browserstack.local_f74ac98.libspec b/libspecs/browserstack.local_f74ac98.libspec deleted file mode 100644 index 8eb48ab..0000000 --- a/libspecs/browserstack.local_f74ac98.libspec +++ /dev/null @@ -1,7 +0,0 @@ - - - -global -yes -Documentation for library ``browserstack.local``. - diff --git a/red.xml b/red.xml deleted file mode 100644 index 8a0991c..0000000 --- a/red.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - 2 - WORKSPACE - - - - - - - true - 1024 - diff --git a/web/test/parallel/0-selenium-screenshot-1.png b/web/test/parallel/0-selenium-screenshot-1.png deleted file mode 100644 index 37b3597c25ada6efbed5cb7684a42b1f8fdd4a4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236112 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%0D{y%tKHgyT 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

)z^dmTbwyyq(t6pK-yD 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 oQED_KMiawmei+Ci;r)MRt366 Date: Mon, 5 Sep 2022 19:42:14 +0530 Subject: [PATCH 2/2] License added --- LICENSE | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f9c7afb --- /dev/null +++ b/LICENSE @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright (c) 2021, BrowserStack Limited. https://www.browserstack.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file