Reputation: 393
I have a web page in my web project “CalculatorWeb” where I placed a single text box with id “txtNum1”
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<form id="frmCalc">
<div style="padding-top:20px;">
My Sample Text Box <br/><br/>
<input id="txtNum1" type="text" />
</div>
</form>
</body>
</html>
Nothing fancy so the page loads up as below
Now I created a feature file “BrowserTest1.feature” to my project “Calculator.Specs”. The code as follows
Feature: BrowserTest1
In order to check url
As browser
I want to be see url of page
@mytag
Scenario: Go to URL
Given I have entered 'http://localhost:58529/'
When I go to that url
Then there is a text box on the page with id 'txtNum1'
I then code a file BrowserTest.cs for unit tests implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using TechTalk.SpecFlow;
namespace Calculator.Specs
{
[Binding]
class BrowserTest
{
public string urlPath;
[Given(@"I have entered 'http://localhost:58529/'")]
protected void SetURL()
{
string URLPath = "http://localhost:58529/";
urlPath = URLPath;
}
[When(@"I go to that url")]
protected void NavigateToURL()
{
using (var driver = new ChromeDriver())
{
driver.Navigate().GoToUrl(urlPath);
}
}
[Then(@"there is a text box on the page with id 'txtNum1'")]
protected void TxtBoxExists()
{
bool txtExists = false;
using (var driver = new ChromeDriver())
{
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1"));
if (txtBox1 != null)
{
txtExists = true;
}
}
Assert.AreEqual(true, txtExists);
}
}
}
As far as I am aware I do have all the required references for Visual Studio IDE to SpecFlow/Selenium integration
When I do run the unit test the web page loads up fine , however I get a failing test when I try to find the element with ID “txtNum1” even though the text box with that ID does exist on the page
Exception details appear as follows
Can anybody point me in the right direction as to what am I missing to enable Selenium to find the text box on the page with ID “txtNum1”
Upvotes: 3
Views: 6619
Reputation: 393
Found the answer after a bit of code examination. This issue was to do with multiple instances of ChromeDriver in the code. So the first instance was loading the page but when I was trying to find an item on the page I was using a new instance of the page instead of the one that was already used to load the page. So this second instance of the chrome driver with no page loaded was always returning exception with no item found as the there was no page loaded on this instance of chrome driver
Upvotes: 0
Reputation: 32946
you need to use the same instance of driver between steps, otherwise the driver that navigates to the page is different from the driver that you are trying to get the element from.
you have a couple of choices for this. The simplest is to create a field for your driver instance and use the field in all the steps. This will work as long as all your steps are in the same file.
The other option is to store the driver object in the ScenarioContext.Current
(or FeatureContext.Current
). These are dictionaries so you can do this:
ScenarioContext.Current["webDriver"] = driver;
This will work ok, but you'll have to cast everytime you get the driver out as the dictionary just takes objects, but you'll be able to share your driver instance between steps regardless of which file they are in.
The third (and IMHO best) option is to create a WebDriverContext
class and accept this in your step class constructor. Create your driver once in there (in its constructor) and then every step can use the WebDriverContext instance to access the shared driver.
An example of setting this up can be seen in the answer here
Upvotes: 2
Reputation: 6175
Your driver just needs to proceed a little slower
Add some delay before each driver.FindElement
, for instance with :
Thread.Sleep(2000);
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1"));
Or better yet :
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("txtNum1")));
IWebElement txtBox1 = driver.FindElement(By.Id("txtNum1"));
Upvotes: 1