示例#1
0
        public async Task <Response> NavigateFrameAsync(Frame frame, string url, NavigationOptions options)
        {
            var referrer = string.IsNullOrEmpty(options.Referer)
               ? NetworkManager.ExtraHTTPHeaders?.GetValueOrDefault(MessageKeys.Referer)
               : options.Referer;
            var requests = new Dictionary <string, Request>();
            var timeout  = options?.Timeout ?? DefaultNavigationTimeout;

            using (var watcher = new LifecycleWatcher(this, frame, timeout, options))
            {
                try
                {
                    var navigateTask = NavigateAsync(Client, url, referrer, frame.Id);
                    var task         = await Task.WhenAny(
                        watcher.TimeoutOrTerminationTask,
                        navigateTask).ConfigureAwait(false);

                    await task;

                    task = await Task.WhenAny(
                        watcher.TimeoutOrTerminationTask,
                        _ensureNewDocumentNavigation?watcher.NewDocumentNavigationTask : watcher.SameDocumentNavigationTask
                        ).ConfigureAwait(false);

                    await task;
                }
                catch (Exception ex)
                {
                    throw new NavigationException(ex.Message, ex);
                }

                return(watcher.NavigationResponse);
            }
        }
        public async Task <Response> WaitForFrameNavigationAsync(Frame frame, NavigationOptions options = null)
        {
            var timeout = options?.Timeout ?? DefaultNavigationTimeout;

            using (var watcher = new NavigatorWatcher(_client, this, frame, _networkManager, timeout, options))
            {
                var raceTask = await Task.WhenAny(
                    watcher.NewDocumentNavigationTask,
                    watcher.SameDocumentNavigationTask,
                    watcher.TimeoutOrTerminationTask
                    ).ConfigureAwait(false);

                var exception = raceTask.Exception;
                if (exception == null &&
                    watcher.TimeoutOrTerminationTask.IsCompleted &&
                    watcher.TimeoutOrTerminationTask.Result.IsFaulted)
                {
                    exception = watcher.TimeoutOrTerminationTask.Result.Exception;
                }
                if (exception != null)
                {
                    throw new NavigationException(exception.Message, exception);
                }

                return(watcher.NavigationResponse);
            }
        }
        public NavigatorWatcher(FrameManager frameManager, Frame mainFrame, int timeout, NavigationOptions options)
        {
            var waitUntil = new[] { WaitUntilNavigation.Load };

            if (options?.WaitUntil != null)
            {
                waitUntil = options.WaitUntil;
            }

            _expectedLifecycle = waitUntil.Select(w =>
            {
                var protocolEvent = _puppeteerToProtocolLifecycle.GetValueOrDefault(w);
                Contract.Assert(protocolEvent != null, $"Unknown value for options.waitUntil: {w}");
                return(protocolEvent);
            });

            _frameManager              = frameManager;
            _frame                     = mainFrame;
            _options                   = options;
            _initialLoaderId           = mainFrame.LoaderId;
            _timeout                   = timeout;
            _hasSameDocumentNavigation = false;

            frameManager.LifecycleEvent += CheckLifecycleComplete;
            frameManager.FrameNavigatedWithinDocument += NavigatedWithinDocument;
            frameManager.FrameDetached       += CheckLifecycleComplete;
            SameDocumentNavigationTaskWrapper = new TaskCompletionSource <bool>();
            NewDocumentNavigationTaskWrapper  = new TaskCompletionSource <bool>();
            TimeoutTask = TaskHelper.CreateTimeoutTask(timeout);
        }
示例#4
0
        private async Task <Response> WaitForNavigation(NavigationOptions options = null)
        {
            var mainFrame = _frameManager.MainFrame;
            var timeout   = options?.Timeout ?? DefaultNavigationTimeout;
            var watcher   = new NavigatorWatcher(_frameManager, mainFrame, timeout, options);
            var responses = new Dictionary <string, Response>();

            EventHandler <ResponseCreatedEventArgs> createResponseEventListener = (object sender, ResponseCreatedEventArgs e) =>
                                                                                  responses.Add(e.Response.Url, e.Response);

            _networkManager.ResponseCreated += createResponseEventListener;

            await watcher.NavigationTask;

            _networkManager.ResponseCreated -= createResponseEventListener;

            var exception = watcher.NavigationTask.Exception;

            if (exception != null)
            {
                throw new NavigationException(exception.Message, exception);
            }

            return(responses.GetValueOrDefault(_frameManager.MainFrame.Url));
        }
示例#5
0
        public async Task <Response> ReloadAsync(NavigationOptions options = null)
        {
            var navigationTask = WaitForNavigation(options);

            await Task.WhenAll(
                navigationTask,
                _client.SendAsync("Page.reload")
                );

            return(navigationTask.Result);
        }
