我在JUnit,Selenium Webdriver(版本3.141.59)和Chromedriver(版本2.45)的帮助下编写了自动化测试。
首先,我写了一个登录测试:
[...]
void loginTest() {
driver().findElement(By.id("login-button")).click();
driver().findElement(By.id("name")).sendKeys("mail@xx.com");
driver().findElement(By.id("password")).sendKeys("password");
driver().findElement(By.id("send")).click();
assertTrue(driver().findElement(By.id("logged-in-msg")).isDisplayed());
}
一切正常,一切正常,测试绿色。
然后,我不得不使用越来越多的复杂且长的id和xpath,所以我决定保持测试简短有趣,并将所有定位符放在单独的类中,如下所示:
public class LocatorsList {
public static final String
SIGN_IN_BUTTON = "login-button",
LOG_IN_USERNAME = "name",
LOG_IN_PASSWORD = "password",
LOG_IN_BUTTON = "send",
SUCCESS_MSG = "logged-in-msg";
}
我的测试:
[...]
void loginTest() {
driver().findElement(By.id(SIGN_IN_BUTTON)).click();
driver().findElement(By.id(LOG_IN_USERNAME)).sendKeys("mail@xx.com");
driver().findElement(By.id(LOG_IN_PASSWORD)).sendKeys("password");
driver().findElement(By.id(LOG_IN_BUTTON)).click();
assertTrue(driver().findElement(By.id(SUCCESS_MSG)).isDisplayed());
}
然后它停止工作。 Webdriver发送错误:
org.openqa.selenium.NoSuchElementException: no such element:
Unable to locate element: {"method":"id","selector":"name"}
当我看着测试进行时,该元素就在页面上,webdriver甚至单击它,好像它想填充该字段一样……但是没有。说“无法定位元素”。 我试图更改chromedriver和Selenium版本,但没有帮助。
答案 0 :(得分:0)
这很可能是由于元素不存在,您需要等待元素被加载。使用
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated((By.id(LOG_IN_USERNAME))));
之后,您可以对特定元素执行操作,例如sendKeys事件。
public class Testing {
public static final String
SIGN_IN_BUTTON = "jsid-login-button",
LOG_IN_USERNAME = "login-email-name",
LOG_IN_PASSWORD = "login-email-password",
LOG_IN_BUTTON = "input[type='submit']";
WebDriver driver;
@BeforeMethod
public void setUp() {
System.setProperty("webdriver.chrome.driver", <driverLocation>);
driver = new ChromeDriver();
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.get("https://9gag.com/");
}
@Test
public void demoTest() {
driver.findElement(By.id(SIGN_IN_BUTTON)).click();
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated((By.id(LOG_IN_USERNAME))));
driver.findElement(By.id(LOG_IN_USERNAME)).sendKeys(<YOUR_EMAIL>);
driver.findElement(By.id(LOG_IN_PASSWORD)).sendKeys(<YOUR_PASSWORD>);
driver.findElement(By.cssSelector(LOG_IN_BUTTON)).click();
}
@AfterMethod
public void tearDown() {
driver.quit();
}
}
答案 1 :(得分:0)
老实说,如果这是对代码的唯一真正更改,那么就像在字符串之前缺少类名一样简单吗?即:
driver().findElement(By.id(LocatorsList.SIGN_IN_BUTTON)).click()