How to upload file in canopy? - f#

I have an upload file input on page. How can I test this element in canopy? How to set path to file in input? I tried standard '<<' operator but it doesn't seem to be working in this case.

Setting the file upload input to the full name of the file should be all you need. The following works for me:
#r "../packages/Selenium.WebDriver.2.48.2/lib/net40/WebDriver.dll"
#r "../packages/Selenium.Support.2.48.2/lib/net40/WebDriver.Support.dll"
#r "../packages/canopy.0.9.43/lib/canopy.dll"
open canopy
open System.IO
// I copied chromedriver.exe next to the script file
chromeDir <- __SOURCE_DIRECTORY__
start chrome
url "https://encodable.com/uploaddemo/"
let fileToUpload = FileInfo(Path.Combine(__SOURCE_DIRECTORY__, __SOURCE_FILE__))
"#uploadname1" << fileToUpload.FullName
click "#uploadbutton"
I'm not affiliated with encodable.com in any way. Please use your own service for testing.

Related

F# interactive window folder and type provider default folder

I already changed the folder to my project folder. F# interactive:how to display/change current working directory
However, it got the following error when I sent let xml = XmlProvider<"./DbToken.xml">.GetSample() to interactive window.
DbShared.fs(66,11): error FS3033: The type provider 'ProviderImplementation.XmlProvider' reported an error: Cannot read sample XML from './DbToken.xml': Could not find file 'C:\Users\a\AppData\Local\Temp\DbToken.xml'.
You can set Environment.CurrentDirectory as in the comment but you can also specify the path to the xml file:
[<Literal>]
let xmlpath = __SOURCE_DIRECTORY__ + "/test.xml"
And then say: let xml = XmlProvider<xmlpath>.GetSample()

Meaning of CsvProvider error "The given key was not present in the dictionary" when trying to load sample file?

I am having trouble loading the csv files with FSharp.Data csv provider provided by fslab, including the sample adwords.csv file.
What does this error below mean? Also, when I hover over the code in the Visual studio editor it mentions that "The given key was not present in the dictionary"
Problem example:
#load "packages/FsLab/FsLab.fsx"
open System.IO
open FSharp.Data
"adwords.csv"
|> File.ReadAllLines
let test = CsvProvider<"adwords.csv">.GetSample()
The output:
>
val it : string [] =
[|"Criteria ID,Name,Canonical Name,Parent ID,Country Code,Target Type,Status";
"1000010,Abu Dhabi,"Abu Dhabi,Abu Dhabi,United Arab Emirates",9041082,AE,City,Active";
"1000011,Ajman,"Ajman,Ajman,United Arab Emirates",9047096,AE,City,Active";
"1000012,Al Ain,"Al Ain,Abu Dhabi,United Arab Emirates",9041082,AE,City,Active";
"1000013,Dubai,"Dubai,Dubai,United Arab Emirates",9041083,AE,City,Active";
"2004,Afghanistan,Afghanistan,,AF,Country,Active"|]
>
>System.MethodAccessException: Attempt by method '<StartupCode$FSI_0007>.$FSI_0007.main#()' to access method 'FSharp.Data.Runtime.CsvFile`1<System.__Canon>.Create(System.Func`3<System.Object,System.String[],System.__Canon>,
at <StartupCode$FSI_0007>.$FSI_0007.main#() in C:\test.fsx:line 11
Stopped due to error
I ran into this problem with my own files, so I grabbed this sample file from here: https://raw.githubusercontent.com/fsharp/FSharp.Data/master/tests/FSharp.Data.Tests/Data/Adwords.csv
Debug info:
If I delete the FSharp.Data library folder (v 2.3.0) and replace with version 2.2.5 it works correctly with no error.
If I don't use the FsLab.fsx script and instead use
#I "packages/FSharp.Data/lib/net40
#r "FSharp.Data.dll"
then everything works.
The path to the FsLab.fsx script is correct, it runs when I send the line to fsi.
The F# version is 14.0.23413.0.
The version of FSharp.Data downloaded by FSlab is FSharp.Data.2.3.0.
I have no other references in the .fsx script.
I am using Visual Studio Community edition 14.0.24720.00 Update 1.
.NET version 4.6.01038
I am realizing now that I am not getting the popup asking if I want to allow the .dll like I think I used to get when I used this before.
There is nothing wrong with the file. This for example works:
#load #"..\..\FSLAB\packages\FsLab\FsLab.fsx"
open System.IO
open FSharp.Data
[<Literal>]
let csvFile = #"C:\tmp\adwords.csv"
File.Exists csvFile
type Csv = CsvProvider<csvFile>
let csv = Csv.Load(csvFile)
csv.Rows
There is something wrong with your FsLab of FSharp.Data installation or type providers security maybe. Try the following, specify the path to the file directly. If it still doesn't work just nuget FSharp.Data and try using the csv type provider directly in a new project.
Other info is also helpful. VS version, FSLab version, wha other references you have. etc.
EDIT: Thanks for the debug info. That's actually quite helpful. VS2015 Update 1 broke two things, the Binding Redirect for Fsharp and the type providers (that might have been FSharp Tools, I forgot). I would upgrade to Update 2. If that's not possible please check if your FSharp.Data.TypeProviders.dll is in C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\Type Providers.
As referencing the dlls directly works, it's probably a version mismatch issue. My FsLab install predates VS2015 Update 1 and 2, so will see if it behaves differently with a new download.
There is some issue with the installation of FSharp.Data currently bundled with FsLab (as of June 2016). This issue is with version 2.3.0. If you instead use FSharp.Data 2.2.5 the code works as expected.
Delete the packages/FSharp.Data folder and replace with version 2.2.5. I did it from an old installation but you could do it from Nuget

