I am attempting to set up a Page Factory Model Framework using Selenium in C#
I have got my tests running using Selenium but want to separate out my Tests from the Framework.
Several tests require me to wait for an element to be visible before I do anything with the element. In my other versions of my Selenium testing I would do something like
By selector = By.XPath("/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]");
new WebDriverWait(driver.Instance, TimeSpan.FromSeconds(5)).Until(ExpectedConditions.ElementIsVisible(selector));
However I cant get Element Is Visible to work so have used Wait Until Visible in my Extension Method (Code Below).
When I run my test even with the Wait Until Visible Selenium is not waiting for the Element to appear before continuing. When I Debug the test it is failing with a stackOverflow at the WaitUntilVisible step.
When I run the test normally I am getting the message does not show error, however it is showing (I can see it on the screen). I know from experience of running this test in my alternative frameworks that this is simply because the test is looking for the element before it has appeared.
I am already running an ImplicitWait as part of my Browser Factory Class.
Am I understanding and using my waits correctly in the Page Factory Model?
Test I am running
[Test]
public void Framework_Invalid_Location()
{
BrowserFactory.InitBrowser("Chrome");
BrowserFactory.LoadApplication("xxxxxxxxxxxxxx");
Page.HomePage.SearchForRestaurant("CFYUGHGYHYTDFD");
Assert.That(Page.HomePage.InvalidPostcode(), Is.EqualTo("Please enter a valid location or postcode"), "message does not show");
BrowserFactory.CloseAllDrivers();
}
HomePage Class
private IWebDriver driver;
[FindsBy(How = How.CssSelector, Using = "#js-postcode")]
[CacheLookup]
private IWebElement PostcodeInput { get; set; }
[FindsBy(How = How.XPath, Using = "/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]")]
[CacheLookup]
private IWebElement ErrorMessageInvalidEntry { get; set; }
public void SearchForRestaurant(string Postcode)
{
PostcodeInput.SendKeys(Postcode);
SearchButton.ClickOnIt("SearchButton");
public string InvalidPostcode()
{
ErrorMessageInvalidEntry.WaitUntilVisible(10);
return ErrorMessageInvalidEntry.Text;
}
Element Extension function I am calling for my Wait. Updated from comments and suggestions
public static void Wait(this IWebElement element, IWebDriver driver, float TimeOut) {
WebDriverWait Wait = new WebDriverWait(driver, TimeSpan.FromSeconds(TimeOut));
return Wait.Until(ExpectedConditions.ElementIsVisible(element));
There is still one error with this code for (element) Cannot convert from OpenQa.Selenium.IWebElement to open.Qa.Selenium.By
Really feel I am at the very edge of the little knowledge I have learnt over the past few months so thankyou for all help.
Page Class
namespace KukdFramework.PageObjects
{
public class Page
{
private static T GetPage<T>() where T : new()
public static HomePage HomePage
{
get { return GetPage<HomePage>(); }
}
Browser Factory Code
private static readonly IDictionary<string, IWebDriver> Drivers = new Dictionary<string, IWebDriver>();
private static IWebDriver driver;
public static IWebDriver Driver
{
get
{
if (driver == null)
throw new NullReferenceException("The WebDriver browser instance was not initialized. You should first call the method InitBrowser.");
return driver;
}
private set
{
driver = value;
}
}
public static void InitBrowser(string browserName)
{
switch (browserName)
{
case "Firefox":
if (driver == null)
{
driver = new FirefoxDriver();
Drivers.Add("Firefox", Driver);
BrowserSettings();
}
break;
case "IE":
if (driver == null)
{
driver = new InternetExplorerDriver();
Drivers.Add("IE", Driver);
BrowserSettings();
}
break;
case "Chrome":
if (driver == null)
{
driver = new ChromeDriver();
Drivers.Add("Chrome", Driver);
BrowserSettings();
}
break;
}
}