public void PARENT_MGT_UNLOCK_04() { // To lock this user bool flag = Pages.LoginPage.LockUserWith10TimesInvalidPasswordInput(driver, "*****@*****.**", "123", "Input Valid username and Invalid Password"); // To login with Admin rights if (flag) { Pages.LoginPage.LoginAimy(driver, GlobalVariable.sloginUsername, GlobalVariable.sloginPassword); // To goto Parent Management Page ChromeBrowser.Goto("Parent/Management"); if (Pages.ParentManagementPage.IsParentLocked(driver, "Attendance B, Hana")) { Assert.AreEqual(true, Pages.ParentManagementPage.IsParentUnlocked(driver, "Attendance B, Hana")); } } Thread.Sleep(3000); Pages.ParentManagementPage.GoToEditLoginDetailPage(driver, "Attendance B, Hana"); Pages.EditLoginPage.IsLoginEdited(driver, "12341234"); Thread.Sleep(3000); Pages.ParentManagementPage.LogoutAdminPort(driver); Assert.AreEqual(true, Pages.ParentManagementPage.LoginParentPortalDefault(driver, "*****@*****.**", true, "12341234")); }
public async Task <IReadOnlyList <CopyrightNotice> > GetCopyrightNotices(string channelId) { var notices = new List <CopyrightNotice>(); using (var browser = new ChromeBrowser()) { var parser = new CopyrightNoticesParser(); var videosPageSource = browser.GetPageSource("https://www.youtube.com/my_videos_copyright"); var videoUrls = await parser.ParseVideosCopyright(videosPageSource); foreach (var videoUrl in videoUrls) { var pageSource = browser.GetPageSource($"https://www.youtube.com/{videoUrl}"); var videoId = videoUrl.Replace("/video_copynotice?v=", string.Empty); var copyrightNotices = await parser.ParseCopyrightNotices(videoId, pageSource); if (copyrightNotices != null && copyrightNotices.Any()) { notices.AddRange(copyrightNotices); } } } return(notices); }
/// <summary> /// Remove the current image from the manager and serve up the next one with updated text. /// </summary> private void nextImage(bool actuallyProgressForward = true) { // Check for end if (manager.ImagesRemaining == 0) { Close(); } else { // Show the next image if (actuallyProgressForward) { image = manager.RandomImage(); } if (Manager.SupportedHtml5VideoFormats.Contains(image.Extension)) { this.updateBrowserVideo(); } else { ChromeBrowser.Load($"file:///{image.FullName}"); updateImageLabels(true); } } }
private void AlwaysCrawlProgress_ProgressChanged(object sender, ProgressState state) { AlwaysCrawlProgressTick++; if (AlwaysCrawlProgressTick >= AlwaysCrawlProgressTickEnd) { AlwaysCrawlProgressTick = 0; } // 設定画面を表示中の場合、一部ステップ時にカウント表示を更新 if (ChromeBrowser.Address.EndsWith("setting.html")) { switch (state.CurrentStep) { case ProgressState.Step.RecordUpdateEnd: case ProgressState.Step.PurgeProcessEnd: case ProgressState.Step.AlwaysCrawlDBDocumentDeleteBegin: // 前回から1秒以上経っている場合のみ更新 if (LastUpdatedCountDataInSettingPage == null || (DateTime.Now - LastUpdatedCountDataInSettingPage.Value).TotalMilliseconds >= 1000) { if (ChromeBrowser.CanExecuteJavascriptInMainFrame) { ChromeBrowser.EvaluateScriptAsync("updateCountsAsync();"); } LastUpdatedCountDataInSettingPage = DateTime.Now; } break; } } string suffix; if (AlwaysCrawlProgressTick < AlwaysCrawlProgressTickEnd / 3) { suffix = "."; } else if (AlwaysCrawlProgressTick < AlwaysCrawlProgressTickEnd / 3 * 2) { suffix = ".."; } else { suffix = "..."; } bool onProgress; var newCaption = GetBackgroundCrawlCaption(state.CurrentStep, state.Path, out onProgress); if (newCaption != null) { if (!string.IsNullOrEmpty(newCaption) && onProgress) { newCaption += suffix; } StlBackgroundCrawl.Text = newCaption; } }
private void InitBrowser() { try { Browser?.Dispose(); Browser = ChromeBrowser.OpenBrowser(); LoginToSite(); } catch (Exception e) { Console.WriteLine($"Exception when initializing: {e}"); } }
public void Dispose() { var browser = _browser; _browser = null; if (browser != null) { browser.Dispose(); } }
public void Closing() { // write the end time to log file log.Info("---------------------------------------------------------------------"); log.Info("Test Execution is ended | End Time : " + DateTime.Now.ToString()); log.Info("---------------------------------------------------------------------"); ChromeBrowser.Close(); ChromeBrowser.Quite(); }
public Bot(Writer console, DBmanager db) { UserXpath = "//ul[@class ='Followers-list-vZl']"; FollowingUserXpath = "//ul[@class ='Following-list-1Gx']"; Cons = console; this.db = db; string chromeProfileName = (++profileCounter).ToString() + "BehanceBot"; Сhrome = new ChromeBrowser(chromeProfileName); Сhrome.SetWindowSize(1280, 1000); }
public void CreateChromeInstance(string url) { Logger.LogAction("Creating Chrome instance"); UtilityClass.MoveMousePoinerToTopLeft(Settings.AutoMoveMousePointerToTopLeft); var clientPort = new ChromeClientPort(); clientPort.Connect(url); ChromeBrowser = new ChromeBrowser(clientPort); }
private IEnumerable <Browser> GetBrowsers(List <Exception> asserts) { var response = new List <Browser>(); if (HasBrowserType(BrowserType.Chrome)) { try { var chrome = ChromeBrowser.AttachOrCreate(); chrome.AutoClose = AutoClose; chrome.SlowMotion = SlowMotion; response.Add(chrome); } catch (Exception ex) { asserts.Add(ex); } } if (HasBrowserType(BrowserType.Firefox)) { try { var firefox = FirefoxBrowser.AttachOrCreate(); firefox.AutoClose = AutoClose; firefox.SlowMotion = SlowMotion; response.Add(firefox); } catch (Exception ex) { asserts.Add(ex); } } if (HasBrowserType(BrowserType.InternetExplorer)) { try { var internetExplorer = InternetExplorerBrowser.AttachOrCreate(); internetExplorer.AutoClose = AutoClose; internetExplorer.SlowMotion = SlowMotion; response.Add(internetExplorer); } catch (Exception ex) { asserts.Add(ex); } } ArrangeBrowsers(response); return(response); }
protected virtual void CrawlStart(IEnumerable <string> targetDirPaths = null) { // 検索対象フォルダが存在するかどうかをチェック foreach (var dirPath in App.GetCrawlTargetDirPaths(targetDirPaths)) { if (!Directory.Exists(dirPath)) { Util.ShowErrorMessage(this, $"下記の検索対象フォルダが見つかりませんでした。\n{dirPath}\n\n検索対象フォルダの設定を変更してから、再度クロールを行ってください。"); return; } } // 実行前にDBのサイズを取得 var dbFileSize = App.GM.GetDBFileSizeTotal(); // ルートパスを取得 var rootPath = Path.GetPathRoot(Path.GetFullPath(App.GM.DBDirPath)); // ルートパスがアルファベットから始まっていれば、ローカルにDBがあるとみなし、空き容量チェック var driveLetter = rootPath.Substring(0, 1); if (Regex.IsMatch(driveLetter, "[a-zA-Z]")) { // ドライブの空き容量を取得 var driveFreeSpaceSize = new DriveInfo(driveLetter).AvailableFreeSpace; // ドライブの空き容量(DBサイズ分を除く)が2GB未満の場合は警告 if ((driveFreeSpaceSize - dbFileSize) < 1024L * 1024L * 1024L * 2L) { var freeSpaceByGB = Math.Round(driveFreeSpaceSize / (decimal)(1024L * 1024L * 1024L), 2); var freeSpaceCaption = freeSpaceByGB.ToString() + "GB"; var msg = $"{driveLetter.ToUpper()}ドライブの空き容量が残り少なくなっているため\nクロールによってDBのサイズが拡大し、空き容量が無くなる可能性があります。\n(現在の空き容量: {freeSpaceCaption})\n\nクロールを実行してもよろしいですか?"; var res = MessageBox.Show(this, msg, "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2); if (res == DialogResult.No) { return; } } } ChromeBrowser.EvaluateScriptAsync("$('#CRAWL-START').addClass('disabled'); $('#SETTING-LINK').addClass('disabled');"); var f = new CrawlProgressForm(App, () => { ChromeBrowser.EvaluateScriptAsync("$('#CRAWL-START').removeClass('disabled'); $('#SETTING-LINK').removeClass('disabled');"); }) { TargetDirPaths = targetDirPaths }; f.Show(this); }
private Browser() { _browser = new ChromeBrowser(); var config = Config.Current; _browser.Start(config.Url); if (!String.IsNullOrEmpty(config.Login) && !String.IsNullOrEmpty(config.Password)) { _browser.Login(config.Login, config.Password); } SwitchToCompany(_browser, config.CompanyName); SwitchToPeriod(_browser, config.Period); }
public void SpecialDay_Booking_01_For_One_Child_One_Day() { Pages.LoginPage.LoginAimy(driver, GlobalVariable.sloginUsername, GlobalVariable.sloginPassword); Common.TitleValidation(driver, "Validate Aimy Home Title", "Home - aimy plus"); ChromeBrowser.Goto("Parent/Management"); Common.TitleValidation(driver, "Validate Parent Management Title", "Parent Management - aimy plus"); Pages.ParentManagementPage.FindTheParent(driver, "ema su"); Common.WaitBySleeping(GlobalVariable.iShortWait); Pages.ParentManagementPage.GoToBookingInYourChildPage(driver); Assert.AreEqual(0, Common.TitleValidation(driver, "Validate Book In Your Child Title", "Booking - aimy plus")); Assert.AreEqual(true, Pages.SpecailDayBookingPage.SpecailDayBookingWizard(driver)); Assert.AreEqual(true, Pages.BookingManagerPage.ValidationPendingBookingExist(driver, "ema1 ch")); }
private IBrowser GetBrowser(BrowserType browserType, IWebDriver webDriver) { IBrowser browser = null; switch (browserType) { case BrowserType.IE: browser = new IEBrowser(webDriver); break; case BrowserType.Chrome: browser = new ChromeBrowser(webDriver); break; case BrowserType.Firefox: browser = new FirefoxBrowser(webDriver); break; } return(browser); }
public void Class_Booking_02_For_Two_Children_One_Day_Each_Class() { Pages.LoginPage.LoginAimy(driver, "*****@*****.**", "123123"); Common.TitleValidation(driver, "Validate Aimy Home Title", "Home - aimy plus"); ChromeBrowser.Goto("Parent/Management"); Common.TitleValidation(driver, "Validate Parent Management Title", "Parent Management - aimy plus"); Pages.ParentManagementPage.FindTheParent(driver, "*****@*****.**"); Common.WaitBySleeping(GlobalVariable.iShortWait); Pages.ParentManagementPage.GoToBookingInYourChildPage(driver); Assert.AreEqual(0, Common.TitleValidation(driver, "Validate Book In Your Child Title", "Booking - aimy plus")); Pages.ClassBookingPage.ClassBookingWizard(driver, new string[] { "2016-10-17" }, true, true); Common.WaitBySleeping(GlobalVariable.iShortWait); Assert.AreEqual(true, Pages.BookingManagerPage.ValidationPendingBookingExist(driver, "Test Aimy")); }
/// <summary> /// Resizes the HTML5 video content (when applicable) /// </summary> private void updateBrowserVideo() { if (Manager.SupportedHtml5VideoFormats.Contains(image.Extension)) { ChromeBrowser.LoadHtml($@" <!DOCTYPE html><html><body> <video width=""{ChromeBrowser.Width - 25}"" height=""{ChromeBrowser.Height - 25}"" autoplay controls loop src=""file:///{image.FullName}""> Your browser does not support HTML5 video. </video> </body></html>", $"file:///{image.Directory.FullName}"); } this.updateImageLabels(); }
public void PARENT_MGT_UNLOCK_02() { // To lock this user bool flag = Pages.LoginPage.LockUserWith10TimesInvalidPasswordInput(driver, "*****@*****.**", "123", "Input Valid username and Invalid Password"); // To login with Admin rights if (flag) { Pages.LoginPage.LoginAimy(driver, GlobalVariable.sloginUsername, GlobalVariable.sloginPassword); // To goto Parent Management Page ChromeBrowser.Goto("Parent/Management"); Assert.AreEqual(true, Pages.ParentManagementPage.IsParentLocked(driver, "Attendance B, Hana")); } }
public Bot(Writer console, CancellationToken token) { if (token.IsCancellationRequested) { return; } this.token = token; Cons = console; db = new DBmanager(console); rand = new Random(); Chrome = new ChromeBrowser("InstagramBotProfile"); Chrome.SetWindowSize(500, 1000); }
/// <summary> /// Create or attach a browser of the provided type. /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> /// <exception cref="Exception"></exception> public static Browser AttachOrCreate <T>() { var type = typeof(T); if (type == typeof(ChromeBrowser)) { return(ChromeBrowser.AttachOrCreate()); } if (type == typeof(InternetExplorerBrowser)) { return(InternetExplorerBrowser.AttachOrCreate()); } throw new Exception("Invalid type provided."); }
public string GetTextContentByElementId(string ElementId) { string startDate = ""; string script = string.Format("document.getElementById('{0}').textContent;", ElementId); ChromeBrowser.EvaluateScriptAsync(script).ContinueWith(x => { var response = x.Result; if (response.Success && response.Result != null) { startDate = response.Result.ToString(); } }); return(startDate); }
private void ChromeBrowser_PreviewMouseDown(object sender, MouseButtonEventArgs e) { var window = e.GetPosition(this); Trace.WriteLine(window.ToString()); var bc = e.GetPosition(ChromeBrowser); Trace.WriteLine(bc.ToString()); var images = ChromeBrowser.FindChildren <Image>(); var c = images.Count(); var ii = e.GetPosition(images.First()); Trace.WriteLine(ii.ToString()); //e.Handled = true; }
static void SwitchToPeriod(ChromeBrowser browser, String period) { if (String.IsNullOrEmpty(period)) { return; } var f = new Feature(); var s = new Scenario(); var c = new SelectPeriod() { Text = period }; s.Steps.Add(c); f.Scenarios.Add(s); f.RunAll(browser, (r) => { }); }
static void SwitchToCompany(ChromeBrowser browser, String companyName) { if (String.IsNullOrEmpty(companyName)) { return; } var f = new Feature(); var s = new Scenario(); var c = new SelectCompany() { Text = companyName }; s.Steps.Add(c); f.Scenarios.Add(s); f.RunAll(browser, (r) => { }); }
public Task Initialize(CancellationToken ct) { var icns = new List<string> { ModuleConfiguration.IcnRussia, ModuleConfiguration.IcnNoCash, ModuleConfiguration.IcnKazakhstan }; var tasks = new List<Task>(); foreach (var icn in icns) { var browser = new ChromeBrowser(); _browsers.Add(icn, browser); tasks.Add(BrowserInitialize(browser, icn, ct)); } Task.WaitAll(tasks.ToArray(), ct); ct.ThrowIfCancellationRequested(); return Task.FromResult(0); }
public void A_REG_PARENT_01() { var lib = new RegisteringParentPage_1(); Pages.LoginPage.LoginAimy(driver, "*****@*****.**", "123123"); Common.TitleValidation(driver, "Validate Aimy Home Title", "Home - aimy plus"); //Parent Management --> http://uat.aimy.co.nz/Parent/Management ChromeBrowser.Goto("Parent/Management"); Common.TitleValidation(driver, "Validate Parent Management Title", "Parent Management - aimy plus"); //Register New Parent --> http://uat.aimy.co.nz/Parent/RegisterFromAdmin // Contact Details http://uat.aimy.co.nz/Parent/EditParentContact/30307?Wizard=False //lib.TC_CRE_PARENT_01_1_FillInformation(); //lib.TC_CRE_PARENT_UI_01_1_Data_Required_Validation(); }
private void ChromeBrowser_FrameLoadStart(object sender, FrameLoadStartEventArgs e) { if (e.Url.EndsWith("index.html")) { var selectRes1 = App.GM.Select(Table.Documents , limit: 0 , outputColumns: new[] { Groonga.VColumn.ID } ); DBState.DocumentCount = selectRes1.SearchResult.NHits; DBState.TargetFolderCount = App.UserSettings.TargetFolders.Count; DBState.AlwaysCrawlMode = App.UserSettings.AlwaysCrawlMode; // 更新の有無をチェック ISAutoUpdater.Check(ApplicationEnvironment.IsPortableMode(), (args) => { var msg = $"新しいバージョン ({args.CurrentVersion.TrimEnd('0').TrimEnd('.')}) に更新可能です"; ChromeBrowser.EvaluateScriptAsync($"$('#UPDATE-LINK .message').text('{msg}'); $('#UPDATE-LINK').show();"); }); } }
private void CreateChromeInstance(string url) { Logger.LogAction("Creating Chrome instance"); UtilityClass.MoveMousePoinerToTopLeft(Settings.AutoMoveMousePointerToTopLeft); var clientPort = new ChromeClientPort(); clientPort.Connect(url); ChromeBrowser = new ChromeBrowser(clientPort); }
public ClassBooking_Testcases() { driver = ChromeBrowser.chromeDriver; ChromeBrowser.Initialize(); }
public ChildEnrolTestCases() { driver = ChromeBrowser.chromeDriver; ChromeBrowser.Initialize(); }
public SpecialDayBooking_Testcases() { driver = ChromeBrowser.chromeDriver; ChromeBrowser.Initialize(); }
public static IWebDriver Build(string browser, bool runTestsRemotely, string driverVersion = "Latest") { IWebDriver webDriver; const string nodeURI = "http://23.100.236.70:4446/wd/hub"; switch (browser.ToLower()) { case "chrome": var chromeOptions = new ChromeOptions(); var chromeBrowser = new ChromeBrowser(); chromeBrowser.StartIfNotRunning(); chromeOptions.DebuggerAddress = $"localhost:{chromeBrowser.DebuggingPort}"; chromeOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); new DriverManager().SetUpDriver(new ChromeConfig(), driverVersion); webDriver = runTestsRemotely ? new RemoteWebDriver(new Uri(nodeURI), chromeOptions) : new ChromeDriver(chromeOptions); break; case "chrome-incognito-ignore-certificate": var chromeIncogAndIgnCertErrsOptions = new ChromeOptions(); chromeIncogAndIgnCertErrsOptions.AddArguments("--incognito", "--ignore-certificate-errors"); chromeIncogAndIgnCertErrsOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); new DriverManager().SetUpDriver(new ChromeConfig(), driverVersion); webDriver = runTestsRemotely ? new RemoteWebDriver(new Uri(nodeURI), chromeIncogAndIgnCertErrsOptions) : new ChromeDriver(chromeIncogAndIgnCertErrsOptions); break; case "chrome-headless": var chromeHeadlessOptions = new ChromeOptions(); chromeHeadlessOptions.AddArgument("--headless"); chromeHeadlessOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); new DriverManager().SetUpDriver(new ChromeConfig(), driverVersion); webDriver = runTestsRemotely ? new RemoteWebDriver(new Uri(nodeURI), chromeHeadlessOptions) : new ChromeDriver(chromeHeadlessOptions); break; case "firefox": var firefoxOptions = new FirefoxOptions(); firefoxOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); new DriverManager().SetUpDriver(new FirefoxConfig(), driverVersion); webDriver = runTestsRemotely ? new RemoteWebDriver(new Uri(nodeURI), firefoxOptions) : new FirefoxDriver(firefoxOptions); break; case "edge": var edgeOptions = new EdgeOptions(); edgeOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); new DriverManager().SetUpDriver(new EdgeConfig(), driverVersion); webDriver = runTestsRemotely ? new RemoteWebDriver(new Uri(nodeURI), edgeOptions) : new EdgeDriver(edgeOptions); break; case "safari": var safariOptions = new SafariOptions(); safariOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); webDriver = runTestsRemotely ? new RemoteWebDriver(new Uri(nodeURI), safariOptions) : new SafariDriver(safariOptions); break; default: throw new ApplicationException($"The functionality to run scripts for {browser} driver has not been implemented"); } webDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(WaitUtils.defaultImplicitWait); webDriver.Manage().Window.Maximize(); return(webDriver); }
//Launch chrome with //"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9223 static int Main(string[] args) { var cliArguments = Cli.Parse <CliArguments>(args); //Do an initial check to ensure that the Skrapr Definition exists. if (!File.Exists(cliArguments.SkraprDefinitionPath)) { throw new FileNotFoundException($"The specified skrapr definition ({cliArguments.SkraprDefinitionPath}) could not be found. Please check that the skrapr definition exists."); } //Setup our DI var serviceProvider = new ServiceCollection() .AddLogging() .BuildServiceProvider(); //Remove previous log file File.Delete("skraprlog.json"); //Configure Serilog Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .Enrich.FromLogContext() .WriteTo.File(new JsonFormatter(), "skraprlog.json") .WriteTo.ColoredConsole(restrictedToMinimumLevel: LogEventLevel.Debug) .CreateLogger(); //Configure the logger. var logger = serviceProvider .GetService <ILoggerFactory>() .AddSerilog() .CreateLogger <Program>(); ChromeBrowser browser = null; SkraprDevTools devTools = null; SkraprWorker worker = null; try { if (cliArguments.Launch) { browser = ChromeBrowser.Launch(cliArguments.RemoteDebuggingHost, cliArguments.RemoteDebuggingPort); } logger.LogInformation("Connecting to a Chrome session on {chromeHost}:{chromeRemoteDebuggingPort}...", cliArguments.RemoteDebuggingHost, cliArguments.RemoteDebuggingPort); ChromeSessionInfo session = null; try { var sessions = ChromeBrowser.GetChromeSessions(cliArguments.RemoteDebuggingHost, cliArguments.RemoteDebuggingPort).GetAwaiter().GetResult(); session = sessions.FirstOrDefault(s => s.Type == "page" && !String.IsNullOrWhiteSpace(s.WebSocketDebuggerUrl)); } catch (System.Net.Http.HttpRequestException) { logger.LogWarning("Unable to connect to a Chrome session on {chromeHost}:{chromeRemoteDebuggingPort}.", cliArguments.RemoteDebuggingHost, cliArguments.RemoteDebuggingPort); logger.LogWarning("Please ensure that a chrome session has been launched with the --remote-debugging-port={chromeRemoteDebuggingPort} command line argument", cliArguments.RemoteDebuggingPort); logger.LogWarning("Or, launch SkraprConsoleHost with -l"); Debugger.Break(); return(-1); } //TODO: Create a new session if one doesn't exist. if (session == null) { logger.LogWarning("Unable to locate a suitable session. Ensure that the Developer Tools window is closed on an existing session or create a new chrome instance with the --remote-debugging-port={chromeRemoteDebuggingPort) command line argument", cliArguments.RemoteDebuggingPort); Debugger.Break(); return(-1); } devTools = SkraprDevTools.Connect(serviceProvider, session).GetAwaiter().GetResult(); logger.LogInformation("Using session {sessionId}: {sessionTitle} - {webSocketDebuggerUrl}", session.Id, session.Title, session.WebSocketDebuggerUrl); worker = SkraprWorker.Create(serviceProvider, cliArguments.SkraprDefinitionPath, devTools.Session, devTools, debugMode: cliArguments.Debug); if (cliArguments.Debug) { logger.LogInformation($"Operating in debug mode. Tasks may perform additional behavior or may skip themselves."); } if (cliArguments.Attach == true) { var targetInfo = devTools.Session.Target.GetTargetInfo(session.Id).GetAwaiter().GetResult(); var matchingRuleCount = worker.GetMatchingRules().GetAwaiter().GetResult().Count(); if (matchingRuleCount > 0) { logger.LogInformation($"Attach specified and {matchingRuleCount} rules match the current session's state; Continuing.", matchingRuleCount); worker.Post(new NavigateTask { Url = targetInfo.Url }); } else { logger.LogInformation($"Attach specified but no rules matched the current session's state; Adding start tasks."); worker.AddStartUrls(); } } else { logger.LogInformation($"Adding start tasks."); worker.AddStartUrls(); } Console.TreatControlCAsInput = true; logger.LogInformation("Skrapr is currently processing. Press ENTER to exit..."); var cancelKeyTokenSource = new CancellationTokenSource(); var workerCompletion = worker.Completion .ContinueWith((t) => cancelKeyTokenSource.Cancel()); var keyCompletion = ConsoleUtils.ReadKeyAsync(ConsoleKey.Enter, cancelKeyTokenSource.Token) .ContinueWith(async(t) => { if (!t.IsCanceled) { logger.LogWarning("Stop requested at the console, cancelling..."); worker.Cancel(); await worker.Completion; } }); Task.WaitAny(workerCompletion, keyCompletion); if (worker.Completion.IsFaulted) { logger.LogError("Worker was faulted. Exiting with status code of -1"); if (Debugger.IsAttached) { throw worker.Completion.Exception.Flatten(); } return(-1); } } catch (TaskCanceledException) { //Do Nothing } finally { //Cleanup. if (worker != null) { worker.Dispose(); worker = null; } if (devTools != null) { devTools.Dispose(); devTools = null; } if (browser != null) { browser.Dispose(); browser = null; } } logger.LogInformation("Worker completed successfully. Status code 0"); Debugger.Break(); return(0); }