Using alternative to try catch exception for end of page link - java

Requirement: Go to the link which is a job search for last 3 days.
1) Print job descriptions
2) Click on the next link to go to next page until you reach the last page
Problem: I am using try catch for no such element found for next link when I reach the last page. Using this solution it stops the script, by looking at the JUNIT bar you will not know if the test passed or failed.It is a grey bar since as I used exit. How can I make this code better so that I do not have to use that try catch and see a green bar for a passing test?
Code:
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class QAJob {
#Test
public void jobSearch(){
WebDriver driver= new FirefoxDriver();
driver.get("https://www.indeed.com/jobs?as_and=qa+engineer&as_phr=&as_any=&as_not"
+ "=&as_ttl=&as_cmp=&jt=all&st=&salary=&radius=10&l=Bellevue%2C+WA&fromage=7&limit"
+ "=10&sort=date&psf=advsrch");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//code to scroll down to find the rest pages link
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("window.scrollBy(0,1000)", "");
// Find and print the number of pages for the search
List<WebElement> search_pages=driver.findElements(By.xpath("//div [contains(#class,'pagination')]//a"));
System.out.println("Number of pages found for this search " + search_pages.size());
while(search_pages.size()!=0){
List<WebElement> job_desc=driver.findElements(By.xpath("//div [contains(#id,'p')][contains(#class,'row')]"));
for(WebElement e:job_desc){
String str_job_desc=e.getText();
System.out.println(str_job_desc);
}
try
{
// closes the pop up that appears
driver.findElement(By.id("popover-x-button")).click();
}
catch (Exception e)
{
}
try
{
//click on next link to go to next page
driver.findElement(By.xpath("//span[contains(#class,'np')][contains(text(),'Next')]")).click();
//scroll down
JavascriptExecutor jse1 = (JavascriptExecutor) driver;
jse1.executeScript("window.scrollBy(0,1000)", "");
}
//when I get the exception(because no next link is available) exit.
catch (org.openqa.selenium.NoSuchElementException e)
{
System.exit(0);
}
}
}
}
Thanks in advance for your time and suggestion.

You can actually re-use the trick used in your code to avoid try-catch block
List<WebElement> popXButton=driver.findElements(By.id("popover-x-button"));
if (popXButton.size()>0){
driver.findElement(By.id("popover-x-button")).click();
}
Same extends to the next block too
List<WebElement> nextVal=driver.findElements(By.xpath("//span[contains(#class,'np')][contains(text(),'Next')]"));
if(nextVal.size()>0){
driver.findElement(By.xpath("//span[contains(#class,'np')][contains(text(),'Next')]")).click();
}
else{
break;//exits while loop!
}

Related

List<WebElement> is not storing all the required elements in selenium

