简体   繁体   中英

C# Selenium CSS-selector attribute not working

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

  1. Checked that the css locator is valid in "inspect code" and search
  2. Tried easier locators - it locates the id, but can't locate the attribute and its value
  3. Googling like crazy to find the solution

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)

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

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, eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM