我有一个igCombo下拉控件,它使用虚拟化将项目从javascript加载到HTML中。在初始扩展下拉列表时,完整的项目列表不在列表/ HTML中,只有前10个项目。当用户向下滚动时,新项目将加载到HTML中。所以我不能简单地使用SelecElement.SelectByText,或者我不能使用一个简单的函数来存储来自HTML的for循环中的所有li元素,因为如果我要点击的项目是索引11或更远,它不会在还没有HTML。
我认为攻击它的唯一方法是使用for循环将初始项存储在HTML中。然后,如果用户传递的itemToClick变量值与此for循环中的任何项匹配,请单击该项,否则向下滚动一整页以加载下一个10项。重复循环,直到itemToClick值与滚动后的任何项目匹配,或者直到滚动到达下拉列表的底部,然后在那时,告诉用户该项目不存在。
所以我的方法调用就在这里。请注意,我想点击" MTV",它位于下拉列表的底部:
ClickListItemByNameVirtualization(driver, dropDownElem, scrollBarElem, "MTV");
这是方法。请参阅 NOT CODED YET 评论。这就是我需要帮助的地方。我尝试了几件事,但我不能提出适用于我需要的代码:
public void ClickListItemByNameVirtualization(IWebDriver browser, IWebElement divElemOfScrollBar, IWebElement ulElemOfDropDown, string itemName)
{
bool topOfList = true;
do
{
if (topOfList == false)
{
// NOT CODED YET: I need a method that scrolls down page by page within a dropdown frame. For reference of how I scroll statically inside a
// frame, see my ScrollToWithinFrame method that I referenced at the bottom of this post
ScrollDownPageWithinDropdown();
}
topOfList = false;
// Store all li elements within the unordered list
var liElems = ulElemOfDropDown.FindElements(By.TagName("li")).ToList();
// Loop through all list items
foreach (var liElem in liElems)
{
// if the current list item's text value in the for loop equals the users passed parameter itemName
if (liElem.Text == itemName)
{
liElem.Click();
Thread.Sleep(0200);
return;
}
}
// NOT CODED YET: I need code to add to ScrollBarEnd that returns true or false. Only do the above code if ScrollBarEnd is false
} while (!ScrollBarEnd());
}
最后,作为参考,这是我在框架内滚动的代码:
public void ScrollToWithinFrame(IWebDriver browser, IWebElement divElemOfScrollBar, int xOrYCoordinate, string HorizontalOrVertical)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)browser;
if (HorizontalOrVertical == "Vertical")
{
js.ExecuteScript("arguments[0].scrollTop = arguments[1];", divElemOfScrollBar, xOrYCoordinate);
}
if (HorizontalOrVertical == "Horizontal")
{
// Scroll inside the popup frame element vertically. See the following...
// http://stackoverflow.com/questions/22709200/selenium-webdriver-scrolling-inside-a-div-popup
js.ExecuteScript("arguments[0].scrollLeft = arguments[1];", divElemOfScrollBar, xOrYCoordinate);
}
}
答案 0 :(得分:0)
您可以使用无限循环与服务员等待列表末尾的新<li>
元素:
public void ClickListItemByNameVirtualization(IWebDriver browser, IWebElement divElemOfScrollBar, IWebElement ulElemOfDropDown, string itemName)
{
var wait = new WebDriverWait(browser, TimeSpan.FromSeconds(5));
IWebElement lastLi = null;
while (true) {
// wait for a new li element at the end and store all li elements
var liElems = wait.Until<ReadOnlyCollection<IWebElement>>(drv => {
var elems = ulElemOfDropDown.FindElements(By.TagName("li"));
return (elems.Count > 0 && elems[elems.Count - 1] != lastLi) ? elems : null;
});
// store the last element
lastLi = liElems[liElems.Count - 1];
// Loop through all list items
foreach (var liElem in liElems) {
// if the current list item's text value in the for loop equals the users passed parameter itemName
if (liElem.Text == itemName) {
liElem.Click();
return;
}
}
// scroll the container to the end
((IJavaScriptExecutor)browser).js.ExecuteScript(
"arguments[0].scrollTop = (-1 >>> 1);", divElemOfScrollBar);
}
}
答案 1 :(得分:0)
我想出了一个丑陋的方法。因为我知道滚动条在展开时的可见高度,其中包含可见项目(每个滚动10个加载到HTML中的项目),我使用可见高度(387像素)滚动我的for循环的每一步直到我达到最大高度。这里是。直到2天我都不会将此标记为答案,可能会给别人一个更直观的尝试。
public static void ClickListItemByNameVirtualization(IWebDriver browser, IWebElement ulElem, IWebElement divElem, string itemName)
int scrollAmount = 0;
IJavaScriptExecutor js = (IJavaScriptExecutor)browser;
ProgramLibraryPage PL = new ProgramLibraryPage(browser);
PL.ChangeProgFormSelectProgDrpDnBtn.Click();
// Scroll to the top of the list
js.ExecuteScript("return arguments[0].scrollTop = 0;", divElem);
for (var i = 0; i < 1000; i++)
{
List<IWebElement> liElems = ulElem.FindElements(By.TagName("li")).ToList();
foreach (var liElem in liElems)
{
// if the current list item's text value in the for loop equals the users passed parameter itemName
if (liElem.Text == itemName)
{
liElem.Click();
Thread.Sleep(0200);
return;
}
}
scrollAmount = scrollAmount + 387;
object scrollMaxHeight = js.ExecuteScript("return arguments[0].scrollHeight;", divElem);
var scrollMaxHeightInt = Convert.ToInt32(scrollMaxHeight);
if (scrollMaxHeightInt > scrollAmount)
{
ElemSet.ScrollToWithinFrame(browser, divElem, scrollAmount, "Vertical");
}
}
}