I need to implement & modify my current method to do both matters:
- Waiting for element of being visible - (which is currently implemented but it still uses ExpectedCondition which is obsolete and might be changed)
- Waiting for element of being clickable - (When my test are running, it's face a problems with "loading circles", I'm pressing the button and before window is loaded there is loader which takes for 1 to 4 seconds and then it disappears. My goal is to force Selenium to wait "XXX" time and when loading will finish then continue with process.
Current code:
public static IWebElement WaitForElementVisible(this IWebDriver driver, By by, int timeoutInSeconds = 6)
{
IWebElement element;
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(0);
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
element = wait.Until(ExpectedConditions.ElementIsVisible(by));
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(Configuration.ElementTimeout);
return element;
}
catch (WebDriverTimeoutException e)
{
Console.WriteLine(e.ToString());
}
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(Configuration.ElementTimeout);
return null;
}
Based on different topics I've started writing something but unfortunately it's just copy...
I would prefer to do one valuable method which goal would be to check both things. Could you please give me any advice's/ hints what could be added to that specific method?
//Edit
I'm adding how that loader code looks like:
<div class="Loader__background" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 10;">
<div class="Loader__foreground" style="display: table; width: 100%; height: 100%; text-align: center; z-index: 20; color: white;">
<div class="Loader__message" style="display: table-cell; vertical-align: middle;">
<div mode="indeterminate" value="0" min="0" max="100" style="position: relative; display: inline-block; width: 280px; height: 280px;">
<div style="width: 280px; height: 280px; display: inline-block; transition: transform 10s linear 0ms; transform: rotate(1800deg);">
<svg viewBox="0 0 280 280" style="width: 280px; height: 280px; position: relative;">
<circle cx="140" cy="140" r="137.5" fill="none" stroke-width="5" stroke-miterlimit="20" style="stroke: rgb(0, 188, 212); stroke-linecap: round; transition: all 750ms ease-in-out 0ms; stroke-dasharray: 604.757, 863.938; stroke-dashoffset: -259.181;"></circle>
</svg>
</div>
</div>
</div>
</div>
</div>
I've also transferred @sers Java advice into C#:
public static IWebElement WaitForElementClickable(this IWebDriver driver, By by, int timeoutInSeconds)
{
new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)).Until(d =>
{
Boolean ajaxComplete;
Boolean jsReady;
Boolean loaderHidden = false;
IJavaScriptExecutor js = (IJavaScriptExecutor)d;
jsReady = (Boolean)js.ExecuteScript("return (document.readyState == \"complete\" || document.readyState == \"interactive\")"); ;
try
{
ajaxComplete = (Boolean)js.ExecuteScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
}
catch (Exception)
{
ajaxComplete = true;
}
try
{
loaderHidden = !d.FindElement(by).Displayed;
}
catch (Exception) { }
return ajaxComplete && jsReady && loaderHidden;
});
}
The
ExpectedConditions
in .NET binding is obsolete, however it was moved toDotNetSeleniumExtras
Use
ExpectedConditions
from there, it will dismiss the warningYou can also use
ExpectedConditions
to wait for the element to be clickableAnother option is to wait for the loader to appear and then disappear and then continue
As I understood your element is visible and clickable when loading element on the screen but overlaying you element, also maybe you need to wait javascript to complete to click successfully.
You need get "loading circles" locator. For that open chrome devtools trigger "loading circles" to appear and press F8(pause) then you can find html of loading element.
Wait until loading element is disappeared:
Also you can check if javascript is complete :
Here Java example:
Here your updated code:
How to use: