【问题标题】:Selenium C# - Web element attribute is present but cannot be found?Selenium C# - Web 元素属性存在但找不到?
【发布时间】:2019-03-12 22:36:46
【问题描述】:

我为 selenuim 测试用例编写的函数遇到问题...当我在 Web 元素 ID (#AmountToggle) 上运行 jquery 时,它会显示所有属性。我想验证这个(“lastChild”):

但是当我运行这段代码时:

driver.FindElement(By.CssSelector("#AmountToggle")).GetAttribute("lastChild")

它返回null?!

为什么会这样,我怎样才能得到这个属性的正确值?

【问题讨论】:

  • 使用基于文本的 HTML 更新问题,包括父元素。

标签: c# selenium


【解决方案1】:

所以看起来“lastChild”是一个属性,而不是一个属性。虽然我不能肯定你上面所说的。

不同的是,一个属性会在直接的 html 中显示为某种东西,例如:

<a href="#" id="MyLink">Link</a>

其中 href 和 id 是属性。如果 lastChild 没有像上面的例子一样出现在 html 中,它不会被认为是一个属性。

首先尝试在 javascript 控制台中比较这两个:

$("#AmountToggle").attr("lastChild")
$("#AmountToggle").prop("lastChild")

当您遇到 Selenium 查找问题时,以下是一种解决方法。这种逻辑可以让您轻松地在 iframe 中查找内容,还可以让您使用伪选择器来查找元素:

public static string GetFullyQualifiedXPathToElement(string cssSelector, bool isFullJQuery = false, bool noWarn = false)
        {

            if (cssSelector.Contains("$(") && !isFullJQuery) {

                isFullJQuery = true;

            }
            string finder_method = @"
                        function getPathTo(element) {
                            if(typeof element == 'undefined') return '';
                            if (element.tagName == 'HTML')
                                return '/HTML[1]';
                            if (element===document.body)
                                return '/HTML[1]/BODY[1]';

                            var ix= 0;
                            var siblings = element.parentNode.childNodes;
                            for (var i= 0; i< siblings.length; i++) {
                                var sibling= siblings[i];
                                if (sibling===element)
                                    return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
                                if (sibling.nodeType===1 && sibling.tagName===element.tagName)
                                    ix++;
                            }
                        }
            ";
            if(isFullJQuery) {

                cssSelector = cssSelector.TrimEnd(';');

            }
            string executable = isFullJQuery ? string.Format("{0} return getPathTo({1}[0]);", finder_method, cssSelector) : string.Format("{0} return getPathTo($('{1}')[0]);", finder_method, cssSelector.Replace("'", "\""));
            string xpath = string.Empty;
            try {

                xpath = BaseTest.Driver.ExecuteJavaScript<string>(executable);

            } catch (Exception e) {

                if (!noWarn)  {

                    //Warn about failure with custom message.

                }

            }
            if (!noWarn && string.IsNullOrEmpty(xpath)) {

                //Warn about failure with custom message.
                //string.Format("Supplied cssSelector did not point to an element. Selector is \"{0}\".", cssSelector);

            }
            return xpath;

        }

此方法使用 Jquery,它使用 CssSelectors(例如伪选择器)具有更广泛的搜索选项,并且在给定良好搜索查询的情况下 100% 的时间可以找到东西。此方法使用 JQuery 查找元素,然后在 DOM 中生成指向该元素的显式 XPath,并返回该 XPath。通过显式 XPath,您可以告诉 Selenium 使用 XPath 查找元素。

看起来last-child 的值本身就是一个元素。如果这是真的,那么您可以在示例中使用它:

driver.FindElement(By.XPath(GetFullyQualifiedXPathToElement("$(#AmountToggle).prop('lastChild')[0]", true)));

这里注意三点。首先是我在 JQuery 中使用了“prop”。如果这是正确的调用,请将其更改为“attr”。另外,请注意 [0] 索引。这会将 JQuery 元素值作为常规 javascript DOM 元素返回,这就是上述方法所使用的。最后要注意的是传入的cssSelector值。你可以只传入一个选择器给这个方法,比如“#SomeElementId > div”,也可以传入完整的JQuery,比如“$('#SomeElementId > div ')"。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 2013-07-03
    • 2021-12-31
    • 2020-02-17
    • 2019-04-16
    相关资源
    最近更新 更多