首页 > 其他分享 >Selenium进阶——解决web 自动化中上传文件的问题

Selenium进阶——解决web 自动化中上传文件的问题

时间:2023-09-27 11:34:20浏览次数:42  
标签:case web 进阶 KeyEvent SHIFT VK Selenium doType break


在做ui自动化测试中,经常会遇到上传文件或者图片的场景,通常的解决方案是自动化工具+autoIT,在这里我介绍一种

通过jdk自带api—— java.awt.Robot 来解决类似问题的方法。java.awt.Robot类主要用于模拟用户点击键盘上的按键,或者模拟用户敲击鼠标等动作。

在做web测试时,弹出窗口如下图所示:

 

Selenium进阶——解决web 自动化中上传文件的问题_上传文件

Windows上传文件对话框

 

对于打开上传文件框是input形式的控件可以用selenium 的方法:driver.findElement(By.id("")).sendKeys("文件路径")来完成上传操作;

如果不是,我们可以利用Robot类来解决该问题。核心思路:

1.打开弹出窗口后,光标在输入框内,然后使用键盘上的keycode写入上传文件具体信息

2.点击Tab键(光标移动到“所有文件”框中)

3.点击Tab键(光标移动到“打开”按钮上)

4.点击Enter键,完成上传文件操作。

注意:该方法不支持中文,因此文件路径和名称不能包括中文。

点击键盘按键核心代码如下:

robot.keyPress(keyCodes);

robot.keyRelease(keyCodes);

点击Tab键

robot.keyPress(KeyEvent.VK_TAB);

robot.keyRelease(KeyEvent.VK_TAB);

点击Enter键

robot.keyPress(KeyEvent.VK_ENTER);

robot.keyRelease(KeyEvent.VK_ENTER);

输入字符‘a’

robot.keyPress(KeyEvent. VK_A);

robot.keyRelease(KeyEvent. VK_A);

输入字符‘A’,需要Shift键的配合

robot.keyPress(KeyEvent.VK_SHIFT);

robot.keyPress(KeyEvent.VK_A);

robot.keyRelease(KeyEvent.VK_A);

robot.keyRelease(KeyEvent.VK_SHIFT);

更多的按键信息请参考:

https://docs.oracle.com/javase/8/docs/api/java/awt/event/KeyEvent.html

由于每次输入字符都需要调用robot.keyPress和robot.keyRelease方法,当处多字符写入的场景时效率太低,所以我们需要编写方便的API便于调用,核心代码如下:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import static java.awt.event.KeyEvent.*;
public class RobotKeyboard {
   private static RobotKeyboard uniqueInstance = null;
    private Robot robot;
   publicRobotKeyboard()throws AWTException {
        this.robot = new Robot();
   }
 
   public static synchronized  RobotKeyboardgetInstance()throws AWTException {
        if (uniqueInstance == null) {
            uniqueInstance = new RobotKeyboard();
        }
        return uniqueInstance;
    }
   //输入字符串
   public void typeWords(CharSequence characters) {
 
        int length = characters.length();
        for (int i = 0; i < length; i++) {
            char character = characters.charAt(i);
            typeChar(character);
        }
   }
 //输入特殊键盘按键
   public void typeKey(String p_string,int p_times) {
 
       if (p_string.equalsIgnoreCase("Tab"))
       doTypeLoop(KeyEvent.VK_TAB,p_times);
       else if (p_string.equalsIgnoreCase("Enter"))
       doTypeLoop(KeyEvent.VK_ENTER,p_times);
       else if (p_string.equalsIgnoreCase("Up"))
       doTypeLoop(KeyEvent.VK_UP,p_times);
       else if (p_string.equalsIgnoreCase("Down"))
       doTypeLoop(KeyEvent.VK_DOWN,p_times);
       else if (p_string.equalsIgnoreCase("Left"))
       doTypeLoop(KeyEvent.VK_LEFT,p_times);
       else if (p_string.equalsIgnoreCase("Right"))
       doTypeLoop(KeyEvent.VK_RIGHT,p_times);
       else if (p_string.equalsIgnoreCase("Shift"))
       doTypeLoop(KeyEvent.VK_SHIFT,p_times);
       else if (p_string.equalsIgnoreCase("ESC"))
       doTypeLoop(KeyEvent.VK_ESCAPE,p_times);
       else if (p_string.equalsIgnoreCase("Backspace"))
       doTypeLoop(KeyEvent.VK_BACK_SPACE,p_times);
       else doTypeLoop(0,p_times);
   }
 
