有时一级菜单下可能会有二级菜单,这时就需要对其下面的元素进行判断,如果使用webdriver原生的方法去获取未知的元素进行判断,显然是不可能的,因为webdriver本身就是基于明确的元素进行定位的,如果涉及到未知元素的判断,需要调用原生js或者Jquery

一般页面效果图会如下所示:

页面HTML源码:

<li class="active"><a data-toggle="collapse" class="nav-header" href="#menuL1_3">中标目录管理</a><ul class="nav nav-list menuL2 in" id="menuL1_3" style="height: auto;"><li><a target="mainFrame" class="nav-page" href="gbc/gbcRequest/main.do">我的申请</a></li><li class="active"><a data-toggle="collapse" class="nav-sub" href="#menuL3_2_2">审核管理</a><ul class="nav nav-list menuL3 in" id="menuL3_2_2" style="height: auto;"><li><a target="mainFrame" class="nav-page" href="gbc/gbcCheckPending/main.do">待审核</a></li><li><a target="mainFrame" class="nav-page" href="gbc/gbcAudited/main.do">已审核</a></li></ul></li><li><a target="mainFrame" class="nav-page" href="gbc/gbcBiddingCatalogue/main.do">中标目录</a></li><li><a target="mainFrame" class="nav-page" href="gbc/gpoTags/main.do">标签管理</a></li><li><a target="mainFrame" class="nav-page" href="gbc/gbcPublishedHistory/main.do">发布历史记录</a></li><li><a target="mainFrame" class="nav-page" href="gbc/gbcCatLog/main.do">操作日志</a></li><li><a target="mainFrame" class="nav-page" href="gbc/gbcProcurementCatalogue/main.do">带量采购目录</a></li></ul></li>

对菜单的所有切换与点击功能进行封装:

import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SelectMenue {
    private WebDriver driver;
    
/**
 *
 * @param
 * driver 构造方法参数,取所调用页面的driver
 */
    public SelectMenue(WebDriver driver) {
        this.driver = driver;
    }

    /**
     * 此方法用于只有二级菜单时的切换
     * @param
     * ParentElement 父菜单
     * @param
     * TargetElement 目标菜单
     */
    public void switchMenue(String ParentElement, String TargetElement) {
        WebDriverWait wait = new WebDriverWait(driver, 10);
        JavascriptExecutor js = (JavascriptExecutor) driver;
        driver.switchTo().defaultContent();
        // 展开主菜单
        WebElement parentElement = driver.findElement(By.linkText(ParentElement));
        // 获取父菜单的下一个兄弟节点,并将其强制转换成WebElement类型
        WebElement brotherElement = (WebElement) js.executeScript("return arguments[0].parentNode.children[1]",
                parentElement);
        // 当父菜单不是展开状态的时候就去点击父菜单
        if (!brotherElement.isDisplayed()) {
            parentElement.click();
            // 获取所有子菜单的集合,并不包含子菜单的子元素
            List<WebElement> elements = (List<WebElement>) js.executeScript("return arguments[0].children",
                    brotherElement);
            // 等待brotherElement下所有的li标签都变成可见
            wait.until(ExpectedConditions.visibilityOfAllElements(elements));
        }
        // 点击目标菜单
        brotherElement.findElement(By.linkText(TargetElement)).click();
        // 切换到主页面
        driver.switchTo().frame("mainFrame");
        wait.until(ExpectedConditions.presenceOfElementLocated(By.id("pageNavigationBar")));
    }

    /**
     * 此方法用于有三级菜单时的切换
     * @param
     * ParentElement 父菜单
     * @param
     * SecElement 二级菜单
     * @param
     * TargetElement 目标菜单
     */
    public void switchMenue(String ParentElement, String SecElement, String TargetElement) {
        WebDriverWait wait = new WebDriverWait(driver, 10);
        JavascriptExecutor js = (JavascriptExecutor) driver;
        //调用方法的第一件事,切换到默认文本,清除所有状态
        driver.switchTo().defaultContent();
        // 展开主菜单
        WebElement parentElement = driver.findElement(By.linkText(ParentElement));
        // 获取父菜单的下一个兄弟节点,并将其强制转换成WebElement类型
        WebElement brotherElement = (WebElement) js.executeScript("return arguments[0].parentNode.children[1]",
                parentElement);
        // 当父菜单不是展开状态的时候就去点击父菜单
        if (!brotherElement.isDisplayed()) {
            parentElement.click();
            // 获取所有二级菜单的集合,并不包含二级菜单的子元素
            List<WebElement> elements = (List<WebElement>) js.executeScript("return arguments[0].children",
                    brotherElement);
            // 等待brotherElement下所有的li标签都变成可见
            wait.until(ExpectedConditions.visibilityOfAllElements(elements));
        }
        // 获取二级菜单
        WebElement secElement = brotherElement.findElement(By.linkText(SecElement));
        // 获取二级菜单的下一个兄弟节点,并将其强制转换成WebElement类型
        WebElement secBrotherElement = (WebElement) js.executeScript("return arguments[0].parentNode.children[1]",
                secElement);

        if (!secBrotherElement.isDisplayed()) {
            // 展开二级菜单
            secElement.click();
            // 等待二级菜单下的所有li标签加载完成
            wait.until(ExpectedConditions.visibilityOfAllElements(secBrotherElement.findElements(By.tagName("li"))));
        }
        // 点击目标菜单
        secBrotherElement.findElement(By.linkText(TargetElement)).click();
        // 切换到主页面
        driver.switchTo().frame("mainFrame");
        wait.until(ExpectedConditions.presenceOfElementLocated(By.id("pageNavigationBar")));
    }
}

