ExpectedConditions.ElementIsVisible returns TimeoutException even when element is present

I'm using Selenium ChromeDriver v2.40, Chrome version 67.

var driver = Browser.GetChromeDriver();          
driver.Navigate().GoToUrl(url);
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
var abc=driver.FindElement(By.XPath("//*[@id='pdp-size-select']"));
var aaa=wait.Until(d => d.FindElement(By.XPath("//*[@id='pdp-size-select']")));
abc.Click(); // failed because elementisnotvisible

the above two findelement works fine, can get value but cannot click because the element is not visible

so i go on to try ExpectedConditions, and no luck with this:

wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='pdp-size-select']")));

Above code returns:

OpenQA.Selenium.WebDriverTimeoutException: 'Timed out after 10 seconds'

Does it have any backward compatibility issues with Chrome v67?


Solution 1:

As per the error elementisnotvisible seems you are pretty close. Moving forward as you are trying to invoke Click() on the element, so instead of ExpectedConditions as ElementIsVisible() you need to use ElementToBeClickable() as follows:

new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//*[@id='pdp-size-select']"))).Click();

With out any reference to SeleniumExtras and WaitHelpers the line of code will be:

new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//*[@id='pdp-size-select']"))).Click();

Note: As you mentioned you are using Chrome v67.x ensure that you are using ChromeDriver v2.40 (but not ChromeDriver v2.4)


Update

Debugging further it seems the Locator Strategy you have adapted, identifies exactly two (2) elements within the HTML DOM. So you need to construct a unique locator to identify and click the desired element as follows:

new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a[@data-track-action='Product-Page']//following::select[@id='pdp-size-select']"))).Click();

Note: The desired element is a select element and if you desire to interect with the <select> element as per best practices you need to use the SelectElement Class from OpenQA.Selenium.Support.UI Namespace.