我被分配了一个繁琐的任务,就是要给100个相同的站点做同样的配置。曾经就有做过相同的事,那时还不会写脚本,全靠手动配置。机械的配置了两天的时间,身体感觉被掏空。所以这次我决定还是写一个脚本自动的进行配置。

一、了解Puppeteer

中文版资料:https://juejin.im/entry/59ad6c4f5188250f4850dccc

官方文档(英文):https://github.com/GoogleChrome/puppeteer

Puppeteer的API(英文):https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#

二、环境

只安装了node环境

三、开发阶段

3.1 初始化项目

引用了https://juejin.im/entry/59ad6c4f5188250f4850dccc

项目都是以创建文件夹开始。

  $ mkdir thal
$ cd thal

初始化 NPM,填入一些必要的信息。

  $ npm init

安装 Puppeteer。由于 Puppeteer 并不是稳定的版本而且每天都在更新,所以如果你想要最新的功能可以直接通过 GitHub 的仓库安装。

  $ npm i --save puppeteer

Puppeteer 包含了自己的 chrome / chromium 用以确保可以无界面地工作。因此每当你安装/更新 puppeteer 的时候,他都会下载指定的 chrome 版本。

3.2 编码

3.2.1 工程的目录结构

node_modeles中的内容是从git上拉下来的,src文件夹写得是我自己的代码,我执行的是addConfig里面的文件,common中是一些基础性配置,contentHub配置内容较多,所以我另建了一个contentHub文件夹。

3.2.2 common.js文件写的是常用的功能函数,这个是可以通用的。之前我不是说实现不了全选的功能吗,其实可以调用common中的setOption函数实现全选的功能

 const config = require('./config');

 //根据选择器sel选择id为val的子项
async function setOption(page, sel, val) {
await page.evaluate((sel, val) => {
document.querySelector(`${sel} > option[value="${val}"]`).selected = true;
element = document.querySelector(sel);
var event = new Event('change', { bubbles: true });
event.simulated = true;
element.dispatchEvent(event);
}, sel, val);
} //在id为sel的输入框中输入val
async function setTextVal(page, sel, val) {
await page.evaluate((sel, val) => {
document.querySelector(sel).value = val;
element = document.querySelector(sel);
var event = new Event('change', { bubbles: true });
event.simulated = true;
element.dispatchEvent(event);
}, sel, val);
} //判断选择器是否存在
async function isExist(page, selector) {
var is = await page.evaluate((sel) => {
const element = document.querySelector(sel);
if (!element) {
return false;
} else {
return true;
}
}, selector); return is;
} //导入单个配置
async function importSingleConfiguration(page, configType, configContent) {
const confirmBtn = 'input[value="Confirm"]';
const configTypeSel = '#edit-config-type';
await setOption(page, configTypeSel, configType);
await page.click('#edit-import');
await setTextVal(page, '#edit-import', configContent);
await page.click('#edit-submit');
await page.waitForNavigation(); const is = await isExist(page, confirmBtn);
if (is) {
await page.click(confirmBtn);
await page.waitForNavigation();
await page.waitFor(3 * config.stepWait);
}
} //设置checkbox中子项的值
async function setCheckBoxVal(page, sel, val) {
await page.evaluate((sel, val) => {
document.querySelector(sel).checked = val;
element = document.querySelector(sel);
var event = new Event('change', { bubbles: true });
event.simulated = true;
element.dispatchEvent(event);
}, sel, val);
} module.exports = {
setOption: setOption,
setTextVal: setTextVal,
importSingleConfiguration: importSingleConfiguration,
isExist: isExist,
selectAll: selectAll,
setCheckBoxVal: setCheckBoxVal, }

3.2.3 config.js文件中申明了许多基础性配置

我要跳转的网站url,登录的用户名和密码,站内页面跳转的路径等信息都配置在这个文件里面

const baseUrlArray = [
{
url: '',
langcode: '',
},
];
const baseUrl = baseUrlArray[0].url; const getUrl = (index) => {
const baseUrl = baseUrlArray[index].url;
return {
hubConnection: `${baseUrl}/example`,
};
} const getLangCode = (index) => {
return baseUrlArray[index].langcode;
} module.exports = {
secondWait: 1000,
stepWait: 5000,
username: '',
password: '',
credentials: {
username: '',
password: '',
},
baseUrl: baseUrl,
baseUrlArray: baseUrlArray,
urls: getUrl(0),
getUrl: getUrl,
getLangCode: getLangCode,
}

3.2.4 login.js

 const config = require('./config');

 async function login(page, url = null) {

   //fill authenticate user name and password
await page.authenticate(config.credentials); // goto login page
await page.goto(url ? url : config.urls.login);
const agreeButton = await page.$('#block-popup .btn');
await agreeButton.click(); //fill admin user name and password
await page.focus('#edit-name');
await page.keyboard.type(config.username);
await page.focus('#edit-pass');
await page.keyboard.type(config.password); const inputElement = await page.$('#edit-submit');
await inputElement.click(); await page.waitForNavigation();
} module.exports = login;

3.2.5 好了,登录成功了

四、收获

1.需要被其它页面引用的函数,常量必须要在module.exports={}中申明

2.headles: false是设置自动化操作是可视化的

3.在输入框中输入值并覆盖原有的值:

