Reputation: 3755
I guess this is a classic C# to F# conversion I haven't quite got my head around.
I am trying to automate a browser using the quick start
https://playwright.dev/dotnet/docs/intro
The C# code is
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.GotoAsync("http://www.bing.com");
await page.ScreenshotAsync(path: outputFile);
I've made a start but getting a bit lost already.
let playwright: Playwright = PlaywrightSharp.Playwright.CreateAsync() |> Async.AwaitTask
Incorrect type. What am I doing wrong here?
Error FS0001 This expression was expected to have type
'Playwright'
but here has type
'Async<IPlaywright>'
Upvotes: 4
Views: 744
Reputation: 516
As of F# 6, tasks are now natively supported through the task computation expression. The syntax will be almost identical to the async computation expression from Brian Berns's answer, except that you no longer need to call Async.AwaitTask
on each let!
, use!
, or do!
binding.
let screenshotTask =
task {
use! playwright = Playwright.CreateAsync ()
use! browser = playwright.Chromium.LaunchAsync ()
let! page = browser.NewPageAsync ()
let! _ = page.GotoAsync "https://www.bing.com"
let! _ = page.ScreenshotAsync (PageScreenshotOptions(Path = "screenshot.png"))
return ()
}
screenshotTask.Wait ()
Upvotes: 2
Reputation: 17038
One way to do this is with a F#'s built-in support for async computation expressions. The translation would look something like this:
let (~~) = Async.AwaitTask
async {
use! playwright = ~~Playwright.CreateAsync()
let! browser = ~~playwright.Chromium.LaunchAsync()
let! page = ~~browser.NewPageAsync()
do! ~~page.GoToAsync("http://www.slashdot.com") |> Async.Ignore
do! ~~page.ScreenshotAsync(outputFile) |> Async.Ignore
} |> Async.RunSynchronously
There are a few subtleties here that you'll need to know about:
Async<'T>
. I've used Async.AwaitTask
to convert from C#-style tasks, and defined a prefix operator, ~~
, to make this look a bit cleaner.DisposeAsync
in async
computation expressions yet, so the browser doesn't get disposed of properly. If you want, you can add do! browser.DisposeAsync().AsTask() |> Async.AwaitTask
at the end of the block to do this manually.Async.Ignore
.Upvotes: 1
Reputation: 2436
You can use the TaskBuilder framework https://github.com/rspeele/TaskBuilder.fs
dotnet add package Taskbuilder.fs
and write
task {
use! playwright = Playwright.CreateAsync()
let! browser = playwright.Chromium.LaunchAsync()
let! page = browser.NewPageAsync()
let! response = page.GoToAsync("http://www.bing.com")
let! title = page.GetTitleAsync()
printfn "%s" title
}
|> Task.WaitAll
Upvotes: 2