《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)

简介: 【5月更文挑战第2天】在自动化测试过程中,经常会遇到处理日期控件的点击问题。宏哥之前分享过一种方法,但如果输入框是`readonly`属性,这种方法就无法奏效了。不过,通过修改元素属性,依然可以实现自动化填写日期。首先,定位到日期输入框并移除`readonly`属性,然后使用`sendKeys`方法输入日期。这样,即使输入框设置了`readonly`,也能成功处理日期控件。

1.简介

  理想很丰满现实很骨感,在应用selenium实现web自动化时,经常会遇到处理日期控件点击问题,手工很简单,可以一个个点击日期控件选择需要的日期,但自动化执行过程中,完全复制手工这样的操作就有点难了。宏哥上一篇已经讲解了如何处理日历时间控件,但是对于第一种方法可能会遇到输入框是readonly的情况,那么第一种方法就不适用了,但是只要我们稍微的变通地处理一下,就又可以使用了。

2.问题

宏哥第一种方法地思路就是把它当做输入框,直接输入日期即可,想法是很美好的,但是有时候实行起来却不执行,这个时候我们就要仔细去看看前端的代码了,代码如下:

<div class="col-lg-3 form-input">

 <input id="createTime" class="form-control" type="text" readonly="readonly" name="tatsudoDate" onclick="WdatePicker()" aria-required="true">

</div>

从上边的代码可以看出属性readonly人家根本不允许你输入,你就行不通了。

3.想法

既然这样了,我们就稍微变通一下,不要一条道走到黑。这个时候我们可以移除readonly的属性,问题就轻轻松松解决了,代码如下:

String js = "document.getElementById('createTime').removeAttribute('readonly')"; // 原生js,移除属性

((JavascriptExecutor)driver).executeScript(js); //将driver强制转换为JavascriptExecutor类型

driver.findElement(By.id("createTime")).sendKeys("2016-08-24"); //输入日期

4.注意

代码里面一定要记得导入这个方法(一般代码编辑器eclipse都会报错提示)虽然有提示,但是宏哥在这里还是提示一下,不要导错包了。:

import org.openqa.selenium.JavascriptExecutor;

5.项目实战

网上找了半天也没有找到这样的例子,以前12306的日历是这种。最近升级了,已经不是这种了。不找了索性宏哥自己在本地做一个这样的小demo给小伙伴或者童鞋们来演示一下。

注:本文演示的数据大家可以在公众号后台回复 宏哥38,在java+selenium->38 文件夹领取。

5.1代码准备

5.1.1前端HTML代码

前端HTML代码如下:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

   <title></title>

   <script src="dateJs.js"></script>

   <link rel="stylesheet" type="text/css" href="date.css">  

</head>

<body>

   <div id="wrapper" style="position: relative;top: 100px;left:600px;">

       <button class="button1"><a id="myAnchor" href="https://www.cnblogs.com/du-hong/">北京-宏哥</a></button></br>

       <input type="text" id="Dateinput" readonly=""/>

       <div class="calendar" id="calender" style="display: none;">

       </div>

   </div>

</body>

</html>

5.1.2CSS样式

HTML滑块CSS样式代码如下:

* {

   margin: 0;

   padding: 0;

}


body {

   font-size: 13px;

}


.calendar {

   width: 330px;

}


.calendar .title {

   position: relative;

   width: 100%;

   height: 30px;

   line-height: 30px;

   background: #17a4eb;

}


.title div {

   position: absolute;

}


.prev {

   left: 10px;

}


.now {

   left: 40%;

}


.next {

   right: 10px;

}


input {

   height: 30px;

   width: 326px;

}


table {

   width: 100%;

   border-collapse: collapse;

}


table th {

   border: 1px solid #ccc;

}


table td {

   text-align: center;

   border: 1px solid #ccc;

}


.red {

   background-color: #a1cbdb;

}


.blue {

   background-color: #e4e3e3;

}


