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

news2025/1/12 7:02:07

1.简介

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

2.问题

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

<div class="col-lg-3 form-input">
  <input id="createTime" class="form-control" type="text" readonly="readonly" name="tatsudoDate" οnclick="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的调用做一下铺垫和入门。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1524222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【系统架构师】-第4章-信息安全技术

1、基础知识 五要素&#xff1a; (1)机密性&#xff1a;确保信息不暴露给未授权的实体或进程。 (2)完整性&#xff1a;只有得到允许的人才能修改数据&#xff0c;并且能够判别出数据是否已被篡改。 (3)可用性&#xff1a;得到授权的实体在需要时可访问数据&#xff0c;即攻击…

04:HAL----串口通信UART

目录 前言 一:串口协议 1:通信接口 2:串口通信 3:硬件电路 4:电平标准 5:串口参数及其时序 二:USART介绍 1:简历 2:USART框图 3:USART的基本结构 4:数据帧 5: 波特率发生器 6:数据模式 三:HAL A:HAL库回调 B:配置步骤 四:案例 A:STM32发送数据 B:STM32接收…

mybatis-plus笔记1

mybatis-plus笔记1 mybatis-plus快速入门基于Mapper接口的crud增强基于service的crud分页查询分页添加到自定义方法queryWrapper简单使用使用细节 updateWrapperlambdaWrapper mybatis-plus快速入门 pom.xml文件中导入相关依赖 application.yaml配置文件 MainApplication.java…

2024HVV行动-进军蓝中研判(log4j2、fastjson、Struts2、Shiro)

1、log4j2 特征&#xff1a; 恶意请求中包含 JNDI 协议地址&#xff0c;如"ldap://"、"rmi://"等&#xff0c;被 log4j2 解析为 JNDI 查找。 原理&#xff1a; 在日志输出中&#xff0c;未对字符进行严格的过滤&#xff0c;执行了 JNDI 协议加载的远程恶…

五、保持长期高效的七个法则(二)Rules for Staying Productive Long-Term(1)

For instance - lets say youre a writer.You have a bunch of tasks on your plate for the day, but all of a sudden you get a really good idea for an essay. You should probably start writing now or youll lose your train of thought.What should you do? 举例来说…

7.JavaWebHTML:构建数字世界的语言和结构

目录 导语&#xff1a; 第一部分&#xff1a;Web概念与作用 1.1 Web的定义 1.2 Web的作用 1.3 JavaWeb 第二部分&#xff1a;HTML概念与内容 2.1 HTML的定义 2.2 HTML的内容 第三部分&#xff1a;HTML的作用 3.1 HTML的作用 3.2 HTML在现代Web开发中的角色 …

弗洛伊德-华沙算法求任意两点之间的最短路径算法

对于弗洛伊德-华沙算法首先是要假设研究的图中是不包含有负边的,对于所给的图中的任意亮点v1,vm,假设两点之间存在一条连通路径,对于该路径中去掉头和尾节点,也就是v1,vm,剩下的节点也就称之为这条路径的过渡节点。为图中每个节点进行编号,然后如果图中有n个节点,那么…

WSL的使用记录(1) - 第一次尝试

wsl2下载的话会直接把Ubantu也安装到位&#xff0c;因此我们直接打开Ubantu&#xff0c;在搜索框直接搜索Ubantu&#xff0c;就会出现这个。 我们直接打开就好了。 这时有可能会出现以下文字: wsl: 检测到 localhost 代理配置&#xff0c;但未镜像到 WSL。NAT 模式下的 WSL 不…

【优化算法综述】一行代码实现16种优化算法,常用寻优算法合集及MATLAB快速实现,写好1个就等于写好了16个~

欢迎来到动物园&#xff01; 在已有的众多的优化算法里&#xff0c;生物的行为是研究者们最常模仿的对象&#xff0c;所以你就会经常看到狼啊、麻雀啊、鲸鱼啊&#xff0c;甚至还有小龙虾。 当然这些算法的解决思路都很优秀&#xff0c;而对优化算法的应用和改进&#xff0c;…

