Search code examples
f#canopy-web-testing

Site scraping with F# and Canopy


I am trying to write a simple scraper using F# and Canopy (see http://lefthandedgoat.github.io/canopy/). I am trying to extract text from all element with the class ".application-tile". However, in the code below, I get the following build error and I don't understand it.

This expression was expected to have type
    OpenQA.Selenium.IWebElement -> 'a    
but here has type
    OpenQA.Selenium.IWebElement

Any idea why this is happening? Thanks!

open canopy
open runner
open System

[<EntryPoint>]
let main argv = 
    start firefox

    "taking canopy for a spin" &&& fun _ ->
        url "https://abc.com/"

        // Login Page
        "#i0116" << "abc@abc.com"
        "#i0118" << "abc"
        click "#abcButton"

        // Get the Application Tiles -- BUILD ERROR HAPPENS HERE
        elements ".application-tile" |> List.map (fun tile -> (tile |> (element ".application-name breakWordWrap"))) |> ignore

    run()

Solution

  • open canopy
    open runner
    
    start firefox
    
    "taking canopy for a spin" &&& fun _ ->
        url "http://lefthandedgoat.github.io/canopy/testpages/"
    
        // Get the tds in tr
        let results = elements "#value_list td" |> List.map read
    
        //or print them using iter
        elements "#value_list td" 
            |> List.iter (fun element -> System.Console.WriteLine(read element))
    
    run()
    

    That should do what you want.

    canopy has function called 'read' that takes in either a selector or an element. Since you have all of them from 'elements "selector"' you can map read over the list.

    List.map takes in a function, runs it, and returns a list of results. (in C# its like elements.Select(x => read(x)) List.iter is the same as .foreach(x => System.Console.Writeline(read(x))