2

I have a problem as below. I use the CefSharp offscreen for webpage automation as follows (I open only one and the same page): 1. Open page and wait untill it renders*. 2. With EvaluateScriptAsync I put on value to input form and then with the same method I click the button on webpage. 3. Then there is some JS on this webpage that check result and displays a message. 4. When the message is displayed I make a screenshot. **

However, I have two problems: * My sulution has to be Internet speed proof. And As I used BrowserLoadingStateChanged event and IsLoading method, even though that the events fired the webpage did not load completly - when I started the EavluateScriptAsync method it gives back error because the page was not completly loaded. Sure, I can put sth like ThreadSleep but it does not always work - it is strongly dependent on Your internet speed.

** When I try to make a screenshot it does not always contain the result message displayed by JS - sometimes there is a loading circle instead of message. And here again I can use THreadSleep but it does not always work.

Do You have any ideas? Thanks in advance.

private static void BrowserLoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
        {
            // Check to see if loading is complete - this event is called twice, one when loading starts
            // second time when it's finished
            // (rather than an iframe within the main frame).
            if (!e.IsLoading)
            {
                // Remove the load event handler, because we only want one snapshot of the initial page.
                browser.LoadingStateChanged -= BrowserLoadingStateChanged;

                Thread.Sleep(1800); // e. g. but it isn't a solution in fact

                var scriptTask = browser.EvaluateScriptAsync("document.getElementById('b-7').value = 'something'");



                scriptTask = browser.EvaluateScriptAsync("document.getElementById('b-8').click()");

                //scriptTask.Wait();

                if (browser.IsLoading == false)
                {
                    scriptTask.ContinueWith(t =>
                    {

                        //Give the browser a little time to render
                        //Thread.Sleep(500);
                        Thread.Sleep(500); // still not a solution

                        // Wait for the screenshot to be taken.
                        var task = browser.ScreenshotAsync();
                        task.ContinueWith(x =>
                        {
                            // Make a file to save it to (e.g. C:\Users\jan\Desktop\CefSharp screenshot.png)
                            var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot.png");

                            Console.WriteLine();
                            Console.WriteLine("Screenshot ready. Saving to {0}", screenshotPath);

                            // Save the Bitmap to the path.
                            // The image type is auto-detected via the ".png" extension.
                            task.Result.Save(screenshotPath);

                            // We no longer need the Bitmap.
                            // Dispose it to avoid keeping the memory alive.  Especially important in 32-bit applications.
                            task.Result.Dispose();

                            Console.WriteLine("Screenshot saved.  Launching your default image viewer...");

                            // Tell Windows to launch the saved image.
                            Process.Start(screenshotPath);

                            Console.WriteLine("Image viewer launched.  Press any key to exit.");
                        }, TaskScheduler.Default);
                    });
                }


            }
        }
Mikisz
  • 404
  • 5
  • 20

2 Answers2

0

Ok, so in my case the best sollution was to use javascript to check if element by id exists. If yes then the page is loaded.

Mikisz
  • 404
  • 5
  • 20
  • Loaded, but may still not be rendered. – AgentFire Sep 23 '17 at 21:16
  • True - loaded but may not be rendered however still basing on info that it is loaded and reading some other forums I've ended with soluttion to use thread sleep 200 and in all tests on different hardware page was rendered. Even in CefSharp demo offscreen there is suggestion to use thread sleep to wait until page s rendered. – Mikisz Sep 28 '17 at 16:41
  • What if some process will use all the CPU up? May be there is a way to check if the Chrome's rendering app/processor/therad has become idle? – AgentFire Sep 28 '17 at 18:07
0

I noticed that render time may vary significantly depending on your hardware. It can take up to 5 seconds to render after EvaluateScriptAsync was called. So it always better to do longer delays before calling ScreenshotAsync() if you do not want to get outdated screenshot.

Thread.Sleep(5000);
Trinitron
  • 374
  • 3
  • 12