示例#6
0
        public async Task <Response> GoToAsync(string url, NavigationOptions options = null)
        {
            var referrer = _networkManager.ExtraHTTPHeaders?.GetValueOrDefault("referer");
            var requests = new Dictionary <string, Request>();

            EventHandler <RequestEventArgs> createRequestEventListener = (object sender, RequestEventArgs e) =>
            {
                if (!requests.ContainsKey(e.Request.Url))
                {
                    requests.Add(e.Request.Url, e.Request);
                }
            };

            _networkManager.RequestCreated += createRequestEventListener;

            var mainFrame = _frameManager.MainFrame;
            var timeout   = options?.Timeout ?? DefaultNavigationTimeout;

            var watcher      = new NavigatorWatcher(_frameManager, mainFrame, timeout, options);
            var navigateTask = Navigate(_client, url, referrer);

            await Task.WhenAny(
                navigateTask,
                watcher.NavigationTask
                );

            var exception = navigateTask.Exception;

            if (exception == null)
            {
                await watcher.NavigationTask;
                exception = watcher.NavigationTask.Exception;
            }

            watcher.Cancel();
            _networkManager.RequestCreated -= createRequestEventListener;

            if (exception != null)
            {
                throw new NavigationException(exception.Message, exception);
            }

            Request request = null;

            if (requests.ContainsKey(_frameManager.MainFrame.Url))
            {
                request = requests[_frameManager.MainFrame.Url];
            }

            return(request?.Response);
        }
        public async Task <Response> WaitForFrameNavigationAsync(Frame frame, NavigationOptions options = null)
        {
            var timeout = options?.Timeout ?? TimeoutSettings.NavigationTimeout;

            using (var watcher = new LifecycleWatcher(this, frame, options?.WaitUntil, timeout))
            {
                var raceTask = await Task.WhenAny(
                    watcher.NewDocumentNavigationTask,
                    watcher.SameDocumentNavigationTask,
                    watcher.TimeoutOrTerminationTask).ConfigureAwait(false);

                await raceTask.ConfigureAwait(false);

                return(watcher.NavigationResponse);
            }
        }
        public NavigatorWatcher(
            CDPSession client,
            FrameManager frameManager,
            Frame mainFrame,
            NetworkManager networkManager,
            int timeout,
            NavigationOptions options)
        {
            var waitUntil = new[] { WaitUntilNavigation.Load };

            if (options?.WaitUntil != null)
            {
                waitUntil = options.WaitUntil;
            }

            _expectedLifecycle = waitUntil.Select(w =>
            {
                var protocolEvent = _puppeteerToProtocolLifecycle.GetValueOrDefault(w);
                Contract.Assert(protocolEvent != null, $"Unknown value for options.waitUntil: {w}");
                return(protocolEvent);
            });

            _frameManager              = frameManager;
            _frame                     = mainFrame;
            _options                   = options;
            _initialLoaderId           = mainFrame.LoaderId;
            _timeout                   = timeout;
            _hasSameDocumentNavigation = false;

            frameManager.LifecycleEvent += CheckLifecycleComplete;
            frameManager.FrameNavigatedWithinDocument += NavigatedWithinDocument;
            frameManager.FrameDetached += OnFrameDetached;
            networkManager.Request     += OnRequest;
            var connection = Connection.FromSession(client);

            connection.Closed += (sender, e)
                                 => Terminate(new TargetClosedException("Navigation failed because browser has disconnected!", connection.CloseReason));

            _sameDocumentNavigationTaskWrapper = new TaskCompletionSource <bool>();
            _newDocumentNavigationTaskWrapper  = new TaskCompletionSource <bool>();
            _terminationTaskWrapper            = new TaskCompletionSource <bool>();
            _timeoutTask = TaskHelper.CreateTimeoutTask(timeout);
        }
示例#9
0
        internal async Task SetContentAsync(string html, NavigationOptions options = null)
        {
            var waitUntil = options?.WaitUntil ?? new[] { WaitUntilNavigation.Load };
            var timeout   = options?.Timeout ?? _timeoutSettings.NavigationTimeout;

            // We rely upon the fact that document.open() will reset frame lifecycle with "init"
            // lifecycle event. @see https://crrev.com/608658
            await EvaluateFunctionAsync(@"html => {
                document.open();
                document.write(html);
                document.close();
            }", html).ConfigureAwait(false);

            var watcher     = new LifecycleWatcher(_frameManager, Frame, waitUntil, timeout);
            var watcherTask = await Task.WhenAny(
                watcher.TimeoutOrTerminationTask,
                watcher.LifecycleTask).ConfigureAwait(false);

            await watcherTask.ConfigureAwait(false);
        }
