In this tutorial you will learn how to write your first visual test using Applitools Selenium Python SDK.
Before that, let's take a look at the application under test.
We will be using the Automation Bookstore site created by Angie Jones in her Visual Testing with Java course on Test Automation University.
The site is a simple bookstore with a list of some great books on testing and automation and some of its capabilities are as follows.
You can search the desired book based on the author name.
So, let's say I want to search for the book written by “James”.
Then I can see that he has written How Google Tests Software and it's available in this bookstore.
I can also search based on the name of the book itself.
If I want to know how much the Agile Testing book costs, I can enter that and see the book in the store.
I can also give a partial name of the book and see what all books are available in the bookstore.
Let's say you want to assert that on searching for the book “Agile Testing” on the site we are only able to see the one book on the screen.
We could achieve this by writing a function to get all the elements under this parent and then see if our text is present in the list.
I have already gone ahead and written a Page Object class which does this.
class SearchPage: def __init__(self, driver): self.driver = driver def filter_books(self, search_text): element = self.driver.find_element_by_id('searchBar') element.send_keys(search_text) def verify_visible_books_by_title(self, expected_title): elements = self.driver.find_elements_by_css_selector( '#productList li a h2') for element in elements: if expected_title in element.text: return True return False
verify_visible_books_by_title, expects an argument with the title name and then it iterates in all the available books and sees if our expected book (
expected_title) is present in them.
Otherwise it returns
Here is a test method that does the same thing.
from assertpy import assert_that from time import sleep from automation.page_objects.search_page import SearchPage def test_filter_book(eyes, driver): page = SearchPage(driver) page.filter_books('Agile') sleep(5) result = page.verify_visible_books_by_title('Agile Testing') assert_that(result).is_equal_to(True)
I have initialized the
page Object (
SearchPage) and I'm calling the
filter_books function further by calling the simple assertion to
verify_visible_books_by_title and then asserting the
Let's run this.
However, there are some problems with this assertion.
It is not very robust because it still would not verify that the other books are not displayed.
If you take a look at your DOM right now, all the other books are also present under this parent control.
Also, it does not verify other important details of the book, like the color of the cover, or the price.
All these elements or details are missed while we are trying to verify this.
For such cases Applitools visual assertion can give a lot of value with a very simple assertion that we can do.
Let's see this in action.
We have modified the framework to use
pytest framework. I have added a bunch of fixtures to set up WebDriver, get the Eyes instance with the API key and some other utility functions already.
Before every test
function execution we will initialize the WebDriver, launch the app and after the test is executed, we would be creating the
And likewise, for the
Let's see how we can add a simple function to validate the whole window using Applitools.
Let's add a new function to validate the whole window in the
We’ll add a function
validate_window and pass it the
driver name, the
eyes instance and the
tag name. I'll explain what this tag means in just a minute.
To start validation of a particular window, we need to open eyes, perform the validation and then close the eyes instance. Let's add functions for this.
open_eyes we need to pass it the
driver instance and the
eyes instance, which we have received from our test.
To open the Eyes on the
eyes instance we need to call the
open function and pass it the
driver name that we have just received, the name of the app (
APP_NAME) and the name of the test (
test_name) that is going to get executed. Let's pass this as a default parameter.
I have already written the
get_test_name function, which uses the
inspect module to get the name of the test function.
Let's close the
eyes instance. Nice.
eyes are open on the particular
eyes instance we can call our
check_window function and pass it the
tag that we received from the test function.
import pytest from applitools.selenium import Eyes from selenium import webdriver from automation.config.base import APPLITOOLS_API_KEY APP_NAME = 'automation_bookstore' APP_UNDER_TEST = 'file:///Users/gaurav/Self/Dev/automated-visual-testing/website/index.html' @pytest.fixture(scope='function') def driver(): driver = webdriver.Chrome() driver.get(APP_UNDER_TEST) yield driver driver.quit() @pytest.fixture(scope='function') def eyes(): eyes = initialize_eyes() yield eyes def initialize_eyes(): eyes = Eyes() eyes.api_key = APPLITOOLS_API_KEY return eyes def validate_window(driver, eyes, tag): open_eyes(driver, eyes) eyes.check_window(tag=tag) close_eyes(eyes) def open_eyes(driver, eyes): eyes.open(driver, APP_NAME, test_name=get_test_name()) def get_test_name(): import inspect return inspect.stack().function def close_eyes(eyes): eyes.close()
Now let's add this
validate_window function in our search_test.
Pass it the
eyes instance and a
tag ("filter_text"). Here tag is a way to specify a unique name for this assertion, which we can visualize in the Applitools dashboard.
from assertpy import assert_that from automation.tests.conftest import open_eyes, validate_window, close_eyes from automation.page_objects.search_page import SearchPage def test_filter_book(eyes, driver): page = SearchPage(driver) page.filter_books('Agile') validate_window(driver, eyes, tag='filter_text')
Let's remove these earlier assertions.
And run the test.
We see that the test passed.
Let's see this in Applitools.
Here we have the Applitools Eyes Manager and we can see the results in Applitools website.
Here you can see certain sections like the test that was just executed and see the snapshot that was captured.
Since the snapshot looks okay to me, I can give it a thumbs up and save this as a baseline.
However, what if we changed the book name to be passed to the site?
Let's do that (changing the
filter_books value to “James” instead of “Agile”) and run the test again.
This time we see a different book on the screen as expected, the test failed.
If you take a look at the exception trace, we see Applitools
DiffsFoundError and a URL for the Applitools website with the test results.
This time in the Applitools site, we can see the test is marked as “Unresolved”.
And if we open it, we can see that it has captured the difference between the original baseline and the new one.
Since this is not a change that we are expecting and looks like a visual bug, we can mark it as failed and the test is marked as failed.