Java Automation Selenium findElement by xpath 有时找不到对象



我对Selenium和自动化很陌生。我正在尝试对简单的健康申报表页面进行自动化:https://forms.office.com/Pages/ResponsePage.aspx?id=bGOiBG0y_0iT-HCYdb06qZZ8CdlEQAhOkRllU1E9dVZUMVk1VTZFWThQV1FQUTFUV0FKNkNOVldMSi4u

为了进入文本字段,我使用了xpath:

driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://forms.office.com/Pages/ResponsePage.aspx?id=bGOiBG0y_0iT-HCYdb06qZZ8CdlEQAhOkRllU1E9dVZUMVk1VTZFWThQV1FQUTFUV0FKNkNOVldMSi4u");
WebElement element = driver.findElement(By.xpath("//*[@id="form-container"]/div/div/div[1]/div/div[1]/div[2]/div[2]/div[1]/div[2]/div[3]/div/div/div/input"));
element.click();
element.sendKeys("Testing");

问题是有时它找不到元素,程序就会崩溃。

*** Element info: {Using=xpath, value=//*[@id="form-container"]/div/div/div[1]/div/div[1]/div[2]/div[2]/div[1]/div[2]/div[3]/div/div/div/input}
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:323)
at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:428)
at org.openqa.selenium.By$ByXPath.findElement(By.java:353)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315)
at automactionproj.MainActivity.hazaratBriyot(MainActivity.java:31)
at automactionproj.MainActivity.main(MainActivity.java:23)
Process finished with exit code 1

有什么建议吗?

使用绝对xpath不是一个好方法。我看不到应用程序中的xpath与代码中使用的xpath字符串相匹配。尝试使用以下相对xpath:

WebElement element = driver.findElement(By.xpath("//input[@aria-labelledby='question1-title question1-required question1-questiontype']"));
element.sendKeys("Testing");

即使您可以使用唯一属性(例如//input[contains(@aria-labelledby,'question1-title')](缩短xpath并使其唯一可识别

在文本框中输入文本之前,无需执行单击操作。

不要试图自动化谷歌表单出于多种原因,不建议使用WebDriver登录Gmail和Facebook等网站。除了违反这些网站的使用条款(你可能会面临账户关闭的风险(之外,它速度慢且不可靠。

理想的做法是使用电子邮件提供商提供的API,或者在Facebook的情况下,使用开发者工具服务,该服务公开用于创建测试帐户、好友等的API。尽管使用API可能看起来有点额外的工作量,但您将在速度、可靠性和稳定性方面得到回报。API也不太可能改变,而网页和HTML定位器经常改变,需要您更新测试框架。

在测试的任何时候使用WebDriver登录第三方网站都会增加测试失败的风险,因为这会延长测试时间。一般的经验法则是,时间越长的测试越脆弱、越不可靠。

符合W3C的WebDriver实现还使用WebDriver属性对导航器对象进行注释,从而可以减轻拒绝服务攻击。

由于该页面有5个唯一的输入字段,为了避免html代码更改和定位器的稳定性,您可以直接使用以下定位器:

(//input)[1]

其中,1是第一个输入字段的索引。因此,您可以使用1-5中的任何值。

要在占位符为的第一个元素中发送字符序列请输入答案,您可以使用以下基于xpath的定位器策略:

driver.findElement(By.xpath("//span[text()='Required']//following::div[1]/div//input[@placeholder='Enter your answer']")).sendKeys("LiorShor");

理想情况下,您需要诱导WebDriverWait等待elementToBeClickable(),您可以使用以下解决方案:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//span[text()='Required']//following::div[1]/div//input[@placeholder='Enter your answer']"))).sendKeys("LiorShor");

最新更新