I am trying to set up a visual studio project with acceptance tests using NUnit and Selenium Web Driver, I would like to be able to "run tests" and this to start my web site, use selenium to run the tests and quit.
I have this basic setup so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.PhantomJS;
namespace FrontEndTests.AcceptanceTests
{
[TestFixture]
class Phantom
{
private PhantomJSDriver _driver;
[SetUp]
public void WhenOpeningANewWebPage()
{
_driver = new PhantomJSDriver();
_driver.Navigate().GoToUrl(#"localhost");
}
[Test]
public void ThenICanFindAClass()
{
Assert.NotNull(_driver.FindElement(By.ClassName("featured")));
}
[TearDown]
public void Finally()
{
_driver.Quit();
}
}
}
If I set the URL to 'www.google.com' the tests pass fine (with the correct class set) but localhost returns elementnotfoundexception in selenium.
How do I get it to work locally?
Thanks
Based on this:
"When I run the project in visual studio it points to localhost:31106 I have tried to using this as the URL but this gives the same error - Gregg_1987"
IIS must be running your application. When you click run it starts the application in IIS express for the time that the application is running. Visual Studio then attaches to this for execution purposes.
If you are trying to execute Selenium on this you would have to install regular IIS and register the application through IIS so that it will be accessible. Then your tests can hit this through the URL registered in IIS. Otherwise you would have to try to programmatically execute the app using IIS express which there is some guidance on here: Automatically start ASP.MVC project when running test project
Once the site is accessible through IIS you can then hit it with your Selenium tests.
Well, you need to start you site before all tests or you can start it once in SetUp and kill it in TearDown (or if you are going to run your tests on some CI then run once before all tests and kill after all). To start it you can choose either webdev or iisexpress (on your choice), below sample of using WebDev.WebHost.dll
public class Phantom
{
private PhantomJSDriver _driver;
//Move this field to base class if you need to start site before each test
//e.g. you can move setup and teardown to base class, it's all up to you
public DevServer WebDevServer { get; private set; }
[SetUp]
public void WhenOpeningANewWebPage()
{
WebDevServer = new DevServer();
WebDevServer.Start();
_driver = new PhantomJSDriver();
_driver.Navigate().GoToUrl(#"localhost");
}
[Test]
public void ThenICanFindAClass()
{
Assert.NotNull(_driver.FindElement(By.ClassName("featured")));
}
[TearDown]
public void Finally()
{
_driver.Quit();
WebDevServer.Stop();
}
}
public class DevServer
{
private Server _webServer;
public DirectoryInfo SourcePath { get; set; }
public string VirtualPath { get; set; }
public int Port { get; set; }
public DevServer()
{
//Port
Port = Settings.WebDevPort;
//Path to your site folde
SourcePath = Settings.WebDevSourcePath;
//Virt path can be ~
VirtualPath = Settings.WebDevVirtualPath;
}
public void Start()
{
Stop();
try
{
_webServer = new Server(Port, VirtualPath, SourcePath.FullName);
_webServer.Start();
}
catch (Exception e)
{
Trace.TraceError("Process cannot be started." + Environment.NewLine + e);
throw;
}
}
public void Stop()
{
if (_webServer != null)
{
_webServer.Stop();
_webServer = null;
}
}
}
Related
I am new to C#, i am not able to make driver thread safe. I am able to open the two browser as soon as second browser opens, first driver lose its references.
below is my code i have three class
namespace TestAutomation{
[TestFixture]
[Parallelizable(ParallelScope.Children)]
public class UnitTest1 : Setup
{
[Test, Property("TestCaseID","123")]
public void TestMethod1(this IWebDriver driver1)
{
driver1.Navigate().GoToUrl("https://www.google.com");
driver1.FindElement(By.Name("q")).SendKeys("test1");
Thread.Sleep(10000);
}
[Test, Property("TestCaseID", "234")]
public void TestMethod2()
{
driver.Navigate().GoToUrl("https://www.google.com");
driver.FindElement(By.Name("q")).SendKeys("test2");
Thread.Sleep(15000);
}
}}
Setup Class
namespace TestAutomation{
public class Setup:WebDriverManager
{
[SetUp]
public void setupBrowser()
{
driver = new ChromeDriver("C:\\Users\\Downloads\\chromedriver_win32");
}
[TearDown]
public void CloseBrowser()
{
driver.Close();
driver.Quit();
// driver.Close();
//driver.Quit;
}
}}
Webdrivermanager
namespace TestAutomation{
public class WebDriverManager
{
public IWebDriver driver { get; set; }
}
}
i am looking for a solution like ThreadLocal injava where i can get and set the driver for each thread in the setup method
Remove the SetUp & TearDown Attributes for the methods and call them explicitly. When you use these method attributes, it starts sharing resources across tests in the same class or inherited classes.
The below solution works perfectly fine. I have developed a project in which you can execute browser tests in parallel (method level parallelization). You can modify the project as per your needs.
Project Link: www.github.com/atmakur
[TestFixture]
class Tests
{
[Test]
public void Test1
{
using(var testInst = new TestCase())
{
testInst
.Init()
.NavigateToHomePage();
}
}
}
public class TestBase:IDisposable
{
private IWebDriver BaseWebDriver;
private TestContext _testContext;
public NavigatePage Init()
{
_testContext = TestContext.CurrentTestContext;
BaseWebDriver = new ChromeDriver();
.
.
.
}
public override void Dispose()
{
//Kill Driver here
//TestContext instance will have the AssertCounts
//But The Testcontext instance will have the result as Inconclusive.
}
}
You are doing two contradictory things:
Using a new browser for each test.
Sharing the browser property between the tests.
You should do one or the other. If you want to create a new browser for each test, don't store a reference to it where the other test also accesses it.
Alternatively, use OneTimeSetUp and OneTimeTearDown and only create the browser once. However, in that case, you can't run the tests in parallel.
I have been spending the last 3 Months teaching myself Automated Testing. Having had no previous experience (manual tester who had never coded in my life) I have (with the help of this Board) managed to create a selenium Object Based Framework, written tests that link to this framework and got all my tests to run.
However I now need to take my test suite and pass it through multiple environments on a cloud based service. The problem I have is that I have to define the environment each time I run the test set. Ideally I want to be able to define the environments I run my tests on (Firefox, Chrome, IE etc), and then set the test suite off to run my set of 17 tests 3 times across each browser.
I Don't want to set up a system to run this locally but instead have a method that calls my different methods for my Cloud Service (currently trialling a couple)
a Sample of my code is as follows
Test Code - Login
namespace Kukd_Consumer_Test
{
[TestFixture]
public class Login : Consumer_Standard_Functionality
{
[Test]
public void User_Can_Login()
{
LoginPage.LoginAs("xxxxxxxxxx").WithPassword("xxxxxxx").Login();
Assert.IsTrue(AccountPageBtns.IsAtAccountPage("Hi Richard"), "Failed to login");
AccountPageBtns.Logout();
}
}
}
My standard Functionality (call driver go to homepage, quit etc) Currently I have to comment all but one of my Driver Methods. I want to be able to define multiples here Ideally so I can define which environments I run my tests on (locally or cloud based)
public class Consumer_Standard_Functionality
{
[SetUp]
public void Init()
{
// currently have to comment out all but the one I want to run.
driver.InitializeChrome();
//driver.InitializeFireFox();
//CBT_Driver.InitialiseChromeCBT(testName);
//CBT_Driver.InitialiseFFCBT(testName);
//CBT_Driver.InitialiseIECBT(testName);
//driver.InitialiseBrowserStack();
Homepage.GoTo_HomePage();
}
[TearDown]
public void Cleanup()
{
driver.Quit();
}
My local Driver Class (plus browserstack)
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using System;
namespace Kukd_Consumer_Tests
{
public class driver
{
public static IWebDriver Instance { get; set; }
public static void InitializeChrome()
{
Instance = new ChromeDriver(#"C:\Users\richard.cariven\Documents\Visual Studio 2015\Drivers\Chrome");
Instance.Manage().Window.Position = new System.Drawing.Point(2192, -963);
Instance.Manage().Window.Maximize();
Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
}
public static void InitializeFireFox()
{
Instance = new FirefoxDriver();
Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
}
public static string BSusername = "xxxxxxxxxxx";
public static string BSpassword = "xxxxxxxxxxx";
public static void InitialiseBrowserstack()
{
IWebDriver driver;
DesiredCapabilities caps = new DesiredCapabilities();
//caps.SetCapability("name", TestContext.TestName);
caps.SetCapability("browser", "IE");
caps.SetCapability("browser_version", "11.0");
caps.SetCapability("os", "Windows");
caps.SetCapability("os_version", "10");
caps.SetCapability("resolution", "1024x768");
caps.SetCapability("browserstack.user", BSusername);
caps.SetCapability("browserstack.key", BSpassword);
driver = new RemoteWebDriver
(new Uri("http://hub-cloud.browserstack.com/wd/hub/"), caps);
Instance = driver;
}
public static void refresh()
{
Instance.Navigate().Refresh();
}
public static void Quit()
{
Instance.Quit();
}
}
}
CBT Class - Set up to pick each Cross Browser testing Parameter
namespace Kukd_Consumer_Tests
{
public class CBT_driver
{
public static IWebDriver Instance { get; set; }
public static string CBTusername = "xxxxxxxx";
public static string CBTpassword = "xxxxxxxxxx";
public static void InitialiseChromeCBT(string testName)
{
IWebDriver driver;
var caps = new DesiredCapabilities();
caps.SetCapability("name", testName);
caps.SetCapability("build", "1.0");
caps.SetCapability("browser_api_name", "Chrome56x64");
caps.SetCapability("os_api_name", "Win8");
caps.SetCapability("screen_resolution", "1366x768");
caps.SetCapability("record_video", "true");
caps.SetCapability("record_network", "true");
caps.SetCapability("username", CBTusername);
caps.SetCapability("password", CBTpassword);
driver = new RemoteWebDriver
(new Uri("http://hub.crossbrowsertesting.com:80/wd/hub"), caps);
Instance = driver;
}
public static void InitialiseFFCBT()
{
IWebDriver driver;
var caps = new DesiredCapabilities();
caps.SetCapability("name", "test name");
caps.SetCapability("build", "1.0");
caps.SetCapability("browser_api_name", "FF46x64");
caps.SetCapability("os_api_name", "Win8");
caps.SetCapability("screen_resolution", "1366x768");
caps.SetCapability("record_video", "true");
caps.SetCapability("record_network", "true");
caps.SetCapability("username", CBTusername);
caps.SetCapability("password", CBTpassword);
driver = new RemoteWebDriver
(new Uri("http://hub.crossbrowsertesting.com:80/wd/hub"), caps);
Instance = driver;
}
public static void InitialiseIECBT(string testName)
{
IWebDriver driver;
var caps = new DesiredCapabilities();
caps.SetCapability("name", testName);
caps.SetCapability("build", "1.0");
caps.SetCapability("browser_api_name", "IE10");
caps.SetCapability("os_api_name", "Win8");
caps.SetCapability("screen_resolution", "1366x768");
caps.SetCapability("record_video", "true");
caps.SetCapability("record_network", "true");
caps.SetCapability("username", CBTusername);
caps.SetCapability("password", CBTpassword);
driver = new RemoteWebDriver
(new Uri("http://hub.crossbrowsertesting.com:80/wd/hub"), caps);
Instance = driver;
}
}
}
So what I need to be able to do is, in my common test so it applies to every test, loop through each of my Browsers/CBT Environments for all tests.
Am currently set up using NUnit (changed from MSTest because I have read it is easier to do this kind of thing in NUnit)
Any advice greatly appreciated, I have been advised that because I have used so many statics in my tests this may not be possible.
Regards
Richard
After a lot of searching and investigation I have decided to scrap my current framework and rewrite it using Xunit and a Factory Model. Once I have got this structure completed it should be easier to maintain and less brittle in future :)
I'm new to Selenium Testing and trying to learn it.
When running the test, I have an error OpenQA.Selenium.WebDriverException:
Failed to start up socket within 45000 milliseconds`
This is my sample code:
[TestClass]
public class MyTest
{
IWebDriver driver;
[TestMethod]
public void VerifyTitle()
{
//Write Actual Test
string title = driver.Title;
Assert.AreEqual(title, "Done The deal");
}
[TestInitialize]
public void Setup()
{
//start browser and oprn url
driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://Donethedeal.com/");
}
[TestCleanup]
public void CleanupTest()
{
//close browser
driver.Quit();
}
}
I installed, I think, all necessary libraries using NuGet Package Manager
I have installed Selenium.WebDriver -Version 2.53.1 instead of 3.0.0 beta, since only with this version I was able to start Firefox browser. However, I could not open the url and got the described error while doing so
What am I missing?
at first your mistake is in the IWebDriver object declaration. You are declaring the object locally in the SetUp() method. If you do that the range of the object is inside the method only. Outside of the method the object is null. So move the declaration outside of all methods (preferably on the top, such as bellow)
The next mistake is the Attributes that you are using. I have to mention here that I used the NUnit3TestAdapter and NUnit from Nuget. I didnt find nowhere your attributes so I add mine :) In the SetUp method I used the [SetUp] attribute in the CleanUp[TearDown] and in VerifyTitle [Test]. Take a look in the code bellow for more details
IWebDriver driver = new FirefoxDriver();
static void Main(string[] args)
{
}
[Test]
public void VerifyTitle()
{
//Write Actual Test
string title = driver.Title;
// Assert.AreEqual(title, "DoneThedeal");
////I wanted to keep it simple change it back if u wish
if (title.Contains("DoneTheDeal"))
{
Console.WriteLine(title);
}
else
{
Console.WriteLine("Title not found");
}
}
[SetUp]
public void Setup()
{
//start browser and oprn url
driver.Navigate().GoToUrl("http://Donethedeal.com/");
}
[TearDown]
public void CleanupTest()
{
//close browser
driver.Quit();
}
}
**If you want to see the console results look for "Output" in the Text Explorer
I am automating my github profile and Following are my test cases:
Load Browser (this is defined in testInitialize()
Load Url
Perform Login
Below is the code snippet:
namespace GitAutomationTest
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Remote;
using System;
[TestClass]
public class GitTest
{
private string baseURL = "https://github.com/login";
private RemoteWebDriver driver;
public TestContext TestContext { get; set; }
[TestMethod]
public void LoadURL() {
driver.Navigate().GoToUrl(baseURL);
Console.Write("Loaded URL is :" + baseURL);
}
[TestMethod]
public void PerformLogin() {
driver.FindElementById("login_field").SendKeys("USERNAME");
driver.FindElementById("password").SendKeys("PASSWORD");
Console.Write("password entered \n ");
driver.FindElementByClassName("btn-primary").Click();
driver.GetScreenshot().SaveAsFile(#"screenshot.jpg", format: System.Drawing.Imaging.ImageFormat.Jpeg);
Console.Write("Screenshot Saved: screenshiot.jpg");
}
[TestCleanup()]
public void MyTestCleanup()
{
driver.Quit();
}
[TestInitialize()]
public void MyTestInitialize()
{
driver = new InternetExplorerDriver();
driver.Manage().Window.Maximize();
Console.Write("Maximises The window\n");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
}
}
}
OUTPUT
Everytime I run all tests:
- Test is initialized : the internet explorer is loaded
- The base url is loaded
- Then the driver quits with TestCleanUP()
Next time the driver runs testperformLogin()
- The test cannot find the username and password elements to perform login, because the base url is not loaded this time.
How can we manage the TestInitialize() class such that:
- browser is up with baseurl until all the tests are completed.
How can we manage TestCleanup() such that:
- browser closes only after all the test are completed.
There is a AssemblyCleanup attribute which runs after all the tests are executed.
You can find more info on attributes here - Unit Testing Framework.
You need to move following code to "PerformLogin" test method
driver.Navigate().GoToUrl(baseURL);
OR another approach is to add following code at in "Mytestinitialize" method and remove "LoadURL" method
driver.Navigate().GoToUrl(baseURL);
You are facing the issue since [TestInitialize] is called before every [TestMethod] and [TestCleanup] is called after every [TestMethod].
In your case "LoadURL" test is able to get the URL but "PerformLogin" is not able to get the URL since it is not mentioned in "MyTestInitialize".
I created new unit test project and and trying to test some links with selenium webdriver, but I am getting this error. When I change output type to console or windows, I get 'Program does not contain a static 'Main' method suitable for an entry point'. Please help me fix this
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using System.Collections.Generic;
using OpenQA.Selenium.Support.PageObjects;
namespace billingtest
{
[TestClass]
public class test
{
FirefoxDriver driver;
[TestInitialize()]
public void SyncDriver()
{
driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
}
[TestMethod]
public void LoginToBilling()
{
driver.Navigate().GoToUrl("http://localhost:57862");
driver.FindElement(By.Id("UserNameOrEmail")).SendKeys("aa");
driver.FindElement(By.Id("Password")).SendKeys("aa");
driver.FindElement(By.XPath(".//*[#id='main']/form/div[3]/input")).Click();
driver.FindElement(By.XPath(".//*[#id='content-main']/div/div/a[3]")).Click();
}
[FindsBy(How = How.TagName, Using = "a")]
public static IList<IWebElement> LinkElements { get; set; }
public void LoopLink()
{
int count = LinkElements.Count;
for (int i = 0; i < count; i++)
{
driver.FindElements(By.TagName("a"))[i].Click();
}
}
[TestCleanup]
public void TearDown()
{
driver.Quit();
}
}
}
To run a unit test, put your cursor on the test method and click on the "Run Tests in Current Context" button (also in the 'Test' menu in VS).
See also https://msdn.microsoft.com/en-us/library/ms182524(v=vs.90).aspx.
You should also add some validation to your test method, so that VS can report whether it passed or failed. Add something like:
Assert.IsTrue(outcome);
where outcome is a boolean that indicates the success of your test method.