Esempio n. 1
0
        public async Task ShouldWorkInRealLife()
        {
            var options = TestConstants.DefaultBrowserOptions();

            using (var browser = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
                using (var page = await browser.NewPageAsync())
                {
                    var response = await page.GoToAsync("https://www.google.com");

                    Assert.Equal(HttpStatusCode.OK, response.Status);
                }
        }
Esempio n. 2
0
        public async Task BackgroundPageTargetTypeShouldBeAvailable()
        {
            using (var browserWithExtension = await Puppeteer.LaunchAsync(
                       TestConstants.BrowserWithExtensionOptions(),
                       TestConstants.LoggerFactory))
                using (var page = await browserWithExtension.NewPageAsync())
                {
                    var backgroundPageTarget = await WaitForBackgroundPageTargetAsync(browserWithExtension);

                    Assert.NotNull(backgroundPageTarget);
                }
        }
        public async Task <IActionResult> Post(PostHtmlToImageDTO dto)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");

            if (dto is null)
            {
                throw new ArgumentNullException(nameof(dto));
            }

#if true == DEBUG
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
#endif

            ViewPortOptions defaultViewport = null;
            if (dto.Width.HasValue && dto.Height.HasValue)
            {
                defaultViewport = new ViewPortOptions
                {
                    Width  = dto.Width.Value,
                    Height = dto.Height.Value
                }
            }
            ;

            using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true,
                Args = new[] { "--no-sandbox" },
                DefaultViewport = defaultViewport
            }))
                using (var page = await browser.NewPageAsync())
                {
                    string text = null;

                    if (!string.IsNullOrWhiteSpace(dto.HtmlBase64))
                    {
                        var buff = Convert.FromBase64String(dto.HtmlBase64);
                        text = UTF8Encoding.UTF8.GetString(buff);
                    }
                    else if (!string.IsNullOrWhiteSpace(dto.Html))
                    {
                        text = dto.Html;
                    }

                    await page.SetContentAsync(text);

                    var image = await page.ScreenshotDataAsync();

                    return(new FileContentResult(image, "image/png"));
                }
        }
    }
        private async void button2_Click(object sender, EventArgs e)
        {
            radProgressBar1.Maximum = radListView1.Items.Count;
            radProgressBar1.Text    = "0/" + radProgressBar1.Maximum + "  |  (0.00 %)";
            panel1.Visible          = true;
            button1.Enabled         = false;
            button2.Enabled         = false;
            string[] arg = { "--window-size=1000,1400" };
            browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless        = Properties.Settings.Default.headless,
                DefaultViewport = new ViewPortOptions {
                    Height = 1080, Width = 1400
                },
                Args           = arg,
                ExecutablePath = Properties.Settings.Default.chromepath
            });

            var page = browser.PagesAsync().Result[0];

            var cookiesfile = File.ReadAllText("cookies.json");
            var cookiesdata = JsonConvert.DeserializeObject <List <CookieParam> >(cookiesfile);
            await page.SetCookieAsync(cookiesdata[0]);

            await page.GoToAsync("https://www.fuvi-clan.com/myaccount/download-lists/");


            await page.WaitForSelectorAsync("#menu-menu-principal > li.menu-item.menu-item-type-fuvilist.menu-item-type-fuvilist-cart.nav-item.dropdown > a > img", new WaitForSelectorOptions { Visible = true });

            await page.EvaluateFunctionAsync("()=>document.querySelector(\"#menu-menu-principal > li.menu-item.menu-item-type-fuvilist.menu-item-type-fuvilist-cart.nav-item.dropdown > a > img\").click()");

            await page.WaitForSelectorAsync("#btn_create_fuvilist", new WaitForSelectorOptions { Visible = true });

            var nblist = await page.EvaluateFunctionAsync("()=>document.querySelector(\"#menu-menu-principal > li.menu-item.menu-item-type-fuvilist.menu-item-type-fuvilist-cart.nav-item.dropdown.show > ul > li > div > div.col-12.col-xl-4 > div > select\").length");

            for (int i = 2; i <= Convert.ToInt32(nblist); i++)
            {
                radListView1.Items.RemoveAt(radListView1.Items.Count - 1);
                avancement_suppression++;
                radProgressBar1.Value1++;
                radProgressBar1.Text = avancement_suppression + "/" + radProgressBar1.Maximum + "  |  (" + (((double)avancement_suppression / (double)radProgressBar1.Maximum) * 100).ToString("0.00") + " %)"; await page.WaitForSelectorAsync("body > div.wrap.container > div > main > div > div.col-lg-8.col-xl-9.mt-lg-5.mb-5 > div.fuvilist_container > div:nth-child(1) > div.col-12.col-lg-5.col-xl-4 > div > div > button.btn.btn-outline-danger.delete_fuvi_list", new WaitForSelectorOptions { Visible = true });

                await page.EvaluateFunctionAsync("()=>window.confirm = () => true");

                await page.EvaluateFunctionAsync("()=>document.querySelector(\"body > div.wrap.container > div > main > div > div.col-lg-8.col-xl-9.mt-lg-5.mb-5 > div.fuvilist_container > div:nth-child(1) > div.col-12.col-lg-5.col-xl-4 > div > div > button.btn.btn-outline-danger.delete_fuvi_list\").click()");

                await page.WaitForNavigationAsync(new NavigationOptions { WaitUntil = new[] { WaitUntilNavigation.Networkidle0 } });
            }
            button1.Enabled = true;
            button2.Enabled = true;
            await browser.CloseAsync();
        }
