diff --git a/integration_test/cases/browser/fill_in_test.exs b/integration_test/cases/browser/fill_in_test.exs index b23c803e..867c6adb 100644 --- a/integration_test/cases/browser/fill_in_test.exs +++ b/integration_test/cases/browser/fill_in_test.exs @@ -73,6 +73,17 @@ defmodule Wallaby.Integration.Browser.FillInTest do end end + test "fill_in fields with labels by exact text", %{page: page} do + password = "$uper$ecret" + + page + |> fill_in(Query.text_field("Password"), with: password) + |> fill_in(Query.text_field("Confirm Password"), with: password) + + assert find(page, Query.css("#password_field")) |> has_value?(password) + assert find(page, Query.css("#confirm_password_field")) |> has_value?(password) + end + test "escapes quotes", %{page: page} do assert fill_in(page, Query.text_field("I'm a text field"), with: "Stuff") end diff --git a/integration_test/support/pages/forms.html b/integration_test/support/pages/forms.html index 819890c3..47066bed 100644 --- a/integration_test/support/pages/forms.html +++ b/integration_test/support/pages/forms.html @@ -9,8 +9,13 @@

Forms

+ + + + + diff --git a/lib/wallaby/query/xpath.ex b/lib/wallaby/query/xpath.ex index 9303f43c..ec152e49 100644 --- a/lib/wallaby/query/xpath.ex +++ b/lib/wallaby/query/xpath.ex @@ -31,7 +31,7 @@ defmodule Wallaby.Query.XPath do Match any radio buttons """ def radio_button(query) do - ~s{.//input[./@type = 'radio'][(((./@id = "#{query}" or ./@name = "#{query}") or ./@placeholder = "#{query}") or ./@id = //label[contains(normalize-space(string(.)), "#{query}")]/@for)] | .//label[contains(normalize-space(string(.)), "#{query}")]//.//input[./@type = "radio"]} + ~s{.//input[./@type = 'radio'][(((./@id = "#{query}" or ./@name = "#{query}") or ./@placeholder = "#{query}") or ./@id = //label[normalize-space(string(text())) = "#{query}"]/@for)] | .//label[normalize-space(string(text())) = "#{query}"]//.//input[./@type = "radio"]} end @doc """ @@ -40,21 +40,21 @@ defmodule Wallaby.Query.XPath do `hidden`, or `file`. """ def fillable_field(query) when is_binary(query) do - ~s{.//*[self::input | self::textarea][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'radio' or ./@type = 'checkbox' or ./@type = 'hidden' or ./@type = 'file')][(((./@id = "#{query}" or ./@name = "#{query}") or ./@placeholder = "#{query}") or ./@id = //label[contains(normalize-space(string(.)), "#{query}")]/@for)] | .//label[contains(normalize-space(string(.)), "#{query}")]//.//*[self::input | self::textarea][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'radio' or ./@type = 'checkbox' or ./@type = 'hidden' or ./@type = 'file')]} + ~s{.//*[self::input | self::textarea][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'radio' or ./@type = 'checkbox' or ./@type = 'hidden' or ./@type = 'file')][(((./@id = "#{query}" or ./@name = "#{query}") or ./@placeholder = "#{query}") or ./@id = //label[normalize-space(string(text())) = "#{query}"]/@for)] | .//label[normalize-space(string(text())) = "#{query}"]//.//*[self::input | self::textarea][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'radio' or ./@type = 'checkbox' or ./@type = 'hidden' or ./@type = 'file')]} end @doc """ Match any checkboxes """ def checkbox(query) do - ~s{.//input[./@type = 'checkbox'][(((./@id = "#{query}" or ./@name = "#{query}") or ./@placeholder = "#{query}") or ./@id = //label[contains(normalize-space(string(.)), "#{query}")]/@for)] | .//label[contains(normalize-space(string(.)), "#{query}")]//.//input[./@type = "checkbox"]} + ~s{.//input[./@type = 'checkbox'][(((./@id = "#{query}" or ./@name = "#{query}") or ./@placeholder = "#{query}") or ./@id = //label[normalize-space(string(text())) = "#{query}"]/@for)] | .//label[normalize-space(string(text())) = "#{query}"]//.//input[./@type = "checkbox"]} end @doc """ Match any `select` by name, id, or label. """ def select(query) do - ~s{.//select[(((./@id = "#{query}" or ./@name = "#{query}")) or ./@name = //label[contains(normalize-space(string(.)), "#{query}")]/@for or ./@id = //label[contains(normalize-space(string(.)), "#{query}")]/@for)] | .//label[contains(normalize-space(string(.)), "#{query}")]//.//select} + ~s{.//select[(((./@id = "#{query}" or ./@name = "#{query}")) or ./@name = //label[normalize-space(string(text())) = "#{query}"]/@for or ./@id = //label[normalize-space(string(text())) = "#{query}"]/@for)] | .//label[normalize-space(string(text())) = "#{query}"]//.//select} end @doc """ @@ -68,7 +68,7 @@ defmodule Wallaby.Query.XPath do Matches any file field by name, id, or label """ def file_field(query) do - ~s{.//input[./@type = 'file'][(((./@id = "#{query}" or ./@name = "#{query}")) or ./@id = //label[contains(normalize-space(string(.)), "#{query}")]/@for)] | .//label[contains(normalize-space(string(.)), "#{query}")]//.//input[./@type = 'file']} + ~s{.//input[./@type = 'file'][(((./@id = "#{query}" or ./@name = "#{query}")) or ./@id = //label[normalize-space(string(text())) = "#{query}"]/@for)] | .//label[normalize-space(string(text())) = "#{query}"]//.//input[./@type = 'file']} end @doc """