Charanoglu
Charanoglu

Reputation: 1339

Selenium cannot locate an element

I'm using Selenium for download some data from the site, in particular this is the url.

As you can see there are two tabs:

enter image description here

I'm trying to access to the 1st Half content by simulating a click on it through Selenium, this is my code:

var chromeOpts = new ChromeOptions();
chromeOpts.AddArguments("headless");
var chromeDriverService = ChromeDriverService.CreateDefaultService();
driver = new ChromeDriver(chromeDriverService, chromeOpts);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);            
driver.Navigate().GoToUrl(new Uri("http://www.oddsportal.com/soccer/usa/mls/chicago-fire-new-york-city-CAl0LCJs/?r=1#ah;2"));
driver.FindElement(By.XPath("//*[contains(text(),'1st') and contains(text(),'Half')]")).Click();
string html = driver.PageSource;

the problem is that I get this error:

OpenQA.Selenium.ElementNotVisibleException: 'element not visible

I though that my XPath is wrong, but I tried with other tabs and works, also the html structure is correct.

What's happening?

Upvotes: 0

Views: 913

Answers (3)

Thodoris Koskinopoulos
Thodoris Koskinopoulos

Reputation: 445

You have the unique ID bettype-tabs-scope, and there is ul and 3 li elements.

<div id="bettype-tabs-scope" class="tab-nav-detail">
  <ul class="sub-menu subactive" style="display: block;">
    <li class=" active"><span class="topleft_corner"></span><span class="topright_corner"></span><strong><span>Full&nbsp;Time</span></strong></li>
    <li class=""><a onmousedown="uid(28)._onClick();return false;" title="1st&nbsp;Half" href=""><span>1st&nbsp;Half</span></a></li>
    <li class="last"><a onmousedown="uid(29)._onClick();return false;" title="2nd&nbsp;Half" href=""><span>2nd&nbsp;Half</span></a></li>
  </ul>
</div>

You can pretty easily do:

//Find the unique element and the get all children list items.
var listItems = driver.FindElement(By.Id("bettype-tabs-scope")).FindElements(By.TagName("li"));
//Click the list items that has "1st Half" as it's text.
listItems.Where(li => li.Text == "1st Half").Single().Click();

Otherwise, you can also do driver.FindElement(By.Id("bettype-tabs-scope")).FindElements(By.TagName("li"))[1].Click(); if you are certain that the "1st half" button will always be second in the results (first being the Full Time).

Upvotes: 1

Subburaj
Subburaj

Reputation: 2334

There are two elements are found with same xpath and the first element is invisible. In your code, you have used the FindElement method and hence it is finding the invisible element returning an error.

Solution: You can perform the click action in two ways.

Option 1:

Change the Xpath as //*[contains(text(),'1st') and contains(text(),'Half')][1]

driver.FindElement(By.XPath("//*[contains(text(),'1st') and contains(text(),'Half')][1]")).Click();

Option 2:

Find all the matched elements using FindElements method and then perform the click action only, If the particular element is disaplyed

var halfElementList = driver.FindElements(By.XPath("//*[contains(text(),'1st') and contains(text(),'Half')]"));

string html = "";
foreach(var element in halfElementList)
{
    if (element.Displayed)
    {
        element.Click();
        html = driver.PageSource;
    }
}

Upvotes: 0

Monika
Monika

Reputation: 732

It should work as it works fine on my machine. Maybe page load is taking time on your machine. You can use expected condition wait for checking the visibility of the element. Make sure you've installed both the Selenium. Webdriver and Selenium.Support NuGet packages for your project. You'll need the Selenium. Support package to use ExpectedConditions.

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
IWebElement element = wait.Until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'1st') and contains(text(),'Half')]")));
element.Click();

Upvotes: 0

Related Questions