Esempio n. 5
0
        public static async Task TakeSS(string url, object type, string name)
        {
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
            var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true,
                Args     = new [] {
                    "--proxy-server=",
                    "--no-sandbox",
                    "--disable-infobars",
                    "--disable-setuid-sandbox",
                    "--ignore-certificate-errors",
                },
            });

            try
            {
                using (var page = await browser.NewPageAsync())
                {
                    Console.WriteLine($"rendering {url}");
                    await page.GoToAsync(url);

                    Console.WriteLine($"screenshot in progress");
                    if (type is ScreenshotType)
                    {
                        ScreenshotOptions ssOpt = new ScreenshotOptions()
                        {
                            FullPage = true, Type = (ScreenshotType)type
                        };
                        await page.ScreenshotAsync(name + (ScreenshotType)type, ssOpt);
                    }

                    else
                    {
                        Console.WriteLine("gengerating pdf");

                        await page.PdfAsync(name + "pdf");
                    }

                    await page.WaitForTimeoutAsync(1000);
                }
            }

            catch (System.Exception e)
            {
                Console.WriteLine("gagal!");
                Console.WriteLine(e);
                await browser.CloseAsync();
            }

            await browser.CloseAsync();
        }
        public async Task InitializeAsync()
        {
            Browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true
            });

            Context = await Browser.CreateIncognitoBrowserContextAsync();

            Page = await Context.NewPageAsync();

            await SetUp();
        }
Esempio n. 7
0
 private static async Task <Browser> CreateBrowser(Options option)
 {
     return(await Puppeteer.LaunchAsync(new LaunchOptions()
     {
         Headless = true,
         DefaultViewport = new ViewPortOptions()
         {
             Height = option.Height,
             Width = option.Width,
         },
         IgnoreHTTPSErrors = true,
     }));
 }
Esempio n. 8
0
        //se abre el navegador Chromium
        public async Task AbrirNavegador()
        {
            try
            {
                this.Browser = await Puppeteer.LaunchAsync(Options);

                this.Page = await Browser.NewPageAsync();
            }
            catch (Exception ex)
            {
                throw new Exception("No se pudo abrir el navegador", ex);
            }
        }
