{"id":20838753,"url":"https://github.com/royalicing/ensemble","last_synced_at":"2025-04-10T12:12:23.953Z","repository":{"id":235152172,"uuid":"790192648","full_name":"RoyalIcing/ensemble","owner":"RoyalIcing","description":"All-star cast of ARIA roles for testing Phoenix LiveView","archived":false,"fork":false,"pushed_at":"2024-05-02T12:16:05.000Z","size":30,"stargazers_count":16,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T01:30:47.584Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/ensemble/","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RoyalIcing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-22T12:37:49.000Z","updated_at":"2024-08-30T18:09:48.000Z","dependencies_parsed_at":"2024-04-22T13:04:02.280Z","dependency_job_id":null,"html_url":"https://github.com/RoyalIcing/ensemble","commit_stats":null,"previous_names":["royalicing/ensemble"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyalIcing%2Fensemble","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyalIcing%2Fensemble/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyalIcing%2Fensemble/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoyalIcing%2Fensemble/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RoyalIcing","download_url":"https://codeload.github.com/RoyalIcing/ensemble/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248217080,"owners_count":21066633,"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":[],"created_at":"2024-11-18T01:11:27.543Z","updated_at":"2025-04-10T12:12:23.935Z","avatar_url":"https://github.com/RoyalIcing.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ensemble\n\n[Docs](https://hexdocs.pm/ensemble/)\n\nAn all-star cast of ARIA roles for Phoenix [LiveViewTest](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveViewTest.html).\n\nEnsemble is a library for testing Phoenix LiveView. You write your test using ARIA roles instead of CSS selectors. It means you are incentivised to improve your accessibility, have easier to read tests, and your test is less coupled to a particular implementation making refactoring easier.\n\nEnsemble sits alongside LiveView’s built-in `Phoenix.LiveViewTest`. Ensemble provides you substitutes for `Phoenix.LiveViewTest.element/3` and `Phoenix.LiveViewTest.has_element?/3`:\n\nHere’s a before with CSS selectors:\n\n```elixir\nimport Phoenix.LiveViewTest\nimport Ensemble\n\ntest \"has home link\", %{conn: conn} do\n  {:ok, view, _html} = live(conn, \"/\")\n\n  assert view |\u003e has_element?(~S|a[href=\"/\"]|)\nend\n\ntest \"can subscribe to newsletter\", %{conn: conn} do\n  {:ok, view, _html} = live(conn, \"/\")\n\n  view\n  |\u003e element(~S|button[phx-action=\"subscribe\"]|)\n  |\u003e render_click() =~ \"You are now subscribed.\"\nend\n```\n\nAnd after with ARIA roles and accessible names:\n\n```elixir\nimport Phoenix.LiveViewTest\nimport Ensemble\n\ntest \"has home link\", %{conn: conn} do\n  {:ok, view, _html} = live(conn, \"/\")\n\n  assert view |\u003e has_role?(:link, \"Home\")\nend\n\ntest \"can subscribe to newsletter\", %{conn: conn} do\n  {:ok, view, _html} = live(conn, \"/\")\n\n  view\n  |\u003e role(:button, \"Subscribe\")\n  |\u003e render_click() =~ \"You are now subscribed.\"\nend\n```\n\nThere’s less focus on details such as HTML structure or LiveView attributes that can change, and more focus on the semantic layer presented to users. Your tests become like a screen reader. This means your app will likely work better with real screen readers.\n\nIf you are new to the concepts of ARIA roles or accessible names I recommend reading W3C’s guides:\n\n- [Landmark roles](https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/)\n- [Structual content roles](https://www.w3.org/WAI/ARIA/apg/practices/structural-roles/)\n- [Accessible names](https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/)\n\n## Installation\n\nInstall via [Hex](https://hex.pm/) by adding `ensemble` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:ensemble, \"~\u003e 0.0.1\"}\n  ]\nend\n```\n\n## Usage\n\nWrite a [LiveViewTest](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveViewTest.html) and `import Ensemble`.\n\n```elixir\ndefmodule TodoLiveTest do\n  use YourAppWeb.ConnCase, async: true\n\n  import Phoenix.LiveViewTest\n  import Ensemble\n\n  test \"has navigation\", %{conn: conn} do\n    {:ok, view, _html} = live(conn, \"/todos\")\n\n    assert view |\u003e has_role?(:banner)\n    assert view |\u003e has_role?(:contentinfo)\n\n    assert view |\u003e has_role?(:navigation, \"Primary\")\n    assert view |\u003e has_role?(:link, \"Home\")\n    assert view |\u003e has_role?(:link, \"About\")\n    assert view |\u003e has_role?(:button, \"Sign Out\")\n\n    refute view |\u003e has_role?(:link, \"Does not exist\")\n\n    assert view\n           |\u003e role(:link, \"Home\")\n           |\u003e render() == ~S|\u003ca href=\"/\"\u003eHome\u003c/a\u003e|\n  end\n\n  test \"form\", %{conn: conn} do\n    {:ok, view, _html} = live(conn, \"/todos\")\n\n    assert view |\u003e has_role?(:form, \"New todo item\")\n    assert view |\u003e has_role?(:textbox, \"Description\")\n    assert view |\u003e has_role?(:checkbox, \"High priority\")\n\n    assert view\n           |\u003e role(:button, \"Add item\")\n           |\u003e render_click() =~ \"Item created.\"\n  end\nend\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froyalicing%2Fensemble","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froyalicing%2Fensemble","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froyalicing%2Fensemble/lists"}