示例#10
0
        public async Task <Response> NavigateFrameAsync(Frame frame, string url, NavigationOptions options)
        {
            var referrer = string.IsNullOrEmpty(options.Referer)
               ? _networkManager.ExtraHTTPHeaders?.GetValueOrDefault(MessageKeys.Referer)
               : options.Referer;
            var requests = new Dictionary <string, Request>();
            var timeout  = options?.Timeout ?? DefaultNavigationTimeout;

            using (var watcher = new NavigatorWatcher(_client, this, frame, _networkManager, timeout, options))
            {
                var navigateTask = NavigateAsync(_client, url, referrer, frame.Id);
                await Task.WhenAny(
                    watcher.TimeoutOrTerminationTask,
                    navigateTask).ConfigureAwait(false);

                AggregateException exception = null;
                if (navigateTask.IsFaulted)
                {
                    exception = navigateTask.Exception;
                }
                else
                {
                    await Task.WhenAny(
                        watcher.TimeoutOrTerminationTask,
                        _ensureNewDocumentNavigation?watcher.NewDocumentNavigationTask : watcher.SameDocumentNavigationTask
                        ).ConfigureAwait(false);

                    if (watcher.TimeoutOrTerminationTask.IsCompleted && watcher.TimeoutOrTerminationTask.Result.IsFaulted)
                    {
                        exception = watcher.TimeoutOrTerminationTask.Result.Exception;
                    }
                }

                if (exception != null)
                {
                    throw new NavigationException(exception.InnerException.Message, exception.InnerException);
                }

                return(watcher.NavigationResponse);
            }
        }
        public LifecycleWatcher(
            FrameManager frameManager,
            Frame frame,
            int timeout,
            NavigationOptions options)
        {
            var waitUntil = _defaultWaitUntil;

            if (options?.WaitUntil != null)
            {
                waitUntil = options.WaitUntil;
            }

            _expectedLifecycle = waitUntil.Select(w =>
            {
                var protocolEvent = _puppeteerToProtocolLifecycle.GetValueOrDefault(w);
                Contract.Assert(protocolEvent != null, $"Unknown value for options.waitUntil: {w}");
                return(protocolEvent);
            });

            _frameManager              = frameManager;
            _frame                     = frame;
            _options                   = options;
            _initialLoaderId           = frame.LoaderId;
            _timeout                   = timeout;
            _hasSameDocumentNavigation = false;

            _sameDocumentNavigationTaskWrapper = new TaskCompletionSource <bool>();
            _newDocumentNavigationTaskWrapper  = new TaskCompletionSource <bool>();
            _lifecycleTaskWrapper   = new TaskCompletionSource <bool>();
            _terminationTaskWrapper = new TaskCompletionSource <bool>();

            frameManager.LifecycleEvent += CheckLifecycleComplete;
            frameManager.FrameNavigatedWithinDocument += NavigatedWithinDocument;
            frameManager.FrameDetached          += OnFrameDetached;
            frameManager.NetworkManager.Request += OnRequest;
            frameManager.Client.Disconnected    += OnClientDisconnected;
        }
示例#12
0
        public NavigatorWatcher(FrameManager frameManager, Frame mainFrame, int timeout, NavigationOptions options)
        {
            var waitUntil = new[] { WaitUntilNavigation.Load };

            if (options?.WaitUntil != null)
            {
                waitUntil = options.WaitUntil;
            }

            _expectedLifecycle = waitUntil.Select(w =>
            {
                var protocolEvent = _puppeteerToProtocolLifecycle.GetValueOrDefault(w);
                Contract.Assert(protocolEvent != null, $"Unknown value for options.waitUntil: {w}");
                return(protocolEvent);
            });

            _frameManager    = frameManager;
            _frame           = mainFrame;
            _options         = options;
            _initialLoaderId = mainFrame.LoaderId;
            _timeout         = timeout;

            frameManager.LifecycleEvent += FrameManager_LifecycleEvent;
            frameManager.FrameDetached  += FrameManager_LifecycleEvent;
            LifeCycleCompleteTaskWrapper = new TaskCompletionSource <bool>();

            NavigationTask = Task.WhenAny(new[]
            {
                CreateTimeoutTask(),
                LifeCycleCompleteTask,
            }).ContinueWith((task) =>
            {
                CleanUp();
                return(task.GetAwaiter().GetResult());
            });
        }
示例#13
0
 /// <summary>
 /// Sets the HTML markup to the page
 /// </summary>
 /// <param name="html">HTML markup to assign to the page.</param>
 /// <param name="options">The options</param>
 /// <returns>Task.</returns>
 /// <seealso cref="Page.SetContentAsync(string, NavigationOptions)"/>
 public Task SetContentAsync(string html, NavigationOptions options = null)
 => SecondaryWorld.SetContentAsync(html, options);