Esempio n. 9
0
        public async Task TargetPageShouldReturnABackgroundPage()
        {
            using (var browserWithExtension = await Puppeteer.LaunchAsync(
                       TestConstants.BrowserWithExtensionOptions(),
                       TestConstants.LoggerFactory))
            {
                var backgroundPageTarget = await WaitForBackgroundPageTargetAsync(browserWithExtension);

                var page = await backgroundPageTarget.PageAsync();

                Assert.Equal(6, await page.EvaluateFunctionAsync <int>("() => 2 * 3"));
            }
        }
 public static async Task InitialiseBrowser()
 {
     // Download brower if needed, and instantiate
     await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
     Browser = await Puppeteer.LaunchAsync(new LaunchOptions
     {
         Headless        = true,
         DefaultViewport = new ViewPortOptions()
         {
             Width = 1920, Height = 1080
         }
     });
 }
        public async Task <Stream> ConvertAsync(string html, CrossCuttingConcerns.PdfConverter.PdfOptions pdfOptions = null)
        {
            await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });

            await using var page = await browser.NewPageAsync();

            await page.SetContentAsync(html);

            return(new MemoryStream(await page.PdfDataAsync(new global::PuppeteerSharp.PdfOptions
            {
                PrintBackground = true,
            })));
        }
Esempio n. 12
0
        private async Task <Browser> GetNewBrowserAsync()
        {
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);

            LaunchOptions browserOptions = new LaunchOptions
            {
                Headless = true, Args = new string[] { "--lang=" + Vkontakte.Language.ToString().ToLowerInvariant() }
            };

            Browser browser = await Puppeteer.LaunchAsync(browserOptions);

            return(browser);
        }
Esempio n. 13
0
 private async ValueTask RunBrowserAsync()
 {
     Browser = await Puppeteer.LaunchAsync(new LaunchOptions
     {
         Headless        = false,
         DefaultViewport = new ViewPortOptions()
         {
             DeviceScaleFactor = 1,
             Height            = 800,
             Width             = 1024
         }
     });
 }
Esempio n. 14
0
        //private static Browser _browser = null;
        /*@brief Return puppeteer instance*/
        public async static Task <Browser> getInstance()
        {
            /*Init puppeteer instance if doesn't init*/
            /*Donwload chromium and init puppeteer instance*/
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
            var _browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                /*@deprecate: Modify when distributing*/
                Headless = false
            });

            return(_browser);
        }
Esempio n. 15
0
        public async Task <byte[]> GenerateReport(bool headless)
        {
            Console.WriteLine(MessageResources.GenerateReportLaunching);
            var opt = new LaunchOptions
            {
                Headless        = headless,
                Args            = new[] { "--no-sandbox" },
                DefaultViewport = new ViewPortOptions
                {
                    Width  = _settings.Viewport.Width,
                    Height = _settings.Viewport.Height
                },
                ExecutablePath = _settings.ChromiumPath
            };

            using var browser = await Puppeteer.LaunchAsync(opt);

            using var page = await browser.NewPageAsync();

            Console.WriteLine(MessageResources.GenerateReportLoggingIn);
            await page.GoToAsync("https://telkomdds.atlassian.net", WaitUntilNavigation.Networkidle0);

            await page.TypeAsync("#username", _settings.AtlassianAccount.Email);

            await page.ClickAsync("#login-submit");

            await page.WaitForSelectorAsync("#password", new WaitForSelectorOptions { Visible = true, Timeout = TimeoutDuration });

            await page.TypeAsync("#password", _settings.AtlassianAccount.Password);

            await page.ClickAsync("#login-submit");

            await page.WaitForSelectorAsync("#jira-frontend", new WaitForSelectorOptions { Visible = true, Timeout = TimeoutDuration });

            Console.WriteLine(MessageResources.GenerateReportScreenshot);
            await page.GoToAsync("https://telkomdds.atlassian.net/issues/?filter=11241", TimeoutDuration, new[] { WaitUntilNavigation.Networkidle0 });

            var img = await page.ScreenshotDataAsync();


            Console.WriteLine(MessageResources.GenerateReportLoggingOut);
            await page.GoToAsync("https://telkomdds.atlassian.net/logout", TimeoutDuration, new[] { WaitUntilNavigation.Networkidle0 });

            await page.CloseAsync();

            await browser.CloseAsync();

            await SaveReport(img);

            return(img);
        }
