《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)
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的调用做一下铺垫和入门。
《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)的更多相关文章
- 《手把手教你》系列技巧篇(三十七)-java+ selenium自动化测试-日历时间控件-上篇(详解教程)
1.简介 我们在实际工作中,有可能遇到有些web产品,网页上有一些时间选择,然后支持按照不同时间段范围去筛选数据.网页上日历控件一般,是一个文本输入框,鼠标点击,就会弹出日历界面,可以选择具体日期.这 ...
- 《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...
- 《手把手教你》系列技巧篇(三十)-java+ selenium自动化测试- Actions的相关操作下篇(详解教程)
1.简介 本文主要介绍两个在测试过程中可能会用到的功能:Actions类中的拖拽操作和Actions类中的划取字段操作.例如:需要在一堆log字符中随机划取一段文字,然后右键选择摘取功能. 2.拖拽操 ...
- 《手把手教你》系列技巧篇(三十二)-java+ selenium自动化测试-select 下拉框(详解教程)
1.简介 在实际自动化测试过程中,我们也避免不了会遇到下拉选择的测试,因此宏哥在这里直接分享和介绍一下,希望小伙伴或者童鞋们在以后工作中遇到可以有所帮助. 2.select 下拉框 2.1Select ...
- 《手把手教你》系列技巧篇(二十八)-java+ selenium自动化测试-处理模态对话框弹窗(详解教程)
1.简介 在前边的文章中窗口句柄切换宏哥介绍了switchTo方法,这篇继续介绍switchTo中关于处理alert弹窗的问题.很多时候,我们进入一个网站,就会弹窗一个alert框,有些我们直接关闭, ...
- 《手把手教你》系列技巧篇(四十八)-java+ selenium自动化测试-判断元素是否可操作(详解教程)
1.简介 webdriver有三种判断元素状态的方法,分别是isEnabled,isSelected 和 isDisplayed,其中isSelected在前面的内容中已经简单的介绍了,isSelec ...
- 《手把手教你》系列技巧篇(十七)-java+ selenium自动化测试-元素定位大法之By css上卷(详细教程)
1.简介 CSS定位方式和xpath定位方式基本相同,只是CSS定位表达式有其自己的格式.CSS定位方式拥有比xpath定位速度快,且比CSS稳定的特性.下面详细介绍CSS定位方式的使用方法.xpat ...
- 《手把手教你》系列技巧篇(四十七)-java+ selenium自动化测试-判断元素是否显示(详解教程)
1.简介 webdriver有三种判断元素状态的方法,分别是isEnabled,isSelected 和 isDisplayed,其中isSelected在前面的内容中已经简单的介绍了,isSelec ...
- 《手把手教你》系列技巧篇(六)-java+ selenium自动化测试-阅读selenium源码(详细教程)
1.简介 前面几篇基础系列文章,足够你迈进了Selenium门槛,再不济你也至少知道如何写你第一个基于Java的Selenium自动化测试脚本.接下来宏哥介绍Selenium技巧篇,主要是介绍一些常用 ...
随机推荐
- Jmeter线程组设置
添加线程组:右键测试计划->添加->Threads->线程组 左侧树形标签栏中,显示标签信息. 选中线程组,右侧内容栏中显示线程组的相关信息. 名称:可以给线程组设置一个个性化的命名 ...
- Python调用函数带括号和不带括号的区别
1.不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不需等该函数执行完成 2.带括号(此时必须传入需要的参数),调用的是函数的return结果,需要等待函数执行完成的结果 如果函数本 ...
- springboot 运行出现错误 Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
原因是我将springboot启动类换到了另外一个方法中 出现了一个异常 后来发现因为我换了类但是忘记了换类名所以才报错 @ComponentScan @EnableAutoConfiguration ...
- LR虚拟用户已设置集合点,但controller无法设置集合点策略的解决方案
原文来自:https://blog.csdn.net/qq_34982914/article/details/90905030 学习loadrunner的过程中,肯定涉及集合点的添加,但是我们按照书上 ...
- P7046-「MCOI-03」诗韵【SAM,倍增,树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P7046 题目大意 给出一个长度为 \(n\) 的字符串,然后 \(m\) 次把它的一个子串加入集合.如果一个字符串 ...
- CF25E-Test【AC自动机,bfs】
正题 题目链接:https://www.luogu.com.cn/problem/CF25E 题目大意 给出三个串,然后求一个最短的串包含这三个串. \(1\leq |s_1|,|s_2|,|s_3| ...
- 使用jacob调用Windows的com对象,进行word、ppt等转换成ptf、html(二)
富文本转pdf : 注意:simsun.ttc 可以百度下载:http://www.pc6.com/softview/SoftView_100415.html package com.orangecd ...
- Cnblogs 主题设置
https://www.cnblogs.com/enjoy233/p/cnblogs-markdown-code-display-opt.html 复制: 右上角添加复制按钮:https://www. ...
- minikube addons enable ingress 启动错误
minikube addons enable ingress 启动错误 开启 minkube ingress 时错误 minikube addons enable ingress --alsologt ...
- Edit Step Ladders - UVA 10029
题意 题目链接(Virtual Judge):Edit Step Ladders - UVA 10029 题意: 如果单词 \(x\) 能通过添加.删除或修改一个字母变换为单词 \(y\),则称单词 ...