基于 chrome-remote-interface 的自动化工具。
API与 Nightmare 保持高度兼容。
  chrome({ show: true })
  .viewport(1900, 1000)
  .useragent('Mozilla/5.0 Chrome/59.0.3071.115 Mobile Safari/537.36')
  .goto('https://www.baidu.com/')
  .wait('body')
  .insert('input#kw', 'hello world\r')
  .wait('.c-container a')
  .click('.c-container a')
  .wait('[id^="highlighter_"]')
  .screenshot('1.png')
  .evaluate(() => document.querySelectorAll('.para-title.level-3')[9].nextElementSibling.querySelector('.code').textContent)
  .pipe((code) => console.log(code))
  .url()
  .end()
  .then((url) => console.log(url))var Nightmare = require('chrome-automator')
Nightmare.action('hello', function () {
  console.log('Get url')
  return this.evaluate_now(function () {
    return document.querySelector('#links_wrapper a.result__a').href
  })
})
var nightmare = Nightmare({ show: true })
try {
  nightmare
  .goto('https://duckduckgo.com')
  .type('#search_form_input_homepage', 'github nightmare')
  .click('#search_button_homepage')
  .wait('#zero_click_wrapper .c-info__title a')
  .hello()
  .end()
  .then(function (result) {
    console.log(result)
  })
} catch (e) {
  console.log(e)
}> chrome-automator
.chrome() // 启动chrome
.goto('https://baidu.com')
.goto{ frameId: '64607.1' }
.insert('#kw', 'hello world\r')
.screenshot('1.jpg')
.title()
.end() // 关闭chrome
输出: hello world_百度搜索
- 
constructor 支持如下参数 - port
- show
- chromePath
- waitTimeout
- executionTimeout
- loadTimeout
 
- 
goto 
- 
url 
- 
title 
- 
action 只支持 Promise 和 async 方式的异步写法,不支持 callback 方式 
- 
evaluate 
- 
click 
- 
type 
- 
insert 
- 
wait 
- 
mouseup 
- 
mouseover 
- 
mousedown 
- 
check 
- 
uncheck 
- 
select 
- 
scrollTo 
- 
visible 
- 
exists 
- 
path 
- 
back 
- 
forward 
- 
refresh 
- 
end 
- 
focusSelector 
- 
blurSelector 
- 
pdf 仅支持headless模式,设置 show: false 开启 
- 
screenshot 
- 
viewport 
- 
useragent 
- 
html 
- 
authentication 
- 
cookies - set
- get
- clear
 
- 
inject 
- 
on 暂时支持的事件与Nightmare不同 
列表如下: 详细说明见 https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-loadingFailed
- 
Page.javascriptDialogOpening 弹窗事件 - [x] Console.messageAdded 旧console事件,不建议使用 
- 
Runtime.consoleAPICalled console事件 
- 
Network.resourceChangedPriority 
- 
Network.requestWillBeSent 
- 
Network.requestServedFromCache 
- 
Network.responseReceived 
- 
Network.dataReceived 
- 
Network.loadingFinished 
- 
Network.loadingFailed 
- 
Network.webSocketWillSendHandshakeRequest 
- 
Network.webSocketHandshakeResponseReceived 
- 
Network.webSocketCreated 
- 
Network.webSocketClosed 
- 
Network.webSocketFrameReceived 
- 
Network.webSocketFrameError 
- 
Network.webSocketFrameSent 
- 
Network.eventSourceMessageReceived 
- 
Network.requestIntercepted 
- 
Page.domContentEventFired 
- 
Page.loadEventFired 
- 
Page.frameAttached 
- 
Page.frameNavigated 
- 
Page.frameDetached 
- 
Page.frameStartedLoading 
- 
Page.frameStoppedLoading 
- 
Page.frameScheduledNavigation 
- 
Page.frameClearedScheduledNavigation 
- 
Page.frameResized 
- 
Page.javascriptDialogClosed 
- 
Page.screencastFrame 
- 
Page.screencastVisibilityChanged 
- 
Page.interstitialShown 
- 
Page.interstitialHidden 
两种模式:
- 非阻塞式 默认方式,建议在 goto 之前使用
- 阻塞式,使用方式 on(eventName, fn, { detach: false })。 如想取消监听,可以return { cancled: true }继续接下来的流程。 例子见 test4,test5
- 
once 只监听事件一次,监听完成后可以继续后续的动作 
- 
halt 暂时不支持,chrome在此场景不太适用 segment-boneyard/nightmare#835 
- 
header 目前可以使用setExtraHTTPHeaders代替部分功能 
- iframe 进入iframe,方便iframe里面的操作
- pipe 支持流程衔接,如登录流程,和 then 一样,pipe 也可以接收上个流程的返回值,建议在中间流程使用 pipe 替代 then
- 支持新窗口打开时自动跟踪,防控制跳失 注: headless模式下存在bug
- setExtraHTTPHeaders
- ignoreSWCache 忽略service worker缓存
PS:目前原有框架(Nightmare)回调写法全部去除,仅保留 Promise 写法。
Tips: 执行过程中手动进行某些操作(如打开开发者工具)可能会使用动作失效。 因为 Promise 无法取消的原因,所以在流程执行完 end 操作后node可能并不会立即退出,一般会在 30s 左右自动退出,可以缩短 loadTimeout 和 executionTimeout 解决 Promise 异步流程目前在node下还无法显示完整的错误堆栈信息,可以考虑使用
node --trace-warnings查看,也可以使用global.Promise = require('bluebird')解决,使用过程中记得使用 try catch 包裹执行段
MIT
- Nightmare
- chrome-remote-interface
- lighthouse