Esempio n. 16
0
        public async void Connect(string mail, string pass)
        {
            var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless        = false,
                DefaultViewport = null,
                ExecutablePath  = Properties.Settings.Default.chromepath
            });

            var page = browser.PagesAsync().Result[0];

            await page.GoToAsync("https://www.fuvi-clan.com/myaccount/");

            await page.WaitForSelectorAsync("#username");

            await page.TypeAsync("#username", mail);

            await page.WaitForSelectorAsync("#password");

            await page.TypeAsync("#password", pass);

            await page.ClickAsync("#rememberme");

            await page.ClickAsync("#customer_login > div:nth-child(1) > form > div.d-flex.justify-content-md-between.align-items-center.mt-3 > p.form-group.form-row > button");

            await Task.Delay(2000);


            await page.WaitForSelectorAsync("body > div.wrap.container > div > main > div > div.col-lg-4.col-xl-3.my-5 > div > div", new WaitForSelectorOptions { Visible = true });

            await page.WaitForSelectorAsync("body > div.wrap.container > div > main > div > div.col-lg-4.col-xl-3.my-5 > div > div > h6", new WaitForSelectorOptions { Visible = true });

            var FuviUserName = await page.EvaluateFunctionAsync(
                "()=>document.querySelector(\"body > div.wrap.container > div > main > div > div.col-lg-4.col-xl-3.my-5 > div > div > h4\").textContent"
                );

            var FuviInscription = await page.EvaluateFunctionAsync(
                "()=>document.querySelector(\"body > div.wrap.container > div > main > div > div.col-lg-4.col-xl-3.my-5 > div > div > h6\").textContent"
                );

            Properties.Settings.Default.FuviUserName   = FuviUserName.ToString();
            Properties.Settings.Default.FuviInscriDate = FuviInscription.ToString();
            MessageBox.Show("Connexion reussi !" + Environment.NewLine + Environment.NewLine + "Salut, " + Properties.Settings.Default.FuviUserName + Environment.NewLine + Properties.Settings.Default.FuviInscriDate, "Connexion reussi !", MessageBoxButtons.OK, MessageBoxIcon.Information);
            MessageBox.Show("Le logiciel va enregistré les cookies de votre session pour vous evité de vous reconnecter souvent, aucune données n'est sauvegardé sur serveur." + Environment.NewLine + "Elle est sauvegardé à l'emplacement racine de l'application.", "Connexion reussi !", MessageBoxButtons.OK, MessageBoxIcon.Information);

            var Cookies = await page.GetCookiesAsync();

            File.WriteAllText("cookies.json", JsonConvert.SerializeObject(Cookies));

            await browser.CloseAsync();
        }
Esempio n. 17
0
        public async Task ShouldFilterOutIgnoredDefaultArguments()
        {
            var defaultArgs = Puppeteer.GetDefaultArgs();
            var options     = TestConstants.DefaultBrowserOptions();

            options.IgnoredDefaultArgs = new[] { defaultArgs[0], defaultArgs[2] };
            using (var browser = await Puppeteer.LaunchAsync(options))
            {
                var spawnargs = browser.Process.StartInfo.Arguments;
                Assert.DoesNotContain(defaultArgs[0], spawnargs);
                Assert.Contains(defaultArgs[1], spawnargs);
                Assert.DoesNotContain(defaultArgs[2], spawnargs);
            }
        }
Esempio n. 18
0
        public async Task ShouldSupportIgnoreHTTPSErrorsOption()
        {
            var options = TestConstants.DefaultBrowserOptions();

            options.IgnoreHTTPSErrors = true;

            using (var browser = await Puppeteer.LaunchAsync(options, TestConstants.ChromiumRevision, TestConstants.LoggerFactory))
                using (var page = await browser.NewPageAsync())
                {
                    var response = await page.GoToAsync(TestConstants.HttpsPrefix + "/empty.html");

                    Assert.Equal(HttpStatusCode.OK, response.Status);
                }
        }