Fsx execution path

I have a c# .net library I am looking to use within FSI/FSX. As part of the initialization of the .net lib, by default it expects and references a custom config file (MyAppConfig.xml) which loads various things before it can be used. When using it in c# it gets copied to the bin folder and the app by default expects it to be there and references it there unless there is a specific entry in the app.config to tell it otherwise. (I should add that it does it all by convention rather than injecting a path + filename, as per NLog, say)
I have an f# source file in a console app which will execute this initialization find, but I can't quite work out how to achieve this with FSI/FSX.
So my program.fs looks simply like
open System
open myApp
module Program =
[<EntryPoint>]
let Main(args) =
myApp.Initialization.Load() // references MyAppConfig.xml
Console.WriteLine("do my stuff!")
Console.ReadLine() |> ignore
0
If I try and do the same in FSI or using FSX, I have
#r #"E:\...path to MyApp...\MyApp.dll"
#I #"E:\...path to MyAppConfig.xml ..."
Environment.CurrentDirectory <- #"E:\...path to MyAppConfig.xml ..."
myApp.Initialization.Load() |> ignore // fails ... can't find MyAppConfig.xml
//do my stuff
I suspect that I've not got the paths quite right.
I'd be grateful of a steer
EDIT:
So I've managed to attach a debugger to the c# lib and see where it is looking for the config file - turns out it is "c:\Program Files\Microsoft F#\v4.0\" ( System.AppDomain.CurrentDomain.BaseDirectory) which again shows I've not quite understood how to tell FSI/FSX to use a particular path. If I copy the config file (MyAppConfig.xml) to that location it works fine.
Many thx
S
I'm not sure of the implications, but one possiblity might be temporarily changing the app base:
let origAppBase = AppDomain.CurrentDomain.BaseDirectory
AppDomain.CurrentDomain.SetData("APPBASE", "path_to_MyAppConfig.xml")
myApp.Initialization.Load() |> ignore
AppDomain.CurrentDomain.SetData("APPBASE", origAppBase) //restore original app base

F# Module/Namespace Error

My first program with F#.
I have one file like so:
namespace LanguageMapper.Data
#if INTERACTIVE
#r "System.Data"
#r "System.Data.Linq"
#r "FSharp.Data.TypeProviders"
#endif
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
module Data =
// You can use Server Explorer to build your ConnectionString.
type SqlConnection = Microsoft.FSharp.Data.TypeProviders.SqlDataConnection<ConnectionString = #"connstring">
let db = SqlConnection.GetDataContext()
Then i have another file like so
namespace LanguageMapper.Program
open Data
module Program =
[<EntryPoint>]
let main argv =
let getLocale x =
match x with
| [|"live"|] -> "live"
| [|"dev"|] -> "dev"
| _ -> "local"
Over top of the open Data i get a red squiggly in VS telling me:
"Error 1 This declaration opens the namespace or module
'Microsoft.FSharp.Data' through a partially qualified path. Adjust
this code to use the full path of the namespace. This change will make
your code more robust as new constructs are added to the F# and CLI
libraries."
What am i doing wrong? I just want to reference one file from the other.
You need to open the module using its fully qualified name, that is including its namespace. So in LanguageMapper.Program you need to open LanguageMapper.Data.Data (only the last bit is the module name).
The Compiler is complaining on your open definition because it only specifies to open a namespace or module named Data - and it finds one in Microsoft.FSharp.Data, probably because there are some 'automatic' opens for the Microsoft.FSharp namespaces.

process.start from a variable location %temp%

I have the program unzipping the file to %temp%\myfolder\
I need to run a file from within that location.
I have tried both shell and process.start but ultimately I'm looking for:
Process.start("%temp%\myfolder\start.cmd")
Also I looked on msdn on the getenvironmentvariable but nothing has worked. :(
Update: This is what I have in a nutshell
Imports system.diagnostics
Imports system.IO
System.Environment.GetEnvironmentVariable("TEMP")
Dim temp As String = System.IO.Path.GetTempPath
Things I have tried
process.start("%temp%\myfolder\start.cmd")
process.start("temp" & "myfolder\start.cmd")
I get an error code saying "file not found". But if I copy %temp%\myfolder\start.cmd into run or cmd.exe the program runs.
First set the
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("temp")
' Possible variables include temp, tmp, and windir for examples.
This command will place the current directory as C:\Users\ (currentuser)\appdata\local\temp or which ever the variable is set for. Then run process start. It should look like this:
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("temp")
Process.start("myfolder\start.cmd")

Resources