Apiritif

Allows to run load and functional Python tests using Apiritif test framework, which is based on Nose library. You can run Nose tests the following way:

execution:
- executor: apiritif
  scenario:
    script: test_nose.py

Also, if not present, Taurus creates and stores Nose test to the artifacts directory, when Apiritif executor is used.

Taurus can loop test suite execution in a loop until desired number of iterations will complete or hold-for time will be exceeded.

Usage:

execution:
- executor: apiritif
  scenario:
    script: tests/

It allows you to use some logic blocks:

  • transactions: collect requests in one block
  • set-variables: set/change value of variable
  • include-scenario: include scenario into another one

and CSV data sources. Use following format to specify them:

scenarios:
  sample:
    variables:
      var1: val1
    requests:
    - http://blazedemo.com     # ordinal request
    - transaction: second   # transaction
      do:
      - http://blazedemo.com/send
      - http://blazedemo.com/receive/${var1} # get 'receive/val2'
      - set-variables:  # change variable value
          var1: val2
      - http://blazedemo.com/receive/${var1} # get 'receive/val2'
    - include-scenario: inner

    data-sources: # these are data-sources options for Apiritif. See more info below.
    - path/to/my.csv  # this is a shorthand form
    - path: path/to/another.csv  # this is a full form
      delimiter: ';'
      quoted: false
      loop: true
      variable-names: id,name

  inner:
    requests:
    - set-variables:
        var1: val3
    - http://blazedemo.com/receive/${var1}

See more info about data-sources here.

It is valid to specify both single Python module (single .py file) and a Python package (folder with Python modules and packages).

Configuration options:

modules:
  apiritif:
    working-dir: classes  # set name of runner working directory within artifacts dir
    interpreter: /home/user/interpreter/python  # path to custom interpreter.

Scenario

Apiritif executor supports building test script from the requests option of scenario. In that case Taurus will generate a Python script that will be launched with apiritif.

With Apiritif executor you can ask for Selenium browser test with test-mode option:

execution:
- executor: apiritif
  test-mode: selenium

In selenium mode follow request features are supported:

  • browser for the following browser types: Chrome, Firefox, Ie, Opera, Android-Chrome, iOS-Safari, Remote
  • remote for local webdriver, local remote webdriver or remote webdriver
  • capabilities of remote webdriver: browser, version, javascript, platform, os_version, selenium, device, app
  • request only for GET method
    • action keyword for Selenium actions
    • assert (requested page source inspected use the new assertTitle, assertTextBy or assertValueBy* for item level)
  • timeout and think-time on both scenario and request levels

Here is the list of supported actions, sorted by action type.

Locators

Below you will see some actions, which look like this: actionX, i.e. dragByX, clickBy, etc. Here X means a certain action object. It can be one of the following: ID, Name, LinkText, CSS, XPath. For example, clickByID, waitByName, keysByCSS.

How to find them

1. By ID

<td>
    <h1 id="my_locator_ID">Locator ID</h1>
</td>

Header tag has an ID attribute (id="Locator_ID"). For example, wait until the element is displayed waitByID(Locator_ID).

2. By the attribute Name

<input name="inputName">

This is an input element and it has attribute name="inputName".

For example, insert text the following in the input keysByName(inputName): First_Name. Locator determination by the attribute Name is often used when working with input fields.

3. By CSS Selector

CSS is used for styling different elements of an HTML webpage, to separate the content of the page and its design. The .css files define these styles, set font size, width, height, etc. There are certain patterns in the CSS, which act as selectors and are applied to HTML elements of the page. Selenium uses the same principle to find items.

Here is an example. This is how to find div with input.

<div class="controls">
    <input id="inputName" placeholder="First Last" name="inputName" type="text">
</div>

This CSS selector .controls will select all elements with class controls. For example, wait until the element is displayed waitByCSS(.controls). Using attributes and their value

 <input id="inputName" placeholder="First Last" name="inputName" type="text">