Esempio n. 19
0
        public static async Task StartAsync()
        {
            await new BrowserFetcher().DownloadAsync();
            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true, IgnoreHTTPSErrors = true, Args = new string[] { "--no-sandbox", "--disable-web-security" } });

            _page = await browser.NewPageAsync();

            await _page.GoToAsync("https://discord.com");

            var properties = new SuperProperties();
            await _page.SetUserAgentAsync(properties.UserAgent);

            _superProps = properties.ToBase64();
        }
    private async Task <ExportStatementPage> LoadExportStatementsPage()
    {
        await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);
        _browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });

        _page = await _browser.NewPageAsync();

        await _page.SetDownloadPath(_options.DownloadPath);

        var loginPage    = new LoginPage(_page);
        var balancesPage = await loginPage.Login(_options.UserName, _options.Password);

        return(await balancesPage.GoToExportStatementPage());
    }
        public async Task ShouldCloseBrowserWithBeforeunloadPage()
        {
            var headfulOptions = TestConstants.DefaultBrowserOptions();

            headfulOptions.Headless = false;
            await using (var browser = await Puppeteer.LaunchAsync(headfulOptions))
                await using (var page = await browser.NewPageAsync())
                {
                    await page.GoToAsync(TestConstants.ServerUrl + "/beforeunload.html");

                    // We have to interact with a page so that 'beforeunload' handlers fire.
                    await page.ClickAsync("body");
                }
        }
        static async Task Main(string[] args)
        {
            var style = new LaunchOptions {
                Headless = true
            };

            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
            Console.WriteLine("\nGet information from CGV...");

            using (var browser = await Puppeteer.LaunchAsync(style))
                using (var page = await browser.NewPageAsync()) {
                    await page.GoToAsync("https://www.cgv.id/en/movies/now_playing");

                    var jsSelectAllAnchors = await page.QuerySelectorAllHandleAsync(".movie-list-body > ul >li > a").EvaluateFunctionAsync <string[]> ("elements => elements.map(a => a.href)");

                    Console.WriteLine("\n=========Now Playing=========");
                    HtmlWeb web = new HtmlWeb();
                    for (int i = 0; i < jsSelectAllAnchors.Length; i++)
                    {
                        var htmlDoc = web.Load(jsSelectAllAnchors[i]);

                        Console.WriteLine("\n\n========================================================================================================");

                        var Title = htmlDoc.DocumentNode.SelectNodes("//div[@class='movie-info-title']");
                        foreach (var node in Title)
                        {
                            Console.WriteLine("\nTITLE :\n" + node.InnerText.Trim() + "\n");
                        }

                        var Starring = htmlDoc.DocumentNode.SelectNodes("//div[@class='movie-add-info left']/ul /li");
                        foreach (var node in Starring)
                        {
                            Console.WriteLine("> " + node.InnerText.Trim());
                        }

                        var Trailer = htmlDoc.DocumentNode.SelectNodes("//div[@class='trailer-btn-wrapper']/img");
                        foreach (var node in Trailer)
                        {
                            var getLink = node.GetAttributeValue("onclick", string.Empty);
                            Console.WriteLine("\n> TRAILER LINK : " + getLink.Remove(0, 11));
                        }

                        var Synopsis = htmlDoc.DocumentNode.SelectNodes("//div[@class='movie-synopsis right']");
                        foreach (var node in Synopsis)
                        {
                            Console.WriteLine("\n> SYNOPIS : " + node.InnerText.Trim());
                        }
                    }
                }
        }
        public async Task ShouldOpenDevtoolsWhenDevtoolsTrueOptionIsGiven()
        {
            var headfulOptions = TestConstants.DefaultBrowserOptions();

            headfulOptions.Devtools = true;
            await using (var browser = await Puppeteer.LaunchAsync(headfulOptions))
            {
                var context = await browser.CreateIncognitoBrowserContextAsync();

                await Task.WhenAll(
                    context.NewPageAsync(),
                    context.WaitForTargetAsync(target => target.Url.Contains("devtools://")));
            }
        }
