-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Selectors improvements #73
Comments
Hi Sergey, thanks for opening a ticket! For the first part you would want to see something like: let subElement = elementWithin (element "#someSection") ".subElement" elementWithin being the new method with the signature similar to what you provided? let subElements = elementsWithin (element "#someSection") ".subElement" For the second part something like this? let e = someElement ".selector" Currently 'element' will try over and over to find an element up to the aloted timeout before failing (mainly useful for ajaxy sites). Would someElement do the same or be fast, returning None if nothing exists? |
Yes, you are right for the first part: let elementsWithin cssSelector (element:IWebElement) =
element.FindElements(By.CssSelector(cssSelector)) to be able use it in pipelining root |> elementWithin "a" |> getHref
root |> elementWithin "p.title" |> getText For the second part will be nice to have two methods: I think it should try over and over up to timeout (to be sure that such element really does not exist). Now I use the following code: let someElement s =
match (s |> elements) with
| [x] -> Some(x)
| [] -> None
| _ -> failwith "Selected too much elements" It fails when user expects for one element, but in fact there are more. (I think, it means that script is wrong and we have to tell the user about this) Current implementation of One more useful selector is a let parentElement (element:IWebElement) =
element.FindElement(By.XPath("..")) or even maybe something more generic let elementByXPath xPath (element:IWebElement) =
element.FindElement(By.XPath(xPath)) |
According to my current understanding, that it will be as follows: let elementsWithin cssSelector (element:IWebElement) =
element.FindElements(By.CssSelector(cssSelector)) |> Seq.toList
let private someElementFromList elementsList =
match elementsList with
| [x] -> Some(x)
| [] -> None
| _ -> failwith "Selected too much elements"
let someElement cssSelector =
cssSelector |> elements |> someElementFromList
let someElementWithin cssSelector element =
element |> elementsWithin cssSelector |> someElementFromList
let elementsByXPath xPath (element:IWebElement) =
element.FindElements(By.XPath(xPath)) |> Seq.toList
let someElementByXPath xPath element =
element |> elementsByXPath xPath |> someElementFromList
let parentElement element =
element |> someElementByXPath ".." |> Option.get I think that I do not need |
Very cool, I will need to build in retry-ability into elementsWithin which may take some time. I will try to have a new build with these additions today. Thanks! |
Sergey, canopy 0.7.3 is released and pushed to nuget. I will have the documentation updated by end of day tomorrow. If you need to see examples before then you can look into the commits linked to this issue. I didn't add the xpath version of the methods, instead I added implicit xpath searching which should work with all existing operations. Thanks for the suggestions, let me know if something is not working as you expected or have more suggestions! |
It will be nice to have more powerful css-selectors in canopy
Sub-element selectors.
Something like this:
There are very useful if you need to make search into DOM sub-tree.
Option as result for select-one selectors (like
element
)Expected behavior is to get
Some(IWebElement)
if exactly one element existsNone
if there is no such elementsThe text was updated successfully, but these errors were encountered: