考虑这个网址:https://sfbay.craigslist.org/pen/apa/5759740929.html 单击“回复”按钮时,您将看到一个带有回复选项的弹出式窗口。 div可能有也可能没有电话号码和联系人姓名。
我为此制作了一些代码,我期望按照以下几点提到的工作。
1-如果单击了回复按钮,则等待回复选项弹出窗口可见。当弹出窗口可见时,查找任何电话号码并提取它们。
2-如果弹出窗口中没有数字,则不执行任何操作(因为此人不想分享他/她的电话号码。)
3-如果有人在弹出窗口未打开时尝试提取电话号码/姓名,则抛出一个运行时异常,表示没有点击回复按钮。
为什么在使用wait_for_reply_options_popup_to_be_visible()时代码会失败,但在我使用时会传递: wait_for_calling_options_to_be_visible();
请帮助我理解原因并解决此问题。谢谢!
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.List;
import static Utils.extract_phone_numbers;
public class Temp {
private static final WebDriver browser = new ChromeDriver();
private static String url = "https://sfbay.craigslist.org/pen/apa/5759740929.html";
private WebElement reply_btn;
private String reply_btn_xpath = "//button[contains(concat(\" \", normalize-space(@class), \" \"), \" "
+ "reply_button" + " \")]";
private By reply_btn_loc = By.xpath(reply_btn_xpath);
private String reply_options_xpath = "//button[contains(concat(\" \", normalize-space(@class), \" \"), \" "
+ "reply_options" + " \")]";
private By reply_options_loc = By.xpath(reply_options_xpath);
private String call_options_xpath = "//b[contains(text(), 'call') or contains(text(), 'text')]";
private By call_options_loc = By.xpath(call_options_xpath);
public String phone_xpath = "following-sibling::ul/li";
public By phone_loc = By.xpath(phone_xpath);
@Before
public void before_each_test() {
browser.get(url);
load_elements();
}
@Test
public void get_phone_number() throws Exception {
reply_btn.click();
List<String> phones = get_calling_or_texting_options();
System.out.println(phones);
}
private void load_elements() {
reply_btn = new WebDriverWait(browser, 5).until(
ExpectedConditions.presenceOfElementLocated(reply_btn_loc));
}
private void wait_for_calling_options_to_be_visible(){
new WebDriverWait(browser, 5).until(ExpectedConditions.visibilityOfElementLocated(call_options_loc));
}
private void wait_for_reply_options_popup_to_be_visible(){
new WebDriverWait(browser, 5).until(ExpectedConditions.visibilityOfElementLocated(reply_options_loc));
}
private List<String> get_calling_or_texting_options() {
wait_for_reply_options_popup_to_be_visible();
//wait_for_calling_options_to_be_visible();
//Look for any element which contains call or text. Their sibling elements should have a number.
List<WebElement> calling_options = browser.findElements(call_options_loc);
WebElement calling_option = calling_options.get(0);
if (calling_options.size() > 0) {
//Get the sibling elements which contain phone numbers.
WebElement phone_info = calling_option.findElement(phone_loc);
//Remove all the extra text and extract only the phone number.
List<String> phones = extract_phone_numbers(phone_info.getText());
return phones;
} else {
String error = "Cannot get list of contact numbers! Please click the reply button first!";
throw new RuntimeException(error);
}
}
}
堆栈跟踪:
org.openqa.selenium.TimeoutException: Timed out after 5 seconds waiting for visibility of element located by By.xpath: //button[contains(concat(" ", normalize-space(@class), " "), " reply_options ")].......
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:80)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:261)
at src.Temp.wait_for_reply_options_popup_to_be_visible(Temp.java:59)
at src.Temp.get_calling_or_texting_options(Temp.java:63)
at src.Temp.get_phone_number(Temp.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
.......
Caused by: org.openqa.selenium.NoSuchElementException: no such element
(Session info: chrome=52.0.2743.116)
(Driver info: chromedriver=2.9.248315,platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 9 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html..........
............
*** Element info: {Using=xpath, value=//button[contains(concat(" ", normalize-space(@class), " "), " reply_options ")]}
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
...........
答案 0 :(得分:1)
WebElement
个对象会告诉您它们是否通过内置函数可见/启用。
try{
if(someElement.isDisplayed()) {
// Do something...
} else {
// Do nothing...
}
} catch (Exception e) {
// Do nothing or handle exception...
}
另一方面,为了便于阅读,通常更好的做法是为功能提供更多......简洁的名称。即wait_for_reply_options_popup_to_be_visible()
可能是waitForReplyOptions()
。
编辑:直接从回购,建议你自己做方法进行检查,如下所示:
public static boolean isPresentAndDisplayed(final WebElement element) {
try {
return element.isDisplayed();
} catch (NoSuchElementException e) {
return false;
}
}
答案 1 :(得分:0)
您应该使用try catch创建一个方法,如上所述。但我建议不要使用isDisplay()方法本身。相反,你应该使用FluentWait()
制作一个方法public WebElement visibilityWait(int timeInMilliSeconds, By by) {
WebElement element = null;
try {
element = new FluentWait<>(webDriver).
withTimeout(timeoutInMilliSeconds, TimeUnit.MILLISECONDS).
pollingEvery(500, TimeUnit.MILLISECONDS).
ignoring(NotFoundException.class).ignoring(NoSuchElementException.class).
until(visibilityOfElementLocated(by));
} catch (TimeoutException ex) {
logger.warn("Ignore TimeoutException: ", ex.getMessage());
}
return element;
}
此方法仅在元素存在且可见时才返回该元素,如果它不返回null。您可以为您的案例设置超时,例如我不知道的15秒。
PS:顺便说一句,如果你的某个方法正在运行而另一个方法不正常,请再次检查你的xpath。没有看到网站就不能再说了什么:)。