/// <summary>
        /// This method scrolls element into view if needed, and then uses <seealso cref="Page.ScreenshotDataAsync(ScreenshotOptions)"/> to take a screenshot of the element.
        /// If the element is detached from DOM, the method throws an error.
        /// </summary>
        /// <returns>The task</returns>
        /// <param name="file">The file path to save the image to. The screenshot type will be inferred from file extension.
        /// If path is a relative path, then it is resolved relative to current working directory. If no path is provided,
        /// the image won't be saved to the disk.</param>
        /// <param name="options">Screenshot options.</param>
        public async Task ScreenshotAsync(string file, ScreenshotOptions options)
        {
            if (!options.Type.HasValue)
            {
                options.Type = ScreenshotOptions.GetScreenshotTypeFromFile(file);
            }

            var data = await ScreenshotDataAsync(options).ConfigureAwait(false);

            using (var fs = AsyncFileHelper.CreateStream(file, FileMode.Create))
            {
                await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
            }
        }
        internal static async Task <string> ReadProtocolStreamStringAsync(ChromiumSession client, string handle, string path)
        {
            var result = new StringBuilder();
            var fs     = !string.IsNullOrEmpty(path) ? AsyncFileHelper.CreateStream(path, FileMode.Create) : null;

            try
            {
                bool eof = false;

                while (!eof)
                {
                    var response = await client.SendAsync(new IOReadRequest
                    {
                        Handle = handle,
                    }).ConfigureAwait(false);

                    eof = response.Eof.Value;

                    result.Append(response.Data);

                    if (fs != null)
                    {
                        var data = Encoding.UTF8.GetBytes(response.Data);
                        await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
                    }
                }

                await client.SendAsync(new IOCloseRequest
                {
                    Handle = handle,
                }).ConfigureAwait(false);

                return(result.ToString());
            }
            finally
            {
                fs?.Dispose();
            }
        }
        internal static async Task <byte[]> ReadProtocolStreamByteAsync(ChromiumSession client, string handle, string path)
        {
            IEnumerable <byte> result = null;
            bool eof = false;
            var  fs  = !string.IsNullOrEmpty(path) ? AsyncFileHelper.CreateStream(path, FileMode.Create) : null;

            try
            {
                while (!eof)
                {
                    var response = await client.SendAsync(new IOReadRequest
                    {
                        Handle = handle,
                    }).ConfigureAwait(false);

                    eof = response.Eof.Value;
                    var data = Convert.FromBase64String(response.Data);
                    result = result == null ? data : result.Concat(data);

                    if (fs != null)
                    {
                        await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
                    }
                }

                await client.SendAsync(new IOCloseRequest
                {
                    Handle = handle,
                }).ConfigureAwait(false);

                return(result.ToArray());
            }
            finally
            {
                fs?.Dispose();
            }
        }
Esempio n. 4
0
        internal async Task <ElementHandle> AddStyleTagAsync(AddTagOptions options)
        {
            const string addStyleUrl     = @"async function addStyleUrl(url) {
              const link = document.createElement('link');
              link.rel = 'stylesheet';
              link.href = url;
              const promise = new Promise((res, rej) => {
                link.onload = res;
                link.onerror = rej;
              });
              document.head.appendChild(link);
              await promise;
              return link;
            }";
            const string addStyleContent = @"async function addStyleContent(content) {
              const style = document.createElement('style');
              style.type = 'text/css';
              style.appendChild(document.createTextNode(content));
              const promise = new Promise((res, rej) => {
                style.onload = res;
                style.onerror = rej;
              });
              document.head.appendChild(style);
              await promise;
              return style;
            }";

            if (!string.IsNullOrEmpty(options.Url))
            {
                var url = options.Url;
                try
                {
                    var context = await GetExecutionContextAsync().ConfigureAwait(false);

                    return((await context.EvaluateFunctionHandleAsync(addStyleUrl, url).ConfigureAwait(false)) as ElementHandle);
                }
                catch (PuppeteerException)
                {
                    throw new PuppeteerException($"Loading style from {url} failed");
                }
            }

            if (!string.IsNullOrEmpty(options.Path))
            {
                var contents = await AsyncFileHelper.ReadAllText(options.Path).ConfigureAwait(false);

                contents += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
                var context = await GetExecutionContextAsync().ConfigureAwait(false);

                return((await context.EvaluateFunctionHandleAsync(addStyleContent, contents).ConfigureAwait(false)) as ElementHandle);
            }

            if (!string.IsNullOrEmpty(options.Content))
            {
                var context = await GetExecutionContextAsync().ConfigureAwait(false);

                return((await context.EvaluateFunctionHandleAsync(addStyleContent, options.Content).ConfigureAwait(false)) as ElementHandle);
            }

            throw new ArgumentException("Provide options with a `Url`, `Path` or `Content` property");
        }
Esempio n. 5
0
        internal async Task <ElementHandle> AddScriptTagAsync(AddTagOptions options)
        {
            const string addScriptUrl     = @"async function addScriptUrl(url, type) {
              const script = document.createElement('script');
              script.src = url;
              if(type)
                script.type = type;
              const promise = new Promise((res, rej) => {
                script.onload = res;
                script.onerror = rej;
              });
              document.head.appendChild(script);
              await promise;
              return script;
            }";
            const string addScriptContent = @"function addScriptContent(content, type = 'text/javascript') {
              const script = document.createElement('script');
              script.type = type;
              script.text = content;
              let error = null;
              script.onerror = e => error = e;
              document.head.appendChild(script);
              if (error)
                throw error;
              return script;
            }";

            async Task <ElementHandle> AddScriptTagPrivate(string script, string urlOrContent, string type)
            {
                var context = await GetExecutionContextAsync().ConfigureAwait(false);

                return((string.IsNullOrEmpty(type)
                        ? await context.EvaluateFunctionHandleAsync(script, urlOrContent).ConfigureAwait(false)
                        : await context.EvaluateFunctionHandleAsync(script, urlOrContent, type).ConfigureAwait(false)) as ElementHandle);
            }

            if (!string.IsNullOrEmpty(options.Url))
            {
                var url = options.Url;
                try
                {
                    return(await AddScriptTagPrivate(addScriptUrl, url, options.Type).ConfigureAwait(false));
                }
                catch (PuppeteerException)
                {
                    throw new PuppeteerException($"Loading script from {url} failed");
                }
            }

            if (!string.IsNullOrEmpty(options.Path))
            {
                var contents = await AsyncFileHelper.ReadAllText(options.Path).ConfigureAwait(false);

                contents += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
                return(await AddScriptTagPrivate(addScriptContent, contents, options.Type).ConfigureAwait(false));
            }

            if (!string.IsNullOrEmpty(options.Content))
            {
                return(await AddScriptTagPrivate(addScriptContent, options.Content, options.Type).ConfigureAwait(false));
            }

            throw new ArgumentException("Provide options with a `Url`, `Path` or `Content` property");
        }