前言
看网上大多提到Puppeteer都是用它来做自动化测试,爬虫等等,而我在看到这个工具的第一想法是,它能否帮我提高开发过程中使用工具的效率。
在我的工作环境中,线上服务查慢接口,看日志等等需要首先登录jumpserver,再一步步寻址找到我需要的工具,点开它,选择自己需要的服务查看日志,查看耗时等等,这个过程鼠标点击好多次,重复工作很多,我就想能否节省前面这些步骤的时间。
直接给出效果吧
以上效果除了登录时候需要输入下验证码,之后没有移动鼠标,都有代码自行完成,包括自动打开树状结构菜单,自动选择skywalking,自动在打开的界面点击确认,自动选择最近7天,自动选择我要选择的项目,自动切换模式。
当你平时工作中看个东西有一堆固定的前置操作的时候,就可以想到,是否可以用它节省你的时间
执行代码
json
import puppeteer from 'puppeteer';
(async () => {
// Launch the browser and open a new blank page
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
args: ['--start-maximized']
});
const context = browser.defaultBrowserContext();
// 要查看哪个项目的skywalking
let project = 'project-center';
// 设置默认权限
context.overridePermissions('https://jumpserver.xxx.com.cn/luna/', ['clipboard-read']);
const page = await browser.newPage();
await page.goto('https://jumpserver.xxx.com.cn/core/auth/login/?next=/luna/');
// await page.mouse.click(1389,383);
await page.waitForSelector('#id_username')
// 替换为用户名和密码输入框的选择器
await page.type('#id_username', '真实用户名');
await page.type('#password', '真实密码');
const captchaClassExists = await page.$('.captcha')
if(captchaClassExists){
await page.waitForSelector('#AssetTree_3_a');
}else{
await page.click('#login-form > div:nth-child(6) > button')
}
await new Promise(r => setTimeout(r, 1000));
const [elementHandle] = await page.$x('//*[@id="AssetTree_3"]');
if (elementHandle) {
await elementHandle.click();
}
await new Promise(r => setTimeout(r, 500));
await page.waitForSelector('#AssetTree_5')
await page.click('#AssetTree_5')
await new Promise(r => setTimeout(r, 500));
await page.waitForSelector('#AssetTree_7')
await page.click('#AssetTree_7')
await new Promise(r => setTimeout(r, 500));
await page.waitForSelector('#AssetTree_12')
await page.click('#AssetTree_12')
await page.waitForSelector('#mat-dialog-0 > elements-asset-tree-dialog > div > div.dialog-body.mat-dialog-content > mat-dialog-actions > button')
await page.click('#mat-dialog-0 > elements-asset-tree-dialog > div > div.dialog-body.mat-dialog-content > mat-dialog-actions > button')
await new Promise(r => setTimeout(r, 10000));
// 确认60分钟警告
await placeMarker(page, 1148, 450);
await page.mouse.click(1148, 450);
// 选择最近7天
await new Promise(r => setTimeout(r, 1000));
await placeMarker(page, 1244, 102);
await page.mouse.click(1244, 102);
await new Promise(r => setTimeout(r, 1000));
await placeMarker(page, 913, 288);
await page.mouse.click(913, 288);
// 选择trace
await new Promise(r => setTimeout(r, 1000));
await placeMarker(page, 795, 226);
await page.mouse.click(795, 226);
// 选择输入框
await new Promise(r => setTimeout(r, 1000));
await placeMarker(page, 639, 280);
await page.mouse.click(639, 280);
// 输入具体的项目名
await new Promise(r => setTimeout(r, 100));
await page.keyboard.type(project)
// 选择具体的项目
await new Promise(r => setTimeout(r, 1000));
await placeMarker(page, 639, 332);
await page.mouse.click(639, 332);
// 选择Duration
await new Promise(r => setTimeout(r, 1000));
await placeMarker(page, 816, 381);
await page.mouse.click(816, 381);
await new Promise(r => setTimeout(r, 200));
await placeMarker(page, 816, 463);
await page.mouse.click(816, 463);
})();
let enableMarkerPlacement = false;
// 封装的放置标记的函数
async function placeMarker(page, x, y) {
if (enableMarkerPlacement) {
await page.evaluate(({ x, y }) => {
const marker = document.createElement('div');
marker.style.width = '10px';
marker.style.height = '10px';
marker.style.background = 'red';
marker.style.position = 'absolute';
marker.style.top = `${y}px`;
marker.style.left = `${x}px`;
marker.style.zIndex = '10000';
marker.style.borderRadius = '50%';
document.body.appendChild(marker);
}, { x, y });
}
}
因为jumpserver点击具体工具后的界面是canvas,没有界面元素,所以只能按位置进行点击,所以这个代码在不同的电脑可能还运行不了相同的效果。但其提供了一种思路,其它人要模仿,这里唯一的问题点是如何获取我在界面上要点击的座标?
关于这点,做前端的应该比较熟,我这里提供一种方法,直接打开浏览器,按F12,打开console标签,里面输入
json
document.addEventListener('mousemove', (event) => {
console.log(`Mouse X: ${event.clientX}, Mouse Y: ${event.clientY}`);
});
接下来你鼠标移动到哪里,console都会显示当前鼠标的座标,这样你就可以估算canvas你要点击的按钮的座标位置了。
在写代码期间可以把enableMarkerPlacement参数改为true,它会显示模拟点击的座标位置,画个小红点,不至于摸不着头脑不知道自己是否真的点击了
抛砖引玉,各位大神给出你们的离谱用法吧~