Esempio n. 24
0
        public async Task <Browser> LaunchAsync(LaunchOptions options)
        {
            _plugins.ForEach(e => e.BeforeLaunch(options));
            var browser = await Puppeteer.LaunchAsync(options);

            _plugins.ForEach(e => e.AfterLaunch(browser));
            await OnStart(new BrowserStartContext()
            {
                StartType  = StartType.Launch,
                IsHeadless = options.Headless
            }, browser);

            return(browser);
        }
        public async Task Setup()
        {
            ConfigurationHelper.Initialise(TestContext.CurrentContext.TestDirectory);
            DbHelper.ClearDb();
            IdentityHelpers.ClearAll();

            //todo: allow other actors (types of provider)
            //var providerActor = (ProviderActor)TestContext.CurrentContext.Test.Arguments.GetValue(0);
            var provider = Actors.Provider.Create();


            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);

            var launchOptions = new LaunchOptions
            {
                Headless          = false,
                IgnoreHTTPSErrors = true,
                //SlowMo = 10
            };

            Console.WriteLine("Launching browser...");

            Browser = await Puppeteer.LaunchAsync(launchOptions);

            var context = Browser.DefaultContext;

            Page = await context.NewPageAsync();

            var url = LaunchPage.Url.Replace("{providerId}", provider.ProviderId.ToString());

            Console.WriteLine($"Opening {url}");
            var response = await Page.GoToAsync(url);

            //Realm selection
            await Page.ClickOn(LaunchPage.Realm);

            await Page.WaitForNavigationAsync();

            await Page.TypeInputAsync(LaunchPage.Username, provider.Username);

            await Page.TypeInputAsync(LaunchPage.Password, provider.Password);

            Console.Write("Signing in... ");
            await Page.Keyboard.DownAsync("Enter"); //hit enter, rather than click button

            await Page.WaitForSelectorAsync(".govuk-header");

            //await Page.WaitForNavigationAsync();
            Console.WriteLine("Complete");
        }
        public async Task <Browser> GetBrowser()
        {
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);

            return(await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true,
                Args = new []
                {
                    "--no-sandbox",
                    "--disable-setuid-sandbox"
                }
            }, _loggerFactory));
        }
Esempio n. 27
0
        public async Task ShouldWorkWithNoDefaultArguments()
        {
            var options = TestConstants.DefaultBrowserOptions();

            options.IgnoreDefaultArgs = true;
            using (var browser = await Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory))
            {
                Assert.Single(await browser.PagesAsync());
                using (var page = await browser.NewPageAsync())
                {
                    Assert.Equal(121, await page.EvaluateExpressionAsync <int>("11 * 11"));
                }
            }
        }
Esempio n. 28
0
        public async Task StartAsync()
        {
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
            Console.WriteLine("Got Chrome Driver");

            // Create an instance of the browser and configure launch options
            this.browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true,
                Timeout  = (int)TimeSpan.FromSeconds(10).TotalMilliseconds
            });

            Console.WriteLine("Created Browser Instance");
        }
Esempio n. 29
0
        public async Task ShouldRejectIfExecutablePathIsInvalid()
        {
            var options = TestConstants.DefaultBrowserOptions();

            options.ExecutablePath = "random-invalid-path";

            var exception = await Assert.ThrowsAsync <FileNotFoundException>(() =>
            {
                return(Puppeteer.LaunchAsync(options, TestConstants.LoggerFactory));
            });

            Assert.Equal("Failed to launch chrome! path to executable does not exist", exception.Message);
            Assert.Equal(options.ExecutablePath, exception.FileName);
        }
Esempio n. 30
0
        public async Task ExecuteAsync()
        {
            var path = Path.Combine(Path.GetTempPath(), "FatTiger.png");

            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);

            using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true,
                Args     = new string[] { "--no-sandbox" }
            });

            using var page = await browser.NewPageAsync();

            await page.SetViewportAsync(new ViewPortOptions
            {
                Width  = 1920,
                Height = 1080
            });

            var url = "https://www.baidu.com";
            await page.GoToAsync(url, WaitUntilNavigation.Networkidle0);

            var content = await page.GetContentAsync();

            await page.PdfAsync("FatTiger.pdf");

            await page.ScreenshotAsync(path, new ScreenshotOptions
            {
                FullPage = true,
                Type     = ScreenshotType.Png
            });

            // 发送带图片的Email
            var builder = new BodyBuilder();

            var image = builder.LinkedResources.Add(path);

            image.ContentId = MimeUtils.GenerateMessageId();

            builder.HtmlBody = "当前时间:{0}.<img src=\"cid:{1}\"/>".FormatWith(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), image.ContentId);

            var message = new MimeMessage
            {
                Subject = "【定时任务】每日热点数据抓取任务推送",
                Body    = builder.ToMessageBody()
            };
            await EmailHelper.SendAsync(message);
        }