示例#14
0
 /// <summary>
 /// This resolves when the frame navigates to a new URL or reloads.
 /// It is useful for when you run code which will indirectly cause the frame to navigate.
 /// </summary>
 /// <param name="options">navigation options</param>
 /// <returns>Task which resolves to the main resource response.
 /// In case of multiple redirects, the navigation will resolve with the response of the last redirect.
 /// In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`.
 /// </returns>
 /// <remarks>
 /// Usage of the <c>History API</c> <see href="https://developer.mozilla.org/en-US/docs/Web/API/History_API"/> to change the URL is considered a navigation
 /// </remarks>
 /// <example>
 /// <code>
 /// <![CDATA[
 /// var navigationTask =frame.page.WaitForNavigationAsync();
 /// await frame.ClickAsync("a.my-link");
 /// await navigationTask;
 /// ]]>
 /// </code>
 /// </example>
 public Task <Response> WaitForNavigationAsync(NavigationOptions options = null) => FrameManager.WaitForFrameNavigationAsync(this, options);
示例#15
0
 /// <summary>
 /// Navigates to an url
 /// </summary>
 /// <remarks>
 /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will throw an error if:
 /// - there's an SSL error (e.g. in case of self-signed certificates).
 /// - target URL is invalid.
 /// - the `timeout` is exceeded during navigation.
 /// - the remote server does not respond or is unreachable.
 /// - the main resource failed to load.
 ///
 /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will not throw an error when any valid HTTP status code is returned by the remote server,
 /// including 404 "Not Found" and 500 "Internal Server Error".  The status code for such responses can be retrieved by calling <see cref="Response.Status"/>
 ///
 /// > **NOTE** <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> either throws an error or returns a main resource response.
 /// The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
 ///
 /// > **NOTE** Headless mode doesn't support navigation to a PDF document. See the <see fref="https://bugs.chromium.org/p/chromium/issues/detail?id=761295">upstream issue</see>.
 /// </remarks>
 /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>
 /// <param name="options">Navigation parameters.</param>
 /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.</returns>
 /// <seealso cref="GoToAsync(string, int?, WaitUntilNavigation[])"/>
 public Task <Response> GoToAsync(string url, NavigationOptions options) => FrameManager.NavigateFrameAsync(this, url, options);
示例#16
0
        public static async Task Main(string[] args)
        {
            var currentDirectory = Directory.GetCurrentDirectory();
            var downloadPath     = Path.Combine(currentDirectory, "CustomChromium");

            Console.WriteLine($"Attemping to set up puppeteer to use Chromium found under directory {downloadPath} ");

            if (!Directory.Exists(downloadPath))
            {
                Console.WriteLine("Custom directory not found. Creating directory");
                Directory.CreateDirectory(downloadPath);
            }

            Console.WriteLine("Downloading Chromium...");

            var browserFetcherOptions = new BrowserFetcherOptions {
                Path = downloadPath
            };
            var browserFetcher = new BrowserFetcher(browserFetcherOptions);
            await browserFetcher.DownloadAsync(BrowserFetcher.DefaultRevision);

            var executablePath = browserFetcher.GetExecutablePath(BrowserFetcher.DefaultRevision);

            if (string.IsNullOrEmpty(executablePath))
            {
                Console.WriteLine("Custom Chromium location is empty. Unable to start Chromium. Exiting.\n Press any key to continue");
                Console.ReadLine();
                return;
            }

            Console.WriteLine($"Attemping to start Chromium using executable path: {executablePath}");

            var options = new LaunchOptions {
                Headless = true, ExecutablePath = executablePath
            };

            using (var browser = await Puppeteer.LaunchAsync(options))
                using (var page = await browser.NewPageAsync())
                {
                    await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
                    await page.SetViewportAsync(new ViewPortOptions { Width = 1920, Height = 1080 });

                    var waitUntil = new NavigationOptions {
                        Timeout = 0, WaitUntil = new[] { WaitUntilNavigation.Networkidle0 }
                    };
                    string url = "https://github.com/puppeteer/puppeteer/issues/1345";
                    await page.GoToAsync(url, waitUntil);

                    #region Screenshot Dashboard:
                    var optionsScreenShot = new ScreenshotOptions {
                        FullPage = true
                    };
                    //Đường dẫn lưu file
                    var savePath = Path.Combine(currentDirectory, "Capture");
                    if (!Directory.Exists(savePath))
                    {
                        Console.WriteLine("SavePath directory not found. Creating directory");
                        Directory.CreateDirectory(savePath);
                    }
                    string date       = DateTime.Now.ToString("yyyyMMddHHmmss");
                    var    outputfile = savePath + "/capture_" + date + ".png";
                    await page.ScreenshotAsync(outputfile, optionsScreenShot);

                    Console.WriteLine("Capture completed! Path: " + outputfile, ConsoleColor.Green);
                    #endregion

                    await page.CloseAsync();
                }
            return;
        }