Charanoglu
Charanoglu

Reputation: 1339

Unable to locate an existing element

I'm using Selenium to get data from this site and I encountered a problem that happen intermittently, I think this problem is related to the refresh of the page that the site runs every x seconds. Looking at the page of the link above I'm trying to get this table:

enter image description here

My code have have this design:

//Navigate to fixture page.
driver.Navigate().GoToUrl("http://www.oddsportal.com/soccer/europe/europa-league/fc-copenhagen-stjarnan-hzwurDB2/");

//Get all the available categories (eg: 1X2, AH, O/U etc...).
var listItems = driver.FindElement(By.Id("bettype-tabs-scope")).FindElements(By.TagName("li"));

//Get the tab 2nd Half.
var category = listItems.Where(li => li.Text == "2nd Half").SingleOrDefault();

//Click on the tab for load the table.
if (category != null)
{
   category.Click();
}
else
{
   //Tab doesn't exist, return an empty string.
   return string.Empty;
}

//Get the table.
var table = driver.FindElement(By.XPath("(//table[contains(@class, 'table-main')])[1]//tbody//tr[normalize-space()]"));

As I said this code works, but sometimes appear this error:

: 'no such element: Unable to locate element: {"method":"xpath","selector":"(//table[contains(@class, 'table-main')])1//tbody//tr[normalize-space()]"} (Session info: headless chrome=68.0.3440.84) (Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.17134 x86_64)'

I also tried to add an implicit wait after the click simulation:

driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);

but this didn't fix the problem.

Someone know how can I handle this?

Thanks in advance.

Upvotes: 1

Views: 164

Answers (1)

Subburaj
Subburaj

Reputation: 2334

You need to add some explicit wait after clicking the 2nd Half link.Since,table loading is taking sometime.

Modified Code:

WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5));
//DotNetSeleniumExtras.WaitHelpers NuGet package needs to be added
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("(//table[contains(@class, 'table-main')])[1]//tbody//tr[normalize-space()]")));

//Get the table.
var table = _driver.FindElement(By.XPath("(//table[contains(@class, 'table-main')])[1]//tbody//tr[normalize-space()]"));

Console.WriteLine(table.Text);

Output:

 18bet  
-227
+225
+775
89.6%

Edit:

ExpectedConditions is deprecated from the OpenQA.Selenium.Support.UI and newly added in SeleniumExtras.WaitHelpers. Please include the below NuGet Package

NuGet Package Needs to be Added:

DotNetSeleniumExtras.WaitHelpers

Expected Conditions will be available in both OpenQA.Selenium.Support.UI and SeleniumExtras.WaitHelpers.In order to avoid the conflicts, you can assign the newly imported package in one variable and can be access the required method.

So you can do the import like this ( using SeleniumWaitHelper = SeleniumExtras.WaitHelpers; ) and ExpectedConditions can be accessed as SeleniumWaitHelper.ExpectedConditions

Code:

WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5));
//DotNetSeleniumExtras.WaitHelpers NuGet package needs to be added
wait.Until(SeleniumWaitHelper.ExpectedConditions.ElementIsVisible(By.XPath("(//table[contains(@class, 'table-main')])[1]//tbody//tr[normalize-space()]")));

//Get the table.
var table = _driver.FindElement(By.XPath("(//table[contains(@class, 'table-main')])[1]//tbody//tr[normalize-space()]"));

Console.WriteLine(table.Text);

Upvotes: 1

Related Questions