   //输入常用单个字符
   public void typeChar(char character) {
        switch (character) {
        case 'a': doType(VK_A); break;
        case 'b': doType(VK_B); break;
        case 'c': doType(VK_C); break;
        case 'd': doType(VK_D); break;
        case 'e': doType(VK_E); break;
        case 'f': doType(VK_F); break;
        case 'g': doType(VK_G); break;
        case 'h': doType(VK_H); break;
        case 'i': doType(VK_I); break;
        case 'j': doType(VK_J); break;
        case 'k': doType(VK_K); break;
        case 'l': doType(VK_L); break;
        case 'm': doType(VK_M); break;
        case 'n': doType(VK_N); break;
        case 'o': doType(VK_O); break;
        case 'p': doType(VK_P); break;
        case 'q': doType(VK_Q); break;
        case 'r': doType(VK_R); break;
        case 's': doType(VK_S); break;
        case 't': doType(VK_T); break;
        case 'u': doType(VK_U); break;
        case 'v': doType(VK_V); break;
        case 'w': doType(VK_W); break;
        case 'x': doType(VK_X); break;
        case 'y': doType(VK_Y); break;
        case 'z': doType(VK_Z); break;
        case 'A': doType(VK_SHIFT, VK_A); break;
        case 'B': doType(VK_SHIFT, VK_B); break;
        case 'C': doType(VK_SHIFT, VK_C); break;
        case 'D': doType(VK_SHIFT, VK_D); break;
        case 'E': doType(VK_SHIFT, VK_E); break;
        case 'F': doType(VK_SHIFT, VK_F); break;
        case 'G': doType(VK_SHIFT, VK_G); break;
        case 'H': doType(VK_SHIFT, VK_H); break;
        case 'I': doType(VK_SHIFT, VK_I); break;
        case 'J': doType(VK_SHIFT, VK_J); break;
        case 'K': doType(VK_SHIFT, VK_K); break;
        case 'L': doType(VK_SHIFT, VK_L); break;
        case 'M': doType(VK_SHIFT, VK_M); break;
        case 'N': doType(VK_SHIFT, VK_N); break;
        case 'O': doType(VK_SHIFT, VK_O); break;
        case 'P': doType(VK_SHIFT, VK_P); break;
        case 'Q': doType(VK_SHIFT, VK_Q); break;
        case 'R': doType(VK_SHIFT, VK_R); break;
        case 'S': doType(VK_SHIFT, VK_S); break;
        case 'T': doType(VK_SHIFT, VK_T); break;
        case 'U': doType(VK_SHIFT, VK_U); break;
        case 'V': doType(VK_SHIFT, VK_V); break;
        case 'W': doType(VK_SHIFT, VK_W); break;
        case 'X': doType(VK_SHIFT, VK_X); break;
        case 'Y': doType(VK_SHIFT, VK_Y); break;
        case 'Z': doType(VK_SHIFT, VK_Z); break;
        case '`': doType(VK_BACK_QUOTE); break;
        case '0': doType(VK_0); break;
        case '1': doType(VK_1); break;
        case '2': doType(VK_2); break;
        case '3': doType(VK_3); break;
        case '4': doType(VK_4); break;
        case '5': doType(VK_5); break;
        case '6': doType(VK_6); break;
        case '7': doType(VK_7); break;
        case '8': doType(VK_8); break;
        case '9': doType(VK_9); break;
        case '-': doType(VK_MINUS); break;
        case '=': doType(VK_EQUALS); break;
        case '~': doType(VK_SHIFT, VK_BACK_QUOTE); break;
        case '!': doType(VK_EXCLAMATION_MARK); break;
        case '@': doType(VK_AT); break;
        case '#': doType(VK_NUMBER_SIGN); break;
        case '$': doType(VK_DOLLAR); break;
        case '%': doType(VK_SHIFT, VK_5); break;
        case '^': doType(VK_CIRCUMFLEX); break;
        case '&': doType(VK_AMPERSAND); break;
        case '*': doType(VK_ASTERISK); break;
        case '(': doType(VK_LEFT_PARENTHESIS); break;
        case ')': doType(VK_RIGHT_PARENTHESIS); break;
        case '_': doType(VK_UNDERSCORE); break;
        case '+': doType(VK_PLUS); break;
        case '\t': doType(VK_TAB); break;
        case '\n': doType(VK_ENTER); break;
        case '[': doType(VK_OPEN_BRACKET); break;
        case ']': doType(VK_CLOSE_BRACKET); break;
        case '\\': doType(VK_BACK_SLASH); break;
        case '{': doType(VK_SHIFT, VK_OPEN_BRACKET); break;
        case '}': doType(VK_SHIFT, VK_CLOSE_BRACKET); break;
        case '|': doType(VK_SHIFT, VK_BACK_SLASH); break;
        case ';': doType(VK_SEMICOLON); break;
        case ':': doType(VK_SHIFT, VK_SEMICOLON); break;
        case '\'': doType(VK_QUOTE); break;
        case '"': doType(VK_QUOTEDBL); break;
        case ',': doType(VK_COMMA); break;
        case '<': doType(VK_LESS); break;
        case '.': doType(VK_PERIOD); break;
        case '>': doType(VK_GREATER); break;
        case '/': doType(VK_SLASH); break;
        case '?': doType(VK_SHIFT, VK_SLASH); break;
        case ' ': doType(VK_SPACE); break;
        default:
            throw new IllegalArgumentException("Cannot type character " + character);
        }
   }
 
