单击相关按钮

时间:2016-06-17 09:01:45

标签: java selenium selenium-webdriver

我有一个页面,其中显示了许多产品,我需要为所选产品找到clicking相关buttons的方式(产品名称来自数据表)。每个产品的详细信息都存储在div class="cf"

<div class="cf">
   <div class="component ticket-item-base ticket-item-options cf">
      <div class="ticket-image">
         <picture>
            <span class="alt-text">City 7 day megarider</span>
      </div>
      <div class="ticket-item-details">
         <h3>City 7 day megarider</h3>
         <ul>
            <li class="icon ticket-calendar">Unlimited travel X76 service.</li>
            <li class="icon ticket-location">
               <li class="icon ticket-person">1 adult</li>
               <li class="icon ticket-discount">Save when you buy online</li>
               <li class="terms">
                  <a class="open-popup" href="#ticket-item-terms-popup-0-9">Full terms & conditions for this ticket</a>
               </li>
         </ul>
      </div>
      <div class="ticket-fulfilment-price">
         <div class="row">
            <div class="ticket-option">
               <div class="ticket-price-panel">
                  <label>Total</label>
                  <div class="ticket-price">
                     <div class="button-cart-wrapper cf">
                        <a class="submit-btn uniform-button button-orange button-smaller button-cart" data-ticket-id="7b0c3c08-a82a-4421-8232-dbb15def3428" href="#">
                           <span class="js-info-pop-up">Add to basket</span>
                        </a>
                        <div class="component added-to-basket-pop-up info-pop-up cf" style="display: block;">
                           <a class="close-icon" href="#">
                              <span class="alt-text">Close</span>
                           </a>
                           <p>
                              <span>1 ticket</span> added to basket.
                           </p>
                           <a class="link-arrow" href="/basket">View basket</a>
                        </div>
                     </div>
                  </div>
               </div>
               <div class="more-details-panel">
                  <div class="row">
                     <div class="more-details-panel">
                     </div>
                     <div id="ticket-item-terms-popup-0-9" class="overlay white-popup mfp-hide zoom-anim-dialog rich-text cf">
                     </div>
                  </div>
               </div>

以下是我如何处理它的步骤:

  1. 获取产品名称。
  2. 检查产品是否在线销售,然后单击其相关按钮。找到产品后我想点击的按钮是:添加到购物篮和关闭图标。
  3. 最新代码:

    // List products that have class-cf
    List<WebElement> listProduct = driver.findElements(By.xpath(
            "//html/body/div/div[4]/div/div/div[4]/div/div[2]/div[3]/div/ul/li[1]/div/div[@class='accordion-content cf']/div[@class='cf']"));
    
    for (WebElement eachElem : listProduct)
    {
        System.out.println("Searching for the exact element:");
    
        if (eachElem.getText().contains(TicketName))
        {
            // Identify the button to click on
            WebElement button = eachElem.findElement(By.xpath(".//span[@class='js-info-pop-up']"));
    
            // WebElement button = eachElem.findElement(By.xpath("//div/div/div[1]/div/div/a/span[contains(text(),'Add to basket')]"));
    
            Thread.sleep(500);
            break; // Break out of iteration.
        }
    }
    

4 个答案:

答案 0 :(得分:0)

我发布了一个方法,我发现它更有用。 我个人更喜欢使用xpath,因为我发现它更准确,但它确实只是个人偏好。如果有帮助,你可以尝试一下。

Elements are identifying successfully but while sending keys getting no such element error

使用pageObjects抓取元素的示例:

public class Grabber {
    /*
     *      There exists a plugin in firefox to right click an element, inspect it, then right clicking the element
     *      and copying the xpath and pasting it here.
     */

    private static WebElement element = null;

    public static WebElement input_box(WebDriver driver, WebDriverWait wait) {
        wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("XPATH HERE")));
        //Used if element is a button or needs to bet clicked
        //wait.until(ExpectedConditions.elementToBeClickable(By.xpath("XPATH HERE")));
        element = driver.findElement(By.xpath("XPATH HERE"));
        return element;
    }

}

如何使用它:

编辑:初始化,NavigateTo和Dispose会给你一个错误,因为它们必须是静态的,我快速写下来给出一个例子,你应该按照你认为合适的方式编辑它以获得你想要的工作。我希望我指出了解决问题的正确方向。

编辑:这里的处理是在驱动程序完成或抛出异常时清除驱动程序。删除遗漏的Temp文件。

public class Test {

    private WebDriver driver;
    private WebDriverWait wait;

    public static void main(String[] args) {

        try {
            initialize();
            navigateTo("www.somewhere.com");
            Grabber.input_box(driver, wait).sendKeys("I want to send these keys");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            dispose();
        }

    }

