1 | var spawn = require('child_process').spawn;
|
2 | var windows = require('./windows');
|
3 | var darwin = require('./darwin');
|
4 |
|
5 | var browsers = {
|
6 | 'google-chrome' : {
|
7 | name : 'chrome',
|
8 | re : /Google Chrome (\S+)/,
|
9 | type : 'chrome',
|
10 | profile : true,
|
11 | },
|
12 | 'chromium-browser' : {
|
13 | name : 'chromium',
|
14 | re : /Chromium (\S+)/,
|
15 | type : 'chrome',
|
16 | profile : true,
|
17 | },
|
18 | 'firefox' : {
|
19 | name : 'firefox',
|
20 | re : /Mozilla Firefox (\S+)/,
|
21 | type : 'firefox',
|
22 | profile : true,
|
23 | },
|
24 | 'phantomjs' : {
|
25 | name : 'phantom',
|
26 | re : /(\S+)/,
|
27 | type : 'phantom',
|
28 | headless : true,
|
29 | profile : true,
|
30 | },
|
31 | 'safari': {
|
32 | name: 'safari',
|
33 | type: 'safari',
|
34 | profile: false
|
35 | },
|
36 | 'ie': {
|
37 | windows: true,
|
38 | name: 'ie',
|
39 | type: 'ie',
|
40 | profile: false
|
41 | }
|
42 | };
|
43 |
|
44 | var mix = function(s, r) {
|
45 | Object.keys(s).forEach(function(name) {
|
46 | if (!r.hasOwnProperty(name)) {
|
47 | r[name] = s[name];
|
48 | }
|
49 | });
|
50 | return r;
|
51 | };
|
52 |
|
53 | module.exports = function (cb) {
|
54 | var available = [],
|
55 | pending = Object.keys(browsers).length;
|
56 | Object.keys(browsers).forEach(function (name) {
|
57 | var br = browsers[name];
|
58 | check(name, function (err, v, p) {
|
59 | if (err === null) {
|
60 | if (Array.isArray(v)) {
|
61 | v.forEach(function(item) {
|
62 | available.push(mix(br, {
|
63 | command : item.path,
|
64 | version : item.version
|
65 | }));
|
66 | });
|
67 | }
|
68 | else {
|
69 | available.push(mix(br, {
|
70 | command : p || name,
|
71 | version : v
|
72 | }));
|
73 | }
|
74 | }
|
75 | if (--pending === 0) cb(available);
|
76 | });
|
77 | });
|
78 | };
|
79 |
|
80 |
|
81 | function checkWindows (name, cb) {
|
82 | if (windows[name]) {
|
83 | windows[name].version(function(err, version) {
|
84 | if (version) {
|
85 | windows[name].path(function(err, p) {
|
86 | if (err) {
|
87 | return cb('failed to get path for ' + name);
|
88 | }
|
89 | cb(null, version, p);
|
90 | });
|
91 | }
|
92 | else {
|
93 | cb('failed to get version for ' + name);
|
94 | }
|
95 | });
|
96 | }
|
97 | else {
|
98 | checkWhich(name, cb);
|
99 | }
|
100 | };
|
101 |
|
102 | function checkDarwin (name, cb) {
|
103 | if (darwin[name]) {
|
104 | if (darwin[name].all) {
|
105 | darwin[name].all(function(err, available) {
|
106 | if (err) {
|
107 | cb('failed to get version for ' + name);
|
108 | }
|
109 | else {
|
110 | cb(err, available);
|
111 | }
|
112 | });
|
113 | }
|
114 | else {
|
115 | darwin[name].version(function(err, version) {
|
116 | if (version) {
|
117 | darwin[name].path(function(err, p) {
|
118 | if (err) {
|
119 | return cb('failed to get path for ' + name);
|
120 | }
|
121 | cb(null, version, p);
|
122 | });
|
123 | }
|
124 | else {
|
125 | cb('failed to get version for ' + name);
|
126 | }
|
127 | });
|
128 | }
|
129 | }
|
130 | else {
|
131 | checkWhich(name, cb);
|
132 | }
|
133 | };
|
134 |
|
135 | function check(name, cb) {
|
136 | switch (process.platform) {
|
137 | case 'win32':
|
138 | checkWindows(name, cb);
|
139 | break;
|
140 | case 'darwin':
|
141 | checkDarwin(name, cb);
|
142 | break;
|
143 | default:
|
144 | checkWhich(name, cb);
|
145 | break;
|
146 | }
|
147 | };
|
148 |
|
149 | function checkWhich (name, cb) {
|
150 | var re = browsers[name].re;
|
151 | if (browsers[name].windows) {
|
152 | return cb('not installed');
|
153 | }
|
154 | var ps = spawn(name, [ '--version' ]);
|
155 | var data = '';
|
156 | ps.stdout.on('data', function (buf) { data += buf });
|
157 |
|
158 | ps.on('error', function () {
|
159 | cb('not installed');
|
160 | cb = null;
|
161 | })
|
162 |
|
163 | ps.on('exit', function (code, sig) {
|
164 | if (!cb) return;
|
165 | if (code !== 0) return cb('not installed');
|
166 |
|
167 | var m = re.exec(data);
|
168 | if (m) cb(null, m[1])
|
169 | else cb(null, data.trim())
|
170 | });
|
171 | };
|