Find the element by name="inputName". For example, keysByCSS(#inputName): First Name

4. Using ID

Find the field for input name with id="inputName"

<input id="inputName" placeholder="First Last" name="inputName" type="text">

CSS selector - #inputName. Fox example, add text in the field keysByCSS(#inputName): first_name

5. Child elements

<div class="controls">
    <input id="inputName" placeholder="First Last" name="inputName" type="text">
</div>

Find child element INPUT with id="inputName" in the div with class="controls". Describe as div.controls>input#inputName. For example, keysByCSS(div.controls>input#inputName): first_name

6. By XPath

XPath is the language used for locating nodes in an XML document. As HTML can be an implementation of XML (XHTML), Selenium can use this language to find elements for the web page. One of the main reasons for using XPath is when you don't have a suitable id or name attribute for the element you wish to locate. To locate the element we can use absolute XPath or use relative path elements that have attributes id, name etc.

For INPUT

<div class="controls">
    <input placeholder="First Last" type="text">
</div>

We can compose following XPath expressions:

  • //div/input
  • //div[@class="controls"]/input

Any of these expressions can be used to fetch the desired element, if these attributes are unique.

7. By Shadow Locator

Shadow Locator enables to work with Shadow DOM which is designed as a tool for building component-based applications. For example Salesforce Lightning Component Library is based on Shadow DOM. Shadow DOM is self-contained and thus simple locators will not return nodes inside it.

Shadow Locator is composed by a sequence of css selectors, e.g.:

shadow: c-basic, lightning-accordion-section, .slds-button

The last CSS Selector refers to the target element in a shadow tree. The preceding CSS Selectors refer to the shadow hosts.

Most of the actions in Apiritif support Shadow Locators.

Alternative syntax supporting multiple locators

It is possible to specify multiple locators for each action. This helps to increase script resiliency. If a locator fails (e.g. because of a webpage change and the script was not updated to reflect the changes) an alternative locator will be used. If no locator succeeds then the script fails. All the locators above are supported, i.e. ID, Name, LinkText, CSS, XPath.

This is an example how it looks like:

  - type: select  # action name
    param: American Express # parameter for the select action
    locators:     # list of locators for the action, these are attempted one by one from top to bottom
      - id: select_id           # locator types are case insensitive
      - css: another_class    
      - xpath: absolute_xpath
      - xpath: relative_xpath   # there may be multiple locators of the same type
      - name: select_name

You can see full example here.

If Blocks

Apiritif allows to control execution flow using if blocks. These blocks enable conditional execution of actions.

Each if block should contain a mandatory then field, and an optional else field. Both then and else fields should contain list of actions.

Here's a simple example:

scenarios:
  example:
    browser: Chrome
    variables:
      elem_id: id_123
    timeout: 10s
    requests:
      - label: example1
        actions:
          - go(http://blazedemo.com)
          - if: 'document.getElementById("${elem_id}") !== undefined'
            then:
              - clickById(${elem_id})
            else:
              - go(http://blazedemo.com/login)

Logic blocks can also be nested:

scenarios:
  nested_example:
    requests:
      - label: nested_req
        actions:
          - if: <condition1>
            then:
              - if: <condition2>
                then:
                  - go(https://google.com/)
                else:
                  - go(https://yahoo.com/)
            else:
              - go(https://bing.com/)

Note that <conditions> are evaluated as JavaScript code so they must contain valid JavaScript expression that yields boolean value.

Loops

Loop blocks allow repeated execution of actions.

It is necessary to specify variable name used in the loop, along with the start and end indexes. The actions that shall be executed in the loop are defined in the do field. In these action you can then reference the variable by the name you defined next to the loop keyword.

Optionally you can set the step field which defines the difference between each number in the sequence (it can also be negative). If step is not explicitly set then it will default to 1.

scenarios:
  example:
    browser: Chrome
    timeout: 10s
    requests:
      - label: example_loop
        actions:
          - go(http://blazedemo.com)
          - loop: var_i
            start: 1
            end: 10
            do:
              - clickById(id_${var_i})
              - typeById(input_${var_i}): My Item ${var_i} 

Note that both the start and end index are included in the loop. So for example setting start to 1 and end to 5 will loop through these values: [1, 2, 3, 4, 5\].

It is also possible to specify the step negative. In that case the loop will go from the higher numbers to the lower ones. However it is also necessary that the start index is higher than the end index.

For example:

  - loop: i
    start: 5
    end: 1
    step: -1
    do: 
      - clickById(id_${i})

This will loop through the values [5, 4, 3, 2, 1\] in the descending order.

Note that you may also use variables in the start, end and step fields. These fields may include numbers surrounded by quotes and one can even concatenate in this case numbers with variables.

For example:

scenarios:
  example:
    browser: Chrome
    timeout: 10s
    variables:
      step: 1
      end: '00'
    requests:
      - label: example_loop
        actions:
          - go(http://blazedemo.com)
          - loop: i
            start: '1'
            end: '1${end}' # will result in 100
            step: ${step}
            do: 
              - clickById(id_${i}) 

Foreach

foreach blocks allow to iterate over each element on a page that matches the specified locators.

For example:

scenarios:
  example:
    browser: Chrome
    timeout: 10s
    requests:
      - label: example_foreach_1
        actions:
          - go(http://blazedemo.com)
          - foreach: el             # specify the name of the variable that will be used in the actions referring that element
            locators:
              - css: input
              - xpath: //input
            do:
              - clickByElement(el)  # refers to the variable el 
              - typeByElement(el): text to type
              - type: storeValue
                element: el         # refers to the variable el
                param: my_var
 

locators is an array of selectors equivalent to those used in alternative syntax notation. The locators also work the same way - the selectors in the array are examined one by one and which first returns a not empty set of elements is used then for the iteration.

To refer to the given element in the current iteration you need to use either the suffix ByElement for the short version of actions notation or element for the alternative version. This way explicit locators (e.g. ById, ByXpath) are replaced by reference to the variable you define in the foreach loop. You however can still use the explicit locators combined with the ByElement actions in the loop. See the example below.

scenarios:
  example:
    browser: Chrome
    timeout: 10s
    requests:
      - label: example_foreach_2
        actions:
          - go(http://blazedemo.com)
          - foreach: el             # specify the name of the variable that will be used in the actions referring that element
            locators:
              - css: input
              - xpath: //input
            do:
              - clickByElement(el)  # refers to the variable el 
              - dragByElement(el): elementById(id_123)
              - keysById(btn_submit): KEY_ENTER

You can also nest multiple foreach blocks, just make sure to use unique names for the variables in each of the blocks.

Please note that it is not possible to use wait and waitFor actions in the foreach using ByElement. However you can still use it inside the loop the common way - e.g. `waitById(my_id)`.

Perform actions in foreach using the parent context

It is possible to specify in each action inside the foreach loop additional set of locators besides just the element field. This way it allows to locate a child element within the parent element.

In the following example we iterate over table rows and do a click action on the button that should be located on each row.

scenarios:
  example:
    browser: Chrome
    timeout: 10s
    requests:
      - label: example_foreach_context
        actions:
          - go(http://blazedemo.com)
          - foreach: el             
            locators:
              - css: table_row
              - xpath: //tr
            do:
              - type: click
                element: el
                locators:         # the list of locators that to find the child element in the parent 'el'
                  - css: .btn-small
                  - css: .button-small

Note that this is only supported while using the alternative syntax for the action.

Alert

For alert handling, use the following methods:

  • alert("OK") to click "OK" on an alert
  • alert("Dismiss") to dismiss alert

Besides, you can use alternative syntax:

- type: alert
  param: OK

For additional operations with dialogs see Dialogs management.

Assertion

For requested page source inspection you can use the following actions:

  • assertTextByX(X_name): "text" to assert text to an element
  • assertValueByX(X_name): value to assert value
  • assertTitle(title) to assert page title
  • `assertEval(js_expr)` to assert that evaluation of a JavaScript expression returns true value

Don't forget to replace X with the right locators. See sample usage in Frame Management section.

For assertion you can also use special assertion block. See example here.

Using the alternative syntax:

- type: assertText
  param: text
  locators:
    - id: element_id
    - xpath: /xpath
- type: assertValue
  param: value
  locators:
    - id: element_id
- type: assertTitle
  param: title
- type: assertEval
  param: js_expr

Cookies

To delete all cookies use clearCookies() action.

The same can be written like this:

- type: clearCookies

Dialogs management

Besides the basic functionality to handle Alerts it is also possible to use the following actions to do assertion and answering on Dialogs.

Assertions

Enables to check whether a dialog of a specified type was previously displayed with the given message. The type can be any of the following: alert, prompt or confirm.

Examples:

- assertDialog(alert): Error occurred
- assertDialog(prompt): Enter your name
- assertDialog(confirm): Are you sure to proceed?

Example using the Alternative syntax:

- type: assertDialog
  param: alert
  value: Error occurred

Answering dialogs

Allows to set the value that will be returned by displaying a dialog. It is applicable to alert, prompt and confirm dialogs. This action actually prevents showing the dialog and instead returns the specified value directly.

For alert dialogs the value needs to be always '#Ok' for dismissing the dialog. For confirmation dialogs the value can only be either '#Ok' or '#Cancel', meaning to simulate click on 'Ok' or 'Cancel' buttons.

Examples:

- answerDialog(alert): '#Ok'
- answerDialog(prompt): John Doe
- answerDialog(confirm): '#Cancel'

Examples using the alternative syntax:

- type: answerDialog
  param: alert
  value: '#Ok'
- type: answerDialog
  param: prompt
  value: Jon Doe
- type: answerDialog
  param: confirm
  value: '#Cancel'

Echoing

Use echoString("echoed text") to print text string on the Apiritif output execution.

Or you may use:

- type: echoString
  param: echoed text

Editing

editContentByX(X_name): "new test for X" will help you change text in an editable field.

Or by using the alternative syntax:

- type: editContent
  param: new text for X
  locators:
    - css: element_class

Execution

For execution of a non-yaml code you can use the following options:

  • scriptEval("script") to execute JS command like this
scriptEval("alert('This is a JavaScript command.');")

Which can be written also like:

- type: scriptEval
  param: alert('This is a JavaScript command.')
  • rawCode: Python code to insert python code as it is.
rawCode: print('This is a python command.')
- type: rawCode
  param: print('This is a python command.')

See example here.

Frame management

When you need to perform actions on elements that are inside a frame or iframe, you must use the switchFrame command to activate the frame before perform any action.

Sample usage:

scenarios:
  sample_frame:
    requests:
    - url: http://a-frame-sample.com
      actions:
      - switchFrame(index=0) # Select First Frame
      - assertTextByCSS(body): "First Frame Body"
      - switchFrame(relative=parent) # Go to parent
      - switchFrame(index=1) # Select Second frame
      - switchFrame(index=0) # Nested Frame, Select the First frame inside the Top Second frame
      - assertTextByID(content): "First Frame Body inside Second Frame Body"
      - switchFrame(relative=top) # Go to top frame (main document)

Note: For first level frames, it is possible to use switchFrameByX and using selector to match the frame to switch.

Disclaimer: Currently there are problems in the support of this functionality by geckodriver and chromedriver, depending on the case to test some of these methods can generate a failure, mainly in cases where you have nested frames or frames mixed between frame and iframes.

It is also possible to use the alternative syntax for Frame management, however there is currently no support for multiple locators:

- type: switchFrame
  param: index=0
- type: switchFrame
  param: relative=parent
- type: switchFrameByName
  param: frame_name

Go

Use go(url) to redirect to another website.

- type: go
  param: url

Mouse actions

For mouse imitating actions you can use the following:

  • clickByX(X_name)
  • doubleClickByX(X_name)
  • mouseDownByX(X_name)
  • mouseUpByX(X_name)
  • mouseOutByX(X_name)
  • mouseOverByX(X_name)
  • dragByX(X_name): elementByX(another_X_name)

X here is for one of locators.

Or by using the multiple locators syntax:

- type: click
  locators:
     - css: element_class
     - xpath: /xpath/
- type: doubleClick
  locators:
     - css: element_class
     - xpath: /xpath/
- type: mouseDown
  locators:
     - css: element_class
     - xpath: /xpath/
- type: mouseUp
  locators:
     - css: element_class
     - xpath: /xpath/
- type: mouseOut
  locators:
     - css: element_class
     - xpath: /xpath/
- type: mouseOver
  locators:
     - css: element_class
     - xpath: /xpath/
- type: drag
  source:
    - name: element_name
    - xpath: /xpath/
  target:
    - css: element_css
    - xpath: /xpath/

Pause

For pause you can use the following actions:

  • waitForByX(X_name, condition): timeout

This action allows for checking that the given object meets the condition within the timeout period.

condition is one of the following:

  • Present
  • Visible
  • Clickable
  • NotPresent
  • NotVisible
  • NotClickable

timeout is optional with default value of 10 (10 seconds). Timeout can be provided as a numeric value and that will mean seconds or it can be provided as a formatted string with the pattern 1d2h3m4s5ms where you can provide number of days, hours, minutes, seconds and milliseconds it’s required to wait.

You can also define waitFor using the alternative syntax to provide multiple locators:

- type: waitFor
  locators: 
    - css: element_class
    - id: element_id
  param: Clickable    # the condition
  value: 2m30s        # the timeout    
  • waitByX(X_name) to wait for presence or waitByX(X_name): visible to wait for visibility
  • *DEPRECATION WARNING** waitByX is deprecated and will be removed soon, please use the waitForByX version above.

You can also define wait using the alternative syntax to provide multiple locators:

- type: wait
  locators: 
    - css: element_class
    - id: element_id
- type: wait
  param: visible
  locators:
    - css: element_class    
  • pauseFor(time)
- type: pauseFor
  param: time

X here is for one of locators.

Screenshot

To take a screenshot of a viewport and save it in a file use this: screenshot(file_name)

Or like this by using the alternative syntax:

- type: screenshot
  param: file_name

Select

To select a value use this: selectByX(X_name): value.

See documentation for X here.

Or by using the alternative syntax:

- type: select
  param: value
  locators:
    - id: element_id

Store

For storing variables use the following actions:

  • `storeTitle(): var_title`
  • `storeString(value): "var_string"`
  • `storeTextByX(X_name): "var_text"`
  • `storeValueByX(X_name): var_value`

See documentation for X here.

For storing the result of evaluation of a JavaScript expression use:

  • storeEval(jsexpr): vareval

The following example will store to the `el_present` variable a flag indicating whether the find element by id was successful or not:

  • storeEval(document.getElementById("elemid") !== undefined): elpresent

Or use the alternative syntax:

- type: storeTitle
  param: var_title
- type: storeString
  param: var_string
  value: value
- type: storeText
  param: var_text
  locators:
    - id: element_id  
- type: storeValue
  param: var_value
  locators:
    - id: element_id
- type: storeEval
  param: var_eval
  value: js_expr

Typing

Typing actions are the following:

  • typeByX(X_name): "text_to_type" clears X value and then types text.
  • submitByX(X_name)
  • keysByX(X_name): value sends keystrokes to X. value can be formed like this: KEY_ENTER. See docs for it here.

X here is for one of locators.

Typing actions with multiple locators support:

- type: type
  param: text_to_type
  locators:
    - css: input_css
    - name: input_name
- type: submit
  locators:
    - id: element_id
- type: keys
  param: KEY_ENTER
  locators:
    - id: element_id  

Window management

To manage windows or tabs, the switchWindow(value) and closeWindow(value) commands will allow you to manage them.

These actions require a value parameter, the possible values are:

  • number: The index to the window in reference, 0 is the first, 1 is the second, and so with those who want to manage. It can be also surrounded with quotes.
  • win_ser_number: Provides exactly the same functionality just like using only number - e.g. you can use win_ser_0 to navigate to the first window
  • name: The name of the window (reference to the name used in the target window attribute in a link).
  • win_ser_name: In the name part, assign a name to the focused opened window, the next time when reference to the same window name, returns with focus to the named window selected.
  • win_ser_local: Go to the initial window.
  • no value: When no value is assigned, it means that the selection action is assigned over the last created window, and if the close action is used, it will also be over the last one created.

Note: When any action command opens a new window (like click on a link with target window assigned), the action of selecting the window must always be declared, otherwise the actions executed by the execution will be performed on the default window or the last one used with switchWindow command.

Or using the alternative syntax:

- type: switchWindow
  param: value
- type: closeWindow
  param: value

Sample scenario

scenarios:
  request_example:
    browser: Firefox  # available browsers are: ["Firefox", "Chrome", "Ie", "Opera"]
    headless: true  # available only for Chrome/Firefox and only on Selenium 3.8.0+, disabled by default
    timeout: 10  #  global scenario timeout for connecting, receiving results, 30 seconds by default
    think-time: 1s500ms  # global scenario delay between each request
    default-address: http://blazedemo.com/  # specify a base address, so you can use short urls in requests
    requests:
    - url: /  # url to open, only get method is supported
      actions:  # holds list of actions to perform
      - waitByCSS(body)
      - clickByID(mySubmitButton)
      - openWindow(http://blazedemo.com/vacation.html) # new window is created (#1)
      - switchWindow(1)     # switch to the second window (#0)
      - resizeWindow(750, 750) # change window size to x, y
      - maximizeWindow() # change window size to maximum
      - closeWindow()      # close the second window (#1)
      - pauseFor(5s)
      - clearCookies()
      - keysByName(myInputName): keys_to_type
      - submitByName(myInputName)
      - waitByID(myObjectToAppear): visible
      - scriptEval("alert('This is Sparta');")
      - rawCode: print('It\'s Python')  # insert as-is into script file
      - rawCode: |
          for i in range(10):           # multiline example
            if i % 2 == 0:
              print(i)
      - clickByShadow(c-basic,form-opened,#mytext)   # sample usage of shadow locator
      assert: # assert executed after actions
      - contains:
        - blazemeter  # list of search patterns
        - Trusted
        subject: body # only body subject supported
        regexp: false  # treat string as regular expression
        not: false  # inverse assertion condition

All action names are case insensitive. Despite it misprint in action names or usage of unsupported actions break your scenario execution. To avoid it you can use ignore-unknown-actions Apiritif flag and taurus will show warning when unknown action occurs.

scenarios:
  sample:
    requests:
    - url: http://blazedemo.com
      actions:
      - definitelyUnknownAction(unknownSelector)
modules:
  apiritif:
    ignore-unknown-actions: True
 

Sample scenario using multiple locators

When using multiple locators alternative syntax it is possible to mix it with the shorter version of action definition.

scenarios:
  request_example:
    browser: Firefox  # available browsers are: ["Firefox", "Chrome", "Ie", "Opera"]
    headless: true  # available only for Chrome/Firefox and only on Selenium 3.8.0+, disabled by default
    timeout: 10  #  global scenario timeout for connecting, receiving results, 30 seconds by default
    think-time: 1s500ms  # global scenario delay between each request
    default-address: http://blazedemo.com/  # specify a base address, so you can use short urls in requests
    requests:
    - url: /  # url to open, only get method is supported
      actions:  # holds list of actions to perform
      - type: wait
        locators:
          - css: body
          - xpath: /body/
      - type: click
        locators:
          - id: mySubmitButton
          - linktext: Submit Form
          - css: btn_primary
      - openWindow(http://blazedemo.com/vacation.html)
      - clearCookies()
      - type: keys
        param: keys_to_type
        locators:
          - name: myInputName
      - type: submit
        locators:
          - name: myInputName
      - type: wait
        param: visible
        locators:
          - id: myObjectToAppear
          - name: myObjectToAppearName
      - scriptEval("alert('This is Sparta');")
      - type: rawCode
        param: print('It\'s Python')  # insert as-is into script file
      - type: click   # sample usage of shadow locator
        shadow: 'c-basic, form-opened, #mytext'
      assert: # assert executed after actions
      - contains:
        - blazemeter  # list of search patterns
        - Trusted
        subject: body # only body subject supported
        regexp: false  # treat string as regular expression
        not: false  # inverse assertion condition

Variables

It is possible to define variables to be used in the script, declaring them at the scenario level.

To use it, simply in any reference to a text in the script you must declare the insertion of the variable by using ${name}

The use of variables can be used in many reference locations, in selectors or in values. There are also commands that allow you to store and manipulate them. Some of them are storeTitle, storeTextBy *, storeValueBy * and storeString.

Sample:

scenario:
  sample:
    variables:
        sample: The is a sample site you can test with BlazeMeter!
    requests:
    - url: http://blazedemo.com/
      actions:
      - assertTextByCSS(body > div.jumbotron > div > p:nth-child(2)): ${sample}
      - storeTitle(): my_title
      - storeTextByXPath(//my/XPath/here): my_text
      - storeValueByXPath(//my/XPath/here): my_value
      - storeString(${my_title} love my ${my_text} with ${my_value}): final_text

Remote WebDriver

It is possible to use the browser remotely using Remote WebDriver. It must be indicated as the browser name Remote and indicate in the remote property the URL in which the webdriver service is located to control the browser.

To specify the capabilities of the Remote WebDriver, it is necessary to be able to configure properties necessary for remote instantiation. You must use the capabilities structure where you can specify the main properties required by the remote webdriver.

Note: The capabilities are a way in which the remote service filters and selects the device or browser to be selected for the test, depending on its configuration according to the configured specifications. It is recommended to read the documentation of who provides the service

Commonly used capabilities

  • browser
  • version
  • platform
  • device # Id of the device (Mobile browser)
  • os_version # commonly used only for mobile

Note: Currently it is possible to perform basic tests in mobile browsers using the available actions commands, in the future more commands related to mobile will be incorporated to allow a better interactivity.

Sample Remote Webdriver scenario:

scenarios:
  request_example:
    browser: Remote
    remote: http://user:key@remote_web_driver_host:port/wd/hub
    capabilities:
      browser: firefox  # Depends on the capabilities of the remote selenium server
      version: "54.0"
    requests:
    - url: http://demo.blazemeter.com  # url to open, only get method is supported
      actions:  # holds list of actions to perform
      - waitByCSS(body)
    # ...

It is possible to use only the remote option, and in this way declare the intention to use the browser: Remote, allowing a more compact YAML.

Sample usage of remote without browser: Remote clause declaration:

scenarios:
  request_example:
    remote: http://user:key@remote_web_driver_host:port/wd/hub
    capabilities:
      browser: firefox  # Depends on the capabilities of the remote selenium server
      version: "54.0"
    requests:
    - url: http://demo.blazemeter.com  # url to open, only get method is supported
      actions:  # holds list of actions to perform
      - waitByCSS(body)
    # ...

Note that remote keyword can be used on module settings, execution settings, or scenario level.

Mobile Browsers

It is also possible to perform tests on mobile browsers. Currently the browsers supported are Chrome-Android and Safari-iOS. Mobile test services are provided by Appium, and it is possible to use Appium locally or some remote Appium service through the Remote WebDriver capability.

Note: Taurus provides the ability to provide Appium provisioning support, it is recommended to read the documentation related to Selenium Executor / Appium

Sample Mobile Browser scenario:

scenarios:
  request_example:
    browser: Chrome-Android
    capabilities:
      device: id_device # set the id of the device here (adb devices)
      remote: custom_appium_url # You can specify a custom url
    timeout: 10  #  global scenario timeout for connecting, receiving results, 30 seconds by default
    think-time: 1s500ms  # global scenario delay between each request
    default-address: http://demo.blazemeter.com  # specify a base address, so you can use short urls in requests
    requests:
    - url: /  # url to open, only get method is supported
      actions:  # holds list of actions to perform
      - waitByCSS(body)
      - clickByID(mySubmitButton)
      - pauseFor(5s)
      - clearCookies()
      - keysByName(myInputName): keys_to_type
      - waitByID(myObjectToAppear): visible
      assert: # assert executed after actions
      - contains:
        - blazemeter  # list of search patterns
        - Trusted
        subject: body # only body subject supported
        regexp: false  # treat string as regular expression
        not: false  # inverse assertion condition

services:
- appium
- android-emulator

modules:
  android-emulator:
    avd: android10_arm128

Reporting

It is recommended to incorporate the use of the final-stats module with the option enabled summary-labels to have a better vision of results. It will allow to visualize the status of the tests, the average time per transaction and to visualize the errors that may occur in webdriver and other components involved in the test.

Sample configuration:

reporting:
- module: final-stats
  summary-labels: true

Sample output:

+-----------------+--------+---------+----------+-------+
| label           | status | success | avg time | error |
+-----------------+--------+---------+----------+-------+
| Find Flights    |   OK   | 100.00% |  10.581  |       |
| Reserve Flight  |   OK   | 100.00% |  1.276   |       |
| Purchase Flight |   OK   | 100.00% |  4.951   |       |
| Thanks          |   OK   | 100.00% |  0.062   |       |
+-----------------+--------+---------+----------+-------+

Flow Markers

Functional test execution in the cloud requires additional metadata about the tests, which can be provided by flow markers. Flow markers are little pieces of code added by the Taurus to the test script that provide more data for the test execution engine. Generating flow markers is disabled by default and enabled only for browser: Remote.

You can enable/disable it manually with generate-flow-markers option. It can be used on both scenario-level and settings-level.

scenarios:
  request_example:
    browser: Chrome
    generate-flow-markers: true  # scenario-specific setting
    requests:
    - url: http://blazedemo.com/
      actions:
      - waitByCSS(body)
      - clickByID(mySubmitButton)
      - pauseFor(5s)

modules:
  apiritif:
    generate-flow-markers: true  # global setting