在构建自动化套件的过程中,日期操作是一件很重要也很频繁的事情。有的日期控件的 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();
}


↙↙↙阅读原文可查看相关链接,并与作者交流