Home Reference Source

lib/input/Mouse.js

const Keyboard = require('./Keyboard')

class Mouse {
  /**
   * @param {Chrome|CRIConnection|CDPSession|Object} client
   * @param {?Keyboard} [keyboard]
   */
  constructor (client, keyboard) {
    this._client = client
    this._keyboard = keyboard != null ? keyboard : new Keyboard(client)
    this._x = 0
    this._y = 0
    /** @type {'none'|'left'|'right'|'middle'} */
    this._button = 'none'
  }

  /**
   * @param {number} x
   * @param {number} y
   * @param {!{steps?: number}=} options
   */
  async move (x, y, options = {}) {
    const { steps = 1 } = options
    const fromX = this._x

    const fromY = this._y
    this._x = x
    this._y = y
    for (let i = 1; i <= steps; i++) {
      await this._client.send('Input.dispatchMouseEvent', {
        type: 'mouseMoved',
        button: this._button,
        x: fromX + (this._x - fromX) * (i / steps),
        y: fromY + (this._y - fromY) * (i / steps),
        modifiers: this._keyboard._modifiers
      })
    }
  }

  /**
   * @param {number} x
   * @param {number} y
   * @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
   */
  async click (x, y, options = {}) {
    const { delay = null } = options
    await this.move(x, y)
    await this.down(options)
    if (delay !== null) await new Promise(resolve => setTimeout(resolve, delay))
    await this.up(options)
  }

  /**
   * @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options
   */
  async down (options = {}) {
    const { button = 'left', clickCount = 1 } = options
    this._button = button
    await this._client.send('Input.dispatchMouseEvent', {
      type: 'mousePressed',
      button,
      x: this._x,
      y: this._y,
      modifiers: this._keyboard._modifiers,
      clickCount
    })
  }

  /**
   * @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options
   */
  async up (options = {}) {
    const { button = 'left', clickCount = 1 } = options
    this._button = 'none'
    await this._client.send('Input.dispatchMouseEvent', {
      type: 'mouseReleased',
      button,
      x: this._x,
      y: this._y,
      modifiers: this._keyboard._modifiers,
      clickCount
    })
  }
}

/**
 * @type {Mouse}
 */
module.exports = Mouse