简体   繁体   English

对于大小为3的WebElement列表的循环,在第一个实例之后单击同一链接

[英]For loop with a size 3 WebElement List clicking on the same link after first instance

I have 3 links within a bento box group in our website. 我在我们网站的便当盒组中有3个链接。 I need to click the specific link if the link text matches my condition (I need to click all the 3 links anyways and I need to perform different actions after clicking them). 如果链接文本符合我的条件,我需要单击特定的链接(无论如何我都需要单击所有3个链接,并且在单击它们之后需要执行不同的操作)。 I wrote if loops within a for loop for achieving this. 我在for循环中编写了if循环来实现这一点。

When I execute this, for the first loop ie i=0, it clicks on the correct link. 当我执行此操作时,对于第一个循环(即i = 0),它单击正确的链接。 For the second loop (i=1), I expect it to pick the second link. 对于第二个循环(i = 1),我希望它选择第二个链接。 But it clicks on the third link. 但是它单击了第三个链接。 For the third loop as well, it clicks on the third link. 对于第三个循环,也单击第三个链接。 Not sure what I am missing here.` 不确定我在这里缺少什么。

public void SeasonalLinks() throws InterruptedException
{
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    List <WebElement> Seasonallnks = driver.findElements(By.xpath("//section[@id='seasonallinks']/ul/li/div/a"));
    int sl = Seasonallnks.size();
    System.out.println("Total no.of seasonal Links: "+sl);
    int i=0;

    for (i=0;i<sl;i++)
    {
        List <WebElement> Seasonallnks1 = driver.findElements(By.xpath("//section[@id='seasonal-links']/ul/li/div/a"));
        String sl1 = Seasonallnks1.get(i).getText();

        if (sl1.equalsIgnoreCase("Start a provider search"))
        {
            Seasonallnks1.get(i).click();
            WebDriverWait pshome = new WebDriverWait(driver,20);
            pshome.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']")));
            Thread.sleep(5000);
            driver.findElement(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']")).click();
        }
        else if (sl1.equalsIgnoreCase("Use pharmacy self-service tools"))
        {
            Seasonallnks1.get(i).click();
            WebDriverWait phome = new WebDriverWait(driver,20);
            phome.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']")));
            Thread.sleep(5000);
            WebDriverWait iswait1 = new WebDriverWait(driver,30);
            iswait1.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='acc-spinner-container]")));
            driver.findElement(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']")).click();
        }

        else if (sl1.equalsIgnoreCase("Start rewarding yourself today"))
        {
            Seasonallnks1.get(i).click();
            WebDriverWait hhome = new WebDriverWait(driver,20);
            hhome.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']")));
            driver.findElement(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']")).click();
        }
    }

Some feedback... to make your code more maintainable and save effort, you should follow the DRY principle (eliminate repetitive code). 一些反馈...为了使您的代码更具可维护性并节省精力,您应遵循DRY原则 (消除重复性代码)。 If you take a look at your if-else chain, there is a lot of repetition there. 如果您看一下if-else链,那里会有很多重复。 Each time you click on the same link, wait for an element to be clickable and click it. 每次单击相同的链接时,请等待元素可单击并单击它。 There's really only one unique thing you do for a single element. 对于单个元素,实际上只有一件独特的事情要做。

Use of Thread.sleep() should be avoided (google to see a full explanation). 应避免使用Thread.sleep() (谷歌查看完整说明)。 You are already using WebDriverWait s, which is a good practice, so add another WebDriverWait to avoid the Thread.sleep() usage, if it's needed. 您已经在使用WebDriverWait ,这是一个好习惯,因此,如果需要,可以添加另一个WebDriverWait以避免Thread.sleep()使用。

You have two collections, Seasonallnks and Seasonallnks1 that both store the same elements but the second instance looks like it has a typo in the locator. 您有两个集合, SeasonallnksSeasonallnks1 ,它们都存储相同的元素,但是第二个实例看起来像在定位器中有错字。 I combined the two of them. 我将两者结合在一起。

implicitlyWait() timeout only needs to be set once for the life of the driver and probably should be set outside this function. 在驱动程序的整个生命周期中, implicitlyWait()超时仅需设置一次,并且可能应在此函数之外设置。

The declaration of int i = 0; int i = 0;的声明int i = 0; can/should be done inside the for loop declaration. 可以/应该在for循环声明中完成。

You declared two waits but you can reuse the first to make the code more succinct. 您声明了两次等待,但是您可以重用第一次等待,以使代码更简洁。

If you use a locator more than once, consider declaring it as a variable of type By for easier reuse. 如果多次使用定位器,请考虑将其声明为By类型的变量,以方便重用。 It avoids typos and makes it easier to change, when needed, because it only needs to be changed in one place. 它避免了拼写错误,并且在需要时更易于更改,因为它只需要在一个地方进行更改。

wait.until() returns the element(s) waited for so when you wait for an element to be clickable and then intend to click it, you can just add .click() to the end, eg wait.until(...).click(); wait.until()返回等待的元素,因此当您等待元素可单击然后打算单击它时,您可以在末尾添加.click() ,例如wait.until(...).click();

You should also strive to have more descriptive variable names. 您还应该努力拥有更多描述性的变量名。 It will help you in a few months or someone else that has to read your code and figure out what it's doing. 它会在几个月后或其他需要阅读您的代码并弄清楚它在做什么的人中为您提供帮助。

Hopefully you can see from the cleaned up code below how many lines you can save by using DRY and applying some of the other suggestions I listed above. 希望您能从下面的清理代码中看到通过使用DRY并应用上面列出的其他一些建议可以节省多少行。

public void SeasonalLinks() throws InterruptedException
{
    By seasonalLinksLocator = By.xpath("//section[@id='seasonallinks']/ul/li/div/a");
    List<WebElement> seasonalLinks = driver.findElements(seasonalLinksLocator);
    System.out.println("Total no.of seasonal Links: " + seasonalLinks.size());
    WebDriverWait wait = new WebDriverWait(driver, 20);
    for (int i = 0; i < seasonalLinks.size(); i++)
    {
        String seasonalLinkText = seasonalLinks.get(i).getText();
        seasonalLinks.get(i).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@id='nav-home']/a[@aria-label='home button']"))).click();
        if (seasonalLinkText.equalsIgnoreCase("Use pharmacy self-service tools"))
        {
            wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='acc-spinner-container]")));
        }
        seasonalLinks = driver.findElements(seasonalLinksLocator);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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