1

I have been teaching myself Selenium over the past few weeks and have started writing my own tests, I can get all my happy flow tests to work fine but my first attempt at writing a test to check an error message is not working.

As an overview the test is really simple:

  1. Enter an invalid postcode into a search box
  2. click search
  3. Assert the screen shows an error message below the search box.

I know the logic of my code works as when I run the positive flow (enter postcode, click search, new page opens) the automated test is working fine. Also when I run the test in debug mode and step through the failed Assert the test passes with the error message picked up.

My Test code

[TestClass]
public class invalidSearch
{
    [TestInitialize]
    public void Init()
    {
        driver.Initialize();
    }

    [TestMethod]
    public void Invalid_Location_Returns_Error()
    {
        Homepage.GoTO_HomePage();
        SearchPage.enterSearch("CFYUGHGYHYTDFD").Search();
        Assert.IsTrue(SearchErrorMessage.IsInValidLocation("Please enter a valid location or postcode", "Validation Fails"));
    }

    [TestCleanup]
    public void Cleanup()
    {
        driver.Close();
    }

My assert class

public class SearchErrorMessage
{
    public static bool IsInValidLocation(string InvalidLocation)
    {
        var ErrorMessage = driver.Instance.FindElement(By.XPath("/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]"));
        bool result = ErrorMessage.Text.Contains(InvalidLocation); 
        return result;
    }

My driver Class

public class driver
{
    public static IWebDriver Instance { get; set; }

    public static void Initialize()
    {
        Instance = new ChromeDriver(@"C:\Users\xxxxxx.xxxxxx\Documents\Visual Studio 2015\Drivers\Chrome");
        Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
    }

    public static void Close()
    {
        Instance.Close();
    }
CDspace
  • 2,639
  • 18
  • 30
  • 36
Richard C
  • 513
  • 1
  • 7
  • 26

1 Answers1

0

You probably just need an explicit wait, try this:

public static bool IsInValidLocation(string invalidLocation)
    {
        By selector = By.XPath("/html/body/header/div/div[4]/div/div/div[2]/div[1]/form/div[2]/span[2]");
        // You might want to research how to construct stable xpaths/selctors
        new WebDriverWait(driver.Instance, TimeSpan.FromSeconds(5)).Until(ExpectedConditions.ElementIsVisible(selector));
        var ErrorMessage = driver.Instance.FindElement(selector);
        bool result = ErrorMessage.Text.Contains(invalidLocation); 
        return result;
    }

The above code will give that message up to 5 seconds to appear, and will throw a timeout exception if it doesn't appear within 5 seconds. You can adjust it to wait longer if needed.

mrfreester
  • 1,981
  • 2
  • 17
  • 36
  • Also, moving the wait stuff into a generalized method that can be called from anywhere is a good idea :) – mrfreester Feb 10 '17 at 16:58
  • Thankyou for that, however am getting an error with the code you have given me WebDriverWait(driver, the driver command is highlighted and is telling me "driver is a type which is not valid in the given context" is there somthing I need to do differently in my driver Class to get this to run? – Richard C Feb 10 '17 at 17:07
  • Also thanks for the advice re xpath/selectors, it is on my list of things to get my head around, first off I just wanted to get some tests working, then start figuring out how to refactor my code to simplify it all. – Richard C Feb 10 '17 at 17:10
  • `driver` should just be the actual `IWebDriver` instance, I've updated my answer after looking at your code a little closer to get the `driver` instance :) – mrfreester Feb 10 '17 at 17:25
  • also, just a heads up, you might want to use `Instance.Quit();` or `Instance.Dispose()` in your `Close()` method instead of `Instance.Close()`. [close vs. quit vs. dispose](http://stackoverflow.com/a/17266450/1183506) – mrfreester Feb 10 '17 at 17:36
  • Hi Mrfreester, that has all worked perfectly, and, more importantly, I understand what your code is doing there and why its in that location of the test. I have applied the quit and dispose methods and tried them out, so another tool to add to my very basic starter set :). Going to look at refactoring the tests now, getting all my cleanup into 1 class, moving all the wait stuff into a generalised method instead of in each test, etc with the small number of tests I have written. But thanks again for you help with this issue. – Richard C Feb 13 '17 at 09:44