saucelabs
Advanced tools
Comparing version 4.0.0 to 4.0.1
@@ -737,9 +737,16 @@ { | ||
"parameters": { | ||
"filename": { | ||
"description": "filename", | ||
"assetName": { | ||
"description": "filename of the asset", | ||
"in": "path", | ||
"name": "filename", | ||
"name": "assetName", | ||
"required": true, | ||
"type": "string" | ||
}, | ||
"filepath": { | ||
"description": "file path to store the asset at", | ||
"in": "path", | ||
"name": "filepath", | ||
"required": false, | ||
"type": "string" | ||
}, | ||
"full": { | ||
@@ -2294,3 +2301,6 @@ "description": "Should the return result contain everything or just the basics", | ||
{ | ||
"$ref": "#/parameters/filename" | ||
"$ref": "#/parameters/assetName" | ||
}, | ||
{ | ||
"$ref": "#/parameters/filepath" | ||
} | ||
@@ -2297,0 +2307,0 @@ ], |
@@ -39,3 +39,3 @@ "use strict"; | ||
} | ||
}, argv => { | ||
}, async argv => { | ||
const { | ||
@@ -54,4 +54,6 @@ user, | ||
const requiredParams = params.filter(p => p.required).map(p => argv[p.name]); | ||
api[commandName](...requiredParams, argv).then(result => { | ||
/* istanbul ignore if */ | ||
try { | ||
const result = await api[commandName](...requiredParams, argv); | ||
if (typeof result === 'object') { | ||
@@ -64,9 +66,8 @@ // eslint-disable-next-line no-console | ||
console.log(result); | ||
}, | ||
/* istanbul ignore next */ | ||
error => { | ||
} catch (error) { | ||
// eslint-disable-next-line no-console | ||
console.error(error); | ||
process.exit(1); | ||
}); | ||
return process.exit(1); | ||
} | ||
return api; | ||
@@ -73,0 +74,0 @@ }); |
@@ -38,3 +38,5 @@ "use strict"; | ||
/* istanbul ignore if */ | ||
if (protocolFlattened.has(commandName)) { | ||
@@ -41,0 +43,0 @@ throw new Error(`command ${commandName} already registered`); |
export interface SauceLabsOptions { | ||
/** | ||
* Your Sauce Labs username. | ||
*/ | ||
user: string; | ||
/** | ||
* Your Sauce Labs access key. | ||
*/ | ||
key: string; | ||
/** | ||
* Your Sauce Labs datacenter region. The following regions are available: | ||
* | ||
* - us-west-1 (short 'us') | ||
* - eu-central-1 (short 'eu') | ||
* - us-east-1 (headless) | ||
*/ | ||
region?: "us" | "eu" | "us-west-1" | "eu-central-1"; | ||
/** | ||
* If set to true you are accessing the headless Sauce instances (this discards the region option). | ||
*/ | ||
headless?: boolean; | ||
proxy?: string; | ||
/** | ||
* If you want to tunnel your API request through a proxy please see the [got proxy docs](https://github.com/sindresorhus/got/blob/master/readme.md#proxies) for more information. | ||
*/ | ||
proxy?: object; | ||
} | ||
@@ -2262,7 +2281,12 @@ | ||
* @param {string} id - job id | ||
* @param {string} filename - filename | ||
* @param {string} assetName - filename of the asset | ||
* @param {string} filepath - file path to store the asset at | ||
*/ | ||
downloadJobAsset(id: string, filename: string): Promise<File>; | ||
downloadJobAsset( | ||
id: string, | ||
assetName: string, | ||
filepath?: string | ||
): Promise<File>; | ||
} | ||
export default SauceLabs; |
@@ -27,4 +27,9 @@ "use strict"; | ||
this._accessKey = this._options.key; | ||
this._auth = `${this.username}:${this._accessKey}`; | ||
this.proxy = this._options.proxy; | ||
this._api = _got.default.extend({ | ||
username: this.username, | ||
password: this._accessKey, | ||
rejectUnauthorized: (0, _utils.getStrictSsl)(), | ||
proxy: this._options.proxy, | ||
followRedirect: true | ||
}); | ||
/** | ||
@@ -181,13 +186,12 @@ * public fields | ||
try { | ||
const response = await _got.default[method](uri, { | ||
[method === 'get' ? 'searchParams' : 'body']: body, | ||
json: true, | ||
auth: this._auth, | ||
rejectUnauthorized: (0, _utils.getStrictSsl)(), | ||
proxy: this.proxy | ||
const response = await this._api[method](uri, { ...(method === 'get' ? { | ||
searchParams: body | ||
} : { | ||
json: body | ||
}), | ||
responseType: 'json' | ||
}); | ||
return response.body; | ||
} catch (err) { | ||
const reason = (0, _utils.getErrorReason)(err.body); | ||
throw new Error(`Failed calling ${propName}, status code: ${err.statusCode}, reason: ${reason}`); | ||
throw new Error(`Failed calling ${propName}: ${err.message}`); | ||
} | ||
@@ -197,3 +201,5 @@ }; | ||
async _downloadJobAsset(jobId, assetName, downloadPath) { | ||
async _downloadJobAsset(jobId, assetName, { | ||
filepath | ||
} = {}) { | ||
/** | ||
@@ -208,8 +214,8 @@ * check job id | ||
const host = (0, _utils.getSauceEndpoint)('saucelabs.com', this._options.region, this._options.headless, 'https://assets.'); | ||
const responseType = assetName.endsWith('mp4') ? 'buffer' : 'text'; | ||
const uri = `${host}/jobs/${jobId}/${assetName}?ts=${Date.now()}&auth=${hmac}`; | ||
try { | ||
const res = await _got.default.get(`${host}/jobs/${jobId}/${assetName}?ts=${Date.now()}&auth=${hmac}`, { | ||
method: 'GET', | ||
rejectUnauthorized: (0, _utils.getStrictSsl)(), | ||
proxy: this.proxy | ||
const res = await this._api.get(uri, { | ||
responseType | ||
}); | ||
@@ -228,4 +234,16 @@ /** | ||
if (typeof downloadPath === 'string') { | ||
_fs.default.writeFileSync(_path.default.resolve(process.cwd(), downloadPath), res.body); | ||
if (typeof filepath === 'string') { | ||
let data = res.body; | ||
const downloadPath = _path.default.resolve(process.cwd(), filepath); | ||
const encoding = res.headers['content-type'] === 'application/json' ? 'utf8' : 'binary'; | ||
if (res.headers['content-type'] === 'application/json') { | ||
data = JSON.stringify(res.body, null, 4); | ||
} | ||
_fs.default.writeFileSync(downloadPath, data, { | ||
encoding | ||
}); | ||
} | ||
@@ -235,4 +253,3 @@ | ||
} catch (err) { | ||
const reason = (0, _utils.getErrorReason)(err.body); | ||
throw new Error(`There was an error downloading asset ${assetName}, status code: ${err.statusCode}, reason: ${reason}`); | ||
throw new Error(`There was an error downloading asset ${assetName}: ${err.message}`); | ||
} | ||
@@ -239,0 +256,0 @@ } |
@@ -11,3 +11,2 @@ "use strict"; | ||
exports.isValidType = isValidType; | ||
exports.getErrorReason = getErrorReason; | ||
exports.getStrictSsl = getStrictSsl; | ||
@@ -129,32 +128,2 @@ | ||
/** | ||
* get error message from API call | ||
* @param {*} body body message of response | ||
* @return {String} error message | ||
*/ | ||
function getErrorReason(body = {}) { | ||
if (typeof body === 'string') { | ||
try { | ||
body = JSON.parse(body); | ||
} catch (e) { | ||
body = { | ||
message: body | ||
}; | ||
} | ||
} | ||
/** | ||
* due to a bug in the performance API we need to workaround this | ||
*/ | ||
if (Array.isArray(body)) { | ||
body = { | ||
message: body[0] | ||
}; | ||
} | ||
return body.message || body.detail || 'unknown'; | ||
} | ||
/** | ||
* If the environment variable "STRICT_SSL" is defined as "false", it doesn't require SSL certificates to be valid. | ||
@@ -161,0 +130,0 @@ * This is used in requests to define the value of the "strictSSL" option. |
@@ -56,3 +56,3 @@ SauceLabs Interface | ||
<br><h4>Options</h4> | ||
<ul> <li><b>auto_only</b>: FIXME ---- ?</li> <li><b>to</b>: receive jobs until specific timestamp</li> <li><b>from</b>: receive jobs beginning of a specific timestamp</li> <li><b>owner</b>: username of owner of the jobs</li> <li><b>owner_type</b>: owner type for jobs</li> <li><b>name</b>: name of the job</li> <li><b>limit</b>: Number of results to return</li> <li><b>manual_only</b>: Only return manual jobs</li> <li><b>full</b>: Should the return result contain everything or just the basics</li> <li><b>subaccounts</b>: Include subaccounts in list of jobs</li> </ul> </td> | ||
<ul> <li><b>auto_only</b>: No description available.</li> <li><b>to</b>: receive jobs until specific timestamp</li> <li><b>from</b>: receive jobs beginning of a specific timestamp</li> <li><b>owner</b>: username of owner of the jobs</li> <li><b>owner_type</b>: owner type for jobs</li> <li><b>name</b>: name of the job</li> <li><b>limit</b>: Number of results to return</li> <li><b>manual_only</b>: Only return manual jobs</li> <li><b>full</b>: Should the return result contain everything or just the basics</li> <li><b>subaccounts</b>: Include subaccounts in list of jobs</li> </ul> </td> | ||
</tr> | ||
@@ -157,2 +157,10 @@ <tr> | ||
<td> | ||
<b>GET</b> <code>/v1/users/{username}/subaccounts</code><br> | ||
No description available. | ||
<h3>Example:</h3> | ||
<code>api.getSubaccounts(username)</code> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<b>GET</b> <code>/v1/users/{username}/activity</code><br> | ||
@@ -275,4 +283,5 @@ No description available. | ||
<h3>Example:</h3> | ||
<code>api.downloadJobAsset(id, filename)</code> | ||
</td> | ||
<code>api.downloadJobAsset(id, assetName, { ...options })</code> | ||
<br><h4>Options</h4> | ||
<ul> <li><b>filepath</b>: file path to store the asset at</li> </ul> </td> | ||
</tr> | ||
@@ -686,2 +695,2 @@ <tr> | ||
</tr> | ||
</tbody></table> | ||
</tbody></table> |
{ | ||
"name": "saucelabs", | ||
"version": "4.0.0", | ||
"version": "4.0.1", | ||
"author": "Christian Bromann <christian@saucelabs.com>", | ||
@@ -22,3 +22,3 @@ "description": "A wrapper around Sauce Labs REST API", | ||
"scripts": { | ||
"build": "run-s clean compile", | ||
"build": "run-s clean compile generate:typings", | ||
"clean": "rm -rf ./build ./coverage", | ||
@@ -34,4 +34,8 @@ "compile": "babel src -d build", | ||
"release:major": "np major", | ||
"test": "run-s eslint test:unit", | ||
"test": "run-s build eslint test:typings test:unit", | ||
"test:unit": "jest --coverage", | ||
"test:typings": "run-s test:typings:*", | ||
"test:typings:setup": "mkdir -p ./tests/typings/node_modules/saucelabs && cp ./package.json ./tests/typings/node_modules/saucelabs && cp -r ./build ./tests/typings/node_modules/saucelabs", | ||
"test:typings:run": "cd ./tests/typings && tsc --incremental", | ||
"test:typings:cleanup": "rm -r ./tests/typings/node_modules", | ||
"watch": "npm run compile -- --watch" | ||
@@ -69,3 +73,4 @@ }, | ||
"source-map-support": "^0.5.9", | ||
"swagger-typescript-codegen": "^1.10.0" | ||
"swagger-typescript-codegen": "^1.10.0", | ||
"typescript": "^3.8.3" | ||
}, | ||
@@ -80,6 +85,6 @@ "jest": { | ||
"global": { | ||
"branches": 95, | ||
"branches": 94, | ||
"functions": 100, | ||
"lines": 97, | ||
"statements": 97 | ||
"lines": 96, | ||
"statements": 96 | ||
} | ||
@@ -86,0 +91,0 @@ }, |
@@ -92,2 +92,7 @@ <p align="center"> | ||
or download a job asset: | ||
```sh | ||
sl downloadJobAsset 690c5877710c422d8be4c622b40c747f video.mp4 --filepath ./video.mp4 | ||
### As NPM Package | ||
@@ -94,0 +99,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
207
291456
25
13
8721