I've utilized the following links for reference, but still cannot get my code to print the HTML
<title>This is the title</title>
Using Selenium Code with F# Canopy
http://lefthandedgoat.github.io/canopy/actions.html
The following 3 lines of code do not print what I am expecting (I am attempting C# at the end as another way to do this). What I had expected this to do, was extract the TITLE from my HTML file and print it to the console window. I do not have a "purpose" for this yet, but I was just testing all of the actions available in the documentation.
let theTitle = title()
printfn "Page title is: %s" title()
System.Console.WriteLine("Print the title here: {0}", theTitle);
With this code:
let title() = #"<title>This is the title</title>"
printfn "Page title is: %s" (title())
Page title is: <title>This is the title</title>
I get the expected result. Due to F# type inference restrictions, you need to use a pair of brackets around title().
Related
I have a selenium UI test written with F# (using canopy selenium nuget package). I have a module that defines page selectors and helper functions. The page module is called by a test module. Within the test module, I am calling a function called 'handlemobimodals()', which runs four sub functions (if/else code blocks) that look for the existence of an element on a page and click on it, if it exists.
The problem I'm facing is that when the 'handlemobimodals()' function is called for a second time within the test, I get a Stack Overflow Exception (WebDriver Process is terminated due to StackOverflowException), right after its first sub function is called.
The function runs completely fine for the first time (called indirectly from another function earlier in the test), but fails the second time when called directly in the test. I'm pretty new to F# and I can't figure out how I'm causing a recursion in my test as the stackoverflow exception suggests.
Any insights would be greatly appreciated.
Snippet from Page Module:
module some_page
let isOKGotItDisplayed () =
isDisplayed <| "div.action-button.dismiss-overlay"
let clickOKGotit() =
if isOKGotItDisplayed() = true then
click "OK, GOT IT"
describe "OK, Got It clicked"
else describe "Got nothing"
let isGoToSearchDisplayed() =
isDisplayed <| "button:contains('Go to Search')"
let clickGoToSearch() =
if isGoToSearchDisplayed() = true then
click "button:contains('Go to Search')"
describe "go search button clicked"
else describe "Got nothing"
let isSkipDisplayed() =
isDisplayed <| "#uploadPhotos > div.continue.skip"
let clickSkip() =
if isSkipDisplayed() = true then
click "Skip"
describe "Skip link clicked"
else describe "Got nothing"
let mobiOkayGotItDisplayed () =
isDisplayed <| "Okay, got it"
let mobiOKGotit() =
if mobiOkayGotItDisplayed() = true then
click "Okay, got it"
describe "Okay, got it"
else describe "Got nothing"
let handleMobiModals() =
clickSkip()
clickOKGotit()
clickGoToSearch()
mobiOKGotit()
loginForPathAs user =
username << "somename"
paswword << "somepassword"
handleMobiModals()
Snippet from Test Module (note the first instance of the handleMobiModals function is called in the LoginforPathAs function, which is defined in the same page definition module):
module_sometest
open some_page
"Test 001: Log in and do something" &&& fun _ ->
newBrowser platform
loginForPathAs user1
displayed quicknoteSendButton
click quicknoteSendButton
handleMobiModals ()
displayed "Subscribe"
Note: Snippets are edited for simplicity and clarity.
It's not a direct answer, but I believe it would help to find the problem much easier. I did notice something that makes it somewhat difficult to debug this problem. You're calling multiple functions from another function, and calling this single function from a test. Splitting out these functions into separate tests and changing the tests into WIP mode should help to pinpoint your issue. There are a lot of possible points of failure within that one test.
For instance, you can use before(fun _ -> some function(s) here) or once(fun _ -> some function(s) here) within your context in Canopy to start a new browser and login, separating that part from the test.
This issue appears to have resolved itself. I believe my most recent auto-update for Chrome fixed the problem.
I'm trying to print out all the elements in this array, and when I display it, it only prints out Pickup laundry.
var todo = ["Return Calls", "Write blog", "Cook Dinner", "Pickup laundry"]
for element in todo {
print(element)
}
I'm not sure why this is wrong...
I copied your code and pasted it into an app. I ran the app. I saw this in the console:
Return Calls
Write blog
Cook Dinner
Pickup laundry
So I conclude that either you are lying — that is not your code, or that is not what is printed — or you don't know how to test (e.g. you don't know how to read the console or you're in a playground and you don't understand where the console is).
I would like to use non-literal strings for the "format" parameter of a logging type function, as shown here:
// You need to make c:\testDir or something similar to run this.....
//
let csvFile = #"c:\testDir\foo.csv"
open System.IO
let writer file (s:string) =
use streamWriter = new StreamWriter(file, true)
streamWriter.WriteLine(s)
// s
let log format = Printf.ksprintf (writer csvFile) format
let oneString format = (Printf.StringFormat<string->string> format)
let format = oneString "(this does not %s)"
//log format "important string"
log "this works %s" "important string"
My first attempt used a literal string, and the above fragment should work fine for you if you create the directory it needs or similar.
After discovering that you can't just "let bind" a format string, I then learned about Printf.StringFormatand more details about Printf.ksprintf, but I am obviously missing something, because I can't get them to work together with my small example.
If you comment out the last line and reinstate its predecessor, you will see a compiler error.
Making the function writer return a string almost helped (uncomment its last line), but that then makes log return a string (which means every call now needs an ignore).
I would like to know how to have my format strings dynamically settable within the type checked F# printf world!
Update
I added the parameter format to log to avoid a value restriction error that happens if log is not later called as it is in my example. I also change fmt to format in oneString.
Update
This is a different question from this one. That question does not show a function argument being passed to Printf.StringFormat (a minor difference), and it does not have the part about Printf.ksprintf not taking a continuation function that returns unit.
I thought I had found a solution with:
let oneString format = (Printf.StringFormat<string->string,unit> format)
this compiles, but there is a runtime error. (The change is the ,unit)
The MSDN page about XML documentation shows that you can write simple things like:
/// <summary>Builds a new string whose characters are the results of applying the function <c>mapping</c>
/// to each of the characters of the input string and concatenating the resulting
/// strings.</summary>
/// <param name="mapping">The function to produce a string from each character of the input string.</param>
///<param name="str">The input string.</param>
///<returns>The concatenated string.</returns>
///<exception cref="System.ArgumentNullException">Thrown when the input string is null.</exception>
val collect : (char -> string) -> string -> string
But can you embed images in your XML documentation?
You can include <img ... /> and other HTML tags in the XML documentation. I just tried this and Visual Studio simply skips over the image (so you will not see it in the IntelliSense) but the fshtmldoc tool in F# Power Pack simply copies the HTML tags to the output HTML document including images.
/// <summary>Hi <img src="http://tomasp.net/img/fpman.jpg" /> there!</summary>
type IMultiKey =
// (...)
Gives me the following generated documentation:
I think the C# compiler does some additional validation of the XML tags, but I do not think this is done in the F# compiler. As an aside, I find writing the XML documents a annoyingly long, so I was playing with using F# Formatting to write them in Markdown instead (but I do not have anything ready yet).
i am learning asp.net mvc just going through online tutorial
1) just see <span>#model.Message</span> and #Html.Raw(model.Message)
suppose if "Hello Word" is stored in Message then "Hello Word" should display if i write statement like
<span>#model.Message</span> but i just could not understand what is the special purpose about #Html.Raw(model.Message).
what #Html.Raw() will render ?
please discuss with few more example to understand the difference well.
2) just see the below two snippet
#if (foo) {
<text>Plain Text</text>
}
#if (foo) {
#:Plain Text is #bar
}
in which version of html the tag called was introduce. is it equivalent to or what ? what is the purpose of
this tag ?
just tell me about this #:Plain Text is #bar
what is the special meaning of #: ?
if our intention is to mixing text with expression then can't we write like Plain Text is #bar
3) <span>ISBN#(isbnNumber)</span>
what it will print ? if 2000 is stored in isbnNumber variable then it may print <span>ISBN2000</span>. am i right ?
so tell me what is the special meaning of #(variable-name) why bracket along with # symbol ?
4) just see
<span>In Razor, you use the
##foo to display the value
of foo</span>
if foo has value called god then what this ##foo will print ?
5 ) see this and guide me about few more syntax given below point wise
a) #(MyClass.MyMethod<AType>())
b)
#{
Func<dynamic, object> b =
#<strong>#item</strong>;
}
#b("Bold this")
c) <div class="#className foo bar"></div>
6) see this
#functions
{
string SayWithFunction(string message)
{
return message;
}
}
#helper SayWithHelper(string message)
{
Text: #message
}
#SayWithFunction("Hello, world!")
#SayWithHelper("Hello, world!")
what they are trying to declare ? function ?
what kind of syntax it is ?
it seems that two function has been declare in two different way ? please explain this points with more sample. thanks
Few More question
7)
#{
Func<dynamic, object> b = #<strong>#item</strong>;
}
<span>This sentence is #b("In Bold").</span>
what the meaning of above line ? is it anonymous delegate?
when some one will call #b("In Bold") then what will happen ?
8)
#{
var items = new[] { "one", "two", "three" };
}
<ul>
#items.List(#<li>#item</li>)
</ul>
tell me something about List() function and from where the item variable come ?
9)
#{
var comics = new[] {
new ComicBook {Title = "Groo", Publisher = "Dark Horse Comics"},
new ComicBook {Title = "Spiderman", Publisher = "Marvel"}
};
}
<table>
#comics.List(
#<tr>
<td>#item.Title</td>
<td>#item.Publisher</td>
</tr>)
</table>
please explain briefly the above code. thanks
1) Any kind of #Variable output makes MVC automatically encode the value. That is to say if foo = "Joe & Dave", then #foo becomes Joe & Dave automatically. To escape this behavior you have #Html.Raw.
2) <text></text> is there to help you when the parser is having trouble. You have to keep in mind Razor goes in and out of HTML/Code using the semantics of the languages. that is to say, it knows it's in HTML using the XML parser, and when it's in C#/VB by its syntax (like braces or Then..End respectively). When you want to stray from this format, you can use <text>. e.g.
<ul>
<li>
#foreach (var item in items) {
#item.Description
<text></li><li></text>
}
</li>
</ul>
Here you're messing with the parser because it no longer conforms to "standard" HTML blocks. The </li> would through razor for a loop, but because it's wrapped in <text></text> it has a more definitive way of knowing where code ends and HTML begins.
3) Yes, the parenthesis are there to help give the parser an explicit definition of what should be executed. Razor makes its best attempt to understand what you're trying to output, but sometimes it's off. The parenthesis solve this. e.g.
#Foo.bar
If you only had #Foo defined as a string, Razor would inevitably try to look for a bar property because it follows C#'s naming convention (this would be a very valid notation in C#, but not our intent). So, to avoid it from continuing on we can use parenthesis:
#(Foo).bar
A notable exception to this is when there is a single trailing period. e.g.
Hello, #name.
The Razor parser realizes nothing valid (in terms of the language) follows, so it just outputs name and a period thereafter.
4) ## is the escape method for razor when you need to actually print #. So, in your example, you'd see #foo on the page in plain text. This is useful when outputting email addresses directly on the page, e.g.
bchristie##contoso.com
Now razor won't look for a contoso.com variable.
5) You're seeing various shortcuts and usages of how you bounce between valid C# code and HTML. Remember that you can go between, and the HTML you're seeing is really just a compiled IHtmlString that is finally output to the buffer.
1.
By default, Razor automatically html-encodes your output values (<div> becomes <div>). #Html.Raw should be used when you explicitly want to output the value as-is without any encoding (very common for outputting JSON strings in the middle of a <script>).
2.
The purpose of <text> and #: is to escape the regular Razor syntax flow and output literal text values. for example:
// i just want to print "Haz It" if some condition is true
#if (Model.HasSomething) { Haz It } // syntax error
#if (Model.HasSomething) { <text>Haz It</text> } // just fine
As of #:, it begins a text literal until the next line-feed (enter), so:
#if (Model.HasSomething) { #:Haz It } // syntax error, no closing '}' encountered
// just fine
#if (Model.HasSomething)
{
#:Haz It
}
3.
By default, if your # is inside a quote/double-quotes (<tr id="row#item.Id"), Razor interprets it as a literal and will not try to parse it as expression (for obvious reasons), but sometimes you do want it to, then you simply write <tr id="row#(item.Id").
4.
The purpose of ## is simply to escape '#'. when you want to output '#' and don't want Razor to interpret is as an expression. then in your case ##foo would print '#foo'.
5.
a. #(MyClass.MyMethod<AType>()) would simply output the return value of the method (using ToString() if necessary).
b. Yes, Razor does let you define some kind of inline functions, but usually you better use Html Helpers / Functions / DisplayTemplates (as follows).
c. See above.
6.
As of Razor Helpers, see http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx