No description
Find a file
2026-04-13 19:06:24 +02:00
.github use org secret 2025-02-05 08:34:45 -05:00
config cleanup Readme file 2023-11-14 18:26:58 +01:00
lib Fix text matching for HTML with escaped entities 2026-04-13 18:34:12 +02:00
test Update to Elixir 1.7 and other latest versions. 2024-12-16 14:18:37 -05:00
.credo.exs format and cleanup code 2019-01-26 22:38:43 +01:00
.dialyzer_ignore.exs delete unused dialyzer filters 2022-05-19 15:35:12 +02:00
.formatter.exs update formatter 2019-06-19 19:44:45 +03:00
.gitignore Adding github actions 2025-02-05 08:30:04 -05:00
.tool-versions update deps 2025-06-05 16:47:55 +02:00
.travis.yml add :count, :min, :max checkers 2019-04-30 11:46:04 +03:00
CHANGELOG.md add badges to readme 2019-02-04 18:29:19 +02:00
LICENSE.md simplify assert_attributes matcher 2019-01-08 00:53:04 +02:00
mix.exs Bump version to 0.2.3 2026-04-13 19:06:24 +02:00
mix.lock update deps 2026-04-12 10:30:47 +02:00
README.md cleanup Readme file 2023-11-14 18:26:58 +01:00
TODO.md add badges to readme 2019-02-04 18:29:19 +02:00

AssertHTML: Elixir Library for testing HTML and XML using CSS selectors

Build Status Hex pm Coverage Status

AssertHTML is a powerful Elixir library designed for parsing and extracting data from HTML and XML using CSS. It also provides ExUnit assert helpers for testing rendered HTML using CSS selectors, making it an essential tool for Phoenix Controller and Integration tests.

Features

  • HTML and XML Parsing: Easily parse and extract data from HTML and XML documents.
  • CSS Selectors: Use CSS selectors to find and manipulate elements in your HTML or XML.
  • ExUnit Assert Helpers: Test your rendered HTML with the help of ExUnit assert helpers.

Getting Started

Follow these steps to get started with AssertHTML:

  1. Install the Library: Add assert_html to your list of dependencies in mix.exs:
def deps do
  [
    {:assert_html, "~> 0.1"}
  ]
end

Then run mix deps.get to fetch the dependency.

  1. Import formating: Update your .formatter.exs file with the following import:
[
  import_deps: [
    :assert_html
  ]
]
  1. Add the Library to your Test: Add AssertHTML to your test file:
use AssertHTML

Usage

Usage in Phoenix Controller and Integration Test

Assuming the html_response(conn, 200) returns:

<!DOCTYPE html>
<html>
  <head>
    <title>PAGE TITLE</title>
  </head>
  <body>
    <a href="/signup">Sign up</a>
    <a href="/help">Help</a>
  </body>
</html>

An example controller test:

defmodule YourAppWeb.PageControllerTest do
  use YourAppWeb.ConnCase, async: true

  test "should get index", %{conn: conn} do        
    resp_conn = conn
    |> get(Routes.page_path(conn, :index))

    html_response(resp_conn, 200)
    # The page title is "PAGE TITLE"
    |> assert_html("title", "PAGE TITLE")
    # The page title is "PAGE TITLE", and there is only one title element
    |> assert_html("title", count: 1, text: "PAGE TITLE")
    # The page title matches "PAGE", and there is only one title element
    |> assert_html("title", count: 1, match: "PAGE")
    # The page has one link with the href value "/signup"
    |> assert_html("a[href='/signup']", count: 1)
    # The page has at least one link
    |> assert_html("a", min: 1)
    # The page has at most two links
    |> assert_html("a", max: 2)
    # The page contains no forms
    |> refute_html("form")
  end
end

Contains

assert_html(html, ~r{Hello World}) - match string in HTML
refute_html(html, ~r{Another World}) - should not contain string in HTML

assert_html(html, ".content") do
  assert_html(~r{Hello World})
end

CSS selectors

assert_html(html, ".css .selector") - checks if an element exists in the CSS selector path refute_html(html, ".errors .error") - checks if an element does not exist in the path

Check attributes

assert_html(html, "form", class: "form", method: "post", action: "/session/login") do
  assert_html ".-email" do
    assert_html("label", text: "Email", for: "staticEmail", class: "col-form-label")
    assert_html("div input", type: "text", readonly: true, class: "form-control-plaintext", value: "email@example.com")
  end
  assert_html(".-password") do
    assert_html("label", text: "Password", for: "inputPassword")
    assert_html("div input", placeholder: "Password", type: "password", class: "form-control", id: "inputPassword")
  end

  assert_html("button", type: "submit", class: "primary")
end

Example

defmodule ExampleControllerTest do
  use ExUnit.Case, async: true
  use AssertHTML

  test "shows search form", %{conn: conn} do
    conn_resp = get(conn, Routes.page_path(conn, :new))
    assert response = html_response(conn_resp, 200)

    assert_html response do
      # Check if element exists in CSS selector path
      assert_html "p.description"

      # Check if element doesn't exist
      refute_html ".flash-message"

      # Assert form attributes
      assert_html "form.new_page", action: Routes.page_path(conn, :create), method: "post" do
        # Assert elements inside the `form.new_page` selector
        assert_html "label", class: "form-label", text: "Page name"
        assert_html "input", type: "text", class: "form-control", value: "", name: "page_name"
        assert_html "button", class: "form-button", text: "Submit"
      end
    end
  end
end

Documentation can be found at https://hexdocs.pm/assert_html.

Contribution

Feel free to send your PR with proposals, improvements or corrections 😉.

Author

Anatolii Kovalchuk (@Kr00liX)

License

This software is licensed under the MIT license.