FindsBy from SeleniumExtras can't find IWebElement - c#

I've updated packages from my project on Mac and find out that PageObjects has been moved to SeleniumExtras. I struggle to use it but the error "System.NullReferenceException : Object reference not set to an instance of an object." is shown.
Nevertheless, the same element can be found through FindElement. Currently, I run out of ideas and would appreciate the help.
Thanks!
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NUnit.Framework;
using NUnit.Compatibility;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumExtras.PageObjects;
namespace SomeTest
{
[TestFixture]
public class UnitTest1
{
[FindsBy(How = How.XPath, Using = "//*[#id='lst-ib']")]
public IWebElement _searchField;
public IWebDriver chrome;
[SetUp]
public void TestMethod1()
{
chrome = new ChromeDriver(#"/Volumes/Macintosh HD/QA/SomeTest/SomeTest/bin/Debug/netcoreapp2.1");
}
[Test]
public void SomeTest()
{
chrome.Navigate().GoToUrl("https://www.google.com/");
_searchField.SendKeys("Some Text");
}
[TearDown]
public void CloseBrowser()
{
chrome.Close();
}
}
}

Got solution:
Add all DotNetSeleniumExtras through NuGet Packages: PageObjects and PageObjects.Core;
Add namespaces:
using FindsByAttribute = SeleniumExtras.PageObjects.FindsByAttribute;
using How = SeleniumExtras.PageObjects.How;

Related

Not able to call method from class

I have a class named test.cs:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using qa.WrapperFactory;
namespace Common.PageObjects
{
public class Test
{
[FindsBy(How = How.XPath, Using = "xpath")]
private IWebElement foundElement;
[FindsBy(How = How.XPath, Using = "xpath")]
private IWebElement EnvironmentLogoElement;
[FindsBy(How = How.XPath, Using = "xpath")]
private IWebElement UsernameElement;
[FindsBy(How = How.Id, Using = "xpath")]
private IWebElement PasswordElement;
public void Setup()
{
// Set window to full screen
BrowserFactory.Driver.Manage().Window.Maximize();
// Clear all cookies
BrowserFactory.Driver.Manage().Cookies.DeleteAllCookies();
}
public void CheckLoginPage ()
{
WaitMethods.WaitForShort(() => foundElement.Displayed);
Assert.IsTrue(UsernameElement.Displayed);
Assert.IsTrue(PasswordElement.Displayed);
}
}
}
I want to call the method public void CheckLoginPage () from the specflow steps. that looks like this:
using System.Configuration;
using Common.PageObjects;
using qa.WrapperFactory;
using TechTalk.SpecFlow;
namespace RegressionTest
{
[Binding]
public class SmokeTestSteps
{
[Given(#"I go to the HRControlnet login page")]
public void GivenIGoToTheHRControlnetLoginPage()
{
BrowserFactory.InitBrowser("Firefox");
var subDomain = ConfigurationManager.AppSettings["Environment"];
BrowserFactory.LoadApplication(subDomain);
}
[Then(#"the result should be on the screen")]
public void ThenTheResultShouldBeOnTheScreen()
{
Test.CheckLoginPage();
}
}
}
I get now the error on the step ThenTheResultShouldBeOnTheScreen() with
Error CS0120 An object reference is required for the non-static field, method, or property.
I tried to make CheckLoginPage () a static but then all the xpaths give an error.
Anyone can help me out on how to fix this?
You just have to initialize the class and call the method something like below:
public void ThenTheResultShouldBeOnTheScreen()
{
new Test().CheckLoginPage();
}
public void ThenTheResultShouldBeOnTheScreen()
{
Test test = new Test() // initialize new instance of class
test.CheckLoginPage() // call method
}
If this doesn't work, you need to add reference

Test Executed successfully but report doesn't extent report doesn't generate in specflow

Currently I am working designing my project in Specflow. I want to implement some reporting to my project. Currently I have created one separate .cs file and kept all my report setting. But when i execute my code test run successfully but report doesn't generate. i am using the given code please check and suggest me
SeleniumDriver.cs
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ReportDemoPOC
{
class SeleniumDriver
{
public static IWebDriver WebDriver { get; set; }
public static string BaseAddress
{
get { return Constants.Url; }
}
public static void Intitialize()
{
WebDriver = new ChromeDriver();
WebDriver.Manage().Window.Maximize();
TurnOnWait();
}
public static void Navigate()
{
WebDriver.Navigate().GoToUrl(BaseAddress);
}
public static void Close()
{
WebDriver.Close();
}
public static void Quit()
{
WebDriver.Quit();
}
private static void TurnOnWait()
{
WebDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
WebDriver.Manage().Timeouts().PageLoad = TimeSpan.FromMinutes(2);
}
public void Shutdown()
{
WebDriver.Quit();
}
}
}
Start.cs
using AventStack.ExtentReports;
using AventStack.ExtentReports.Reporter;
using AventStack.ExtentReports.Reporter.Configuration;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TechTalk.SpecFlow;
namespace ReportDemoPOC
{
public class Start
{
public static ExtentReports extent;
public static ExtentHtmlReporter htmlReporter;
public static ExtentTest test;
static Start()
{
if (extent == null)
{
BasicSetUp();
}
}
[BeforeScenario]
public void Setup()
{
SeleniumDriver.Intitialize();
SeleniumDriver.Navigate();
test = extent.CreateTest(ScenarioContext.Current.ScenarioInfo.Title);
}
[AfterScenario]
public void TearDown()
{
if (ScenarioContext.Current.TestError != null)
{
var error = ScenarioContext.Current.TestError;
var errormessage = "<pre>" + error.Message + "</pre>";
//Add capture screen shot line here
extent.AddTestRunnerLogs(errormessage);
test.Log(Status.Error, errormessage);
test.Fail(errormessage);
}
SeleniumDriver.Close();
}
[OneTimeSetUp]
public static void BasicSetUp()
{
string pth = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
// string pth = System.IO.Directory.GetCurrentDirectory();
string actualPath = pth.Substring(0, pth.LastIndexOf("bin"));
string projectPath = new Uri(actualPath).LocalPath;
Console.WriteLine(" -----------Project Path--------------------------------------");
Console.WriteLine(projectPath);
// string reportPath = projectPath + "Reports\\" + FeatureContext.Current.FeatureInfo.Title + ".html";
string reportPath = projectPath + "Reports\\TestRunReport.html";
// Console.WriteLine("Report Path is " + reportPath);
htmlReporter = new ExtentHtmlReporter(reportPath);
htmlReporter.Configuration().Theme = Theme.Dark;
htmlReporter.Configuration().DocumentTitle = "SpecFlow Test Resport Document";
htmlReporter.Configuration().ReportName = "Feature Run Results";
extent = new ExtentReports();
extent.AttachReporter(htmlReporter);
//extent.LoadConfig(projectPath + "Extent-Config.xml");
}
[AfterFeature()]
public static void EndReport()
{
extent.Flush();
}
}
}
LoginSteps.cs
using NUnit.Framework;
using ReportDemoPOC.Page;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TechTalk.SpecFlow;
namespace ReportDemoPOC.Steps
{
[Binding]
[TestFixture]
class LoginSteps : Start
{
LoginPage loginPage;
[Given(#"I am at Facebook login page")]
public void GivenIAmAtFacebookLoginPage()
{
//Navigate();
loginPage = new LoginPage();
}
[When(#"I enter ashusoni(.*)#gmail\.com in the Email or Phone textbox")]
public void WhenIEnterAshusoniGmail_ComInTheEmailOrPhoneTextbox(String p0)
{
loginPage.enterValueInUser("abcd" + p0 + "#gmail.com");
}
[When(#"I Enter (.*) in the password")]
public void WhenIEnterInThePassword(String p0)
{
loginPage.enterValueInPassword(p0);
}
[When(#"Click on the Login button")]
public void WhenClickOnTheLoginButton()
{
loginPage.clickOnLoginButton();
}
[Then(#"Application should display an error message")]
public void ThenApplicationShouldDisplayAnErrorMessage()
{
Console.WriteLine("Verification");
// loginPage.Shutdown();
}
}
}
It may sound like off topic, but still...
I'm not sure it makes sense to use ExtentReports for you automation frameworkwritten in C#.
Starting from v.4 ExtentReports they don't support it anymore.
The reply from them was that they were going to support only Java.
This is a feature of NUnit 3. You should install the Visual Studio Test Adapter ( https://github.com/nunit/docs/wiki/Visual-Studio-Test-Adapter ) via NuGet package named "NUnit3TestAdapter" to get the OneTimeSetup to work.
Then you can check your implementation of the report :-)
Maybe your report is created in the temporary folder (after some time I found it, using windows search). I have the same when running my tests, using Visual Studio. Try to run your test, using Nunit console application. Download it separately, then run tests using console command
nunit "path to compiled .dll with tests"
In this case, I think you should found reports near .dll file. This happens in my case (using Allure reports).

Confusion over Page Object Model C# Selenium

I've written basic code which goes to a specific URL then changes the country and currency. I now want to tidy my code up and make it easier to maintain.
I've not used page object model before so have been reading about it. I understand the basic concepts of creating another class within the project and creating an extension to page objects that are used to initialize the web elements.
So essentially all my FindElements will be stored in a separate class. I've created two Classes within a PageObjects folder. HomePage and PreferencePage.
Below code is working and does exactly as I expect.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Interactions;
using System.Threading;
namespace Exercise1
{
class Program
{
static void Main(string[] args)
{
IWebDriver webDriver = new ChromeDriver();
webDriver.Navigate().GoToUrl("http://www.asos.com/men/");
webDriver.Manage().Window.Maximize();
webDriver.FindElement(By.XPath(".//button[#data-testid='country-selector-btn']")).Click();
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.Id("country")));
SelectElementFromDropDown(country, "India");
IWebElement currency = wait.Until(ExpectedConditions.ElementExists(By.Id("currency")));
SelectElementFromDropDown(currency, "$ USD");
webDriver.FindElement(By.XPath(".//button[#data-testid='save-country-button']")).Click();
webDriver.Quit();
}
private static void SelectElementFromDropDown(IWebElement ele, string text)
{
SelectElement select = new SelectElement(ele);
select.SelectByText(text);
}
}
}
Now I want to implement Page Object Model. I have created my main TestClass, along with a HomePage and PreferencePage class. I'm unsure of how to implement the next bit. I know my TestClass will be making a call to the HomePage for the URL and PreferencePage for the country and currency but I'm unsure how the implementation would look.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace Exercise1
{
class TestClass
{
private IWebDriver driver;
public void SetUp()
{
IWebDriver webDriver = new ChromeDriver();
webDriver.Manage().Window.Maximize();
}
public void ChangePreferences()
{
Homepage home = new Homepage(driver);
home.goToPage();
PreferencePage preference = home.GoToPreferencePage();
UpdateCountry = preference.UpdateCountryPreference();
UpdateCurrency = preference.UpdateCurrencyPreference();
UpdatePreference = preference.PreferenceUpdated();
}
}
}
HomePage class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Exercise1
{
class HomePage
{
private IWebDriver driver;
public HomePage(IWebDriver driver)
{
this.driver = driver;
PageFactory.InitElements(driver, this);
}
public void goToPage()
{
driver.Navigate().GoToUrl("http://www.asos.com/men/");
}
}
}
Preference page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Exercise1.PageObjects
{
class PreferencePage
{
private IWebDriver driver;
public UpdateCountry(string text)
{
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
IWebElement country = wait.Until(ExpectedConditions.ElementExists(By.Id("country")));
SelectElementFromDropDown(country, "India");
}
public void UpdateCurrency()
{
IWebElement currency = wait.Until(ExpectedConditions.ElementExists(By.Id("currency")));
SelectElementFromDropDown(currency, "$ USD");
}
public void ClickPreference()
{
webDriver.FindElement(By.XPath(".//button[#data-testid='save-country-button']")).Click();
}
}
}
it would look like that:
class TestClass
{
private IWebDriver driver;
public void SetUp()
{
..
}
public TestChangePreferences()
{
//actual test
ChangePreferences();
}
public void ChangePreferences()
{
.......
}
}
I'd wrap it with a testing framework such as NUnit for better test management and tools.
this could give you a pretty good example:
https://github.com/nunit/nunit-csharp-samples/blob/master/DataDrivenTests/GenericTestFixture.cs

invalid opcode error on invoking firefox driiver in selenium c#

I am running my selenium script on amazon work space, scripting language using is c#
when i run my script in visual studio i got a error popup with message "installer corrupted:invalid opcode" . my script run properly but each time Firefox driver instance triggered this popup also appear
Below is my code used
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.IE;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace Automation
{
[TestFixture]
public class Loginpage
{
private FirefoxDriver driver;
private string baseURL;
public Loginpage() { }
[SetUp]
public void LoadDriver()
{
Console.WriteLine("SetUp");
driver = new FirefoxDriver();
baseURL = "https://google.com";
}
[Test]
public void Login()
{
driver.Navigate().GoToUrl(baseURL);
}
[TearDown]
public void UnloadDriver()
{
Console.WriteLine("TearDown");
driver.Quit();
}
}
}
Can anyone please help me on this.
Thanks in Advance

BDD Specflow Object reference not set to an instance of an object in ObjectContainer.RegisterInstanceAs

I have rearranged my class files and Webdriver variable so I can use Context Injection to share the Webdriver variable between steps. Before I was using SetupFixture, Setup and TearDown which is not correct for BDD. Trying Context Injection now with BeforeAllTests, BeforeTestRun etc.
I am getting the error:
System.NullReferenceException: Object reference not set to an instance of an object
The line highlighted where the error is here:
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
}
My setup.cs implementation is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TechTalk.SpecFlow;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using OpenQA.Selenium.Firefox;
using SearchTest.Setup;
using BoDi;
using SearchTest.WebDriver;
namespace SearchTest.Setup
{
[Binding]
public class BeforeAllTests
{
private readonly IObjectContainer objectContainer;
private static SeleniumContext seleniumContext;
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = objectContainer;
}
[BeforeTestRun]
public static void RunBeforeAllTests()
{
seleniumContext = new SeleniumContext();
}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SeleniumContext>(seleniumContext);
}
}
}
My HomePage class HomePage.cs implementation is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using OpenQA.Selenium.Firefox;
using NUnit.Framework;
using SearchTest.Setup;
using SearchTest.WebDriver;
using TechTalk.SpecFlow;
using BoDi;
namespace SearchTest.PageObjects
{
[Binding]
public class HomePage : PageObjectBase
{
private SeleniumContext seleniumContext;
//private IWebDriver driver{ get; set; }
[FindsBy(How = How.XPath, Using = ".//TITLE")]
public IWebElement Title{ get; set; }
// search text field on the homepage
//[FindsBy(How= How.Id, Using="twotabsearchtextbox")]
//private IWebElement Searchfield_ID { get; set; }
[FindsBy(How = How.XPath, Using = ".//*[#id='twotabsearchtextbox']")]
private IWebElement Searchfield_XPATH { get; set; }
[FindsBy(How = How.Id, Using = "nav-search-submit-text")]
private IWebElement SearchButton { get; set; }
[FindsBy(How = How.XPath, Using = ".//*[#id='nav-search']/form/div[2]/div/input")]
private IWebElement searchButton_Xpath {get; set;}
// public HomePage(IWebDriver driver)
public HomePage(SeleniumContext seleniumContext)
/*This is to reference the PageObjectBase Class. Passing in the Title of the
* page that is expected for the HomePage to ensure the correct Page is loaded
* before starting any tests.
*/
//: base("Amazon.co.uk: Low Prices in Electronics, Books, Sports Equipment & more")
: base(seleniumContext)
{
//driver = new FirefoxDriver();
//Console.Out.WriteLine("from Homepage Constructor Driver.title in SearchResultsPage class = " + driver.Title);
//driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
//PageFactory.InitElements(driver, this);
this.seleniumContext = seleniumContext;
PageFactory.InitElements(seleniumContext.driver, this);
}
public void goToURL() {
//driver.Navigate().GoToUrl("http://www.amazon.co.uk");
}
public void EnterSearchText(String text)
{
Searchfield_XPATH.SendKeys(text);
}
public SearchResultsPage click_search_button() {
searchButton_Xpath.Click();
return new SearchResultsPage(seleniumContext);
}
}
}
Steps class SearchSteps.cs implementation is:
using System;
using TechTalk.SpecFlow;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using NUnit.Framework;
using SearchTest.PageObjects;
using SearchTest.WebDriver;
namespace SearchTest
{
[Binding]
public class SearchSteps
{
private SeleniumContext seleniumContext;
private IWebDriver driver { get; set; }
PageObjects.HomePage home_page { get; set; }
private SearchResultsPage search_results_page;
[Given(#"I navigate to the page ""(.*)""")]
public void GivenINavigateToThePage(string p0)
home_page = new PageObjects.HomePage(seleniumContext);
//home_page.goToURL();
}
[Given(#"I see the page is loaded")]
public void GivenISeeThePageIsLoaded()
{
//Assert.AreEqual("http://localhost:8080: PS4 products", driver.Title);
}
[When(#"I enter Search Keyword in the Search Text box")]
public void WhenIEnterSearchKeywordInTheSearchTextBox(Table table)
{
//string search_text = table.Rows[0]["Keyword"].ToString();
//driver.FindElement(By.Id("twotabsearchtextbox")).SendKeys(search_text);
//SearchResultsPage SearchResultsPage = home_page.EnterSearchText("F1");
home_page.EnterSearchText("F1");
}
[When(#"I click on Search Button")]
public void WhenIClickOnSearchButton()
{
//driver.FindElement(By.Name("BtnG")).Click();
search_results_page = home_page.click_search_button();
}
[Then(#"Search items shows the items related to PS4")]
public void ThenSearchItemsShowsTheItemsRelatedToPS4()
{
//Assert.AreEqual("PS4", driver.FindElement(By.XPath(".//*[#id='desktop-auto-sparkle-multi']/div/a")).Text);
//Assert.AreEqual("PS4", driver.FindElement(By.XPath("//h2[contains(text(), "PS4")]")));
search_results_page.get_search_result_title();
}
}
}
How do I resolve this please?
I think it is complaining that objectContainer.RegisterInstanceAs does not have any value, it is Null. It has not been instantiated?
Thanks, Riaz
your problem is that you have a typo in your constructor. This:
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = objectContainer;
}
should be
public BeforeAllTests(IObjectContainer container)
{
this.objectContainer = container;
}
you are not using the container instance given in the constructor, you are simply setting the objectContainer to itself.

Categories