diff --git a/src/canopy/canopy.fs b/src/canopy/canopy.fs index d3526ae5..9292dbf7 100644 --- a/src/canopy/canopy.fs +++ b/src/canopy/canopy.fs @@ -278,35 +278,41 @@ let first cssSelector = (elements cssSelector).Head let last cssSelector = (List.rev (elements cssSelector)).Head //read/write -let private writeToSelect cssSelector text = - let elem = element cssSelector +let private writeToSelect (elem:IWebElement) (text:string) = let options = Seq.toList (elem.FindElements(By.XPath(sprintf "option[text()='%s']" text))) match options with - | [] -> raise (CanopyOptionNotFoundException(sprintf "element %s does not contain value %s" cssSelector text)) + | [] -> raise (CanopyOptionNotFoundException(sprintf "element %s does not contain value %s" (elem.ToString()) text)) | head::tail -> head.Click() -let ( << ) cssSelector text = - wait elementTimeout (fun _ -> - let writeToElement (e : IWebElement) = - if e.TagName = "select" then - writeToSelect cssSelector text - else - let readonly = e.GetAttribute("readonly") - if readonly = "true" then - raise (CanopyReadOnlyException(sprintf "element %s is marked as read only, you can not write to read only elements" cssSelector)) - try e.Clear() with ex -> ex |> ignore - e.SendKeys(text) - - elements cssSelector - |> List.map (fun elem -> - try - writeToElement elem - true - with - | :? CanopyReadOnlyException as ex -> reraise() - | _ -> false) - |> List.exists (fun elem -> elem = true) +let private writeToElement (e : IWebElement) (text:string) = + if e.TagName = "select" then + writeToSelect e text + else + let readonly = e.GetAttribute("readonly") + if readonly = "true" then + raise (CanopyReadOnlyException(sprintf "element %s is marked as read only, you can not write to read only elements" (e.ToString()))) + try e.Clear() with ex -> ex |> ignore + e.SendKeys(text) + +let ( << ) item text = + match box item with + | :? IWebElement as elem -> writeToElement elem text + | :? string as cssSelector -> + wait elementTimeout (fun _ -> + elements cssSelector + |> List.map (fun elem -> + try + writeToElement elem text + true + with + //Note: Enrich exception with proper cssSelector description + | :? CanopyReadOnlyException -> raise (CanopyReadOnlyException(sprintf "element %s is marked as read only, you can not write to read only elements" cssSelector)) + | _ -> false) + |> List.exists (fun elem -> elem = true) ) + | _ -> raise (CanopyNotStringOrElementException(sprintf "Can't read %O because it is not a string or element" item)) + + let private textOf (element : IWebElement) = match element.TagName with diff --git a/tests/basictests/Program.fs b/tests/basictests/Program.fs index ea8ef62f..10df6413 100644 --- a/tests/basictests/Program.fs +++ b/tests/basictests/Program.fs @@ -85,6 +85,13 @@ test (fun _ -> "#lastName" << "Smith" "#lastName" == "Smith" +"writing to #lastName (as element) sets text to John" &&& fun _ -> + !^ testpage + let lastname = element "#lastname" + clear lastname + lastname << "John" + lastname == "John" + "writing to .lastName sets text to new Smith in both boxes" &&& fun _ -> !^ testpage clear "#lastName" @@ -590,7 +597,7 @@ context "pluggable finders tests" //and let canopy do the work of trying to find something by convention let findByHref href f = try - let cssSelector = sprintf "a[href='%s']" href + let cssSelector = sprintf "a[href*='%s']" href f(By.CssSelector(cssSelector)) |> List.ofSeq with | ex -> []