How to deal with search that does not give any results on a webpage?

Multi tool use
How to deal with search that does not give any results on a webpage?
I wrote a program with some help from a few other Stack Overflow members a few days ago, and I now had a new functionality question.
So here is my code:
// importing a bunch of packages
public class webSearch {
public webSearch() {
}
public WebDriver driver = new ChromeDriver();
public void openTestSite() {
//driver.navigate().to(the URL for the website);
driver.get("https://wonef.fr/try/");
driver.manage().window().maximize();
//Explicit wait is added after the Page load
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.titleContains("WoNeF"));
}
public void enter(String word) {
WebElement query_editbox =
driver.findElement(By.id("query"));
query_editbox.sendKeys(word);
//AutoComplete is happening even after sending the Enter Key.
// So, Value needs to be selected from the autocomplete
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='autocomplete']/div")));
List<WebElement> matchedList=driver.findElements(By.xpath("//div[@class='autocomplete']/div"));
// System.out.println(matchedList.size());
for(WebElement element : matchedList){
if(element.getText().equalsIgnoreCase(word)){
element.click();
}
}
query_editbox.sendKeys(Keys.RETURN);
}
public void getText(String name) throws IOException {
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='mid']/div")));
WebElement result=driver.findElement(By.id("mid"));
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(name), "utf-8"));
writer.write(result.getText());
writer.close();
}
}
It basically opens a website, types in a word, presses enter, and then saves whatever is returned to a text file.
My question is how do I deal with the program when a word is typed in but there isn't a single hit in the search. This always causes the following error in my code:
Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath: //div[@class='autocomplete']/div (tried for 20 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:81)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:271)
at src.webSearch.enter(webSearch.java:43)
at src.Engine.main(Engine.java:58)
Caused by: org.openqa.selenium.NoSuchElementException: Cannot locate an element using By.xpath: //div[@class='autocomplete']/div
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.13.0', revision: '2f0d292', time: '2018-06-25T15:32:14.902Z'
System info: host: 'my-MacBook-Air.local', ip: 'fe80:0:0:0:a6d1:8cff:fece:5dae%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.6', java.version: '1.8.0_171'
Driver info: driver.version: unknown
at org.openqa.selenium.support.ui.ExpectedConditions.lambda$findElement$0(ExpectedConditions.java:896)
at java.util.Optional.orElseThrow(Optional.java:290)
at org.openqa.selenium.support.ui.ExpectedConditions.findElement(ExpectedConditions.java:895)
at org.openqa.selenium.support.ui.ExpectedConditions.access$000(ExpectedConditions.java:44)
at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:206)
at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:202)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:248)
... 2 more
New error:
Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath: //div[@id='mid']/div (tried for 20 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:81)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:271)
at src.webSearch.getText(webSearch.java:62)
at src.Engine.main(Engine.java:57)
Caused by: org.openqa.selenium.NoSuchElementException: Cannot locate an element using By.xpath: //div[@id='mid']/div
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.13.0', revision: '2f0d292', time: '2018-06-25T15:32:14.902Z'
System info: host: 'my-MacBook-Air.local', ip: 'fe80:0:0:0:a6d1:8cff:fece:5dae%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.6', java.version: '1.8.0_171'
Driver info: driver.version: unknown
at org.openqa.selenium.support.ui.ExpectedConditions.lambda$findElement$0(ExpectedConditions.java:896)
at java.util.Optional.orElseThrow(Optional.java:290)
at org.openqa.selenium.support.ui.ExpectedConditions.findElement(ExpectedConditions.java:895)
at org.openqa.selenium.support.ui.ExpectedConditions.access$000(ExpectedConditions.java:44)
at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:206)
at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:202)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:248)
... 2 more
I do not see any chrome path command in your code
– cruisepandey
Jul 3 at 5:12
I do not see any auto complete though. Why do you need that string prior of clicking on enter button. I mean you already have the key , why would selenium returns it. If it is available in DOM then only Selenium can help.
– cruisepandey
Jul 3 at 5:19
What I am confused about is one thing in my code? The element is not going to even be in the matched list if nothing shows up in the search bar, right? That was my intention when I wrote it and asked about it before.
– userNeedsHelp
Jul 3 at 5:28
I have a main method in the engine class which has the chrome driver access given to it. Also @Kayaman, thanks for the suggestion, however, I am not sure which exception I would catch.
– userNeedsHelp
Jul 3 at 5:30
2 Answers
2
When you entered some unavailable word, then autocomplete is not happening and hence TimeoutException
is throwing. You need to handle this exception using try catch block.So, that your execution will be continued without any Exception. If you need to add some logic when the autocomplete is not happening, then you can handle those logic in catch block.
TimeoutException
If the AutoComplete is not displayed within 20 seconds, then we can assume that entered value is invalid.
Please find the modified code:
enter Method:
public void enter(String word) {
WebElement query_editbox =
driver.findElement(By.id("query"));
query_editbox.clear();
query_editbox.sendKeys(word);
try{
//AutoComplete is happening even after sending the Enter Key.
// So, Value needs to be selected from the autocomplete
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='autocomplete']/div")));
List<WebElement> matchedList=driver.findElements(By.xpath("//div[@class='autocomplete']/div"));
// System.out.println(matchedList.size());
for(WebElement element : matchedList){
if(element.getText().equalsIgnoreCase(word)){
element.click();
}
}
}catch (TimeoutException e){
System.out.println("Invalid Word is entered");
}
query_editbox.sendKeys(Keys.RETURN);
}
Edit: To Address followup Question
I have added the clear action in enter
method before entering the word.you can introduce some for loop in your main method in order to execute with different words
enter
String input={};
for(int i=0;i<input.length;i++){
webSrcapper.enter(input[i]);
webSrcapper.getText();
}
Sample with Array List:
ArrayList<String> list=new ArrayList<>();
list.add("Word1");
list.add("Word2");
list.add("Word3");
for(int i=0;i<input.length;i++){
webSrcapper.enter(list.get(i));
webSrcapper.getText();
}
You need to modify your webSearch class as below
public class webSearch {
public WebDriver driver;
public webSearch() {
ChromeOptions options = new ChromeOptions();
options.addArguments("headless");
driver=new ChromeDriver(options);
}
getText Method :
public void getText(String name) throws IOException {
try{
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='mid']/div")));
WebElement result=driver.findElement(By.id("mid"));
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(name), "utf-8"));
writer.write(result.getText());
writer.close();
}catch (TimeoutException e){
System.out.println("No Result is found for the requested word");
}
}
Thank you so much!! Sorry to bother you again, but I had one more question. Do you know how I can clear the search bar after entering one word? So, I have a for loop which goes through the words in an array, enters each word into the search bar, and saves the contents into a text file. So, do you know how I can clear the element each time?
– userNeedsHelp
Jul 4 at 0:05
Also, is there any way to do this without actually opening the chrome browser? I'm just wondering because that will be much more efficient.
– userNeedsHelp
Jul 4 at 0:06
@userNeedsHelp: I have updated the answer. Please check with the updated answer and you need to add query_editbox.clear(); before doing the sendkeys in enter Method
– Subburaj
Jul 4 at 4:32
Thank you for the updates! I had previously done the for loop thing and am actually getting a new error. Can you please refer to the code above to see it?
– userNeedsHelp
Jul 4 at 4:54
@userNeedsHelp. If the invalid Word is searched, then it will not give any result.So, you need to use try catch blcok in your getText method as well. updated the answer
– Subburaj
Jul 4 at 5:00
You can select your desired option using below code :
WebElement query_editbox = driver.findElement(By.id("query"));
query_editbox.sendKeys("bad");
String wordToBeSelected = "badge";
selectOptionFromDropdown(driver, wordToBeSelected);
private static void selectOptionFromDropdown(WebDriver driver, String wordToBeSelected) {
WebDriverWait wait=new WebDriverWait(driver,25);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".autocomplete div")));
List<WebElement> dropdownList = driver.findElements(By.cssSelector(".autocomplete div"));
WebElement desiredElement = dropdownList.stream()
.filter(element -> element.getAttribute("title").equals(wordToBeSelected))
.findFirst().get();
desiredElement.click();
}
Hope this helps you.
Thank you for your suggestion! I think I got this part working with your suggestion and @Subburaj's suggestion.
– userNeedsHelp
Jul 4 at 0:06
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You could catch the exception and then do (or not do) something based on it.
– Kayaman
Jul 3 at 5:11