diff --git a/README.md b/README.md index 8446e1732..870005a17 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,40 @@ childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) { ``` +Or `exec()` method is also provided for convenience: + +```javascript +var phantomjs = require('phantomjs-prebuilt') +var program = phantomjs.exec('phantomjs-script.js', 'arg1', 'arg2') +program.stdout.pipe(process.stdout) +program.stderr.pipe(process.stderr) +program.on('exit', code => { + // do something on end +}) +``` + +Note: [childProcess.spawn()](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) is called inside `exec()`. + +Running with WebDriver +---------------------- + +`run()` method detects when PhantomJS gets ready. It's handy to use with WebDriver (Selenium). + +```javascript +var phantomjs = require('phantomjs-prebuilt') +var webdriverio = require('webdriverio') +var wdOpts = { desiredCapabilities: { browserName: 'phantomjs' } } + +phantomjs.run('--webdriver=4444').then(program => { + webdriverio.remote(wdOpts).init() + .url('https://developer.mozilla.org/en-US/') + .getTitle().then(title => { + console.log(title) // 'Mozilla Developer Network' + program.kill() // quits PhantomJS + }) +}) +``` + Versioning ---------- @@ -185,7 +219,7 @@ env variable described above. ##### I am behind a corporate proxy that uses self-signed SSL certificates to intercept encrypted traffic. -You can tell NPM and the PhantomJS installer to skip validation of ssl keys with NPM's +You can tell NPM and the PhantomJS installer to skip validation of ssl keys with NPM's [strict-ssl](https://www.npmjs.org/doc/misc/npm-config.html#strict-ssl) setting: ``` @@ -205,7 +239,7 @@ use the manually-installed binaries. Some Linux distros tried to rename `node` to `nodejs` due to a package conflict. This is a non-portable change, and we do not try to support this. The [official documentation](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os) -recommends that you run `apt-get install nodejs-legacy` to symlink `node` to `nodejs` +recommends that you run `apt-get install nodejs-legacy` to symlink `node` to `nodejs` on those platforms, or many NodeJS programs won't work properly. Contributing diff --git a/lib/phantomjs.js b/lib/phantomjs.js index 65403cdf6..488b2226f 100644 --- a/lib/phantomjs.js +++ b/lib/phantomjs.js @@ -7,6 +7,8 @@ var fs = require('fs') var path = require('path') +var spawn = require('child_process').spawn +var Promise = require('es6-promise').Promise /** @@ -61,3 +63,39 @@ if (exports.path) { // We did our best. Likely because phantomjs was already installed. } } + +/** + * Executes a script or just runs PhantomJS + */ +exports.exec = function () { + var args = Array.prototype.slice.call(arguments) + return spawn(exports.path, args) +} + +/** + * Runs PhantomJS with provided options + * @example + * // handy with WebDriver + * phantomjs.run('--webdriver=4444').then(program => { + * // do something + * program.kill() + * }) + * @returns {Promise} the process of PhantomJS + */ +exports.run = function () { + var args = arguments + return new Promise(function (resolve, reject) { + try { + var program = exports.exec.apply(null, args) + var isFirst = true + program.stdout.on('data', function () { + // This detects PhantomJS instance get ready. + if (!isFirst) return + isFirst = false + resolve(program) + }) + } catch (err) { + reject(err) + } + }) +} diff --git a/package.json b/package.json index 216dc3058..ab2bace0d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "test": "nodeunit --reporter=minimal test/tests.js && eslint ." }, "dependencies": { + "es6-promise": "^3.2.1", "extract-zip": "~1.5.0", "fs-extra": "~0.30.0", "hasha": "^2.2.0", @@ -50,7 +51,8 @@ }, "devDependencies": { "eslint": "2.7.0", - "nodeunit": "0.9.1" + "nodeunit": "0.9.1", + "webdriverio": "^4.2.3" }, "bundledDependencies": [ "extract-zip", diff --git a/test/tests.js b/test/tests.js index 0f229d6ad..10192ec80 100644 --- a/test/tests.js +++ b/test/tests.js @@ -6,10 +6,10 @@ var childProcess = require('child_process') var fs = require('fs') var path = require('path') +var webdriverio = require('webdriverio') var phantomjs = require('../lib/phantomjs') var util = require('../lib/util') - exports.testDownload = function (test) { test.expect(1) test.ok(fs.existsSync(phantomjs.path), 'Binary file should have been downloaded') @@ -98,3 +98,28 @@ exports.testSuccessfulVerifyChecksum = function (test) { test.done() }) } + +exports.testPhantomExec = function (test) { + test.expect(1) + var p = phantomjs.exec(path.join(__dirname, 'exit.js')) + p.on('exit', function (code) { + test.equals(code, 123, 'Exit code should be returned from phantom script') + test.done() + }) +} + +exports.testPhantomRun = function (test) { + test.expect(1) + var wdOpts = { desiredCapabilities: { browserName: 'phantomjs' } } + phantomjs.run('--webdriver=4444').then(function (p) { + webdriverio.remote(wdOpts).init() + .url('https://developer.mozilla.org/en-US/') + .getTitle().then(function (title) { + test.equals(title, 'Mozilla Developer Network', 'Page title') + }) + .then(function () { + p.kill() + test.done() + }) + }) +}