1

我正在使这个网站自动化,但面临ExplicitWait管理时间的条件问题。

场景是当我在发送用户名后单击登录链接或提交按钮时,它会在此过程中显示一个加载程序,一旦进程完成,加载程序就会从 DOM 中删除。

我已经使用了invisibilityOfElementLocated如下条件

new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));

但这无法预测正确的时间,它需要更多时间(不完全是 60 秒,而是大约 15-20 秒或可能是 30 秒。)然后允许执行下一个命令。

我必须在 4 个命令之前放置同一行才能完成登录过程。所以它似乎消耗了大约 90 秒来登录。

如果我不使用Explicitwait或删除Impliciwait等待,那么脚本会一直失败,因为加载程序会点击而不是其他一些元素。

到目前为止我尝试过的代码:

WebDriver driver = new FirefoxDriver();

System.out.println("Browser Opened");
driver.manage().window().maximize();
driver.get("https://www.rcontacts.in");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);    
System.out.println("URL Opened");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
driver.findElement(By.cssSelector(".ng-scope>a span[translate='login.register']")).click();
System.out.println("Register Link Clicked");
driver.findElement(By.name("userId")).sendKeys("9422307801");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
driver.findElement(By.xpath("//button[@type='submit']")).click();
System.out.println("Mobile number entered");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));

是否有任何解决方案可以在加载程序被删除后立即开始执行操作?

或者有什么方法可以等到加载器元素从 DOM 中删除。删除后,我可以继续进行进一步的操作吗?

4

2 回答 2

1

根据文档

警告:不要混合隐式和显式等待。这样做会导致不可预测的等待时间。

这可能是您的问题的原因。建议不要使用隐式等待。我会删除它们,然后根据需要添加显式等待,看看情况如何。

我拿走了你的代码并重写了它(如下),它每次都对我有用。

String url = "https://www.rcontacts.in";
driver.navigate().to(url);
waitForLoader();
driver.findElement(By.cssSelector("span[translate='login.register']")).click();
waitForLoader();
driver.findElement(By.cssSelector("input[name='userId']")).sendKeys("9422307801");
driver.findElement(By.cssSelector("button[translate='common.btns.next']")).click();

我有时遇到的问题是脚本多次向前跳跃。我添加了代码来waitForLoader()等待加载器出现(可见)然后消失(不可见)。一旦我这样做了,它就可以 100% 地工作。

public static void waitForLoader()
{
    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.id("loading-bar")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
}
于 2017-09-11T13:28:47.397 回答
1

首先,你已经诱导implicitlyWait()如下:

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

以及WebDriverWait()如下:

new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));

根据显式和隐式等待的文档,明确提到:

不要混合隐式和显式等待。这样做会导致不可预测的等待时间。例如,设置 10 秒的隐式等待和 15 秒的显式等待,可能会导致 20 秒后发生超时。

再一次,似乎将ExpectedConditions子句从invisibilityOfElementLocated(By.id("loading-bar")to 改为elementToBeClickable(By.xpath("//span[contains(text(),'Register')]")给了我 80% 的成功率。Windows 8这是我盒子上的有效代码块:

System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver(); 
driver.get("https://www.rcontacts.in");
System.out.println("URL Opened");
WebDriverWait wait = new WebDriverWait (driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[contains(text(),'Register')]")));
driver.findElement(By.xpath("//span[contains(text(),'Register')]")).click();
System.out.println("Register Link clicked");

注意:始终driver.quit()tearDown(){}方法内调用以优雅地关闭和销毁WebDriverWeb 客户端实例,以确保在您启动执行时不存在(通过) geckodriver的悬空实例。Task Manager

于 2017-09-11T11:39:22.727 回答