0

I have customized an XPath for adding a product which has discount 30% for 2. Now I am facing problem while adding this into the cart.

package sample;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class Coop_angebote {

    public static void main(String[]args) throws InterruptedException{

        System.setProperty("webdriver.chrome.driver","C:\\Chrome\\chromedriver.exe");
    ChromeOptions options = new ChromeOptions();
     Map<String, Object> prefs = new HashMap<String, Object>();
      prefs.put("credentials_enable_service", false);
      prefs.put("password_manager_enabled", false); 
      options.setExperimentalOption("prefs", prefs);
    options.addArguments("start-maximized");
    options.addArguments("disable-infobars");
    WebDriver driver = new ChromeDriver(options);
    driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);

    // For Login Functionality

    driver.get("https://www.coopathome.ch/de?lang=de");
    driver.findElement(By.xpath("html/body/div[2]/div/div[2]/nav[2]/div/ul/li[2]/a[1]/span")).click();
    Thread.sleep(2000);
    driver.findElement(By.xpath("html/body/div[1]/div[2]/div/div/div/div/div/div/form/div[3]/div/div/input")).sendKeys("USERNAME");
    driver.findElement(By.xpath("html/body/div[1]/div[2]/div/div/div/div/div/div/form/div[4]/div[2]/div/input")).sendKeys("PASSWORD");
    driver.findElement(By.xpath("html/body/div[1]/div[2]/div/div/div/div/div/div/form/div[6]/button")).click();
    Thread.sleep(2000);
    driver.findElement(By.xpath("html/body/div[3]/div/div[2]/div[2]/header/a")).click();
    JavascriptExecutor jse = (JavascriptExecutor)driver;
    jse.executeScript("window.scrollBy(0,800)", "");

    Thread.sleep(1000);

    JavascriptExecutor jse1=(JavascriptExecutor)driver;
    jse1.executeScript("window.scrollBy(0,400)", "");

    Thread.sleep(1000);

    JavascriptExecutor jse2=(JavascriptExecutor)driver;
    jse2.executeScript("window.scrollBy(0,800)", "");

    Thread.sleep(1000);

    JavascriptExecutor jse3=(JavascriptExecutor)driver;
    jse3.executeScript("window.scrollBy(0,800)", "");

    Thread.sleep(1000);

    JavascriptExecutor jse4=(JavascriptExecutor)driver;
    jse4.executeScript("window.scrollBy(0,800)", "");

    Thread.sleep(1000);

    JavascriptExecutor jse5=(JavascriptExecutor)driver;
    jse5.executeScript("window.scrollBy(0,250)", "");

    Thread.sleep(1000);

    JavascriptExecutor jse6=(JavascriptExecutor)driver;
    jse6.executeScript("window.scrollBy(0,250)", "");

  //driver.findElement(By.xpath("//*[contains(text(),'30% ab 2')]")).click();


    List<WebElement> var=driver.findElements(By.xpath("//*[contains(text(),'30% ab 2')]"));
    System.out.println(var.size());

    for(int i = 0;i<=var.size();i++){

         List<String> li = new ArrayList<String>();
         var.get(i).getText().trim();
         System.out.println("ACTUAL:'"+ var.get(i).getText().trim() + "'");
           if(var.get(i).getText().trim().equals("30% ab 2"))
           {
               driver.findElement(By.xpath("//*[@class='btn__inner']")).click();
               Thread.sleep(1000);
               System.out.println("IN iF:");
           }

I have attached screenshot for HTML code.

2
  • 1
    Which error did you get??
    – Bharat Mane
    Commented Jul 14, 2017 at 4:54
  • I didnt get any error in console. but the required action of adding products into the cart is not completed and the page is navigated to some other instead of adding products into the cart. Hello Lauda, //div[@class='product-item'][.//span[contains(.,'30%')]]//button[@data-add-to-basket] This x path worked for me. thank you for your help.Now i can add all products into the cart which is in category 30%for2. Commented Jul 14, 2017 at 5:00

2 Answers 2

0

Same as for the other one, the xpath for add to cart button should be:

//div[@class='product-item'][.//span[contains(.,'30%')]]//button[@data-add-to-basket]

0

The mistake you're making is here:

//the below is ok
List<WebElement> var = driver.findElements(
        By.xpath("//*[contains(text(),'30% ab 2')]"));
System.out.println(var.size());

//use a for each loop to make your life
//easier than keeping track of .size and i's
for (int i = 0; i <= var.size(); i++) {
    //not used
    List<String> li = new ArrayList<String>();
    //not assigned to anything
    var.get(i).getText().trim();
    System.out.println("ACTUAL:'" + var.get(i).getText().trim() + "'");

    if (var.get(i).getText().trim().equals("30% ab 2")) {
        //The above is your mistake
        driver.findElement(By.xpath("//*[@class='btn__inner']")).click();
        Thread.sleep(1000);
        System.out.println("IN iF:");
    }
}

You'll need to click the "btn_inner" button element descending ancestor of var.get(i) in the approach you've given, using driver.findelement at that point will just returns the first visible "btn_inner" element in the whole page, the driver doesn't hold memory to where the last element(s) you called to find were. It re-evaluates the whole present page every single time it's called.

As I think it's going to be a bit hard for you to do the above proposal, you can also try to directly locate the buttons related to specified discount products based on an xpath like this:

findElements(By.xpath("//*[contains(text(),'30% ab 2')]/*[@class='btn__inner']")

which means to return the direct-child button element of all elements that contain '30% ab 2' text. Then by using something similar to your original approach, you can just re-iterate over a list of the above found elements and just .click() them to add to cart as you intended to do. P.S. try to learn how to use css selectors as well; it's a much more robust way to create tests and future-proof in that it doesn't care for the exact layout of the page as long as the element you want is still visible. With your approach even a single button being added/removed and you'll have to change up all your By's.

4
  • Please, take some time and properly format your code.
    – beatngu13
    Commented Jul 14, 2017 at 9:12
  • @beatngu13 My only code contribution is the couple lines on the end, the first code is the OPs.I only slightly un-formatted then so my added comments are visible without scrolling, dont think it should be that much of a nuisance..
    – Leon
    Commented Jul 14, 2017 at 9:15
  • 1
    Personally, I think following the boy scout rule is a good way to improve the quality of this site.
    – beatngu13
    Commented Jul 14, 2017 at 9:20
  • Absolutely, but I favored comments being conveniently visible instead of formatted code with comments outside reach, since its only a few relevant lines of code I copied from OP, not the whole thing, so hopefully shouldn't be too hard to follow.
    – Leon
    Commented Jul 14, 2017 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.