Testing Puppeter如何处理click Object/DevTools协议Chrome/Chrome
我需要知道Puppeter如何处理click对象,以及ChromiumDevToolsAPI。我试图自己研究它,但发现自己无法找到处理它的实际代码 我需要知道的原因是,我正在开发一个包装器,在测试网页的代码中测试事件,并想看看实现一个事件处理例程是否有益于使用事件的Puppeter界面(点击和点击鼠标悬停,以及可能需要的其他事件,如触摸事件或滚动) 以下是我取得的成绩: Puppeter API使用DevTools的帧逻辑来联系API: 这是我所能做到的,因为我试图查找页面协议,但我不知道那里发生了什么Testing Puppeter如何处理click Object/DevTools协议Chrome/Chrome,testing,events,click,puppeteer,chromium,Testing,Events,Click,Puppeteer,Chromium,我需要知道Puppeter如何处理click对象,以及ChromiumDevToolsAPI。我试图自己研究它,但发现自己无法找到处理它的实际代码 我需要知道的原因是,我正在开发一个包装器,在测试网页的代码中测试事件,并想看看实现一个事件处理例程是否有益于使用事件的Puppeter界面(点击和点击鼠标悬停,以及可能需要的其他事件,如触摸事件或滚动) 以下是我取得的成绩: Puppeter API使用DevTools的帧逻辑来联系API: 这是我所能做到的,因为我试图查找页面协议,但我不知道那里
任何帮助都将不胜感激,即使是在研究中。主要部分发生在
JSHandle
:
异步单击(选项){
等待此消息。_scrollIntoViewIfNeeded();
const{x,y}=等待此操作。_clickablePoint();
等待此消息。\u页面。鼠标。单击(x,y,选项);
}
它滚动直到元素在视口中(否则它不会单击),然后使用DevTools API在元素上找到可单击的坐标:
async\u clickablePoint(){
const[result,layoutMetrics]=wait Promise.all([
此._client.send('DOM.getContentQuads'{
objectId:此。\u remoteObject.objectId
}).catch(调试错误),
此._client.send('Page.getLayoutMetrics'),
]);
如果(!result | |!result.quads.length)
抛出新错误('节点不可见或不是HtmleElement');
//过滤掉面积太小而无法单击的四边形。
const{clientWidth,clientHeight}=layoutMetrics.layoutViewport;
const quads=result.quads.map(quad=>this.\u from protocolquad(quad)).map(quad=>this.\u intersectQuadWithViewport(quad,clientWidth,clientHeight)).filter(quad=>computequadrarea(quad)>1);
如果(!四边形长度)
抛出新错误('节点不可见或不是HtmleElement');
//返回第一个四边形的中点。
常量四元=四元[0];
设x=0;
设y=0;
用于(四边形的常量点){
x+=点x;
y+=点y;
}
返回{
x:x/4,
y:y/4
};
}
最后,它将鼠标移动到坐标并单击它
异步点击(x,y,选项={}){
const{delay=null}=options;
如果(延迟!==null){
等待承诺([
这个。移动(x,y),
这个.向下(选项),
]);
等待新的承诺(f=>setTimeout(f,delay));
等待这个。向上(选项);
}否则{
等待承诺([
这个。移动(x,y),
这个.向下(选项),
此.up(选项),
]);
}
}
它使用devtoolsapi与鼠标进行交互
异步关闭(选项={}){
const{button='left',clickCount=1}=options;
这个按钮=按钮;
等待此消息。_client.send('Input.dispatchMouseEvent'{
键入:“鼠标按下”,
按钮
x:这个,
y:这个,
修饰符:这个。_键盘。_修饰符,
点击计数
});
}
/**
* @param {string} selector
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/
click(selector, options = {}) {
return this.mainFrame().click(selector, options);
}
/**
* @return {!Puppeteer.Frame}
*/
/**
* @param {!Protocol.Page.Frame} framePayload`
*/
_onFrameNavigated(framePayload) {
const isMainFrame = !framePayload.parentId;
let frame = isMainFrame ? this._mainFrame : this._frames.get(framePayload.id);
assert(isMainFrame || frame, 'We either navigate top level or have old version of the navigated frame');
// Detach all child frames first.
if (frame) {
for (const child of frame.childFrames())
this._removeFramesRecursively(child);
}
if (isMainFrame) {
if (frame) {
// Update frame id to retain frame identity on cross-process navigation.
this._frames.delete(frame._id);
frame._id = framePayload.id;
} else {
// Initial main frame navigation.
frame = new Frame(this, this._client, null, framePayload.id);
}
this._frames.set(framePayload.id, frame);
this._mainFrame = frame;
}