[英]Why can't I access some Salesforce DOM elements with (C#) Selenium By.CssSelector(), when I can 'see' them under their 'distant' ancestor nodes
我正在尝试通过具有 Lightning 组件 (LWC) 的 Salesforce 实现编写 E2E UI 测试。 我正在使用 Selenium 和 C# 来自动化测试。 我已经成功地使用 XPaths 定位了我的目标元素,但是已经阅读了推荐使用 CSS 选择器(为了自动测试速度和稳健性),所以我试图将我的By
调用从By.XPath()
转换为By.CssSelector()
。
但是,在将 CSS 选择器与 Salesforce 一起使用时,我看到了奇怪的行为,并且我发现无法访问 DOM 中的某些元素,即使当我访问它们的(遥远的)祖先时我可以“看到”它们。
这段代码...
var cssSel = "body";
var element = wait.Until(ExpectedConditions.ElementExists(By.CssSelector(cssSel)));
Console.WriteLine(element.GetAttribute("outerHTML"));
给我 DOM 中<body>
节点下的每个元素。 很好,我可以看到整个 DOM 结构——包括我想要定位的元素。
然后我可以将搜索细化为...
var cssSel = "body>div.desktop div.slds-no-print";
我得到类似...
<div class="slds-no-print oneAppNavContainer" data-aura-rendered-by="299:0;p" data-aura-class="oneAppNavContainer" style="top: 83px;">
<one-appnav data-data-rendering-service-uid="138" data-aura-rendered-by="244:0">
<div class="slds-context-bar">
<div class="slds-context-bar__primary navLeft">
<div class="slds-context-bar__item slds-context-bar_dropdown-trigger slds-dropdown-trigger slds-dropdown-trigger--click slds-no-hover">
<div class="appLauncher slds-context-bar__icon-action" role="navigation" aria-label="App">
<one-app-launcher-header class="slds-icon-waffle_container">
<button class="slds-button slds-show" aria-haspopup="dialog">
<div class="slds-icon-waffle">
<div class="slds-r1"/>
.
.
<div class="slds-r9"/>
<span class="slds-assistive-text">App Launcher</span>
</div>
</button>
</one-app-launcher-header>
</div>
<span class="appName slds-context-bar__label-action slds-context-bar__app-name">
<span class="slds-truncate" title="Critical Indicators – Sales">Critical Indicators – Sales</span>
</span>
</div>
</div>
<one-app-nav-bar class="slds-grid slds-has-flexi-truncate" one-appnavbar_appnavbar-host="">
<span one-appnavbar_appnavbar="" class="slds-assistive-text" id="operationId-5">Press Spacebar to reorder.</span>
<span one-appnavbar_appnavbar="" class="slds-assistive-text keyboardDnd" id="dndAssistiveText-5" aria-live="assertive"/>
<nav one-appnavbar_appnavbar="" class="slds-context-bar__secondary navCenter" role="navigation" aria-label="Global">
<div one-appnavbar_appnavbar="" class="slds-grid slds-has-flexi-truncate navUL" role="list" aria-describedby="operationId-5">
<one-app-nav-bar-item-root one-appnavbar_appnavbar="" class="navItem slds-context-bar__item slds-shrink-none slds-is-active" data-id="home" data-assistive-id="operationId" aria-hidden="false" draggable="true" role="listitem">
<a class="slds-context-bar__label-action dndItem" href="/lightning/page/home" title="Home" tabindex="0" draggable="false" aria-current="page">
<span class="slds-truncate">Home</span>
</a>
</one-app-nav-bar-item-root>
.
.
<!-- hundreds of lines of elements cut out -->
.
.
</div>
</nav>
</one-app-nav-bar>
</div>
</one-appnav>
<!--render facet: 301:0;p-->
</div>
仍然很好 - 我的目标元素仍然在那个 DOM 结构中。 但是,如果我现在用这些中的任何一个来获取下一个元素...
var cssSel = "body>div.desktop div.slds-no-print>one-appnav";
// or
var cssSel = "body>div.desktop div.slds-no-print one-appnav";
// or
var cssSel = "one-appnav";
我只取回那个单一元素,并且它不包含任何子元素......
<one-appnav data-data-rendering-service-uid="138" data-aura-rendered-by="244:0"></one-appnav>
我的目标元素在这个<one-appnav>
元素之下。 但是,如果我尝试使用类似...的方式访问它们
var cssSel = "body>div.desktop div.slds-no-print>one-appnav>div.slds-context-bar";
// or
var cssSel = "body>div.desktop div.slds-no-print>one-appnav div.slds-context-bar";
// or
var cssSel = "body>div.desktop div.slds-no-print div.slds-context-bar";
我得到一个例外...
OpenQA.Selenium.NoSuchElementException: no such element: Unable to locate element:
{"method":"css selector",
"selector":"body>div.desktop div.slds-no-print>one-appnav>div.slds-context-bar"}
尽管我之前可以在 DOM 树中看到该元素(如上面的示例输出所示)。
当我检查 Salesforce 页面时,我还可以在 Chrome Inspector 中看到所有目标元素。
那么,为什么在访问他们的“远距离”祖先时我可以在 DOM 树中看到我的目标元素,但在访问他们更“最近”的祖先时却看不到? 同样,我使用 XPath 访问所有这些目标元素没有问题。 那么为什么不使用 CSS 选择器呢?
因此,试图为这种奇怪的情况找到解决方案并不快乐。 事实上,我现在在不同的 Salesforce DOM 树中遇到了类似的情况。
再次,我可以看到更高的“远”祖先下方的整个 DOM 树,但是当我将目标定位在树的更下方时,在某个点上只有单个元素可用,而在它下面显然没有任何可访问的元素。
同样,这似乎只是在访问By.CssSelector
时出现的问题。 当我使用By.XPath
时,一切都按预期工作——我可以访问 DOM 树中的任何元素。
这里有一个有趣的点——当我比较两个 DOM 树中的两个“麻烦”元素时——原始场景中的一个,以及我刚刚发现的最新一个......
原来的...
<one-appnav data-data-rendering-service-uid="138" data-aura-rendered-by="244:0"></one-appnav>
最新的...
<force-aloha-page data-data-rendering-service-uid="1102" data-aura-rendered-by="6404:0" force-alohapage_alohapage-host=""/>
这些元素的共同因素是...
data-data-rendering-service-uid
和data-aura-rendered-by
我的感觉是这与rendering
/ rendered
属性有关。 我不确定他们做了什么,或者他们相关的动态值指向什么......可能指向一个javascript函数? 此处提出的问题,Salesforce 没有任何回应。
看起来我只需要恢复使用By.XPath
代替。 希望这会帮助找到类似情况的人。 如果您找到解决方案,请告诉我。
从那以后,我发现了对 Salesforce 更高版本(2020 年春季)的引用,他们建议在 CSS 选择器上使用 XPaths ,其中特别指出......
*Convert non-XPath locators to XPath*
LWC uses a _polyfill_ to implement shadow DOM rather than a native browser
implementation. This implementation restricts Selenium access by non-XPath
selectors, like By.cssSelector(), but still allows direct access with By.xpath().
The simplest fix is to convert your non-XPath locators to XPath.
- Microsoft.NETCore.App (v3.1.0)
- C# (v8)
- Selenium.Support package (v4.1.0)
- Chrome and Chromedriver (v102.0.5005.61)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.