UNPKG

4.95 kBJavaScriptView Raw
1import request from 'request-promise';
2import { fs } from 'appium-support';
3import logger from './logger';
4import _ from 'lodash';
5
6
7const hubUri = (config) => {
8 const protocol = config.hubProtocol || 'http';
9 return `${protocol}://${config.hubHost}:${config.hubPort}`;
10};
11
12async function registerNode (configFile, addr, port) {
13 let data;
14 try {
15 data = await fs.readFile(configFile, 'utf-8');
16 } catch (err) {
17 logger.error(`Unable to load node configuration file to register with grid: ${err.message}`);
18 return;
19 }
20
21 // Check presence of data before posting it to the selenium grid
22 if (!data) {
23 logger.error('No data found in the node configuration file to send to the grid');
24 return;
25 }
26 postRequest(data, addr, port);
27}
28
29async function registerToGrid (options_post, jsonObject) {
30 try {
31 let response = await request(options_post);
32 if (response === undefined || response.statusCode !== 200) {
33 throw new Error('Request failed');
34 }
35 let logMessage = `Appium successfully registered with the grid on ${hubUri(jsonObject.configuration)}`;
36 logger.debug(logMessage);
37 } catch (err) {
38 logger.error(`Request to register with grid was unsuccessful: ${err.message}`);
39 }
40}
41
42function postRequest (data, addr, port) {
43 // parse json to get hub host and port
44 let jsonObject;
45 try {
46 jsonObject = JSON.parse(data);
47 } catch (err) {
48 logger.errorAndThrow(`Syntax error in node configuration file: ${err.message}`);
49 }
50
51 // Move Selenium 3 configuration properties to configuration object
52 if (!_.has(jsonObject, 'configuration')) {
53 let configuration = {};
54 for (const property in jsonObject) {
55 if (_.has(jsonObject, property) && property !== 'capabilities') {
56 configuration[property] = jsonObject[property];
57 delete jsonObject[property];
58 }
59 }
60 jsonObject.configuration = configuration;
61 }
62
63 // if the node config does not have the appium/webdriver url, host, and port,
64 // automatically add it based on how appium was initialized
65 // otherwise, we will take whatever the user setup
66 // because we will always set localhost/127.0.0.1. this won't work if your
67 // node and grid aren't in the same place
68 if (!jsonObject.configuration.url || !jsonObject.configuration.host || !jsonObject.configuration.port) {
69 jsonObject.configuration.url = `http://${addr}:${port}/wd/hub`;
70 jsonObject.configuration.host = addr;
71 jsonObject.configuration.port = port;
72 }
73 // if the node config does not have id automatically add it
74 if (!jsonObject.configuration.id) {
75 jsonObject.configuration.id = `http://${jsonObject.configuration.host}:${jsonObject.configuration.port}`;
76 }
77
78 // re-serialize the configuration with the auto populated data
79 data = JSON.stringify(jsonObject);
80
81 // prepare the header
82 let post_headers = {
83 'Content-Type': 'application/json',
84 'Content-Length': data.length
85 };
86 // the post options
87 let post_options = {
88 url: `${hubUri(jsonObject.configuration)}/grid/register`,
89 method: 'POST',
90 body: data,
91 headers: post_headers,
92 resolveWithFullResponse: true // return the full response, not just the body
93 };
94
95 if (jsonObject.configuration.register !== true) {
96 logger.debug(`No registration sent (${jsonObject.configuration.register} = false)`);
97 return;
98 }
99
100 let registerCycleTime = jsonObject.configuration.registerCycle;
101 if (registerCycleTime !== null && registerCycleTime > 0) {
102 // initiate a new Thread
103 let first = true;
104 logger.debug(`Starting auto register thread for grid. Will try to register every ${registerCycleTime} ms.`);
105 setInterval(async function registerRetry () {
106 if (first !== true) {
107 let isRegistered = await isAlreadyRegistered(jsonObject);
108 if (isRegistered !== null && isRegistered !== true) {
109 // make the http POST to the grid for registration
110 await registerToGrid(post_options, jsonObject);
111 }
112 } else {
113 first = false;
114 await registerToGrid(post_options, jsonObject);
115 }
116 }, registerCycleTime);
117 }
118}
119
120async function isAlreadyRegistered (jsonObject) {
121 //check if node is already registered
122 let id = jsonObject.configuration.id;
123 try {
124 let response = await request({
125 uri: `${hubUri(jsonObject.configuration)}/grid/api/proxy?id=${id}`,
126 method: 'GET',
127 timeout: 10000,
128 resolveWithFullResponse: true // return the full response, not just the body
129 });
130 if (response === undefined || response.statusCode !== 200) {
131 throw new Error(`Request failed`);
132 }
133 let responseData = JSON.parse(response.body);
134 if (responseData.success !== true) {
135 // if register fail, print the debug msg
136 logger.debug(`Grid registration error: ${responseData.msg}`);
137 }
138 return responseData.success;
139 } catch (err) {
140 logger.debug(`Hub down or not responding: ${err.message}`);
141 }
142}
143
144
145export default registerNode;