前言
看网上大多提到Puppeteer都是用它来做自动化测试,爬虫等等,而我在看到这个工具的第一想法是,它能否帮我提高开发过程中使用工具的效率。
在我的工作环境中,线上服务查慢接口,看日志等等需要首先登录jumpserver,再一步步寻址找到我需要的工具,点开它,选择自己需要的服务查看日志,查看耗时等等,这个过程鼠标点击好多次,重复工作很多,我就想能否节省前面这些步骤的时间。
直接给出效果吧
以上效果除了登录时候需要输入下验证码,之后没有移动鼠标,都有代码自行完成,包括自动打开树状结构菜单,自动选择skywalking,自动在打开的界面点击确认,自动选择最近7天,自动选择我要选择的项目,自动切换模式。
当你平时工作中看个东西有一堆固定的前置操作的时候,就可以想到,是否可以用它节省你的时间
执行代码
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标签,里面输入
document.addEventListener('mousemove', (event) => { console.log(`Mouse X: ${event.clientX}, Mouse Y: ${event.clientY}`); });
接下来你鼠标移动到哪里,console都会显示当前鼠标的座标,这样你就可以估算canvas你要点击的按钮的座标位置了。
在写代码期间可以把enableMarkerPlacement参数改为true,它会显示模拟点击的座标位置,画个小红点,不至于摸不着头脑不知道自己是否真的点击了
抛砖引玉,各位大神给出你们的离谱用法吧~