Skip to content

Commit

Permalink
Implicit performance enhancements for #163
Browse files Browse the repository at this point in the history
  • Loading branch information
lefthandedgoat committed Aug 24, 2014
1 parent d2365c5 commit 6202a0d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
25 changes: 14 additions & 11 deletions src/canopy/canopy.fs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ let waitFor2 message (f : unit -> bool) =
let waitFor = waitFor2 "Condition not met in given amount of time. If you want to increase the time, put compareTimeout <- 10.0 anywhere before a test to increase the timeout"

//find related
let rec private findElements cssSelector (searchContext : ISearchContext) : IWebElement list =
let rec private findElements cssSelector (searchContext : ISearchContext) counter : IWebElement list =
searchedFor <- (cssSelector, browser.Url) :: searchedFor
let findInIFrame () =
let iframes = findByCss "iframe" searchContext.FindElements
Expand All @@ -204,16 +204,17 @@ let rec private findElements cssSelector (searchContext : ISearchContext) : IWeb
iframes |> List.iter (fun frame ->
browser.SwitchTo().Frame(frame) |> ignore
let root = browser.FindElement(By.CssSelector("html"))
webElements := findElements cssSelector root
)
webElements := findElements cssSelector root counter
)
!webElements

try
let results =
configuredFinders cssSelector searchContext.FindElements
let results =
configuredFinders cssSelector (tryToOptimizeFindersForPerformance && counter <= 3) searchContext.FindElements
|> Seq.filter(fun list -> not(list.IsEmpty))
if Seq.isEmpty results then
findInIFrame()
if skipTryingToFindElementsInIFramesForPerformance && counter = 1 then
[]
else findInIFrame()
else
results |> Seq.head
with | ex -> []
Expand All @@ -224,12 +225,14 @@ let private findByFunction cssSelector timeout waitFunc searchContext reliable =
try
if reliable then
let elements = ref []
let counter = ref 0
wait.Until(fun _ ->
elements := waitFunc cssSelector searchContext
counter := !counter + 1
elements := waitFunc cssSelector searchContext !counter
not <| List.isEmpty !elements) |> ignore
!elements
else
wait.Until(fun _ -> waitFunc cssSelector searchContext)
wait.Until(fun _ -> waitFunc cssSelector searchContext 0)
with
| :? WebDriverTimeoutException ->
suggestOtherSelectors cssSelector
Expand Down Expand Up @@ -769,6 +772,6 @@ let coverage (url : 'a) =

let addFinder finder =
let currentFinders = configuredFinders
configuredFinders <- (fun cssSelector f ->
currentFinders cssSelector f
configuredFinders <- (fun cssSelector optimize f ->
currentFinders cssSelector optimize f
|> Seq.append (seq { yield finder cssSelector f }))
4 changes: 3 additions & 1 deletion src/canopy/configuration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ let mutable disableSuggestOtherSelectors = false
let mutable autoPinBrowserRightOnLaunch = true
let mutable throwIfMoreThanOneElement = false
let mutable configuredFinders = finders.defaultFinders
let mutable writeToSelectWithOptionValue = true
let mutable writeToSelectWithOptionValue = true
let mutable tryToOptimizeFindersForPerformance = true
let mutable skipTryingToFindElementsInIFramesForPerformance = true
31 changes: 24 additions & 7 deletions src/canopy/finders.fs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,32 @@ let findByValue value f =
findByCss (sprintf "*[value='%s']" value) f |> List.ofSeq
with | _ -> []

let mutable htmlElements = [ "html"; "body"; "ul"; "li"; "a "; "p "; "div"; "span"; "table"; "tr"; "td"; "thead"; "tbody"; "label"; "input"; "button"; "select"; "option"; "textarea" ] //using a(space) instead of a because I dont want to match any word starting with a

let mutable selectorIsProbablyXpath = fun (selector : string) -> selector.StartsWith("/") || selector.Contains("id(") || selector.Contains("text()")
let mutable selectorIsProbablyJQuery = fun (selector : string) -> not <| selectorIsProbablyXpath selector && selector.Contains(":") //:eq :contains etc
let mutable selectorIsProbablyCSS = fun (selector : string) -> not <| selectorIsProbablyJQuery selector && (selector.StartsWith("#") || selector.StartsWith(".") || htmlElements |> List.exists (fun html -> selector.StartsWith(html)))
let mutable selectorIsProbablyValue = fun (selector : string) -> not <| selectorIsProbablyCSS selector
let mutable selectorIsProbablyLabel = fun (selector : string) -> not <| selectorIsProbablyCSS selector
let mutable selectorIsProbablyText = fun (selector : string) -> not <| selectorIsProbablyCSS selector

//you can use this as an example to how to extend canopy by creating your own set of finders, tweaking the current collection, or adding/removing
let mutable defaultFinders =
(fun cssSelector f ->
(fun cssSelector optimize f ->
seq {
yield findByCss cssSelector f
yield findByValue cssSelector f
yield findByXpath cssSelector f
yield findByLabel cssSelector f
yield findByText cssSelector f
yield findByJQuery cssSelector f
if optimize then
if selectorIsProbablyCSS cssSelector then yield findByCss cssSelector f
if selectorIsProbablyValue cssSelector then yield findByValue cssSelector f
if selectorIsProbablyXpath cssSelector then yield findByXpath cssSelector f
if selectorIsProbablyLabel cssSelector then yield findByLabel cssSelector f
if selectorIsProbablyText cssSelector then yield findByText cssSelector f
if selectorIsProbablyJQuery cssSelector then yield findByJQuery cssSelector f
else
yield findByCss cssSelector f
yield findByValue cssSelector f
yield findByXpath cssSelector f
yield findByLabel cssSelector f
yield findByText cssSelector f
yield findByJQuery cssSelector f
}
)

0 comments on commit 6202a0d

Please sign in to comment.