{"id":13509252,"url":"https://github.com/stuart/tuco_tuco","last_synced_at":"2026-02-21T15:05:05.604Z","repository":{"id":14421554,"uuid":"17132597","full_name":"stuart/tuco_tuco","owner":"stuart","description":"Yet another South American rodent...a Capybara like web app testing tool for Elixir.","archived":false,"fork":false,"pushed_at":"2016-09-15T09:56:37.000Z","size":206,"stargazers_count":58,"open_issues_count":4,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-12-13T02:14:35.970Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stuart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-24T10:30:07.000Z","updated_at":"2024-12-10T09:54:18.000Z","dependencies_parsed_at":"2022-08-29T05:22:13.954Z","dependency_job_id":null,"html_url":"https://github.com/stuart/tuco_tuco","commit_stats":null,"previous_names":["stuart/tuco-tuco"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/stuart/tuco_tuco","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuart%2Ftuco_tuco","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuart%2Ftuco_tuco/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuart%2Ftuco_tuco/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuart%2Ftuco_tuco/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stuart","download_url":"https://codeload.github.com/stuart/tuco_tuco/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stuart%2Ftuco_tuco/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29684076,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T14:31:22.911Z","status":"ssl_error","status_checked_at":"2026-02-21T14:31:22.570Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-08-01T02:01:05.250Z","updated_at":"2026-02-21T15:05:05.573Z","avatar_url":"https://github.com/stuart.png","language":"Elixir","funding_links":[],"categories":["Testing"],"sub_categories":[],"readme":"# TucoTuco\n[![Build Status](https://travis-ci.org/stuart/tuco_tuco.png?branch=master)](https://travis-ci.org/stuart/tuco_tuco)\n\nTesting for Elixir web applications.\n\nTucoTuco helps you test your web application by running a web browser\nand simulating user interaction with your application.\n\nWith a DSL approximating that of Capybara's, it should be\neasy for developers to write tests for a web application.\n\n## Setup\nIn your mix.exs add the following to the test environment deps:\n\n    {:tuco_tuco, \"~\u003e0.8.1\", only: test}\n\nEither specify tuco_tuco in your application block in mix.exs or do:\n\n    :application.start TucoTuco\n\n## Requirements\nTesting requires that you have Phantomjs, Firefox or ChromeDriver installed.\nThe WebDriver library will also prompt you to install the Firefox plugin with\n`mix webdriver.firefox.plugin` if it is not present.\nYou can also test against a remote WebDriver server such as a Selenium instance.\n\n## Documentation\nHere is a rough guide to using TucoTuco.\n\n### Starting A Session\n  Import the DSL functionality with:\n\n```\nuse TucoTuco.DSL\n```\n\n  Start a session with:\n\n```\nTucoTuco.start_session :browser_name, :session_name, :browser_type\n```\n\n  Where browser_name and session_name are atoms to reference the running\n  browser and session with later and browser_type is one of\n\n    * :phantomjs\n    * :firefox\n    * :chromedriver\n    * :remote\n\n### Navigation\n  Visit sends the browser to other pages.\n\n```elixir\n  visit \"http://elixir-lang.org\"\n  visit \"/login\"\n```\n\n  Relative urls will be appended with the TucoTuco.app_root value.\n\n  You can go back and forward in the browser history:\n\n```elixir\n  go_forward\n  go_back\n```\n\n  And query the current url:\n\n```elixir\ncurrent_url\ncurrent_path\ncurrent_query\ncurrent_port\n```\n\n### Clicking\n  You can click on a link or button with the `click_link` and\n`click_button` commands.\n\n```elixir\n  click_link \"Home\"\n  click_link \"i3\"\n  click_button \"Back\"\n  click_button \"Submit\"\n```\n\n  Yet to come: mouse movements.\n\n### Forms\n  Interacting with forms is easy with TucoTuco's functions for that:\n\n```elixir\n  fill_in \"Login\", \"Stuart\"\n  fill_in \"Password\", \"secret_password\"\n  click_button \"Submit\"\n  choose \"A radio button\"\n  select \"Carrot\"\n  select \"Tomato\", from: \"Vegetables\"\n  check \"A Checkbox\"\n```\n\n  You can even attach files:\n\n```elixir\n  attach_file \"Upload Picture\", \"path/to/my_photo.png\"\n```\n\n### Querying\n  Getting information about the page to use in assertions:\n\n```elixir\n  Page.has_css? \"table thead tr.header\"\n  Page.has_xpath? \"//foo/bar[@name='baz']\"\n  Page.has_text? \"Some text from the page\"\n  Page.has_link? \"Back\"\n```\n\n  With 'has_css?` and `has_xpath?` you can specify a count\n  of how many should be found.\n\n```elixir\n  # Check that there are 5 rows in the table.\n  Page.has_css? \"table tbody tr\", count: 5\n```\n\n  There are many more. Check the documentation for them.\n\n### Assertions\n  TucoTuco supplies two assertions that you can use directly in tests:\n\n```elixir\n  assert_selector :xpath, \"//foo/bar\"\n  refute_selector :xpath, \"//baz[@class='bob']\"\n```\n\n### Finder\n  Finder return elements from the DOM.\n\n```elixir\n  Finder.find :id, \"foo\"\n  Finder.find :css, \".bar\"\n  Finder.find :xpath, \"//foo/bar\"\n```\n\n  Find returns an Element record.\n\n### Elements\n  The following functions for manipulating elements are imported from\n  WebDriver, they all take a WebDriver.Element struct as the\n  first argument. Luckily that is exactly what all the finders return:\n\n```elixir\n  Element.attribute reference, :a_html_attribute\n  Element.clear reference\n  Element.click reference\n  Element.css reference, \"some-css-property-name\"\n  Element.displayed? reference\n  Element.enabled? reference\n  Element.equals? reference, other_reference\n  Element.location? reference\n  Element.location_in_view? reference\n  Element.name reference\n  Element.selected? reference\n  Element.size reference\n  Element.submit reference\n  Element.text reference\n  Element.value reference, \"value to set\"\n```\n\n  For more detailed docs on the Element functions see\n  [WebDriver.Element](http://stuart.github.io/elixir-webdriver/WebDriver.Element.html).\n\n### Javascript\n  Javascript can be run using the `execute_javascript` and `execute_async_javascript`\n  commands.\n\n```elixir\n  iex\u003e execute_javascript \"return argument[0] * 10\", [3]\n  iex\u003e 30\n```\n\n### Retrying\n  When you are testing applications that have Javascript modifying the page\n  it is possible that elements will not be available when you want them because\n  the browser script takes some time to run.\n\n  To alleviate this TucoTuco has retry settings. When retry is turned on all the\n  Page.has_foo? and action functions will retry for a set number of times before failing.\n\n  You can also use the retry function yourself like this:\n\n```elixir\n  # Find elements\n  TucoTuco.Finder.find using, selector\n\n  # Any function\n  TucoTuco.Retry.retry fn -\u003e my_function(args) end\n```\n\n  Changing retry settings:\n\n```elixir\n  # Set retries on\n  TucoTuco.use_retries true\n  # Set the maximum retry time in milliseconds.\n  TucoTuco.max_retry_time 1000\n  # Set the delay between retries in milliseconds.\n  TucoTuco.retry_delay 20\n```\n\n### Multiple Sessions\n  You can run multiple sessions on different browser or on the same browser.\n  To start a session use:\n\n    TucoTuco.start_session :browser_name, :session_name, browser_type\n\n  Where the browser type is one of :phantomjs, :firefox or :chrome.\n  If the process :browser_name is already running the session will be started on\n  that, otherwise a new browser will start running.\n\n  Once you have multiple sessions running you can swap sessions with:\n\n    TucoTuco.session :new_session\n\n  And to get a list of sessions that are running:\n\n    TucoTuco.sessions\n\n\n### Screenshot\n   When the driver supports it, you can take a screenshot and\n   save it as a PNG file.\n\n    save_screenshot \"path/to/file.png\"\n\nExample Session from console:\n\n```elixir\n    iex(1)\u003e use TucoTuco.DSL\n    :ok\n    iex(2)\u003e TucoTuco.start_session :test_browser, :tuco_test, :phantomjs\n    {:ok,\n     %TucoTuco.SessionPool.SessionPoolState{app_root: nil,\n      current_session: :tuco_test, max_retry_time: 2000, retry_delay: 50,\n      use_retry: false}}\n    iex(3)\u003e visit \"http://elixir-lang.org\"\n    {:ok,\n     %WebDriver.Protocol.Response{request: %WebDriver.Protocol.Request{body: \"{\\\"url\\\":\\\"http://elixir-lang.org\\\"}\",\n       headers: [\"Content-Type\": \"application/json;charset=UTF-8\",\n        \"Content-Length\": 32], method: :POST,\n       url: \"http://localhost:57491/wd/hub/session/4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7/url\"},\n      session_id: \"4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7\", status: 0, value: %{}}}\n    iex(4)\u003e click_link \"getting started guide\"\n    {:ok,\n     %WebDriver.Protocol.Response{request: %WebDriver.Protocol.Request{body: \"{}\",\n       headers: [\"Content-Type\": \"application/json;charset=UTF-8\",\n        \"Content-Length\": 2], method: :POST,\n       url: \"http://localhost:57491/wd/hub/session/4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7/element/:wdc:1408353394161/click\"},\n      session_id: \"4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7\", status: 0, value: %{}}}\n    iex(5)\u003e current_url\n    \"http://elixir-lang.org/getting_started/1.html\"\n    iex(6)\u003e Page.has_css? \"article h1#toc_0\"\n    false\n    iex(7)\u003e Page.has_text? \"Elixir also supports UTF-8 encoded strings:\"\n    false\n    iex(8)\u003e click_link \"Next →\"\n    {:ok,\n     %WebDriver.Protocol.Response{request: %WebDriver.Protocol.Request{body: \"{}\",\n       headers: [\"Content-Type\": \"application/json;charset=UTF-8\",\n        \"Content-Length\": 2], method: :POST,\n       url: \"http://localhost:57491/wd/hub/session/4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7/element/:wdc:1408353427808/click\"},\n      session_id: \"4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7\", status: 0, value: %{}}}\n    iex(9)\u003e current_url\n    \"http://elixir-lang.org/getting_started/2.html\"\n    iex(10)\u003e  Page.has_xpath? \"//h1[.='2 Diving in']\"\n    false\n    iex(11)\u003e go_back\n    {:ok,\n     %WebDriver.Protocol.Response{request: %WebDriver.Protocol.Request{body: \"{}\",\n       headers: [\"Content-Type\": \"application/json;charset=UTF-8\",\n        \"Content-Length\": 2], method: :POST,\n       url: \"http://localhost:57491/wd/hub/session/4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7/back\"},\n      session_id: \"4dc0b3b0-26b8-11e4-85b9-7b8e9f3c77e7\", status: 0, value: %{}}}\n    iex(12)\u003e current_path\n    \"/getting_started/1.html\"\n```\n\n## Using with Phoenix\n\nHere are some preliminary instructions for using TucoTuco for\ntesting Phoenix applications.\n\n### Dependencies\n\nEdit mix.exs to include the tuco_tuco dependency and to start TucoTuco in test mode.\n\n```elixir\n  def application do\n    [\n      mod: { Photuco, [] },\n      applications: applications(Mix.env)\n    ]\n  end\n\n  defp applications do\n    [:phoenix, :cowboy]\n  end\n\n  defp applications :test do\n    applications ++ [:tuco_tuco]\n  end\n\n  defp applications _ do\n    applications\n  end\n\n  defp deps do\n    [\n      {:phoenix, github: \"phoenixframework/phoenix\"},\n      {:cowboy, \"~\u003e 1.0.0\"},\n      {:tuco_tuco, \"~\u003e0.8.1\"}\n    ]\n  end\n```\n\n### Test Setup\n\nAdd the setup block for the tests in the `foo_test.exs` file\n\n```elixir\n  setup_all do\n    router = Phoenix.Project.module_root.Router\n    port = Phoenix.Config.get([router,:port])\n    router.start\n\n    {:ok, _} = TucoTuco.start_session :test_browser, :test_session, :firefox\n    TucoTuco.app_root \"http://localhost:#{port}\"\n\n    on_exit fn -\u003e TucoTuco.stop end\n    :ok\n  end\n```\n\n### Changelog\n2014-12-20\n  * 0.8.1\n  * Elixir 1.1.1 compatability\n\n2014-10-30\n  * 0.7.1\n  * Made password inputs fillable\n\n2014-10-23\n  * 0.7.0\n  * Add alert handling code\n\n2014-10-21\n  * 0.6.1\n  * Bump Webdriver version to 0.6.1\n\n2014-08-20\n  * 0.6.0\n  * Webdriver 0.6.0\n\n2014-08-17\n  * 0.5.1\n  * Webdriver 0.5.2\n  * Use hex.pm for deps\n\n2014-08-12\n  * 0.5.0\n  * Elixir-0.15.0\n  * Webdriver 0.5.0\n\n2014-03-06\n  * 0.4.0\n  * Added save_screenshot\n\n2014-03-04\n  * 0.3.0\n  * Added execute_javascript and execute_async_javascript\n\n2014-03-02\n  * 0.2.1\n  * Element functions from WebDriver\n  * Retries\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuart%2Ftuco_tuco","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstuart%2Ftuco_tuco","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstuart%2Ftuco_tuco/lists"}