Testing Puppeter如何处理click Object/DevTools协议Chrome/Chrome

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: 这是我所能做到的,因为我试图查找页面协议,但我不知道那里

我需要知道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;
        }