   //无需shift键配合的单字符输入的核心API
   private void doType(int keyCodes) {
    if(keyCodes==0)
    {
        return;
    }
    robot.keyPress(keyCodes);
    robot.keyRelease(keyCodes);
 }
 
   //循环输入键值
   private void doTypeLoop(int keyCodes,int times){
    if(keyCodes==0)
    {
        return;
    }
    for(int i=0;i<times;i++){
        robot.keyPress(keyCodes);
         robot.keyRelease(keyCodes);
    }
 
 }
   //需要shift键配合的单字符输入的核心API
   private void doType(int keyShit,int keyCodes) {
    if(keyCodes==0)
    {
        return;
    }
    robot.keyPress(keyShit);
    robot.keyPress(keyCodes);
    robot.keyRelease(keyCodes);
    robot.keyRelease(keyShit);
    }
}

 

使用代码如下:

public static void main(String[] args) throws AWTException {
    RobotKeyboard.getInstance().type("D:\\test\\test.png"); //输入要上传的文件
    RobotKeyboard.getInstance().typeKey("Tab", 2); //点击两次Tab键
    RobotKeyboard.getInstance().typeKey("Enter", 1);//点击一次Tab键
 
}

这里只提供了基础代码,大家可以根据项目实际需求进行改写!

标签:case,web,进阶,KeyEvent,SHIFT,VK,Selenium,doType,break
From: https://blog.51cto.com/liwen629/7622005

相关文章

  • 一张图搞定技术型测试工程师的进阶之路
    话不多说,一张图搞定!!! ......
  • 进阶Python,从编写Python函数开始!
    好多同学都有这样的疑惑,我学习了python的基础语法,那么具体应用该从哪里入手呢?首先大家要确定,代码必须用起来才能越来越熟练!读懂十行代码不如自己亲自上手遍写一行!代码想熟练最好的方法就是能够通过代码解决工作中的实际问题,例如完成UI自动化测试、接口测试、创建测试数据、构建测试......
  • MySQL进阶篇:第二章_二.二_索引结构
    2.2索引结构2.2.1概述MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种:索引结构描述B+Tree索引最常见的索引类型,大部分引擎都支持B+树索引Hash索引底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范......
  • MySQL进阶篇:第二章_二.一_索引概述
    2.1索引概述2.1.1介绍索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。2.1.2演示表结构及其数据如下......
  • MySQL进阶篇:第一章_一.五_MySQL存储引擎选择
    MySQL存储引擎选择在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。InnoDB:是Mysql的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作......
  • 干货!Playwright架构与Selenium 架构对比
    在Web测试自动化方面,Selenium多年来一直是行业的主导工具。但是,市场上还有许多其他自动化测试工具。Playwright是一种较新的工具,已经越来越受欢迎。网上有很多文章对二者进行对比,今天我从二者的架构角度进行一下对比分析!关于二者在其他方面的区别,我会在后面的文章中持续更新,......
  • 干货!一文搞定无头浏览器的概念以及在selenium中的应用
     无头浏览器无头浏览器,即HeadlessBrowser,是一种没有界面的浏览器。它拥有完整的浏览器内核,包括JavaScript解析引擎、渲染引擎等。与普通浏览器最大的不同是,无头浏览器执行过程中看不到运行的界面,但是我们依然可以用GUI测试框架的截图功能截取它执行中的页面。在这里强调一下......
  • 12-web前端轮播图案例 (小米商城)
    说明:轮播图在前端开发中是一种常见的元素,通常用于展示一系列的图片或者内容,并通过滑动或者点击的方式进行切换。使用JavaScript来实现轮播图有以下几个意义:提升用户体验:轮播图可以在有限的空间内展示更多的内容,为用户提供更多的信息。同时,轮播图也具有较好的视觉效果,可以吸引用......
  • Python的Selenium库:鼠标滚动和操作弹出窗口
    Selenium是一个用于自动化web应用测试的开源工具。通过Selenium,我们可以模拟真实用户的操作,如点击、输入、滚动页面等,来测试web应用的稳定性和可靠性。PythonSelenium库是Selenium的一个分支,可以方便地与Python语言结合使用。在PythonSelenium库中,元素定位和文本输入是最常用的......
  • webpack介绍
    (1).构建工具的作用:转换ES6语法.转换JSX.CSS前缀补全、预处理器.压缩混淆.图片压缩.1.静态模块打包器:将入口文件引入的各种资源=>chunk(块)=>less转换为css、es6转换为es5=>bundle(输出内容)将所有资源文件(js/css/html/less/json...)当做模块处理.根据模块的依赖......