下拉框元素定位

来源:互联网 发布:linux 查看系统空间 编辑:程序博客网 时间:2024/06/05 18:51

转载自:http://www.cnblogs.com/tobecrazy/p/4752684.html

去哪儿网输入框三种输入方式(selenium webdriver 干货)


在机票预定的页面,输入出发城市和到达城市输入框的时候, 发现直接使用sendkeys不好使,

大部分情况出现输入某城市后没有输入进去, 经过几天的研究,发现可以采取三种方式:

1. 先点击输入框,待弹出 城市选择框之后,点击相应的城市

2. 缓慢输入城市的缩略字母或者城市的名字的部分,会显示出待选城市的下拉列表,进而从下拉列表中选择相应的城市.

3. 直接执行 js脚本对input的value设置为想要的值

首先说一下第三种方式:

   

    JavascriptExecutor js = (JavascriptExecutor) driver;        js.executeScript("arguments[0].value=\"北京\"", from_inpox);

 执行效果最好,

22:35:34.885 INFO - Executing: [execute script: arguments[0].value="北京", [[[Ch
romeDriver: chrome on XP (6452a4a961be7bffa2af9d1b63f3d111)] -> xpath: //div[@id
='js_flighttype_tab_domestic']//input[@name='fromCity']]]])

如上图所演示,两种方式均是用户真实行为。

采取第一种方式:

  • 首先定位到输入框
  • 点击输入框
  • 从弹出的热门城市框中点击所需要的城市
复制代码
WebElement from_inpox = driver.findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='fromCity']"));Actions actions = new Actions(driver);actions.moveToElement(from_inpox).click().perform();driver.findElement(By.xpath("//div[@data-panel='domesticfrom-flight-hotcity-from']//a[@class='js-hotcitylist' and text()='西安']")).click();
复制代码

这里我并没有直接使用click, 而是使用Actions,原因是我在对到达城市操作时,发现经常报element can't be clicked这样的错误,

大意是,当要点击到达城市输入框,其实是被上层的元素遮挡,没法使用click方法,但是可以使用Actions的moveToElement方法之后可以click

或者采取滚动到该元素,调用JS

JavascriptExecutor jse = (JavascriptExecutor) driver;jse.executeScript("arguments[0].scrollIntoView()",element);

之后就可进行click操作.

如果使用第二种方法,就会遇到一个很大的问题:

  如何定位到JS生成的下拉列表的城市?Firebug定位之前列表就消失!

看上去很难哈,反复尝试无所成, 最后突然想起既然是JS生成的,何不使用浏览器的JS debug功能,设置断点一步一步

果不其然,药到病除。nice job~

思路有了,跟我一起做,点开firebug ,切换到“脚本”界面,首先在输入框输入单字母s,待弹出下拉列表后,单击左侧的插入断点操作

你会发现该下拉框被冻结,不错呦,之后切换到html界面进行定位。

不光是去哪网,像百度输入框也可以采取这样的办法,JS设置断点,js的弹出框,弹出菜单就会冻结.

接下来我的输入就是选择下拉菜单中所需城市:

复制代码
        from_inpox.clear();        from_inpox.sendKeys("BJ");        Thread.sleep(8000);        By bj=new By.ByXPath("//div[@class='qcbox-fixed js-suggestcontainer']//td[contains(text(),'北京')]");        if(isElementPresent(driver,bj,20))        {            driver.findElement(bj).click();        }
复制代码

所要注意的是,下拉菜单中未必弹出那么快,需要做一次等待,在选择下拉菜单的时候需要做一次判断,当然这个判断方法是使用WebDriverWait

复制代码
/**     * @author Young     * @param driver     * @param by     * @param timeOut     * @return     */    public static boolean isElementPresent(WebDriver driver, final By by, int timeOut) {        WebDriverWait wait = new WebDriverWait(driver, timeOut);        boolean isPresent = false;        isPresent = wait.until(new ExpectedCondition<WebElement>() {            @Override            public WebElement apply(WebDriver d) {                return d.findElement(by);            }        }).isDisplayed();        return isPresent;    }
复制代码

依然不够完美,为什么这么说,如果元素没有出现,并不是返回的false而是直接抛异常,并不是期望的,所以修改为findElements

如果找不到,返回List长度必然为0,进而返回false而不是抛出异常

复制代码
/**     * @author Young     * @param driver     * @param by     * @param timeOut     * @return     * @throws InterruptedException     */    public static boolean isElementPresent(WebDriver driver, final By by,            int timeOut) throws InterruptedException {        boolean isPresent = false;        Thread.sleep(timeOut * 1000);        List<WebElement> we = driver.findElements(by);        if (we.size() != 0) {            isPresent = true;        }        return isPresent;    }
复制代码

 

测试步骤:

1.选择出发城市-> 北京

  到达城市->上海

  选择今天之后的七天

  点击search button

2.选择某带“每段航班均需缴纳税费” 的订单

复制代码
public static void main(String[] args) throws InterruptedException {        WebDriver driver = DriverFactory.getChromeDriver();        driver.get("http://flight.qunar.com/");        driver.manage().window().maximize();        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);        WebElement from_inpox = driver                .findElement(By                        .xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='fromCity']"));        WebElement to_inpox = driver                .findElement(By                        .xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='toCity']"));        WebElement from_date = driver                .findElement(By                        .xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='fromDate']"));        WebElement sigleWayCheckBox = driver                .findElement(By                        .xpath("//div[@id='js_flighttype_tab_domestic']//input[@class='inp_chk js-searchtype-oneway']"));        if (!sigleWayCheckBox.isSelected()) {            sigleWayCheckBox.click();        }        from_inpox.clear();        from_inpox.sendKeys("BJ");        Thread.sleep(8000);        By bj = new By.ByXPath(                "//div[@class='qcbox-fixed js-suggestcontainer']//td[contains(text(),'北京')]");        if (isElementPresent(driver, bj, 20)) {            driver.findElement(bj).click();        }        to_inpox.clear();        to_inpox.sendKeys("SH");        Thread.sleep(8000);        By sh = new By.ByXPath(                "//div[@class='qcbox-fixed js-suggestcontainer']//td[contains(text(),'上海')]");        if (isElementPresent(driver, sh, 20)) {            driver.findElement(sh).click();        }        // Actions actions = new Actions(driver);        // actions.moveToElement(from_inpox).click().perform();        // driver.findElement(        // By.xpath("//div[@data-panel='domesticfrom-flight-hotcity-from']//a[@class='js-hotcitylist' and text()='西安']"))        // .click();        // driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);        // driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);        // actions.moveToElement(to_inpox).click().perform();        // driver.findElement(        // By.xpath("//div[@data-panel='domesticto-flight-hotcity-to']//a[@class='js-hotcitylist' and text()='北京']"))        // .click();        // driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);        // driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);        from_date.clear();        from_date.sendKeys(getDateAfterToday(7));        WebElement search = driver                .findElement(By                        .xpath("//div[@id='js_flighttype_tab_domestic']//button[@class='btn_search']"));        search.submit();        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);        WebElement page2 = driver.findElement(By                .xpath("//div[@id='hdivPager']/a[@value='2']"));        JavascriptExecutor jse = (JavascriptExecutor) driver;        jse.executeScript("arguments[0].scrollIntoView()", page2);        page2.click();        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);        driver.findElement(                By.xpath("(//div[@class='avt_trans']//p[contains(text(),'每段航班均需缴纳税费')]/ancestor::div//div[@class='a_booking']/a)[3]"))                .click();        driver.findElement(                By.xpath("//div[@id='flightbarXI883']//div[@class='t_bk']/a"))                .click();    }    public static String getDateAfterToday(int dateAfterToday) {        Calendar cal = Calendar.getInstance();        cal.add(Calendar.DATE, +dateAfterToday);        System.out.println(cal.getTime().toString());        Date date = cal.getTime();        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");        System.out.println(df.format(date));        return df.format(date);    }    /**     * @author Young     * @param driver     * @param by     * @param timeOut     * @return     * @throws InterruptedException     */    public static boolean isElementPresent(WebDriver driver, final By by,            int timeOut) throws InterruptedException {        boolean isPresent = false;        Thread.sleep(timeOut * 1000);        List<WebElement> we = driver.findElements(by);        if (we.size() != 0) {            isPresent = true;        }        return isPresent;    }
复制代码

效果如下:

  

   

    


0 0