Repository: saucelabs/node-saucelabs
Pull request #96 (2020-09-15 14:13:35)

Support custom header
- request headers can be set by using `headers` option.
- set default headers



Patch:
diff --git a/README.md b/README.md
index a451714..9340d13 100644
--- a/README.md
+++ b/README.md
@@ -55,6 +55,13 @@ If you want to tunnel your API request through a proxy please provide your proxy
 Type: `string`<br>
 Default: `null`
 
+### headers
+
+If you want to set request headers, as example {'User-Agent': 'node-saucelabs'}
+
+Type: `object`<br>
+Default: `{'User-Agent': 'saucelabs/<VERSION> (nodejs <PLATFORM>)'}`
+
 ## Usage
 
 All accessible API commands with descriptions can be found [here](docs/interface.md).
diff --git a/scripts/constants.js b/scripts/constants.js
index eb1dd53..2043ff2 100644
--- a/scripts/constants.js
+++ b/scripts/constants.js
@@ -31,6 +31,10 @@ export interface SauceLabsOptions {
      * If you want to tunnel your API request through a proxy please provide your proxy URL.
      */
     proxy?: string;
+    /**
+     * If you want to set request headers, as example {'User-Agent': 'node-saucelabs'}
+     */
+    headers?: object;
 }`
 
 exports.TC_SAUCE_CONNECT_OBJ = `
diff --git a/src/constants.js b/src/constants.js
index 5ee9f5e..e47e9cd 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -1,4 +1,6 @@
 import { camelCase } from 'change-case'
+import os from 'os'
+
 import { version } from '../package.json'
 
 export const DEFAULT_SAUCE_CONNECT_VERSION = '4.6.2'
@@ -69,7 +71,8 @@ export const DEFAULT_OPTIONS = {
     key: process.env.SAUCE_ACCESS_KEY,
     headless: false,
     region: 'us',
-    proxy: process.env.HTTPS_PROXY || process.env.HTTP_PROXY
+    proxy: process.env.HTTPS_PROXY || process.env.HTTP_PROXY,
+    headers: { 'User-Agent': `saucelabs/v${version} (nodejs ${os.platform()})` },
 }
 
 export const ASSET_REGION_MAPPING = {
diff --git a/src/index.js b/src/index.js
index 26a677a..b2979a9 100644
--- a/src/index.js
+++ b/src/index.js
@@ -29,6 +29,7 @@ export default class SauceLabs {
             password: this._accessKey,
             https: { rejectUnauthorized: getStrictSsl() },
             followRedirect: true,
+            headers: this._options.headers
         })
 
         if (typeof this._options.proxy === 'string') {
@@ -52,7 +53,8 @@ export default class SauceLabs {
             region: this._options.region,
             headless: this._options.headless,
             proxy: this._options.proxy,
-            webdriverEndpoint: this.webdriverEndpoint
+            webdriverEndpoint: this.webdriverEndpoint,
+            headers: this._options.headers
         }, { get: ::this.get })
     }
 


Test patch:
diff --git a/tests/__snapshots__/index.test.js.snap b/tests/__snapshots__/index.test.js.snap
index 6b5f922..42d52ee 100644
--- a/tests/__snapshots__/index.test.js.snap
+++ b/tests/__snapshots__/index.test.js.snap
@@ -1,5 +1,11 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`should contain custom headers 1`] = `
+Object {
+  "user-agent": "foo",
+}
+`;
+
 exports[`startSauceConnect should not overwrite rest-url if given as a parameter 1`] = `
 Array [
   Array [
diff --git a/tests/index.test.js b/tests/index.test.js
index 60727d6..7f7903c 100644
--- a/tests/index.test.js
+++ b/tests/index.test.js
@@ -327,6 +327,16 @@ test('should not even try to upload if no files were selected', async () => {
     expect(result.message).toBe('No files to upload selected')
 })
 
+test('should contain custom headers', async () => {
+    const api = new SauceLabs({ user: 'foo', key: 'bar', headers: { 'user-agent': 'foo' } })
+    got.mockReturnValue(Promise.resolve({
+        body: JSON.stringify({ foo: 'bar' })
+    }))
+    await api.updateTest('123', '{ "passed": false }')
+    const requestOptions = got.extend.mock.calls[0][0]
+    expect(requestOptions.headers).toMatchSnapshot()
+})
+
 describe('startSauceConnect', () => {
     it('should start sauce connect with proper parsed args', async () => {
         const logs = []