.button1 {

   background-color: #f44336;

   border: none;

   color: white;

   padding: 15px 32px;

   text-align: center;

   text-decoration: none;

   display: inline-block;

   font-size: 28px;

   margin-bottom: 100px;

   text-decoration: none;

   color: white;

}


#myAnchor {

   text-decoration: none;

   color: white;

}

5.1.3日历JS

日历JS代码如下:

window.onload = function () {

   //获取日期 输入框

   var oInput = document.getElementById('Dateinput');

   //获取日历

   var oCalender = document.getElementById('calender');

   //获取当前日期

   var oDate = new Date();

   //获取当年 年

   var year = oDate.getFullYear();

   //获取当前 月

   var month = oDate.getMonth() + 1;


   //日历框不能重复创建

   var flag = false;

   //日期输入框 获取焦点时 加载日历

   oInput.onfocus = function () {

       showDate(year, month);

   }


   //显示日历

   function showDate(year, month) {

       if (false == flag) {

           //1.日历标题

           var oTitle = document.createElement('div');

           oTitle.className = 'title';


           //1.1日历标题文本

           var prevM = 0;

           var nextM = 0;


           prevM = month - 1;

           nextM = month + 1;


           //当月份为1时 上一个月为12

           if (month == 1) {

               prevM = 12;

           }//当月份为12时 下一个月为1

           else if (month == 12) {

               nextM = 1;

           }


           var titleHtml = "";

           titleHtml += '<div class="prev" id="prev"><span>';

           titleHtml += prevM + '</span>月</div>';

           titleHtml += '<div class="now">';

           titleHtml += '<span class="span">';

           titleHtml += year;

           titleHtml += '</span>年';

           titleHtml += '<span class="span">' + month;

           titleHtml += '</span>月</div>';

           titleHtml += '<div class="next" id="next"><span>';

           titleHtml += nextM + '</span>月</div>';


           oTitle.innerHTML = titleHtml;

           //将日历标题 拼接到日历

           oCalender.appendChild(oTitle);


           //1.2获取日历 表头元素(以便添加事件)

           var oSpans = oCalender.getElementsByTagName('span');

           var prevMonth = oSpans[0];

           var nextMonth = oSpans[3];

           var nowMonth = oSpans[2];

           var nowYear = oSpans[1];


           //2.创建星期 表头

           var otable = document.createElement('table');

           var othead = document.createElement('thead');

           var otr = document.createElement('tr');


           //2.1表头内容填充

           var arr = ['日', '一', '二', '三', '四', '五', '六'];

           for (var i = 0; i < arr.length; i++) {

               //创建th

               var oth = document.createElement('th');

               oth.innerHTML = arr[i];

               otr.appendChild(oth);

           }


           //2.2将表头加入到日历

           othead.appendChild(otr);

           otable.appendChild(othead);

           oCalender.appendChild(otable);


           //3.添加 当前日历 全部日期

           //3.1.先获得当期月 有多少天

           var dayNum = 0;

           if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {

               dayNum = 31;

           } else if (month == 4 || month == 6 || month == 9 || month == 11) {

               dayNum = 30;

           } else if (month == 2 && isLeapYear(year)) {

               dayNum = 29;

           } else {

               dayNum = 28;

           }


           //3.2.创建 6行7列 日期容器

           var otbody = document.createElement('tbody');

           for (var i = 0; i < 6; i++) {

               var otr = document.createElement('tr');

               for (var j = 0; j < 7; j++) {

                   var otd = document.createElement('td');

                   otr.appendChild(otd);

               }

               otbody.appendChild(otr);

           }

           otable.appendChild(otbody);


           //3.3获得 1号对应的是星期几

           //3.3.1.将当月1号赋值给日期变量

           oDate.setFullYear(year);

           //注意 js日期的月份是从0 开始计算

           oDate.setMonth(month - 1);

           oDate.setDate(1);


           //3.3.2.计算1号在第一行日期容器中的位置,依次给日期容器填充内容

           //注意 js中 getDay方法是获取当前日期是星期几

           var week = oDate.getDay();

           var otds = oCalender.getElementsByTagName('td');

           for (var i = 0; i < dayNum; i++) {

               otds[i + week].innerHTML = i + 1;

           }



           //让当前日期显示红色、后面的显示蓝色

           showColor(otds);

           //给左右月份绑定点击事件

           monthEvent();

           //判断最后一行是否全为空

           lastTr(otds);

           flag = true;

           document.getElementById('calender').style.display = "block";

       }

   }


   //判断是否是闰年

   function isLeapYear(year) {

       if (year % 100 == 0 && year % 400 == 0) {

           return true;

       } else if (year % 100 != 0 && year % 4 == 0) {

           return true;

       } else {

           return false;

       }

   }


   //判断日期容器最后一行是否有值

   function lastTr(otds) {

       var flag = true;

       for (var i = 35; i < 42; i++) {

           if (otds[i].innerHTML != '') {

               flag = false;

           }

       }

       //全是空的

       if (flag) {

           for (var i = 35; i < 42; i++) {

               otds[i].style.display = 'none';

           }

       }

   }


   //当前日期显示红色、前面的显示灰色

   function showColor(otds) {

       //当前日期

       var nowday = new Date().getDate();

       var nowyear = new Date().getFullYear();

       var nowmonth = new Date().getMonth();


       var oCalendar = document.getElementById("calender");

       ospans = oCalendar.getElementsByTagName('span');

       var contralYear = ospans[1].innerHTML;

       var contralMonth = ospans[2].innerHTML;


       var oindex = 0;

       for (var i = 0; i < otds.length; i++) {

           if (nowday == otds[i].innerHTML && nowyear == contralYear && nowmonth + 1 == contralMonth) {

               otds[i].className = 'red';

               oindex = i;

           }

       }

   }


   //给左右月份绑定点击事件

   function monthEvent() {

       var oCalendar = document.getElementById("calender");

       var prevDiv = document.getElementById("prev");

       var nextDiv = document.getElementById("next");


       var prevMonth = prevDiv.getElementsByTagName("span");

       var nextMonth = nextDiv.getElementsByTagName("span");


       prevDiv.onclick = function () {

           flag = false;

           oCalendar.innerHTML = '';

           showDate(year, parseInt(prevMonth[0].innerHTML));

       }


       nextDiv.onclick = function () {

           flag = false;

           oCalendar.innerHTML = '';

           showDate(year, parseInt(nextMonth[0].innerHTML));

       }


   }

}

