Skip to main content

Framework to build UI test automation in Page Transactions pattern

Project description

Guará

Photo by Mateus Campos Felipe on Unsplash


Scarlet ibis (Guará)

The scarlet ibis, sometimes called red ibis (Eudocimus ruber), is a species of ibis in the bird family Threskiornithidae. It inhabits tropical South America and part of the Caribbean. In form, it resembles most of the other twenty-seven extant species of ibis, but its remarkably brilliant scarlet coloration makes it unmistakable. It is one of the two national birds of Trinidad and Tobago, and its Tupi–Guarani name, guará, is part of the name of several municipalities along the coast of Brazil.

Syntax

Application.at(apage.DoSomething [,with_parameter=value, ...]).asserts(it.Matches, a_condition)

Introduction

[!IMPORTANT] Guará is the Python implementation of the desing pattern Page Transactions. It is more of a programming pattern than a tool. It can be bound to any web driver other than Selenium.. Check the examples here

The intent of this pattern is to simplify UI test automation. It was inspired by Page Objects, App Actions, and Screenplay. Page Transactions focus on the operations (transactions) a user can perform on a web page, such as Login, Logout, or Submit Forms.

The pattern

  • AbstractTransaction: This is the class from which all transactions inherit. The do method is implemented by each transaction. In this method, calls to WebDriver are placed. If the method returns something, like a string, the automation can use it for assertions.

  • IAssertion: This is the interface implemented by all assertion classes.
  • The asserts method of each subclass contains the logic to perform validations. For example, the IsEqualTo subclass compares the result with the expected value provided by the tester.
  • Testers can inherit from this interface to add new subclasses of validations that the framework does not natively support. More details here.

  • Application: This is the runner of the automation. It executes the do method of each transaction and validates the result using the asserts method.
  • The asserts method receives a reference to an IAssertion instance. It implements the Strategy Pattern (GoF) to allow its behavior to change at runtime.
  • Another important component of the Application is the result property. It holds the result of the transaction, which can be used by asserts or inspected by the test using the native built-in assert method.

Framework in action

The idea is to group blocks of interactions into classes. These classes inherit from AbstractTransaction and override the do method.

Each transaction is passed to the Application instance, which provides the methods at and asserts. These are the only two methods necessary to orchestrate the automation. While it is primarily bound to Selenium WebDriver, experience shows that it can also be used to test REST APIs, unit tests and can be executed in asynchronous mode (check the tests folder).

When the framework is in action, it follows a highly repetitive pattern. Notice the use of the at method to invoke transactions and the asserts method to apply assertion strategies. Also, the automation is described in plain English improving the comprehention of the code.

from selenium import webdriver
from pages import home, contact, info
from guara.transaction import Application
from guara import it, setup

def test_sample_web_page():
    # Instantiates the Application with a driver
    app = Application(webdriver.Chrome())
    
    # At setup opens the web application
    app.at(setup.OpenApp, url="https://anyhost.com/",)
    
    # At Home page changes the language to Portuguese and asserts its content
    app.at(home.ChangeToPortuguese).asserts(it.IsEqualTo, content_in_portuguese)
    
    # Still at Home page changes the language
    # to English and uses native assertion to validate the `result`
    assert app.at(home.ChangeToEnglish).result == content_in_english
    
    # At Info page asserts the text is present
    app.at(info.NavigateTo).asserts(
        it.Contains, "This project was born"
    )

    # At setup closes the web application
    app.at(setup.CloseApp)
  • setup.OpenApp and setup.CloseApp are part of the framework and provide basic implementation to open and close the web application using Selenium Webdriver.
  • it is the module which contains the concret assertions.

The ugly code which calls the webdriver is like this:

class ChangeToPortuguese(AbstractTransaction):
    def __init__(self, driver):
        super().__init__(driver)

    # Implements the `do` method and returns the `result`
    def do(self, **kwargs):
        self._driver.find_element(
            By.CSS_SELECTOR, ".btn:nth-child(3) > button:nth-child(1) > img"
        ).click()
        self._driver.find_element(By.CSS_SELECTOR, ".col-md-10").click()
        return self._driver.find_element(By.CSS_SELECTOR, "label:nth-child(1)").text

Again, it is a very repetivite activity:

  • Create a class representing the transaction, in this case, the transaction changes the language to Portuguese
  • Inherits from AbstractTransaction
  • Implementes the do method
    • Optinonal: Returns the result of the transaction

Read more in Tutorial

Installation

This framework can be installed by

pip install guara

Execution with Selenium

It is recommended to use pytest

# Executes reporting the complete log
python -m pytest -o log_cli=1 --log-cli-level=INFO

Outputs

tests/web_ui_local/test_local_page.py::TestLocalTransaction::test_local_page 
--------------------------------------------------------------- live log setup ---------------------------------------------------------------
INFO     guara.transaction:transaction.py:26 Transaction 'OpenApp'
INFO     guara.transaction:transaction.py:28  url: file:////sample.html
INFO     guara.transaction:transaction.py:28  window_width: 1094
INFO     guara.transaction:transaction.py:28  window_hight: 765
INFO     guara.transaction:transaction.py:28  implicitly_wait: 0.5
--------------------------------------------------------------- live log call ----------------------------------------------------------------
INFO     guara.transaction:transaction.py:26 Transaction 'SubmitText'
INFO     guara.transaction:transaction.py:28  text: bla
INFO     guara.transaction:transaction.py:34 Assertion 'IsEqualTo'
INFO     guara.transaction:transaction.py:35  actual:   'It works! bla!'
INFO     guara.transaction:transaction.py:36  expected: 'It works! bla!'
INFO     guara.transaction:transaction.py:37 ---
INFO     guara.transaction:transaction.py:26 Transaction 'SubmitText'
INFO     guara.transaction:transaction.py:28  text: bla
INFO     guara.transaction:transaction.py:34 Assertion 'IsNotEqualTo'
INFO     guara.transaction:transaction.py:35  actual:   'It works! blabla!'
INFO     guara.transaction:transaction.py:36  expected: 'Any'
INFO     guara.transaction:transaction.py:37 ---
PASSED

Execution with Caqui (async)

# runs the example TestAsyncTransaction.
# Go to test_async.py to check requisites to start Caqui
python -m pytest -n auto -k TestAsyncTransaction -s

Outputs

4 workers [2 items]
..
============================================================= 2 passed in 3.56s ==============================================================

Tutorial

Read the step-by-step to build your first automation with this framework.

Contributing

Read the Code of Conduct before push new Merge Requests. Now, follow the steps in Contributing session.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

guara-0.0.3.tar.gz (84.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

guara-0.0.3-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file guara-0.0.3.tar.gz.

File metadata

  • Download URL: guara-0.0.3.tar.gz
  • Upload date:
  • Size: 84.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.9.21

File hashes

Hashes for guara-0.0.3.tar.gz
Algorithm Hash digest
SHA256 08fd085cad683640595e7a0bd6d2007fe5932169de2dc9b49c3e3a6fff4b627b
MD5 4334763cd4c24e52740c1b674d6de724
BLAKE2b-256 d506a2b8a413244b618c3936afe2f4fd93f1eab502c6fa583fd302f9dd096bf8

See more details on using hashes here.

File details

Details for the file guara-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: guara-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.9.21

File hashes

Hashes for guara-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7b8773d223eb05f4617a9c60fa627135cfdfdab9375d8ab8f0f499a0655e5710
MD5 253d5710b5d94e84ce3e037241f96fb9
BLAKE2b-256 ef4fa765294a5006ca8656048df6baee9f155c0c6c6ad7cd1dbe759b5b3ef7a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page