Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/javascript/webdriver/test/http/http_test.js
2868 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
goog.require('bot.ErrorCode');
19
goog.require('goog.Promise');
20
goog.require('goog.Uri');
21
goog.require('goog.testing.MockControl');
22
goog.require('goog.testing.jsunit');
23
goog.require('goog.userAgent');
24
goog.require('webdriver.Command');
25
goog.require('webdriver.http.Client');
26
goog.require('webdriver.http.Executor');
27
goog.require('webdriver.test.testutil');
28
29
// Alias for readability.
30
var callbackHelper = webdriver.test.testutil.callbackHelper;
31
32
var control = new goog.testing.MockControl();
33
var mockClient, executor, onCallback, onErrback;
34
35
function shouldRunTests() {
36
return !goog.userAgent.IE || goog.userAgent.isVersionOrHigher(10);
37
}
38
39
function setUp() {
40
mockClient = control.createStrictMock(webdriver.http.Client);
41
42
executor = new webdriver.http.Executor(mockClient);
43
}
44
45
function tearDown() {
46
control.$tearDown();
47
}
48
49
function assertSuccess() {
50
onErrback.assertNotCalled('Did not expect errback');
51
onCallback.assertCalled('Expected callback');
52
}
53
54
function assertFailure() {
55
onCallback.assertNotCalled('Did not expect callback');
56
onErrback.assertCalled('Expected errback');
57
}
58
59
function headersToString(headers) {
60
var str = [];
61
for (var key in headers) {
62
str.push(key + ': ' + headers[key]);
63
}
64
return str.join('\n');
65
}
66
67
function expectRequest(method, path, data, headers) {
68
var description = method + ' ' + path + '\n' + headersToString(headers) +
69
'\n' + JSON.stringify(data);
70
71
return mockClient.send(new goog.testing.mockmatchers.ArgumentMatcher(
72
function(request) {
73
assertEquals('wrong method', method, request.method);
74
assertEquals('wrong path', path + '', request.path);
75
webdriver.test.testutil.assertObjectEquals(data, request.data);
76
assertNull(
77
'Wrong headers for request:\n' + description +
78
'\n Actual headers were:\n' + headersToString(request.headers),
79
goog.testing.asserts.findDifferences(headers, request.headers));
80
return true;
81
}, description));
82
}
83
84
function response(status, headers, body) {
85
return new webdriver.http.Response(status, headers, body);
86
}
87
88
function respondsWith(error, opt_response) {
89
return function() {
90
if (error) {
91
return goog.Promise.reject(error);
92
} else {
93
return goog.Promise.resolve(opt_response);
94
}
95
};
96
}
97
98
///////////////////////////////////////////////////////////////////////////////
99
//
100
// Tests
101
//
102
///////////////////////////////////////////////////////////////////////////////
103
104
function testBuildPath() {
105
var parameters = {'sessionId':'foo', 'url':'http://www.google.com'};
106
var finalPath = webdriver.http.Executor.buildPath_(
107
'/session/:sessionId/url', parameters);
108
assertEquals('/session/foo/url', finalPath);
109
webdriver.test.testutil.assertObjectEquals({'url':'http://www.google.com'},
110
parameters);
111
}
112
113
function testBuildPath_withWebElement() {
114
var parameters = {'sessionId':'foo', 'id': {}};
115
parameters['id']['ELEMENT'] = 'bar';
116
117
var finalPath = webdriver.http.Executor.buildPath_(
118
'/session/:sessionId/element/:id/click', parameters);
119
assertEquals('/session/foo/element/bar/click', finalPath);
120
webdriver.test.testutil.assertObjectEquals({}, parameters);
121
}
122
123
function testBuildPath_throwsIfMissingParameter() {
124
assertThrows(goog.partial(webdriver.http.Executor.buildPath_,
125
'/session/:sessionId', {}));
126
127
assertThrows(goog.partial(webdriver.http.Executor.buildPath_,
128
'/session/:sessionId/element/:id', {'sessionId': 'foo'}));
129
}
130
131
function testBuildPath_doesNotMatchOnSegmentsThatDoNotStartWithColon() {
132
assertEquals('/session/foo:bar/baz',
133
webdriver.http.Executor.buildPath_('/session/foo:bar/baz', {}));
134
}
135
136
function testExecute_rejectsUnrecognisedCommands() {
137
assertThrows(goog.bind(executor.execute, executor,
138
new webdriver.Command('fake-command-name')));
139
}
140
141
/**
142
* @param {!webdriver.Command} command The command to send.
143
* @param {!Function=} opt_onSuccess The function to check the response with.
144
*/
145
function assertSendsSuccessfully(command, opt_onSuccess) {
146
return executor.execute(command)
147
.then(function(response) {
148
control.$verifyAll();
149
if (opt_onSuccess) {
150
opt_onSuccess(response);
151
}
152
});
153
}
154
155
/**
156
* @param {!webdriver.Command} command The command to send.
157
* @param {!Function=} opt_onError The function to check the error with.
158
*/
159
function assertFailsToSend(command, opt_onError) {
160
return executor.execute(command)
161
.then(fail, function(e) {
162
control.$verifyAll();
163
if (opt_onError) {
164
opt_onError(e);
165
}
166
});
167
}
168
169
function testExecute_clientFailsToSendRequest() {
170
var error = new Error('boom');
171
expectRequest('POST', '/session', {}, {
172
'Accept': 'application/json; charset=utf-8'
173
}).
174
$does(respondsWith(error));
175
control.$replayAll();
176
177
return assertFailsToSend(
178
new webdriver.Command(webdriver.CommandName.NEW_SESSION),
179
function(e) {
180
assertEquals(error, e);
181
});
182
}
183
184
function testExecute_commandWithNoUrlParameters() {
185
expectRequest('POST', '/session', {}, {
186
'Accept': 'application/json; charset=utf-8'
187
}).
188
$does(respondsWith(null, response(200, {}, '')));
189
control.$replayAll();
190
191
return assertSendsSuccessfully(
192
new webdriver.Command(webdriver.CommandName.NEW_SESSION));
193
}
194
195
function testExecute_rejectsCommandsMissingUrlParameters() {
196
var command =
197
new webdriver.Command(webdriver.CommandName.FIND_CHILD_ELEMENT).
198
setParameter('sessionId', 's123').
199
// Let this be missing: setParameter('id', {'ELEMENT': 'e456'}).
200
setParameter('using', 'id').
201
setParameter('value', 'foo');
202
203
control.$replayAll();
204
assertThrows(goog.bind(executor.execute, executor, command));
205
control.$verifyAll();
206
}
207
208
function testExecute_replacesUrlParametersWithCommandParameters() {
209
var command =
210
new webdriver.Command(webdriver.CommandName.GET).
211
setParameter('sessionId', 's123').
212
setParameter('url', 'http://www.google.com');
213
214
expectRequest('POST', '/session/s123/url',
215
{'url': 'http://www.google.com'},
216
{'Accept': 'application/json; charset=utf-8'}).
217
$does(respondsWith(null, response(200, {}, '')));
218
control.$replayAll();
219
220
return assertSendsSuccessfully(command);
221
}
222
223
function testExecute_returnsParsedJsonResponse() {
224
var responseObj = {
225
'status': bot.ErrorCode.SUCCESS,
226
'value': 'http://www.google.com'
227
};
228
var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
229
setParameter('sessionId', 's123');
230
231
expectRequest('GET', '/session/s123/url', {}, {
232
'Accept': 'application/json; charset=utf-8'
233
}).$does(respondsWith(null,
234
response(200, {'Content-Type': 'application/json'},
235
JSON.stringify(responseObj))));
236
control.$replayAll();
237
238
return assertSendsSuccessfully(command, function(response) {
239
webdriver.test.testutil.assertObjectEquals(responseObj, response);
240
});
241
}
242
243
function testExecute_returnsSuccessFor2xxWithBodyAsValueWhenNotJson() {
244
var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
245
setParameter('sessionId', 's123');
246
247
expectRequest('GET', '/session/s123/url', {}, {
248
'Accept': 'application/json; charset=utf-8'
249
}).$does(respondsWith(null,
250
response(200, {}, 'hello, world\r\ngoodbye, world!')));
251
control.$replayAll();
252
253
return assertSendsSuccessfully(command, function(response) {
254
webdriver.test.testutil.assertObjectEquals({
255
'status': bot.ErrorCode.SUCCESS,
256
'value': 'hello, world\ngoodbye, world!'
257
}, response);
258
});
259
}
260
261
function testExecute_returnsSuccessFor2xxInvalidJsonBody() {
262
var invalidJson = '[';
263
expectRequest('POST', '/session', {}, {
264
'Accept': 'application/json; charset=utf-8'
265
}).
266
$does(respondsWith(null, response(200, {
267
'Content-Type': 'application/json'
268
}, invalidJson)));
269
control.$replayAll();
270
271
return assertSendsSuccessfully(
272
new webdriver.Command(webdriver.CommandName.NEW_SESSION),
273
function(response) {
274
webdriver.test.testutil.assertObjectEquals({
275
'status': bot.ErrorCode.SUCCESS,
276
'value': invalidJson
277
}, response);
278
});
279
}
280
281
function testExecute_returnsUnknownCommandFor404WithBodyAsValueWhenNotJson() {
282
var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
283
setParameter('sessionId', 's123');
284
285
expectRequest('GET', '/session/s123/url', {}, {
286
'Accept': 'application/json; charset=utf-8'
287
}).$does(respondsWith(null,
288
response(404, {}, 'hello, world\r\ngoodbye, world!')));
289
control.$replayAll();
290
291
return assertSendsSuccessfully(command, function(response) {
292
webdriver.test.testutil.assertObjectEquals({
293
'status': bot.ErrorCode.UNKNOWN_COMMAND,
294
'value': 'hello, world\ngoodbye, world!'
295
}, response);
296
});
297
}
298
299
function testExecute_returnsUnknownErrorForGenericErrorCodeWithBodyAsValueWhenNotJson() {
300
var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
301
setParameter('sessionId', 's123');
302
303
expectRequest('GET', '/session/s123/url', {}, {
304
'Accept': 'application/json; charset=utf-8'
305
}).$does(respondsWith(null,
306
response(500, {}, 'hello, world\r\ngoodbye, world!')));
307
control.$replayAll();
308
309
return assertSendsSuccessfully(command, function(response) {
310
webdriver.test.testutil.assertObjectEquals({
311
'status': bot.ErrorCode.UNKNOWN_ERROR,
312
'value': 'hello, world\ngoodbye, world!'
313
}, response);
314
});
315
}
316
317
function testExecute_attemptsToParseBodyWhenNoContentTypeSpecified() {
318
var responseObj = {
319
'status': bot.ErrorCode.SUCCESS,
320
'value': 'http://www.google.com'
321
};
322
var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
323
setParameter('sessionId', 's123');
324
325
expectRequest('GET', '/session/s123/url', {}, {
326
'Accept': 'application/json; charset=utf-8'
327
}).$does(respondsWith(null,
328
response(200, {}, JSON.stringify(responseObj))));
329
control.$replayAll();
330
331
return assertSendsSuccessfully(command, function(response) {
332
webdriver.test.testutil.assertObjectEquals(responseObj, response);
333
});
334
}
335
336
function testCanDefineNewCommands() {
337
executor.defineCommand('greet', 'GET', '/person/:name');
338
339
var command = new webdriver.Command('greet').
340
setParameter('name', 'Bob');
341
342
expectRequest('GET', '/person/Bob', {},
343
{'Accept': 'application/json; charset=utf-8'}).
344
$does(respondsWith(null, response(200, {}, '')));
345
control.$replayAll();
346
347
return assertSendsSuccessfully(command);
348
}
349
350
function testCanRedefineStandardCommands() {
351
executor.defineCommand(webdriver.CommandName.GO_BACK,
352
'POST', '/custom/back');
353
354
var command = new webdriver.Command(webdriver.CommandName.GO_BACK).
355
setParameter('times', 3);
356
357
expectRequest('POST', '/custom/back',
358
{'times': 3},
359
{'Accept': 'application/json; charset=utf-8'}).
360
$does(respondsWith(null, response(200, {}, '')));
361
control.$replayAll();
362
363
return assertSendsSuccessfully(command);
364
}
365
366
function FakeXmlHttpRequest(headers, status, responseText) {
367
return {
368
getAllResponseHeaders: function() { return headers; },
369
status: status,
370
responseText: responseText
371
};
372
}
373
374
function testXmlHttpRequestToHttpResponse_parseHeaders_windows() {
375
var response = webdriver.http.Response.fromXmlHttpRequest(
376
FakeXmlHttpRequest([
377
'a:b',
378
'c: d',
379
'e :f',
380
'g : h'
381
].join('\r\n'), 200, ''));
382
assertEquals(200, response.status);
383
assertEquals('', response.body);
384
385
webdriver.test.testutil.assertObjectEquals({
386
'a': 'b',
387
'c': 'd',
388
'e': 'f',
389
'g': 'h'
390
}, response.headers);
391
}
392
393
function testXmlHttpRequestToHttpResponse_parseHeaders_unix() {
394
var response = webdriver.http.Response.fromXmlHttpRequest(
395
FakeXmlHttpRequest([
396
'a:b',
397
'c: d',
398
'e :f',
399
'g : h'
400
].join('\n'), 200, ''));
401
assertEquals(200, response.status);
402
assertEquals('', response.body);
403
404
webdriver.test.testutil.assertObjectEquals({
405
'a': 'b',
406
'c': 'd',
407
'e': 'f',
408
'g': 'h'
409
}, response.headers);
410
}
411
412
function testXmlHttpRequestToHttpResponse_noHeaders() {
413
var response = webdriver.http.Response.fromXmlHttpRequest(
414
FakeXmlHttpRequest('', 200, ''));
415
assertEquals(200, response.status);
416
assertEquals('', response.body);
417
webdriver.test.testutil.assertObjectEquals({}, response.headers);
418
}
419
420
function testXmlHttpRequestToHttpResponse_stripsNullCharactersFromBody() {
421
var response = webdriver.http.Response.fromXmlHttpRequest(
422
FakeXmlHttpRequest('', 200, '\x00\0foo\x00\x00bar\x00\0'));
423
assertEquals(200, response.status);
424
assertEquals('foobar', response.body);
425
webdriver.test.testutil.assertObjectEquals({}, response.headers);
426
}
427
428