C# 每次向下滚动下拉列表(igCombo)元素一页,直到它到达列表的末尾

C# 每次向下滚动下拉列表(igCombo)元素一页,直到它到达列表的末尾,c#,selenium,C#,Selenium,我有一个igCombo下拉控件,它使用虚拟化将项目从javascript加载到HTML中。在最初扩展下拉列表时,完整的项目列表不在list/HTML中,只有大约前10个项目是。当用户向下滚动时,新项目将加载到HTML中。因此,我不能简单地使用SelecElement.SelectByText,也不能使用简单的函数将所有li元素存储在HTML中的for循环中,因为如果我要单击的项目位于索引11或更高的位置,它还不会在HTML中 我认为解决这个问题的唯一方法是使用for循环在HTML中存储初始项。然

我有一个igCombo下拉控件,它使用虚拟化将项目从javascript加载到HTML中。在最初扩展下拉列表时,完整的项目列表不在list/HTML中,只有大约前10个项目是。当用户向下滚动时,新项目将加载到HTML中。因此,我不能简单地使用SelecElement.SelectByText,也不能使用简单的函数将所有li元素存储在HTML中的for循环中,因为如果我要单击的项目位于索引11或更高的位置,它还不会在HTML中

我认为解决这个问题的唯一方法是使用for循环在HTML中存储初始项。然后,如果用户传递的itemToClick变量值与此for循环中的任何项目匹配,请单击该项目,否则向下滚动一整页以加载接下来的10个项目。重复循环,直到itemToClick值与滚动后的任何项目匹配,或者直到滚动到达下拉列表的底部,然后在该点告诉用户该项目不存在

所以我的方法调用在这里。请注意,我想单击下拉列表底部的“MTV”:

ClickListItemByNameVirtualization(driver, dropDownElem, scrollBarElem, "MTV");
这里是方法。请参阅尚未编码的注释。这就是我需要帮助的地方。我尝试了几件事,但我无法找到适合我需要的代码:

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);
    }
}

您可以使用无限循环,让服务员在列表末尾等待新的
  • 元素:

    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);
        }
    }
    
    public void ClickListItemByNameVirtualization(IWebDriver浏览器、IWebElement divElemOfScrollBar、IWebElement ulElemOfDropDown、string itemName)
    {
    var wait=new WebDriverWait(浏览器,TimeSpan.FromSeconds(5));
    IWebElement lastLi=null;
    while(true){
    //在末尾等待新的li元素并存储所有li元素
    var liElems=等待.直到(drv=>{
    var elems=ulElemOfDropDown.FindElements(按.TagName(“li”));
    返回(elems.Count>0&&elems[elems.Count-1]!=lastLi)?elems:null;
    });
    //存储最后一个元素
    lastLi=liElems[liElems.Count-1];
    //循环浏览所有列表项
    foreach(liElems中的var liElem){
    //如果for循环中当前列表项的文本值等于用户传递的参数itemName
    if(liElem.Text==itemName){
    liElem.Click();
    返回;
    }
    }
    //将容器滚动到末尾
    ((IJavaScriptExecutor)浏览器).js.ExecuteScript(
    “参数[0]。scrollTop=(-1>>>1);”,divElemOfScrollBar);
    }
    }
    
    您可以使用无限循环,服务员在列表末尾等待新的
  • 元素:

    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);
        }
    }
    
    public void ClickListItemByNameVirtualization(IWebDriver浏览器、IWebElement divElemOfScrollBar、IWebElement ulElemOfDropDown、string itemName)
    {
    var wait=new WebDriverWait(浏览器,TimeSpan.FromSeconds(5));
    IWebElement lastLi=null;
    while(true){
    //在末尾等待新的li元素并存储所有li元素
    var liElems=等待.直到(drv=>{
    var elems=ulElemOfDropDown.FindElements(按.TagName(“li”));
    返回(elems.Count>0&&elems[elems.Count-1]!=lastLi)?elems:null;
    });
    //存储最后一个元素
    lastLi=liElems[liElems.Count-1];
    //循环浏览所有列表项
    foreach(liElems中的var liElem){
    //如果for循环中当前列表项的文本值等于用户传递的参数itemName
    if(liElem.Text==itemName){
    liElem.Click();
    返回;
    }
    }
    //将容器滚动到末尾
    ((IJavaScriptExecutor)浏览器).js.ExecuteScript(
    “参数[0]。scrollTop=(-1>>>1);”,divElemOfScrollBar);
    }
    }
    
    我想出了一个丑陋的方法。由于我知道滚动条在展开时的可见高度,其中包含可见项目(每个滚动条加载到HTML中的项目为10个),因此我使用该可见高度(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");
                }
            }
    }
    
    publicstaticvoid单击ListItemByNameVirtualization(IWebDriver浏览器、IWebElement-ulElem、IWebElement-divElem、string-itemName)
    int scrollmount=0;
    IJavaScriptExecutor js=(IJavaScriptExecutor)浏览器;
    ProgramLibraryPage PL=新的ProgramLibraryPage(浏览器);
    PL.ChangeProgFormSelectProgDrpDnBtn.Click();
    //滚动到列表的顶部
    js.ExecuteScript(“返回参数[0].scrollTop=0;”,divElem);
    对于(变量i=0;i<1000;i++)
    {
    List liElems=ulElem.FindElements(按.TagName(“li”)).ToList();
    foreach(liElems中的var liElem)
    {
    //如果for循环中当前列表项的文本值等于用户传递的参数itemName
    if(liElem.Text==itemName)
    {
    liElem.Click();
    睡眠(0200);
    返回;
    }
    }
    scrollAmount=scrollAmount+387;
    对象scrollMaxHeight=js.ExecuteScript(“返回参数[0].scrollHeight;”,divElem);
    var scrollMaxHeightInt=Convert.ToInt32(scrollMaxHeight);
    如果(scrollMaxHeightInt>scrollAmount)
    {
    ElemSet.ScrollToWithinFrame(浏览器,divElem,scrollAmount,“垂直”);
    }
    }
    }
    
    我想出了一个丑陋的方法。因为我知道滚动条在展开时的可见高度,滚动条包含可见项(每个滚动条加载到HTML中的项数为10),