diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 61edeb4..0ef154b 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -30,6 +30,8 @@ A release with an intentional breaking changes is marked with: ** {issue}647[#647]: Fix logic bug in `intersects?`. Added tests to test suite. ({person}dgr[@dgr]) ** {issue}649[#649]: When supplied a vector argument for `q-text`, `fill-multi` and `fill-human-multi` now fill fields in the order that fields appear in the vector. Previously, the order was not guaranteed. ({person}dgr[@dgr]) ** {issue}657[#657]: Make `set--timeout` functions resilient to reasonable non-integer timeouts (e.g., rationals, doubles, etc.). ({person}dgr[@dgr]) +* Docs +** {issue}656[#656]: Correctly describe behavior when query's parameter is a string. The User Guide and `query` doc strings say that a string passed to `query` is interpreted as an XPath expression. In fact, `query` interprets this as either XPath or CSS depending on the setting of the driver's `:locator` parameter, which can be changed. ({person}dgr[@dgr]) == v1.1.41 [minor breaking] - 2024-08-14 [[v1.1.41]] diff --git a/doc/01-user-guide.adoc b/doc/01-user-guide.adoc index d489cd5..ccb2f92 100644 --- a/doc/01-user-guide.adoc +++ b/doc/01-user-guide.adoc @@ -531,7 +531,10 @@ If you want to query for an element with an ID of "active", use the map syntax, (e/fill driver {:id "uname"} "Etaoin Again" k/enter) ---- -* a string containing an link:{xpath-sel}[XPath] expression. +* a string containing either an link:{xpath-sel}[XPath] or a link:{css-sel}[CSS] expression. +The way `query` interprets this string depends on the driver's `:locator` setting. +By default, the driver's `:locator` is set to `"xpath"`. +The `:locator` can be changed using the `use-css`, `with-css`, `use-xpath`, and `with-xpath` functions and macros. (Be careful when writing XPath manually; see <>.) Here, we find an `input` tag with an attribute `id` of `uname` and an attribute `name` of `username`: + @@ -543,6 +546,15 @@ Here, we find an `input` tag with an attribute `id` of `uname` and an attribute ;; let's check if that worked as expected: (e/get-element-value driver :uname) ;; => "XPath can be tricky" + +;; let's modify the driver to use CSS rather than XPath +;; note that this returns a new, modified copy of the driver +;; the old driver is still valid, however +(def driver-css (e/use-css driver)) +(e/refresh driver-css) +(e/fill driver-css "input#uname[name='username']" "CSS can be tricky, too") +(e/get-element-value driver-css :uname) +;; => "CSS can be tricky, too" ---- * a map with either `:xpath` or `:css` key with a string in corresponding syntax: diff --git a/src/etaoin/api.clj b/src/etaoin/api.clj index 26c4a94..e2f863c 100644 --- a/src/etaoin/api.clj +++ b/src/etaoin/api.clj @@ -602,25 +602,32 @@ - Note that `:active` conflicts with this usage and therefore you cannot search for a keyword named `:active` and expect to find an element with ID equal to \"active\". In this case, use `{:id \"active\"}`. - - an XPath expression: - - `\".//input[@id='uname']\"` + - a string that contains either an XPath or CSS expression, depending on the + driver's locator setting. Defaults to XPath. + See [[use-css]], [[with-css]], [[use-xpath]], [[with-xpath]] for methods + changing the driver's locator setting. + - XPath: `\".//input[@id='uname'][@name='username']\"` + - CSS: `\"input#uname[name='username']\"` - a map with either `:xpath` or `:css`: - `{:xpath \".//input[@id='uname']\"`}` - `{:css \"input#uname[name='username']\"}` - any other map is converted to an XPath expression: - `{:tag :div}` - is equivalent to XPath: `\".//div\"` - - multiple of the above (wrapped in a vector or not). - The result of each expression is fed into the next. - - `{:tag :div} \".//input[@id='uname']\"` - - `[{:tag :div} \".//input[@id='uname']\"]` + - multiple of the above (wrapped in a vector or not). + The result of each search anchors the search for the next, + effectively providing a path through the DOM (though you do not + have to specify each and every point in the path). + - `{:tag :div} \".//input[@id='uname']\"` + - `[{:tag :div} \".//input[@id='uname']\"]` + Returns the final element's unique identifier, or throws if any element + is not found. - Returns the found element's unique identifier, or throws when not found. - - See [Selecting Elements](/doc/01-user-guide.adoc#querying) for more details. + See [Selecting Elements](/doc/01-user-guide.adoc#querying) for more details. Makes use of: - https://www.w3.org/TR/webdriver2/#dfn-get-active-element + - https://www.w3.org/TR/webdriver2/#dfn-find-element - https://www.w3.org/TR/webdriver2/#dfn-find-element-from-element" ([driver q] (cond