Separate the functions and basic test into two cs files - c#

I want to create global cs file for all my test projects to keep all my constants and functions.
For example this file for different tests global.cs:
namespace SeleniumTests
{
Public class forAllTests
{
//....
public void Login()
{
wait.Until<IWebElement>((d) => { return d.FindElement(By.Id("login")); });
driver.FindElement(By.Id("login")).SendKeys("login");
wait.Until<IWebElement>((d) => { return d.FindElement(By.Id("password")); });
driver.FindElement(By.Id("password")).SendKeys("password");
}
}
}
And for example another file Program.cs
namespace SeleniumTests
{
Public class Test
{
forAllTests.Login();
//.....
}
}
Its possible or not?
UPD.
Thanks for answers. Yes, I want more specific advice. I am making tests for Firefox, Chrome and Safari. I know about page objects pattern and i am using it. For example some code from me.
Soo some code here(parts 3* 4* - does not works and want to make them correct, please help me). How its works now:
1* Program.cs --
using System;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Safari;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Support.PageObjects;
using System.Diagnostics;
using System.Threading;
using Microsoft.Office.Interop.Excel;
using Excel = Microsoft.Office.Interop.Excel;
using System.Web;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using System.Windows.Controls;
namespace SeleniumTests
{
[TestFixture]
public class Auth01
{
private bool acceptNextAlert = true;
private LoginPage loginPage;
private PatientsPage patientsPage;
private MainViewPage mainViewPage;
private EmkPage emkPage;
private IWebDriver driver;
private StringBuilder verificationErrors;
private string baseURL;
string drop_down_id;
string drop_down_text;
string url1;
string url2;
string now1;
[SetUp]
public void SetupTest()
{
driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
baseURL = "http://....";
driver.Navigate().GoToUrl(baseURL + Constants.startUrl);
// driver.Manage().Window.Maximize();
loginPage = new LoginPage();
PageFactory.InitElements(driver, loginPage);
verificationErrors = new StringBuilder();
}
public void login()
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
loginPage.Login.Clear();
loginPage.Login.SendKeys("login");
loginPage.Password.Clear();
loginPage.Password.SendKeys("password");
IWebElement myDynamicElement = wait.Until<IWebElement>((d) => { return d.FindElement(By.CssSelector(loginPage.enterbuttonPublic)); });
loginPage.EnterButton.Click();
}
public void drop_down()
{
IWebElement elem = driver.FindElement(By.Id(drop_down_id));
var options = elem.FindElements(By.TagName("option"));
string opt;
string value;
string x;
foreach (IWebElement option in options)
{
opt = option.Text;
value = option.GetAttribute("value");
if (drop_down_text.Equals(opt))
{
x = "//select[#id='" + drop_down_id + "']/option[#value='" + value + "']";
}
}
}
[TearDown]
public void TeardownTest()
{
try
{
driver.Quit();
}
catch (Exception)
{
} Assert.AreEqual("", verificationErrors.ToString());
}
[Test]
public void The0Auth01Test()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
login();
//.....
drop_down_id="id";
drop_down_text = "text";
drop_down();
//...
stopWatch.Stop();
}
static void Main()
{
Auth01 Auth01_1 = new Auth01();
Auth01_1.SetupTest();
Auth01_1.The0Auth01Test();
}
2* AllAuth.cs --- // for all tests
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Support.PageObjects;
using System.IO
;
namespace SeleniumTests
{
public class LoginPage
{
private IWebDriver driver;
const string login = "USERNAME";
public string loginPublic = login;
[FindsBy(How = How.Id, Using = login)]
public IWebElement Login { get; set; }
const string password = "PASSWORD";
public string passwordPublic = password;
[FindsBy(How = How.Id, Using = password)]
public IWebElement Password { get; set; }
const string enterbutton = "button.button-gray";
public string enterbuttonPublic = enterbutton;
[FindsBy(How = How.CssSelector, Using = enterbutton)]
public IWebElement EnterButton { get; set; }
const string notification = "#notification-message";
public string notificationPublic = notification;
[FindsBy(How = How.CssSelector, Using = notification)]
public IWebElement Notification { get; set; }
const string body = "BODY";
public string bodyPublic = body;
[FindsBy(How = How.CssSelector, Using = body)]
public IWebElement Body { get; set; }
public LoginPage() { }
public LoginPage(IWebDriver driver)
{
this.driver = driver;
if (!driver.Url.Contains("http:..."))
{
throw new StaleElementReferenceException("This is not the login page");
}
PageFactory.InitElements(driver, this);
}
}
3* And I dream about:
AllAuth.cs ---
///...
namescpace SeleniumTests
{
/////.....
public class Fantasy
{
private IWebDriver driver;
login()
{
//....
}
drop_down()
{
//...
}
}
}
4* Program.cs ---
///...
namescpace SeleniumTests
{
/////.....
[Test]
public void The0Auth01Test()
{
fantasy.login();
fantasy.drop_down();
}
///...
}

Sure it's possible. Selenium is merely and API accessed through the WebDriver.dll to drive a browser. Any coding structure you want to use can easily be used for this. I have done a 7 layer version for a company and have seen many just write it all in 1, 2, or 3 layers.
The question is what is best for your organization. For example...if you utilize a particular UnitTest Framework then your "tests" will all exist in a unit test project and reference your core functions similar to an API layer. I would recommend at the very least to incorporate this, as repeating code for common controls in your application is really poor for maintainability and best practices.
The above is in layers and not files. Unless you only have like 5 total tests it is really impractical and difficult to maintain trying to put everything into one or two files. I would really recommend using common coding standards and practices to go with Selenium tests, just like regular c# code. The below links are for c# since this is tagged as c#.
Naming conventions: http://msdn.microsoft.com/en-us/library/ff926074.aspx
Framework Guidelines: http://msdn.microsoft.com/en-us/library/ms229042.aspx
Standards Guidlelines: http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx
Many more if you google it...If you would like more specific advice please add more details to your question, that indicate what your project is, how many tests, specifics of the type of web application and how many different browser types are supported, does it support mobile, database usage, team size, etc...All factor into a good design
UPDATE:
It looks like you are on the right path, but you will need to setup your driver and pass it to the functions...or use a public/protected variable that is the same for all. The way you have it now it looks like it is starting a new driver every time you call a separate function/method which of course won't work.
So put your setup at the top of your test file (#3) with a single test method in (#4) to "setup". When (#4) first test is called the setup will instantiate your driver and save it in (#3). Then pass that driver variable into all your functions on (#3->#2) so that they execute on the same driver instance. The actual setup call should be in (#3) but called similar with the fantasy.setup(); from (#4). Similarly when you update your page object you pass the existing driver into it and overwrite the existing page object with the new page object...unless you want to keep a bunch of different pages...watch memory usage. This will allow your methods to not have to worry about the driver handling at all. This will also allow you to kick off multiple test threads and each will maintain their own drivers. Then when you call the fantasy.login(); it will go to that method in (#3) and call the (#2) method and pass the private driver from memory in (#3) to (#2) method for execution purposes.
Please let me know if that isn't clear...

Related

Not sure how to handle exceptions using try catch if element was not found

I am trying to handle the error message on login page by clearing the Username field from the entered input.
Here is my code:
using OpenQA.Selenium;
using System;
using System.Linq.Expressions;
using TestProject.Common.Extensions;
using TestProject.SDK;
using TestProject.SDK.Tests;
using TestProject.SDK.Tests.Helpers;
namespace SecondTest
{
public class LoginTest : IWebTest
{
public object Assert { get; private set; }
public object TimeUnit { get; private set; }
public object InvalidInputErrorTxt { get; private set; }
public bool IWebelement { get; private set; }
public bool ErrorMsg { get; private set; }
public ExecutionResult Execute(WebTestHelper helper)
{
var driver = helper.Driver;
var URL = "https://www.office1.bg/login";
driver.Navigate().GoToUrl(URL);
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
driver.FindElementById("CybotCookiebotDialogBodyLevelButtonAccept").Click();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
//Login
Pages.LoginPage LoginPage = new Pages.LoginPage(driver);
LoginPage.PerformLogin("atanas.grudev1#gmail.com", "123456789");
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
try
{
IWebElement Level = driver.FindElementByClassName("corporal-page-list-item");
if (Level.Displayed)
{
Level.Click();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
driver.FindElementByClassName("corporate-login-button-wrapper").Click();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
return ExecutionResult.Passed;
}
else
{
IWebElement ErrorMsg = driver.FindElementByXPath("//*[#id='loginForm']/div/div[1]");
if (ErrorMsg.Displayed)
{
LoginPage.TxtUserName.Clear();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
return ExecutionResult.Failed;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return ExecutionResult.Passed;
}
}
}
Seems ExecutionResult at the beginning requires return ExecutionResult.Passed/Failed; at the end of the code, but since I have try - catch I am not sure how to get the correct result. End goal is:
If valid credentials are entered code from the first if statement should be executed and to get Passed result.
If the entered credentials are not valid the website will throw an error and if the error is present on the the screen the input from the username field should be cleared and get the Failed Result.
Thank you in advance!
A few suggestions:
In general, you want to avoid use of try-catch to control code flow whenever possible. In this case, you can use driver.FindElements() (note the plural ElementS) and check for an empty list to avoid exceptions being thrown when no element is found. This is a best practice according to the docs.
findElement should not be used to look for non-present elements, use findElements(By) and assert zero length response instead.
Setting the timeout for ImplicitWait only needs to be done once. Once set, that timeout is applied automatically every time an element is searched for. It doesn't actually wait when called... I think maybe you are confusing it with WebDriverWait?
Using ImplicitWait is not recommended by the Selenium contributors. You should instead use WebDriverWait each time you need to wait.
I would suggest you investigate and use the Page Object Model. If done right, it will save you a lot of time with code reuse, make your project much more organized, and make your test code a lot cleaner. It looks like you are trying to use something like Page Objects with your LoginPage.PerformLogin() call but all your driver.FindElement() calls should be in the appropriate page object and you should have one page object per "page".
Here's the code after implementing the first two suggestions. I'll let you do #3 and #4, if you choose to. I removed the try-catch, added new ifs, and removed all but the first ImplicitWait set.
using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Linq;
using TestProject.Common.Extensions;
using TestProject.SDK;
using TestProject.SDK.Tests;
using TestProject.SDK.Tests.Helpers;
namespace SecondTest
{
public class LoginTest : IWebTest
{
public object Assert { get; private set; }
public object TimeUnit { get; private set; }
public object InvalidInputErrorTxt { get; private set; }
public bool IWebelement { get; private set; }
public bool ErrorMsg { get; private set; }
public ExecutionResult Execute(WebTestHelper helper)
{
var driver = helper.Driver;
var URL = "https://www.office1.bg/login";
driver.Navigate().GoToUrl(URL);
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
driver.FindElementById("CybotCookiebotDialogBodyLevelButtonAccept").Click();
//Login
Pages.LoginPage LoginPage = new Pages.LoginPage(driver);
LoginPage.PerformLogin("atanas.grudev1#gmail.com", "123456789");
IReadOnlyCollection<IWebElement> level = driver.FindElementsByClassName("corporal-page-list-item");
if (level.Any() && level.ElementAt(0).Displayed)
{
level.ElementAt(0).Click();
driver.FindElementByClassName("corporate-login-button-wrapper").Click();
return ExecutionResult.Passed;
}
IReadOnlyCollection<IWebElement> errorMsg = driver.FindElementsByXPath("//*[#id='loginForm']/div/div[1]");
if (errorMsg.Any() && errorMsg.ElementAt(0).Displayed)
{
LoginPage.TxtUserName.Clear();
return ExecutionResult.Failed;
}
return ExecutionResult.Passed;
}
}
}
A few notes on the new code that you may not have seen before.
.Any() is an equivalent in LINQ to .Count > 0. It returns true if the list is not empty, and false otherwise.
.ElementAt() is a LINQ method that allows you to access a member of the collection by index. NOTE: Even though it has "Element" in the name, it has nothing to do with WebElement or Selenium.
Let me know if you have any questions.

Object Reference not set to an instance of an object error C# Class selenium webdriver [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have a class called Driver and I'm trying to five its attributes to another class, so I can use it for the Locators, but it is giving me this error on the driver from the locator.
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
namespace AutomationTest
{
public class BaseLocator
{
public static RemoteWebDriver driver;
public static WebDriverWait wait;
public IWebElement SearchBox => driver.FindElementByCssSelector("#twotabsearchtextbox");
public IWebElement SearchButton => driver.FindElementByCssSelector("span#nav-search-submit-text + input");
public IWebElement GoToShoppingButton => driver.FindElementByCssSelector("#nav-cart-count");
public IWebElement GoToYourAmazonButton => driver.FindElementByCssSelector("a#nav-your-amazon");
}
}
and I have Driver set up as:
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;
namespace AutomationTest
{
public class Driver
{
public RemoteWebDriver SetUp()
{
RemoteWebDriver driver = new ChromeDriver();
return driver;
}
}
}
You need to initialize driver. Unless you plan on having multiple things to setup in the driver class, it's unnecessary (don't over think it).
this example initializes the driver object inline with the definition.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
namespace AutomationTest
{
public class BaseLocator
{
public static RemoteWebDriver driver = new ChromeDriver();
//public static WebDriverWait wait; //TODO: Initialize variable as above
public IWebElement SearchBox => driver.FindElementByCssSelector("#twotabsearchtextbox");
public IWebElement SearchButton => driver.FindElementByCssSelector("span#nav-search-submit-text + input");
public IWebElement GoToShoppingButton => driver.FindElementByCssSelector("#nav-cart-count");
public IWebElement GoToYourAmazonButton => driver.FindElementByCssSelector("a#nav-your-amazon");
}
}
while this example initializes it via the default constructor method:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
namespace AutomationTest
{
public class BaseLocator
{
public static RemoteWebDriver driver;
//public static WebDriverWait wait;
public BaseLocator()
{
driver = new ChromeDriver();
}
public IWebElement SearchBox => driver.FindElementByCssSelector("#twotabsearchtextbox");
public IWebElement SearchButton => driver.FindElementByCssSelector("span#nav-search-submit-text + input");
public IWebElement GoToShoppingButton => driver.FindElementByCssSelector("#nav-cart-count");
public IWebElement GoToYourAmazonButton => driver.FindElementByCssSelector("a#nav-your-amazon");
}
}
If you don't need driver outside of the BaseLocator class, then you should consider making it private. Not sure it needs to be declared as a static member either.
I'm unfamiliar with Selenium, so I approached this from a C# language angle- but it should get you down the track.
recommended reading on constructors: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors

ML.NET to predict New York taxi fares - Program does not contain a static 'Main' method suitable for an entry point [duplicate]

This question already has answers here:
Can't specify the 'async' modifier on the 'Main' method of a console app
(20 answers)
Closed 4 years ago.
I was trying to do the example of ML.net to predict New York taxi fares, but when I finished the tutorial had the message: Program does not contain a static 'Main' method suitable for an entry point
Here the code that I did:
Class Program.cs
using System;
using System.IO;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Models;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
using System.Threading.Tasks;
namespace TaxiFarePrediction2
{
public class Program
{
static readonly string _datapath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-train.csv");
static readonly string _testdatapath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-test.csv");
static readonly string _modelpath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
static async Task Main(string[] args)
{
PredictionModel<TaxiTrip, TaxiTripFarePrediction> model = await Train();
Evaluate(model);
TaxiTripFarePrediction prediction = model.Predict(TestTrips.Trip1);
Console.WriteLine("Predicted fare: {0}, actual fare: 29.5", prediction.FareAmount);
}
public static async Task<PredictionModel<TaxiTrip, TaxiTripFarePrediction>> Train()
{
var pipeline = new LearningPipeline
{
new TextLoader(_datapath).CreateFrom<TaxiTrip>(useHeader: true, separator: ','),
new ColumnCopier(("FareAmount", "Label")),
new CategoricalOneHotVectorizer(
"VendorId",
"RateCode",
"PaymentType"),
new ColumnConcatenator(
"Features",
"VendorId",
"RateCode",
"PassengerCount",
"TripDistance",
"PaymentType"),
new FastTreeRegressor()
};
PredictionModel<TaxiTrip, TaxiTripFarePrediction> model = pipeline.Train<TaxiTrip, TaxiTripFarePrediction>();
await model.WriteAsync(_modelpath);
return model;
}
private static void Evaluate(PredictionModel<TaxiTrip, TaxiTripFarePrediction> model)
{
var testData = new TextLoader(_testdatapath).CreateFrom<TaxiTrip>(useHeader: true, separator: ',');
var evaluator = new RegressionEvaluator();
RegressionMetrics metrics = evaluator.Evaluate(model, testData);
Console.WriteLine($"Rms = {metrics.Rms}");
Console.WriteLine($"RSquared = {metrics.RSquared}");
}
}
}
class TaxiTrip.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ML.Runtime.Api;
namespace TaxiFarePrediction2
{
public class TaxiTrip
{
[Column("0")]
public string VendorId;
[Column("1")]
public string RateCode;
[Column("2")]
public float PassengerCount;
[Column("3")]
public float TripTime;
[Column("4")]
public float TripDistance;
[Column("5")]
public string PaymentType;
[Column("6")]
public float FareAmount;
}
public class TaxiTripFarePrediction
{
[ColumnName("Score")]
public float FareAmount;
}
}
class TestTrips.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ML.Runtime.Api;
namespace TaxiFarePrediction2
{
public class TaxiTrip
{
[Column("0")]
public string VendorId;
[Column("1")]
public string RateCode;
[Column("2")]
public float PassengerCount;
[Column("3")]
public float TripTime;
[Column("4")]
public float TripDistance;
[Column("5")]
public string PaymentType;
[Column("6")]
public float FareAmount;
}
public class TaxiTripFarePrediction
{
[ColumnName("Score")]
public float FareAmount;
}
}
The tutorial is in : https://learn.microsoft.com/en-us/dotnet/machine-learning/tutorials/taxi-fare
please help me to do this example.
Main method can not support asycn before c# 7.1, You can start main once and than create tasks in main method that can be async if you are using earlier versions.
You can writesomething mentioned by Chris Moschini
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
// Do any async anything you need here without worry
}).GetAwaiter().GetResult();
}
The link you posted clearly mention about c# version specified ...
Because the async Main method is the feature added in C# 7.1 and the default language version of the project is C# 7.0, you need to change the language vers
ion to C# 7.1 or higher. To do that, right-click the project node in Solution Explorer and select Properties. Select the Build tab and select the Advanced button. In the dropdown, select C# 7.1 (or a higher version). Select the OK button.
A good read on main with async

Error CS0103: The name 'TimeSpan' does not exist in the current context (CS0103) (testingProgram)?

I am trying to create tests in C# with selenium driver in visual studio. I get the following error. Error CS0103: The name 'TimeSpan' does not exist in the current context (CS0103) (testingProgram) ?? I also have a second error displayed in the images provided. The code uses the PageObjectPattern >> https://www.automatetheplanet.com/page-object-pattern/
Btw I am using a mac. I have added some images to help better describe the situation.The following images show both files. Can someone please try to run in on their end to see if it works.
How do I fix this? Can someone try and run the program to see if it is running on their end?? How do I get this program to run successfully?
here is the following code-
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support;
using OpenQA.Selenium.Support.UI;
[TestClass]
public class SearchEngineTests
{
public IWebDriver Driver { get; set; }
public WebDriverWait Wait { get; set; }
[TestInitialize]
public void SetupTest()
{
this.Driver = new FirefoxDriver();
this.Wait = new WebDriverWait(this.Driver, TimeSpan.FromSeconds(30));
}
[TestCleanup]
public void TeardownTest()
{
this.Driver.Quit();
}
[TestMethod]
public void SearchTextInSearchEngine_First()
{
SearchEngineMainPage searchEngineMainPage = new SearchEngineMainPage(this.Driver);
searchEngineMainPage.Navigate();
searchEngineMainPage.Search("Automate The Planet");
searchEngineMainPage.ValidateResultsCount("264,000 RESULTS");
}
}
here is the second file-
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
public class SearchEngineMainPage
{
private readonly IWebDriver driver;
private readonly string url = #"searchEngineUrl";
[FindsBy(How = How.Id, Using = "sb_form_q")]
public IWebElement SearchBox { get; set; }
[FindsBy(How = How.Id, Using = "sb_form_go")]
public IWebElement GoButton { get; set; }
[FindsBy(How = How.Id, Using = "b_tween")]
public IWebElement ResultsCountDiv { get; set; }
public void Navigate()
{
this.driver.Navigate().GoToUrl(this.url);
}
public void Search(string textToType)
{
this.SearchBox.Clear();
this.SearchBox.SendKeys(textToType);
this.GoButton.Click();
}
public void ValidateResultsCount(string expectedCount)
{
Assert.IsTrue(this.ResultsCountDiv.Text.Contains(expectedCount), "The results DIV doesn't contains the specified text.");
}
}
Okay, so, in both cases, the error message tells you exactly what's missing.
First, TimeSpan is in the System namespace, and there is no using System; in there, so the compiler can't find it.
Second, SearchEngineMainPage doesn't have a constructor that takes a single parameter (in fact it doesn't have a constructor at all, so the compiler generates one for you, but that one takes no parameters, so it's still not good).

Selenium C# parallel testing using single driver\browser

I have a project which uses the page object model and I've edited it to try and use parallel testing with Nunit. However when I run one single test it will launch a second unwanted browser. I think this is where I'm initiating my page at the beginning of the test.
The files I have are a Base class for the driver:
namespace ParallelTests
{
public class Base
{
public static IWebDriver Driver { get; set; }
}
}
A hooks file to setup the driver:
namespace ParallelTests
{
public class Hooks : Base
{
public Hooks()
{
Driver = new ChromeDriver(#"D:\Data\user\Documents\Visual Studio 2012\Projects\ParallelTests\ParallelTests\bin");
}
}
}
The page file:
namespace ParallelTests
{
class PageObject_LoggedIn : Hooks
{
public PageObject_LoggedIn()
{
PageFactory.InitElements(Driver, this);
}
[FindsBy(How = How.Id, Using = "lst-ib")]
public IWebElement SearchBox = null;
public void Search()
{
SearchBox.SendKeys("Deep Purple");
SearchBox.SendKeys(Keys.Enter);
}
}
}
And the test itself:
[TestFixture]
[Parallelizable]
public class ChromeTesting : Hooks
{
[Test]
public void ChromegGoogleTest()
{
PageObject_LoggedIn loggedIn = new PageObject_LoggedIn();
Driver.Navigate().GoToUrl("https://www.google.co.uk");
loggedIn.Search();
}
}
I think it's PageObject_LoggedIn loggedIn = new PageObject_LoggedIn(); in the test which is launching the second browser but I'm not sure how to rectify it.
This is an extension to an original issue, but is treated as a separate issue

Categories

Resources