api.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. "use strict";
  2. var should = require("should");
  3. var BrowserStack = require("../lib/browserstack");
  4. var util = require("./util");
  5. var username = util.browserStack.username;
  6. var password = util.browserStack.password;
  7. if (!username || !password) {
  8. throw new Error("Please set BROWSERSTACK_USERNAME and BROWSERSTACK_KEY environment variables.");
  9. }
  10. describe("BrowserStack API", function() {
  11. this.timeout(60000); // 60s
  12. var client;
  13. var workers = [];
  14. beforeEach(function() {
  15. client = BrowserStack.createClient({
  16. username: username,
  17. password: password
  18. });
  19. });
  20. afterEach(function(done) {
  21. util.terminateWorkers(client, workers, function() {
  22. workers = [];
  23. done();
  24. });
  25. });
  26. describe("API Status", function() {
  27. it("should get API status", function(done) {
  28. client.getApiStatus(function(err, status) {
  29. should.ifError(err);
  30. status.should.be.an.Object().and.have.keys([
  31. "running_sessions",
  32. "sessions_limit",
  33. "used_time",
  34. "total_available_time"
  35. ]);
  36. done(err);
  37. });
  38. });
  39. });
  40. describe("Browser Listing", function() {
  41. it("should list browsers", function(done) {
  42. client.getBrowsers(function(err, browsers) {
  43. should.ifError(err);
  44. browsers.should.be.an.Array().and.not.be.empty();
  45. browsers.map(util.validateBrowserObject);
  46. done(err);
  47. });
  48. });
  49. it("should get latest browser versions", function(done) {
  50. client.getLatest(function(err, versions) {
  51. should.ifError(err);
  52. versions.should.be.an.Object().and.not.be.empty();
  53. done(err);
  54. });
  55. });
  56. it("should get the latest version for specified browser", function(done) {
  57. client.getBrowsers(function(err, browsers) {
  58. should.ifError(err);
  59. browsers = browsers.filter(function(browser) {
  60. return !browser.device;
  61. });
  62. var requests = browsers.length;
  63. browsers.forEach(function(browser) {
  64. client.getLatest(browser, function(err, version) {
  65. should.ifError(err);
  66. version.should.match(/\d+(\.)*\d*/);
  67. if (err || --requests < 1) {
  68. if (done) {
  69. done(err);
  70. done = null;
  71. }
  72. }
  73. });
  74. });
  75. });
  76. });
  77. it("should fail to get the latest version for invalid browser", function(done) {
  78. client.getLatest({
  79. os: "Windows",
  80. os_version: "10",
  81. browser: "mosaic"
  82. }, function(err, version) {
  83. should.ifError(err);
  84. should.equal(undefined, version);
  85. done(err);
  86. });
  87. });
  88. });
  89. describe("Worker API", function() {
  90. var sampleDesktopBrowser = {
  91. os: "Windows",
  92. os_version: "10",
  93. browser: "chrome",
  94. browser_version: "47.0",
  95. timeout: 20
  96. };
  97. var sampleDeviceBrowser = {
  98. device: "Google Nexus 6",
  99. os: "android",
  100. os_version: "5.0",
  101. browser: "Android Browser",
  102. timeout: 20
  103. };
  104. it("should create worker", function(done) {
  105. client.createWorker(util.merge(sampleDesktopBrowser, {
  106. url: "http://www.example.com"
  107. }), function(err, worker) {
  108. should.ifError(err);
  109. util.validateWorker(worker);
  110. workers.push(worker);
  111. done(err);
  112. });
  113. });
  114. it("should create worker with latest edge", function(done) {
  115. client.createWorker({
  116. os: "Windows",
  117. os_version: "10",
  118. browser: "Edge",
  119. browser_version: "latest",
  120. url: "http://www.example.com",
  121. timeout: 20
  122. }, function(err, worker) {
  123. should.ifError(err);
  124. util.validateWorker(worker);
  125. workers.push(worker);
  126. done(err);
  127. });
  128. });
  129. it("should fail to create worker for invalid browser", function(done) {
  130. client.createWorker(util.merge(sampleDesktopBrowser, {
  131. url: "http://www.example.com",
  132. browser: "mosaic"
  133. }), function(err, worker) {
  134. err.should.be.an.Error();
  135. err.message.should.match(/validation failed/i);
  136. should.not.exist(worker);
  137. done();
  138. });
  139. });
  140. it("should create a worker with details", function(done) {
  141. client.createWorker(util.merge(sampleDesktopBrowser, {
  142. url: "http://www.example.com",
  143. name: "worker-1",
  144. build: "build-1",
  145. project: "project-1"
  146. }), function(err, worker) {
  147. should.ifError(err);
  148. util.validateWorker(worker);
  149. workers.push(worker);
  150. done(err);
  151. });
  152. });
  153. it("should create a worker for a device browser", function(done) {
  154. client.createWorker(util.merge(sampleDeviceBrowser, {
  155. url: "http://www.example.com"
  156. }), function(err, worker) {
  157. should.ifError(err);
  158. util.validateWorker(worker);
  159. workers.push(worker);
  160. done(err);
  161. });
  162. });
  163. it("should fail to create worker for invalid device", function(done) {
  164. client.createWorker(util.merge(sampleDeviceBrowser, {
  165. url: "http://www.example.com",
  166. device: "Nexus 5S"
  167. }), function(err, worker) {
  168. err.should.be.an.Error();
  169. err.message.should.match(/validation failed/i);
  170. should.not.exist(worker);
  171. done();
  172. });
  173. });
  174. it("should get created worker by id", function(done) {
  175. client.createWorker(util.merge(sampleDeviceBrowser, {
  176. url: "http://www.example.com"
  177. }), function(err, worker) {
  178. should.ifError(err);
  179. util.validateWorker(worker);
  180. workers.push(worker);
  181. client.getWorker(worker.id, function(err, worker2) {
  182. should.ifError(err);
  183. util.validateWorker(worker2);
  184. should.equal(worker.id, worker2.id, "Worker id mismatch");
  185. done(err);
  186. });
  187. });
  188. });
  189. it("should fetch list of workers", function(done) {
  190. client.createWorker(util.merge(sampleDeviceBrowser, {
  191. url: "http://www.example.com"
  192. }), function(err, worker) {
  193. should.ifError(err);
  194. util.validateWorker(worker);
  195. workers.push(worker);
  196. client.getWorkers(function(err, workers) {
  197. should.ifError(err);
  198. workers.should.be.an.Array().and.not.be.empty();
  199. var workerExists = workers.filter(function(w) {
  200. util.validateWorker(w);
  201. return (w.id === worker.id);
  202. }).shift();
  203. done(workerExists ? null : new Error("failed to fetch created worker"));
  204. });
  205. });
  206. });
  207. it("should terminate a worker by id", function(done) {
  208. client.createWorker(util.merge(sampleDeviceBrowser, {
  209. url: "http://www.example.com"
  210. }), function(err, worker) {
  211. should.ifError(err);
  212. util.validateWorker(worker);
  213. workers.push(worker);
  214. client.terminateWorker(worker.id, function(err, data) {
  215. should.ifError(err);
  216. data.should.be.an.Object();
  217. data.time.should.match(/\d+/);
  218. done(err);
  219. });
  220. });
  221. });
  222. });
  223. describe("Worker Session APIs", function() {
  224. this.timeout(100000);
  225. var sampleDesktopBrowser = {
  226. os: "Windows",
  227. os_version: "10",
  228. browser: "chrome",
  229. browser_version: "47.0",
  230. timeout: 120
  231. };
  232. it("should change worker url", function(done) {
  233. client.createWorker(util.merge(sampleDesktopBrowser, {
  234. url: "http://www.example.com"
  235. }), function(err, worker) {
  236. should.ifError(err);
  237. util.validateWorker(worker);
  238. workers.push(worker);
  239. util.pollApiWorker(client, worker, function(err, isRunning) {
  240. if (isRunning) {
  241. return client.changeUrl(worker.id, {
  242. url: "http://www.example.net",
  243. timeout: 20
  244. }, function(err, data) {
  245. should.ifError(err);
  246. data.should.be.an.Object();
  247. data.message.should.match(/browser updated with new url/i);
  248. done(err);
  249. });
  250. }
  251. should.ifError(err);
  252. return done(err || new Error("worker remained in queue until timeout"));
  253. });
  254. });
  255. });
  256. it("should take screenshot of worker session", function(done) {
  257. client.createWorker(util.merge(sampleDesktopBrowser, {
  258. url: "http://www.example.com"
  259. }), function(err, worker) {
  260. should.ifError(err);
  261. util.validateWorker(worker);
  262. workers.push(worker);
  263. util.pollApiWorker(client, worker, function(err, isRunning) {
  264. if (isRunning) {
  265. // wait for page load
  266. var pageLoadTime = 5000;
  267. return setTimeout(function() {
  268. client.takeScreenshot(worker.id, function(err, data) {
  269. should.ifError(err);
  270. data.should.be.an.Object();
  271. data.url.should.match(/^http(s)?:\/\/.*\.png$/i);
  272. done(err);
  273. });
  274. }, pageLoadTime);
  275. }
  276. should.ifError(err);
  277. return done(err || new Error("worker remained in queue until timeout"));
  278. });
  279. });
  280. });
  281. });
  282. });