Reputation: 108
I'm trying to run Selenium test, where it waits until a certain attribute has a value to continue and when checking in the browser (Code inspection Ctrl+shift+I, ctrl+F), it locates the element using the css locator, but I in when running the test, I always get a timeout - and the element gets the desired value before that time
My code (CMExtensionMethods.IsElementVisible == ExpectedConditions, does the same thing):
public static WebDriverWait waitForElement = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
waitForElement.Until(CMExtensionMethods.IsElementVisible(By.CssSelector("#page_progress[style~='display:']")));
public static Func<IWebDriver, IWebElement> IsElementVisible(By identifier) {
return (driver) =>
{
try {
return IfElementVisible(driver.FindElement(identifier));
}
catch(NoSuchElementException) {
return null;
}
};
}
// Part of the method above
private static IWebElement IfElementVisible(IWebElement element) {
return element.Displayed ? element : null;
}
HTML code on the page(page_progress style changes depending on the website state - the style is either like this or empty):
<div id="page_progress" class="loading-progress" style="display: none;">
</div>
<div id="page_saveindicator" class="unsaved-changes" style="display:
none;"></div>
Expectation: The code to continue right after the style gets a value
Result: Nothing is located and I get a timeout error after 5 sec (as set), despite the element having the attribute and the value it's supposed to
Might be worth mentioning - the method IsElementVisible works - tested on IDs, and CSSselectors using Class and Id (alone)
Upvotes: 0
Views: 854
Reputation: 25542
You don't need to (and shouldn't) include style=display:...
in your locator to determine visibility. Selenium does that for you when you use .Displayed
or use ExpectedConditions
and wait for visible. Just locate the element normally, e.g. both of your elements have an ID so use By.Id("page_progress")
, like
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("page_progress"));
and Selenium will take care of the rest.
Upvotes: 1
Reputation: 18783
The wrong comparison operator is being used in the CSS selector.
The ~=
operator must exactly match the value of the attribute.
Either add the block
part of the attribute value, or change the comparison operator to ^=
.
By.CssSelector("#page_progress[style^='display:']")
More info: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
Upvotes: 0