public void CloseWindow() { var windows = _webDriver.WindowHandles.ToList(); for (int i = windows.Count - 1; i >= 0; i--) { try { _webDriver.SwitchTo().Window(windows[i]); _webDriver.Close(); try { var alert = _webDriver.SwitchTo().Alert(); if (alert != null) { Console.WriteLine(alert.Text); alert.Accept(); } } catch { } } catch (Exception) { } } }
public AccountDetail GetAccountDetails() { if (driver != null) { string abc = string.Empty; Document body = null; ReadOnlyCollection <IWebElement> alltables; try { driver.SwitchTo().Window(driver.CurrentWindowHandle); driver.SwitchTo().Frame("frame_menu"); driver.FindElementById("RRADTlink").Click(); driver.SwitchTo().Window(driver.CurrentWindowHandle); driver.SwitchTo().Frame("frame_txn"); SelectElement elem = new SelectElement(driver.FindElementById("fldacctnodesc")); elem.SelectByValue(this.Value); driver.FindElementByName("fldsubmit").Click(); alltables = driver.FindElementsByClassName("infotable"); abc = alltables[0].GetAttribute("innerHTML"); body = Supremes.Dcsoup.Parse(abc); } catch { throw new Exception("(ErrorCode:6) Service Or Network not Available Or Might be Some Rendering Problem Try again."); } AccountDetail detail = new AccountDetail(this.Value, driver); detail.AccountTitle = body.Body.TextNodes[1].Text; detail.AccountNumber = body.Body.TextNodes[4].Text; abc = alltables[2].GetAttribute("innerHTML"); body = Supremes.Dcsoup.Parse(abc); detail.CurrentBalance = Convert.ToDouble(body.Body.TextNodes[2].Text.Replace(",", "")); detail.AmountOnHold = Convert.ToDouble(body.Body.TextNodes[4].Text.Replace(",", "")); detail.UnClearedFunds = Convert.ToDouble(body.Body.TextNodes[6].Text.Replace(",", "")); detail.OverDraftLimit = Convert.ToDouble(body.Body.TextNodes[8].Text.Replace(",", "")); detail.AvailableBalance = Convert.ToDouble(body.Body.TextNodes[10].Text.Replace(",", "")); detail.NetAvailableBalanceForWithDrawls = Convert.ToDouble(body.Body.TextNodes[12].Text.Replace(",", "")); return(detail); } else { throw new Exception("(ErrorCode:5) Account object not initialized"); } }
public void ReloadPage() { _logger.Info("Start ReloadPage."); var result = "OK"; var shouldAlertAccept = (0 != String.Compare(_driver.Url, MainUrl, StringComparison.Ordinal)); try { _driver.Navigate().Refresh(); } catch (Exception ex) { _logger.Error( $"Navigate().RefreshException with message = {ex.Message}"); if (!ex.Message.StartsWith("Unexpected modal dialog")) { result = "ERROR"; shouldAlertAccept = false; } } if (shouldAlertAccept) { Thread.Sleep(500); try { if (_driver.SwitchTo().Alert() != null) { _driver.SwitchTo().Alert().Accept(); } } catch (NoAlertPresentException ex) { _logger.Trace(// Alert not present $"SwitchTo().NoAlertPresentException with message = {ex.Message}"); } } _logger.Info($"End ReloadPage. Status={result}"); }
/// <summary> /// SlideWithPhantomJs /// </summary> /// <param name="companyName"></param> private static string SlideUsePhantomJs(string companyName) { const string url = "http://www.gsxt.gov.cn/index.html"; var userAgent = @"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"; var options = new PhantomJSOptions(); options.AddAdditionalCapability(@"phantomjs.page.settings.userAgent", userAgent); using (var driver = new PhantomJSDriver(options)) { //设置浏览器大小 设置为最大 元素的X,Y坐标就准了 不然就不准(不知道原因) driver.Manage().Window.Maximize(); var navigation = driver.Navigate(); navigation.GoToUrl(url); //等待时间 var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60)); //等待元素全部加载完成 wait.Until(ExpectedConditions.ElementExists(By.Id("keyword"))); var keyWord = driver.FindElement(By.Id("keyword")); //keyWord.SendKeys("温州红辣椒电子商务有限公司"); keyWord.SendKeys(companyName); //等待元素全部加载完成 wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("btn_query"))); var js = (IJavaScriptExecutor)driver; var btnQuery = driver.FindElement(By.Id("btn_query")); //经测试,这里要停一下,不然刚得到元素就click可能不会出现滑动块窗口(很坑的地方) Thread.Sleep(1000); js.ExecuteScript("arguments[0].click();", btnQuery); //btnQuery.Click(); //btnQuery.SendKeys(Keys.Enter); //截图加滑动处理 //因为只有一个弹出窗口,所以直接进到这个里面就好了 var allWindowsId = driver.WindowHandles; if (allWindowsId.Count != 1) { throw new Exception("多个弹出窗口。"); } foreach (var windowId in allWindowsId) { driver.SwitchTo().Window(windowId); } //等待元素全部加载完成 wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(By.CssSelector("div.gt_box"))); //找到图片 var imageBox = driver.FindElement(By.CssSelector("div.gt_box")); //先休息一会,不然截图不对 Thread.Sleep(1000); //截图得到子图片 var imageFirst = GetSubImage(driver, imageBox); //imageFirst?.Save("c:/test.png"); var slide = driver.FindElement(By.CssSelector("div.gt_slider_knob.gt_show")); var action = new Actions(driver); //移到起始位置 action.ClickAndHold(slide).MoveByOffset(0, 0).Perform(); //先休息一会,不然截图不对 Thread.Sleep(1000); //再截图得到子图片 var imageSecond = GetSubImage(driver, imageBox); //imageSecond?.Save("c:/test1.png"); var pass = false; var tryTimes = 0; //试5次或者pass while (tryTimes++ < 5 && !pass) { Console.WriteLine($"第{tryTimes}次。"); var left = SlideImageHandler.FindXDiffRectangeOfTwoImage(imageFirst, imageSecond) - 7; Console.WriteLine($"减7后等于:{left}"); if (left <= 0) { throw new Exception("算出的距离小于等于0"); } var pointsTrace = SlideImageHandler.GeTracePoints(left); //移动 MoveHandler(pointsTrace, action, slide); wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(By.XPath("//div[@class='gt_info_text']/span[@class='gt_info_type']"))); //找得到元素,但是它不在当前可见的页面上。 var infoText = driver.FindElement(By.XPath("//div[@class='gt_info_text']/span[@class='gt_info_type']")).Text; if (infoText.Contains("验证通过")) { pass = true; } //如果判断为非人行为 刷新验证码 重新截图 else if (infoText.Contains("再来一次")) { wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(By.ClassName("gt_refresh_button"))); var refreshButtom = driver.FindElement(By.ClassName("gt_refresh_button")); refreshButtom.Click(); //等待元素全部加载完成 wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(By.CssSelector("div.gt_box"))); //找到图片 imageBox = driver.FindElement(By.CssSelector("div.gt_box")); //先休息一会,不然截图不对 Thread.Sleep(1000); //截图得到子图片 imageFirst = GetSubImage(driver, imageBox); //imageFirst?.Save("c:/test.png"); //移到起始位置 action.ClickAndHold(slide).MoveByOffset(0, 0).Perform(); //先休息一会,不然截图不对 Thread.Sleep(1000); //再截图得到子图片 imageSecond = GetSubImage(driver, imageBox); //imageSecond?.Save("c:/test1.png"); Console.WriteLine("刷新图片。"); pass = false; } else { pass = false; } Console.WriteLine($"pass:{pass}。"); //先休息一会,不然截图不对 //Thread.Sleep(1000); var imageThird = GetSubImage(driver, imageBox); //imageThird?.Save("c:/test2.png"); } Console.WriteLine(pass ? "验证通过。" : "验证失败。"); if (!pass) { throw new Exception("极速验证码验证失败。"); } //得到页面内容 return(driver.PageSource); } }
public HblBank(string Username, string Password) { try { driver.Navigate().GoToUrl("https://hblibank.com.pk/"); } catch { throw new Exception("(ErrorCode:1) Bank Service Unavailable Or Network Not Available"); } try { driver.FindElementById("btnProceed").Click(); driver.FindElementByName("fldLoginUserId").SendKeys(Username); driver.FindElementByName("fldPassword").SendKeys(Password); driver.FindElementById("foo").Click(); ReadOnlyCollection <String> handles = driver.WindowHandles; driver.SwitchTo().Window(handles[0]); } catch { throw new Exception("(ErrorCode:2) Service Response Delay"); } try { driver.SwitchTo().Frame("frame_menu"); driver.FindElementById("RRAAClink").Click(); } catch { throw new Exception("(ErrorCode:3) Credentials are not Valid Or Network Not Available"); } try { driver.SwitchTo().Window(driver.CurrentWindowHandle); driver.SwitchTo().Frame("frame_txn"); string abc = driver.FindElementByName("fldacctno").GetAttribute("innerHTML"); Document body = Supremes.Dcsoup.Parse(abc); Elements options = body.Select("option"); Accounts = new List <Account>(); foreach (Element el in options) { if (!el.Val.Equals("")) { Accounts.Add(new Account(driver) { Name = el.OwnText, Value = el.Val }); } } } catch { throw new Exception("(ErrorCode:4) Network Or Service not Available"); } }
public void ScheduleGET() { var driverService = PhantomJSDriverService.CreateDefaultService(); driverService.HideCommandPromptWindow = true; // Disables verbose phantomjs output IWebDriver driver = new PhantomJSDriver(driverService); //IWebDriver driver = new FirefoxDriver(); // Debug with firefox. Console.WriteLine("Logging into Office 365."); driver.Navigate().GoToUrl("https://wegmans.sharepoint.com/resources/Pages/LaborPro.aspx"); if (driver.Title.ToString() == "Sign in to Office 365") { IWebElement loginentry = driver.FindElement(By.XPath("//*[@id='cred_userid_inputtext']")); loginentry.SendKeys(Username); IWebElement rememberme = driver.FindElement(By.XPath("//*[@id='cred_keep_me_signed_in_checkbox']")); rememberme.Click(); } WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); try { wait.Until((d) => { return(d.Title.ToString().Contains("Sign In") || d.Title.ToString().Contains("My Schedule")); }); } // Sometimes it skips the second login page. catch (WebDriverTimeoutException) { driver.Quit(); throw new ScheduleGETException("Did not recieve an appropriate response from the Sharepoint server. The connection most likely timed out."); } Console.WriteLine("Logging into Sharepoint."); if (driver.Title.ToString() == "Sign In") { try { wait.Until((d) => { return(d.FindElement(By.XPath("//*[@id='passwordInput']"))); }); } catch (Exception) { driver.Quit(); throw new ScheduleGETException("Password input box did not load correctly."); } IWebElement passwordentry = driver.FindElement(By.XPath("//*[@id='passwordInput']")); password = ConvertToUnsecureString(securePwd); passwordentry.SendKeys(password); ClearPassword(); passwordentry.Submit(); } try { wait.Until((d) => { return(d.Title.ToString().Contains("Sign In") || d.Title.ToString().Contains("My Schedule")); }); } // Checks to see if the password was incorrect. catch (WebDriverTimeoutException) { driver.Quit(); throw new ScheduleGETException("Did not recieve an appropriate response from the Sharepoint server. The connection most likely timed out."); } if (driver.Title.ToString() == "Sign In") { IWebElement error = driver.FindElement(By.XPath("//*[@id='error']")); string errorString = error.Text.ToString(); if (errorString.Contains("Incorrect user ID or password")) { while (driver.Title.ToString() == "Sign In") { IWebElement usernameentry = driver.FindElement(By.XPath("//*[@id='userNameInput']")); IWebElement passwordentry = driver.FindElement(By.XPath("//*[@id='passwordInput']")); usernameentry.Clear(); passwordentry.Clear(); Console.WriteLine("You seem to have entered the wrong username or password."); GetLoginCreds(); Console.WriteLine("Trying again..."); usernameentry.SendKeys(Username); password = ConvertToUnsecureString(securePwd); passwordentry.SendKeys(password); ClearPassword(); passwordentry.Submit(); } SaveLoginCreds(); } else { Console.WriteLine("An unexpected error has occured with the webpage."); Console.WriteLine(errorString); driver.Quit(); throw new ScheduleGETException("An unexpected error has occured with the webpage."); } } Console.WriteLine("Waiting for LaborPro..."); int retries = 2; while (true) // Retry because this error can be solved by a simple page reload. { try { wait.Until((d) => { return(d.SwitchTo().Frame(0)); }); break; } // Waits for the inline frame to load. catch (WebDriverTimeoutException) { Console.WriteLine("LaborPro link's inline frame was not generated properly."); Console.WriteLine("Reloading the page..."); driver.Navigate().Refresh(); retries--; if (retries <= 0) { driver.Quit(); throw new ScheduleGETException("LaborPro link's inline frame was not generated properly."); } } } string BaseWindow = driver.CurrentWindowHandle; try { wait.Until((d) => { return(d.FindElement(By.XPath("/html/body/a"))); }); } // Waits until javascript generates the SSO link. catch (Exception) { if (driver.Title.ToString().Contains("Sign In")) // We were redirected to the sign-in page once again, so let's fill it out again... { IWebElement usernameentry = driver.FindElement(By.XPath("//*[@id='userNameInput']")); IWebElement passwordentry = driver.FindElement(By.XPath("//*[@id='passwordInput']")); usernameentry.Clear(); passwordentry.Clear(); usernameentry.SendKeys(Username); password = ConvertToUnsecureString(securePwd); passwordentry.SendKeys(password); ClearPassword(); passwordentry.Submit(); } else { driver.Quit(); throw new ScheduleGETException("LaborPro SSO Link was not generated properly."); } } IWebElement accessschedule = driver.FindElement(By.XPath("/html/body/a")); accessschedule.Click(); string popupHandle = string.Empty; ReadOnlyCollection <string> windowHandles = driver.WindowHandles; foreach (string handle in windowHandles) { if (handle != driver.CurrentWindowHandle) { popupHandle = handle; break; } } driver.SwitchTo().Window(popupHandle); Console.WriteLine("Accessing LaborPro."); try { wait.Until((d) => { return(d.Title.ToString().Contains("Welcome")); }); } catch (WebDriverTimeoutException) { throw new ScheduleGETException("Did not properly switch to LabroPro Window."); } Schedules.Add(driver.PageSource.ToString()); for (int i = 0; i < 2; i++) // Clicks "Next" and gets the schedules for the next two weeks. { driver.FindElement(By.XPath("//*[@id='pageBody']/form/table[2]/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td/div/table[1]/tbody/tr/td[1]/a[3]")).Click(); Schedules.Add(driver.PageSource.ToString()); } ClearPassword(); // We don't need the password anymore, so let's not keep it laying around. driver.Quit(); Console.WriteLine("Got your Schedule."); }
public AccountStatement GetAccountStatement(DateTime From, DateTime To) { if (driver != null) { try { driver.SwitchTo().Window(driver.CurrentWindowHandle); driver.SwitchTo().Frame("frame_menu"); driver.FindElementById("RRAAClink").Click(); driver.SwitchTo().Window(driver.CurrentWindowHandle); driver.SwitchTo().Frame("frame_txn"); SelectElement elem = new SelectElement(driver.FindElementByName("fldacctno")); elem.SelectByValue(this.Account_Value); //driver.SwitchTo().Window(driver.CurrentWindowHandle); //driver.SwitchTo().Frame("frame_txn"); var abcd = driver.FindElementsByClassName("objselect"); SelectElement elem2 = new SelectElement(abcd[1]); elem2.SelectByValue("3"); driver.FindElementById("fldfromdateid").SendKeys(From.ToString("dd-MM-yyyy")); driver.FindElementById("fldtodateid").SendKeys(To.ToString("dd-MM-yyyy")); driver.FindElementByName("fldsubmit").Click(); var alltables = driver.FindElementsByClassName("graphtable"); string abc = alltables[0].GetAttribute("innerHTML"); Document body = Supremes.Dcsoup.Parse(abc); AccountStatement statement = new AccountStatement(); statement.OpeningBalance = HelpingClass.ToDouble(body.Body.TextNodes[4].Text); statement.ClosingBalance = HelpingClass.ToDouble(body.Body.TextNodes[5].Text); abc = alltables[1].GetAttribute("innerHTML"); body = Supremes.Dcsoup.ParseBodyFragment("<table>" + abc + "</table>"); List <AccountActivity> activities = new List <AccountActivity>(); AccountActivity activity = new AccountActivity(); Elements trs = body.Select("tr"); Elements tds = null; bool isavilable = false; abc = driver.FindElementByClassName("standardtable").GetAttribute("innerHTML"); body = Supremes.Dcsoup.ParseBodyFragment("<table>" + abc + "</table>"); string[] arr = body.Body.Text.Split(new string[] { "Pages : (" }, StringSplitOptions.None); int totalpage = Convert.ToInt32(arr[1].Split(')')[0].Trim()); int currentpage = 1; do { for (int i = 0; i < trs.Count; i++) { if (i != 0) { tds = trs[i].Select("td"); activity = new AccountActivity(); activity.TransactionDate = DateTime.ParseExact(tds[0].OwnText, "dd-MM-yyyy", CultureInfo.InvariantCulture); activity.ValueDate = DateTime.ParseExact(tds[1].OwnText, "dd-MM-yyyy", CultureInfo.InvariantCulture); activity.TransactionReferenceNo = tds[2].OwnText; activity.Description = tds[3].OwnText; activity.Debit = HelpingClass.ToDouble(tds[4].OwnText); activity.Credit = HelpingClass.ToDouble(tds[5].OwnText); activity.Balance = HelpingClass.ToDouble(tds[6].OwnText); activities.Add(activity); } } if (currentpage < totalpage) { currentpage++; driver.FindElementByCssSelector("a[href=\"javascript:SendPageRequest(" + currentpage.ToString() + ")\"]").Click(); alltables = driver.FindElementsByClassName("graphtable"); abc = alltables[1].GetAttribute("innerHTML"); body = Supremes.Dcsoup.ParseBodyFragment("<table>" + abc + "</table>"); trs = body.Select("tr"); isavilable = true; } else { isavilable = false; } } while (isavilable); statement.Activities = activities.AsReadOnly(); return(statement); } catch { throw new Exception("(ErrorCode:11) Network Or Service is not available Or May be Problem occured While Fetching Account Details Try Again.."); } } else { throw new Exception("(ErrorCode:10) Account Detail object not initialized"); } }
/// <summary> /// Our objective from here is to get the json data in the source and save it. We'll pull it apart later. /// </summary> /// <param name="args"></param> static void Main(string[] args) { try { Console.WriteLine("Hit enter to start the magic....."); Console.ReadLine(); string uid = "*****@*****.**", pwd = "leblanc2016"; // PhantomJSOptions options = new PhantomJSOptions(); // driver.Manage().Timeouts().ImplicitWait = implicitWait; driver.Manage().Timeouts().PageLoad = pageLoadWait; //I can't really say what this might do but f**k it, why not? driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080); driver.Navigate().GoToUrl("http://www.loopnet.com/xNet/MainSite/User/customlogin.aspx?LinkCode=31824"); //var bigAssTextBox = driver.FindElementByName("geography"); //Console.WriteLine("This element has this for a class value: " + bigAssTextBox.GetAttribute("class")); //login driver.FindElement(By.Name("ctlLogin$LogonEmail")).SendKeys(uid); driver.FindElement(By.Name("ctlLogin$LogonPassword")).SendKeys(pwd); driver.FindElement(By.Id("ctlLogin_btnLogon")).Click(); //Go to the searches page // driver.Navigate().GoToUrl("http://www.loopnet.com/xNet/MainSite/Listing/SavedSearches/MySavedSearches_FSFL.aspx?LinkCode=29400"); // //Get the search names first, then get their urls // var submarketNamesCollection = driver.FindElement(By.ClassName("savedSearchContainer")).FindElements(By.XPath("./tbody/tr/td[2]")); var searchLinkElements = driver.FindElementsByXPath("//*[@id='form1']/div[5]/div/div/table/tbody/tr/td[1]/div/a[1]"); //Spin up a collection to hold our data from here on out // List <BaseSearch> recoveredSearches = new List <BaseSearch>(); if (submarketNamesCollection.Count != searchLinkElements.Count) { throw new Exception($"Submarket/Search names count: {submarketNamesCollection.Count}. Doesn't equal recovered link elements count: {searchLinkElements.Count}"); } for (int i = 0; i < submarketNamesCollection.Count; i++) { recoveredSearches.Add(new BaseSearch() { Name = submarketNamesCollection[i].Text, BaseResultsURL = searchLinkElements[i].GetAttribute("href") }); } //Iterate through the results and do your thing for (int searchIndex = 0; searchIndex < recoveredSearches.Count; searchIndex++) { var currentSearch = recoveredSearches[searchIndex]; driver.Navigate().GoToUrl(currentSearch.BaseResultsURL); //Property name is in the title attribute of these link elements var propertyNamesList = driver.FindElements(By.XPath("//*[@id='placardSec']//h5[@class = 'listing-address']/a")).Select(x => x.GetAttribute("title")).ToList <string>(); //Let's get the building class since they need that. May also need broker info. var possibleBldgClasses = driver.FindElements(By.XPath("//*[@id='placardSec']/div[2]/div/article/div[1]/section[2]/div[1]/ul/li[3]/i")).Select(x => x.Text.Trim()).ToList <string>(); //Make sure the classes list and names list are 1 to 1 if (propertyNamesList.Count != possibleBldgClasses.Count) { throw new Exception($"The property names list count: {propertyNamesList.Count} does not match the Bldg Class candidate list count: {possibleBldgClasses.Count}"); } for (int tempIndex = 0; tempIndex < propertyNamesList.Count; tempIndex++) { currentSearch.Listings.Add(new Listing() { PropertyName = propertyNamesList[tempIndex], BldgClass = char.IsLetter(possibleBldgClasses[tempIndex][0]) ? possibleBldgClasses[tempIndex] : "N/A" }); } //Broker info. Deal with that later. //Click the create reports button // driver.FindElement(By.XPath("/html/body/section/main/section/div/section[1]//div[@class='toolbar-right']/div/button")).Click(); //Select all reports // bool firstTry = true; bool lastPage = false; while (!lastPage) { //We're already on the page for the first group we need to select, so we don't go to the next one on the first go around // if (!firstTry) { //firstTry = false; FlipDriverTimeout(true); var nextPageLinkContainer = driver.FindElements(By.CssSelector("a.caret-right-large")); FlipDriverTimeout(false); if (nextPageLinkContainer?.Count > 0) { nextPageLinkContainer[0].Click(); } else { lastPage = true; } } firstTry = false; //Select all the elements then circle around to the next page and repeat. // //driver.GetScreenshot(); var selectAllButton = driver.FindElement(By.XPath("//button[text()='Select all']")); ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click();", selectAllButton); //OpenQA.Selenium.Interactions.Actions actions = new OpenQA.Selenium.Interactions.Actions(driver); //actions.MoveToElement(selectAllButton); //actions.Perform(); // //selectAllButton.Click(); } //Onward to our report. Click the big red generate reports button. driver.FindElement(By.XPath("//button[text()='Generate Reports']")).Click(); // //Select listing summary report radio button driver.FindElement(By.Id("listingSummary")).Click(); // driver.FindElement(By.Id("btnCreateReport1")).Click(); // driver.SwitchTo().Frame("reportFrame"); //Get that dirty JSON string source = driver.PageSource; source = source.Substring(source.IndexOf("\"Data\":{\"Report\":")); source = source.Substring(0, source.IndexOf("Config={")).Trim(); //If this is indeed valid JSON, save it. currentSearch.rawJSON = source; // if (Directory.Exists(jsonOutputDirectory) == false) { Directory.CreateDirectory(jsonOutputDirectory); } // File.WriteAllText(jsonOutputDirectory + "//SearchData_" + searchIndex, currentSearch.rawJSON); } } catch (Exception ex) { Console.WriteLine("Explosion: " + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine); } finally { driver.Close(); Console.WriteLine("Tear down complete, strike [ENTER] to exit."); } }