From 4a7eadea238d32c368174c1bc6fd4a82f8ab8053 Mon Sep 17 00:00:00 2001 From: Zirak Date: Sat, 2 May 2015 17:07:20 +0300 Subject: [PATCH] Improved headless mode (cookies, config, REPL) * Stores cookies so you won't waste time on auth * Put the base site and chat as config * After all's well and done, you get a REPL with the bot's page --- run-headless.js | 141 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 107 insertions(+), 34 deletions(-) diff --git a/run-headless.js b/run-headless.js index 3988ff4..852a0da 100644 --- a/run-headless.js +++ b/run-headless.js @@ -1,10 +1,17 @@ -var Nightmare = require('nightmare'); -var hound = new Nightmare(); +var Nightmare = require('nightmare'), + readline = require('readline'); + +var hound = new Nightmare({ + cookiesFile: 'cookies.jar' +}); /*********** Change me! ***********/ var config = { email: 'you can guess', - password: 'what these are' + password: 'what these are', + + siteUrl: 'https://stackoverflow.com', + roomUrl: 'https://chat.stackoverflow.com/rooms/1' }; function once (fn) { @@ -19,40 +26,106 @@ function once (fn) { }; } +hound.drainQueue = function (cb) { + var self = hound; + + setTimeout(next, 0); + function next(err) { + var item = self.queue.shift(); + if (!item) { + cb && cb(err, self); + return; + } + + var method = item[0], + args = item[1]; + args.push(once(next)); + method.apply(self, args); + } +}; + +function seLogin () { + hound + .type('#se-login input[type="email"]', config.email) + .type('#se-login input[type="password"]', config.password) + .click('#se-login input[type="button"]') + .wait() + .screenshot('pics/login.png'); +} +function injectToChat (hound) { + hound + .goto(config.roomUrl) + .wait() + .screenshot('pics/chat.png') + .evaluate(function () { + var script = document.createElement('script'); + script.src = 'https://raw.github.com/Zirak/SO-ChatBot/master/master.js'; + script.onload = function() { + bot.activateDevMode(); + console.log('Loaded bot'); + bot.adapter.out.add('I will derive!'); + }; + document.head.appendChild(script); + }, function () { + console.log('Injected chatbot.'); + }); +} + hound - .goto('https://stackoverflow.com/users/login/') + .goto(config.siteUrl + '/users/login/') .screenshot('pics/pre-login.png') - .type('#se-login input[type="email"]', config.email) - .type('#se-login input[type="password"]', config.password) - .click('#se-login input[type="button"]') - .wait() - .screenshot('pics/login.png') - .goto('https://chat.stackoverflow.com/rooms/76070') - .screenshot('pics/chat.png') - .evaluate(function () { - var script = document.createElement('script'); - script.src = 'https://raw.github.com/Zirak/SO-ChatBot/master/master.js'; - script.onload = function() { - console.log('Loaded bot'); - }; - document.head.appendChild(script); - }, function () { - console.log('Injected chatbot.'); + .wait(1000) + .url(function (url) { + if (!/login-add$/.test(url)) { + console.log('Need to authenticate'); + hound.use(seLogin); + } + else { + console.log('Cool, already logged in'); + } + + hound.use(injectToChat); + hound.drainQueue(function () { + console.log('Should be done loading stuff.'); + hitTheRepl(); + }); }) .setup(function () { - var self = hound; - - setTimeout(next, 0); - function next(err) { - var item = self.queue.shift(); - if (!item) { - console.log('Should be done loading stuff.'); - return; - } + hound.drainQueue(); + }); - var method = item[0], - args = item[1]; - args.push(once(next)); - method.apply(self, args); - } +function hitTheRepl() { + var repl = readline.createInterface({ + input: process.stdin, + output: process.stdout }); + + console.log('You are now in a REPL with the remote page. Have fun!'); + + hound.on('consoleMessage', function (msg) { + console.log('<', msg); + }); + hound.on('error', function (msg) { + console.log('! ', msg); + }); + + repl.on('line', function (data) { + hound.evaluate(function (code) { + try { + return eval(code); + } + catch (e) { + return e.message; + } + }, function (res) { + console.log('$', res); + repl.prompt(); + }, data).drainQueue(); + }); + repl.on('close', function () { + console.log('Leaving the nightmare...'); + hound.teardownInstance(); + }); + + repl.prompt(); +}