搜维尔科技:使用SenseGlove Nova手套操纵其“CAVE”投影室中的虚拟对象

创造了一种基于 PC 的创新型多边沉浸式环境&#xff0c;让参与者完全被虚拟图像和声音包围。 需要解决的挑战&#xff1a; 传统的 VR 系统往往缺乏真实的触摸反馈&#xff0c;限制了用户的沉浸感。AVR Japan 旨在通过将触觉技术融入到他们的 CAVE 系统中来应对这一挑战&#x…

指挥航空公司架次与延误率占比

打开前端Vue项目kongguan_web&#xff0c;创建前端 src/components/Delay.vue 页面&#xff0c;并添加柱状图与折线图叠加&#xff0c;设置双Y轴。 页面div设计&#xff0c;代码如下&#xff1a; <template><div><div class"home"><div id&qu…

短剧小程序软件开发首页接口转发到Selectpage

工具&#xff1a;用的是uniapp开发 技术栈&#xff1a;vue、nide..js、云开发 用时&#xff1a;20工作天 软件&#xff1a;Hb、微信开发者工具 <?php namespace app\api\controller; use app\common\controller\Api; /** * 首页接口 */ class Index extends Api { …

关于PXIE3U18槽背板原理拓扑关系

如今IT行业日新月异&#xff0c;飞速发展&#xff0c;随之带来的是数据吞吐量的急剧升高。大数据&#xff0c;大存储将成为未来数据通信的主流&#xff0c;建立快速、大容量的数据传输通道将成为电子系统的关键。随着集成技术和互连技术的发展&#xff0c;新的串口技术&#xf…

MySQL数据库定时备份

小伙伴们好&#xff0c;欢迎关注&#xff0c;一起学习&#xff0c;无限进步 文章目录 MySQL 定时备份方式一&#xff1a;简单版方式二&#xff1a;复杂版方式三&#xff1a;doker定时备份&#xff0c;根据备份数量删除方式四&#xff1a;不是 docker 安装备份4、配置定时任务补…

科研绘图二:箱线图(抖动散点)

R语言绘图系列—箱线图抖动散点 &#xff08;二&#xff09;: 科研绘图一&#xff1a;箱线图&#xff08;抖动散点&#xff09; 文章目录 R语言绘图系列---箱线图抖动散点&#xff08;二&#xff09;: 科研绘图一&#xff1a;箱线图&#xff08;抖动散点&#xff09; 前言一、…

C++学习基础版(一)

目录 一、C入门 1、C和C的区别 2、解读C程序 3、命名空间 4、输入输出 &#xff08;1&#xff09;cout输出流 &#xff08;2&#xff09;endl操纵符 &#xff08;3&#xff09;cin输入流 二、C表达式和控制语句 1、数据机构 特别&#xff1a;布尔类型bool 2、算数运…

java框架 2 springboot 过滤器 拦截器 异常处理 事务管理 AOP

Filter 过滤器 对所有请求都可以过滤。 实现Filter接口&#xff0c;重写几个方法&#xff0c;加上WebFilter注解&#xff0c;表示拦截哪些路由&#xff0c;如上是所有请求都会拦截。 然后还需要在入口处加上SvlterComponentScan注解&#xff0c;因为Filter是javaweb三大组件之…

深度学习pytorch——拼接与拆分(持续更新)

cat拼接 使用条件&#xff1a;合并的dim的size可以不同&#xff0c;但是其它的dim的size必须相同。 语法&#xff1a;cat([tensor1,tensor2],dim n) # 将tensor1和tensor2的第n个维度合并 代码演示&#xff1a; # 拼接与拆分 a torch.rand(4,32,8) b torch.rand(…

AI大浪潮,怎能少了国产HBM内存?

据有关报道显示&#xff0c;武汉新芯半导体制造有限公司&#xff08;XMC&#xff09;正在启动一项专注于开发和生产高带宽内存&#xff08;HBM&#xff09;的项目。 HBM作为一种关键的DRAM类型&#xff0c;对于人工智能&#xff08;AI&#xff09;和高性能计算&#xff08;HPC&…

基于springboot+vue的疗养院管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…