---
title: Integrating screenshots in Allure Report with Pytest and Selenium
description: The guide describes how you can integrate the screenshots in Allure Report with Pytest and Selenium
---

# Integrating screenshots in Allure Report with Pytest and Selenium

The process of interpreting test results should be optimized for speed and clarity. Ideally, the root cause of a failure should be immediately identifiable without requiring the reader to inspect additional code, execute a debugger, or seek assistance from other team members.

To achieve this goal, test reports must convey comprehensive information in a concise format. One effective approach is the inclusion of screenshots, which provide visual context for test failures. This guide outlines the process of capturing screenshots using the pytest-selenium plugin and integrating them into test reports with Allure Report for enhanced readability and analysis.

## 1. Preparation

### Prerequisites

Make sure the following prerequisites are met:

- [Python installed](https://www.python.org/downloads/)
- [Allure Report installed](/docs/v2/install/)

### Dependency list

This guide uses the following packages:

- [Pytest 8.3.4](https://pypi.org/project/pytest/8.3.4/)
- [allure-pytest 2.13.5](https://pypi.org/project/allure-pytest/2.13.5/)
- [pytest-selenium 4.1.0](https://pypi.org/project/pytest-selenium/4.1.0/)

### Code sample

The complete source code used in this guide is available at [https://github.com/allure-examples/guide-pytest-selenium-screenshots](https://github.com/allure-examples/guide-pytest-selenium-screenshots/).

### Setup

To run the examples in this guide:

1. Install [Python](https://www.python.org/downloads/)
1. Install [Allure Report](/docs/v2/install/)
1. Download a fresh project with Pytest from [Allure Start](/start/)
1. Add [the pytest-selenium plugin](https://pytest-selenium.readthedocs.io/en/latest/installing.html) to your project. For example, if you use `pip`:

**Install pytest-selenium:**
```shell
pip install pytest-selenium
```

## 2. Screenshots with Selenium

To take screenshots with pytest-selenium at an arbitrary time, use the methods provided by the `WebDriver` object, for example, [`save_screenshot`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.save_screenshot). To get the `WebDriver` object, you can use [the `selenium` fixture](https://pytest-selenium.readthedocs.io/en/latest/user_guide.html#quick-start):

```python
def test_example(selenium):
    selenium.get("https://www.selenium.dev/")
    try:
        assert "Selenium" in selenium.title
    except AssertionError:
        selenium.save_screenshot("path/to/screenshot.png")
        raise
```

Whenever you call the `save_screenshot` method, a screenshot will appear at `path/to/screenshot.png`. You can also use other methods that the `WebDriver` object provides:

- [`get_screenshot_as_file()`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.get_screenshot_as_file)
- [`get_screenshot_as_png()`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.get_screenshot_as_png)
- [`get_screenshot_as_base64()`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.get_screenshot_as_base64)

To take a screenshot of a particular element, use the [`screenshot`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webelement.WebElement.screenshot) method of the `WebElement` object, for example:

```python
element = selenium.find_element(By.NAME, "q") # or however you find the element
# take the screenshot
element.screenshot("path/to/element_screenshot.png")
```

You can also use these properties of `WebElement`:

- [`screenshot_as_png`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webelement.WebElement.screenshot_as_png)
- [`screenshot_as_base64`](https://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webelement.WebElement.screenshot_as_base64)

## 3. Automatic screenshots on failure

To take screenshots automatically of every test failure:

1. Write a hook that pytest-selenium will call to process the screenshots it takes. The hook code must be placed in the `conftest.py` file in your project's test root directory:

   **pytest-selenium:**
   ```python
   # Contents of conftest.py
   import base64

   def pytest_selenium_capture_debug(item, report, extra):
       for log_type in extra:
           if log_type["name"] == "Screenshot":
               content = base64.b64decode(log_type["content"].encode("utf-8"))
               with open(f"{item.name}.png", "wb") as f:
                   f.write(content)
   ```

1. Set the `selenium_capture_debug` option to `failure` in [Pytest configuration](https://pytest.org/en/latest/reference/customize.html#command-line-options-and-configuration-file-settings). For example, if you use `pyproject.toml` as a configuration file, add the following:

   ```toml
   [tool.pytest.ini_options]
   ...
   selenium_capture_debug = "failure"
   ```

Now, when a test fails, a screenshot file will be saved automatically in your project.

## 4. Integrating with Allure Report

While capturing screenshots is beneficial for diagnosing test failures, viewing them separately can be inefficient. When test data is dispersed across multiple locations, the process of identifying and resolving failures becomes more time-consuming.

To streamline this workflow, screenshots should be directly attached to Allure Reports, ensuring all relevant test information is consolidated in a single location for efficient analysis and troubleshooting.

Allure Report shows you screenshots inside the test in which they were taken. That is also where the error messages and other attachments are presented to you, so you have everything you need to analyze test results in one place:

![Screenshot Attachment in Allure Report](/images/guides/pytest-screenshots/screesnshot_in_scenario.png "Screenshot Attachment in Allure Report")

To attach screenshots to Allure, use either the [`allure.attach()`](/docs/pytest-reference/#attaching-content-from-variables) or the [`allure.attach.file()`](/docs/pytest-reference/#reading-attachments-from-files) functions.

Use `allure.attach.file()` to attach an existing file:

```python
import allure
from pathlib import Path

# Attach a screenshot of a page
def attach_screenshot(driver, path):
    name = Path(path).name
    driver.get_screenshot_as_file(path)
    allure.attach.file(
        path,
        name=name,
        attachment_type=allure.attachment_type.PNG,
    )

# Attach a screenshot of an element
def attach_element_screenshot(element, path):
    name = Path(path).name
    element.screenshot(path)
    allure.attach.file(
        path,
        name=name,
        attachment_type=allure.attachment_type.PNG,
    )
```

Use `allure.attach()` if you don’t need to save the screenshot on disk:

```python
import allure

# Attach a screenshot of a page
def attach_screenshot(driver, name):
    allure.attach(
        driver.get_screenshot_as_png(),
        name=name,
        attachment_type=allure.attachment_type.PNG,
    )

# Attach a screenshot of an element
def attach_element_screenshot(element, name):
    allure.attach(
        element.get_screenshot_as_png(),
        name=name,
        attachment_type=allure.attachment_type.PNG,
    )
```

Tip:

When you need to attach a screenshot you just took, prefer using the `allure.attach` function if possible. The reason is that when you save a screenshot on disk, it may not always be immediately available for reading because of OS caching. If that happens, you may end up with an empty file attached to Allure.

To automatically attach screenshots to Allure on each test failure, use a slightly modified version of the pytest-selenium hook we’ve written in the [**Automatic screenshots on failure**](#_3-automatic-screenshots-on-failure) section:

**pytest-selenium:**
```python
# Contents of conftest.py
import allure
import base64

from allure_commons.types import AttachmentType

def pytest_selenium_capture_debug(item, report, extra):
    for log_type in extra:
        if log_type["name"] == "Screenshot":
            content = base64.b64decode(log_type["content"].encode("utf-8"))
            allure.attach(
                content,
                name="Screenshot on failure",
                attachment_type=AttachmentType.PNG,
            )
```

## 5. Other attachment types

Allure Report can also handle other types of attachments - text, tables, URI lists, or documents (XML, JSON, YAML). For example:

```python
allure.attach(
    response_content,
    name="response content",
    attachment_type=allure.attachment_type.XML
)
```

Allure Pytest makes some attachments automatically:

1. everything passed to `sys.stdout` - e.g. `print(...)`
2. everything passed to `sys.stderr` - e.g. `print(..., file=sys.stderr)`
3. logging, e.g. `logging.warning(...)`

These outputs are attached as pseudo-files to the report:

![Automatic Attachments In Allure Report With Pytest](/images/guides/pytest-screenshots/attachment_pytest_auto.png "Automatic Attachments In Allure Report With Pytest")

If you don’t want all of this to appear in the report, use the [`--allure-no-capture`](/docs/pytest-configuration/#allure-no-capture) option.

Allure also allows you to [attach videos](/docs/attachments/#videos). You can consult the official documentation for more on [attachments with Pytest](/docs/pytest/#attach-screenshots-and-other-files) and [attachment types](/docs/attachments/).

## 6. Conclusion

When using Pytest with Selenium, you can take screenshots at arbitrary times in your tests or instruct Selenium to take screenshots automatically on test failures. Allure Report allows viewing the screenshots and other test attachments (text, documents, tables, video) in one place, providing the reader with the maximum amount of data to resolve test failures.
