0
votes

I'm currently learning C# with Selenium (Chrome Driver). I found some website which can be used for learning automation with Selenium and I have a really basic code which just opens the url, types something and searches for results.

Then I wanted to try and implement Page Object Model in my code. The first page would be responsible for opening url, writing something in the search box and clicking 'search'. The second page would be responsible for gathering results (not yet implemented in my code).

Unfortunately after implementing changes into my code (first approach to POM) my webdriver:

  1. Opens the url and loads the webpage without locating the element, then opens a new blank window and repeats this three or four times.
  2. Crashes while trying to locate element

I looked up some similar questions and I tried implementing some code before locating the element, but:

  • Driver.SwitchTo().DefaultContent();---> doesn't do anything for me
  • Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2); ----> doesn't help either

This is the code which is working fine:

namespace Seleniumtest1 { class Program { static void Main(string[] args) { var driver = new ChromeDriver();

            driver.Url = "http://automationpractice.com/index.php";

            var newSearch = driver.FindElement(By.Id("search_query_top"));
            newSearch.SendKeys("top");
            var searchConfrim = driver.FindElement(By.Name("submit_search"));

            searchConfrim.Click();

        }
    }
} 

This is the code after my attempt to implement POM, which doesn't work:

namespace ConsoleApplication_training
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.ReadKey();
            var page = new WebPage();
            page.ClickButton();
        }
    }

    internal class WebPage
    {
        private IWebDriver driver;
        private string websiteUrl;

        public IWebDriver Driver
        {
            get { return new ChromeDriver(); }
        }

        public string WebsiteUrl
        {
            get { return "http://automationpractice.com/index.php"; }

            set
            {
                websiteUrl = value;
            }
        }

        public WebPage()
        {
            Driver.Navigate().GoToUrl(WebsiteUrl);
            Driver.SwitchTo().DefaultContent();
            Driver.FindElement(By.Id("search_query_top"));
        }

        public void ClickButton()
        {
            Driver.FindElement(By.Name("submit_search")).Click();
        }
    }
}

The actual error is:

"OpenQA.Selenium.NoSuchElementException:no such element: Unable to locate element: {"method":"id","selector":"search_query_top"}"

Could anyone help with this issue or point out what might be the cause of the problem?

1

1 Answers

1
votes

The source of your problem is a misunderstanding of a ChromeDriver lifetime. With the next lines of code, you create a new instance of the driver for each call of Driver property.

public IWebDriver Driver
    {
        get { return new ChromeDriver(); }
    }

For your example you can just create an instance of ChromeDriver once, for example, using private property:

private readonly IWebDriver _driver = new ChromeDriver();
public IWebDriver Driver => _driver;

But this approach will cause other errors if you will have multiple pages. So it's better to create an instance of web driver separately and pass it to the pages via the constructor.