When testing mobile apps, you have the option to upload your app to our Application Storage. Here are some benefits:
- Upload all of your mobile apps to the same location for cross-device Automated and Live testing with both virtual devices and real devices
- Share your uploaded apps with your team members
- Store apps for up to 60 days
See the following sections for more information:
What You'll Need
- A Sauce Labs account
- A mobile app you wish to test. If you don't have one, you can use the Sauce Labs sample mobile app
Live Testing
Upload an App to Real Devices with App-Upload
- Log in to Sauce Labs and select LIVE from the options in the left-hand navigation.
- Select Mobile-App.
- You will see a list of previously uploaded apps.
- To the right of the page, select App Upload to upload a new application.
NOTE: App-Upload UI currently supports Live Testing on Real Devices only. Use the REST API to upload apps for use with virtual devices.
You can either drag and drop an application, or browse for the file. We support mobile app *.APK and *IPA files up to 4 GB. Non-app file uploads are not supported in the UI at this time, but can be uploaded through the API.
Delete Apps with the Delete Button
The Delete button will delete a whole application (e.g., a group of builds belonging to the same app package). Files associated with app identifiers (i.e., belong to the same platform and are accessible to the same team) are indicated by the + symbol next to version number. Also, the version number shown is the most recently updated file, not necessarily the "latest" version of the application.
Automated Testing
Upload Files with the REST API
Below are some examples of how to use the Sauce Labs REST API to upload your mobile file to Sauce Storage. If you do not have a file to test, consider using the Sauce Labs Swag Labs sample app for validating this process.
REST API Authentication
The APIs and authorization credentials are located here: app.saucelabs.com. A recommended best practice is to set your credentials as environment variables like so:
SAUCE_USERNAME='valid.username' SAUCE_ACCESS_KEY='valid.key'
For specific instructions on how to set environment variables visit, the following links:
- Set Environment Variables with Windows 10
- Set Environment Variables with MacOS
- Set Environment Variables with Linux
Accepted File Types
App Storage recognizes *.apk files as Android apps and *.ipa files as iOS apps, and will also parse a *.zip file to determine whether a valid *.app bundle exists, accepting it as an iOS app if it does. You can also upload and store other file types for generic use, such as a pre-run executable, package, or binary. Some of the formats for this type of use case include:
- *.js
- *.py
- *.tar
- *.zip
- *.sh
- *.bat
Team Management Sync
App Storage uses a Team Management sync feature that allows for user permissions schemes. In other words, a Sauce Labs admin (either an org admin or a team admin) can control access to individual application files or specific binary/script files. By default, all uploaded files are shared with the same team where the user participates currently. You, as a user, can only access files that are shared with the team where you contribute/participate unless your role is an organization admin in which case you have access to all files in your particular organization.
To manage access to your organization go to Account > Team Management.
Storage API Endpoints
There are two main contexts/branches for the storage API:
- One for working with separate application builds (individual builds, application files, etc.)
- One for working with apps (groups of application builds with the same unique identifier, belonging to the same platform and team)
NOTE: Data center-specific endpoints should be used whenever possible. For more information, see Data Center Endpoints.
Upload
HTTP methods: POST, PUT
We support app files in *.APK, *.IPA, or *.ZIP format, up to 4GB.
Uploading with cURL
If you're using cURL
for the upload, you must include the @
before your file path (i.e., payload=@path/to/your_file_name
).
$ curl -F 'payload=@/Users/<user-name>/Downloads/<file_name>.apk' -F name=<file_name>.apk -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.us-west-1.saucelabs.com/v1/storage/upload'
> curl -F "payload=@\Users\%SAUCE_USERNAME%\Downloads\<file_name>.apk" -F name=<file_name>.apk -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.us-west-1.saucelabs.com/v1/storage/upload'
$ curl -F 'payload=@/Users/<user-name>/Downloads/<file_name>.apk' -F name=<file_name>.apk -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.eu-central-1.saucelabs.com/v1/storage/upload'
> curl -F 'payload=@\Users\<user-name>\Downloads\<file_name>.ipa' -F name=<file_name>.ipa -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.eu-central-1.saucelabs.com/v1/storage/upload'
Download
HTTP methods: GET
NOTE: Each instance of an uploaded application generates a unique identification number. If you're not sure of the file_id
number, you can use the files management endpoints to find the desired key.
$ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.us-west-1.saucelabs.com/v1/storage/download/<file_id>' -o /path/to/test/code/app-name
> curl -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.us-west-1.saucelabs.com/v1/storage/download/<file_id>' -o \path\to\test\code\app-name
$ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.eu-central-1.saucelabs.com/v1/storage/download/<file_id>' -o /path/to/test/code
> curl -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.eu-central-1.saucelabs.com/v1/storage/download/<file_id>' -o \path\to\test\code
Edit
HTTP methods: PUT
Allows you to edit files, as long as the files are available to the requester.
Required parameters:
file_id
= one or more file ids to be listedA request body:
Example JSON{ "item": { "description": "string" } }
curl -X PUT -H "Content-Type: application/json" -d '{"item": {"description":"string"}}' -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" https://api.us-west-1.saucelabs.com/v1/storage/files/754366c5-cd33-478b-83e0-dd1a0a1f801d
curl -X PUT -H "Content-Type: application/json" -d '{"item": {"description":"string"}}' -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% https://api.us-west-1.saucelabs.com/v1/storage/files/754366c5-cd33-478b-83e0-dd1a0a1f801d
curl -X PUT -H "Content-Type: application/json" -d '{"item": {"description":"string"}}' -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" https://api.eu-central-1.saucelabs.com/v1/storage/files/754366c5-cd33-478b-83e0-dd1a0a1f801d
curl -X PUT -H "Content-Type: application/json" -d '{"item": {"description":"string"}}' -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% https://api.eu-central-1.saucelabs.com/v1/storage/files/754366c5-cd33-478b-83e0-dd1a0a1f801d
Files
HTTP methods: GET
Possible parameters for /files
:
q
: search term (semantic version, build number, file name, app name, app identifier, etc.)kind
= ios, android, otherfile_id
= one or more file ids to be listedteam_id
= one or more team ids the listed file(s) should be shared withpage
= the number of the current page to show, by default it starts from oneper_page
= the count of items per listed page. By default it is 25, and the acceptable range is 1-100
$ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.us-west-1.saucelabs.com/v1/storage/files?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
> curl -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.us-west-1.saucelabs.com/v1/storage/files?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
$ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.eu-central-1.saucelabs.com/v1/storage/files?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
> curl -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.eu-central-1.saucelabs.com/v1/storage/files?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
Groups (App)
HTTP methods: GET
Possible Parameters for /groups
:
q
: search term (semantic version, build number, file name, app name, app identifier, etc.)kind
= ios, android, othergroup_id
= one or more group ids to be listedpage
= the number of the current page to show, by default it starts from oneper_page
= the count of items per listed page. By default it is 25, and the acceptable range is 1-100
$ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.us-west-1.saucelabs.com/v1/storage/groups?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
> curl -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.us-west-1.saucelabs.com/v1/storage/groups?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
$ curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.eu-central-1.saucelabs.com/v1/storage/groups?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
> curl -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.eu-central-1.saucelabs.com/v1/storage/groups?q=Android.SauceLabs.Mobile.Sample.app.2.3.0.apk&kind=android'
Delete
HTTP methods: DELETE
Generally there are two ways to delete existing applications in App Storage API:
- Delete a group of files by
group_id
(for example application builds with the same identifier) - Delete a single file/application build by
file_id
// Delete a Single File $ curl -X DELETE -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.us-west-1.saucelabs.com/v1/storage/files/<file_id>' // Delete a Group of Files $ curl -X DELETE -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.us-west-1.saucelabs.com/v1/storage/groups/<group_id>'
// Delete a Single File > curl -X DELETE -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.us-west-1.saucelabs.com/v1/storage/files/<file_id>' // Delete a Group of Files > curl -X DELETE -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.us-west-1.saucelabs.com/v1/storage/groups/<group_id>'
// Delete a Single File $ curl -X DELETE -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.eu-central-1.saucelabs.com/v1/storage/files/<file_id>' // Delete a Group of Files $ curl -X DELETE -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" 'https://api.eu-central-1.saucelabs.com/v1/storage/groups/<group_id>'
// Delete a Single File > curl -X DELETE -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.eu-central-1.saucelabs.com/v1/storage/files/<file_id>' // Delete a Group of Files > curl -X DELETE -u "%SAUCE_USERNAME%:%SAUCE_ACCESS_KEY%" 'https://api.eu-central-1.saucelabs.com/v1/storage/groups/<group_id>'
Using Application Storage with Automated Test Builds
After successfully uploading your file to application storage, you need to reference the unique app Identifier (file_id
) in your test code to retrieve and use your app for automated tests.
For example, let's assume you've updated a new version of your app using the /upload
endpoint. The JSON response would be something like below:
{ "item":{ "id":"379c301a-199c-4b40-ad45-4a95e5f30a3a", "owner":{ "id":"286c0fbb0cb644c4a012d505b8a0a1ac", "org_id":"c064890612424e34a12fca98ce4f32c6" }, "name":"Android.SauceLabs.Mobile.Sample.app.2.3.0.apk", "upload_timestamp":1593450387, "etag":"0cf189b1c4c17a56656ada5e2d75cd51", "kind":"android", "group_id":2807, "metadata":{ "identifier":"com.swaglabsmobileapp", "name":"Swag Labs Mobile App", "version":"2.3.0", "icon":"<long-serial-number>", "version_code":13, "min_sdk":16, "target_sdk":28 }, ... } } }
Then the file_id
would be "id":"379c301a-199c-4b40-ad45-4a95e5f30a3a"
. If you're unsure of the id of an existing app, you can use the endpoint, along with the necessary parameters to find the desired application.
File Name instead of File ID
You can also use the app "name"
field from the storage API in the "app"
capability. This approach is particularly useful if you uploaded your build to Application Storage via a CI pipeline, and you either don't know the id
, or you do not wish to perform JSON parsing in order to retrieve the id
. The filename
field also includes any supported file that can be uploaded to application storage.
Example of uploading an Android .apk file:
caps.setCapability("app", "storage:filename=<file-name>.apk");
caps['app'] = 'storage:filename=<file-name>.apk';
caps['app'] = "storage:filename=<file-name>.apk"
caps['app'] = 'storage:filename=<file-name>.apk'
caps.SetCapability("app","storage:filename=<file-name>.apk");
Limitations:
- File names are NOT unique, therefore they will always default to the latest version.
- Currently you cannot specify the version of the app using this feature.
build
capability not supported in VDC at this time.
Updating WebDriver Capabilities
If you were previously using application stored in sauce-storage
, you can convert your existing test capabilities by replacing sauce-storage:myapp
with storage:<file_id>
.
Example Code Snippets
These examples assume file_id = c8511dd6-38ec-4f58-b8b9-4ec8c23ad882
caps.setCapability("app", "sauce-storage:some-app.apk");
caps.setCapability("app", "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
caps['app'] = 'sauce-storage:my_app.apk';
caps['app'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882';
caps['app'] = "sauce-storage:my_app.apk"
caps['app'] = "storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882"
caps['app'] = 'sauce-storage:my_app.apk'
caps['app'] = 'storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882'
caps.SetCapability("app","sauce-storage:my_app.apk");
caps.SetCapability("app","storage:c8511dd6-38ec-4f58-b8b9-4ec8c23ad882");
Uploading to a Remote Location
There may be situations where you want to install an application from a downloadable remote location (AWS S3 bucket, a GitHub repository, etc.).
Please review the following guidelines below before uploading your application:
- Make sure your application meets the prerequisite requirements for Android and iOS Mobile Application Testing.
- Upload your application to the hosting location.
- Ensure Sauce Labs has READ access to the app URL.
In your test script, enter the URL for the application as the
"app"
desired capability. Below are some example snippets:caps.setCapability("app", "https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip);
caps.SetCapability("app", "https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip");
app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip',
'app': 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip',
app: 'https://github.com/saucelabs/sample-app-mobile/releases/download/2.2.1/iOS.Simulator.SauceLabs.Mobile.Sample.app.2.1.1.zip'
Uploading to Legacy Sauce Storage
Sauce Storage is our legacy private storage space for apps. Files uploaded will expire seven days after upload, and be removed. You can upload the app you want to test to Sauce Storage using our REST API, and then access it for testing by specifying sauce-storage:myapp
for the app
capability in your test script. You upload apps using the upload_file
method of the Sauce Labs REST API.
You can use any REST client; cURL is a convenient command-line option.
US-WEST Data Center
$ curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY -X POST -H "Content-Type: application/octet-stream" \ "https://saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/$APP_NAME?overwrite=true" --data-binary @path/to/your_file_name
US-EAST Data Center
$ curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY -X POST -H "Content-Type: application/octet-stream" \ "https://us-east-1.saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/$APP_NAME?overwrite=true" --data-binary @path/to/your_file_name
EU-CENTRAL Data Center
$ curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY -X POST -H "Content-Type: application/octet-stream" \ "https://eu-central-1.saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/$APP_NAME?overwrite=true" --data-binary @path/to/your_file_name
US-WEST Data Center
> curl -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% -X POST -H "Content-Type: application/octet-stream" \ "https://saucelabs.com/rest/v1/storage/%SAUCE_USERNAME%/%APP_NAME%?overwrite=true" --data-binary @path\to\your_file_name
US-EAST Data Center
> curl -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% -X POST -H "Content-Type: application/octet-stream" \ "https://us-east-1.saucelabs.com/rest/v1/storage/%SAUCE_USERNAME%/%APP_NAME%?overwrite=true" --data-binary @path\to\your_file_name
EU-CENTRAL Data Center
> curl -u %SAUCE_USERNAME%:%SAUCE_ACCESS_KEY% -X POST -H "Content-Type: application/octet-stream" \ "https://eu-central-1.saucelabs.com/rest/v1/storage/%SAUCE_USERNAME%/%APP_NAME%?overwrite=true" --data-binary @path\to\your_file_name