diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle index 40542641dc..e6792de04c 100644 Binary files a/.doctrees/environment.pickle and b/.doctrees/environment.pickle differ diff --git a/.doctrees/libraries/http/python.doctree b/.doctrees/libraries/http/python.doctree index 33cacec9e2..cdf75ae846 100644 Binary files a/.doctrees/libraries/http/python.doctree and b/.doctrees/libraries/http/python.doctree differ diff --git a/.doctrees/releasenotes.doctree b/.doctrees/releasenotes.doctree index 9811b6bb2f..99713d2eea 100644 Binary files a/.doctrees/releasenotes.doctree and b/.doctrees/releasenotes.doctree differ diff --git a/_sources/releasenotes.rst.txt b/_sources/releasenotes.rst.txt index 20910a6021..bc6d214604 100644 --- a/_sources/releasenotes.rst.txt +++ b/_sources/releasenotes.rst.txt @@ -27,6 +27,7 @@ Security releases regarding dependency packages `pillow`, `cryptography` and `ai - package ``rpaframework-hubspot`` **1.0.1** - package ``rpaframework-openai`` **1.3.2** - package ``rpaframework-pdf`` **7.3.2** +- package ``rpaframework-recognition`` **5.2.4** - package ``rpaframework-windows`` **7.5.1** .. note:: diff --git a/latest.json b/latest.json index e8d93ac1ec..1d1a5cac25 100644 --- a/latest.json +++ b/latest.json @@ -4,7 +4,7 @@ "name": "RPA.Archive", "doc": "
Archive is a library for operating with ZIP and TAR packages.
\nExamples
\n\n*** Settings ***\nLibrary RPA.Archive\n\n*** Tasks ***\nCreating a ZIP archive\n Archive Folder With ZIP ${CURDIR}${/}tasks tasks.zip recursive=True include=*.robot exclude=/.*\n @{files} List Archive tasks.zip\n FOR ${file} IN ${files}\n Log ${file}\n END\n Add To Archive .${/}..${/}missing.robot tasks.zip\n &{info} Get Archive Info\n\n
\nfrom RPA.Archive import Archive\n\nlib = Archive()\nlib.archive_folder_with_tar('./tasks', 'tasks.tar', recursive=True)\nfiles = lib.list_archive('tasks.tar')\nfor file in files:\n print(file)\n\n
The Assistant library provides a way to display information to a user\nand request input while a robot is running. It allows building processes\nthat require human interaction. Also it offers capabilities of running\nother robots inside the current one and determine what to display to the\nuser based on his previous responses.
\nIt is not included in the rpaframework package, so in order to use it\nyou have to add rpaframework-assistant with the desired version in your\nconda.yaml file
\nSome examples of use-cases could be the following:
\nWorkflow
\nThe library is used to create dialogs, i.e. windows, that can be composed\non-the-fly based on the current state of the execution.
\nThe content of the dialog is defined by calling relevant keywords\nsuch as Add text or Add file input. When the dialog is opened\nthe content is generated based on the previous keywords.
\nDepending on the way the dialog is started, the execution will either\nblock or continue while the dialog is open. During this time the user\ncan freely edit any possible input fields or handle other tasks.
\nAfter the user has successfully submitted the dialog, any possible\nentered input will be returned as a result. The user also has the option\nto abort by closing the dialog window forcefully.
\nResults
\nEach input field has a required name argument that controls what\nthe value will be called in the result object. Each input name should be\nunique, and must not be called submit as that is reserved for the submit\nbutton value.
\nA result object is a Robot Framework DotDict, where each key\nis the name of the input field and the value is what the user entered.\nThe data type of each field depends on the input. For instance,\na text input will have a string, a checkbox will have a boolean, and\na file input will have a list of paths.
\nIf the user closed the window before submitting or there was an internal\nerror, the results object returned by Run Dialog or Ask User won't have a "submit"\nkey.
\nLayouting
\nBy default elements are added to the assistant dialog from top to bottom, with a bit\nof margin around each element to add spaciousness. This margin is added as a\nContainer you can manually use Open Container to override the default\ncontainer. You can use it to set smaller margins.
\nYou can combine layouting elements with each other. Layouting elements need to be\nclosed with the corresponding Close keyword. (So Open Row and then\nClose Row.)
\nOpen Row can be used to layout elements in the same row.
\nOpen Column can be used to layout elements in columns.
\nOpen Stack and multiple Open Container's inside it can be used to set\npositions like Center, Topleft, BottomRight, or coordinate tuples likes (0, 0),\n(100, 100) and such.
\nOpen Container can bse used for absolute positioning inside a Stack, or anywhere\nfor setting background color or margins and paddings.
\nOpen Navbar can be used to make a navigation bar that will stay at the top of\nthe dialog. Its contents won't be cleared when.
\nExamples
\n\n*** Keywords ***\nSuccess dialog\n Add icon Success\n Add heading Your orders have been processed\n Add files *.txt\n Run dialog title=Success\n\nFailure dialog\n Add icon Failure\n Add heading There was an error\n Add text The assistant failed to login to the Enterprise portal\n Add link https://robocorp.com/docs label=Troubleshooting guide\n Run dialog title=Failure\n\nLarge dialog\n Add heading A real chonker size=large\n Add image fat-cat.jpeg\n Run dialog title=Large height=1024 width=1024\n\nConfirmation dialog\n Add icon Warning\n Add heading Delete user ${username}?\n Add submit buttons buttons=No,Yes default=Yes\n ${result}= Run dialog\n IF $result.submit == "Yes"\n Delete user ${username}\n END\n\nInput form dialog\n Add heading Send feedback\n Add text input email label=E-mail address\n Add text input message\n ... label=Feedback\n ... placeholder=Enter feedback here\n ... maximum_rows=5\n ${result}= Run dialog\n Send feedback message ${result.email} ${result.message}\n\n
\ndef success_dialog():\n assistant = Assistant()\n assistant.add_icon("success")\n assistant.add_heading("Your orders have been processed")\n assistant.add_files("*.txt")\n assistant.run_dialog(title="Success")\n\ndef failure_dialog():\n assistant = Assistant()\n assistant.add_icon("failure")\n assistant.add_heading("There was an error")\n assistant.add_text("The assistant failed to login to the Enterprise portal")\n assistant.add_link("https://robocorp.com/docs", label="Troubleshooting guide")\n assistant.add_files("*.txt")\n assistant.run_dialog(title="Failure")\n\ndef large_dialog():\n assistant = Assistant()\n assistant.add_heading("A real chonker", size="large")\n assistant.add_image("fat-cat.jpeg")\n assistant.run_dialog(title="Large", height=1024, width=1024)\n\ndef confirmation_dialog():\n assistant = Assistant()\n assistant.add_icon("warning")\n assistant.add_heading("Delete user ${username}?")\n assistant.add_submit_buttons(buttons="No, Yes", default="Yes")\n result = assistant.run_dialog()\n if result.submit == "Yes":\n delete_user(username)\n\ndef input_from_dialog():\n assistant = Assistant()\n assistant.add_heading("Send feedback")\n assistant.add_text_input("email", label="E-mail address")\n assistant.add_text_input("message", label="Feedback", placeholder="Enter feedback here", maximum_rows=5)\n assistant.add_submit_buttons("Submit", default="Submit")\n result = assistant.run_dialog()\n send_feedback_message(result.email, result.message)\n\n
SeleniumLibrary is a web testing library for Robot Framework.
\nThis document explains how to use keywords provided by SeleniumLibrary. For information about installation, support, and more, please visit the project pages. For more information about Robot Framework, see http://robotframework.org.
\nSeleniumLibrary 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 Browser drivers chapter for more details about WebDriver binary installation.
\nAll 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.
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.
\nBy 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:
\nClick Element | \nexample | \n# Match based on id or name . | \n
Click Link | \nexample | \n# Match also based on link text and href . | \n
Click Button | \nexample | \n# Match based on id , name or value . | \n
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:
\nClick Element | \nname:foo | \n# Find element with name foo . | \n
Click Element | \ndefault:name:foo | \n# Use default strategy with value name:foo . | \n
Click Element | \n//foo | \n# Find element using XPath //foo . | \n
Click Element | \ndefault: //foo | \n# Use default strategy with value //foo . | \n
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 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.
\nStrategy | \nMatch based on | \nExample | \n
---|---|---|
id | \nElement id . | \nid:example | \n
name | \nname attribute. | \nname:example | \n
identifier | \nEither id or name . | \nidentifier:example | \n
class | \nElement class . | \nclass:example | \n
tag | \nTag name. | \ntag:div | \n
xpath | \nXPath expression. | \nxpath://div[@id=\"example\"] | \n
css | \nCSS selector. | \ncss:div#example | \n
dom | \nDOM expression. | \ndom:document.images[5] | \n
link | \nExact text a link has. | \nlink:The example | \n
partial link | \nPartial link text. | \npartial link:he ex | \n
sizzle | \nSizzle selector deprecated. | \nsizzle:div.example | \n
data | \nElement data-* attribute | \ndata:id:my_id | \n
jquery | \njQuery expression. | \njquery:div.example | \n
default | \nKeyword specific default behavior. | \ndefault:example | \n
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:
\nClick Element | \nid:foo | \n# Element with id 'foo'. | \n
Click Element | \ncss:div#foo h1 | \n# h1 element under div with id 'foo'. | \n
Click Element | \nxpath: //div[@id=\"foo\"]//h1 | \n# Same as the above using XPath, not CSS. | \n
Click Element | \nxpath: //*[contains(text(), \"example\")] | \n# Element containing text 'example'. | \n
NOTE:
\nstrategy:value
syntax is only supported by SeleniumLibrary 3.0 and newer.sizzle
strategy or its alias jquery
requires that the system under test contains the jQuery library.xpath
, css
and sizzle/jquery
strategies.data
strategy is conveniance locator that will construct xpath from the parameters. If you have element like <div data-automation=\"automation-id-2\">, you locate the element via data:automation:automation-id-2
. This feature was added in SeleniumLibrary 5.2.0If the locator starts with //
or multiple opening parenthesis in front of the //
, the locator is considered to be an XPath expression. In other words, using //div
is equivalent to using explicit xpath://div
and ((//div))
is equivalent to using explicit xpath:((//div))
Examples:
\nClick Element | \n//div[@id=\"foo\"]//h1 | \n
Click Element | \n(//div)[2] | \n
The support for the (//
prefix is new in SeleniumLibrary 3.0. Supporting multiple opening parenthesis is new in SeleniumLibrary 5.0.
It is possible chain multiple locators together as single locator. Each chained locator must start with locator strategy. Chained locators must be separated with single space, two greater than characters and followed with space. It is also possible mix different locator strategies, example css or xpath. Also a list can also be used to specify multiple locators. This is useful, is some part of locator would match as the locator separator but it should not. Or if there is need to existing WebElement as locator.
\nAlthough all locators support chaining, some locator strategies do not abey the chaining. This is because some locator strategies use JavaScript to find elements and JavaScript is executed for the whole browser context and not for the element found be the previous locator. Chaining is supported by locator strategies which are based on Selenium API, like xpath or css, but example chaining is not supported by sizzle or `jquery
\nExamples:
\nClick Element | \ncss:.bar >> xpath://a | \n# To find a link which is present after an element with class \"bar\" | \n
List examples:
\n${locator_list} = | \nCreate List | \ncss:div#div_id | \nxpath://*[text(), \" >> \"] | \n
Page Should Contain Element | \n${locator_list} | \n\n | \n |
${element} = | \nGet WebElement | \nxpath://*[text(), \" >> \"] | \n\n |
${locator_list} = | \nCreate List | \ncss:div#div_id | \n${element} | \n
Page Should Contain Element | \n${locator_list} | \n\n | \n |
Chaining locators in new in SeleniumLibrary 5.0
\nIn 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.
\n${elem} = | \nGet WebElement | \nid:example | \n
Click Element | \n${elem} | \n\n |
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:
\nCustom Locator Strategy | \n[Arguments] | \n${browser} | \n${locator} | \n${tag} | \n${constraints} | \n
\n | ${element}= | \nExecute Javascript | \nreturn window.document.getElementById('${locator}'); | \n\n | \n |
\n | [Return] | \n${element} | \n\n | \n | \n |
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 | \ncustom | \nCustom Locator Strategy | \n
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:
\nClick Element | \ncustom:example | \n
See the Add Location Strategy keyword for more details.
\nThere is different conceptual meaning when SeleniumLibrary talks about windows or browsers. This chapter explains those differences.
\nWhen Open Browser or Create WebDriver keyword is called, it will create a new Selenium WebDriver instance by using the 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.
\nWindows 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:
\n\nExecute Javascript window.open() # Opens a new window with location about:blank\n\n
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.
\nStructure:
\n\nBrowserA\n Window 1 (location=https://robotframework.org/)\n Window 2 (location=https://robocon.io/)\n Window 3 (location=https://github.com/robotframework/)\n\nBrowserB\n Window 1 (location=https://github.com/)\n\n
Example:
\nOpen Browser | \nhttps://robotframework.org | \n${BROWSER} | \nalias=BrowserA | \n# BrowserA with first window is opened. | \n
Execute Javascript | \nwindow.open() | \n\n | \n | # In BrowserA second window is opened. | \n
Switch Window | \nlocator=NEW | \n\n | \n | # Switched to second window in BrowserA | \n
Go To | \nhttps://robocon.io | \n\n | \n | # Second window navigates to robocon site. | \n
Execute Javascript | \nwindow.open() | \n\n | \n | # In BrowserA third window is opened. | \n
${handle} | \nSwitch Window | \nlocator=NEW | \n\n | # Switched to third window in BrowserA | \n
Go To | \nhttps://github.com/robotframework/ | \n\n | \n | # Third windows goes to robot framework github site. | \n
Open Browser | \nhttps://github.com | \n${BROWSER} | \nalias=BrowserB | \n# BrowserB with first windows is opened. | \n
${location} | \nGet Location | \n\n | \n | # ${location} is: https://www.github.com | \n
Switch Window | \n${handle} | \nbrowser=BrowserA | \n\n | # BrowserA second windows is selected. | \n
${location} | \nGet Location | \n\n | \n | # ${location} = https://robocon.io/ | \n
@{locations 1} | \nGet Locations | \n\n | \n | # By default, lists locations under the currectly active browser (BrowserA). | \n
@{locations 2} | \nGet Locations | \nbrowser=ALL | \n\n | # By using browser=ALL argument keyword list all locations from all browsers. | \n
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/.
\nThis 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.
\nSeleniumLibrary 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. If no default timeout is set globally, the default is 5 seconds. If None is specified for the timeout argument in the keywords, the default is used. See time format below for supported timeout syntax.
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 Selenium documentation for more information about this functionality.
See time format below for supported syntax.
\nPage load timeout is the amount of time to wait for page load to complete until a timeout exception is raised.
\nThe default page load timeout can be set globally when importing the library with the page_load_timeout
argument or by using the Set Selenium Page Load Timeout keyword.
See time format below for supported timeout syntax.
\nSupport for page load is new in SeleniumLibrary 6.1
\nSelenium 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.
\nSee time format below for supported syntax.
\nAll 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 Robot Framework User Guide.
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
.
Starting from 5.0 SeleniumLibrary relies on Robot Framework to perform the boolean conversion based on keyword arguments type hint. More details in Robot Framework user guide
\nPlease note SeleniumLibrary 3 and 4 did have own custom methods to covert arguments to boolean values.
\nThe SeleniumLibrary offers support for EventFiringWebDriver. See the Selenium and SeleniumLibrary EventFiringWebDriver support documentation for further details.
\nEventFiringWebDriver is new in SeleniumLibrary 4.0
\nSeleniumLibrary is not thread-safe. This is mainly due because the underlying 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.
\nSeleniumLibrary 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 plugin API documentation for further details.
\nPlugin API is new SeleniumLibrary 4.0
\nBy default, the browser instances created during a task execution are closed at the end of the task. This can be prevented with the auto_close
parameter when importing the library.
The value of the parameter needs to be set to False
or any object evaluated as false (see Boolean arguments).
Browser library is a browser automation library for Robot Framework.
\nThis is the keyword documentation for Browser library. For information about installation, support, and more please visit the project pages. For more information about Robot Framework itself, see robotframework.org.
\nBrowser library uses Playwright Node module to automate Chromium, Firefox and WebKit with a single library.
\nBrowser library works with three different layers that build on each other: Browser, Context and Page.
\nA browser can be started with one of the three different engines Chromium, Firefox or Webkit.
\nBrowser | \nBrowser with this engine | \n
chromium | \nGoogle Chrome, Microsoft Edge (since 2020), Opera | \n
firefox | \nMozilla Firefox | \n
webkit | \nApple Safari, Mail, AppStore on MacOS and iOS | \n
Since Playwright comes with a pack of builtin binaries for all browsers, no additional drivers e.g. geckodriver are needed.
\nAll these browsers that cover more than 85% of the world wide used browsers, can be tested on Windows, Linux and MacOS. There is no need for dedicated machines anymore.
\nA browser process is started headless
(without a GUI) by default. Run New Browser with specified arguments if a browser with a GUI is requested or if a proxy has to be configured. A browser process can contain several contexts.
A context corresponds to a set of independent incognito pages in a browser that share cookies, sessions or profile settings. Pages in two separate contexts do not share cookies, sessions or profile settings. Compared to Selenium, these do not require their own browser process. To get a clean environment a test can just open a new context. Due to this new independent browser sessions can be opened with Robot Framework Browser about 10 times faster than with Selenium by just opening a New Context within the opened browser.
\nTo make pages in the same suite share state, use the same context by opening the context with New Context on suite setup.
\nThe context layer is useful e.g. for testing different user sessions on the same webpage without opening a whole new browser context. Contexts can also have detailed configurations, such as geo-location, language settings, the viewport size or color scheme. Contexts do also support http credentials to be set, so that basic authentication can also be tested. To be able to download files within the test, the acceptDownloads
argument must be set to True
in New Context keyword. A context can contain different pages.
A page does contain the content of the loaded web site and has a browsing history. Pages and browser tabs are the same.
\nTypical usage could be:
\n\n* Test Cases *\nStarting a browser with a page\n New Browser chromium headless=false\n New Context viewport={'width': 1920, 'height': 1080}\n New Page https://marketsquare.github.io/robotframework-browser/Browser.html\n Get Title == Browser\n\n
The Open Browser keyword opens a new browser, a new context and a new page. This keyword is useful for quick experiments or debugging sessions.
\nWhen a New Page is called without an open browser, New Browser and New Context are executed with default values first.
\nEach Browser, Context and Page has a unique ID with which they can be addressed. A full catalog of what is open can be received by Get Browser Catalog as a dictionary.
\nControls when contexts and pages are closed during the test execution.
\nIf automatic closing level is TEST, contexts and pages that are created during a single test are automatically closed when the test ends. Contexts and pages that are created during suite setup are closed when the suite teardown ends.
\nIf automatic closing level is SUITE, all contexts and pages that are created during the test suite are closed when the suite teardown ends.
\nIf automatic closing level is MANUAL, nothing is closed automatically while the test execution is ongoing.
\nAll browsers are automatically closed, always and regardless of the automatic closing level at the end of the test execution. This will also close all remaining pages and contexts.
\nAutomatic closing can be configured or switched off with the auto_closing_level library import parameter.
\nSee: Importing
\nAll keywords in the library that need to interact with an element on a web page take an argument typically named selector
that specifies how to find the element. Keywords can find elements with strict mode. If strict mode is true and locator finds multiple elements from the page, keyword will fail. If keyword finds one element, keyword does not fail because of strict mode. If strict mode is false, keyword does not fail if selector points many elements. Strict mode is enabled by default, but can be changed in library importing or Set Strict Mode keyword. Keyword documentation states if keyword uses strict mode. If keyword does not state that strict mode is used, then strict mode is not applied for the keyword. For more details, see Playwright strict documentation.
Selector strategies that are supported by default are listed in the table below.
\nStrategy | \nMatch based on | \nExample | \n
---|---|---|
css | \nCSS selector. | \ncss=.class > \\#login_btn | \n
xpath | \nXPath expression. | \nxpath=//input[@id=\"login_btn\"] | \n
text | \nBrowser text engine. | \ntext=Login | \n
id | \nElement ID Attribute. | \nid=login_btn | \n
CSS Selectors can also be recorded with Record selector keyword.
\nThe explicit selector strategy is specified with a prefix using syntax strategy=value
. Spaces around the separator are ignored, so css=foo
, css= foo
and css = foo
are all equivalent.
The default selector strategy is css.
\nIf selector does not contain one of the know explicit selector strategies, it is assumed to contain css selector.
\nSelectors that are starting with //
or ..
are considered as xpath selectors.
Selectors that are in quotes are considered as text selectors.
\nExamples:
\n\n# CSS selectors are default.\nClick span > button.some_class # This is equivalent\nClick css=span > button.some_class # to this.\n\n# // or .. leads to xpath selector strategy\nClick //span/button[@class=\"some_class\"]\nClick xpath=//span/button[@class=\"some_class\"]\n\n# \"text\" in quotes leads to exact text selector strategy\nClick \"Login\"\nClick text=\"Login\"\n\n
As written before, the default selector strategy is css. See css selector for more information.
\nAny malformed selector not starting with //
or ..
nor starting and ending with a quote is assumed to be a css selector.
Note that #
is a comment character in Robot Framework syntax and needs to be escaped like \\#
to work as a css ID selector.
Examples:
\n\nClick span > button.some_class\nGet Text \\#username_field == George\n\n
XPath engine is equivalent to Document.evaluate. Example: xpath=//html/body//span[text()=\"Hello World\"]
.
Malformed selector starting with //
or ..
is assumed to be an xpath selector. For example, //html/body
is converted to xpath=//html/body
. More examples are displayed in Examples.
Note that xpath does not pierce shadow_roots.
\nText engine finds an element that contains a text node with the passed text. For example, Click text=Login
clicks on a login button, and Wait For Elements State text=\"lazy loaded text\"
waits for the \"lazy loaded text\" to appear in the page.
Text engine finds fields based on their labels in text inserting keywords.
\nMalformed selector starting and ending with a quote (either \"
or '
) is assumed to be a text selector. For example, Click \"Login\"
is converted to Click text=\"Login\"
. Be aware that these leads to exact matches only! More examples are displayed in Examples.
By default, the match is case-insensitive, ignores leading/trailing whitespace and searches for a substring. This means text= Login
matches <button>Button loGIN (click me)</button>
.
Text body can be escaped with single or double quotes for precise matching, insisting on exact match, including specified whitespace and case. This means text=\"Login \"
will only match <button>Login </button>
with exactly one space after \"Login\". Quoted text follows the usual escaping rules, e.g. use \\\"
to escape double quote in a double-quoted string: text=\"foo\\\"bar\"
.
Text body can also be a JavaScript-like regex wrapped in / symbols. This means text=/^hello .*!$/i
or text=/^Hello .*!$/
will match <span>Hello Peter Parker!</span>
with any name after Hello
, ending with !
. The first one flagged with i
for case-insensitive. See https://regex101.com for more information about RegEx.
Input elements of the type button and submit are rendered with their value as text, and text engine finds them. For example, text=Login
matches <input type=button value=\"Login\">
.
Browser library supports the same selector strategies as the underlying Playwright node module: xpath, css, id and text. The strategy can either be explicitly specified with a prefix or the strategy can be implicit.
\nA major advantage of Browser is that multiple selector engines can be used within one selector. It is possible to mix XPath, CSS and Text selectors while selecting a single element.
\nSelectors are strings that consists of one or more clauses separated by >>
token, e.g. clause1 >> clause2 >> clause3
. When multiple clauses are present, next one is queried relative to the previous one's result. Browser library supports concatenation of different selectors separated by >>
.
For example:
\n\nHighlight Elements \"Hello\" >> ../.. >> .select_button\nHighlight Elements text=Hello >> xpath=../.. >> css=.select_button\n\n
Each clause contains a selector engine name and selector body, e.g. engine=body
. Here engine
is one of the supported engines (e.g. css or a custom one). Selector body
follows the format of the particular engine, e.g. for css engine it should be a css selector. Body format is assumed to ignore leading and trailing white spaces, so that extra whitespace can be added for readability. If the selector engine needs to include >>
in the body, it should be escaped inside a string to not be confused with clause separator, e.g. text=\"some >> text\"
.
Selector engine name can be prefixed with *
to capture an element that matches the particular clause instead of the last one. For example, css=article >> text=Hello
captures the element with the text Hello
, and *css=article >> text=Hello
(note the *) captures the article element that contains some element with the text Hello.
For convenience, selectors in the wrong format are heuristically converted to the right format. See Implicit Selector Strategy
\n\n# queries 'div' css selector\nGet Element css=div\n\n# queries '//html/body/div' xpath selector\nGet Element //html/body/div\n\n# queries '\"foo\"' text selector\nGet Element text=foo\n\n# queries 'span' css selector inside the result of '//html/body/div' xpath selector\nGet Element xpath=//html/body/div >> css=span\n\n# converted to 'css=div'\nGet Element div\n\n# converted to 'xpath=//html/body/div'\nGet Element //html/body/div\n\n# converted to 'text=\"foo\"'\nGet Element \"foo\"\n\n# queries the div element of every 2nd span element inside an element with the id foo\nGet Element \\#foo >> css=span:nth-child(2n+1) >> div\nGet Element id=foo >> css=span:nth-child(2n+1) >> div\n\n
Be aware that using #
as a starting character in Robot Framework would be interpreted as comment. Due to that fact a #id
must be escaped as \\#id
.
By default, selector chains do not cross frame boundaries. It means that a simple CSS selector is not able to select an element located inside an iframe or a frameset. For this use case, there is a special selector >>>
which can be used to combine a selector for the frame and a selector for an element inside a frame.
Given this simple pseudo html snippet:
\n\n<iframe id=\"iframe\" src=\"src.html\">\n #document\n <!DOCTYPE html>\n <html>\n <head></head>\n <body>\n <button id=\"btn\">Click Me</button>\n </body>\n </html>\n</iframe>\n\n
Here's a keyword call that clicks the button inside the frame.
\n\nClick id=iframe >>> id=btn\n\n
The selectors on the left and right side of >>>
can be any valid selectors. The selector clause directly before the frame opener >>>
must select the frame element. Frame selection is the only place where Browser Library modifies the selector, as explained in above. In all cases, the library does not alter the selector in any way, instead it is passed as is to the Playwright side.
Playwright and so also Browser are able to do automatic piercing of Shadow DOMs and therefore are the best automation technology when working with WebComponents.
\nAlso other technologies claim that they can handle Shadow DOM and Web Components. However, none of them do pierce shadow roots automatically, which may be inconvenient when working with Shadow DOM and Web Components.
\nFor that reason, the css engine pierces shadow roots. More specifically, every Descendant combinator pierces an arbitrary number of open shadow roots, including the implicit descendant combinator at the start of the selector.
\nThat means, it is not necessary to select each shadow host, open its shadow root and select the next shadow host until you reach the element that should be controlled.
\ncss:light
engine is equivalent to Document.querySelector and behaves according to the CSS spec. However, it does not pierce shadow roots.
css
engine first searches for elements in the light dom in the iteration order, and then recursively inside open shadow roots in the iteration order. It does not search inside closed shadow roots or iframes.
Examples:
\n\n<article>\n <div>In the light dom</div>\n <div slot='myslot'>In the light dom, but goes into the shadow slot</div>\n <open mode shadow root>\n <div class='in-the-shadow'>\n <span class='content'>\n In the shadow dom\n <open mode shadow root>\n <li id='target'>Deep in the shadow</li>\n </open mode shadow root>\n </span>\n </div>\n <slot name='myslot'></slot>\n </open mode shadow root>\n</article>\n\n
Note that <open mode shadow root>
is not an html element, but rather a shadow root created with element.attachShadow({mode: 'open'})
.
\"css=article div\"
and \"css:light=article div\"
match the first <div>In the light dom</div>
.\"css=article > div\"
and \"css:light=article > div\"
match two div
elements that are direct children of the article
.\"css=article .in-the-shadow\"
matches the <div class='in-the-shadow'>
, piercing the shadow root, while \"css:light=article .in-the-shadow\"
does not match anything.\"css:light=article div > span\"
does not match anything, because both light-dom div
elements do not contain a span
.\"css=article div > span\"
matches the <span class='content'>
, piercing the shadow root.\"css=article > .in-the-shadow\"
does not match anything, because <div class='in-the-shadow'>
is not a direct child of article
\"css:light=article > .in-the-shadow\"
does not match anything.\"css=article li#target\"
matches the <li id='target'>Deep in the shadow</li>
, piercing two shadow roots.text
engine open pierces shadow roots similarly to css
, while text:light
does not. Text engine first searches for elements in the light dom in the iteration order, and then recursively inside open shadow roots in the iteration order. It does not search inside closed shadow roots or iframes.
Attribute engines are selecting based on the corresponding attribute value. For example: data-test-id=foo
is equivalent to css=[data-test-id=\"foo\"]
, and id:light=foo
is equivalent to css:light=[id=\"foo\"]
.
It is possible to get a reference to a Locator by using Get Element and Get Elements keywords. Keywords do not save reference to an element in the HTML document, instead it saves reference to a Playwright Locator. In nutshell Locator captures the logic of how to retrieve that element from the page. Each time an action is performed, the locator re-searches the elements in the page. This reference can be used as a first part of a selector by using a special selector syntax element=. like this:
\n\n${ref}= Get Element .some_class\n Click ${ref} >> .some_child # Locator searches an element from the page.\n Click ${ref} >> .other_child # Locator searches again an element from the page.\n\n
The .some_child and .other_child selectors in the example are relative to the element referenced by ${ref}. Please note that frame piercing is not possible with element reference.
\nKeywords that accept arguments assertion_operator
<AssertionOperator> and assertion_expected
can optionally assert that a specified condition holds. Keywords will return the value even when the assertion is performed by the keyword.
Assert will retry and fail only after a specified timeout. See Importing and retry_assertions_for
(default is 1 second) for configuring this timeout.
Currently supported assertion operators are:
\nOperator | \nAlternative Operators | \nDescription | \nValidate Equivalent | \n
---|---|---|---|
== | \nequal , equals , should be | \nChecks if returned value is equal to expected value. | \nvalue == expected | \n
!= | \ninequal , should not be | \nChecks if returned value is not equal to expected value. | \nvalue != expected | \n
> | \ngreater than | \nChecks if returned value is greater than expected value. | \nvalue > expected | \n
>= | \n\n | Checks if returned value is greater than or equal to expected value. | \nvalue >= expected | \n
< | \nless than | \nChecks if returned value is less than expected value. | \nvalue < expected | \n
<= | \n\n | Checks if returned value is less than or equal to expected value. | \nvalue <= expected | \n
*= | \ncontains | \nChecks if returned value contains expected value as substring. | \nexpected in value | \n
\n | not contains | \nChecks if returned value does not contain expected value as substring. | \nexpected in value | \n
^= | \nshould start with , starts | \nChecks if returned value starts with expected value. | \nre.search(f\"^{expected}\", value) | \n
$= | \nshould end with , ends | \nChecks if returned value ends with expected value. | \nre.search(f\"{expected}$\", value) | \n
matches | \n\n | Checks if given RegEx matches minimum once in returned value. | \nre.search(expected, value) | \n
validate | \n\n | Checks if given Python expression evaluates to True . | \n\n |
evaluate | \nthen | \nWhen using this operator, the keyword does return the evaluated Python expression. | \n\n |
Currently supported formatters for assertions are:
\nFormatter | \nDescription | \n
---|---|
normalize spaces | \nSubstitutes multiple spaces to single space from the value | \n
strip | \nRemoves spaces from the beginning and end of the value | \n
case insensitive | \nConverts value to lower case before comparing | \n
apply to expected | \nApplies rules also for the expected value | \n
Formatters are applied to the value before assertion is performed and keywords returns a value where rule is applied. Formatter is only applied to the value which keyword returns and not all rules are valid for all assertion operators. If apply to expected
formatter is defined, then formatters are then formatter are also applied to expected value.
By default, keywords will provide an error message if an assertion fails. Default error messages can be overwritten with a message
argument. The message
argument accepts {value}, {value_type}, {expected} and {expected_type} format options. The {value} is the value returned by the keyword and the {expected} is the expected value defined by the user, usually the value in the assertion_expected
argument. The {value_type} and {expected_type} are the type definitions from {value} and {expected} arguments. In similar fashion as Python type returns type definition. Assertions will retry until timeout
has expired if they do not pass.
The assertion assertion_expected
value is not converted by the library and is used as is. Therefore when assertion is made, the assertion_expected
argument value and value returned the keyword must have the same type. If types are not the same, assertion will fail. Example Get Text always returns a string and has to be compared with a string, even the returned value might look like a number.
Other Keywords have other specific types they return. Get Element Count always returns an integer. Get Bounding Box and Get Viewport Size can be filtered. They return a dictionary without a filter and a number when filtered. These Keywords do automatic conversion for the expected value if a number is returned.
\n* < less or greater > With Strings* Comparisons of strings with greater than
or less than
compares each character, starting from 0 regarding where it stands in the code page. Example: A < Z
, Z < a
, ac < dc It does never compare the length of elements. Neither lists nor strings. The comparison stops at the first character that is different. Examples: `'abcde' < 'abd'
, '100.000' < '2'
In Python 3 and therefore also in Browser it is not possible to compare numbers with strings with a greater or less operator. On keywords that return numbers, the given expected value is automatically converted to a number before comparison.
The getters Get Page State and Get Browser Catalog return a dictionary. Values of the dictionary can directly asserted. Pay attention of possible types because they are evaluated in Python. For example:
\n\nGet Page State validate 2020 >= value['year'] # Comparison of numbers\nGet Page State validate \"IMPORTANT MESSAGE!\" == value['message'] # Comparison of strings\n\n
Keywords that accept arguments assertion_operator
and assertion_expected
can optionally also use then
or evaluate
closure to modify the returned value with BuiltIn Evaluate. Actual value can be accessed with value
.
For example Get Title then 'TITLE: '+value
. See Builtin Evaluating expressions for more info on the syntax.
\n# Keyword Selector Key Assertion Operator Assertion Expected\nGet Title equal Page Title\nGet Title ^= Page\nGet Style //*[@id=\"div-element\"] width > 100\nGet Title matches \\\\w+\\\\s\\\\w+\nGet Title validate value == \"Login Page\"\nGet Title evaluate value if value == \"some value\" else \"something else\"\n\n
Browser library and Playwright have many mechanisms to help in waiting for elements. Playwright will auto-wait before performing actions on elements. Please see Auto-waiting on Playwright documentation for more information.
\nOn top of Playwright auto-waiting Browser assertions will wait and retry for specified time before failing any Assertions. Time is specified in Browser library initialization with retry_assertions_for
.
Browser library also includes explicit waiting keywords such as Wait for Elements State if more control for waiting is needed.
\nBrowser library integrated nodejs and python. The NodeJS side can be also executed as a standalone process. Browser libraries running on the same machine can talk to that instead of starting new node processes. This can speed execution when running tests parallel. To start node side run on the directory when the Browser package is PLAYWRIGHT_BROWSERS_PATH=0 node Browser/wrapper/index.js PORT
.
PORT
is the port you want to use for the node process. To execute tests then with pabot for example do ROBOT_FRAMEWORK_BROWSER_NODE_PORT=PORT pabot ..
.
Browser library is integrated with NodeJSand and Python. Browser library starts a node process, to communicate Playwright API in NodeJS side. It is possible to provide parameters for the started node process by defining ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS environment variable, before starting the test execution. Example: ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS=--inspect;robot path/to/tests
. There can be multiple arguments defined in the environment variable and arguments must be separated with comma.
Some keywords which manipulates library settings have a scope argument. With that scope argument one can set the \"live time\" of that setting. Available Scopes are: Global, Suite and Test/Task See Scope. Is a scope finished, this scoped setting, like timeout, will no longer be used.
\nLive Times:
\nA new set higher order scope will always remove the lower order scope which may be in charge. So the setting of a Suite scope from a test, will set that scope to the robot file suite where that test is and removes the Test scope that may have been in place.
\nBrowser library can be extended with JavaScript. The module must be in CommonJS format that Node.js uses. You can translate your ES6 module to Node.js CommonJS style with Babel. Many other languages can be also translated to modules that can be used from Node.js. For example TypeScript, PureScript and ClojureScript just to mention few.
\n\nasync function myGoToKeyword(url, args, page, logger, playwright) {\n logger(args.toString())\n playwright.coolNewFeature()\n return await page.goto(url);\n}\n\n
Functions can contain any number of arguments and arguments may have default values.
\nThere are some reserved arguments that are not accessible from Robot Framework side. They are injected to the function if they are in the arguments:
\npage
: the playwright Page object.
args
: the rest of values from Robot Framework keyword call *args
.
logger
: callback function that takes strings as arguments and writes them to robot log. Can be called multiple times.
playwright
: playwright module (* from 'playwright'). Useful for integrating with Playwright features that Browser library doesn't support with it's own keywords. API docs
also argument name self
can not be used.
\nasync function myGoToKeyword(pageUrl, page) {\n await page.goto(pageUrl);\n return await page.title();\n}\nexports.__esModule = true;\nexports.myGoToKeyword = myGoToKeyword;\n\n
\n* Settings *\nLibrary Browser jsextension=${CURDIR}/module.js\n\n* Test Cases *\nHello\n New Page\n ${title}= myGoToKeyword https://playwright.dev\n Should be equal ${title} Playwright\n\n
Also selector syntax can be extended with a custom selector using a js module
\n\nasync function registerMySelector(playwright) {\nplaywright.selectors.register(\"myselector\", () => ({\n // Returns the first element matching given selector in the root's subtree.\n query(root, selector) {\n return root.querySelector(a[data-title=\"${selector}\"]);\n },\n\n // Returns all elements matching given selector in the root's subtree.\n queryAll(root, selector) {\n return Array.from(root.querySelectorAll(a[data-title=\"${selector}\"]));\n }\n}));\nreturn 1;\n}\nexports.__esModule = true;\nexports.registerMySelector = registerMySelector;\n\n
Browser library 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 plugin API documentation for further details.
\nAutomatic headless detection is supported when opening a new browser.
", "version": "17.5.2", - "generated": "2024-04-03 09:43:43", + "generated": "2024-04-03 09:44:59", "type": "LIBRARY", "scope": "GLOBAL", "docFormat": "HTML", @@ -24053,7 +24053,7 @@ "name": "RPA.Browser.Selenium", "doc": "SeleniumLibrary is a web testing library for Robot Framework.
\nThis document explains how to use keywords provided by SeleniumLibrary. For information about installation, support, and more, please visit the project pages. For more information about Robot Framework, see http://robotframework.org.
\nSeleniumLibrary 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 Browser drivers chapter for more details about WebDriver binary installation.
\nAll 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.
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.
\nBy 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:
\nClick Element | \nexample | \n# Match based on id or name . | \n
Click Link | \nexample | \n# Match also based on link text and href . | \n
Click Button | \nexample | \n# Match based on id , name or value . | \n
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:
\nClick Element | \nname:foo | \n# Find element with name foo . | \n
Click Element | \ndefault:name:foo | \n# Use default strategy with value name:foo . | \n
Click Element | \n//foo | \n# Find element using XPath //foo . | \n
Click Element | \ndefault: //foo | \n# Use default strategy with value //foo . | \n
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 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.
\nStrategy | \nMatch based on | \nExample | \n
---|---|---|
id | \nElement id . | \nid:example | \n
name | \nname attribute. | \nname:example | \n
identifier | \nEither id or name . | \nidentifier:example | \n
class | \nElement class . | \nclass:example | \n
tag | \nTag name. | \ntag:div | \n
xpath | \nXPath expression. | \nxpath://div[@id=\"example\"] | \n
css | \nCSS selector. | \ncss:div#example | \n
dom | \nDOM expression. | \ndom:document.images[5] | \n
link | \nExact text a link has. | \nlink:The example | \n
partial link | \nPartial link text. | \npartial link:he ex | \n
sizzle | \nSizzle selector deprecated. | \nsizzle:div.example | \n
data | \nElement data-* attribute | \ndata:id:my_id | \n
jquery | \njQuery expression. | \njquery:div.example | \n
default | \nKeyword specific default behavior. | \ndefault:example | \n
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:
\nClick Element | \nid:foo | \n# Element with id 'foo'. | \n
Click Element | \ncss:div#foo h1 | \n# h1 element under div with id 'foo'. | \n
Click Element | \nxpath: //div[@id=\"foo\"]//h1 | \n# Same as the above using XPath, not CSS. | \n
Click Element | \nxpath: //*[contains(text(), \"example\")] | \n# Element containing text 'example'. | \n
NOTE:
\nstrategy:value
syntax is only supported by SeleniumLibrary 3.0 and newer.sizzle
strategy or its alias jquery
requires that the system under test contains the jQuery library.xpath
, css
and sizzle/jquery
strategies.data
strategy is conveniance locator that will construct xpath from the parameters. If you have element like <div data-automation=\"automation-id-2\">, you locate the element via data:automation:automation-id-2
. This feature was added in SeleniumLibrary 5.2.0If the locator starts with //
or multiple opening parenthesis in front of the //
, the locator is considered to be an XPath expression. In other words, using //div
is equivalent to using explicit xpath://div
and ((//div))
is equivalent to using explicit xpath:((//div))
Examples:
\nClick Element | \n//div[@id=\"foo\"]//h1 | \n
Click Element | \n(//div)[2] | \n
The support for the (//
prefix is new in SeleniumLibrary 3.0. Supporting multiple opening parenthesis is new in SeleniumLibrary 5.0.
It is possible chain multiple locators together as single locator. Each chained locator must start with locator strategy. Chained locators must be separated with single space, two greater than characters and followed with space. It is also possible mix different locator strategies, example css or xpath. Also a list can also be used to specify multiple locators. This is useful, is some part of locator would match as the locator separator but it should not. Or if there is need to existing WebElement as locator.
\nAlthough all locators support chaining, some locator strategies do not abey the chaining. This is because some locator strategies use JavaScript to find elements and JavaScript is executed for the whole browser context and not for the element found be the previous locator. Chaining is supported by locator strategies which are based on Selenium API, like xpath or css, but example chaining is not supported by sizzle or `jquery
\nExamples:
\nClick Element | \ncss:.bar >> xpath://a | \n# To find a link which is present after an element with class \"bar\" | \n
List examples:
\n${locator_list} = | \nCreate List | \ncss:div#div_id | \nxpath://*[text(), \" >> \"] | \n
Page Should Contain Element | \n${locator_list} | \n\n | \n |
${element} = | \nGet WebElement | \nxpath://*[text(), \" >> \"] | \n\n |
${locator_list} = | \nCreate List | \ncss:div#div_id | \n${element} | \n
Page Should Contain Element | \n${locator_list} | \n\n | \n |
Chaining locators in new in SeleniumLibrary 5.0
\nIn 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.
\n${elem} = | \nGet WebElement | \nid:example | \n
Click Element | \n${elem} | \n\n |
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:
\nCustom Locator Strategy | \n[Arguments] | \n${browser} | \n${locator} | \n${tag} | \n${constraints} | \n
\n | ${element}= | \nExecute Javascript | \nreturn window.document.getElementById('${locator}'); | \n\n | \n |
\n | [Return] | \n${element} | \n\n | \n | \n |
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 | \ncustom | \nCustom Locator Strategy | \n
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:
\nClick Element | \ncustom:example | \n
See the Add Location Strategy keyword for more details.
\nThere is different conceptual meaning when SeleniumLibrary talks about windows or browsers. This chapter explains those differences.
\nWhen Open Browser or Create WebDriver keyword is called, it will create a new Selenium WebDriver instance by using the 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.
\nWindows 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:
\n\nExecute Javascript window.open() # Opens a new window with location about:blank\n\n
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.
\nStructure:
\n\nBrowserA\n Window 1 (location=https://robotframework.org/)\n Window 2 (location=https://robocon.io/)\n Window 3 (location=https://github.com/robotframework/)\n\nBrowserB\n Window 1 (location=https://github.com/)\n\n
Example:
\nOpen Browser | \nhttps://robotframework.org | \n${BROWSER} | \nalias=BrowserA | \n# BrowserA with first window is opened. | \n
Execute Javascript | \nwindow.open() | \n\n | \n | # In BrowserA second window is opened. | \n
Switch Window | \nlocator=NEW | \n\n | \n | # Switched to second window in BrowserA | \n
Go To | \nhttps://robocon.io | \n\n | \n | # Second window navigates to robocon site. | \n
Execute Javascript | \nwindow.open() | \n\n | \n | # In BrowserA third window is opened. | \n
${handle} | \nSwitch Window | \nlocator=NEW | \n\n | # Switched to third window in BrowserA | \n
Go To | \nhttps://github.com/robotframework/ | \n\n | \n | # Third windows goes to robot framework github site. | \n
Open Browser | \nhttps://github.com | \n${BROWSER} | \nalias=BrowserB | \n# BrowserB with first windows is opened. | \n
${location} | \nGet Location | \n\n | \n | # ${location} is: https://www.github.com | \n
Switch Window | \n${handle} | \nbrowser=BrowserA | \n\n | # BrowserA second windows is selected. | \n
${location} | \nGet Location | \n\n | \n | # ${location} = https://robocon.io/ | \n
@{locations 1} | \nGet Locations | \n\n | \n | # By default, lists locations under the currectly active browser (BrowserA). | \n
@{locations 2} | \nGet Locations | \nbrowser=ALL | \n\n | # By using browser=ALL argument keyword list all locations from all browsers. | \n
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/.
\nThis 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.
\nSeleniumLibrary 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. If no default timeout is set globally, the default is 5 seconds. If None is specified for the timeout argument in the keywords, the default is used. See time format below for supported timeout syntax.
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 Selenium documentation for more information about this functionality.
See time format below for supported syntax.
\nPage load timeout is the amount of time to wait for page load to complete until a timeout exception is raised.
\nThe default page load timeout can be set globally when importing the library with the page_load_timeout
argument or by using the Set Selenium Page Load Timeout keyword.
See time format below for supported timeout syntax.
\nSupport for page load is new in SeleniumLibrary 6.1
\nSelenium 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.
\nSee time format below for supported syntax.
\nAll 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 Robot Framework User Guide.
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
.
Starting from 5.0 SeleniumLibrary relies on Robot Framework to perform the boolean conversion based on keyword arguments type hint. More details in Robot Framework user guide
\nPlease note SeleniumLibrary 3 and 4 did have own custom methods to covert arguments to boolean values.
\nThe SeleniumLibrary offers support for EventFiringWebDriver. See the Selenium and SeleniumLibrary EventFiringWebDriver support documentation for further details.
\nEventFiringWebDriver is new in SeleniumLibrary 4.0
\nSeleniumLibrary is not thread-safe. This is mainly due because the underlying 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.
\nSeleniumLibrary 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 plugin API documentation for further details.
\nPlugin API is new SeleniumLibrary 4.0
\nBy default, the browser instances created during a task execution are closed at the end of the task. This can be prevented with the auto_close
parameter when importing the library.
The value of the parameter needs to be set to False
or any object evaluated as false (see Boolean arguments).
Documentation for library RPA.Browser.common
.
Library for handling different operations for date and time\nhandling especially in business days and holiday contexts.
\nUtilizing pendulum and\nholidays packages.
\nLibrary is by default using days from Monday to Friday as business\ndays, but that can be changed by giving list of weekdays to\nSet Business Days keyword. A weekday is given as a integer, the\n0 for Sunday and 6 for Saturday.
\nCommon country holidays are respected when getting next and previous\nbusiness days, but custom holidays can be added into consideration\nusing keyword Add Custom Holidays keyword.
\nSome dates containing for example month names are in English (en), but\nthe locale of the library can be changed with keyword Set Locale or\nfor specific keyword if that has a locale parameter.
\nAWS is a library for operating with Amazon AWS services S3, SQS,\nTextract and Comprehend.
\nServices are initialized with keywords like Init S3 Client for S3.
\nAWS authentication
\nAuthentication for AWS is set with key id and access key which can be given to the library\nin three different ways.
\nNote. Starting from rpaframework-aws 1.0.3 region can be given as environment\nvariable AWS_REGION or include as Robocorp Vault secret with the same key name.
\nRedshift Data authentication: Depending on the authorization method, use\none of the following combinations of request parameters, which can only\nbe passed via method 2:
\n\n\n\n
\n- Secrets Manager - when connecting to a cluster, specify the Amazon\nResource Name (ARN) of the secret, the database name, and the\ncluster identifier that matches the cluster in the secret. When\nconnecting to a serverless endpoint, specify the Amazon Resource\nName (ARN) of the secret and the database name.
\n- Temporary credentials - when connecting to a cluster, specify the\ncluster identifier, the database name, and the database user name.\nAlso, permission to call the redshift:GetClusterCredentials\noperation is required. When connecting to a serverless endpoint,\nspecify the database name.
\n
Role Assumption: With the use of the STS service client, you are able\nto assume another role, which will return temporary credentials. The\ntemporary credentials will include an access key and session token, see\nkeyword documentation for Assume Role for details of how the\ncredentials are returned. You can use these temporary credentials\nas part of method 2, but you must also include the session token.
\nMethod 1. credentials using environment variable
\n\n*** Settings ***\nLibrary RPA.Cloud.AWS\n\n*** Tasks ***\nInit AWS services\n # NO parameters for client, expecting to get credentials\n # with AWS_KEY, AWS_KEY_ID and AWS_REGION environment variables\n Init S3 Client\n\n
Method 2. credentials with keyword parameter
\n\n*** Settings ***\nLibrary RPA.Cloud.AWS region=us-east-1\n\n*** Tasks ***\nInit AWS services\n Init S3 Client aws_key_id=${AWS_KEY_ID} aws_key=${AWS_KEY}\n\n
Method 3. setting Robocorp Vault in the library init
\n\n*** Settings ***\nLibrary RPA.Cloud.AWS robocorp_vault_name=aws\n\n*** Tasks ***\nInit AWS services\n Init S3 Client use_robocorp_vault=${TRUE}\n\n
Method 3. setting Robocorp Vault with keyword
\n\n*** Settings ***\nLibrary RPA.Cloud.AWS\n\n*** Tasks ***\nInit AWS services\n Set Robocorp Vault vault_name=aws\n Init Textract Client use_robocorp_vault=${TRUE}\n\n
Requirements
\nThe default installation depends on boto3 library. Due to the size of the\ndependency, this library is available separate package rpaframework-aws but can\nalso be installed as an optional package for rpaframework.
\nRecommended installation is rpaframework-aws plus rpaframework package.\nRemember to check latest versions from rpaframework Github repository.
\n\nchannels:\n - conda-forge\ndependencies:\n - python=3.7.5\n - pip=20.1\n - pip:\n - rpaframework==13.0.2\n - rpaframework-aws==1.0.3\n\n
Example
\n\n*** Settings ***\nLibrary RPA.Cloud.AWS region=us-east-1\n\n*** Variables ***\n${BUCKET_NAME} testbucket12213123123\n\n*** Tasks ***\nUpload a file into S3 bucket\n [Setup] Init S3 Client\n Upload File ${BUCKET_NAME} ${/}path${/}to${/}file.pdf\n @{files} List Files ${BUCKET_NAME}\n FOR ${file} IN @{files}\n Log ${file}\n END\n\n
Azure is a library for operating with Microsoft Azure API endpoints.
\nList of supported service names:
\nAzure authentication
\nAuthentication for Azure is set with service subscription key which can be given to the library\nin two different ways.
\nMethod 1. subscription key using environment variable
\n\n*** Settings ***\nLibrary RPA.Cloud.Azure\n\n*** Tasks ***\nInit Azure services\n # NO parameters for client, expecting to get subscription key\n # with AZURE_TEXTANALYTICS_KEY or AZURE_SUBSCRIPTION_KEY environment variable\n Init Text Analytics Service\n\n
Method 2. setting Robocorp Vault in the library init
\n\n*** Settings ***\nLibrary RPA.Cloud.Azure robocorp_vault_name=azure\n\n*** Tasks ***\nInit Azure services\n Init Text Analytics Service use_robocorp_vault=${TRUE}\n\n
Method 2. setting Robocorp Vault with keyword
\n\n*** Settings ***\nLibrary RPA.Cloud.Azure\n\n*** Tasks ***\nInit Azure services\n Set Robocorp Vault vault_name=googlecloud\n Init Text Analytics Service use_robocorp_vault=${TRUE}\n\n
References
\nList of supported language locales - Azure locale list
\nList of supported region identifiers - Azure region list
\nExamples
\nRobot Framework
\nThis is a section which describes how to use the library in your\nRobot Framework tasks.
\n\n*** Settings ***\nLibrary RPA.Cloud.Azure\n\n*** Variables ***\n${IMAGE_URL} IMAGE_URL\n${FEATURES} Faces,ImageType\n\n*** Tasks ***\nVisioning image information\n Init Computer Vision Service\n &{result} Vision Analyze image_url=${IMAGE_URL} visual_features=${FEATURES}\n @{faces} Set Variable ${result}[faces]\n FOR ${face} IN @{faces}\n Log Age: ${face}[age], Gender: ${face}[gender], Rectangle: ${face}[faceRectangle]\n END\n\n
Python
\nThis is a section which describes how to use the library in your\nown Python modules.
\n\nlibrary = Azure()\nlibrary.init_text_analytics_service()\nlibrary.init_face_service()\nlibrary.init_computer_vision_service()\nlibrary.init_speech_service("westeurope")\n\nresponse = library.sentiment_analyze(\n text="The rooms were wonderful and the staff was helpful."\n)\nresponse = library.detect_face(\n image_file=PATH_TO_FILE,\n face_attributes="age,gender,smile,hair,facialHair,emotion",\n)\nfor item in response:\n gender = item["faceAttributes"]["gender"]\n age = item["faceAttributes"]["age"]\n print(f"Detected a face, gender:{gender}, age: {age}")\n\nresponse = library.vision_analyze(\n image_url=URL_TO_IMAGE,\n visual_features="Faces,ImageType",\n)\nmeta = response['metadata']\nprint(\n f"Image dimensions meta['width']}x{meta['height']} pixels"\n)\n\nfor face in response["faces"]:\n left = face["faceRectangle"]["left"]\n top = face["faceRectangle"]["top"]\n width = face["faceRectangle"]["width"]\n height = face["faceRectangle"]["height"]\n print(f"Detected a face, gender:{face['gender']}, age: {face['age']}")\n print(f" Face rectangle: (left={left}, top={top})")\n print(f" Face rectangle: (width={width}, height={height})")\n\nlibrary.text_to_speech(\n text="Developer tools for open-source RPA leveraging the Robot Framework ecosystem",\n neural_voice_style="cheerful",\n target_file='output.mp3'\n)\n\n
Google is a library for operating with Google API endpoints.
\nInstallation
\nUsage requires the following steps:
\nCheck the latest package version from PyPI.
\nGoogle authentication
\nAuthentication for Google is set with service account JSON file which can be given to the library\nin three different ways or with OAuth2 token, which is used for OAuth authentication.
\nSee library authentication examples for more information.
\nBasic usage examples
\nPython
\n\nfrom RPA.Cloud.Google import Google\n\nlibrary = Google()\nservice_account = '/path/to/service_account.json'\n\nlibrary.init_vision(service_account)\nlibrary.init_text_to_speech(service_account)\n\nresponse = library.detect_text('imagefile.png', 'result.json')\nlibrary.synthesize_speech('I want this said aloud', target_file='said.mp3')\n\n
Robot Framework
\n\n*** Settings ***\nLibrary RPA.Cloud.Google\n\n*** Variables ***\n${SERVICE_ACCOUNT} ${/}path${/}to${/}service_account.json\n${BUCKET_NAME} testbucket12213123123\n\n*** Tasks ***\nUpload a file into a new storage bucket\n [Setup] Init Storage ${SERVICE_ACCOUNT}\n Create Storage Bucket ${BUCKET_NAME}\n Upload Storage File ${BUCKET_NAME}\n ... ${/}path${/}to${/}file.pdf\n ... myfile.pdf\n @{files} List Storage Files ${BUCKET_NAME}\n FOR ${file} IN @{files}\n Log ${file}\n END\n\n
Library for common encryption and hashing operations.
\nLibrary uses by default the\nFernet format\nfor encryption. More specifically, it uses AES in CBC mode with\na 128-bit key for encryption and HMAC with SHA256 for authentication.
\nAlternative encryption format for the library is\nAES256.
\nTo use the encryption features, generate a key with the command line\nutility rpa-crypto or with the keyword Generate Key. Store\nthe key in a secure place, such as Robocorp Vault, and load it within\nthe execution before calling encryption/decryption keywords.
\nExample usage with Robocorp Vault
\nCreate an encryption key with the CLI utility:
\n\n> rpa-crypto key\nrGx1edA07yz7uD08ChiPSunn8vaauRxw0pAbsal9zjM=\n
\nStore the key in Robocorp Vault, in this case with the name EncryptionKey.
\nLoad the key from the vault before encryption operations:
\n\nUse encryption key from vault EncryptionKey\n${encrypted}= Encrypt file orders.xlsx\nAdd work item file ${encrypted} name=Orders\n\n
In another task, this same key can be used to decrypt the file:
\n\nUse encryption key from vault EncryptionKey\n${encrypted}= Get work item file Orders\n${orders}= Decrypt file ${encrypted}\n\n
Database is a library for handling different database operations.
\nAll database operations are supported. Keywords Query and Get Rows\nreturn values by default in RPA.Table format.
\nLibrary is compatible with any Database API Specification 2.0 module.
\nWorkaround for inserting large JSON data for Call Stored Procedure
\nWorkaround is to use instead Query keyword. At the moment there is\nno known fix for the Call Stored Procedure keyword as it fails if\nJSON string is more than 8000 characters long.
\nRobot Framework
\n\n${data}= Load JSON from file random_data.json\n${json}= Convert JSON to String ${data}\n# Single quotes around ${json} string are necessary\nQuery exec InsertJsonDataToSampleTable '${json}'\n\n
References:
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Database\n\n*** Tasks ***\nGet Orders From Database\n Connect To Database pymysql tester user password 127.0.0.1\n @{orders} Query Select * FROM incoming_orders\n FOR ${order} IN @{orders}\n Handle Order ${order}\n END\n\n
Python
\n\nfrom RPA.Database import Database\nfrom RPA.Robocorp.Vault import FileSecrets\n\nfilesecrets = FileSecrets("secrets.json")\nsecrets = filesecrets.get_secret("databasesecrets")\n\ndb = Database()\ndb.connect_to_database('pymysql',\n secrets["DATABASE"],\n secrets["USERNAME"],\n secrets["PASSWORD"],\n '127.0.0.1'\n )\norders = db.query("SELECT * FROM incoming_orders")\nfor order in orders:\n print(order)\n\n
Desktop is a cross-platform library for navigating and interacting with\ndesktop environments. It can be used to automate applications through\nthe same interfaces that are available to human users.
\nThe library includes the following features:
\nWarning
\nWindows element selectors are not currently supported, and require the use of RPA.Desktop.Windows
\nInstallation
\nThe basic features such as mouse and keyboard input and application\ncontrol work with a default rpaframework install.
\nAdvanced computer-vision features such as image template matching and\nOCR require an additional library called rpaframework-recognition.
\nThe dependency should be added separately by specifing it in your conda.yaml\nas rpaframework-recognition==5.0.1 for example. If installing recognition\nthrough pip instead of conda, the OCR feature also requires tesseract.
\nLocating elements
\nTo automate actions on the desktop, a robot needs to interact with various\ngraphical elements such as buttons or input fields. The locations of these\nelements can be found using a feature called locators.
\nA locator describes the properties or features of an element. This information\ncan be later used to locate similar elements even when window positions or\nstates change.
\nThe currently supported locator types are:
\nName | \nArguments | \nDescription | \n
---|---|---|
alias | \nname (str) | \nA custom named locator from the locator database, the default. | \n
image | \npath (str) | \nImage of an element that is matched to current screen content. | \n
point | \nx (int), y (int) | \nPixel coordinates as absolute position. | \n
offset | \nx (int), y (int) | \nPixel coordinates relative to current mouse position. | \n
size | \nwidth (int), height (int) | \nRegion of fixed size, around point or screen top-left | \n
region | \nleft (int), top (int), right (int), bottom (int) | \nBounding coordinates for a rectangular region. | \n
ocr | \ntext (str), confidence (float, optional) | \nText to find from the current screen. | \n
A locator is defined by its type and arguments, divided by a colon.\nSome example usages are shown below. Note that the prefix for alias can\nbe omitted as its the default type.
\n\nClick point:50,100\nClick region:20,20,100,30\n\nMove mouse image:%{ROBOT_ROOT}/logo.png\nMove mouse offset:200,0\nClick\n\nClick alias:SpareBin.Login\nClick SpareBin.Login\n\nClick ocr:"Create New Account"\n\n
You can also pass internal region objects as locators:
\n\n${region}= Find Element ocr:"Customer name"\nClick ${region}\n\n
Locator chaining
\nOften it is not enough to have one locator, but instead an element\nis defined through a relationship of various locators. For this use\ncase the library supports a special syntax, which we will call\nlocator chaining.
\nAn example of chaining:
\n\n# Read text from area on the right side of logo\nRead text image:logo.png + offset:600,0 + size:400,200\n\n
The supported operators are:
\nOperator | \nDescription | \n
---|---|
then, + | \nBase locator relative to the previous one | \n
and, &&, & | \nBoth locators should be found | \n
or, ||, | | \nEither of the locators should be found | \n
not, ! | \nThe locator should not be found | \n
Further examples:
\n\n# Click below either label\nClick (image:name.png or image:email.png) then offset:0,300\n\n# Wait until dialog disappears\nWait for element not image:cookie.png\n\n
Named locators
\nThe library supports storing locators in a database, which contains\nall of the required fields and various bits of metadata. This enables\nhaving one source of truth, which can be updated if a website's or applications's\nUI changes. Robot Framework scripts can then only contain a reference\nto a stored locator by name.
\nThe main way to create named locators is with VSCode.
\nRead more on identifying elements and crafting locators:
\nKeyboard and mouse
\nKeyboard keywords can emulate typing text, but also pressing various function keys.\nThe name of a key is case-insensitive and spaces will be converted to underscores,\ni.e. the key Page Down and page_down are equivalent.
\nThe following function keys are supported:
\nKey | \nDescription | \n
---|---|
shift | \nA generic Shift key. This is a modifier. | \n
shift_l | \nThe left Shift key. This is a modifier. | \n
shift_r | \nThe right Shift key. This is a modifier. | \n
ctrl | \nA generic Ctrl key. This is a modifier. | \n
ctrl_l | \nhe left Ctrl key. This is a modifier. | \n
ctrl_r | \nThe right Ctrl key. This is a modifier. | \n
alt | \nA generic Alt key. This is a modifier. | \n
alt_l | \nThe left Alt key. This is a modifier. | \n
alt_r | \nThe right Alt key. This is a modifier. | \n
alt_gr | \nThe AltGr key. This is a modifier. | \n
cmd | \nA generic command button (Windows / Command / Super key). This may be a modifier. | \n
cmd_l | \nThe left command button (Windows / Command / Super key). This may be a modifier. | \n
cmd_r | \nThe right command button (Windows / Command / Super key). This may be a modifier. | \n
up | \nAn up arrow key. | \n
down | \nA down arrow key. | \n
left | \nA left arrow key. | \n
right | \nA right arrow key. | \n
enter | \nThe Enter or Return key. | \n
space | \nThe Space key. | \n
tab | \nThe Tab key. | \n
backspace | \nThe Backspace key. | \n
delete | \nThe Delete key. | \n
esc | \nThe Esc key. | \n
home | \nThe Home key. | \n
end | \nThe End key. | \n
page_down | \nThe Page Down key. | \n
page_up | \nThe Page Up key. | \n
caps_lock | \nThe Caps Lock key. | \n
f1 to f20 | \nThe function keys. | \n
insert | \nThe Insert key. This may be undefined for some platforms. | \n
menu | \nThe Menu key. This may be undefined for some platforms. | \n
num_lock | \nThe Num Lock key. This may be undefined for some platforms. | \n
pause | \nThe Pause / Break key. This may be undefined for some platforms. | \n
print_screen | \nThe Print Screen key. This may be undefined for some platforms. | \n
scroll_lock | \nThe Scroll Lock key. This may be undefined for some platforms. | \n
When controlling the mouse, there are different types of actions that can be\ndone. Same formatting rules as function keys apply. They are as follows:
\nAction | \nDescription | \n
---|---|
click | \nClick with left mouse button | \n
left_click | \nClick with left mouse button | \n
double_click | \nDouble click with left mouse button | \n
triple_click | \nTriple click with left mouse button | \n
right_click | \nClick with right mouse button | \n
The supported mouse button types are left, right, and middle.
\nExamples
\nBoth Robot Framework and Python examples follow.
\nThe library must be imported first.
\n\n*** Settings ***\nLibrary RPA.Desktop\n\n
\nfrom RPA.Desktop import Desktop\ndesktop = Desktop()\n\n
The library can open applications and interact with them through\nkeyboard and mouse events.
\n\n*** Keywords ***\nWrite entry in accounting\n [Arguments] ${entry}\n Open application erp_client.exe\n Click image:%{ROBOT_ROOT}/images/create.png\n Type text ${entry}\n Press keys ctrl s\n Press keys enter\n\n
\ndef write_entry_in_accounting(entry):\n desktop.open_application("erp_client.exe")\n desktop.click(f"image:{ROBOT_ROOT}/images/create.png")\n desktop.type_text(entry)\n desktop.press_keys("ctrl", "s")\n desktop.press_keys("enter")\n\n
Targeting can be currently done using coordinates (absolute or relative),\nbut using template matching is preferred.
\n\n*** Keywords ***\nWrite to field\n [Arguments] ${text}\n Move mouse image:input_label.png\n Move mouse offset:200,0\n Click\n Type text ${text}\n Press keys enter\n\n
\ndef write_to_field(text):\n desktop.move_mouse("image:input_label.png")\n desktop.move_mouse("offset:200,0")\n desktop.click()\n desktop.type_text(text)\n desktop.press_keys("enter")\n\n
Elements can be found by text too.
\n\n*** Keywords ***\nClick New\n Click ocr:New\n\n
\ndef click_new():\n desktop.click('ocr:"New"')\n\n
It is recommended to wait for the elements to be visible before\ntrying any interaction. You can also pass region objects as locators.
\n\n*** Keywords ***\nClick New\n ${region}= Wait For element ocr:New\n Click ${region}\n\n
\ndef click_new():\n region = desktop.wait_for_element("ocr:New")\n desktop.click(region)\n\n
Another way to find elements by offsetting from an anchor:
\n\n*** Keywords ***\nType Notes\n [Arguments] ${text}\n Click With Offset ocr:Notes 500 0\n Type Text ${text}\n\n
\ndef type_notes(text):\n desktop.click_with_offset("ocr:Notes", 500, 0)\n desktop.type_text(text)\n\n
DEPRECATED!! Use library RPA.Desktop's clipboard functionality instead.
\nClipboard is a library for managing clipboard - copy text to,\npaste text from, and clear clipboard contents.
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Desktop.Clipboard\n\n*** Tasks ***\nClipping\n Copy To Clipboard Text from Robot to clipboard\n ${var}= Paste From Clipboard\n Clear Clipboard\n\n
Python
\n\nfrom RPA.Desktop.Clipboard import Clipboard\n\nclip = Clipboard()\nclip.copy_to_clipboard('Text from Python to clipboard')\ntext = clip.paste_from_clipboard()\nprint(f"clipboard had text: '{text}'")\nclip.clear_clipboard()\n\n
OperatingSystem is a cross-platform library for managing\ncomputer properties and actions.
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Desktop.OperatingSystem\n\n*** Tasks ***\nGet computer information\n ${boot_time}= Get Boot Time as_datetime=${TRUE}\n ${machine}= Get Machine Name\n ${username}= Get Username\n &{memory}= Get Memory Stats\n Log Many ${memory}\n\n
Python
\n\nfrom RPA.Desktop.OperatingSystem import OperatingSystem\n\ndef get_computer_information():\n ops = OperatingSystem()\n print(f"Boot time : { ops.get_boot_time(as_datetime=True) }"\n f"Machine name : { ops.get_machine_name() }"\n f"Username : { ops.get_username() }"\n f"Memory : { ops.get_memory_stats() }")\n\nif __name__ == "__main__":\n get_computer_information()\n\n
Windows is a library for managing the Windows operating system.
\nDEPRECATION WARNING! USE RPA.Windows library instead.
\nFor Windows desktop automation Robocorp recommends the RPA.Windows library.
\nNo further updates will be released for this library and new functionality will continue\nto be developed in RPA.Windows library.
\nRunning Windows applications
\nWindows applications can be started in several ways. The library supports\nthe following keywords:
\nLocators
\nLocator is used to identify the element for interaction - usually for a mouse click.
\nLocators can investigated for application once it has been opened by calling\nthe keyword get_windows_elements which can store locator information into JSON file\nand screenshot of the element into an image file.
\nIdentifying locator
\nThe element needs to be identified by a unique method, for example, "Three" for button 3\nin the Calculator application. It can be given either as Three or name:Three.
\nPossible search criterias:
\nThe current method of inspecting elements on Windows is inspect.exe which is part\nof Windows SDK.
\nKeyboard
\nThe keyword send_keys can be used to send keys to the active window. The keyword\ntype_keys sends keys to the active window element.
\nSpecial key codes are documented on pywinauto\ndocumentation page.
\nFAQ
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Desktop.Windows\nSuite Teardown Close all applications\n\n*** Tasks ***\nOpen Calculator using run dialog\n ${result}= Open using run dialog calc.exe Calculator\n ${result}= Get Window Elements\n Send Keys 5*2=\n ${result}= Get element partial name:Display is\n Log Many ${result}\n ${result}= Get element rich text id:CalculatorResults\n Should Be Equal As Strings ${result} Display is 10\n ${result}= Get element rectangle partial name:Display is\n ${result}= Is Element Visible CalculatorResults\n ${result}= Is Element Enabled partial name:Display is\n\n
Python
\n\nfrom RPA.Desktop.Windows import Windows\n\nwin = Windows()\n\ndef open_calculator():\n win.open_from_search("calc.exe", "Calculator")\n elements = win.get_window_elements()\n\ndef make_calculations(expression):\n win.send_keys(expression)\n result = win.get_element_rich_text('id:CalculatorResults')\n return int(result.strip('Display is '))\n\nif __name__ == "__main__":\n open_calculator()\n exp = '5*2='\n result = make_calculations(exp)\n print(f"Calculation result of '{exp}' is '{result}'")\n win.close_all_applications()\n\n
Wrapper library offering generic keywords for initializing, scanning and\nretrieving results as fields from documents (PDF, PNG etc.).
\nLibrary requires at the minimum rpaframework version 19.0.0.
\nThis is a helper facade for the following libraries:
\nWhere the following steps are required:
\nSo no matter the engine you're using, the very same keywords can be used, as only\nthe passed parameters will differ (please check the docs on each library for\nparticularities). Once initialized, you can jump between the engines with\nSwitch Engine. Before scanning documents, you must configure the service first,\nwith a model to scan the files with and an API key for authorizing the access.
\nSee Portal example: https://robocorp.com/portal/robot/robocorp/example-document-ai
\nExample: Robot Framework
\n\n*** Settings ***\nLibrary RPA.DocumentAI\n\n*** Tasks ***\nScan Documents\n Init Engine base64ai vault=document_ai:base64ai\n Init Engine nanonets vault=document_ai:nanonets\n\n Switch Engine base64ai\n Predict invoice.png\n ${data} = Get Result\n Log List ${data}\n\n Switch Engine nanonets\n Predict invoice.png model=858e4b37-6679-4552-9481-d5497dfc0b4a\n ${data} = Get Result\n Log List ${data}\n\n
Example: Python
\n\nfrom RPA.DocumentAI import DocumentAI, EngineName\n\nlib_docai = DocumentAI()\nlib_docai.init_engine(\n EngineName.GOOGLE, vault="document_ai:serviceaccount", region="eu"\n)\nlib_docai.predict(\n "invoice.pdf", model="df1d166771005ff4",\n project_id="complete-agency-347912", region="eu"\n)\nprint(lib_docai.get_result())\n\n
Library to support Base64.ai service for intelligent\ndocument processing (IDP).
\nLibrary requires at the minimum rpaframework version 19.0.0.
\nService supports identifying fields in the documents, which can be given to the\nservice in multiple different file formats and via URL.
\nRobot Framework example usage
\n\n*** Settings ***\nLibrary RPA.DocumentAI.Base64AI\nLibrary RPA.Robocorp.Vault\n\n*** Tasks ***\nIdentify document\n ${secrets}= Get Secret base64ai-auth\n Set Authorization ${secrets}[email-address] ${secrets}[apikey]\n ${results}= Scan Document File\n ... ${CURDIR}${/}invoice.pdf\n ... model_types=finance/check/usa,finance/invoice/usa\n # Scan response contains list of detected models in the document\n FOR ${result} IN @{results}\n Log To Console Model: ${result}[model]\n Log To Console Field keys: ${{','.join($result['fields'].keys())}}\n Log To Console Fields: ${result}[fields]\n Log To Console Text (OCR): ${result}[ocr]\n END\n\n
Python example usage
\n\nfrom RPA.DocumentAI.Base64AI import Base64AI\nfrom RPA.Robocorp.Vault import Vault\n\nsecrets = Vault().get_secret("base64ai-auth")\nbaselib = Base64AI()\nbaselib.set_authorization(secrets["email-address"], secrets["apikey"])\nresult = baselib.scan_document_file(\n "invoice.pdf",\n model_types="finance/invoice,finance/check/usa",\n)\nfor r in result:\n print(f"Model: {r['model']}")\n for key, props in r["fields"].items():\n print(f"FIELD {key}: {props['value']}")\n print(f"Text (OCR): {r['ocr']}")\n\n
Portal example: https://github.com/robocorp/example-idp-base64
\nWrapper library offering generic keywords for initializing, scanning and\nretrieving results as fields from documents (PDF, PNG etc.).
\nLibrary requires at the minimum rpaframework version 19.0.0.
\nThis is a helper facade for the following libraries:
\nWhere the following steps are required:
\nSo no matter the engine you're using, the very same keywords can be used, as only\nthe passed parameters will differ (please check the docs on each library for\nparticularities). Once initialized, you can jump between the engines with\nSwitch Engine. Before scanning documents, you must configure the service first,\nwith a model to scan the files with and an API key for authorizing the access.
\nSee Portal example: https://robocorp.com/portal/robot/robocorp/example-document-ai
\nExample: Robot Framework
\n\n*** Settings ***\nLibrary RPA.DocumentAI\n\n*** Tasks ***\nScan Documents\n Init Engine base64ai vault=document_ai:base64ai\n Init Engine nanonets vault=document_ai:nanonets\n\n Switch Engine base64ai\n Predict invoice.png\n ${data} = Get Result\n Log List ${data}\n\n Switch Engine nanonets\n Predict invoice.png model=858e4b37-6679-4552-9481-d5497dfc0b4a\n ${data} = Get Result\n Log List ${data}\n\n
Example: Python
\n\nfrom RPA.DocumentAI import DocumentAI, EngineName\n\nlib_docai = DocumentAI()\nlib_docai.init_engine(\n EngineName.GOOGLE, vault="document_ai:serviceaccount", region="eu"\n)\nlib_docai.predict(\n "invoice.pdf", model="df1d166771005ff4",\n project_id="complete-agency-347912", region="eu"\n)\nprint(lib_docai.get_result())\n\n
Library to support Nanonets service for intelligent document processing (IDP).
\nLibrary requires at the minimum rpaframework version 19.0.0.
\nService supports identifying fields in the documents, which can be given to the\nservice in multiple different file formats and via URL.
\nRobot Framework example usage
\n\n*** Settings ***\nLibrary RPA.DocumentAI.Nanonets\nLibrary RPA.Robocorp.Vault\n\n*** Tasks ***\nIdentify document\n ${secrets}= Get Secret nanonets-auth\n Set Authorization ${secrets}[apikey]\n ${result}= Predict File\n ... ${CURDIR}${/}files${/}eckero.jpg\n ... ${secrets}[receipts-model-id]\n ${fields}= Get Fields From Prediction Result ${result}\n FOR ${field} IN @{fields}\n Log To Console Label:${field}[label] Text:${field}[ocr_text]\n END\n ${tables}= Get Tables From Prediction Result ${result}\n FOR ${table} IN @{tables}\n FOR ${rows} IN ${table}[rows]\n FOR ${row} IN @{rows}\n ${cells}= Evaluate [cell['text'] for cell in $row]\n Log To Console ROW:${{" | ".join($cells)}}\n END\n END\n END\n\n
Python example usage
\n\nfrom RPA.DocumentAI.Nanonets import Nanonets\nfrom RPA.Robocorp.Vault import Vault\n\nsecrets = Vault().get_secret("nanonets-auth")\nnanolib = Nanonets()\nnanolib.set_authorization(secrets["apikey"])\nresult = nanolib.predict_file(file_to_scan, secrets["receipts-model-id"])\nfields = nanolib.get_fields_from_prediction_result(result)\nfor field in fields:\n print(f"Label: {field['label']} Text: {field['ocr_text']}")\ntables = nanolib.get_tables_from_prediction_result(result)\nfor table in tables:\n rpatable = Tables().create_table(table["rows"])\n for row in table["rows"]:\n cells = [cell["text"] for cell in row]\n print(f"ROW: {' | '.join(cells)}")\n\n
Exchange is a library for sending, reading, and deleting emails.\nExchange is interfacing with Exchange Web Services (EWS).
\nFor more information about server settings, see\nthis Microsoft support article.
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Email.Exchange\n... vault_name=email_oauth_microsoft vault_token_key=token\n... tenant=ztzvn.onmicrosoft.com # your custom tenant here\nTask Setup Ensure Auth\n\n*** Variables ***\n${ACCOUNT} ACCOUNT_NAME\n${RECIPIENT_ADDRESS} RECIPIENT\n${IMAGES} myimage.png\n${ATTACHMENTS} C:${/}files${/}mydocument.pdf\n\n*** Keywords ***\nEnsure Auth\n ${secrets} = Get Secret email_oauth_microsoft\n RPA.Email.Exchange.Authorize ${ACCOUNT}\n ... is_oauth=${True} # use the OAuth2 auth code flow (required)\n ... client_id=${secrets}[client_id] # app ID\n ... client_secret=${secrets}[client_secret] # app password\n ... token=${secrets}[token] # token dict (access, refresh, scope etc.)\n\n*** Tasks ***\nTask of sending email\n Send Message recipients=${RECIPIENT_ADDRESS}\n ... subject=Exchange Message from RPA Robot\n ... body=<p>Exchange RPA Robot message body<br><img src='myimage.png'/></p>\n ... save=${TRUE}\n ... html=${TRUE}\n ... images=${IMAGES}\n ... cc=EMAIL_ADDRESS\n ... bcc=EMAIL_ADDRESS\n ... attachments=${ATTACHMENTS}\n\nTask of listing messages\n # Attachments are saved specifically with a keyword Save Attachments\n ${messages}= List Messages\n FOR ${msg} IN @{messages}\n Log Many ${msg}\n ${attachments}= Run Keyword If "${msg}[subject]"=="about my orders"\n ... Save Attachments\n ... ${msg}\n ... save_dir=${CURDIR}${/}savedir\n END\n # Using save_dir all attachments in listed messages are saved\n ${messages}= List Messages\n ... INBOX/Problems/sub1\n ... criterion=subject:'about my orders'\n ... save_dir=${CURDIR}${/}savedir2\n FOR ${msg} IN @{messages}\n Log Many ${msg}\n END\n\nTask of moving messages\n Move Messages criterion=subject:'about my orders'\n ... source=INBOX/Processed Purchase Invoices/sub2\n ... target=INBOX/Problems/sub1\n\n
Python
\n\nfrom RPA.Email.Exchange import Exchange\nfrom RPA.Robocorp.Vault import Vault\n\nvault_name = "email_oauth_microsoft"\nsecrets = Vault().get_secret(vault_name)\nex_account = "ACCOUNT_NAME"\n\nmail = Exchange(\n vault_name=vault_name,\n vault_token_key="token",\n tenant="ztzvn.onmicrosoft.com"\n)\nmail.authorize(\n username=ex_account,\n is_oauth=True,\n client_id=secrets["client_id"],\n client_secret=secrets["client_secret"],\n token=secrets["token"]\n)\nmail.send_message(\n recipients="RECIPIENT",\n subject="Message from RPA Python",\n body="RPA Python message body",\n)\n\n
OAuth2
\nThe OAuth2 flow is the only way of authorizing at the moment as Microsoft disabled\nentirely the usage of passwords, even App Passwords. And since you have to work\nwith tokens now and because this library has the capability to automatically\nrefresh an expired token, please don't forget to initialize the library with the\nfollowing parameters: vault_name, vault_token_key and tenant.
\nLearn more on how to use the OAuth2 flow in this Portal robot\nexample-oauth-email.
\nAbout criterion parameter
\nFollowing table shows possible criterion keys that can be used to filter emails.\nThere apply to all keywords which have criterion parameter.
\nKey | \nEffective search | \n
---|---|
subject | \nsubject to match | \n
subject_contains | \nsubject to contain | \n
body | \nbody to match | \n
body_contains | \nbody to contain | \n
sender | \nsender (from) to match | \n
sender_contains | \nsender (from) to contain | \n
before | \nreceived time before this time | \n
after | \nreceived time after this time | \n
between | \nreceived time between start and end | \n
category | \ncategories to match | \n
category_contains | \ncategories to contain | \n
importance | \nimportance to match | \n
Keys before, after and between at the moment support two\ndifferent timeformats either %d-%m-%Y %H:%M or %d-%m-%Y. These\nkeys also support special string NOW which can be used especially\ntogether with keyword Wait for message criterion=after:NOW.
\nWhen giving time which includes hours and minutes then the whole\ntime string needs to be enclosed into single quotes.
\n\nbefore:25-02-2022\nafter:NOW\nbetween:'31-12-2021 23:50 and 01-01-2022 00:10'\n\n
Different criterion keys can be combined.
\n\nsubject_contains:'new year' between:'31-12-2021 23:50 and 01-01-2022 00:10'\n\n
Please note that all values in the criterion that contain spaces need\nto be enclosed within single quotes.
\nIn the following example the email subject is going to matched\nonly against new not new year.
\n\nsubject_contains:new year\n
\nImapSmtp is a library for sending, reading, and deleting emails.\nImapSmtp is interfacing with SMTP and IMAP protocols.
\n*About criteria argument*
\nVarious keywords like List Messages and Move Messages have keyword\nargument called criterion which can be used to filter emails according\nto given criteria.
\nSyntax needs to according to specification and more information about that\ncan be read from https://robocorp.com/docs/development-guide/email/sending-emails-with-gmail-smtp#listing-email-messages-by-criteria
\nTroubleshooting
\nMake sure to specify a provider (and optionally a tenant) when importing\nthe library and planning to use this flow.
\nExamples
\nRobot Framework
\nIt is highly recommended to secure your passwords and take care\nthat they are not stored in version control by mistake.\nSee RPA.Robocorp.Vault to see how to store secrets in\nRobocorp Vault.
\nWhen sending HTML content with IMG tags, the src filenames must match\nthe base image name given with the images parameter.
\n\n*** Settings ***\nLibrary RPA.Email.ImapSmtp smtp_server=smtp.gmail.com smtp_port=587\nTask Setup Authorize account=${GMAIL_ACCOUNT} password=${GMAIL_PASSWORD}\n\n*** Variables ***\n${GMAIL_ACCOUNT} ACCOUNT_NAME\n${GMAIL_PASSWORD} APP_PASSWORD\n${RECIPIENT_ADDRESS} RECIPIENT\n${BODY_IMG1} ${IMAGEDIR}${/}approved.png\n${BODY_IMG2} ${IMAGEDIR}${/}invoice.png\n${EMAIL_BODY} <h1>Heading</h1><p>Status: <img src='approved.png' alt='approved image'/></p>\n... <p>INVOICE: <img src='invoice.png' alt='invoice image'/></p>\n\n*** Tasks ***\nSending email\n Send Message sender=${GMAIL_ACCOUNT}\n ... recipients=${RECIPIENT_ADDRESS}\n ... subject=Message from RPA Robot\n ... body=RPA Robot message body\n\nSending HTML Email With Image\n [Documentation] Sending email with HTML content and attachment\n Send Message\n ... sender=${GMAIL_ACCOUNT}\n ... recipients=${RECIPIENT_ADDRESS}\n ... subject=HTML email with body images (2) plus one attachment\n ... body=${EMAIL_BODY}\n ... html=${TRUE}\n ... images=${BODY_IMG1}, ${BODY_IMG2}\n ... attachments=example.png\n\n
Python
\n\nfrom RPA.Email.ImapSmtp import ImapSmtp\n\ngmail_account = "ACCOUNT_NAME"\ngmail_password = "APP_PASSWORD"\n\nmail = ImapSmtp(smtp_server="smtp.gmail.com", smtp_port=587)\nmail.authorize(account=gmail_account, password=gmail_password)\nmail.send_message(\n sender=gmail_account,\n recipients="RECIPIENT",\n subject="Message from RPA Python",\n body="RPA Python message body",\n)\n\n
Excel.Application is a library for controlling the Excel application.
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Excel.Application\nTask Setup Open Application\nTask Teardown Quit Application\n\n*** Tasks ***\nManipulate Excel application\n Open Workbook workbook.xlsx\n Set Active Worksheet sheetname=new stuff\n Write To Cells row=1\n ... column=1\n ... value=my data\n Save Excel\n\nRun Excel Macro\n Open Workbook orders_with_macro.xlsm\n Run Macro Sheet1.CommandButton1_Click\n\nExport Workbook as PDF\n Open Workbook workbook.xlsx\n Export as PDF workbook.pdf\n\n
Python
\n\nfrom RPA.Excel.Application import Application\n\napp = Application()\n\napp.open_application()\napp.open_workbook('workbook.xlsx')\napp.set_active_worksheet(sheetname='new stuff')\napp.write_to_cells(row=1, column=1, value='new data')\napp.save_excel()\napp.quit_application()\n\n
Caveats
\nThis library works on a Windows operating system with UI enabled only, and you must\nensure that you open the app first with Open Application before running any\nother relevant keyword which requires to operate on an open app. The application is\nautomatically closed at the end of the task execution, so this can be changed by\nimporting the library with the autoexit=${False} setting.
\n\n*** Settings ***\nLibrary RPA.Excel|Outlook|Word.Application autoexit=${False}\n\n
If you're running the Process by Control Room through a custom self-hosted Worker\nservice, then please make sure that you enable an RDP session by ticking "Use\nDesktop Connection" under the Step configuration.
\nIf you still encounter issues with opening a document, please ensure that file can\nbe opened first manually and dismiss any alert potentially blocking the process.
\nCheck the documentation below for more info:
\n\nThe Excel.Files library can be used to read and write Excel\nfiles without the need to start the actual Excel application.
\nIt supports both legacy .xls files and modern .xlsx files.
\nNote: To run macros or load password protected worksheets,\nplease use the Excel application library.
\nExamples
\nRobot Framework
\nA common use-case is to load an existing Excel file as a table,\nwhich can be iterated over later in a Robot Framework keyword or task:
\n\n*** Settings ***\nLibrary RPA.Tables\nLibrary RPA.Excel.Files\n\n*** Keywords ***\nRead orders as table\n Open workbook ${ORDERS_FILE}\n ${worksheet}= Read worksheet header=${TRUE}\n ${orders}= Create table ${worksheet}\n [Return] ${orders}\n [Teardown] Close workbook\n\n
Processing all worksheets in the Excel file and checking row count:
\n\n*** Settings ***\nLibrary RPA.Excel.Files\n\n*** Variables ***\n${EXCEL_FILE} /path/to/excel.xlsx\n\n*** Tasks ***\nRows in the sheet\n [Setup] Open Workbook ${EXCEL_FILE}\n @{sheets}= List Worksheets\n FOR ${sheet} IN @{sheets}\n ${count}= Get row count in the sheet ${sheet}\n Log Worksheet '${sheet}' has ${count} rows\n END\n\n*** Keywords ***\nGet row count in the sheet\n [Arguments] ${SHEET_NAME}\n ${sheet}= Read Worksheet ${SHEET_NAME}\n ${rows}= Get Length ${sheet}\n [Return] ${rows}\n\n
Creating a new Excel file with a dictionary:
\n\n*** Tasks ***\nCreating new Excel\n Create Workbook my_new_excel.xlsx\n FOR ${index} IN RANGE 20\n &{row}= Create Dictionary\n ... Row No ${index}\n ... Amount ${index * 25}\n Append Rows to Worksheet ${row} header=${TRUE}\n END\n Save Workbook\n\n
Creating a new Excel file with a list:
\n\n*** Variables ***\n@{heading} Row No Amount\n@{rows} ${heading}\n\n*** Tasks ***\nCreating new Excel\n Create Workbook my_new_excel.xlsx\n FOR ${index} IN RANGE 1 20\n @{row}= Create List ${index} ${index * 25}\n Append To List ${rows} ${row}\n END\n Append Rows to Worksheet ${rows}\n Save Workbook\n\n
Python
\nThe library can also be imported directly into Python.
\n\nfrom RPA.Excel.Files import Files\n\ndef read_excel_worksheet(path, worksheet):\n lib = Files()\n lib.open_workbook(path)\n try:\n return lib.read_worksheet(worksheet)\n finally:\n lib.close_workbook()\n\n
FTP library can be used to access an FTP server,\nand interact with files.
\nThe library is based on Python's built-in ftplib.
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.FTP\n\n*** Variables ***\n${HOST} 127.0.0.1\n${PORT} 27345\n${USER} user\n${PASS} 12345\n\n*** Tasks ***\nList files on the server directory\n Connect ${HOST} ${PORT} ${USER} ${PASS}\n @{files} List Files\n FOR ${file} IN @{files}\n Log ${file}\n END\n\n
Python
\n\nfrom RPA.FTP import FTP\n\nlibrary = FTP()\nlibrary.connect('127.0.0.1', 27345, 'user', '12345')\nfiles = library.list_files()\nfor f in files:\n print(f)\n\n
The FileSystem library can be used to interact with files and directories\non the local computer. It can inspect and list files, remove and create them,\nread contents from files, and write data out.
\nIt shadows the built-in OperatingSystem library but contains keywords\nwhich are more RPA-oriented.
\nExamples
\nRobot Framework
\nThe library allows, for instance, iterating over files and inspecting them.
\n\n*** Settings ***\nLibrary RPA.FileSystem\n\n*** Keywords ***\nDelete large files\n ${files}= List files in directory archive/orders/\n FOR ${file} IN @{FILES}\n Run keyword if ${file.size} > 10**8 Remove file ${file}\n END\n\nRead process output\n Start external program\n Wait until modified process.log\n ${output}= Read file process.log\n [Return] ${output}\n\n
Python
\nThe library can also be used inside Python.
\n\nfrom RPA.FileSystem import FileSystem\n\ndef move_to_archive():\n lib = FileSystem()\n\n matches = lib.find_files("**/*.xlsx")\n if matches:\n lib.create_directory("archive")\n lib.move_files(matches, "archive")\n\n
The RPA.HTTP library extends functionality of the RequestsLibrary.\nSee that documentation for several examples of how to issue GET\nrequests and utilize the returned result objects.
\nThis extension provides helper keywords to get an HTTP resource on a\nsession. The HTTP Get and Download keywords will initiate a\nsession if one does not exist for the provided URL, or use an existing\nsession. When using these keywords, you do not need to manage\nsessions with Create Session. Session management is still\nrequired if you use the underlying session keywords, e.g.,\n* On Session.
\nCreate Session: create a HTTP session to a server
\nurl Base url of the server
\nalias Robot Framework alias to identify the session
\nheaders Dictionary of default headers
\ncookies Dictionary of cookies
\nclient_certs ['client certificate', 'client key'] PEM files containing the client key and certificate
\ntimeout Connection timeout
\ndisable_warnings Disable requests warning useful when you have large number of testcases
\nCreate Session: create a HTTP session to a server
\nurl Base url of the server
\nalias Robot Framework alias to identify the session
\nheaders Dictionary of default headers
\ncookies Dictionary of cookies
\ntimeout Connection timeout
\ndisable_warnings Disable requests warning useful when you have large number of testcases
\nCreate Session: create a HTTP session to a server
\nurl Base url of the server
\nalias Robot Framework alias to identify the session
\nheaders Dictionary of default headers
\ncookies Dictionary of cookies
\nauth ['DOMAIN', 'username', 'password'] for NTLM Authentication
\ntimeout Connection timeout
\ndisable_warnings Disable requests warning useful when you have large number of testcases
\nCreate Session: create a HTTP session to a server
\nurl Base url of the server
\nalias Robot Framework alias to identify the session
\nheaders Dictionary of default headers
\ncookies Dictionary of cookies
\nauth ['DOMAIN', 'username', 'password'] for NTLM Authentication
\ntimeout Connection timeout
\ndisable_warnings Disable requests warning useful when you have large number of testcases
\nCreate Session: create a HTTP session to a server
\nalias Robot Framework alias to identify the session
\nurl Base url of the server
\nheaders Dictionary of default headers
\ncookies Dictionary of cookies
\nauth List of username & password for HTTP Basic Auth
\ntimeout Connection timeout
\nverify Whether the SSL cert will be verified. A CA_BUNDLE path can also be provided.
\ndisable_warnings Disable requests warning useful when you have large number of testcases
\nHubspot is a library for accessing HubSpot using REST API. It\nextends hubspot-api-client.
\nCurrent features of this library focus on retrieving CRM object data\nfrom HubSpot via API. For additional information, see\nUnderstanding the CRM.
\nWhen using date times with the Hubspot API, you must provide\nthem as Unix-style epoch timestamps (with milliseconds), which can be obtained\nusing the DateTime library's Convert Date with the\nargument result_format=epoch. The resulting timestamp string\nwill be a float, but the API only accepts integers, so you must\nmultiply the resulting timestamp by 1,000 and then round it to\nthe nearest integar to include in API calls (i.e., the resulting\ninteger sent to the API must have 13 digits as of March 18, 2022).
\nRobot framework example usage:
\n\n*** Settings ***\nLibrary DateTime\nLibrary RPA.Hubspot\nTask Setup Authorize Hubspot\n\n*** Tasks ***\nSearch with date\n ${yesterday}= Get current date increment=-24h result_format=epoch\n ${yesterday_hs_ts}= Evaluate round(${yesterday} * 1000)\n ${deals}= Search for objects DEALS\n ... hs_lastmodifieddate GTE ${yesterday_hs_ts}\n\n
Python example usage
\n\nfrom robot.libraries.DateTime import get_current_date, subtract_time_from_date\nfrom RPA.Hubspot import Hubspot\nfrom RPA.Robocorp.Vault import Vault\n\nsecrets = Vault().get_secret("hubspot")\n\nhs = Hubspot(hubspot_apikey=secrets["api_key"])\nyesterday = round(\n subtract_time_from_date(get_current_date(), "24h", result_format="epoch") * 1000\n)\ndeals = hs.search_for_objects("DEALS", "hs_lastmodifieddate", "GTE", yesterday)\nprint(deals)\n\n
When retrieving information, the library automatically batches requests\nthat are provided as lists, see Get object keyword for an example,\nbut when wishing to create or update many objects, the library provides\na batching system.
\nIn order to start a batch, you must first call the Create new batch\nkeyword. This initializes a new batch to accept inputs. If a batch\nalready exists when you call this keyword, it will be lost and a new\nblank one will be started.
\nOnce the batch has been initialized, you can add inputs one at a time with\nAdd input to batch or many at a time with Extend batch with inputs.
\nIn order to finally send the batch to HubSpot, you must call\nExecute batch. The final keyword will return the created or updated\nobjects from HubSpot. New object IDs can be obtained from the id\nproperty, see the SimplePublicObject reference.
\nRobot framework example:
\n\n*** Settings ***\nLibrary RPA.Hubspot\nLibrary RPA.Robocorp.Vault\nTask Setup Authorize Hubspot\n\n*** Tasks ***\nCreate objects via batch\n Create new batch\n Add input to batch name=Nokia country=Finland\n Add input to batch name=Google country=USA\n ${new_companies}= Execute batch\n Log The first new company added has the new id ${{$new_companies[0].id}}\n\n*** Keywords ***\nAuthorize Hubspot\n ${secrets}= Get secret hubspot\n Auth with api key ${secrets}[API_KEY]\n\n
Python example:
\nNOTE: When executing a batch input in Python, you can directly import the\nBatchInputFactory class to use to create your batch input before\nexecuting the batch.
\n\nfrom RPA.Hubspot import Hubspot, BatchInputFactory, BatchMode\nfrom RPA.Robocorp.Vault import RobocorpVault\n\n\nvault = RobocorpVault()\nsecrets = vault.get_secret("hubspot")\n\nhs = Hubspot(secrets["API_KEY"])\n\nbatch = BatchInputFactory(BatchMode.UPDATE, "company")\nbatch.extend_inputs(\n [\n {"name": "Nokia's New Name", "city": "Espoo"},\n {"name": "Alphabet", "city": "Mountain View"},\n ],\n ["1001", "1002"],\n)\nhs.batch_input = batch\nupdated_companies = hs.execute_batch()\nprint(\n "Companies have been updated:\\\\n" +\n "\\\\n".join([str(c) for c in updated_companies])\n)\n\n
This library loads custom object schemas and pipelines into memory\nthe first time when keywords using them are called. These cached versions\nare recalled unless the use_cache is set to False, where available.
\nAll keywords that request a parameter of object_type can accept\ncustom object type names as long as they are properly configured in\nHubSpot. The system will lookup the custom object ID using the\nprovided name against the configured name or one of the configured\nlabels (e.g., "singular" and "plural" types of the name).
\nThis section describes the types of objects returned by this Library\nand their associated attributes. These attributes can be accessed via\ndot-notation as described in the Attribute Access section below.
\nKeywords return native Python Hubspot objects, rather than common Robot\nFramework types. These types have sets of defined attributes allowing\nfor dot-notation access of object properties. Properties (e.g.,\nthose configured in Hubspot settings for each object) will be\naccessible in a Python dictionary attached to the properties attribute\nof the returned object. See the Attribute Definitions section for\ndetails of that associated attributes for all types returned by this\nlibrary.
\nExample usage retrieving the city property of a Company object:
\nRobot framework example:
\n\n*** Settings ***\nLibrary RPA.Hubspot\nLibrary RPA.Robocorp.Vault\n\nTask Setup Authorize Hubspot\n\n*** Variables ***\n${ACCOUNT_NOKIA} 6818764598\n\n*** Tasks ***\nObtain city information from Hubspot\n ${account}= Get object COMPANY ${ACCOUNT_NOKIA}\n Log The city for account number ${ACCOUNT_NOKIA} is ${account.properties}[city]\n\n*** Keywords ***\nAuthorize Hubspot\n ${secrets}= Get secret hubspot\n Auth with api key ${secrets}[API_KEY]\n\n
Python example:
\n\nfrom RPA.Hubspot import Hubspot\nfrom RPA.Robocorp.Vault import RobocorpVault\n\nvault = RobocorpVault()\nsecrets = vault.get_secret("hubspot")\n\nhs = Hubspot(secrets["API_KEY"])\nnokia_account_id = "6818764598"\naccount = hs.get_object("COMPANY", nokia_account_id)\nprint(f"The city for account number {nokia_account_id} is {account.properties['city']}")\n\n
This library can return various types of objects, whose attributes\nare only accessible via dot-notation. The below reference describes\nthe attributes available on these objects.
\nAn object in HubSpot. The object itself does not describe what type\nit represents.
\nAn object in HubSpot including associations to other objects. The\nobject itself does not describe what type it represents.
\nThe ID of an associated object, as well as the type of association.
\nA container object for a collection of AssociatedId objects returned\nby the API.
\nA pipeline represents the steps objects travel through within HubSpot.
\nA pipeline stage is one of the various stages defined in a Pipeline.
\nAn owner in HubSpot. Owners of companies and deals are responsible\nfor driving a sale to close or similar.
\nA team of owners in HubSpot
\nImages is a library for general image manipulation.\nFor image-based desktop automation, use the RPA.Desktop library.
\nCoordinates
\nThe coordinates used in the library are pairs of x and y values that\nrepresent pixels. The upper left corner of the image or screen\nis (0, 0). The x-coordinate increases towards the right, and the y-coordinate\nincreases towards the bottom.
\nRegions are represented as tuples of (left, top, right, bottom). For example,\na 400 by 200-pixel region in the upper left corner would be (0, 0, 400, 200).
\nTemplate matching
\nTemplate matching refers to an operation where the (potential) location of\na smaller image is searched from a larger image. It can be used for verifying\ncertain conditions or locating UI elements for desktop or web automation.
\nRequirements
\nThe default installation depends on Pillow\nlibrary, which is used for general image manipulation operations.
\nFor more robust and faster template matching, the library can use a combination\nof NumPy and OpenCV.\nThey can be installed by opting in to the recognition dependency:
\npip install rpaframework rpaframework-recognition
\nExamples
\nRobot Framework
\nThe Images library can be imported and used directly in Robot Framework,\nfor instance, for capturing screenshots or verifying something on the screen.
\nDesktop automation based on images should be done using the corresponding\ndesktop library, i.e. RPA.Desktop.
\n\n*** Settings ***\nLibrary RPA.Images\n\n*** Keywords ***\nShould show success\n [Documentation] Raises ImageNotFoundError if success image is not on screen\n Find template on screen ${CURDIR}${/}success.png\n\nSave screenshot to results\n [Documentation] Saves screenshot of desktop with unique name\n ${timestamp}= Get current date result_format=%H%M%S\n Take screenshot filename=${OUTPUT_DIR}${/}desktop_${timestamp}.png\n\n
Python
\n\nfrom RPA.Images import Images\n\ndef draw_matches_on_image(source, template):\n matches = lib.find_template_in_image(source, template)\n for match in matches:\n lib.show_region_in_image(source, match)\n\n source.save("matches.png")\n\n
JSON is a library for manipulating JSON files and strings.
\nJSON is a common data interchange format inspired by a subset of\nthe Javascript programming language, but these days is a de facto\nstandard in modern web APIs and is language agnostic.
\nThe term serialization refers to the process of converting\nRobot Framework or Python types to JSON or the other way around.
\nBasic types can be easily converted between the domains,\nand the mapping is as follows:
\nJSON | \nPython | \n
---|---|
object | \ndict | \n
array | \nlist | \n
string | \nstr | \n
number (int) | \nint | \n
number (real) | \nfloat | \n
true | \nTrue | \n
false | \nFalse | \n
null | \nNone | \n
Reading and writing values from/to JSON serializable objects is done\nusing JSONPath. It's a syntax designed to quickly and easily refer to\nspecific elements in a JSON structure. The specific flavor used in this\nlibrary is based on jsonpath-ng.
\nCompared to Python's normal dictionary access, JSONPath expressions can\ntarget multiple elements through features such as conditionals and wildcards,\nwhich can simplify many JSON-related operations. It's analogous to XPath\nfor XML structures.
\nFor this example consider the following structure:
\n\n{\n "clients": [\n {\n "name": "Johnny Example",\n "email": "john@example.com",\n "orders": [\n {"address": "Streetroad 123", "price": 103.20},\n {"address": "Streetroad 123", "price": 98.99}\n ]\n },\n {\n "name": "Jane Example",\n "email": "jane@example.com",\n "orders": [\n {"address": "Waypath 321", "price": 22.00},\n {"address": "Streetroad 123", "price": 2330.01}\n ]\n }\n ]\n}\n\n
In the simplest case JSONPath can replace nested access:
\n\n*** Tasks ***\nNested access\n # First order of first client, with direct dictionary access\n ${value}= Set variable ${json}["clients"][0]["orders"][0]\n\n # JSONPath access\n ${value}= Get value from JSON ${json} $.clients[0].orders[0]\n\n
But the power comes from complicated expressions:
\n\n*** Tasks ***\nComplicated expressions\n # Find delivery addresses for all orders\n ${prices}= Get values from JSON $..address\n\n # Find orders that cost over 100\n ${expensives}= Get values from JSON $..orders[?(@.price>100)]\n\n
The supported syntax elements are:
\nElement | \nDescription | \n
---|---|
$ | \nRoot object/element | \n
@ | \nCurrent object/element inside expressions | \n
. or [] | \nChild operator | \n
.. | \nRecursive descendant operator | \n
`parent` | \nParent operator, see functions | \n
* | \nWilcard, any element | \n
, | \nSelect multiple fields | \n
[n] | \nArray index | \n
[a:b:c] | \nArray slice (start, end, step) | \n
[a,b] | \nUnion of indices or names | \n
[?()] | \nApply a filter expression | \n
() | \nScript expression | \n
[\\\\field] | \nSort descending by field, cannot be combined with\nfilters. | \n
[/field] | \nSort ascending by field, cannot be combined with\nfilters. | \n
`str()` | \nConvert value to string, see functions | \n
`sub()` | \nRegex substitution function, see functions | \n
`len` | \nCalculate value's length, see functions | \n
`split()` | \nString split function, see functions | \n
+ - * / | \nArithmetic functions, see functions | \n
This library allows JSON path expressions to include certain functions\nwhich can provide additional benefit to users. These functions are\ngenerally encapsulated in backticks (`). Some functions require\nyou to pass arguments similar to a Python function.
\nFor example, let's say a JSON has nodes on the JSON path\n$.books[*].genres which are represented as strings of genres with\ncommas separating each genre. So for one book, this node might have a\nvalue like horror,young-adult. You can return a list of first genre\nfor each book by using the split function like so:
\n\n*** Task ***\nGet genres\n ${genres}= Get values from JSON $.books[*].genres.`split(,, 0, -1)`\n\n
Each functions parameters are defined here:
\nFunction | \nUsage | \n
---|---|
str() | \nNo parameters, but parenthesis are required | \n
sub(/regex/, repl) | \nThe regex pattern must be provided in regex\nand the replacement value provided in repl | \n
len | \nNo parameters and no parenthesis | \n
split(char, segment, max_split) | \nSeparator character provided as char, which\nindex from the resulting array to be returns\nprovided as segment, and maximum number of\nsplits to perform provided as max_split,\n-1 for all splits. | \n
parent | \nNo parameters, no parenthesis | \n
Arithmetic Functions
\nJSON Path can be written and combined to concatenate string values\nor perform arithmetic functions on numerical values. Each JSONPath\nexpression used must return the same type, and when performing\nsuch functions between returned lists, each list must be the same\nlength. An example is included in documentation for the keyword\nGet values from JSON.
\nThere are a multitude of different script expressions\nin addition to the elements listed above, which can\nbe seen in the aforementioned article.
\nFor further library usage examples, see the individual keywords.
\nJava application UI automation library using Java Access Bridge technology.
\nThe library utilizes java-access-bridge-wrapper package to interact with\nJava UI. Currently only the 64-bit Windows OS is supported.
\nInspecting elements
\nWe have built an Assistant for working with Java application's element structure and Java locators.\nThe Assistant provides copy-paste-able locators for each element and also allows testing locators against\nselected application.
\nIf our tools fail to pick the locator from your target application, there is always the\nAccess Bridge Explorer from Google that enables you to see the raw view. Please note that\nAccess Bridge Explorer repository has been archived on July 27, 2022 and is no longer actively\nmaintained.
\nThe Accessibility Insights for Windows can show element properties if application framework\nsupports Windows UI Automation (UIA), see more at using Accessibility Insights. Then the recommended\nlibrary would be RPA.Windows library.
\nSteps to enable
\n\n\n\n
\n- Enable the Java Access Bridge in Windows
\n- Set environment variable RC_JAVA_ACCESS_BRIDGE_DLL as an absolute path to WindowsAccessBridge-64.dll.\nIt is also possible to give DLL location as library initialization parameter access_bridge_path.
\n\nC:\\path\\to\\java\\bin\\jabswitch -enable\nset RC_JAVA_ACCESS_BRIDGE_DLL=C:\\path\\to\\Java\\bin\\WindowsAccessBridge-64.dll\n
\n\n*** Settings ***\nLibrary RPA.JavaAccessBridge access_bridge_path=C:\\path\\to\\Java\\bin\\WindowsAccessBridge-64.dll\n\n
About Java wrapper callbacks and actions
\nThere might be a compatibility issue with callbacks and actions on target Java application. Possible reasons:
\nWorkaround for this situation is to initialize JavaAccessBridge library with parameter ignore_callbacks=True.\nThen application's element information is still accessible and any actions on those elements can be performed\nwith RPA.Desktop library. Keep in mind that you can still manuall refresh an element with Refresh Element.
\nNote. There are still keywords, for example. Call Element Action, which will cause error if used in this\nsituation.
\n\n*** Settings ***\nLibrary RPA.JavaAccessBridge ignore_callbacks=True\n\n
Controlling the Java window
\nKeyword for this purpose is Select Window. Window selection is based on the title parameter, which can be\ngiven as a regular expressions to match the correct window. The keyword brings the window into focus and initially\nreads window's element structure.
\nLocating elements
\nTo automate actions on the Java application, the robot needs locations to various elements\nusing a feature called Java locators. Locator describes properties of an element.
\nAt the moment library contains basic level support for locators.
\nThe common locator types are name and role.
\nTo identify element with more than one property and can be used, for example:
\n\n\nrole:push button and name:Clear\n
\n
\nTo address element within parent element > can be used, for example:
\n\n\nname:Find Purchase Orders > name:NumberField\n
\n
\nSome keywords accept element as an parameter in place of locator.
\nNew locator type strict has been added in rpaframework==12.5.0. Currently\nproperty values of string type have been evaluated with startsWith which\ncan match several property values. With strict set in the locator string,\nall locator on the right side of this definition will be matched using\nstrict (equal matching), example:
\n\n\n\n# without strict, name can be 'Type', 'Type1', 'Type of'...\nGet Elements role:push button and name:Type\n# name must be equal to 'Type'\nGet Elements role:push button and strict:True and name:Type\n\n
Keyword Get Elements has extra parameter strict, which when set to\nTrue forces all locator value matches to be strict, example:
\n\n\n\n# without strict, name can be 'Type', 'Type1', 'Type of'...\nGet Elements role:push button and name:Type\n# name must be equal to 'Type' and role must be equal to 'text'\nGet Elements role:text and name:Type strict=True\n\n
About JavaElement object
\nThe JavaElement was added in rpaframework==12.3.0 for easy access into\nContextNode objects which have been returned by Get Elements keyword.
\nKeyword Get Elements still returns ContextNode objects, but with parameter\njava_elements=True the keyword returns JavaElement objects instead (they\nstill contain reference to ContextNode object via node property, e.g.\nJavaObject.node).
\nProperties and methods included in the JavaElement:
\nInteracting with elements
\nBy default application elements are interacted with Actions supported by the element.\nMost common example is click action supported by an button element.
\nBut because application and technology support for the actions might be limited, it is also\npossible to opt for interaction elements by their coordinates by giving keyword parameter\naction=False if parameter is available.
\nExamples
\nrobotframework
\n\n*** Settings ***\nLibrary RPA.JavaAccessBridge\nLibrary Process\n\n*** Tasks ***\nWrite text into Swing application\n Start Process java -jar BasicSwing.jar\n ... shell=${TRUE}\n ... cwd=${CURDIR}\n Select Window Chat Frame\n Type Text role:text\n ... text for the textarea\n Type Text role:text\n ... text for the input field\n ... index=1\n ... clear=${TRUE}\n Click Element role:push button and name:Send\n\n
Python
\n\nfrom RPA.JavaAccessBridge import JavaAccessBridge\nimport subprocess\n\njab = JavaAccessBridge()\n\nsubprocess.Popen(\n ["java", "-jar", "BasicSwing.jar"],\n shell=True,\n cwd=".",\n close_fds=True\n)\njab.select_window("Chat Frame")\njab.type_text(\n "role:text",\n "text for the textarea",\n enter=True\n)\njab.type_text(\n "role:text",\n "text for the input field",\n index=1,\n clear=True\n)\njab.click_element("role:push button and name:Send")\n\n
RPA.MFA is a library intended mainly for generating one-time passwords (OTP)\nand not only, as OAuth2 support was introduced lately.
\nLibrary requires at the minimum rpaframework version 19.4.0.
\nBased on the pyotp and\nrequests_oauthlib packages. It\nprovides support for both MFA with the * OTP related keywords and OAuth2\n"Authorization Code Flow" with the * OAuth * related keywords.
\nIn the below example the mfa secret we are reading from the Robocorp\nVault is the passcode generated by the Authenticator service. The passcode\nvalue is stored into the Vault with key otpsecret.
\nPasscode is typically a long string (16-32 characters), which is provided\nin a form of QR image, but it can be obtained by requesting access to a string.
\nNote that same code can be used to add a mobile phone as a duplicate authentication\ndevice at the same time when the same code is added into the Vault.
\nRobot framework example usage:
\n\n*** Settings ***\nLibrary RPA.MFA\nLibrary RPA.Robocorp.Vault\n\n*** Tasks ***\nGenerate time based code\n ${secrets}= Get Secret mfa\n ${code}= Get Time Based OTP ${secrets}[otpsecret]\n\n
Python example usage
\n\nfrom RPA.MFA import MFA\nfrom RPA.Robocorp.Vault import Vault\n\n\ndef main():\n secrets = Vault().get_secret("mfa")\n code = MFA().get_time_based_otp(secrets["otpsecret"])\n\n
The MSGraph library wraps the O365 package, giving robots\nthe ability to access the Microsoft Graph API programmatically.
\nOAuth Configuration
\nGraph's API primarily authenticates via the OAuth 2.0 authorization code grant\nflow or OpenID Connect. This library exposes the OAuth 2.0 flow for robots to\nauthenticate on behalf of users. A user must complete an initial authentication\nflow with the help of our OAuth Graph Example Bot.
\nFor best results, register an app in Azure AD and configure it as so:
\nNetsuite is a library for accessing Netsuite using NetSuite SOAP web service SuiteTalk.\nThe library extends the netsuitesdk library.
\nMore information available at NetSuite SOAP webservice SuiteTalk.
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Netsuite\nLibrary RPA.Excel.Files\nLibrary RPA.Tables\nTask Setup Authorize Netsuite\n\n*** Tasks ***\nGet data from Netsuite and Store into Excel files\n ${accounts}= Get Accounts account_type=_expense\n ${accounts}= Create table ${accounts}\n Create Workbook\n Append Rows To Worksheet ${accounts}\n Save Workbook netsuite_accounts.xlsx\n Close Workbook\n ${bills}= Get Vendor Bills\n ${bills}= Create table ${bills}\n Create Workbook\n Append Rows To Worksheet ${bills}\n Save Workbook netsuite_bills.xlsx\n Close Workbook\n\n\n*** Keywords ***\nAuthorize Netsuite\n ${secrets}= Get Secret netsuite\n Connect\n ... account=${secrets}[ACCOUNT]\n ... consumer_key=${secrets}[CONSUMER_KEY]\n ... consumer_secret=${secrets}[CONSUMER_KEY]\n ... token_key=${secrets}[CONSUMER_SECRET]\n ... token_secret=${secrets}[TOKEN_KEY]\n\n
Python
\n\nfrom RPA.Netsuite import Netsuite\n\nns = Netsuite()\nns.connect()\naccounts = ns.get_accounts()\ncurrencies = ns.get_currencies()\n\n
Notifier is a library interfacting with different notification providers.
\nSupported providers
\nProviders not supported yet via specific keywords
\nThere is a keyword Generic Notify which can be used\nto call above services, for example.
\n\nGeneric Notify\n provider_name=gitter\n message=Hello from Robot\n token=TOKEN\n room_id=ID_OF_THE_GITTER_ROOM\n\n
Parameters for different providers can be read from the\nNotifiers documents (link below).
\nRead more at https://notifiers.readthedocs.io/en/latest/
\nAbout kwargs
\nThe **kwargs is a term for any extra named parameters, which\ncan be included in the same way as already named arguments,\ne.g. Notify Email could be called with subject=my email subject\nwhich will be passed through **kwargs.
\nNotifier documentation contains information about all possible\narguments that different providers support.
\nRobot Framework
\n\n&{account}= Create Dictionary\n... host=smtp.office365.com\n... username=ACCOUNT_USERNAME\n... password=ACCOUNT_PASSWORD\nNotify Email\n... to=RECIPIENT_EMAIL\n... from_=SENDER_ADDRESS # passed via kwargs\n... subject=Hello from the Robot # passed via kwargs\n... message=Hello from the Robot\n... &{account} # passed via kwargs\n\n
\nnotifier = Notifier()\naccount = {\n "host": "smtp.office365.com",\n "username": "EMAIL_USERNAME",\n "password": "EMAIL_PASSWORD"\n}\nnotifier.email_notify(\n to="RECIPIENT_EMAIL",\n from_="SENDER_EMAIL",\n subject="Hello from the Python Robot",\n message="Hello from the Python RObot",\n **account\n)\n\n
Examples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Notifier\n\n*** Variables ***\n${SLACK_WEBHOOK} https://hooks.slack.com/services/WEBHOOKDETAILS\n${CHANNEL} notification-channel\n\n*** Tasks ***\nLets notify\n Notify Slack message from robot channel=${CHANNEL} webhook_url=${SLACK_WEBHOOK}\n\n
Python
\n\nfrom RPA.Notifier import Notifier\n\nlibrary = Notifier()\n\nslack_attachments = [\n {\n "title": "attachment 1",\n "fallback": "liverpool logo",\n "image_url": "https://upload.wikimedia.org/wikipedia/fi/thumb/c/cd/Liverpool_FC-n_logo.svg/1200px-Liverpool_FC-n_logo.svg.png",\n }\n]\n\nlibrary.notify_slack(\n message='message for the Slack',\n channel="notification-channel",\n webhook_url=slack_webhook_url,\n attachments=slack_attachments,\n)\n\n
Library to support OpenAI and Azure OpenAI services.
\nLibrary is not included in the rpaframework package, so in order to use it\nyou have to add rpaframework-openai with the desired version in your\nconda.yaml file.
\nRobot Framework example usage
\n\n*** Settings ***\nLibrary RPA.Robocorp.Vault\nLibrary RPA.OpenAI\n\n*** Tasks ***\nCreate a text completion\n ${secrets} Get Secret secret_name=OpenAI\n Authorize To OpenAI api_key=${secrets}[key]\n ${completion} Completion Create\n ... Write a tagline for an ice cream shop\n ... temperature=0.6\n Log ${completion}\n\n
Python example usage
\n\nfrom RPA.Robocorp.Vault import Vault\nfrom RPA.OpenAI import OpenAI\n\nsecrets = Vault().get_secret("OpenAI")\nbaselib = OpenAI()\nbaselib.authorize_to_openai(secrets["key"])\n\nresult = baselib.completion_create(\n Create a tagline for icecream shop',\n temperature=0.6,\n)\nprint(result)\n\n
Outlook.Application is a library for controlling the Outlook application.
\nAbout Email Filtering
\nEmails can be filtered according to specification set by Restrict method of the\nItem class https://docs.microsoft.com/en-us/office/vba/api/outlook.items.restrict.
\nCouple of examples:
\n\nGet Emails\n... email_filter=[Subject]='test email'\n\nMove Emails\n... email_filter=[SenderEmailAddress]='hello@gmail.com'\n\n
Examples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.Outlook.Application\nTask Setup Open Application\nSuite Teardown Quit Application\n\n*** Variables ***\n${RECIPIENT} address@domain.com\n\n*** Tasks ***\nSend email\n Send Email recipients=${RECIPIENT}\n ... subject=This is the subject\n ... body=This is the message body\n .. attachments=approved.png\n\n
Python
\n\nfrom RPA.Outlook.Application import Application\n\ndef send_email():\n app = Application()\n app.open_application()\n app.send_email(\n recipients='EMAILADDRESS_1, EMAILADDRESS_2',\n subject='email subject',\n body='email body message',\n attachments='../orders.csv'\n\n
For more information, see: https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2007/bb219950(v=office.12)
\nCaveats
\nThis library works on a Windows operating system with UI enabled only, and you must\nensure that you open the app first with Open Application before running any\nother relevant keyword which requires to operate on an open app. The application is\nautomatically closed at the end of the task execution, so this can be changed by\nimporting the library with the autoexit=${False} setting.
\n\n*** Settings ***\nLibrary RPA.Excel|Outlook|Word.Application autoexit=${False}\n\n
If you're running the Process by Control Room through a custom self-hosted Worker\nservice, then please make sure that you enable an RDP session by ticking "Use\nDesktop Connection" under the Step configuration.
\nIf you still encounter issues with opening a document, please ensure that file can\nbe opened first manually and dismiss any alert potentially blocking the process.
\nCheck the documentation below for more info:
\n\nPDF is a library for managing PDF documents.
\nIt can be used to extract text from PDFs, add watermarks to pages, and\ndecrypt/encrypt documents.
\nMerging and splitting PDFs is supported by Add Files To PDF keyword. Read\nthe keyword documentation for examples.
\nThere is also limited support for updating form field values. (check\nSet Field Value and Save Field Values for more info)
\nThe input PDF file can be passed as an argument to the keywords, or it can be\nomitted if you first call Open PDF. A reference to the current active PDF will\nbe stored in the library instance and can be changed by using the Switch To PDF\nkeyword with another PDF file path, therefore you can asynchronously work with\nmultiple PDFs.
\nAttention!
\nKeep in mind that this library works with text-based PDFs, and it can't\nextract information from an image-based (scan) PDF file. For accurate\nresults, you have to use specialized external services wrapped by the\nRPA.DocumentAI library.
\nPortal example with video recording demo for parsing PDF invoices:\nhttps://github.com/robocorp/example-parse-pdf-invoice
\nExamples
\nRobot Framework
\n\n*** Settings ***\nLibrary RPA.PDF\nLibrary String\n\n*** Tasks ***\nExtract Data From First Page\n ${text} = Get Text From PDF report.pdf\n ${lines} = Get Lines Matching Regexp ${text}[${1}] .+pain.+\n Log ${lines}\n\nGet Invoice Number\n Open Pdf invoice.pdf\n ${matches} = Find Text Invoice Number\n Log List ${matches}\n\nFill Form Fields\n Switch To Pdf form.pdf\n ${fields} = Get Input Fields encoding=utf-16\n Log Dictionary ${fields}\n Set Field Value Given Name Text Box Mark\n Save Field Values output_path=${OUTPUT_DIR}${/}completed-form.pdf\n ... use_appearances_writer=${True}\n\n
\nfrom RPA.PDF import PDF\nfrom robot.libraries.String import String\n\npdf = PDF()\nstring = String()\n\ndef extract_data_from_first_page():\n text = pdf.get_text_from_pdf("report.pdf")\n lines = string.get_lines_matching_regexp(text[1], ".+pain.+")\n print(lines)\n\ndef get_invoice_number():\n pdf.open_pdf("invoice.pdf")\n matches = pdf.find_text("Invoice Number")\n for match in matches:\n print(match)\n\ndef fill_form_fields():\n pdf.switch_to_pdf("form.pdf")\n fields = pdf.get_input_fields(encoding="utf-16")\n for key, value in fields.items():\n print(f"{key}: {value}")\n pdf.set_field_value("Given Name Text Box", "Mark")\n pdf.save_field_values(\n output_path="completed-form.pdf",\n use_appearances_writer=True\n )\n\n
A library for interacting with Control Room work items.
\nWork items are used for managing data that go through multiple\nsteps and tasks inside a process. Each step of a process receives\ninput work items from the previous step, and creates output work items for\nthe next step.
\nItem structure
\nA work item's data payload is JSON and allows storing anything that is\nserializable. This library by default interacts with payloads that\nare a dictionary of key-value pairs, which it treats as individual\nvariables. These variables can be exposed to the Robot Framework task\nto be used directly.
\nIn addition to the data section, a work item can also contain files,\nwhich are stored by default in Robocorp Control Room. Adding and using\nfiles with work items requires no additional setup from the user.
\nLoading inputs
\nThe library automatically loads the first input work item, if the\nlibrary input argument autoload is truthy (default).
\nAfter an input has been loaded its payload and files can be accessed\nthrough corresponding keywords, and optionally these values can be modified.
\nE-mail triggering
\nSince a process can be started in Control Room by sending an e-mail, a body\nin Text/JSON/YAML/HTML format can be sent as well and this gets attached to the\ninput work item with the rawEmail payload variable. This library automatically\nparses the content of it and saves into parsedEmail the dictionary\ntransformation of the original e-mail.
\nIf "Parse email" Control Room configuration option is enabled (recommended), then\nyour e-mail is automatically parsed in the work item under the email payload\nvariable, which is a dictionary containing a body holding the final parsed form\nof the interpreted e-mail body. The payload variable parsedEmail is still\navailable for backwards compatibility reasons and holds the very same body inside\nthe parsedEmail[Body].
\nE-mail attachments will be added into the work item as files. Read more on:\nhttps://robocorp.com/docs/control-room/attended-or-unattended/email-trigger
\nExample:
\nAfter starting the process by sending an e-mail with a body like:
\n\n{\n "message": "Hello world!"\n}\n\n
The robot can use the parsed e-mail body's dictionary:
\n\n*** Tasks ***\nUsing Parsed Emails\n ${mail} = Get Work Item Variable email\n Set Work Item Variables &{mail}[body]\n ${message} = Get Work Item Variable message\n Log ${message} # will print "Hello world!"\n\n
The behaviour can be disabled by loading the library with\nauto_parse_email=${None} or altered by providing to it a dictionary with one\n"key: value" where the key is usually "email.text" (deprecated "rawEmail", the\nvariable set by Control Room, which acts as source for the parsed (deprecated raw)\ne-mail data) and the value can be "email.body" (deprecated "parsedEmail", where the\nparsed e-mail data gets stored into), value which can be customized and retrieved\nwith Get Work Item Variable.
\nCreating outputs
\nIt's possible to create multiple new work items as an output from a\ntask. With the keyword Create Output Work Item a new empty item\nis created as a child for the currently loaded input.
\nAll created output items are sent into the input queue of the next\nstep in the process.
\nActive work item
\nKeywords that read or write from a work item always operate on the currently\nactive work item. Usually that is the input item that has been automatically\nloaded when the execution started, but the currently active item is changed\nwhenever the keywords Create Output Work Item or Get Input Work Item\nare called. It's also possible to change the active item manually with the\nkeyword Set current work item.
\nSaving changes
\nWhile a work item is loaded automatically when a suite starts, changes are\nnot automatically reflected back to the source. The work item will be modified\nlocally and then saved when the keyword Save Work Item is called.\nThis also applies to created output work items.
\nIt is recommended to defer saves until all changes have been made to prevent\nleaving work items in a half-modified state in case of failures.
\nLocal Development
\nWhile Control Room is the default implementation, it can also be replaced\nwith a custom adapter. The selection is based on either the default_adapter\nargument for the library, or the RPA_WORKITEMS_ADAPTER environment\nvariable. The library has a built-in alternative adapter called FileAdapter for\nstoring work items to disk.
\nThe FileAdapter uses a local JSON file for input work items.\nIt's a list of work items, each of which has a data payload and files.
\nAn example of a local file with one work item:
\n\n[\n {\n "payload": {\n "variable1": "a-string-value",\n "variable2": ["a", "list", "value"]\n },\n "files": {\n "file1": "path/to/file.ext"\n }\n }\n]\n\n
Output work items (if any) are saved to an adjacent file\nwith the same name, but with the extension .output.json. You can specify\nthrough the "RPA_OUTPUT_WORKITEM_PATH" env var a different path and name for this\nfile.
\nSimulating the Cloud with Robocorp Code VSCode Extension
\nIf you are developing in VSCode with the Robocorp Code extension, you can\nutilize the built in local development features described in the\nDeveloping with work items locally section of the\nUsing work items development guide.
\nExamples
\nRobot Framework
\nIn the following example a task creates an output work item,\nand attaches some variables to it.
\n\n*** Settings ***\nLibrary RPA.Robocorp.WorkItems\n\n*** Tasks ***\nSave variables to Control Room\n Create Output Work Item\n Set work item variables user=Dude mail=address@company.com\n Save Work Item\n\n
In the next step of the process inside a different robot, we can use\npreviously saved work item variables. Also note how the input work item is\nloaded implicitly when the suite starts.
\n\n*** Settings ***\nLibrary RPA.Robocorp.WorkItems\n\n*** Tasks ***\nUse variables from Control Room\n Set task variables from work item\n Log Variables are now available: s${user}, ${mail}\n\n
Python
\nThe library can also be used through Python, but it does not implicitly\nload the first work item.
\n\nimport logging\nfrom RPA.Robocorp.WorkItems import WorkItems\n\ndef list_variables(item_id):\n library = WorkItems()\n library.get_input_work_item()\n\n variables = library.get_work_item_variables()\n for variable, value in variables.items():\n logging.info("%s = %s", variable, value)\n\n