UNPKG

3.12 kBJavaScriptView Raw
1// Copyright 2013 The Obvious Corporation.
2
3/**
4 * @fileoverview Helpers made available via require('phantomjs') once package is
5 * installed.
6 */
7
8var fs = require('fs')
9var path = require('path')
10var spawn = require('child_process').spawn
11var Promise = require('es6-promise').Promise
12
13
14/**
15 * Where the phantom binary can be found.
16 * @type {string}
17 */
18try {
19 var location = require('./location')
20 exports.path = path.resolve(__dirname, location.location)
21 exports.platform = location.platform
22 exports.arch = location.arch
23} catch(e) {
24 // Must be running inside install script.
25 exports.path = null
26}
27
28
29/**
30 * The version of phantomjs installed by this package.
31 * @type {number}
32 */
33exports.version = '2.1.1'
34
35
36/**
37 * Returns a clean path that helps avoid `which` finding bin files installed
38 * by NPM for this repo.
39 * @param {string} path
40 * @return {string}
41 */
42exports.cleanPath = function (path) {
43 return path
44 .replace(/:[^:]*node_modules[^:]*/g, '')
45 .replace(/(^|:)\.\/bin(\:|$)/g, ':')
46 .replace(/^:+/, '')
47 .replace(/:+$/, '')
48}
49
50
51// Make sure the binary is executable. For some reason doing this inside
52// install does not work correctly, likely due to some NPM step.
53if (exports.path) {
54 try {
55 // avoid touching the binary if it's already got the correct permissions
56 var st = fs.statSync(exports.path)
57 var mode = st.mode | parseInt('0555', 8)
58 if (mode !== st.mode) {
59 fs.chmodSync(exports.path, mode)
60 }
61 } catch (e) {
62 // Just ignore error if we don't have permission.
63 // We did our best. Likely because phantomjs was already installed.
64 }
65}
66
67/**
68 * Executes a script or just runs PhantomJS
69 */
70exports.exec = function () {
71 var args = Array.prototype.slice.call(arguments)
72 return spawn(exports.path, args)
73}
74
75/**
76 * Runs PhantomJS with provided options
77 * @example
78 * // handy with WebDriver
79 * phantomjs.run('--webdriver=4444').then(program => {
80 * // do something
81 * program.kill()
82 * })
83 * @returns {Promise} the process of PhantomJS
84 */
85exports.run = function () {
86 var args = arguments
87 return new Promise(function (resolve, reject) {
88 try {
89 var program = exports.exec.apply(null, args)
90 var isFirst = true
91 var stderr = ''
92 program.stdout.on('data', function () {
93 // This detects PhantomJS instance get ready.
94 if (!isFirst) return
95 isFirst = false
96 resolve(program)
97 })
98 program.stderr.on('data', function (data) {
99 stderr = stderr + data.toString('utf8')
100 })
101 program.on('error', function (err) {
102 if (!isFirst) return
103 isFirst = false
104 reject(err)
105 })
106 program.on('exit', function (code) {
107 if (!isFirst) return
108 isFirst = false
109 if (code == 0) {
110 // PhantomJS doesn't use exit codes correctly :(
111 if (stderr.indexOf('Error:') == 0) {
112 reject(new Error(stderr))
113 } else {
114 resolve(program)
115 }
116 } else {
117 reject(new Error('Exit code: ' + code))
118 }
119 })
120 } catch (err) {
121 reject(err)
122 }
123 })
124}