Webdriver实现对菜单栏的灵活切换功能,附上代码,类似的菜单栏切换可以自己封装的更多相关文章

  1. ViewPager取消左右滑动切换功能

    ViewPager取消左右滑动切换功能 最近做项目要求某种情况下ViewPager不能滑动,那么我们只需要重写这个方法就可以禁止ViewPager滑动 IndexViewPager.java: imp ...

  2. Android app应用多语言切换功能实现

    最近在做一个多语言切换的功能,类似于微信的语言切换,搜了下资料基本上都是以下这种: 1. 实现的效果 和微信类似,在设置界面打开切换语言的界面,选择语言后重启 HomeActivity,语言切换完成, ...

  3. ViewPager撤消左右滑动切换功能

    ViewPager取消左右滑动切换功能 最近做项目要求某种情况下ViewPager不能滑动,那么我们只需要重写这个方法就可以禁止ViewPager滑动 IndexViewPager.java: imp ...

  4. javascript回车完美实现tab切换功能

    javascript通过回车实现tab切换功能,最经有一个项目是给化工厂做的在使用的过程中需要输入大量的数据,使用的都是小键盘区,在以前都是通过excel录入数据的现在, 在网页上需要实现excel ...

  5. iOS应用内语言切换功能

    当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了.当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局.交互效果的转变,如微信,微博,QQ这类应用都有 ...

  6. JS 实现 Tab标签切换功能

    Tab标签切换 效果图: HTML部分: <div class="wrap">     <ul id="tag">       < ...

  7. 【百度地图API】暑假放假回老家——城市切换功能

    原文:[百度地图API]暑假放假回老家--城市切换功能 任务描述: 酸奶小妹放寒假啦,要从北京呼啦一下飞回重庆呢.现在百度地图API上不能直接切换城市,怎么办呢? 如何实现: 利用API先搜索到要去城 ...

  8. 为JQuery EasyUI 表单组件增加“焦点切换”功能

    1.背景说明 在使用 JQuery  EasyUI 各表单组件时,实际客户端页面元素是由 JQuery EasyUI 生成的,元素的焦点切换,虽然 Tab 键可以正常用,但顺序控制属性 tabinde ...

  9. vue实现tab切换功能

    最近用vue做一个页面的tab功能,经过一查找资料,没用路由,也没用动态组件,完美实现了tab切换功能,效果如下 下面是代码实现,这是模板 <article id="example&q ...

随机推荐

  1. js便利关联数组 及数组定义方式 分类

    "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv=& ...

  2. BAPI_GOODSMVT_CREATE 移动类型311 CODE = '04' 代码

    DATA: MAT_DOC LIKE BAPI2017_GM_HEAD_RET-MAT_DOC.      "物料凭证编号   DATA: GMHEAD LIKE BAPI2017_GM_H ...

  3. myeclipse连接数据库oracle

    package xsl; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStat ...

  4. 各个Maven仓库镜像(包括国内)

    各个Maven仓库镜像(包括国内) 衽孤魍墓 ゅ槭 众矿工唯唯诺诺我在旁哭笑不得原 宦蠃サ 骘猩池 粑涫汾滹 吧滔哌蹋 飑俗た 狃攵庾唾 想必是想挡住什么我想反正这笔筒也不是 翡蜮胼 娴左 ...

  5. 编写简单的爬虫从流行的Scrapy 框架讲起

    到目前为止,我们已经完成了向站点添加搜索和过滤的功能,并且我们已经可以向站点添加一些分类和产品信息.下面我们将考虑当尝试删除实体信息时会发生什么事情. 首先,向站点添加一个名为Test的新分类,然后再 ...

  6. 在eclipse中生成实体类

    1.在eclipse的windows中选中preferences在查询框中输入driver definition 2.点击add在Name/type中选中mysql jdbc driver 5.1然后 ...

  7. jQuery(4)—— jQuery中的事件

    jQuery中的事件 [加载DOM] 在常规的JavaScript代码中,通常使用window.onload方法,在jQuery中,使用的是$(document).ready()方法.极大地提高了we ...

  8. linux下svn目录管理

    linux 下安装的svn目录文件: /data/svndata/winne/conf/passwd 是配置用户密码的文件路径

  9. Okhttp设置http缓存,在没有网络的情况下加载http缓存里面的内容

    HTTP_CACHE_FILENAME为缓存地址根路径: private final String HTTP_CACHE_FILENAME = "HttpCache"; priva ...

  10. ggplot2 scale相关设置2—时间设置

    在scale设置中,常用的日期方面的设置函数包括: scale_x_date(),scale_y_date(),scale_x_datetime(),scale_y_datetime()   接下来, ...