My myntra wishlist has 41 products, of which 19 are out of stock. I tried printing the names of the 'out of stock' products.
'out of stock' elements had a common class name using which I identified the product's name using xpath by traversing through parent and child nodes.
when i validated it in console, it gave the right response. It showed 19 products and when i hovered the mouse pointer it highlighted the out of stock products as expected. Works as expected when i debugged the code too.
But when i hit run, it printed only 7 products, size of the list was 7.
The page initially displays top 20 products and later displays the remaining as we scroll down. Out of the top 20, 7 are out of stock. Could this be a reason. If that is the case, how to handle this scroll event?
Here's the code snippet:
import java.util.List;
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;
public class stockout {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "path of chromedriver.exe");
WebDriver driver = new ChromeDriver();
WebDriverWait w =new WebDriverWait(driver,30);
driver.get(myntra login page);
//enter phone number driver.findElement(By.xpath(("//div[#class='signInContainer']/div[2]/div/input"))).sendKeys(phone number);
driver.findElement(By.cssSelector("div.submitBottomOption")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//div[#class='bottomeLink']/span")).click();
//enter password
driver.findElement(By.xpath("//input[#type='password']")).sendKeys(password);
driver.findElement(By.cssSelector("button.btn.primary.lg.block.submitButton")).click();
Thread.sleep(4000);
//open wishlist
driver.findElement(By.cssSelector("span.myntraweb-sprite.desktop-iconWishlist.sprites-headerWishlist")).click();
//add out of stock elements to a list
List<WebElement> outofstock = driver.findElements(By.xpath("//img[#class='itemcard-outOfStockItemImage itemcard-itemImage']/parent::picture/parent::a/parent::div/parent::div/div[2]/div/p[1]"));
//explicit wait
w.until(ExpectedConditions.visibilityOfAllElements(outofstock));
System.out.println(outofstock.size());
System.out.println("Items out of stock:");
for (WebElement product: outofstock)
{ System.out.println(product.getText());
}
}
}
Found the solution on the net, but wondering if there's any simpler way to do this. Suggestions are welcomed.
I added this piece of code to scroll down and it worked:
try {
Object lastHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
while (true) {
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
Thread.sleep(2000);
Object newHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
if (newHeight.equals(lastHeight)) {
break;
}
lastHeight = newHeight;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
You can use the following code if you are expecting a specific number of elements to be present.
new WebDriverWait(driver,10).until(ExpectedConditions.numberOfElementsToBe(By by, 19));

Selenium WebElement.click() refreshes the page instead of going to next screen. No response when WebElement.submit() is used

I am learning Selenium and using jetblue.com for test. When I click on "FIND IT" button in homepage by providing all the required values, the page simply refreshes instead of going to the next screen. Can anyone advise where I am going wrong?
I tried using .click() and submit(). but not the control does not go the next page
package testCases;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.Test;
public class Calendar {
#Test
public void calControl() throws InterruptedException
{
System.setProperty("webdriver.chrome.driver","C:\\chromedriver_win32\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("disable-infobars");
options.addArguments("--start-maximized");
WebDriver driver= new ChromeDriver(options);
driver.get("https://www.jetblue.com");
// driver.findElement(By.className("input-group-btn")).click();
Thread.sleep(3000);
// driver.findElement(By.cssSelector("button[class='btn pull-right']")).click();
List<WebElement> count = driver.findElements(By.className("input-group-btn"));
int count1 = driver.findElements(By.className("input-group-btn")).size();
count.get(0).click();
Thread.sleep(3000);
driver.findElement(By.xpath("//table[#class='calendar']//td//span[.=27]")).click();
System.out.println(count1);
for (int i = 0;i<count1;i++)
{
System.out.println(count.get(i).toString());
}
Thread.sleep(3000);
count.get(1).click();
Thread.sleep(3000);
//driver.findElement(By.xpath("//button/span[#class='foreground-sprite-calendarforward']")).click();
List<WebElement> pullRight = driver.findElements(By.cssSelector("button[class='btn pull-right']"));
int count2 = driver.findElements(By.cssSelector("button[class='btn pull-right']")).size();
do
{
pullRight.get(1).click();
} while (driver.findElement(By.xpath("//div/strong[.='March 2018']")).isDisplayed()==false);
List<WebElement> returnDate = driver.findElements(By.xpath("//table[#class='calendar']//td//span[.=8]"));
int returnCount = driver.findElements(By.xpath("//table[#class='calendar']//td//span[.=3]")).size();
returnDate.get(1).click();
//driver.findElement(By.xpath("//input[#class='piejs']")).click(); Find Button
WebElement from = driver.findElement(By.id("jbBookerDepart"));
from.click();
Thread.sleep(2000);
from.sendKeys("DXB");
from.sendKeys(Keys.TAB);
Thread.sleep(2000);
WebElement to = driver.findElement(By.id("jbBookerArrive"));
to.click();
Thread.sleep(2000);
to.sendKeys("SFO");
to.sendKeys(Keys.TAB);
Thread.sleep(2000);
WebElement findButton = driver.findElement(By.xpath("//*[#id='login-search-wrap']/div[3]/div/div[3]/form/input[5]"));
//System.out.println("Value of button:" +driver.findElement(By.xpath("//*[#id='login-search-wrap']/div[3]/div/div[3]/form/input[5]")).toString());
/*Actions a = new Actions(driver);
//a.click(findButton).build().perform();
a.clickAndHold(findButton).doubleClick().build().perform();*/
/*driver.findElement(By.cssSelector("input[value='Find it']")).submit();
driver.findElement(By.xpath("input[value='Find it']")).submit();*/
System.out.println(findButton.isEnabled());
findButton.click();
Thread.sleep(5000);
}
}
That page is probably using anti-selenium software. I debugged your code several times, and here are my observations - I tried do perform some operations by hand, and some by WebDriver, and the result is: If ANY operation is performed by WebDriver, the form will not submit. That even includes opening of the page. They probably set some flag whenever an automated software is performing any action on their page.
Have a look at this answer. I don't know what anti-bot method they may be using, but this could be the first step.

Selenium: Unable to upload files using for loop in Selenium

I want to upload images on a website, I am using XPath to do it. Using for loop I have tried, the loop is executed but no action is performed.
Please find my code below:
WebDriver driver=new FirefoxDriver( );
driver.get("https://www.netmeds.com/");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.xpath(".//*[#id='carousel-header']/div[1]/div/div[1]/div[3]/div/div[3]/button")).click();
for (int i=1;i<5;i++) {
driver.findElement(By.xpath(".//*[#id='lbl"+i+"']")).sendKeys("C:\\Users\\sys\\Downloads\\1.png");
System.out.println("upload");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
Point 1 - Actually you are doing sendkeys() to wrong element i.e. a label. It should be an <input> tag with type=file then only you will be able to upload file using sendkeys() method
Point 2 - No need to mention ImplicitWait more then one place. If you have mentioned it at one place e.g. after get(URL) then it is applicable for throughout the script. Still If you required some wait then use ExplicitWait
Anyway, Use the below code for doing the same what you required :
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test {
public static WebDriver driver;
public static void main(String[] args) throws InterruptedException
{
System.setProperty("webdriver.chrome.driver","Resources/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.netmeds.com");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.xpath("//button[#title='Upload Prescription']")).click();
for(int i=1;i<5;i++)
{
driver.findElement(By.xpath("//input[#id='FileUpload"+i+"']")).sendKeys("C:\\LICENCE.jpg");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOf(driver.findElement(By.id("loaderContainer"))));
System.out.println("File Upload "+ i + "Done");
}
}
}
I've tested at my end and I'm able to upload all 4 images. Let me know if you have any issue with this :)
Try this code in for loop:
for(int i = 1; i < 5; i++){
driver.findElement(By.xpath("//input[#id='FileUpload" + i + "']")).sendKeys("C:\\a.jpg");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
System.out.println("File Upload "+ i + "successfully");
}
And it works for me:)
second I can use the webDriverwait

