BaristaLabs/chrome-dev-tools-generator

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:

https://github.com/BaristaLabs/chrome-dev-tools-runtime/blob/master/BaristaLabs.ChromeDevTools.Runtime.Tests/Tests/ScreenshotUnitTests.cs

Reopen if this isn't quite right. Thanks!