    private void initialize() {
        driver = new FirefoxDriver();
        wait = new WebDriverWait(driver, 15);
    }

    private void navigateTo(String url) {
        driver.get(url);
    }

    private void dispose() {
        RemoteWebDriver cRDriver = (RemoteWebDriver) driver;
        while (cRDriver.getSessionId() != null) {
            driver.quit();
        }
    }

}

答案 1 :(得分:0)

您可以尝试下面的代码。这样可行,因为“添加到购物篮”不是一个类。它是跨度内的文本。

WebElement button = eachElem.findElement(By.xpath("//span[contains(text(),'Add to basket')]"));   
button.click(); 
Thread.Sleep(2000); 
eachElem.findElement(By.xpath("//span[contains(text(),'Close')]")‌​).Click()

答案 2 :(得分:0)

for(WebElement eachElem:listProduct)
{
            String tmp = eachElem.findElement(By.xpath("//h3[contains(.,'" + TicketName + "')]")).getText();    
            System.out.println("Name of the product: " + tmp);
            if (tmp.equals(TicketName)){ 
                System.out.println("Inside the IF loop");
                //Get the parent of the Element <h3></h3> to fetch the child span
                WebElement parentEle = eachElem.findElement(By.xpath("../../..")); 
                WebElement button = parentEle.findElement(By.xpath("//span[contains(text(),'Add to basket')]"));   
                 button.click(); //If title matches click on button for same element.
                  System.out.println("Button Add basket clicked");
               break; //Break out of iteration.
            }
       }

这个问题似乎主要围绕着被收集的元素,即。根据您的xml,此元素没有CHILD。要获取元素,您需要获取ie的父元素。从这个父级,您可以搜索孩子添加到购物篮。让我知道,如果这种推断有意义。感谢!!!

更新:16年6月24日21:00 我赞成一种更通用的方法来找到你的“父”元素(虽然你可能会有所不同)。对于您的问题,请确认您的“添加到购物篮”元素属于/ a / span(在所有页面中)并且className为“js-info-pop-up”。任何偏差都可能影响xPath,因为它相对于currentElement

  //List products that have class-cf
  List<WebElement> listProduct = driver.findElements(By.xpath("//div/div[@class='accordion-content cf']/div[@class='cf']"));

  for(WebElement eachElem:listProduct)
     {   
      System.out.println("Searching for the exact element:");
      if ( eachElem.getText().contains(TicketName))
          {
           //Identify the button to click on
           WebElement button = eachElem.findElement(By.xpath(".//a/span[@class='js-info-pop-up']"));
           Thread.sleep(500);
           button.click();
           break; //Break out of iteration.    
          }        
     }

答案 3 :(得分:0)

我找到了你的网站......:)

我通常接近这样的任务的方法是抓住一个外部元素,其中包含我关心每个项目的所有东西。在这种情况下,正如您所提到的,我们正在寻找div class="cf"。一旦我得到了#34;容器&#34;我开始寻找我关心的孩子元素。在这种情况下,票证名称和购买地点的两个h3标签。一旦我将票证名称与我要查找的票证名称进行比较并确保购买地点在线,我点击添加到购物篮链接和关闭按钮(两者都是儿童)。

以下是工作代码。您可能需要在开头添加等待。该网站有时似乎很慢,有时搜索会在前几个项目由于某种原因完全加载之前开始。我会把它留给你弄清楚。

driver.get("https://www.stagecoachbus.com/regionaltickets/yorkshire/rotherham/megarider");

// close the Please set your location popup
driver.findElement(By.cssSelector("#location-overlay > a.close-icon.js-close-overlay")).click();

String desiredTicketName = "22X 7 day megarider"; // read this from sheet
System.out.println("Looking for: " + desiredTicketName);
WebDriverWait wait = new WebDriverWait(driver, 10);
List<WebElement> ticketContainers = wait
        .until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("div[class='cf']")));
for (WebElement ticketContainer : ticketContainers)
{
    List<WebElement> h3s = ticketContainer.findElements(By.tagName("h3"));
    String currentTicketName = h3s.get(0).getText();
    String currentPurchaseLocation = h3s.get(1).getText();
    if (currentTicketName.contains(desiredTicketName) && currentPurchaseLocation.contains("Smart - online"))
    {
        // found the ticket and it's sold online

        // click Add to basket
        ticketContainer.findElement(By.cssSelector("a.submit-btn")).click();

        // click Close
        wait.until(ExpectedConditions.visibilityOfNestedElementsLocatedBy(ticketContainer, By.cssSelector("a.close-icon"))).get(0)
                .click();

        break;
    }
}