UNPKG

3.83 kBJavaScriptView Raw
1var wd = require('wd');
2var urlModule = require('url');
3var urlparse = urlModule.parse;
4var urlformat = urlModule.format;
5
6var WebDriverInstance = function (baseBrowserDecorator, args, logger) {
7 var log = logger.create('WebDriver');
8
9 var config = args.config || {
10 hostname: '127.0.0.1',
11 port: 4444
12 };
13 var self = this;
14
15 // Intialize with default values
16 var spec = {
17 platform: 'ANY',
18 testName: 'Karma test',
19 tags: [],
20 version: ''
21 };
22
23 Object.keys(args).forEach(function (key) {
24 var value = args[key];
25 switch (key) {
26 case 'browserName':
27 break;
28 case 'platform':
29 break;
30 case 'testName':
31 break;
32 case 'tags':
33 break;
34 case 'version':
35 break;
36 case 'config':
37 // ignore
38 return;
39 }
40 spec[key] = value;
41 });
42
43 if (!spec.browserName) {
44 throw new Error('browserName is required!');
45 }
46
47 baseBrowserDecorator(this);
48
49 this.name = spec.browserName + ' via Remote WebDriver';
50 this.spec = spec;
51
52 // Handle x-ua-compatible option same as karma-ie-launcher(copy&paste):
53 //
54 // Usage :
55 // customLaunchers: {
56 // IE9: {
57 // base: 'WebDriver',
58 // config: webdriverConfig,
59 // browserName: 'internet explorer',
60 // 'x-ua-compatible': 'IE=EmulateIE9'
61 // }
62 // }
63 //
64 // This is done by passing the option on the url, in response the Karma server will
65 // set the following meta in the page.
66 // <meta http-equiv="X-UA-Compatible" content="[VALUE]"/>
67 function handleXUaCompatible(args, urlObj) {
68 if (args['x-ua-compatible']) {
69 urlObj.query['x-ua-compatible'] = args['x-ua-compatible'];
70 }
71 }
72
73 this._start = function (url) {
74 var urlObj = urlparse(url, true);
75
76 handleXUaCompatible(spec, urlObj);
77
78 delete urlObj.search; //url.format does not want search attribute
79 url = urlformat(urlObj);
80
81 log.debug('WebDriver config: ' + JSON.stringify(config));
82 log.debug('Browser capabilities: ' + JSON.stringify(spec));
83
84 self.browser = wd.remote(config);
85
86 var interval = args.pseudoActivityInterval && setInterval(function() {
87 log.debug('Imitate activity');
88 self.browser.title();
89 }, args.pseudoActivityInterval);
90
91 // With the "Promise-based" API from "wd", you can't actually handle
92 // rejections. You can intercept them with .then(), but they still register
93 // as "unhandled rejections" in Karma, and the error messages are devoid of
94 // useful context. So we use the older callback-based model instead.
95 self.browser.init(spec, function() {
96 log.debug('Session ID: ' + self.browser.sessionID);
97 self.browser.get(url, function(error) {
98 if (!error) {
99 return;
100 }
101
102 // Make sure the error log contains the spec, so that we can pin down
103 // issues to the specific Selenium node that failed.
104 log.error('WebDriver command failed', {
105 spec: spec,
106 error: error
107 });
108
109 // Now give up and quit.
110 self._process.kill();
111 });
112 });
113
114 self._process = {
115 kill: function() {
116 interval && clearInterval(interval);
117 self.browser.quit(function() {
118 log.info('Killed ' + spec.testName + '.');
119 self._onProcessExit(self.error ? -1 : 0, self.error);
120 });
121 }
122 };
123 };
124
125 // We can't really force browser to quit so just avoid warning about SIGKILL
126 this._onKillTimeout = function(){};
127};
128
129WebDriverInstance.prototype = {
130 name: 'WebDriver',
131
132 DEFAULT_CMD: {
133 linux: require('wd').path,
134 darwin: require('wd').path,
135 win32: require('wd').path
136 },
137 ENV_CMD: 'WEBDRIVER_BIN'
138};
139
140WebDriverInstance.$inject = ['baseBrowserDecorator', 'args', 'logger'];
141
142// PUBLISH DI MODULE
143module.exports = {
144 'launcher:WebDriver': ['type', WebDriverInstance]
145};