In the last post we discussed writing a simple code for BDD with Selenium and Specflow, but in this part we will start to leverage the power of Page Object Model in Selenium, again Page Object Model is already discussed many of our post, you can find POM with C# as well
Here are some of the links
Since we have already discussed a lot about POM, I am not going to touch anything regarding POM, hence we will directly jump into the feature file we got and will start working from there.
Here is the complete video for the above discussion
Here is the code for the above discussion
Login Page Object
class LoginPage : BasePage
{
public LoginPage()
{
PageFactory.InitElements(Browser.Current, this);
}
[FindsBy(How = How.Name, Using = "UserName")]
public IWebElement txtUserName;
[FindsBy(How = How.Name, Using = "Password")]
public IWebElement txtPassword;
[FindsBy(How = How.Name, Using = "Login")]
public IWebElement btnLogin;
}
Step Definition file
[Binding]
class LoginSteps
{
IWebDriver currentDriver = null;
LoginPage page = new LoginPage();
[Given(@"I have navigated to my application")]
public void GivenIHaveNavigatedToMyApplication()
{
Browser.Current.Navigate().GoToUrl(ConfigurationManager.AppSettings["seleniumBaseUrl"]);
currentDriver = Browser.Current;
}
[Given(@"I typed the admin and admin")]
public void GivenITypedTheAdminAndAdmin(string userName, string password)
{
page.Login(userName, password);
}
[When(@"I click login button")]
public void WhenIClickLoginButton()
{
PropertiesCollection.currentPage = page.ClickLogin();
}
[Then(@"I should see the EA page")]
public void ThenIShouldSeeTheEAPage()
{
((EAPage)PropertiesCollection.currentPage).IsLoggedIn();
}
}
Thanks for watching the video and reading the post !!!
Please leave your comments and let me know if there is anything need to be improved in this post.
Thanks,
Karthik KK
Post Author:
Karthik kk
11 Replies to “Writing BDD Code using Selenium POM and Specflow”
When i run your code i am getting error as below please help me
Warning CS0649 Field ‘Loginpage.txtUserName’ is never assigned to, and will always have its default value null UnitTestProject1 C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Pages\Loginpage.cs 21 Active
Test Name: VerifyLoginFunctionIsWorking(“asdf”,”dffd”,null)
Test FullName: UnitTestProject1.Feature.LoginFeature.VerifyLoginFunctionIsWorking(“asdf”,”dffd”,null)
Test Source: C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Feature\login.feature : line 6
Test Outcome: Failed
Test Duration: 0:00:00.355
Result StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at BoDi.ObjectContainer.CreateObject(Type type, IEnumerable`1 resolutionPath, RegistrationKey keyToResolve)
at BoDi.ObjectContainer.TypeRegistration.Resolve(ObjectContainer container, RegistrationKey keyToResolve, IEnumerable`1 resolutionPath)
at BoDi.ObjectContainer.CreateObjectFor(RegistrationKey keyToResolve, IEnumerable`1 resolutionPath)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, IEnumerable`1 resolutionPath, String name)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, String name)
at lambda_method(Closure , IContextManager )
at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(StepInstance stepInstance)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()
at UnitTestProject1.Feature.LoginFeature.ScenarioCleanup() in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Feature\login.feature.cs:line 0
at UnitTestProject1.Feature.LoginFeature.VerifyLoginFunctionIsWorking(String username, String password, String[] exampleTags) in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Feature\login.feature:line 10
–KeyNotFoundException
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Baseclass.Contrib.SpecFlow.Selenium.NUnit.Bindings.Browser.get_Current()
at UnitTestProject1.Pages.Loginpage..ctor() in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Pages\Loginpage.cs:line 17
at UnitTestProject1.Steps.loginpos..ctor() in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Steps\loginpos.cs:line 21
Result Message:
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
—-> System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
I encounter the same result i have check the @ Browser tag but it not working somehow
Test Name: VerifyIfTheLoginFunctionalityIsWorking(“karthik”,”karthik”,System.String[])
Test FullName: specflow.Feature.LoginFeature.VerifyIfTheLoginFunctionalityIsWorking(“karthik”,”karthik”,System.String[])
Test Source: C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Feature\SpecFlowFeature1.feature : line 7
Test Outcome: Failed
Test Duration: 0:00:00.221
Result StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at BoDi.ObjectContainer.CreateObject(Type type, ResolutionList resolutionPath, RegistrationKey keyToResolve)
at BoDi.ObjectContainer.TypeRegistration.Resolve(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, String name)
at TechTalk.SpecFlow.Infrastructure.BindingInstanceResolver.ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer)
at lambda_method(Closure , IContextManager )
at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(StepInstance stepInstance)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()
at specflow.Feature.LoginFeature.ScenarioCleanup()
at specflow.Feature.LoginFeature.VerifyIfTheLoginFunctionalityIsWorking(String username, String password, String[] exampleTags) in C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Feature\SpecFlowFeature1.feature:line 10
–KeyNotFoundException
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Baseclass.Contrib.SpecFlow.Selenium.NUnit.Bindings.Browser.get_Current()
at specflow.Pages.LoginPages..ctor() in C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Pages\LoginPages.cs:line 16
at specflow.LoginSteps..ctor() in C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Step definition\LoginSteps.cs:line 14
Result Message:
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
—-> System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
Hi Karthik
I am getting below warning in console even its working fine.
“Warning field is never assigned to, and will always have its default value null”
[FindsBy(How = How.XPath, Using = “”)]
private IWebElement SequentialStudyPlanHeader;
Constructor
public SequentialStudyPlan()
{
this.driver = WebDriver;
PageFactory.InitElements(this, new RetryingElementLocator(driver, TimeSpan.FromSeconds(timeOut)));
}
I have to use these constructor only due to limitation in framework
When i run your code i am getting error as below please help me
Warning CS0649 Field ‘Loginpage.txtUserName’ is never assigned to, and will always have its default value null UnitTestProject1 C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Pages\Loginpage.cs 21 Active
Test Name: VerifyLoginFunctionIsWorking(“asdf”,”dffd”,null)
Test FullName: UnitTestProject1.Feature.LoginFeature.VerifyLoginFunctionIsWorking(“asdf”,”dffd”,null)
Test Source: C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Feature\login.feature : line 6
Test Outcome: Failed
Test Duration: 0:00:00.355
Result StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at BoDi.ObjectContainer.CreateObject(Type type, IEnumerable`1 resolutionPath, RegistrationKey keyToResolve)
at BoDi.ObjectContainer.TypeRegistration.Resolve(ObjectContainer container, RegistrationKey keyToResolve, IEnumerable`1 resolutionPath)
at BoDi.ObjectContainer.CreateObjectFor(RegistrationKey keyToResolve, IEnumerable`1 resolutionPath)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, IEnumerable`1 resolutionPath, String name)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, String name)
at lambda_method(Closure , IContextManager )
at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(StepInstance stepInstance)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()
at UnitTestProject1.Feature.LoginFeature.ScenarioCleanup() in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Feature\login.feature.cs:line 0
at UnitTestProject1.Feature.LoginFeature.VerifyLoginFunctionIsWorking(String username, String password, String[] exampleTags) in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Feature\login.feature:line 10
–KeyNotFoundException
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Baseclass.Contrib.SpecFlow.Selenium.NUnit.Bindings.Browser.get_Current()
at UnitTestProject1.Pages.Loginpage..ctor() in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Pages\Loginpage.cs:line 17
at UnitTestProject1.Steps.loginpos..ctor() in C:\Users\pc1\documents\visual studio 2015\Projects\UnitTestProject1\UnitTestProject1\Steps\loginpos.cs:line 21
Result Message:
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
—-> System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
Seems like there is a problem with @Browser tag you have used (if you did), else it should be a problem with page initialization. Please check
I encounter the same result i have check the @ Browser tag but it not working somehow
Test Name: VerifyIfTheLoginFunctionalityIsWorking(“karthik”,”karthik”,System.String[])
Test FullName: specflow.Feature.LoginFeature.VerifyIfTheLoginFunctionalityIsWorking(“karthik”,”karthik”,System.String[])
Test Source: C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Feature\SpecFlowFeature1.feature : line 7
Test Outcome: Failed
Test Duration: 0:00:00.221
Result StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at BoDi.ObjectContainer.CreateObject(Type type, ResolutionList resolutionPath, RegistrationKey keyToResolve)
at BoDi.ObjectContainer.TypeRegistration.Resolve(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, String name)
at TechTalk.SpecFlow.Infrastructure.BindingInstanceResolver.ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer)
at lambda_method(Closure , IContextManager )
at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(StepInstance stepInstance)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()
at specflow.Feature.LoginFeature.ScenarioCleanup()
at specflow.Feature.LoginFeature.VerifyIfTheLoginFunctionalityIsWorking(String username, String password, String[] exampleTags) in C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Feature\SpecFlowFeature1.feature:line 10
–KeyNotFoundException
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Baseclass.Contrib.SpecFlow.Selenium.NUnit.Bindings.Browser.get_Current()
at specflow.Pages.LoginPages..ctor() in C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Pages\LoginPages.cs:line 16
at specflow.LoginSteps..ctor() in C:\Users\suteera\documents\visual studio 2015\Projects\specflow\specflow\Step definition\LoginSteps.cs:line 14
Result Message:
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
—-> System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
Yes, since Specflow 2.0, the latest version wont support the @Browser tag anymore.
How do we now handle the @Browser tag? Please help. Thanks in advance
Its gone !
The developer is not supporting the latest version, you can write custom code as we did in this course https://www.udemy.com/framework-development-with-selenium-csharp-advanced
Thanks,
This does not work
Hi Karthik
I am getting below warning in console even its working fine.
“Warning field is never assigned to, and will always have its default value null”
[FindsBy(How = How.XPath, Using = “”)]
private IWebElement SequentialStudyPlanHeader;
Constructor
public SequentialStudyPlan()
{
this.driver = WebDriver;
PageFactory.InitElements(this, new RetryingElementLocator(driver, TimeSpan.FromSeconds(timeOut)));
}
I have to use these constructor only due to limitation in framework
Hi Karthik,
For CreateDynamicInstance(), I am getting -Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : The best overloaded method
FeatureFile –
When I want to edit the profile
| Hats | Shoes |
| 98 | 99 |
Page class-
public IWebElement TxtHat => _driver.FindElement(By.Id(“Hat”));
public IWebElement TxtShoe => _driver.FindElement(By.Id(“Shoe”));
public void FillDetails (string hat, string shoe)
{
TxtHat.SendKeys(hat);
TxtShoe.SendKeys(shoe);
}
StepDefinition –
[When(@”I want to edit the profile”)]
public void WhenIWantToEditTheProfile(Table table)
{
profile.ClearDetails();
dynamic var = table.CreateDynamicInstance();
profile.FillDetails(var.Hats, var.Shoes);
}
Could you please help me resolve this issue?
Regards,
Adiit
First of all, try not using var as the variable name, since its C# reserved keyword. Try changing it and it should be okay I guess.
Thank,
Instead of passing test data from Example: can I pass them through a class file (*.cs) in feature file?