Page finished loading event
pebezo opened this issue · 6 comments
Do you have an example of how to subscribe to the page load event? The example below never fires.
session.Page.SubscribeToLoadEventFiredEvent((e) =>
{
Console.WriteLine("Finished loading...");
});
I'm trying to navigate and capture a screenshot of a page. It works if I call Sleep(1000) and then capture, which leads me to believe that the issue is that I'm trying to capture the screenshot before the page fully loads.
Here's the full (non-working) example:
using (var session = new ChromeSession("ws://localhost:9222/devtools/page/" + targetId))
{
var navigateResult = session.Page.Navigate(new Page.NavigateCommand
{
Url = "https://www.google.com"
}).GetAwaiter().GetResult();
// This does not work...
session.Page.SubscribeToLoadEventFiredEvent((e) =>
{
Console.WriteLine("Finished loading...");
});
//System.Threading.Thread.Sleep(1000);
Console.WriteLine("Taking a screenshot!");
var screenshotResponse = session.Page.CaptureScreenshot(new Page.CaptureScreenshotCommand
{
}).GetAwaiter().GetResult();
File.WriteAllBytes("ss\\" + Guid.NewGuid().ToString("N") + ".png", Convert.FromBase64String(screenshotResponse.Data));
Console.WriteLine("Done.");
Console.ReadKey();
}
Thanks
To handle events you must first Enable them. For Page it
session.Page.Enable(new Page.EnableCommand())
OK, that worked, but how can I tell it to wait until the page finished loading and only then take a screenshot? If I move the CaptureScreenshot
inside the SubscribeToLoadEventFiredEvent
I get:
System.InvalidOperationException: 'A command response was not received: Page.captureScreenshot'
GetAwaiter().GetResult() not always work correctly in callbacks (other thread). Forget about it and use new C# 7.1 features async Task Main in console apps. Using C# 7.1 . Install Visual Studio Preview and enable C# 7.1 in project properties->Build->Advanced
//C# 7.1
static async Task Main(string[] args)
{
//Launch Chrome With
//"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9223
Console.WriteLine("Hello World!");
var sessions = await GetSessions("http://localhost:9223/"); //.GetAwaiter().GetResult();
using (var session = new ChromeSession(sessions.First(s => s.Type == "page").WebSocketDebuggerUrl))
{
try
{
await session.Page.Enable(new Page.EnableCommand());
//session.Page.SubscribeToLoadEventFiredEvent(async (e2) =>
session.Page.SubscribeToDomContentEventFiredEvent(async (e2) =>
{
var screenshot = await session.Page.CaptureScreenshot(new Page.CaptureScreenshotCommand());
if (!string.IsNullOrWhiteSpace(screenshot.Data))
{
var dir = @"C:\temp";
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
var i = 0;
var path = "";
do
{
i++;
path = Path.Combine(dir, $"screenshot{i}.png");
} while (File.Exists(path));
File.WriteAllBytes(path, Convert.FromBase64String(screenshot.Data));
Console.WriteLine($"saved to {path}");
}
});
var navigateResult = await session.Page.Navigate(new Page.NavigateCommand
{
Url = "https://www.google.com/"
});
Console.ReadLine();
//await session.Page.Disable(new Page.DisableCommand());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
All works now in console. In WPF no need in C# 7.1, from C# 5 it works.
Look my projects: console, WPF example
Console.ReadLine(); must be in using block to prevent session dispose
session.Page.Navigate waits Page to be loaded. It works:
using (var session = new ChromeSession(sessions.First(s => s.Type == "page").WebSocketDebuggerUrl))
{
var navigateResult = session.Page.Navigate(new Page.NavigateCommand
{
Url = "https://www.google.com/"
}).GetAwaiter().GetResult();
var screenshot = session.Page.CaptureScreenshot(new Page.CaptureScreenshotCommand()).GetAwaiter().GetResult();
SaveScreenshot(screenshot);
Console.ReadLine();
}
If I move the CaptureScreenshot inside the SubscribeToLoadEventFiredEvent I get:
System.InvalidOperationException: 'A command response was not received: Page.captureScreenshot'
Page.captureScreenshot in other thread will work. Wrap it with
Task.Run(() => { Page.captureScreenshot ... });
There is some issues with multithreading requests in this lib. #8
It sounds like this has been handled (thanks @ToCSharp!) However, I've also added a unit test demonstrating this here:
Reopen if this isn't quite right. Thanks!