6.自动化代码实现

6.1代码设计

6.2参考代码

package lessons;


import org.openqa.selenium.By;

import org.openqa.selenium.JavascriptExecutor;//注意不要倒错包

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;


/**

* @author 北京-宏哥

*

* 《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)

*

* 2021年10月31日

*/

public class calendar {


   public static void main(String[] args) {

       System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");

       WebDriver driver =new ChromeDriver();

       driver.manage().window().maximize();

       try {

           driver.get("file:///C:/Users/DELL/Desktop/test/Calendar/Calendar.html");

           Thread.sleep(5000);

           //执行方式

           JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;

           String js = "document.getElementById('Dateinput').removeAttribute('readonly')";

           jsExecutor.executeScript(js);//执行js,将readonly属性去掉后就可以写入日期

           driver.findElement(By.id("Dateinput")).clear();//写入前清除数据

           driver.findElement(By.id("Dateinput")).sendKeys("2021-11-11");//写入期望日期

           Thread.sleep(5000);

       } catch (Exception e) {

           e.printStackTrace();

       }finally {

           System.out.println("执行结束,关闭浏览器!提前祝大家光棍节快乐!!!");

           driver.quit();

       }

   }

}

6.3运行代码

1.运行代码,右键Run AS->Java Appliance,控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作,如下小视频所示:

