chrome新特性-recorder
创始人
2024-03-24 02:25:06

chrome新特性-recorder

    • 一、简介
    • 二、录制
    • 三、录制回放
      • 1.Chrome DevTool工具
      • 2.Puppeteer脚本
        • (1) 介绍
        • (2) 使用

一、简介

recorder
与Selenium IDE浏览器插件类似,可用于自动化测试及脚本生成(Puppeteer脚本);前者为Web自动化测试框架Selenium的配套浏览器插件支持Java、Python等测试脚本的生成。

二、录制

录制

三、录制回放

下面介绍两种录制回放方式

1.Chrome DevTool工具

导入json配置文件,通过Chrome DevTool工具回放

2.Puppeteer脚本

(1) 介绍

Puppeteer 是一个 Node library,提供了一套完整的通过 DevTools 协议操纵 Chrome 或 Chromium 的 API。Puppeteer 默认以 无头(headless) 的方式运行, 也可以使用 GUI 的方式运行 Chrome 和 Chromium。
熟悉爬虫或者 UI 自动化的同学可能会联想到 PhantomJS、CasperJS 或者 Selenium,而作为 Chrome DevTools 团队亲自出品和维护的 puppeteer 不管是在功能的完整性、稳定性、兼容性、安全性还是性能都将成为碾压其他工具的存在。

(2) 使用

  • 安装并配置nodejs

可参考 nodejs环境配置

  • 安装依赖包
npm install -g puppeteer
npm install -g url
npm install -g @puppeteer/replay
  • 修改js脚本

禁用headless模式(启用GUI模式)

    const browser = await puppeteer.launch();

改为

    const browser = await puppeteer.launch({headless: false, // GUI模式});
  • 运行js脚本
node test.js
  • test.js

recorder导出的puppeteer脚本如下

const puppeteer = require('puppeteer'); // v13.0.0 or later(async () => {const browser = await puppeteer.launch({headless: false, // GUI模式});const page = await browser.newPage();const timeout = 5000;page.setDefaultTimeout(timeout);{const targetPage = page;await targetPage.setViewport({"width":1752,"height":884})}{const targetPage = page;const promises = [];promises.push(targetPage.waitForNavigation());await targetPage.goto("https://www.baidu.com/");await Promise.all(promises);}{const targetPage = page;await scrollIntoViewIfNeeded([["#kw"],["xpath///*[@id=\"kw\"]"]], targetPage, timeout);const element = await waitForSelectors([["#kw"],["xpath///*[@id=\"kw\"]"]], targetPage, { timeout, visible: true });const type = await element.evaluate(el => el.type);if (["select-one"].includes(type)) {await element.select("你好");} else if (["textarea","text","url","tel","search","password","number","email"].includes(type)) {await element.type("你好");} else {await element.focus();await element.evaluate((el, value) => {el.value = value;el.dispatchEvent(new Event('input', { bubbles: true }));el.dispatchEvent(new Event('change', { bubbles: true }));}, "你好");}}{const targetPage = page;await targetPage.keyboard.down("Enter");}{const targetPage = page;await targetPage.keyboard.up("Enter");}{const targetPage = page;await scrollIntoViewIfNeeded([["aria/你好,汉语词语,百度百科[role=\"link\"]"],["#\\31  > div > div > h3 > a"],["xpath///*[@id=\"1\"]/div/div/h3/a"],["text/你好(汉语词语) - 百度百科"]], targetPage, timeout);const element = await waitForSelectors([["aria/你好,汉语词语,百度百科[role=\"link\"]"],["#\\31  > div > div > h3 > a"],["xpath///*[@id=\"1\"]/div/div/h3/a"],["text/你好(汉语词语) - 百度百科"]], targetPage, { timeout, visible: true });await element.click({offset: {x: 99,y: 14,},});}await browser.close();async function waitForSelectors(selectors, frame, options) {for (const selector of selectors) {try {return await waitForSelector(selector, frame, options);} catch (err) {console.error(err);}}throw new Error('Could not find element for selectors: ' + JSON.stringify(selectors));}async function scrollIntoViewIfNeeded(selectors, frame, timeout) {const element = await waitForSelectors(selectors, frame, { visible: false, timeout });if (!element) {throw new Error('The element could not be found.');}await waitForConnected(element, timeout);const isInViewport = await element.isIntersectingViewport({threshold: 0});if (isInViewport) {return;}await element.evaluate(element => {element.scrollIntoView({block: 'center',inline: 'center',behavior: 'auto',});});await waitForInViewport(element, timeout);}async function waitForConnected(element, timeout) {await waitForFunction(async () => {return await element.getProperty('isConnected');}, timeout);}async function waitForInViewport(element, timeout) {await waitForFunction(async () => {return await element.isIntersectingViewport({threshold: 0});}, timeout);}async function waitForSelector(selector, frame, options) {if (!Array.isArray(selector)) {selector = [selector];}if (!selector.length) {throw new Error('Empty selector provided to waitForSelector');}let element = null;for (let i = 0; i < selector.length; i++) {const part = selector[i];if (element) {element = await element.waitForSelector(part, options);} else {element = await frame.waitForSelector(part, options);}if (!element) {throw new Error('Could not find element: ' + selector.join('>>'));}if (i < selector.length - 1) {element = (await element.evaluateHandle(el => el.shadowRoot ? el.shadowRoot : el)).asElement();}}if (!element) {throw new Error('Could not find element: ' + selector.join('|'));}return element;}async function waitForElement(step, frame, timeout) {const count = step.count || 1;const operator = step.operator || '>=';const comp = {'==': (a, b) => a === b,'>=': (a, b) => a >= b,'<=': (a, b) => a <= b,};const compFn = comp[operator];await waitForFunction(async () => {const elements = await querySelectorsAll(step.selectors, frame);return compFn(elements.length, count);}, timeout);}async function querySelectorsAll(selectors, frame) {for (const selector of selectors) {const result = await querySelectorAll(selector, frame);if (result.length) {return result;}}return [];}async function querySelectorAll(selector, frame) {if (!Array.isArray(selector)) {selector = [selector];}if (!selector.length) {throw new Error('Empty selector provided to querySelectorAll');}let elements = [];for (let i = 0; i < selector.length; i++) {const part = selector[i];if (i === 0) {elements = await frame.$$(part);} else {const tmpElements = elements;elements = [];for (const el of tmpElements) {elements.push(...(await el.$$(part)));}}if (elements.length === 0) {return [];}if (i < selector.length - 1) {const tmpElements = [];for (const el of elements) {const newEl = (await el.evaluateHandle(el => el.shadowRoot ? el.shadowRoot : el)).asElement();if (newEl) {tmpElements.push(newEl);}}elements = tmpElements;}}return elements;}async function waitForFunction(fn, timeout) {let isActive = true;const timeoutId = setTimeout(() => {isActive = false;}, timeout);while (isActive) {const result = await fn();if (result) {clearTimeout(timeoutId);return;}await new Promise(resolve => setTimeout(resolve, 100));}throw new Error('Timed out');}
})().catch(err => {console.error(err);process.exit(1);
});

参考:
chrome开发者工具-recorder-录制回放
Puppeteer 入门指引

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...