Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updating sauce connect api #260

Merged
merged 3 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions apis/sauce.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,84 @@
},
"type": "object"
},
"SauceConnectDownloadInfo": {
"type": "object",
"properties": {
"download_url": {
"type": "string"
},
"sha1": {
"type": "string",
"nullable": true
},
"sha256": {
"type": "string",
"nullable": true
},
"version": {
"type": "string",
"nullable": true
}
}
},
"SauceConnectByPlatform": {
"type": "object",
"properties": {
"linux": {
"$ref": "#/definitions/SauceConnectDownloadInfo",
"nullable": true
},
"linux-arm64": {
"$ref": "#/definitions/SauceConnectDownloadInfo",
"nullable": true
},
"win32": {
"$ref": "#/definitions/SauceConnectDownloadInfo",
"nullable": true
},
"osx": {
"$ref": "#/definitions/SauceConnectDownloadInfo"
}
}
},
"SauceConnectVersions": {
"type": "object",
"properties": {
"latest_version": {
"type": "string"
},
"client_version": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["LATEST", "UPGRADE", "PRERELEASE", "UNKNOWN", "EOL"]
},
"info_url": {
"type": "string"
},
"download_url": {
"type": "string"
},
"sha1": {
"type": "string",
"nullable": true
},
"sha256": {
"type": "string",
"nullable": true
}
},
"downloads": {
"$ref": "#/definitions/SauceConnectByPlatform"
},
"all_downloads": {
"type": "array",
"items": {
"$ref": "#/definitions/SauceConnectByPlatform"
}
}
},
"SauceStatus": {
"properties": {
"service_operational": {
Expand Down Expand Up @@ -742,6 +820,20 @@
"required": true,
"type": "string"
},
"clientHost": {
"description": "SC client host OS and CPU arch",
"in": "query",
"name": "client_host",
"required": false,
"type": "string"
},
"clientVersion": {
"description": "SC client version",
"in": "query",
"name": "client_version",
"required": false,
"type": "string"
},
"filepath": {
"description": "file path to store the asset at",
"in": "path",
Expand All @@ -756,6 +848,14 @@
"required": true,
"type": "string"
},
"filter": {
"description": "Filter expression to apply before returning query results",
"in": "query",
"name": "filter",
"enum": ["v2alpha", "one_per_pool"],
"required": false,
"type": "string"
},
"full": {
"description": "Should the response result contain everything or just the basics",
"in": "query",
Expand Down Expand Up @@ -811,6 +911,21 @@
"type": "object"
}
},
"protocol": {
"description": "Sauce Connect Protocol",
"in": "query",
"name": "protocol",
"required": false,
"enum": ["kgp", "h2c"],
"type": "string"
},
"reason": {
"description": "Reason for stopping a tunnel",
"in": "query",
"name": "reason",
"required": true,
"type": "string"
},
"subaccounts": {
"default": false,
"description": "Include subaccounts in list of jobs",
Expand All @@ -825,6 +940,13 @@
"required": true,
"type": "string"
},
"wait_for_jobs": {
"default": true,
"description": "Wait for jobs to finish",
"in": "query",
"name": "wait_for_jobs",
"type": "boolean"
},
"jobIds": {
"description": "list of jobIds",
"in": "query",
Expand Down Expand Up @@ -1539,6 +1661,12 @@
},
{
"$ref": "#/parameters/full"
},
{
"$ref": "#/parameters/filter"
},
{
"$ref": "#/parameters/protocol"
}
],
"responses": {
Expand Down Expand Up @@ -1577,6 +1705,12 @@
},
{
"$ref": "#/parameters/id"
},
{
"$ref": "#/parameters/reason"
},
{
"$ref": "#/parameters/wait_for_jobs"
}
],
"responses": {
Expand Down Expand Up @@ -1633,6 +1767,38 @@
"tags": ["Tunnel"]
}
},
"/v1/public/tunnels/info/versions": {
"get": {
"operationId": "sc_versions",
"parameters": [
{
"$ref": "#/parameters/clientVersion"
},
{
"$ref": "#/parameters/clientHost"
},
{
"$ref": "#/parameters/all"
}
],
"responses": {
"200": {
"description": "Tunnels",
"schema": {
"$ref": "#/definitions/SauceConnectVersions"
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
},
"summary": "Get tunnels for the user or all the users in the team",
"tags": ["Tunnel"]
}
},
"/v1/jobs/{id}/{assetName}": {
"get": {
"operationId": "download_job_asset",
Expand Down
83 changes: 14 additions & 69 deletions docs/interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,46 +61,6 @@ The following commands are available via package or cli tool:
<code>api.getStatus()</code>
</td>
</tr>
<tr>
<td>
<b>DELETE</b> <code>/v1/manual</code><br>
complete manual task
<h3>Example:</h3>
<code>api.deleteManualJob(ids)</code>
</td>
</tr>
<tr>
<td>
<b>POST</b> <code>/v1/manual</code><br>
Creates a manual job
<h3>Example:</h3>
<code>api.createManualJob(capabilities)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/manual/options/</code><br>
returns a list of supported platforms in the Sauce cloud
<h3>Example:</h3>
<code>api.listManualPlatforms()</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/manual/{taskId}</code><br>
get manual task
<h3>Example:</h3>
<code>api.getManualJob(taskId)</code>
</td>
</tr>
<tr>
<td>
<b>POST</b> <code>/v1/manual/{taskId}/screenshot</code><br>
Take screenshot in manual session
<h3>Example:</h3>
<code>api.createManualJobScreenshot(taskId)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/me</code><br>
Expand All @@ -109,22 +69,6 @@ The following commands are available via package or cli tool:
<code>api.getCurrentUser()</code>
</td>
</tr>
<tr>
<td>
<b>DELETE</b> <code>/v1/tasks</code><br>
complete manual task
<h3>Example:</h3>
<code>api.deleteManualJobLegacy(ids)</code>
</td>
</tr>
<tr>
<td>
<b>POST</b> <code>/v1/tasks</code><br>
Creates a manual job
<h3>Example:</h3>
<code>api.createManualJobLegacy(capabilities)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/users/{username}</code><br>
Expand Down Expand Up @@ -220,15 +164,16 @@ The following commands are available via package or cli tool:
<h3>Example:</h3>
<code>api.listTunnels(username, { ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>all</b>: Should the response contain the same team user data</li> <li><b>full</b>: Should the response result contain everything or just the basics</li> </ul> </td>
<ul> <li><b>all</b>: Should the response contain the same team user data</li> <li><b>full</b>: Should the response result contain everything or just the basics</li> <li><b>filter</b>: Filter expression to apply before returning query results</li> <li><b>protocol</b>: Sauce Connect Protocol</li> </ul> </td>
</tr>
<tr>
<td>
<b>DELETE</b> <code>/v1/{username}/tunnels/{id}</code><br>
Delete a Tunnel
<h3>Example:</h3>
<code>api.deleteTunnel(username, id)</code>
</td>
<code>api.deleteTunnel(username, id, reason, { ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>wait_for_jobs</b>: Wait for jobs to finish</li> </ul> </td>
</tr>
<tr>
<td>
Expand All @@ -238,6 +183,15 @@ The following commands are available via package or cli tool:
<code>api.getTunnel(username, id)</code>
</td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/public/tunnels/info/versions</code><br>
Get tunnels for the user or all the users in the team
<h3>Example:</h3>
<code>api.scVersions({ ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>client_version</b>: SC client version</li> <li><b>client_host</b>: SC client host OS and CPU arch</li> <li><b>all</b>: Should the response contain the same team user data</li> </ul> </td>
</tr>
<tr>
<td>
<b>GET</b> <code>/v1/jobs/{id}/{assetName}</code><br>
Expand All @@ -256,15 +210,6 @@ The following commands are available via package or cli tool:
<br><h4>Options</h4>
<ul> <li><b>full</b>: Should the response result contain everything or just the basics</li> </ul> </td>
</tr>
<tr>
<td>
<b>POST</b> <code>/storage/upload</code><br>
Returns new application id after the upload.
<h3>Example:</h3>
<code>api.uploadApp({ ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>App-Type</b>: Application type</li> <li><b>App-Identifier</b>: Your custom unique identifier for your app</li> <li><b>App-DisplayName</b>: Your custom display name</li> <li><b>App-Active</b>: If true makes uploaded application active one</li> <li><b>body</b>: No description available.</li> </ul> </td>
</tr>
<tr>
<td>
<b>GET</b> <code>/metrics/</code><br>
Expand Down Expand Up @@ -584,7 +529,7 @@ The following commands are available via package or cli tool:
<h3>Example:</h3>
<code>api.getBuildsV2(build_source, { ...options })</code>
<br><h4>Options</h4>
<ul> <li><b>user_id</b>: user_id</li> <li><b>org_id</b>: org_id</li> <li><b>group_id</b>: group_id</li> <li><b>team_id</b>: team_id</li> <li><b>status</b>: status</li> <li><b>name</b>: start</li> <li><b>end</b>: end</li> <li><b>limit</b>: Number of results to return</li> <li><b>offset</b>: Starting number</li> <li><b>sort</b>: sort</li> </ul> </td>
<ul> <li><b>user_id</b>: user_id</li> <li><b>org_id</b>: org_id</li> <li><b>group_id</b>: group_id</li> <li><b>team_id</b>: team_id</li> <li><b>status</b>: status</li> <li><b>start_time</b>: start_time</li> <li><b>end_time</b>: end_time</li> <li><b>limit</b>: Number of results to return</li> <li><b>offset</b>: Starting number</li> <li><b>sort</b>: sort</li> </ul> </td>
</tr>
<tr>
<td>
Expand Down
14 changes: 9 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,20 +529,24 @@ export default class SauceLabs {
const options = args.slice(pathParams.length)[0] || {};
for (const optionParam of params.filter((p) => p.in === 'query')) {
const expectedType = optionParam.type.replace('integer', 'number');
// I'm not sure why query param name is camel-cased here, underscore params do exist in Sauce Labs.
const optionName = camelCase(optionParam.name);
const option = options[optionName];
const optionValue = options[optionName] || options[optionParam.name];
const isRequired =
Boolean(optionParam.required) ||
(typeof optionParam.required === 'undefined' &&
typeof optionParam.default === 'undefined');
if ((isRequired || option) && !isValidType(option, expectedType)) {
if (
(isRequired || optionValue) &&
!isValidType(optionValue, expectedType)
) {
throw new Error(
`Expected parameter for option '${optionName}' from type '${expectedType}', found '${typeof option}'`
`Expected parameter for option '${optionName}' from type '${expectedType}', found '${typeof optionValue}'`
);
}

if (typeof option !== 'undefined') {
bodyMap.set(optionParam.name, option);
if (typeof optionValue !== 'undefined') {
bodyMap.set(optionParam.name, optionValue);
}
}

Expand Down
Loading
Loading