{"id":19829901,"url":"https://github.com/kr00lix/assert_html","last_synced_at":"2025-05-01T15:30:20.306Z","repository":{"id":53833630,"uuid":"164500959","full_name":"Kr00lIX/assert_html","owner":"Kr00lIX","description":"ExUnit assert helpers for testing rendered HTML.","archived":false,"fork":false,"pushed_at":"2023-11-14T17:27:03.000Z","size":122,"stargazers_count":21,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-22T20:24:04.335Z","etag":null,"topics":["elixir","test","view"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kr00lIX.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-07T21:42:51.000Z","updated_at":"2024-10-25T12:01:04.000Z","dependencies_parsed_at":"2022-08-19T15:20:48.931Z","dependency_job_id":null,"html_url":"https://github.com/Kr00lIX/assert_html","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kr00lIX%2Fassert_html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kr00lIX%2Fassert_html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kr00lIX%2Fassert_html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kr00lIX%2Fassert_html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kr00lIX","download_url":"https://codeload.github.com/Kr00lIX/assert_html/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251898476,"owners_count":21661835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","test","view"],"created_at":"2024-11-12T11:20:38.252Z","updated_at":"2025-05-01T15:30:19.825Z","avatar_url":"https://github.com/Kr00lIX.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AssertHTML: Elixir Library for testing HTML and XML using CSS selectors\n\n[![Build Status](https://travis-ci.org/Kr00lIX/assert_html.svg?branch=master)](https://travis-ci.org/Kr00lIX/assert_html)\n[![Hex pm](https://img.shields.io/hexpm/v/assert_html.svg?style=flat)](https://hex.pm/packages/assert_html)\n[![Coverage Status](https://coveralls.io/repos/github/Kr00lIX/assert_html/badge.svg?branch=master)](https://coveralls.io/github/Kr00lIX/assert_html?branch=master)\n \nAssertHTML 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.\n\n## Features\n\n- **HTML and XML Parsing**: Easily parse and extract data from HTML and XML documents.\n- **CSS Selectors**: Use CSS selectors to find and manipulate elements in your HTML or XML.\n- **ExUnit Assert Helpers**: Test your rendered HTML with the help of ExUnit assert helpers.\n\n## Getting Started\n\nFollow these steps to get started with AssertHTML:\n\n1. **Install the Library**: Add `assert_html` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:assert_html, \"~\u003e 0.1\"}\n  ]\nend\n```\n\nThen run `mix deps.get` to fetch the dependency.\n\n2. **Import formating**: Update your .formatter.exs file with the following import:\n\n```elixir\n[\n  import_deps: [\n    :assert_html\n  ]\n]\n```\n\n3. **Add the Library to your Test**: Add `AssertHTML` to your test file:\n\n```elixir\nuse AssertHTML\n```\n\n\n## Usage\n\n### Usage in Phoenix Controller and Integration Test\n\nAssuming the `html_response(conn, 200)` returns:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003ePAGE TITLE\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003ca href=\"/signup\"\u003eSign up\u003c/a\u003e\n    \u003ca href=\"/help\"\u003eHelp\u003c/a\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nAn example controller test:\n\n```elixir\ndefmodule YourAppWeb.PageControllerTest do\n  use YourAppWeb.ConnCase, async: true\n\n  test \"should get index\", %{conn: conn} do        \n    resp_conn = conn\n    |\u003e get(Routes.page_path(conn, :index))\n\n    html_response(resp_conn, 200)\n    # The page title is \"PAGE TITLE\"\n    |\u003e assert_html(\"title\", \"PAGE TITLE\")\n    # The page title is \"PAGE TITLE\", and there is only one title element\n    |\u003e assert_html(\"title\", count: 1, text: \"PAGE TITLE\")\n    # The page title matches \"PAGE\", and there is only one title element\n    |\u003e assert_html(\"title\", count: 1, match: \"PAGE\")\n    # The page has one link with the href value \"/signup\"\n    |\u003e assert_html(\"a[href='/signup']\", count: 1)\n    # The page has at least one link\n    |\u003e assert_html(\"a\", min: 1)\n    # The page has at most two links\n    |\u003e assert_html(\"a\", max: 2)\n    # The page contains no forms\n    |\u003e refute_html(\"form\")\n  end\nend\n```\n\n### Contains\n\n`assert_html(html, ~r{Hello World})` - match string in HTML  \n`refute_html(html, ~r{Another World})` - should not contain string in HTML\n\n```elixir\nassert_html(html, \".content\") do\n  assert_html(~r{Hello World})\nend\n```    \n      \n### CSS selectors\n\n`assert_html(html, \".css .selector\")` - checks if an element exists in the CSS selector path\n`refute_html(html, \".errors .error\")` - checks if an element does not exist in the path\n\n### Check attributes\n\n```elixir\nassert_html(html, \"form\", class: \"form\", method: \"post\", action: \"/session/login\") do\n  assert_html \".-email\" do\n    assert_html(\"label\", text: \"Email\", for: \"staticEmail\", class: \"col-form-label\")\n    assert_html(\"div input\", type: \"text\", readonly: true, class: \"form-control-plaintext\", value: \"email@example.com\")\n  end\n  assert_html(\".-password\") do\n    assert_html(\"label\", text: \"Password\", for: \"inputPassword\")\n    assert_html(\"div input\", placeholder: \"Password\", type: \"password\", class: \"form-control\", id: \"inputPassword\")\n  end\n\n  assert_html(\"button\", type: \"submit\", class: \"primary\")\nend\n```\n\n### Example\n\n```elixir\ndefmodule ExampleControllerTest do\n  use ExUnit.Case, async: true\n  use AssertHTML\n\n  test \"shows search form\", %{conn: conn} do\n    conn_resp = get(conn, Routes.page_path(conn, :new))\n    assert response = html_response(conn_resp, 200)\n\n    assert_html response do\n      # Check if element exists in CSS selector path\n      assert_html \"p.description\"\n\n      # Check if element doesn't exist\n      refute_html \".flash-message\"\n\n      # Assert form attributes\n      assert_html \"form.new_page\", action: Routes.page_path(conn, :create), method: \"post\" do\n        # Assert elements inside the `form.new_page` selector\n        assert_html \"label\", class: \"form-label\", text: \"Page name\"\n        assert_html \"input\", type: \"text\", class: \"form-control\", value: \"\", name: \"page_name\"\n        assert_html \"button\", class: \"form-button\", text: \"Submit\"\n      end\n    end\n  end\nend\n```\n\nDocumentation can be found at [https://hexdocs.pm/assert_html](https://hexdocs.pm/assert_html/AssertHTML.html).\n\n\n## Contribution\nFeel free to send your PR with proposals, improvements or corrections 😉.\n\n## Author\n\nAnatolii Kovalchuk (@Kr00liX)\n\n\n## License\n\nThis software is licensed under [the MIT license](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkr00lix%2Fassert_html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkr00lix%2Fassert_html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkr00lix%2Fassert_html/lists"}