4.调用其他页面函数的声明:const common = require('./common');

五、疑惑

1.关于全选的功能,puppeteer并不支持全选,虽然官方文档上面说了linux和windows支持全选,但是我的linux系统没有任何反应,估计并不支持。补充一下,我这里说的是实现不了ctrl+A的全选功能。

Puppeteer——自动化脚本设计的更多相关文章

  1. Robot Framework测试框架用例脚本设计方法

    Robot Framework介绍 Robot Framework是一个通用的关键字驱动自动化测试框架.测试用例以HTML,纯文本或TSV(制表符分隔的一系列值)文件存储.通过测试库中实现的关键字驱动 ...

  2. 《手把手教你》系列基础篇(五)-java+ selenium自动化测试- 创建首个自动化脚本(详细教程)

    1.简介 前面几篇宏哥介绍了两种(java和maven)环境搭建和三大浏览器的启动方法,这篇文章宏哥将要介绍第一个自动化测试脚本.前边环境都搭建成功了,浏览器也驱动成功了,那么我们不着急学习其他内容, ...

  3. Automation Framework Design 自动化框架设计思想

    从2007年到2017年,十年内自动化测试工具层出不穷,各种工具在运用一段时间之后,各个公司都会有测试架构师对于目前的自动化测试工具进行框架定制设计. 从惠普2007年GDCC推出的的WebDrivi ...

  4. LoadRunner脚本设计、场景设计和结果分析

    本次笔记主要记录LoadRunner脚本设计.场景设计和结果分析   1. 脚本设计       录制模式            手工模式:插入步骤.手动编写       1.1  脚本增强:     ...

  5. Eclipse+Selenium自动化测试脚本设计V1.0

    Eclipse+Selenium自动化测试脚本设计V1.0 http://www.docin.com/p-803032251.html

  6. VS2010+Selenium测试脚本设计

    VS2010+Selenium测试脚本设计 http://www.docin.com/p-755903506.html

  7. CYQ.Data V5 分布式自动化缓存设计介绍(二)

    前言: 最近一段时间,开始了<IT连>创业,所以精力和写的文章多数是在分享创业的过程. 而关于本人三大框架CYQ.Data.Aries.Taurus.MVC的相关文章,基本都很少写了. 但 ...

  8. 自动化脚本中click()或sendKeys()没有反应

    前提: 排除xpath引用错误或元素的xpath每次都不同的情形. 问题描述 自动化脚本中click()方法和sendKeys()方法报错, 返回异常InvocationTargetException ...

  9. appium-desktop录制脚本二次开发,生成我司自动化脚本

    目的 通过对appium-desktop脚本录制功能进行二次开发,使录制的java脚本符合我司自动化框架要求. 实现步骤 1.增加元素名称的输入框 由于ATK(我司自动化测试框架)脚本中元素是以“ap ...

随机推荐

  1. [luoguP1220] 关路灯(DP)

    传送门 如果去关某一个灯,那么途中经过的灯都能关闭,那么就是连续一段区间,区间DP. f[i][j][0] 表示关完 i, j 这个区间且在 i 这个位置 f[i][j][1] 表示关完 i, j 这 ...

  2. P - FatMouse and Cheese 记忆化搜索

    FatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension ...

  3. Ubuntu 16.04安装Meld文件比对工具替代Beyond Compare

    Beyond Compare是商业软件,不建议使用,下载地址:http://www.scootersoftware.com/download.php.下载完直接运行或者通过dpkg安装即可. 其实Li ...

  4. Spring Tool Suite(STS)启动时出现错误:Java was started but returned exit code=13问题解决

    Spring Tool Suite(STS)是开发Spring的套件,也就是一个Eclipse,在之上增加了对Spring框架的支持,使其能快速的开发Spring. 错误如下: 解决办法: 如果系统安 ...

  5. 演练:使用VS2010 C# 创作简单的多线程组件

    BackgroundWorker 组件取代了 System.Threading 命名空间并添加了功能:但是,可以选择保留 System.Threading 命名空间以实现向后兼容并供将来使用.有关更多 ...

  6. ckeditor 设置含有html标签的值

    ckeditor 设置含有html标签的值 需要使用ajax请求拿到那个字符串,然后用editor.setData(text);

  7. 关于OleDB连接Excel的Extended Properties(扩展属性)HDR=YES; IMEX=2个人理解心得

    近期在用C#写一个创建Excel并将数据导出到Excel的WinForm程序, 让我对OleDB连接Excel的Extended Properties(扩展属性)HDR=YES; IMEX=2有了深刻 ...

  8. HR系统-人员申请单

    部门在人员缺失时,须要进行人员申请, 申请会涉及到单据的建立及审核.单据建立界面例如以下:

  9. Linux下使用Vi是方向键变乱码 退格键不能使用的解决方法

    在Linux下编辑一些文件.这就涉及到了vi这个编辑器了.在Linux下,初始使用vi的时候有点问题.就是在编辑模式下使用方向键的时候,并不会使光标移动,而是在命令行中出现[A [B [C [D之类的 ...

  10. Cisco VPP(1) 简单介绍

    一.简单介绍 VPP全称Vector Packet Processing.是Cisco2002年开发的商用代码. 2016年2月11号,Linux基金会创建FD.io项目.Cisco将VPP代码的开源 ...