Can't get selenium to click an element

I'm trying to simulate a few clicks for my new program but I'm stuck on the last thing!
I've managed to make selenium open the page and click on the checkbox which shows a rectangle popup with 9 buttons inside it. The only problem is clicking the buttons inside the pop up! I've checked the xpath a few times but Selenium says "No such element"
Here is my code:
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;
public class test {
static WebDriver driver;
public static void main(String[] args) {
ProfilesIni profile = new ProfilesIni();
FirefoxProfile myprofile = profile.getProfile("default");
driver = new FirefoxDriver(myprofile);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("http://www.runelocus.com/top-rsps-list/vote-1858-GrinderScape%20-%20New%20Website%20and%20Great%20Updates!/");
driver.switchTo().frame(1);
driver.findElement(By.xpath("//*[#id='recaptcha-anchor']/div[5]")).click();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver.findElement(By.cssSelector("#rc-imageselect-target > table > tbody > tr:nth-child(1) > td:nth-child(2)")).click();
}
}
Link to the problem: http://www.runelocus.com/top-rsps-list/vote-1858-GrinderScape%20-%20New%20Website%20and%20Great%20Updates!/
EDIT:
It creates the new elements after you click the checkbox. How would I click them?
Element you are trying to click is in iframe. We need to switch explicitly to that iframe for selenium to locate that element. Below code worked for me. (Please format Xpath in better readable format.)
driver.get("http://www.runelocus.com/top-rsps-list/vote-1858-GrinderScape%20-%20New%20Website%20and%20Great%20Updates!/");
driver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);
WebElement iframeSwitch = driver.findElement(By.xpath("/html/body/section/div/div/section/div/article/div/div[2]/form/table/tbody/tr/td[1]/div/div/div/iframe"));
driver.switchTo().frame(iframeSwitch);
System.out.println("Switched");
driver.findElement(By.cssSelector("div[class=recaptcha-checkbox-checkmark]")).click();

Selenium and Facebook Post Button: How to click facebook post button in java using selenium?

driver.get("https://www.facebook.com/sachin.aryal");
driver.findElement(By.name("xhpc_message_text")).sendKeys("Testing Java and Selenium");
driver.findElement(By.xpath("//*[#id='u_0_1a']/div/div[6]/div/ul/li[2]/button")).click();
The last line of the code is not working. How do I set the XPath of the Post button on facebook?
I know you already marked your own answer but it's not the proper way to do this. There are ways built into Selenium to do waits, e.g. wait for an element to be clickable. This method is the proper and more efficient way to do this.
driver.get("https://www.facebook.com/sachin-aryal/");
driver.findElement(By.name("xhpc_message_text")).sendKeys("Testing Java and Selenium");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button/span[.=\"Post\"]"))).click();
I noticed it works when you first scroll into view the button, try adding before the click on post the:
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,259)","");
Try the below code .. it must work for you..
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Facebook_login {
public static void main(String[] args) throws InterruptedException {
String user_name = "facebook_user_name";
String pwd = "facebook_password";
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.facebook.com");
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys(user_name);
driver.findElement(By.name("pass")).clear();
driver.findElement(By.name("pass")).sendKeys(pwd);
driver.findElement(By.xpath("//input[contains(#value,'Log In')]")).click();
Thread.sleep(10000);
System.out.println("logged in successfully");
WebElement notification = driver.findElement(By.xpath("//a[contains(#action,'cancel')]"));
if(notification.isDisplayed()) {
System.out.println("Notification is present");
notification.click();
}
WebElement status =driver.findElement(By.xpath("//textarea[#name='xhpc_message']"));
status.sendKeys("Hello");
Thread.sleep(3000);
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[text()='Post']"))).click();
}
}

Categories