util.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. "use strict";
  2. var extend = require("../lib/extend");
  3. var pollWorkerRetries = 30;
  4. var pollWorkerRetryInterval = 2000;
  5. var encoding = process.env.TRAVIS ? "base64" : "utf8";
  6. module.exports.browserStack = {
  7. username: Buffer.from(process.env.BROWSERSTACK_USERNAME || "", encoding).toString(),
  8. password: Buffer.from(process.env.BROWSERSTACK_KEY || "", encoding).toString()
  9. };
  10. module.exports.terminateWorkers = function terminateWorkers(client, workers, callback) {
  11. if (!workers.length) {
  12. return callback(null);
  13. }
  14. if (workers[0].id) {
  15. workers = workers.map(function(w) {
  16. return w.id;
  17. });
  18. }
  19. client.terminateWorker(workers.shift(), function() {
  20. if (!workers.length) {
  21. return callback(null);
  22. }
  23. terminateWorkers(client, workers, callback);
  24. });
  25. };
  26. module.exports.pollApiWorker = function pollApiWorker(client, worker, callback) {
  27. pollWorker(worker,
  28. client.getWorker.bind(client),
  29. function getWorkerId(worker) {
  30. return worker && worker.id;
  31. },
  32. function isWorkerRunning(worker) {
  33. return worker && worker.status === "running";
  34. }, callback);
  35. };
  36. module.exports.pollScreenshotWorker = function pollScreenshotWorker(client, worker, callback) {
  37. pollWorker(worker,
  38. client.getJob.bind(client),
  39. function getWorkerId(worker) {
  40. return worker && (worker.job_id || worker.id);
  41. },
  42. function isWorkerRunning(worker) {
  43. return worker && worker.state === "running";
  44. }, callback);
  45. };
  46. module.exports.validateBrowserObject = function validateBrowserObject(browser) {
  47. [
  48. "os",
  49. "os_version",
  50. "browser",
  51. browser.device ? "device" : "browser_version"
  52. ].forEach(function(attr) {
  53. if (attr.match(/version/)) {
  54. browser[attr].should.be.a.String().and.match(/\S+/);
  55. } else {
  56. browser[attr].should.be.a.String().and.match(/^[a-zA-Z]+/);
  57. }
  58. });
  59. return browser;
  60. };
  61. module.exports.validateScreenshotJob = function validateScreenshotJob(job) {
  62. job.should.be.an.Object().and.not.be.empty();
  63. (job.job_id || job.id).should.match(/[a-zA-Z0-9]+/);
  64. [
  65. "quality",
  66. "win_res",
  67. "wait_time"
  68. ].forEach(function(k) {
  69. job.should.have.property(k);
  70. });
  71. job.screenshots
  72. .map(this.validateBrowserObject)
  73. .forEach(function(screenshotState) {
  74. screenshotState.id.should.match(/[a-zA-Z0-9]+/);
  75. ["processing", "pending", "queue", "running"].should.containEql(screenshotState.state);
  76. });
  77. };
  78. module.exports.validateWorker = function validateWorker(w) {
  79. w.should.be.an.Object();
  80. w.id.should.match(/\d+/);
  81. return w;
  82. };
  83. module.exports.merge = function merge(o, a) {
  84. return extend(extend({}, o), a);
  85. };
  86. function pollWorker(worker, getWorkerStatusFn, getWorkerIdFn, isWorkerRunningFn, callback) {
  87. var maxRetries = pollWorkerRetries;
  88. var retryInterval = pollWorkerRetryInterval;
  89. var workerId = getWorkerIdFn(worker);
  90. var timer;
  91. var pollWorkerState = function(id, callback) {
  92. if (--maxRetries < 1) {
  93. clearTimeout(timer);
  94. return callback(null, false);
  95. }
  96. getWorkerStatusFn(workerId, function(err, worker) {
  97. workerId = getWorkerIdFn(worker);
  98. if (err || !workerId) {
  99. clearTimeout(timer);
  100. return callback(err, false);
  101. }
  102. if (isWorkerRunningFn(worker)) {
  103. return callback(null, true);
  104. }
  105. setTimeout(function() {
  106. pollWorkerState(id, callback);
  107. }, retryInterval);
  108. });
  109. };
  110. pollWorkerState(workerId, callback);
  111. }