7.小结

好了,时间不早了,今天就分享到这里,感谢大家耐心的阅读,这两篇其实是为后边文章的JavaScript的调用做一下铺垫和入门。


每天学习一点,今后必成大神-

往期推荐(由于跳转参数丢失了,所有建议选中要访问的右键,在新标签页中打开链接即可访问):


Appium自动化系列,耗时80天打造的从搭建环境到实际应用精品教程测试

Python接口自动化测试教程,熬夜87天整理出这一份上万字的超全学习指南

Python+Selenium自动化系列,通宵700天从无到有搭建一个自动化测试框架

Java+Selenium自动化系列,仿照Python趁热打铁呕心沥血317天搭建价值好几K的自动化测试框架

Jmeter工具从基础->进阶->高级,费时2年多整理出这一份全网超详细的入门到精通教程

Fiddler工具从基础->进阶->高级,费时100多天吐血整理出这一份全网超详细的入门到精通教程

Pycharm工具基础使用教程

相关文章
|
1天前
|
存储 JavaScript Java
《手把手教你》系列技巧篇(四十七)-java+ selenium自动化测试-判断元素是否显示(详解教程)
【5月更文挑战第11天】WebDriver 的 `isDisplayed()` 方法用于检查页面元素是否可见,如果元素存在于DOM中且可视,返回`true`,否则返回`false`。在自动化测试中,这个方法常用于验证元素是否真正显示在页面上。示例代码展示了如何使用 `isDisplayed()` 判断百度登录页面的特定错误提示文字是否出现。
10 1
|
2天前
|
JavaScript Java 测试技术
《手把手教你》系列技巧篇(四十六)-java+ selenium自动化测试-web页面定位toast-下篇(详解教程)
【5月更文挑战第10天】本文介绍了使用Java和Selenium进行Web自动化测试的实践,以安居客网站为例。最后,提到了在浏览器开发者工具中调试和观察页面元素的方法。
12 2
|
3天前
|
敏捷开发 测试技术 持续交付
深入理解自动化测试框架:以Selenium为例
【5月更文挑战第16天】 随着软件行业的迅猛发展,质量保障变得愈加重要。自动化测试作为确保软件质量的重要环节,其效率和可靠性受到了广泛关注。本文旨在深入探讨自动化测试框架的构建与优化,特别是以Selenium框架为例,分析其在实际应用中的优势、常见问题以及解决方案。通过具体案例分析,揭示如何提高自动化测试的稳定性和灵活性,从而更好地服务于敏捷开发和持续集成流程。
19 5
|
3天前
|
Web App开发 JavaScript 测试技术
《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)
【5月更文挑战第9天】本文介绍了在Appium中处理App自动化测试中遇到的Toast元素定位的方法。Toast在Web UI测试中也常见,通常作为轻量级反馈短暂显示。文章提供了两种定位Toast元素的技巧.
10 0
|
4天前
|
数据采集 Web App开发 数据挖掘
利用Python和Selenium实现定时任务爬虫
利用Python和Selenium实现定时任务爬虫
|
4天前
|
JavaScript 前端开发 测试技术
Python Selenium基本用法
Python Selenium基本用法
38 2
|
4天前
|
Web App开发 数据采集 前端开发
基于Python的Selenium详解:从入门到实践
基于Python的Selenium详解:从入门到实践
124 0
|
1天前
|
机器学习/深度学习 Java 数据挖掘
selenium的配置与基本使用(1),2024年最新网易Python面试必问
selenium的配置与基本使用(1),2024年最新网易Python面试必问
|
2天前
|
Web App开发 Ubuntu Linux
Linux无图形界面环境使用Python+Selenium实践
【5月更文挑战第1天】Linux无图形界面环境使用Python+Selenium实践
21 2
|
4天前
|
前端开发 Java 测试技术
selenium+python自动化测试--登录
selenium+python自动化测试--登录
12 2

热门文章

最新文章