123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- var util = require("util");
- var BaseClient = require("./client");
- var extend = require("./extend");
- function ApiBaseClient(settings) {
- this.server = {
- host: "api.browserstack.com"
- };
- BaseClient.call(this, settings);
- }
- util.inherits(ApiBaseClient, BaseClient);
- // public API
- extend(ApiBaseClient.prototype, {
- getBrowsers: function(fn) {
- this._getBrowsers(function(error, browsers) {
- if (!error) {
- this.updateLatest(browsers);
- }
- fn(error, browsers);
- }.bind(this));
- },
- createWorker: function(options, fn) {
- if (options[this.versionField] === "latest") {
- return this.getLatest(options, function(error, version) {
- if (error) {
- return fn(error);
- }
- options = extend({}, options);
- options[this.versionField] = version;
- this.createWorker(options, fn);
- }.bind(this));
- }
- var data = JSON.stringify(options);
- this.request({
- path: this.path("/worker"),
- method: "POST"
- }, data, fn);
- },
- getWorker: function(id, fn) {
- this.request({
- path: this.path("/worker/" + id)
- }, fn);
- },
- changeUrl: function(id, options, fn) {
- var data = JSON.stringify(options);
- this.request({
- path: this.path("/worker/" + id + "/url.json"),
- method: "PUT"
- }, data, fn);
- },
- terminateWorker: function(id, fn) {
- this.request({
- path: this.path("/worker/" + id),
- method: "DELETE"
- }, fn);
- },
- getWorkers: function(fn) {
- this.request({
- path: this.path("/workers")
- }, fn);
- },
- getLatest: function(browser, fn) {
- var latest = this.latest;
- if (typeof browser === "function") {
- fn = browser;
- browser = null;
- }
- // there may be a lot of createWorker() calls with "latest" version
- // so minimize the number of calls to getBrowsers()
- if (this.latestPending) {
- return setTimeout(function() {
- this.getLatest(browser, fn);
- }.bind(this), 50);
- }
- // only cache browsers for one day
- if (!latest || this.latestUpdate < (new Date() - 864e5)) {
- this.latestPending = true;
- return this.getBrowsers(function(error) {
- this.latestPending = false;
- if (error) {
- return fn(error);
- }
- this.getLatest(browser, fn);
- }.bind(this));
- }
- process.nextTick(function() {
- fn(null, browser ? latest[this.getBrowserId(browser)] : extend({}, latest));
- }.bind(this));
- },
- takeScreenshot: function(id, fn) {
- this.request({
- path: this.path("/worker/" + id + "/screenshot.json")
- }, fn);
- }
- });
- // internal API
- extend(ApiBaseClient.prototype, {
- latest: null,
- latestUpdate: 0,
- latestPending: false,
- path: function(path) {
- return "/" + this.version + path;
- },
- updateLatest: function(browsers) {
- var latest = this.latest = {};
- var getBrowserId = this.getBrowserId.bind(this);
- var versionField = this.versionField;
- this.latestUpdate = new Date();
- browsers.forEach(function(browser) {
- var version = browser[versionField];
- var browserId = getBrowserId(browser);
- // ignore devices that don't have versions
- if (!version) {
- return;
- }
- // ignore pre-release versions
- if (/\s/.test(version)) {
- return;
- }
- if (parseFloat(version) > (parseFloat(latest[browserId]) || 0)) {
- latest[browserId] = version;
- }
- });
- },
- getBrowserId: function(browser) {
- return this._getBrowserId(browser).toLowerCase();
- }
- });
- // Versions
- ApiBaseClient.versions = {};
- ApiBaseClient.latestVersion = 0;
- ApiBaseClient.createVersion = function(version, prototype) {
- function ApiClient(settings) {
- ApiBaseClient.call(this, settings);
- }
- util.inherits(ApiClient, ApiBaseClient);
- ApiClient.prototype.version = version;
- extend(ApiClient.prototype, prototype);
- ApiBaseClient.versions[version] = ApiClient;
- ApiBaseClient.latestVersion = Math.max(ApiBaseClient.latestVersion, version);
- };
- ApiBaseClient.createVersion(1, {
- useHttp: true,
- versionField: "version",
- _getBrowsers: function(fn) {
- this.request({
- path: this.path("/browsers")
- }, fn);
- },
- _getBrowserId: function(browser) {
- return browser.browser;
- }
- });
- ApiBaseClient.createVersion(2, {
- useHttp: true,
- versionField: "version",
- _getBrowsers: function(fn) {
- this.request({
- path: this.path("/browsers")
- }, function(error, osBrowsers) {
- if (error) {
- return fn(error);
- }
- fn(null, [].concat.apply([],
- Object.keys(osBrowsers).map(function(os) {
- return osBrowsers[os].map(function(browser) {
- browser.os = os;
- return browser;
- });
- })
- ));
- });
- },
- _getBrowserId: function(browser) {
- return browser.os + ":" + (browser.browser || browser.device);
- }
- });
- ApiBaseClient.createVersion(3, {
- useHttp: true,
- versionField: "browser_version",
- _getBrowsers: function(fn) {
- this.request({
- path: this.path("/browsers?flat=true")
- }, fn);
- },
- _getBrowserId: function(browser) {
- var id = browser.os + ":" + browser.os_version + ":" + browser.browser;
- if (browser.device) {
- id += ":" + browser.device;
- }
- return id;
- },
- getApiStatus: function(fn) {
- this.request({
- path: this.path("/status")
- }, fn);
- }
- });
- ApiBaseClient.createVersion(4, {
- versionField: "browser_version",
- _getBrowsers: function(fn) {
- this.request({
- path: this.path("/browsers?flat=true")
- }, fn);
- },
- _getBrowserId: function(browser) {
- var id = browser.os + ":" + browser.os_version + ":" + browser.browser;
- if (browser.device) {
- id += ":" + browser.device;
- }
- return id;
- },
- getApiStatus: function(fn) {
- this.request({
- path: this.path("/status")
- }, fn);
- }
- });
- module.exports = {
- createClient: function(settings) {
- var ApiClient = ApiBaseClient.versions[settings.version || ApiBaseClient.latestVersion];
- if (!ApiClient) {
- throw new Error("Invalid version");
- }
- return new ApiClient(settings);
- }
- };
|