通用技术 Web UI 自动化日期控件的处理

卡农Lucas · 2015年01月27日 · 最后由 卡农Lucas 回复于 2015年01月27日 · 2016 次阅读


在构建自动化套件的过程中,日期操作是一件很重要也很频繁的事情。有的日期控件的 div 层级结构复杂,同一个类型的日期控件在多个子系统中的表现形式也大相径庭。多数工程师为了避免重复的工作,会封装抽象一个方法或公共的库,还有部分会封装成单独的日期类库。

控件
下面是去啊的日期控件

下面是相关的 HTML

当然,有的日期控件元素的 id 为对应的日期。

代码逻辑
针对这种双日期的格式,我们如何在代码中进行处理输入?

  1. 输入目标日期。
  2. 判断目标日期与当前日期的差值
  3. 目标日期的年小于当前日期的年  小于的情况同大于(如下)
  4. 目标日期的年等于当前日期的年  月份相差除以 2,计算步长(即向后翻页的次数)
  5. 目标日期的年大于当前日期的年  计算当年剩余月份数量  计算从下一年开始到目标日期的月份  月份相加计算出总额并除以 2,得出向后翻页的次数。
  6. 循环点击翻页。
  7. 找到相应的 html 标签,点击即可。

实现
如果按照原逻辑实现,代码不够精炼。仔细研究,不难发现,逻辑主要是计算翻页的次数,且该计算逻辑是可以合并一个公式的。再仔细研究,当前日期小于大于目标期时,其绝对值与大于的情况相等,所以仅需乘以-1 即可。

最终版的代码

internal static void InternalSelectDeliveryDate(IWebDriver driver, DateTime date)
{
    DateTime expDate = ConvertToComparableDate(date);
    DateTime curDate = ConvertToComparableDate(DateTime.Now);

    int clicks = ((expDate.Year - curDate.Year) * 12 + (expDate.Month - curDate.Month)) / 2;
    Func<By, IWebElement> exp = (condition) => { return InternalFindElement(driver, condition, TimeSpan.FromSeconds(1)); };
    By by = By.ClassName("month_next");

    // We currently initialize the wrapDiv, previous, next element every time.
    // To avoid the invalid state exception.
    if (clicks < 0)
    {
        clicks = (-1) * clicks;
        by = By.ClassName("month_prev");
    }

    for (int i = 0; i < clicks; i++)
    {
        IWebElement navButton = exp(by);
        navButton.Click();
    }

    IWebElement targetLinkElem = InternalFindElement(driver, By.Id(expDate.ToString("yyyy-MM-dd")), TimeSpan.FromSeconds(1));
    targetLinkElem.Click();
}
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 2 条回复 时间 点赞

一般控件都是掉的第三方控件,逻辑部分不太可能有 bug,而且控件一旦变化,代码改动比较大,一般这种 js 模拟下即可,省时省力,不过楼主实现的也不错。

@luis 模拟人的操作要走逻辑的吧。更省力的可以直接输入文本。JS 这种看情况,不能一概而论,看场景,看测试目的。每次迭代回归,保不齐哪里出错。第三方控件也有 Bug,也要集成子系统里,而且控件的显示方式也有差异,展示上是程序员写的,逻辑上我会看一看,可以研究一下各种网站的 Date 控件。具体我不敢说是否适合每个团队的需要,关键是看场景。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册