单击多个按钮系列

raogr8fs  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(351)

我有一个Angular 的应用程序,我想自动化使用 selenium 网络驱动程序。
我尝试实现这段代码,用“确定”按钮自动化一系列对话框窗口:

// We check if Survey exit window is displayed using button ID
clickConfirmWindow(driver, SURVEY_EXIT_BUTTON_ID_LOCATOR, "Survey exit window");

// Wait Progress bar to finish
new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]")));

// We check if Select Equipment Ok window is displayed using button ID
clickConfirmWindow(driver, MESSAGE_CONTROLLER_SELECTEQUIPMENT_OK_BUTTON, "Select Equipment Ok window");

// Wait Progress bar to finish
new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]")));

// We check if Ok window is displayed using button ID
clickConfirmWindow(driver, MESSAGE_CONTROLLER_OK_BUTTON_ID_LOCATOR, "Ok window");

// Wait Progress bar to finish
new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]")));

// We check if Select Equipment Exit window is displayed using button ID
clickConfirmWindow(driver, SURVEY_SELECTEQUIPMENT_EXIT_BUTTON, "Select Equipment Exit window");

方法

private void clickConfirmWindow(WebDriver driver, String element_id, String name){
    // We check if warning window is displayed using button ID
    System.out.println("Searching " + name + " using " + element_id);
    Boolean isPresent = driver.findElements(By.id(element_id)).size() > 0;
    if(isPresent)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, 5);
        System.out.println("Found " + name + " using " + element_id);
        WebElement webElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(By.id(element_id)));
        webElement.click();
     }
}

由于某些原因,有时某些按钮没有被单击,代码就会失败。代码多次成功执行。有没有更好的方法来组织这一系列的点击?

lymnna71

lymnna711#

我认为造成间歇性成功的主要原因是你的 clickConfirmWindow() 方法。

Boolean isPresent = driver.findElements(By.id(element_id)).size() > 0;

这条线等不及了。。。它只是检查,如果它是假的,它假设它永远不会通过和跳过点击。您需要在这里添加一个合理的等待,以确保如果元素来了,它就有机会加载。在代码中,您希望等待元素可单击,因此我编写了该方法 isClickable() .

private Boolean isClickable(String element_id, int timeOut) {
    try {
        new WebDriverWait(driver, timeOut).until(ExpectedConditions.visibilityOfElementLocated(By.id(element_id)));
        return true;
    } catch (TimeoutException e) {
        return false;
    }
}

如果元素可单击,则返回true。如果不是,它会等到 timeOut 如果不成功则返回false。
至于剩下的代码,我有一些建议。
在编程中有一个干燥的概念(不要重复你自己)。你可以做一些谷歌搜索,但基本上如果你看到代码被多次使用,考虑把它放在一个方法。我在代码中看到的一个例子是等待进度条完成。那行被调用了3次,所以我把它放在一个方法中。它不仅使您的代码更易于阅读,还使您在需要更改等待、更改定位器等时更易于维护。

private void waitForProgressBar() {
    new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]")));
}

如果你的 WebDriverWait() 使用相同的超时,可以声明变量并重用它。

WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(...);

我没有重写这部分,但你真的应该把定位器存储为 By 而不是身份证 String . 如果有其他元素要使用的方法不是按id定位的,则需要使用基本相同的代码编写一个全新的方法来使用它。一个简单的例子。。。

private void click(WebDriver driver, By locator) {
    driver.findElement(locator).click();
}

然后用

click(driver, By.id("someId"));

此方法可用于所有定位器类型。。。id、css选择器、xpath等。
把这些放在一起,

// We check if Survey exit window is displayed using button ID
clickConfirmWindow(driver, SURVEY_EXIT_BUTTON_ID_LOCATOR, "Survey exit window");

// Wait Progress bar to finish
waitForProgressBar();

// We check if Select Equipment Ok window is displayed using button ID
clickConfirmWindow(driver, MESSAGE_CONTROLLER_SELECTEQUIPMENT_OK_BUTTON, "Select Equipment Ok window");

// Wait Progress bar to finish
waitForProgressBar();

// We check if Ok window is displayed using button ID
clickConfirmWindow(driver, MESSAGE_CONTROLLER_OK_BUTTON_ID_LOCATOR, "Ok window");

// Wait Progress bar to finish
waitForProgressBar();

// We check if Select Equipment Exit window is displayed using button ID
clickConfirmWindow(driver, SURVEY_SELECTEQUIPMENT_EXIT_BUTTON, "Select Equipment Exit window");

支护方法

private void clickConfirmWindow(WebDriver driver, String element_id, String name) {
    // We check if warning window is displayed using button ID
    System.out.println("Searching " + name + " using " + element_id);
    if (isClickable(element_id, 10)) {
        System.out.println("Found " + name + " using " + element_id);
        driver.findElement(By.id(element_id)).click();
    }
}

private void waitForProgressBar() {
    new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]")));
}

private Boolean isClickable(String element_id, int timeOut) {
    try {
        new WebDriverWait(driver, timeOut).until(ExpectedConditions.visibilityOfElementLocated(By.id(element_id)));
        return true;
    } catch (TimeoutException e) {
        return false;
    }
}
ct2axkht

ct2axkht2#

我想在里面加了些等待条件 clickConfirmWindow() 将解决问题。
所以取而代之的是

Boolean isPresent = driver.findElements(By.id(element_id)).size() > 0;
        if(isPresent)

在检查元素存在的地方,立即使用 if(waitForElementToBeVisible(element,10)) 哪里 waitForElementToBeVisible

public boolean waitForElementToBeVisible(By element, int delay) {
        wait = new WebDriverWait(driver, delay);
        try {
            wait.until(ExpectedConditions.visibilityOfElementLocated(element));
            return true;
        }catch (Throwable t){
            return false;
        }
    }

或者只是简单地增加一些200-500毫秒的延迟 driver.findElements(By.id(element_id)) 简单的延迟可以通过

public void wait(int delay){
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

使用 wait.until(ExpectedConditions 方法是最佳实践 Selenium ,不使用硬编码的固定延迟

相关问题