├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── user-story.md ├── PULL_REQUEST_TEMPLATE.md ├── SauceLabsLogo.png ├── dependabot.yml ├── issue-branch.yml └── workflows │ ├── codeql-analysis.yml │ ├── dependency-review.yml │ ├── issue-branch.yml │ ├── java-ci.yml │ ├── release.yml │ ├── setup-sauce-connect-tunnels.yml │ └── upload_my_demo_app.yml ├── .gitignore ├── .gitpod.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── saucelabs │ │ └── saucerest │ │ ├── AutomationBackend.java │ │ ├── DataCenter.java │ │ ├── ErrorExplainers.java │ │ ├── HttpMethod.java │ │ ├── JobSource.java │ │ ├── JobVisibility.java │ │ ├── LogEntry.java │ │ ├── SauceException.java │ │ ├── SauceREST.java │ │ ├── SauceShareableLink.java │ │ ├── TestAsset.java │ │ ├── Unfinished.java │ │ ├── api │ │ ├── AbstractEndpoint.java │ │ ├── AccountsEndpoint.java │ │ ├── BuildsEndpoint.java │ │ ├── HttpClientConfig.java │ │ ├── InsightsEndpoint.java │ │ ├── JobsEndpoint.java │ │ ├── PerformanceEndpoint.java │ │ ├── PlatformEndpoint.java │ │ ├── RealDevicesEndpoint.java │ │ ├── ResponseHandler.java │ │ ├── SauceConnectEndpoint.java │ │ └── StorageEndpoint.java │ │ └── model │ │ ├── accounts │ │ ├── Allowed.java │ │ ├── Concurrency.java │ │ ├── CreateTeam.java │ │ ├── CreateUser.java │ │ ├── Current.java │ │ ├── Group.java │ │ ├── Links.java │ │ ├── LookupTeams.java │ │ ├── LookupUsers.java │ │ ├── LookupUsersParameter.java │ │ ├── Organization.java │ │ ├── Organizations.java │ │ ├── ResetAccessKeyForTeam.java │ │ ├── Result.java │ │ ├── Role.java │ │ ├── Roles.java │ │ ├── SetTeam.java │ │ ├── Settings.java │ │ ├── Team.java │ │ ├── TeamMembers.java │ │ ├── UpdateTeam.java │ │ ├── UpdateUser.java │ │ ├── User.java │ │ ├── UserConcurrency.java │ │ └── UsersTeam.java │ │ ├── builds │ │ ├── Build.java │ │ ├── JobInBuild.java │ │ ├── Jobs.java │ │ ├── JobsInBuild.java │ │ ├── LookupBuildsParameters.java │ │ ├── LookupJobsParameters.java │ │ ├── Sort.java │ │ ├── State.java │ │ └── Status.java │ │ ├── insights │ │ ├── Item.java │ │ ├── Meta.java │ │ ├── TestResult.java │ │ └── TestResultParameter.java │ │ ├── jobs │ │ ├── BaseConfig.java │ │ ├── CommandCounts.java │ │ ├── CustomData.java │ │ ├── GetJobsParameters.java │ │ ├── GoogChromeOptions.java │ │ ├── Job.java │ │ ├── JobAssets.java │ │ ├── SauceOptions.java │ │ └── UpdateJobParameter.java │ │ ├── platform │ │ ├── AppiumVersion.java │ │ ├── EndOfLifeAppiumVersions.java │ │ ├── Platform.java │ │ ├── SupportedPlatforms.java │ │ └── TestStatus.java │ │ ├── realdevices │ │ ├── ApplicationSummary.java │ │ ├── AvailableDevices.java │ │ ├── BaseConfig.java │ │ ├── Concurrency.java │ │ ├── Device.java │ │ ├── DeviceDescriptor.java │ │ ├── DeviceJob.java │ │ ├── DeviceJobs.java │ │ ├── Entity.java │ │ ├── MetaData.java │ │ └── Organization.java │ │ ├── sauceconnect │ │ ├── Downloads.java │ │ ├── Instance.java │ │ ├── JobsForATunnel.java │ │ ├── Linux.java │ │ ├── LinuxArm64.java │ │ ├── Metadata.java │ │ ├── Osx.java │ │ ├── StopTunnel.java │ │ ├── Tags.java │ │ ├── TunnelDefault.java │ │ ├── TunnelInformation.java │ │ ├── Versions.java │ │ └── Win32.java │ │ └── storage │ │ ├── Access.java │ │ ├── DeleteAppFile.java │ │ ├── DeleteAppGroupFiles.java │ │ ├── EditAppGroupSettings.java │ │ ├── EditFileDescription.java │ │ ├── GetAppFiles.java │ │ ├── GetAppStorageGroupSettings.java │ │ ├── GetAppStorageGroups.java │ │ ├── GetAppStorageGroupsParameters.java │ │ ├── Instrumentation.java │ │ ├── Item.java │ │ ├── ItemInteger.java │ │ ├── Links.java │ │ ├── Metadata.java │ │ ├── Owner.java │ │ ├── Proxy.java │ │ ├── Recent.java │ │ ├── Resigning.java │ │ ├── Settings.java │ │ ├── StorageParameter.java │ │ └── UploadFileApp.java └── resources │ ├── .properties │ └── com │ └── saucelabs │ └── saucerest │ └── BuildUtils.template └── test ├── java └── com │ └── saucelabs │ └── saucerest │ ├── Helper.java │ ├── integration │ ├── AccountsEndpointTest.java │ ├── BuildsEndpointTest.java │ ├── InsightsEndpointTest.java │ ├── JobsEndpointTest.java │ ├── PlatformEndpointTest.java │ ├── RealDevicesEndpointTest.java │ ├── SauceConnectEndpointTest.java │ ├── StorageEndpointTest.java │ ├── StorageTestHelper.java │ └── TeamDeletionHelper.java │ └── unit │ ├── AbstractEndpointTest.java │ ├── AutomationBackendTest.java │ ├── CreateUserTest.java │ ├── DataCenterTest.java │ ├── EditAppGroupSettingsTest.java │ ├── ErrorExplainerTest.java │ ├── HelperTest.java │ ├── HttpMethodTest.java │ ├── JobSourceTest.java │ ├── LogEntryTest.java │ ├── LookupBuildsParametersTest.java │ ├── ResponseHandlerTest.java │ ├── SauceConnectEndpointTest.java │ ├── SauceExceptionTest.java │ ├── SauceRESTTest.java │ ├── SauceShareableLinkTest.java │ ├── StorageEndpointParameterTest.java │ └── TestAssetTest.java └── resources ├── AppFiles ├── Android-MyDemoAppNative.apk ├── Android-MyDemoAppRN.apk ├── iOS-Real-Device-MyNativeDemoApp.ipa ├── iOS-Real-Device-MyRNDemoApp.ipa └── iOS-Simulator-MyRNDemoApp.zip ├── appium-server.log ├── appium.json ├── assets.json ├── buildsResponse.json ├── buildsResponses.json ├── junit-platform.properties ├── sauce-connect-config-apac-southeast.yaml ├── sauce-connect-config-eu-central.yaml ├── sauce-connect-config-us-west.yaml ├── selenium-server.log ├── testfile.txt ├── tunnelsResponse.json ├── user_test.json └── users_test_concurrency.json /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | end_of_line = lf 3 | indent_style = space 4 | indent_size = 2 5 | insert_final_newline = false 6 | trim_trailing_whitespace = true 7 | 8 | [{pom.xml,*.jelly,*.html,*.java}] 9 | indent_size = 4 10 | max_line_length = 160 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## The problem 11 | 12 | Briefly describe the issue you are experiencing (or the feature you want to see added to Appium). Tell us what you were trying to do and what happened instead. Remember, this is _not_ a place to ask questions. 13 | 14 | ## Environment 15 | 16 | * Java JDK version that exhibits the issue: 17 | * saucerest-java version that exhibits the issue: 18 | * Operating System / version that exhibits the issue: 19 | * Last configuration (Java, saucerest-java, OS, OS version) that did not exhibit the issue (if applicable): 20 | 21 | ## Details 22 | 23 | If necessary, describe the problem you have been experiencing in more detail. 24 | 25 | ## Link to logs 26 | 27 | If your log files are really long consider creating a [GIST](https://gist.github.com) which is a paste of your _full_ logs, and link them here. Otherwise this report will be long and hard to read. 28 | 29 | ## Code To Reproduce Issue [ Good To Have ] 30 | 31 | Please remember that with sample code it's easier to reproduce the bug and it's much faster to fix it. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/user-story.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: User story 3 | about: Template for intrinsic changes from Sauce Labs employees 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | ## Description 13 | 14 | 15 | 16 | ## Motivation and Context 17 | 18 | 19 | 20 | ## Further comments 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Motivation and Context 7 | 8 | 9 | 10 | ## How Has This Been Tested? 11 | 12 | 13 | 14 | 15 | ## Types of changes 16 | 17 | 18 | 19 | - [ ] Bugfix (non-breaking change which fixes an issue) 20 | - [ ] New feature (non-breaking change which adds functionality) 21 | - [ ] Refactoring (change which improves current code base; please describe the change) 22 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 23 | - [ ] Documentation Update (if none of the other choices apply) 24 | 25 | ## Screenshots (if appropriate): 26 | 27 | ## Checklist 28 | 29 | 30 | 31 | 32 | - [ ] I have read the [CONTRIBUTING](https://github.com/saucelabs/saucerest-java/blob/master/CONTRIBUTING.md) doc 33 | - [ ] I have added tests that prove my fix is effective or that my feature works 34 | - [ ] All new and existing tests passed locally 35 | - [ ] I have added necessary documentation (if appropriate) 36 | 37 | ## Further comments 38 | 39 | If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... 40 | -------------------------------------------------------------------------------- /.github/SauceLabsLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saucelabs/saucerest-java/04a21b292d74e2bdb4953b7664d7f895e8fa4979/.github/SauceLabsLogo.png -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" -------------------------------------------------------------------------------- /.github/issue-branch.yml: -------------------------------------------------------------------------------- 1 | gitSafeReplacementChar: '-' 2 | branchName: '${issue.number}-${issue.title}' 3 | defaultBranch: 'master' 4 | branches: 5 | - label: enhancement 6 | prefix: enhancement/ 7 | - label: feature_request 8 | prefix: feature/ 9 | - label: bug 10 | prefix: bugfix/ 11 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "Code Scanning - Action" 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | types: [ opened, reopened, synchronize ] 8 | schedule: 9 | # Run daily at 00:00 10 | - cron: '0 0 * * *' 11 | 12 | jobs: 13 | CodeQL-Build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | - name: Set up JDK 20 20 | uses: actions/setup-java@v4 21 | with: 22 | java-version: '20' 23 | distribution: 'temurin' 24 | 25 | - name: Initialize CodeQL 26 | uses: github/codeql-action/init@v3 27 | with: 28 | languages: java 29 | 30 | - name: Autobuild 31 | uses: github/codeql-action/autobuild@v3 32 | 33 | - name: Perform CodeQL Analysis 34 | uses: github/codeql-action/analyze@v3 35 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. 4 | # 5 | # Source repository: https://github.com/actions/dependency-review-action 6 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement 7 | name: 'Dependency Review' 8 | on: 9 | push: 10 | branches: [ main ] 11 | pull_request: 12 | types: [ opened, reopened, synchronize ] 13 | schedule: 14 | # Run daily at 00:00 15 | - cron: '0 0 * * *' 16 | 17 | permissions: 18 | contents: read 19 | 20 | jobs: 21 | dependency-review: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: 'Checkout Repository' 25 | uses: actions/checkout@v4 26 | - name: 'Dependency Review' 27 | uses: actions/dependency-review-action@v4 28 | with: 29 | base-ref: ${{ github.event.pull_request.base.sha || 'main' }} 30 | head-ref: ${{ github.event.pull_request.head.sha || github.ref }} 31 | -------------------------------------------------------------------------------- /.github/workflows/issue-branch.yml: -------------------------------------------------------------------------------- 1 | name: Create Issue Branch 2 | on: 3 | issues: 4 | types: [assigned] 5 | issue_comment: 6 | types: [created] 7 | 8 | jobs: 9 | create_issue_branch_job: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Create Issue Branch 13 | id: Create_Issue_Branch 14 | uses: robvanderleek/create-issue-branch@main 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | - name: Echo branch name 18 | run: echo ${{ steps.Create_Issue_Branch.outputs.branchName }} 19 | -------------------------------------------------------------------------------- /.github/workflows/java-ci.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | types: [ opened, reopened, synchronize ] 8 | workflow_dispatch: 9 | schedule: 10 | # Run every 6 hours at minute 0: 06:00, 12:00, 18:00, 00:00 11 | - cron: '0 6,12,18,0 * * *' 12 | 13 | concurrency: 14 | group: ${{ github.workflow }} 15 | 16 | permissions: 17 | contents: write 18 | 19 | env: 20 | SAUCE_USERNAME: ${{secrets.SAUCE_USERNAME}} 21 | SAUCE_ACCESS_KEY: ${{secrets.SAUCE_ACCESS_KEY}} 22 | 23 | jobs: 24 | 25 | unit_tests_job: 26 | name: Unit Tests 27 | runs-on: ubuntu-latest 28 | 29 | steps: 30 | - uses: actions/checkout@v4 31 | - name: Set up JDK 21 32 | uses: actions/setup-java@v4 33 | with: 34 | java-version: '21' 35 | distribution: 'temurin' 36 | cache: 'maven' 37 | - name: Build with Maven 38 | run: mvn clean test -Dtest="com.saucelabs.saucerest.unit.**" -Dgpg.skip -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -V 39 | - name: Upload JaCoCo report to Codecov 40 | uses: codecov/codecov-action@v5 41 | with: 42 | flags: unittests,tests 43 | 44 | upload_apps_job: 45 | name: Upload My Demo Apps 46 | # Only proceed if unit tests pass 47 | needs: unit_tests_job 48 | uses: ./.github/workflows/upload_my_demo_app.yml 49 | secrets: inherit 50 | 51 | integration_tests_job: 52 | name: Integration Tests 53 | needs: [ unit_tests_job, upload_apps_job ] 54 | runs-on: ubuntu-latest 55 | 56 | steps: 57 | - name: Set env var for Integration Tests 58 | # Only run integration tests if the code is coming from this repo and not forks 59 | if: ${{ github.repository == github.event.pull_request.head.repo.full_name }} || ${{ github.event.push.head.repo.full_name == github.repository }} 60 | run: | 61 | echo "NOT_FROM_FORK=true" >> $GITHUB_ENV 62 | 63 | - name: Print env var 64 | run: | 65 | echo "NOT_FROM_FORK: ${{ env.NOT_FROM_FORK }}" 66 | 67 | - uses: actions/checkout@v4 68 | if: ${{ env.NOT_FROM_FORK }} == 'true' 69 | 70 | - name: Set up JDK 21 71 | uses: actions/setup-java@v4 72 | if: ${{ env.NOT_FROM_FORK }} == 'true' 73 | with: 74 | java-version: '21' 75 | distribution: 'temurin' 76 | cache: 'maven' 77 | 78 | - name: Setup Sauce Connect US-West 79 | uses: saucelabs/sauce-connect-action@v2 80 | with: 81 | username: ${{ secrets.SAUCE_USERNAME }} 82 | accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} 83 | tunnelName: github-action-tunnel-us-west 84 | configFile: ${{ github.workspace }}/src/test/resources/sauce-connect-config-us-west.yaml 85 | 86 | - name: Setup Sauce Connect EU-Central 87 | uses: saucelabs/sauce-connect-action@v2 88 | with: 89 | username: ${{ secrets.SAUCE_USERNAME }} 90 | accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} 91 | tunnelName: github-action-tunnel-eu-central 92 | configFile: ${{ github.workspace }}/src/test/resources/sauce-connect-config-eu-central.yaml 93 | 94 | - name: Build and Run Integration Tests 95 | if: ${{ env.NOT_FROM_FORK }} == 'true' 96 | uses: nick-invision/retry@v3.0.0 97 | with: 98 | timeout_minutes: 20 99 | max_attempts: 3 100 | command: | 101 | mvn clean test -Dtest="com.saucelabs.saucerest.integration.**" -Dgpg.skip -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dsurefire.rerunFailingTestsCount=2 -V 102 | 103 | - name: Upload JaCoCo report to Codecov 104 | uses: codecov/codecov-action@v5 105 | with: 106 | flags: integrationtests,tests 107 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release to Maven Central 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | releaseversion: 7 | description: 'Release version' 8 | required: true 9 | default: '2.1.0' 10 | 11 | permissions: 12 | contents: write 13 | 14 | env: 15 | SAUCE_USERNAME: ${{secrets.SAUCE_USERNAME}} 16 | SAUCE_ACCESS_KEY: ${{secrets.SAUCE_ACCESS_KEY}} 17 | 18 | jobs: 19 | publish: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - run: echo "Will start a Maven Central upload with version ${{ github.event.inputs.releaseversion }}" 23 | - uses: actions/checkout@v4 24 | 25 | - name: Set up Maven Central Repository 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '20' 29 | distribution: 'temurin' 30 | cache: 'maven' 31 | server-id: ossrh 32 | server-username: MAVEN_USERNAME 33 | server-password: MAVEN_PASSWORD 34 | gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} # Value of the GPG private key to import 35 | gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase 36 | 37 | - name: Setup Sauce Connect US-West 38 | uses: saucelabs/sauce-connect-action@v2 39 | with: 40 | username: ${{ secrets.SAUCE_USERNAME }} 41 | accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} 42 | tunnelName: github-action-tunnel-us-west 43 | configFile: ${{ github.workspace }}/src/test/resources/sauce-connect-config-us-west.yaml 44 | 45 | - name: Setup Sauce Connect EU-Central 46 | uses: saucelabs/sauce-connect-action@v2 47 | with: 48 | username: ${{ secrets.SAUCE_USERNAME }} 49 | accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} 50 | tunnelName: github-action-tunnel-eu-central 51 | configFile: ${{ github.workspace }}/src/test/resources/sauce-connect-config-eu-central.yaml 52 | 53 | - name: Build with Maven 54 | run: mvn clean install -Dgpg.skip -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -V 55 | 56 | - name: Upload JaCoCo report to Codecov 57 | uses: codecov/codecov-action@v5 58 | with: 59 | flags: tests,release 60 | 61 | - name: Set projects Maven version to GitHub Action GUI set version 62 | run: mvn versions:set "-DnewVersion=${{ github.event.inputs.releaseversion }}" -DgenerateBackupPoms=false -B --no-transfer-progress 63 | 64 | - name: Publish package 65 | run: mvn -B --no-transfer-progress clean deploy -DskipTests=true 66 | env: 67 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 68 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 69 | MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} 70 | 71 | - name: Generate changelog 72 | id: changelog 73 | uses: metcalfc/changelog-generator@v4.3.1 74 | with: 75 | myToken: ${{ secrets.GITHUB_TOKEN }} 76 | 77 | - name: Create GitHub Release 78 | id: create_release 79 | uses: actions/create-release@v1 80 | env: 81 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 82 | with: 83 | tag_name: ${{ github.event.inputs.releaseversion }} 84 | release_name: ${{ github.event.inputs.releaseversion }} 85 | body: | 86 | ``` 87 | 88 | 89 | com.saucelabs 90 | saucerest 91 | ${{ github.event.inputs.releaseversion }} 92 | 93 | 94 | ``` 95 | ### Changelog 96 | ${{ steps.changelog.outputs.changelog }} 97 | draft: false 98 | prerelease: false -------------------------------------------------------------------------------- /.github/workflows/setup-sauce-connect-tunnels.yml: -------------------------------------------------------------------------------- 1 | name: Setup Sauce Connect Tunnels 2 | 3 | on: 4 | workflow_call: 5 | 6 | env: 7 | SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} 8 | SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} 9 | 10 | jobs: 11 | setup_sauce_connect_tunnels: 12 | name: Setup Sauce Connect Tunnels 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v4 17 | 18 | - name: Setup Sauce Connect US-West 19 | uses: saucelabs/sauce-connect-action@v2 20 | with: 21 | username: ${{ secrets.SAUCE_USERNAME }} 22 | accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} 23 | tunnelName: github-action-tunnel-us-west 24 | configFile: ${{ github.workspace }}/src/test/resources/sauce-connect-config-us-west.yaml 25 | 26 | - name: Setup Sauce Connect EU-Central 27 | uses: saucelabs/sauce-connect-action@v2 28 | with: 29 | username: ${{ secrets.SAUCE_USERNAME }} 30 | accessKey: ${{ secrets.SAUCE_ACCESS_KEY }} 31 | tunnelName: github-action-tunnel-eu-central 32 | configFile: ${{ github.workspace }}/src/test/resources/sauce-connect-config-eu-central.yaml -------------------------------------------------------------------------------- /.github/workflows/upload_my_demo_app.yml: -------------------------------------------------------------------------------- 1 | name: Upload My Demo App monthly 2 | 3 | on: 4 | workflow_call: 5 | workflow_dispatch: 6 | schedule: 7 | - cron: '0 5 */30 * *' 8 | 9 | env: 10 | SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} 11 | SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} 12 | 13 | jobs: 14 | download_upload_apk_eu: 15 | name: Upload My Demo App apk to EU 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Download My Demo App apk 19 | uses: wei/curl@v1.1.1 20 | with: 21 | args: -L -o Android-MyDemoAppRN.apk https://github.com/saucelabs/my-demo-app-rn/releases/download/v1.3.0/Android-MyDemoAppRN.1.3.0.build-244.apk 22 | - name: Upload My Demo App apk 23 | uses: wei/curl@v1.1.1 24 | with: 25 | args: -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location --request POST 'https://api.eu-central-1.saucelabs.com/v1/storage/upload' --form 'payload=@"Android-MyDemoAppRN.apk"' --form 'name="Android-MyDemoAppRN.apk"' 26 | 27 | download_upload_zip_eu: 28 | name: Upload My Demo App zip to EU 29 | runs-on: ubuntu-latest 30 | steps: 31 | - name: Download My Demo App zip 32 | uses: wei/curl@v1.1.1 33 | with: 34 | args: -L -o iOS-Simulator-MyRNDemoApp.zip https://github.com/saucelabs/my-demo-app-rn/releases/download/v1.3.0/iOS-Simulator-MyRNDemoApp.1.3.0-162.zip 35 | - name: Upload My Demo App zip 36 | uses: wei/curl@v1.1.1 37 | with: 38 | args: -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location --request POST 'https://api.eu-central-1.saucelabs.com/v1/storage/upload' --form 'payload=@"iOS-Simulator-MyRNDemoApp.zip"' --form 'name="iOS-Simulator-MyRNDemoApp.zip"' 39 | 40 | download_upload_ipa_eu: 41 | name: Upload My Demo App ipa to EU 42 | runs-on: ubuntu-latest 43 | steps: 44 | - name: Download My Demo App ipa 45 | uses: wei/curl@v1.1.1 46 | with: 47 | args: -L -o iOS-Real-Device-MyRNDemoApp.ipa https://github.com/saucelabs/my-demo-app-rn/releases/download/v1.3.0/iOS-Real-Device-MyRNDemoApp.1.3.0-162.ipa 48 | - name: Upload My Demo App ipa 49 | uses: wei/curl@v1.1.1 50 | with: 51 | args: -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location --request POST 'https://api.eu-central-1.saucelabs.com/v1/storage/upload' --form 'payload=@"iOS-Real-Device-MyRNDemoApp.ipa"' --form 'name="iOS-Real-Device-MyRNDemoApp.ipa"' 52 | 53 | download_upload_apk_us: 54 | name: Upload My Demo App apk to US 55 | runs-on: ubuntu-latest 56 | steps: 57 | - name: Download My Demo App apk 58 | uses: wei/curl@v1.1.1 59 | with: 60 | args: -L -o Android-MyDemoAppRN.apk https://github.com/saucelabs/my-demo-app-rn/releases/download/v1.3.0/Android-MyDemoAppRN.1.3.0.build-244.apk 61 | - name: Upload My Demo App apk 62 | uses: wei/curl@v1.1.1 63 | with: 64 | args: -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location --request POST 'https://api.us-west-1.saucelabs.com/v1/storage/upload' --form 'payload=@"Android-MyDemoAppRN.apk"' --form 'name="Android-MyDemoAppRN.apk"' 65 | 66 | download_upload_zip_us: 67 | name: Upload My Demo App zip to US 68 | runs-on: ubuntu-latest 69 | steps: 70 | - name: Download My Demo App zip 71 | uses: wei/curl@v1.1.1 72 | with: 73 | args: -L -o iOS-Simulator-MyRNDemoApp.zip https://github.com/saucelabs/my-demo-app-rn/releases/download/v1.3.0/iOS-Simulator-MyRNDemoApp.1.3.0-162.zip 74 | - name: Upload My Demo App zip 75 | uses: wei/curl@v1.1.1 76 | with: 77 | args: -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location --request POST 'https://api.us-west-1.saucelabs.com/v1/storage/upload' --form 'payload=@"iOS-Simulator-MyRNDemoApp.zip"' --form 'name="iOS-Simulator-MyRNDemoApp.zip"' 78 | 79 | download_upload_ipa_us: 80 | name: Upload My Demo App ipa to US 81 | runs-on: ubuntu-latest 82 | steps: 83 | - name: Download My Demo App ipa 84 | uses: wei/curl@v1.1.1 85 | with: 86 | args: -L -o iOS-Real-Device-MyRNDemoApp.ipa https://github.com/saucelabs/my-demo-app-rn/releases/download/v1.3.0/iOS-Real-Device-MyRNDemoApp.1.3.0-162.ipa 87 | - name: Upload My Demo App ipa 88 | uses: wei/curl@v1.1.1 89 | with: 90 | args: -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" --location --request POST 'https://api.us-west-1.saucelabs.com/v1/storage/upload' --form 'payload=@"iOS-Real-Device-MyRNDemoApp.ipa"' --form 'name="iOS-Real-Device-MyRNDemoApp.ipa"' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | dist 3 | src/*.class 4 | target 5 | 6 | .idea/* 7 | 8 | .DS_Store 9 | 10 | .settings 11 | .classpath 12 | .project 13 | 14 | saucerest.iml 15 | atlassian-ide-plugin.xml 16 | src/main/java/com/saucelabs/saucerest/BuildUtils.java 17 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | # This configuration file was automatically generated by Gitpod. 2 | # Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file) 3 | # and commit this file to your remote git repository to share the goodness with others. 4 | 5 | github: 6 | prebuilds: 7 | master: true 8 | branches: true 9 | pullRequests: true 10 | pullRequestsFromForks: true 11 | addCheck: true 12 | addBadge: true 13 | 14 | vscode: 15 | extensions: 16 | - redhat.java 17 | - vscjava.vscode-java-debug 18 | - vscjava.vscode-java-pack 19 | - vscjava.vscode-maven 20 | - vscjava.vscode-java-dependency 21 | - vscjava.vscode-java-test 22 | 23 | tasks: 24 | - name: Install Java8 25 | init: | 26 | yes | sdk install java 8.0.345-tem 27 | sdk use java 8.0.345-tem 28 | gp sync-done java8install 29 | 30 | - name: Install Dependencies 31 | init: | 32 | gp sync-await java8install # Wait for Java to be installed before building 33 | mvn dependency:resolve 34 | gp sync-done dependencies 35 | 36 | - name: Build Code 37 | before: mvn clean 38 | init: | 39 | gp sync-await dependencies # Wait for Java to be installed before building 40 | mvn compile -DskipTests=true 41 | command: mvn test -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Thank You! 2 | We appreciate contributions from the community, helping to make this library better for everyone who uses it. 3 | 4 | # Developing new features and fixing bugs 5 | ## Step 1. Get You A Copy 6 | 1. Fork this repository 7 | 2. Clone your fork to your local machine 8 | 3. (Optional but helpful) Create a branch for your changes with `git checkout -b branchname`. Make your branchname short but descriptive, eg `add_contribution_doc` 9 | 10 | ## Step 2. Set up your environment 11 | 1. Make sure you've a JDK installed, along with Maven, and all the appropriate ENV Vars set 12 | 13 | ## Step 3. Make your changes 14 | 1. Code Changes should be accompanied by documentation (if new features) and tests 15 | 2. Run the JUnit tests with `mvn test` if appropriate 16 | 3. Once they all pass, you're gold! 17 | 18 | ## Step 4. Commit 19 | 1. List changed files with `git status` 20 | 2. Add relevant changed files to your commit with `git add filename` 21 | 3. Start your commit with `git commit` 22 | 4. Write a good commit message. Good messages have a short title describing what changed, as well as a longer message summarising the changes with any context required. If fixing a lodged issue, mention this in the title 23 | 5. Try to commit atomic bug fixes or features, or at least a related set of features 24 | 25 | ## Step 5. Send a Pull Request 26 | 1. `git push` to send your commands back to Github 27 | 2. Visit your repo on Github and click then `Pull Request` button 28 | 3. If required, fill in a PR request. Treat it like a commit message; A short title describing what changed, as well as a longer message summarising changes with any context required. If fixing a lodged issue, include this in the title 29 | 4. Send the Pull Request 30 | 31 | # Using a locally build version for Development or to resolve a bug 32 | We highly encourage users to send PRs and updates that the community might find useful. However, you might want to use a personal release if you're waiting for fixes to be built into a release, to test complicated behaviour, or for company-specific changes. 33 | 34 | One way of doing this is to take a copy of the source and install it locally by doing 35 | `mvn install` 36 | from the repository root. 37 | 38 | You can then update the pom file for your target project so that you're checking out your build version: 39 | 40 | ``` 41 | 42 | 43 | com.saucelabs 44 | saucerest 45 | 1.0.38-SNAPSHOT 46 | 47 | 48 | ``` 49 | 50 | Get the value of the VERSION from the version key in the saucerest-java pom file. ATM it's on line 6: `1.0.38-SNAPSHOT`. 51 | 52 | You may need to give it a custom version. 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Sauce Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | saucerest-java Logo 4 | 5 |

6 | 7 |

saucerest-java

8 | 9 |

10 | 11 | GitHub release (latest by date) 12 | 13 | 14 | CI/CD 15 | 16 | 17 | Codecov 18 | 19 | 20 | Maven 21 | 22 |

23 |
24 | 25 | A Java client for Sauce Labs REST API. 26 | 27 | Currently, this client only support the endpoints listed [here](https://docs.saucelabs.com/dev/api/). 28 | 29 | With version 2.x of SauceREST we have made code-breaking changes to this wrapper. It has been updated to be more 30 | future-proof and to also support the newest APIs from Sauce Labs. 31 | 32 | This is going to be continuous process which means we will release changes to SauceREST over time. 33 | 34 | If a function you're after isn't supported, we suggest either shelling out and using the curl version, _or_ sending a pull 35 | request! [Contribution Details Here](https://github.com/saucelabs/saucerest-java/blob/master/CONTRIBUTING.md). 36 | 37 |
38 | 39 | # How to use 40 | 41 |
42 | Creating a client object 43 | 44 | ```java 45 | SauceREST sauceREST = new SauceREST("username", "access-key", DataCenter.EU_CENTRAL); 46 | ``` 47 | 48 |
49 | 50 | Parameters: 51 | 52 | | Name | Type | Details | 53 | |-------------|---------------------------------|--------------------------------| 54 | | username | String (required) | Your sauce labs username | 55 | | access-key | String (required) | Your sauce labs accesskey | 56 | | data_center | String or DataCenter (required) | One of `US_WEST`, `EU_CENTRAL` | 57 | 58 | ## Code examples 59 | 60 | The best way to find out how to use this library is to look at the tests. They are located in the `src/test/java` directory. Especially the integration tests 61 | will provide you with a good overview of how to use this library. 62 | 63 | # Maven 64 | 65 | ```xml 66 | 67 | 68 | 69 | com.saucelabs 70 | saucerest 71 | LATEST VERSION 72 | test 73 | 74 | 75 | ``` 76 | 77 | For latest version please check the following link: [click](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.saucelabs%22%20AND%20a%3A%22saucerest%22). 78 | 79 | ## Contributing 80 | 81 | Check out our contribution guide [here](CONTRIBUTING.md) for details. 82 | 83 | Want a fast, setup dev 84 | environment? [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/saucelabs/saucerest-java) 85 | 86 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/AutomationBackend.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | public enum AutomationBackend { 4 | APPIUM("appium"), 5 | WEBDRIVER("webdriver"); 6 | 7 | public final String label; 8 | 9 | AutomationBackend(String label) { 10 | this.label = label; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/DataCenter.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | import java.util.stream.Stream; 4 | 5 | public enum DataCenter { 6 | US_WEST("https://saucelabs.com/", "https://api.us-west-1.saucelabs.com/", "https://app.saucelabs.com/"), 7 | EU_CENTRAL("https://eu-central-1.saucelabs.com/", "https://api.eu-central-1.saucelabs.com/", "https://app.eu-central-1.saucelabs.com/"); 8 | 9 | public final String server; 10 | public final String apiServer; 11 | public final String appServer; 12 | 13 | DataCenter(String server, String apiServer, String appServer) { 14 | this.server = server; 15 | this.apiServer = apiServer; 16 | this.appServer = appServer; 17 | } 18 | 19 | public String server() { 20 | return server; 21 | } 22 | 23 | public String apiServer() { 24 | return apiServer; 25 | } 26 | 27 | public String edsServer() { 28 | return apiServer + "v1/eds/"; 29 | } 30 | 31 | public String appServer() { 32 | return appServer; 33 | } 34 | 35 | public static DataCenter fromString(String dataCenter) { 36 | return Stream.of(values()).filter(dc -> dc.name().equalsIgnoreCase(dataCenter)).findFirst().orElse(null); 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | public enum HttpMethod { 4 | GET("GET"), 5 | POST("POST"), 6 | PUT("PUT"), 7 | DELETE("DELETE"), 8 | PATCH("PATCH"), 9 | HEAD("HEAD"), 10 | OPTIONS("OPTIONS"); 11 | 12 | public final String label; 13 | 14 | HttpMethod(String label) { 15 | this.label = label; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/JobSource.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | public enum JobSource { 4 | RDC("rdc"), 5 | VDC("vdc"); 6 | 7 | public final String value; 8 | 9 | JobSource(String value) { 10 | this.value = value; 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/JobVisibility.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public enum JobVisibility { 6 | @SerializedName("public") 7 | PUBLIC, 8 | @SerializedName("public restricted") 9 | PUBLIC_RESTRICTED, 10 | @SerializedName("share") 11 | SHARE, 12 | @SerializedName("team") 13 | TEAM, 14 | @SerializedName("private") 15 | PRIVATE 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/LogEntry.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | public class LogEntry { 4 | private final String timestamp; 5 | private final String level; 6 | private final String message; 7 | 8 | public LogEntry(String time, String level, String message) { 9 | this.timestamp = time; 10 | this.level = level; 11 | this.message = message; 12 | } 13 | 14 | public String getTime() { 15 | return timestamp; 16 | } 17 | 18 | public String getLevel() { 19 | return level; 20 | } 21 | 22 | public String getMessage() { 23 | return message; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return String.format("%s %s %s", timestamp, level, message); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/SauceException.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | /* 3 | * TODO: 2020-02-27 Lets have all these take a message, yeah? 4 | * TODO: 2020-02-27 And also, we should make these IOExceptions, not Runtime. 5 | */ 6 | 7 | /** 8 | * Created by gavinmogan on 2015-11-02. 9 | */ 10 | public class SauceException extends RuntimeException { 11 | /** 12 | * Created by gavinmogan on 2015-11-02. 13 | * {@inheritDoc} 14 | */ 15 | public SauceException(String message) { 16 | super(message); 17 | } 18 | 19 | /** 20 | * Default case. 21 | */ 22 | public SauceException() { 23 | } 24 | 25 | public static class UnknownError extends SauceException { 26 | 27 | public UnknownError(String message) { 28 | super(message); 29 | } 30 | 31 | public UnknownError() { 32 | } 33 | } 34 | 35 | public static class NotAuthorized extends SauceException { 36 | 37 | public NotAuthorized(String message) { 38 | super(message); 39 | } 40 | 41 | public NotAuthorized() { 42 | } 43 | } 44 | 45 | public static class NotFound extends SauceException { 46 | 47 | public NotFound(String message) { 48 | super(message); 49 | } 50 | 51 | public NotFound() { 52 | } 53 | } 54 | 55 | public static class TooManyRequests extends SauceException { 56 | } 57 | 58 | public static class NotYetDone extends SauceException { 59 | public NotYetDone(String message) { 60 | super(message); 61 | } 62 | 63 | public NotYetDone() { 64 | } 65 | } 66 | 67 | public static class ResigningNotAllowed extends SauceException { 68 | public ResigningNotAllowed(String message) { 69 | super(message); 70 | } 71 | 72 | public ResigningNotAllowed() { 73 | } 74 | } 75 | 76 | public static class InstrumentationNotAllowed extends SauceException { 77 | public InstrumentationNotAllowed(String message) { 78 | super(message); 79 | } 80 | 81 | public InstrumentationNotAllowed() { 82 | } 83 | } 84 | 85 | public static class DeviceLockOnlyOnAndroid extends SauceException { 86 | public DeviceLockOnlyOnAndroid(String message) { 87 | super(message); 88 | } 89 | 90 | public DeviceLockOnlyOnAndroid() { 91 | } 92 | } 93 | 94 | public static class MissingCredentials extends SauceException { 95 | public MissingCredentials(String message) { 96 | super(message); 97 | } 98 | 99 | public MissingCredentials() { 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/SauceShareableLink.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.security.InvalidKeyException; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.util.Formatter; 7 | import javax.crypto.Mac; 8 | import javax.crypto.spec.SecretKeySpec; 9 | 10 | /** 11 | * Class providing a method to create a shareable test results link of a test executed on Sauce Labs. 12 | */ 13 | public class SauceShareableLink { 14 | private SauceShareableLink() { 15 | throw new IllegalStateException("Utility class"); 16 | } 17 | 18 | public static String getJobAuthDigest(String username, String accessKey, String sauceJobId) { 19 | try { 20 | String key = String.format("%s:%s", username, accessKey); 21 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.US_ASCII), "HmacMD5"); 22 | Mac mac = Mac.getInstance("HmacMD5"); 23 | mac.init(secretKeySpec); 24 | byte[] result = mac.doFinal(sauceJobId.getBytes(StandardCharsets.US_ASCII)); 25 | return bytesToHex(result).toLowerCase(); 26 | } catch (NoSuchAlgorithmException | InvalidKeyException e) { 27 | throw new IllegalStateException("Error calculating job auth digest", e); 28 | } 29 | } 30 | 31 | private static String bytesToHex(byte[] bytes) { 32 | StringBuilder hexStringBuilder = new StringBuilder(); 33 | Formatter formatter = new Formatter(hexStringBuilder); 34 | for (byte b : bytes) { 35 | formatter.format("%02x", b); 36 | } 37 | return hexStringBuilder.toString(); 38 | } 39 | 40 | /** 41 | * This method will use username and access key from the environment variables SAUCE_USERNAME and SAUCE_ACCESS_KEY. 42 | * 43 | * @param sauceJobId Sauce Labs job id 44 | * @param dataCenter Sauce Labs data center endpoint 45 | * @return A url of the test result with an authentication token, so it can be accessed without Sauce Labs credentials. 46 | */ 47 | public static String getShareableLink(String sauceJobId, DataCenter dataCenter) { 48 | return getShareableLink(null, null, sauceJobId, dataCenter); 49 | } 50 | 51 | /** 52 | * Based on the code from here 53 | * 54 | * @param username Sauce Labs username 55 | * @param accessKey Sauce Labs access key 56 | * @param sauceJobId Sauce Labs job id 57 | * @param dataCenter Sauce Labs data center endpoint 58 | * @return A url of the test result with an authentication token, so it can be accessed without Sauce Labs credentials. 59 | */ 60 | public static String getShareableLink(String username, String accessKey, String sauceJobId, DataCenter dataCenter) { 61 | String defaultUsername = System.getenv("SAUCE_USERNAME"); 62 | String defaultAccessKey = System.getenv("SAUCE_ACCESS_KEY"); 63 | 64 | if (username == null || username.isEmpty()) { 65 | if (defaultUsername == null || defaultUsername.isEmpty()) { 66 | throw new IllegalArgumentException("Sauce Labs username cannot be null or empty"); 67 | } else { 68 | username = defaultUsername; 69 | } 70 | } 71 | 72 | if (accessKey == null || accessKey.isEmpty()) { 73 | if (defaultAccessKey == null || defaultAccessKey.isEmpty()) { 74 | throw new IllegalArgumentException("Sauce Labs access key cannot be null or empty"); 75 | } else { 76 | accessKey = defaultAccessKey; 77 | } 78 | } 79 | 80 | if (sauceJobId == null || sauceJobId.isEmpty()) { 81 | throw new IllegalArgumentException("Sauce Labs job ID cannot be null or empty"); 82 | } 83 | 84 | if (dataCenter == null) { 85 | throw new IllegalArgumentException("Sauce Labs data center endpoint cannot be null"); 86 | } 87 | 88 | String digest = getJobAuthDigest(username, accessKey, sauceJobId); 89 | return dataCenter.appServer + "tests/" + sauceJobId + "?auth=" + digest; 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/TestAsset.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | import java.util.Arrays; 4 | import java.util.Optional; 5 | 6 | /** 7 | * The Sauce Labs test assets do not have consistent names, labels and JSON keys/values. There is a difference 8 | * between the displayed filename in the UI, the JSON key in a HTTP response and its value. 9 | * This enum aims to combine all of these into a single place. 10 | * The enums themselves are named after what makes the most sense and what describes the test asset the best. 11 | * The label is the displayed filename in the UI. 12 | * The jsonKey is the JSON key that is used in the HTTP response and is mapped against 13 | * {@link com.saucelabs.saucerest.model.realdevices.DeviceJob} and {@link com.saucelabs.saucerest.model.jobs.JobAssets}. 14 | */ 15 | public enum TestAsset { 16 | SAUCE_LOG("log.json", "sauce-log"), 17 | VIDEO("video.mp4", "video_url"), 18 | SELENIUM_LOG("selenium-server.log", "log_url"), 19 | AUTOMATOR_LOG("automator.log", "automator.log"), 20 | LOGCAT_LOG("logcat.log", "logcat.log"), 21 | SYSLOG_LOG("ios-syslog.log", "ios-syslog.log"), 22 | HAR("network.har", "network_log_url"), 23 | PERFORMANCE("performance.json", "performance.json"), 24 | CONSOLE_LOG("console.json", "console.json"), 25 | // no JSON key because it's from the /asset/screenshots.zip endpoint 26 | SCREENSHOTS("screenshots.zip", null), 27 | APPIUM_LOG("appium-server.log", "framework_log_url"), 28 | INSIGHTS_LOG("insights.json", "testfairy_log_url"), 29 | CRASH_LOG("crash.json", "crash_log_url"), 30 | DEVICE_LOG("device.log", "device_log_url"), 31 | COMMANDS_LOG("commands.json", "requests_url"); 32 | 33 | public final String label; 34 | public final String jsonKey; 35 | 36 | TestAsset(String label, String jsonKey) { 37 | this.label = label; 38 | this.jsonKey = jsonKey; 39 | } 40 | 41 | public static Optional get(String label) { 42 | return Arrays.stream(TestAsset.values()) 43 | .filter(asset -> asset.label.equals(label)) 44 | .findFirst(); 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/Unfinished.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | public @interface Unfinished { 4 | String value(); 5 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/api/HttpClientConfig.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.api; 2 | 3 | import okhttp3.Authenticator; 4 | import okhttp3.Interceptor; 5 | 6 | import java.net.Proxy; 7 | import java.time.Duration; 8 | 9 | public class HttpClientConfig { 10 | 11 | private final Duration connectTimeout; 12 | private final Duration readTimeout; 13 | private final Duration writeTimeout; 14 | private final Proxy proxy; 15 | private final Authenticator authenticator; 16 | private final Interceptor interceptor; 17 | 18 | protected HttpClientConfig( 19 | Duration connectTimeout, 20 | Duration readTimeout, 21 | Duration writeTimeout, 22 | Proxy proxy, 23 | Authenticator authenticator, 24 | Interceptor interceptor) { 25 | this.connectTimeout = connectTimeout; 26 | this.readTimeout = readTimeout; 27 | this.writeTimeout = writeTimeout; 28 | this.proxy = proxy; 29 | this.authenticator = authenticator; 30 | this.interceptor = interceptor; 31 | } 32 | 33 | public static HttpClientConfig defaultConfig() { 34 | return new HttpClientConfig( 35 | Duration.ofSeconds(300), 36 | Duration.ofSeconds(300), 37 | Duration.ofSeconds(300), 38 | null, 39 | null, 40 | null); 41 | } 42 | 43 | public HttpClientConfig connectTimeout(Duration connectTimeout) { 44 | return new HttpClientConfig( 45 | connectTimeout, readTimeout, writeTimeout, proxy, authenticator, interceptor); 46 | } 47 | 48 | public HttpClientConfig readTimeout(Duration readTimeout) { 49 | return new HttpClientConfig( 50 | connectTimeout, readTimeout, writeTimeout, proxy, authenticator, interceptor); 51 | } 52 | 53 | public HttpClientConfig writeTimeout(Duration writeTimeout) { 54 | return new HttpClientConfig( 55 | connectTimeout, readTimeout, writeTimeout, proxy, authenticator, interceptor); 56 | } 57 | 58 | public HttpClientConfig proxy(Proxy proxy) { 59 | return new HttpClientConfig( 60 | connectTimeout, readTimeout, writeTimeout, proxy, authenticator, interceptor); 61 | } 62 | 63 | public HttpClientConfig authenticator(Authenticator authenticator) { 64 | return new HttpClientConfig( 65 | connectTimeout, readTimeout, writeTimeout, proxy, authenticator, interceptor); 66 | } 67 | 68 | public HttpClientConfig interceptor(Interceptor interceptor) { 69 | return new HttpClientConfig( 70 | connectTimeout, readTimeout, writeTimeout, proxy, authenticator, interceptor); 71 | } 72 | 73 | public Duration getConnectTimeout() { 74 | return this.connectTimeout; 75 | } 76 | 77 | public Duration getReadTimeout() { 78 | return this.readTimeout; 79 | } 80 | 81 | public Duration getWriteTimeout() { 82 | return this.writeTimeout; 83 | } 84 | 85 | public Proxy getProxy() { 86 | return this.proxy; 87 | } 88 | 89 | public Authenticator getAuthenticator() { 90 | return this.authenticator; 91 | } 92 | 93 | public Interceptor getInterceptor() { 94 | return this.interceptor; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/api/InsightsEndpoint.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.api; 2 | 3 | import com.saucelabs.saucerest.DataCenter; 4 | import com.saucelabs.saucerest.HttpMethod; 5 | import com.saucelabs.saucerest.Unfinished; 6 | import com.saucelabs.saucerest.model.insights.TestResult; 7 | import com.saucelabs.saucerest.model.insights.TestResultParameter; 8 | import java.io.IOException; 9 | import java.util.Map; 10 | 11 | @Unfinished("This endpoint is not yet completely implemented") 12 | public class InsightsEndpoint extends AbstractEndpoint { 13 | public InsightsEndpoint(DataCenter dataCenter) { 14 | super(dataCenter); 15 | } 16 | 17 | public InsightsEndpoint(String apiServer) { 18 | super(apiServer); 19 | } 20 | 21 | public InsightsEndpoint(String username, String accessKey, DataCenter dataCenter) { 22 | super(username, accessKey, dataCenter); 23 | } 24 | 25 | public InsightsEndpoint(String username, String accessKey, String apiServer) { 26 | super(username, accessKey, apiServer); 27 | } 28 | 29 | public TestResult getTestResults(TestResultParameter parameter) throws IOException { 30 | String url = getBaseEndpoint() + "v1/analytics/tests"; 31 | Map params; 32 | params = parameter.toMap(); 33 | 34 | return deserializeJSONObject(requestWithQueryParameters(url, HttpMethod.GET, params), TestResult.class); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/api/PerformanceEndpoint.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.api; 2 | 3 | import com.saucelabs.saucerest.DataCenter; 4 | import com.saucelabs.saucerest.Unfinished; 5 | 6 | @Unfinished("This endpoint is not yet completely implemented") 7 | public class PerformanceEndpoint extends AbstractEndpoint { 8 | public PerformanceEndpoint(DataCenter dataCenter) { 9 | super(dataCenter); 10 | } 11 | 12 | public PerformanceEndpoint(String apiServer) { 13 | super(apiServer); 14 | } 15 | 16 | public PerformanceEndpoint(String username, String accessKey, DataCenter dataCenter) { 17 | super(username, accessKey, dataCenter); 18 | } 19 | 20 | public PerformanceEndpoint(String username, String accessKey, String apiServer) { 21 | super(username, accessKey, apiServer); 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/api/PlatformEndpoint.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.api; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import com.saucelabs.saucerest.DataCenter; 5 | import com.saucelabs.saucerest.HttpMethod; 6 | import com.saucelabs.saucerest.model.platform.AppiumVersion; 7 | import com.saucelabs.saucerest.model.platform.EndOfLifeAppiumVersions; 8 | import com.saucelabs.saucerest.model.platform.Platform; 9 | import com.saucelabs.saucerest.model.platform.SupportedPlatforms; 10 | import com.saucelabs.saucerest.model.platform.TestStatus; 11 | import java.io.IOException; 12 | import java.lang.reflect.Type; 13 | import java.util.Map; 14 | import java.util.stream.Collectors; 15 | 16 | public class PlatformEndpoint extends AbstractEndpoint { 17 | 18 | public PlatformEndpoint(DataCenter dataCenter) { 19 | super(dataCenter, false); 20 | } 21 | 22 | public PlatformEndpoint(String apiServer) { 23 | super(apiServer, false); 24 | } 25 | 26 | public PlatformEndpoint(String username, String accessKey, DataCenter dataCenter) { 27 | super(username, accessKey, dataCenter); 28 | } 29 | 30 | public PlatformEndpoint(String username, String accessKey, String apiServer) { 31 | super(username, accessKey, apiServer); 32 | } 33 | 34 | /** 35 | * Returns the status of Sauce Labs. Documentation is 36 | * here 37 | * 38 | * @return {@link TestStatus} 39 | * @throws IOException API request failed 40 | */ 41 | public TestStatus getTestStatus() throws IOException { 42 | String url = getBaseEndpoint() + "/status"; 43 | 44 | return deserializeJSONObject(request(url, HttpMethod.GET), TestStatus.class); 45 | } 46 | 47 | /** 48 | * Returns supported platforms. Valid values are 'all', 'appium' or 'webdriver'. 49 | * Documentation is 50 | * here 51 | * 52 | * @param automationApi Specified automation framework: all, appium or webdriver. 53 | * @return {@link SupportedPlatforms} 54 | */ 55 | public SupportedPlatforms getSupportedPlatforms(String automationApi) throws IOException { 56 | String url = getBaseEndpoint() + "/platforms/" + automationApi; 57 | 58 | return new SupportedPlatforms(deserializeJSONArray(request(url, HttpMethod.GET), Platform.class)); 59 | } 60 | 61 | /** 62 | * Returns all supported Appium versions on Sauce Labs and the expected end of life date of the version. 63 | * Documentation is 64 | * here 65 | * 66 | * @return {@link EndOfLifeAppiumVersions} 67 | */ 68 | public EndOfLifeAppiumVersions getEndOfLifeAppiumVersions() throws IOException { 69 | String url = getBaseEndpoint() + "/platforms/appium/eol"; 70 | 71 | Type type = TypeToken.getParameterized(Map.class, String.class, Integer.class).getType(); 72 | Map mapOfVersions = deserializeJSON(request(url, HttpMethod.GET), type); 73 | return new EndOfLifeAppiumVersions(mapOfVersions.entrySet().stream() 74 | .map(entry -> new AppiumVersion(entry.getKey(), entry.getValue())) 75 | .collect(Collectors.toList()) 76 | ); 77 | } 78 | 79 | /** 80 | * The base endpoint of the Platform endpoint APIs. 81 | */ 82 | @Override 83 | protected String getBaseEndpoint() { 84 | return super.getBaseEndpoint() + "rest/v1/info"; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/api/ResponseHandler.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.api; 2 | 3 | import static java.net.HttpURLConnection.*; 4 | 5 | import com.saucelabs.saucerest.ErrorExplainers; 6 | import com.saucelabs.saucerest.HttpMethod; 7 | import com.saucelabs.saucerest.SauceException; 8 | import okhttp3.Response; 9 | 10 | /** 11 | * Handle non-200 HTTP responses differently if needed per endpoint. 12 | * For example, provide endpoint specific context and error message. 13 | */ 14 | public class ResponseHandler { 15 | private ResponseHandler() { 16 | throw new IllegalStateException("Utility class"); 17 | } 18 | 19 | public static void responseHandler(AbstractEndpoint endpoint, Response response) { 20 | // TODO: refactor this to use Java 17 pattern matching in the future 21 | // TODO: add more specific error messages for each endpoint 22 | switch (response.code()) { 23 | case HTTP_NOT_FOUND: 24 | if (endpoint instanceof SauceConnectEndpoint) { 25 | if (response.request().method().equals(HttpMethod.DELETE.label)) { 26 | String tunnelID = getID(response); 27 | throw new SauceException.NotFound(String.join(System.lineSeparator(), ErrorExplainers.TunnelNotFound(tunnelID))); 28 | } 29 | } else if (endpoint instanceof StorageEndpoint) { 30 | String appFileID = getID(response); 31 | throw new SauceException.NotFound(String.join(System.lineSeparator(), ErrorExplainers.AppNotFound(appFileID))); 32 | } else if (endpoint instanceof AccountsEndpoint) { 33 | String accountID = getID(response); 34 | throw new SauceException.NotFound(String.join(System.lineSeparator(), ErrorExplainers.AccountNotFound(accountID))); 35 | } 36 | throw new SauceException.NotFound(); 37 | case HTTP_UNAUTHORIZED: 38 | throw new SauceException.NotAuthorized(checkCredentials(endpoint)); 39 | case HTTP_BAD_REQUEST: 40 | if (endpoint instanceof JobsEndpoint) { 41 | if (response.message().equalsIgnoreCase("Job hasn't finished running")) { 42 | throw new SauceException.NotYetDone(ErrorExplainers.JobNotYetDone()); 43 | } 44 | } 45 | throw new RuntimeException("Unexpected code " + response); 46 | default: 47 | throw new RuntimeException("Unexpected code " + response); 48 | } 49 | } 50 | 51 | /** 52 | * Returns the ID of the resource from the URL. 53 | */ 54 | private static String getID(Response response) { 55 | String ID = getLastPathSegment(response, 1); 56 | 57 | // if ID is not a UUID 58 | if (!ID.matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}") || !ID.matches("\\d+")) { 59 | return getLastPathSegment(response, 2); 60 | } 61 | 62 | return ID; 63 | } 64 | 65 | private static String getLastPathSegment(Response response, int offset) { 66 | if (offset == 0) { 67 | offset = 1; 68 | } 69 | 70 | return response.request().url().pathSegments().get(response.request().url().pathSegments().size() - offset); 71 | } 72 | 73 | private static String checkCredentials(AbstractEndpoint endpoint) { 74 | String username = endpoint.username; 75 | String accessKey = endpoint.accessKey; 76 | 77 | if ((username == null || username.isEmpty()) && (accessKey == null || accessKey.isEmpty())) { 78 | return String.join(System.lineSeparator(), "Your username and access key are empty or blank.", ErrorExplainers.missingCreds()); 79 | } 80 | 81 | if (username == null || username.isEmpty()) { 82 | return String.join(System.lineSeparator(), "Your username is empty or blank.", ErrorExplainers.missingCreds()); 83 | } 84 | 85 | if (accessKey == null || accessKey.isEmpty()) { 86 | return String.join(System.lineSeparator(), "Your access key is empty or blank.", ErrorExplainers.missingCreds()); 87 | } 88 | 89 | return ErrorExplainers.incorrectCreds(username, accessKey); 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Allowed.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Allowed { 4 | 5 | public Integer vms; 6 | public Integer rds; 7 | public Integer macVms; 8 | 9 | /** 10 | * No args constructor for use in serialization 11 | */ 12 | public Allowed() { 13 | } 14 | 15 | /** 16 | * @param rds 17 | * @param macVms 18 | * @param vms 19 | */ 20 | public Allowed(Integer vms, Integer rds, Integer macVms) { 21 | super(); 22 | this.vms = vms; 23 | this.rds = rds; 24 | this.macVms = macVms; 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Concurrency.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Concurrency { 4 | 5 | public Organization organization; 6 | public Team team; 7 | 8 | /** 9 | * No args constructor for use in serialization 10 | */ 11 | public Concurrency() { 12 | } 13 | 14 | /** 15 | * @param organization 16 | * @param team 17 | */ 18 | public Concurrency(Organization organization, Team team) { 19 | super(); 20 | this.organization = organization; 21 | this.team = team; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/CreateTeam.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class CreateTeam { 4 | 5 | public String createdAt; 6 | public String description; 7 | public Group group; 8 | public String id; 9 | public Boolean isDefault; 10 | public String name; 11 | public String orgUuid; 12 | public Settings settings; 13 | public String updatedAt; 14 | 15 | /** 16 | * No args constructor for use in serialization 17 | */ 18 | public CreateTeam() { 19 | } 20 | 21 | public CreateTeam(String createdAt, String description, Group group, String id, Boolean isDefault, String name, String orgUuid, Settings settings, String updatedAt) { 22 | super(); 23 | this.createdAt = createdAt; 24 | this.description = description; 25 | this.group = group; 26 | this.id = id; 27 | this.isDefault = isDefault; 28 | this.name = name; 29 | this.orgUuid = orgUuid; 30 | this.settings = settings; 31 | this.updatedAt = updatedAt; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Current.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Current { 4 | 5 | public Integer vms; 6 | public Integer rds; 7 | public Integer macVms; 8 | 9 | /** 10 | * No args constructor for use in serialization 11 | */ 12 | public Current() { 13 | } 14 | 15 | /** 16 | * @param rds 17 | * @param macVms 18 | * @param vms 19 | */ 20 | public Current(Integer vms, Integer rds, Integer macVms) { 21 | super(); 22 | this.vms = vms; 23 | this.rds = rds; 24 | this.macVms = macVms; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Group.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Group { 4 | 5 | public String id; 6 | public String name; 7 | public Integer virtualMachines; 8 | public Integer realDevices; 9 | 10 | /** 11 | * No args constructor for use in serialization 12 | */ 13 | public Group() { 14 | } 15 | 16 | /** 17 | * @param realDevices 18 | * @param name 19 | * @param id 20 | * @param virtualMachines 21 | */ 22 | public Group(String id, String name, Integer virtualMachines, Integer realDevices) { 23 | super(); 24 | this.id = id; 25 | this.name = name; 26 | this.virtualMachines = virtualMachines; 27 | this.realDevices = realDevices; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Links.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Links { 4 | 5 | public Object next; 6 | public Object previous; 7 | public String first; 8 | public String last; 9 | 10 | /** 11 | * No args constructor for use in serialization 12 | */ 13 | public Links() { 14 | } 15 | 16 | /** 17 | * @param next 18 | * @param previous 19 | * @param last 20 | * @param first 21 | */ 22 | public Links(Object next, Object previous, String first, String last) { 23 | super(); 24 | this.next = next; 25 | this.previous = previous; 26 | this.first = first; 27 | this.last = last; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/LookupTeams.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class LookupTeams { 6 | 7 | public Links links; 8 | public Integer count; 9 | public List results = null; 10 | 11 | /** 12 | * No args constructor for use in serialization 13 | */ 14 | public LookupTeams() { 15 | } 16 | 17 | /** 18 | * @param count 19 | * @param links 20 | * @param results 21 | */ 22 | public LookupTeams(Links links, Integer count, List results) { 23 | super(); 24 | this.links = links; 25 | this.count = count; 26 | this.results = results; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/LookupUsers.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class LookupUsers { 6 | 7 | public Links links; 8 | public Integer count; 9 | public List results; 10 | 11 | /** 12 | * No args constructor for use in serialization 13 | */ 14 | public LookupUsers() { 15 | } 16 | 17 | public LookupUsers(Links links, Integer count, List results) { 18 | super(); 19 | this.links = links; 20 | this.count = count; 21 | this.results = results; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Organization.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Organization { 4 | 5 | public String id; 6 | public Settings settings; 7 | public Integer totalVmConcurrency; 8 | public String name; 9 | public String createdAt; 10 | public String updatedAt; 11 | public Current current; 12 | public Allowed allowed; 13 | 14 | /** 15 | * No args constructor for use in serialization 16 | */ 17 | public Organization() { 18 | } 19 | 20 | public Organization(String id, Settings settings, Integer totalVmConcurrency, String name, String createdAt, String updatedAt, Current current, Allowed allowed) { 21 | super(); 22 | this.id = id; 23 | this.settings = settings; 24 | this.totalVmConcurrency = totalVmConcurrency; 25 | this.name = name; 26 | this.createdAt = createdAt; 27 | this.updatedAt = updatedAt; 28 | this.current = current; 29 | this.allowed = allowed; 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Organizations.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class Organizations { 6 | 7 | public Links links; 8 | public Integer count; 9 | public List results; 10 | 11 | /** 12 | * No args constructor for use in serialization 13 | */ 14 | public Organizations() { 15 | } 16 | 17 | public Organizations(Links links, Integer count, List results) { 18 | super(); 19 | this.links = links; 20 | this.count = count; 21 | this.results = results; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/ResetAccessKeyForTeam.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class ResetAccessKeyForTeam { 4 | 5 | public String id; 6 | public String username; 7 | public String accessKey; 8 | 9 | /** 10 | * No args constructor for use in serialization 11 | */ 12 | public ResetAccessKeyForTeam() { 13 | } 14 | 15 | /** 16 | * @param accessKey 17 | * @param id 18 | * @param username 19 | */ 20 | public ResetAccessKeyForTeam(String id, String username, String accessKey) { 21 | super(); 22 | this.id = id; 23 | this.username = username; 24 | this.accessKey = accessKey; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Result.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class Result { 6 | 7 | public String id; 8 | public Settings settings; 9 | public Group group; 10 | public Boolean isDefault; 11 | public String name; 12 | public String orgUuid; 13 | public Integer userCount; 14 | public String email; 15 | public String firstName; 16 | public String lastName; 17 | public Boolean isActive; 18 | public Organization organization; 19 | public List roles; 20 | public List teams; 21 | public String username; 22 | 23 | /** 24 | * No args constructor for use in serialization 25 | */ 26 | public Result() { 27 | } 28 | 29 | public Result(String id, Settings settings, Group group, Boolean isDefault, String name, String orgUuid, Integer userCount, String email, String firstName, String lastName, Boolean isActive, Organization organization, List roles, List teams, String username) { 30 | this.id = id; 31 | this.settings = settings; 32 | this.group = group; 33 | this.isDefault = isDefault; 34 | this.name = name; 35 | this.orgUuid = orgUuid; 36 | this.userCount = userCount; 37 | this.email = email; 38 | this.firstName = firstName; 39 | this.lastName = lastName; 40 | this.isActive = isActive; 41 | this.organization = organization; 42 | this.roles = roles; 43 | this.teams = teams; 44 | this.username = username; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Role.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Role { 4 | 5 | public String name; 6 | public Integer role; 7 | 8 | /** 9 | * No args constructor for use in serialization 10 | */ 11 | public Role() { 12 | } 13 | 14 | public Role(String name, Integer role) { 15 | super(); 16 | this.name = name; 17 | this.role = role; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Roles.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public enum Roles { 4 | ORGADMIN(1), 5 | TEAMADMIN(4), 6 | MEMBER(3); 7 | 8 | private final int value; 9 | 10 | Roles(int value) { 11 | this.value = value; 12 | } 13 | 14 | public int getValue() { 15 | return value; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/SetTeam.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class SetTeam { 4 | 5 | public String id; 6 | public User user; 7 | public Team team; 8 | public String createdAt; 9 | public String updatedAt; 10 | 11 | public SetTeam(String id, User user, Team team, String createdAt, String updatedAt) { 12 | this.id = id; 13 | this.user = user; 14 | this.team = team; 15 | this.createdAt = createdAt; 16 | this.updatedAt = updatedAt; 17 | } 18 | 19 | /** 20 | * No args constructor for use in serialization 21 | */ 22 | public SetTeam() { 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Settings.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Settings { 4 | 5 | public Boolean allowIntegrationsPage; 6 | public Boolean canUseTunnelsWithPublicRealDevices; 7 | public String country; 8 | public Boolean disableEmailVerification; 9 | public Boolean groupsEnabled; 10 | public Object jitDefaultTeam; 11 | public String jitUsernamePrefix; 12 | public Boolean jobsCrossTeamSharing; 13 | public Boolean liveOnly; 14 | public String logoutUrl; 15 | public Integer macVirtualMachines; 16 | public Boolean performanceEnabled; 17 | public Boolean rdcEnabled; 18 | public Integer realDevices; 19 | public Boolean ssoEnabled; 20 | public Boolean ssoOnly; 21 | public Integer teamLimit; 22 | public Boolean teamLimitReached; 23 | public Object toPlan; 24 | public Object trialPeriod; 25 | public Boolean tunnelsLockdown; 26 | public String userType; 27 | public Integer virtualMachines; 28 | public Boolean vmLockdown; 29 | public Boolean ssoLegacyEnabled; 30 | 31 | /** 32 | * No args constructor for use in serialization 33 | */ 34 | public Settings() { 35 | } 36 | 37 | public Settings(Boolean allowIntegrationsPage, Boolean canUseTunnelsWithPublicRealDevices, String country, Boolean disableEmailVerification, Boolean groupsEnabled, Object jitDefaultTeam, String jitUsernamePrefix, Boolean jobsCrossTeamSharing, Boolean liveOnly, String logoutUrl, Integer macVirtualMachines, Boolean performanceEnabled, Boolean rdcEnabled, Integer realDevices, Boolean ssoEnabled, Boolean ssoOnly, Integer teamLimit, Boolean teamLimitReached, Object toPlan, Object trialPeriod, Boolean tunnelsLockdown, String userType, Integer virtualMachines, Boolean vmLockdown, Boolean ssoLegacyEnabled) { 38 | super(); 39 | this.allowIntegrationsPage = allowIntegrationsPage; 40 | this.canUseTunnelsWithPublicRealDevices = canUseTunnelsWithPublicRealDevices; 41 | this.country = country; 42 | this.disableEmailVerification = disableEmailVerification; 43 | this.groupsEnabled = groupsEnabled; 44 | this.jitDefaultTeam = jitDefaultTeam; 45 | this.jitUsernamePrefix = jitUsernamePrefix; 46 | this.jobsCrossTeamSharing = jobsCrossTeamSharing; 47 | this.liveOnly = liveOnly; 48 | this.logoutUrl = logoutUrl; 49 | this.macVirtualMachines = macVirtualMachines; 50 | this.performanceEnabled = performanceEnabled; 51 | this.rdcEnabled = rdcEnabled; 52 | this.realDevices = realDevices; 53 | this.ssoEnabled = ssoEnabled; 54 | this.ssoOnly = ssoOnly; 55 | this.teamLimit = teamLimit; 56 | this.teamLimitReached = teamLimitReached; 57 | this.toPlan = toPlan; 58 | this.trialPeriod = trialPeriod; 59 | this.tunnelsLockdown = tunnelsLockdown; 60 | this.userType = userType; 61 | this.virtualMachines = virtualMachines; 62 | this.vmLockdown = vmLockdown; 63 | this.ssoLegacyEnabled = ssoLegacyEnabled; 64 | } 65 | 66 | private Settings(Builder builder) { 67 | virtualMachines = builder.virtualMachines; 68 | } 69 | 70 | public static final class Builder { 71 | private Integer virtualMachines; 72 | 73 | public Builder setVirtualMachines(Integer val) { 74 | virtualMachines = val; 75 | return this; 76 | } 77 | 78 | public Settings build() { 79 | return new Settings(this); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/Team.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class Team { 4 | 5 | public String id; 6 | public Settings settings; 7 | public String createdAt; 8 | public String description; 9 | public Group group; 10 | public Boolean isDefault; 11 | public String name; 12 | public String orgUuid; 13 | public String updatedAt; 14 | public Current current; 15 | public Allowed allowed; 16 | 17 | /** 18 | * No args constructor for use in serialization 19 | */ 20 | public Team() { 21 | } 22 | 23 | /** 24 | * @param settings 25 | * @param createdAt 26 | * @param isDefault 27 | * @param name 28 | * @param description 29 | * @param id 30 | * @param group 31 | * @param orgUuid 32 | * @param updatedAt 33 | */ 34 | public Team(String id, Settings settings, String createdAt, String description, Group group, Boolean isDefault, String name, String orgUuid, String updatedAt, Current current, Allowed allowed) { 35 | super(); 36 | this.id = id; 37 | this.settings = settings; 38 | this.createdAt = createdAt; 39 | this.description = description; 40 | this.group = group; 41 | this.isDefault = isDefault; 42 | this.name = name; 43 | this.orgUuid = orgUuid; 44 | this.updatedAt = updatedAt; 45 | this.current = current; 46 | this.allowed = allowed; 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/TeamMembers.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class TeamMembers { 6 | 7 | public Links links; 8 | public Integer count; 9 | public List results; 10 | 11 | /** 12 | * No args constructor for use in serialization 13 | */ 14 | public TeamMembers() { 15 | } 16 | 17 | /** 18 | * @param count 19 | * @param links 20 | * @param results 21 | */ 22 | public TeamMembers(Links links, Integer count, List results) { 23 | super(); 24 | this.links = links; 25 | this.count = count; 26 | this.results = results; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/UpdateTeam.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class UpdateTeam { 4 | 5 | public String id; 6 | public Settings settings; 7 | public String createdAt; 8 | public String description; 9 | public Group group; 10 | public Boolean isDefault; 11 | public String name; 12 | public String orgUuid; 13 | public String updatedAt; 14 | 15 | /** 16 | * No args constructor for use in serialization 17 | */ 18 | public UpdateTeam() { 19 | } 20 | 21 | /** 22 | * @param settings 23 | * @param createdAt 24 | * @param isDefault 25 | * @param name 26 | * @param description 27 | * @param id 28 | * @param group 29 | * @param orgUuid 30 | * @param updatedAt 31 | */ 32 | public UpdateTeam(String id, Settings settings, String createdAt, String description, Group group, Boolean isDefault, String name, String orgUuid, String updatedAt) { 33 | super(); 34 | this.id = id; 35 | this.settings = settings; 36 | this.createdAt = createdAt; 37 | this.description = description; 38 | this.group = group; 39 | this.isDefault = isDefault; 40 | this.name = name; 41 | this.orgUuid = orgUuid; 42 | this.updatedAt = updatedAt; 43 | } 44 | 45 | private UpdateTeam(Builder builder) { 46 | settings = builder.settings; 47 | description = builder.description; 48 | name = builder.name; 49 | } 50 | 51 | public static final class Builder { 52 | private Settings settings; 53 | private String description; 54 | private String name; 55 | 56 | public Builder setSettings(Settings val) { 57 | settings = val; 58 | return this; 59 | } 60 | 61 | public Builder setDescription(String val) { 62 | description = val; 63 | return this; 64 | } 65 | 66 | public Builder setName(String val) { 67 | name = val; 68 | return this; 69 | } 70 | 71 | public UpdateTeam build() { 72 | return new UpdateTeam(this); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/UpdateUser.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class UpdateUser { 7 | private final String userID; 8 | private final String firstName; 9 | private final String lastName; 10 | private final String phone; 11 | 12 | private UpdateUser(Builder builder) { 13 | userID = builder.userID; 14 | firstName = builder.firstName; 15 | lastName = builder.lastName; 16 | phone = builder.phone; 17 | } 18 | 19 | public Map toMap() { 20 | Map parameters = new HashMap<>(); 21 | 22 | if (this.firstName != null) { 23 | parameters.put("first_name", this.firstName); 24 | } 25 | 26 | if (this.lastName != null) { 27 | parameters.put("last_name", this.lastName); 28 | } 29 | 30 | if (this.phone != null) { 31 | parameters.put("phone", this.phone); 32 | } 33 | 34 | return parameters; 35 | } 36 | 37 | public String getUserID() { 38 | return userID; 39 | } 40 | 41 | public static final class Builder { 42 | private String userID; 43 | private String firstName; 44 | private String lastName; 45 | private String phone; 46 | 47 | public Builder setUserID(String val) { 48 | userID = val; 49 | return this; 50 | } 51 | 52 | public Builder setFirstName(String val) { 53 | firstName = val; 54 | return this; 55 | } 56 | 57 | public Builder setLastName(String val) { 58 | lastName = val; 59 | return this; 60 | } 61 | 62 | public Builder setPhone(String val) { 63 | phone = val; 64 | return this; 65 | } 66 | 67 | public UpdateUser build() { 68 | if (phone != null && !phone.matches("^\\+?1?\\d{8,15}$")) { 69 | throw new IllegalArgumentException("Phone number must be in international format, e.g. +1 1234567890"); 70 | } 71 | 72 | return new UpdateUser(this); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/User.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class User { 6 | 7 | public String id; 8 | public String email; 9 | public String firstName; 10 | public String lastName; 11 | public String username; 12 | public String createdAt; 13 | public List groups; 14 | public Boolean isActive; 15 | public Boolean isOrganizationAdmin; 16 | public Boolean isTeamAdmin; 17 | public Boolean isStaff; 18 | public Boolean isSuperuser; 19 | public Organization organization; 20 | public String phone; 21 | public List roles; 22 | public List teams; 23 | public String updatedAt; 24 | public String userType; 25 | public String accessKey; 26 | 27 | /** 28 | * No args constructor for use in serialization 29 | */ 30 | public User() { 31 | } 32 | 33 | public User(String id, String email, String firstName, String lastName, String username, String createdAt, List groups, Boolean isActive, Boolean isOrganizationAdmin, Boolean isTeamAdmin, Boolean isStaff, Boolean isSuperuser, Organization organization, String phone, List roles, List teams, String updatedAt, String userType, String accessKey) { 34 | super(); 35 | this.id = id; 36 | this.email = email; 37 | this.firstName = firstName; 38 | this.lastName = lastName; 39 | this.username = username; 40 | this.createdAt = createdAt; 41 | this.groups = groups; 42 | this.isActive = isActive; 43 | this.isOrganizationAdmin = isOrganizationAdmin; 44 | this.isTeamAdmin = isTeamAdmin; 45 | this.isStaff = isStaff; 46 | this.isSuperuser = isSuperuser; 47 | this.organization = organization; 48 | this.phone = phone; 49 | this.roles = roles; 50 | this.teams = teams; 51 | this.updatedAt = updatedAt; 52 | this.userType = userType; 53 | this.accessKey = accessKey; 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/UserConcurrency.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | public class UserConcurrency { 4 | 5 | public Float timestamp; 6 | public Concurrency concurrency; 7 | 8 | /** 9 | * No args constructor for use in serialization 10 | */ 11 | public UserConcurrency() { 12 | } 13 | 14 | /** 15 | * @param timestamp 16 | * @param concurrency 17 | */ 18 | public UserConcurrency(Float timestamp, Concurrency concurrency) { 19 | super(); 20 | this.timestamp = timestamp; 21 | this.concurrency = concurrency; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/accounts/UsersTeam.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.accounts; 2 | 3 | import java.util.List; 4 | 5 | public class UsersTeam { 6 | 7 | public Links links; 8 | public Integer count; 9 | public List results; 10 | 11 | /** 12 | * No args constructor for use in serialization 13 | */ 14 | public UsersTeam() { 15 | } 16 | 17 | /** 18 | * @param count 19 | * @param links 20 | * @param results 21 | */ 22 | public UsersTeam(Links links, Integer count, List results) { 23 | super(); 24 | this.links = links; 25 | this.count = count; 26 | this.results = results; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/Build.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.builds; 2 | 3 | public class Build { 4 | 5 | public Integer creationTime; 6 | 7 | public Integer deletionTime; 8 | 9 | public Integer endTime; 10 | 11 | public String groupId; 12 | 13 | public String id; 14 | 15 | public Jobs jobs; 16 | 17 | public Integer modificationTime; 18 | 19 | public String name; 20 | 21 | public String orgId; 22 | 23 | public String ownerId; 24 | 25 | public Object passed; 26 | 27 | public Boolean _public; 28 | 29 | public Integer run; 30 | 31 | public String source; 32 | 33 | public Integer startTime; 34 | 35 | public String status; 36 | 37 | public String teamId; 38 | 39 | public Build() {} 40 | 41 | public Build( 42 | Integer creationTime, 43 | Integer deletionTime, 44 | Integer endTime, 45 | String groupId, 46 | String id, 47 | Jobs jobs, 48 | Integer modificationTime, 49 | String name, 50 | String orgId, 51 | String ownerId, 52 | Object passed, 53 | Boolean _public, 54 | Integer run, 55 | String source, 56 | Integer startTime, 57 | String status, 58 | String teamId) { 59 | super(); 60 | this.creationTime = creationTime; 61 | this.deletionTime = deletionTime; 62 | this.endTime = endTime; 63 | this.groupId = groupId; 64 | this.id = id; 65 | this.jobs = jobs; 66 | this.modificationTime = modificationTime; 67 | this.name = name; 68 | this.orgId = orgId; 69 | this.ownerId = ownerId; 70 | this.passed = passed; 71 | this._public = _public; 72 | this.run = run; 73 | this.source = source; 74 | this.startTime = startTime; 75 | this.status = status; 76 | this.teamId = teamId; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/JobInBuild.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.builds; 2 | 3 | public class JobInBuild { 4 | 5 | public Integer creationTime; 6 | 7 | public Integer deletionTime; 8 | 9 | public String id; 10 | 11 | public Integer modificationTime; 12 | 13 | public State state; 14 | 15 | /** No args constructor for use in serialization */ 16 | public JobInBuild() {} 17 | 18 | public JobInBuild( 19 | Integer creationTime, 20 | Integer deletionTime, 21 | String id, 22 | Integer modificationTime, 23 | State state) { 24 | this.creationTime = creationTime; 25 | this.deletionTime = deletionTime; 26 | this.id = id; 27 | this.modificationTime = modificationTime; 28 | this.state = state; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/Jobs.java: -------------------------------------------------------------------------------- 1 | 2 | package com.saucelabs.saucerest.model.builds; 3 | 4 | public class Jobs { 5 | 6 | public Integer completed; 7 | public Integer errored; 8 | public Integer failed; 9 | public Integer finished; 10 | public Integer passed; 11 | public Integer _public; 12 | public Integer queued; 13 | public Integer running; 14 | 15 | /** 16 | * No args constructor for use in serialization 17 | */ 18 | public Jobs() { 19 | } 20 | 21 | public Jobs(Integer completed, Integer errored, Integer failed, Integer finished, Integer passed, Integer _public, Integer queued, Integer running) { 22 | super(); 23 | this.completed = completed; 24 | this.errored = errored; 25 | this.failed = failed; 26 | this.finished = finished; 27 | this.passed = passed; 28 | this._public = _public; 29 | this.queued = queued; 30 | this.running = running; 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/JobsInBuild.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.builds; 2 | 3 | import java.util.List; 4 | 5 | public class JobsInBuild { 6 | 7 | public List jobs; 8 | 9 | /** No args constructor for use in serialization */ 10 | public JobsInBuild() {} 11 | 12 | public JobsInBuild(List jobs) { 13 | this.jobs = jobs; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/Sort.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.builds; 2 | 3 | public enum Sort { 4 | asc("asc"), 5 | desc("desc"); 6 | 7 | public final String value; 8 | 9 | Sort(String value) { 10 | this.value = value; 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/State.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.builds; 2 | 3 | public class State { 4 | 5 | public Boolean completed; 6 | 7 | public Boolean errored; 8 | 9 | public Boolean failed; 10 | 11 | public Boolean finished; 12 | 13 | public Boolean _new; 14 | 15 | public Boolean passed; 16 | 17 | public Boolean _public; 18 | 19 | public Boolean queued; 20 | 21 | public Boolean running; 22 | 23 | /** No args constructor for use in serialization */ 24 | public State() {} 25 | 26 | public State( 27 | Boolean completed, 28 | Boolean errored, 29 | Boolean failed, 30 | Boolean finished, 31 | Boolean _new, 32 | Boolean passed, 33 | Boolean _public, 34 | Boolean queued, 35 | Boolean running) { 36 | this.completed = completed; 37 | this.errored = errored; 38 | this.failed = failed; 39 | this.finished = finished; 40 | this._new = _new; 41 | this.passed = passed; 42 | this._public = _public; 43 | this.queued = queued; 44 | this.running = running; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/builds/Status.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.builds; 2 | 3 | public enum Status { 4 | running("running"), 5 | error("error"), 6 | failed("failed"), 7 | complete("complete"), 8 | success("success"); 9 | 10 | public final String value; 11 | 12 | Status(String value) { 13 | this.value = value; 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/insights/Item.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.insights; 2 | 3 | public class Item { 4 | 5 | public String ancestor; 6 | public String browser; 7 | public String browserNormalized; 8 | public String build; 9 | public String creationTime; 10 | public String detailsUrl; 11 | public Integer duration; 12 | public String endTime; 13 | public String error; 14 | public String id; 15 | public String name; 16 | public String os; 17 | public String osNormalized; 18 | public String owner; 19 | public String startTime; 20 | public String status; 21 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/insights/Meta.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.insights; 2 | 3 | public class Meta { 4 | public Integer status; 5 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/insights/TestResult.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.insights; 2 | 3 | import java.util.List; 4 | 5 | public class TestResult { 6 | public Boolean hasMore; 7 | public List items; 8 | public Meta meta; 9 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/BaseConfig.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | public class BaseConfig { 4 | 5 | public GoogChromeOptions googChromeOptions; 6 | public SauceOptions sauceOptions; 7 | public String browserName; 8 | public String platformName; 9 | public String browserVersion; 10 | 11 | public BaseConfig() { 12 | } 13 | 14 | public BaseConfig(GoogChromeOptions googChromeOptions, SauceOptions sauceOptions, String browserName, String platformName, String browserVersion) { 15 | super(); 16 | this.googChromeOptions = googChromeOptions; 17 | this.sauceOptions = sauceOptions; 18 | this.browserName = browserName; 19 | this.platformName = platformName; 20 | this.browserVersion = browserVersion; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/CommandCounts.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | public class CommandCounts { 4 | 5 | public Integer all; 6 | public Integer error; 7 | 8 | public CommandCounts() { 9 | } 10 | 11 | public CommandCounts(Integer all, Integer error) { 12 | super(); 13 | this.all = all; 14 | this.error = error; 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/CustomData.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | public class CustomData { 4 | 5 | public String tcd; 6 | public String editor; 7 | 8 | /** 9 | * No args constructor for use in serialization 10 | */ 11 | public CustomData() { 12 | } 13 | 14 | /** 15 | * @param editor 16 | * @param tcd 17 | */ 18 | public CustomData(String tcd, String editor) { 19 | super(); 20 | this.tcd = tcd; 21 | this.editor = editor; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/GetJobsParameters.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class GetJobsParameters { 7 | private final String username; 8 | private final int limit; 9 | private final int skip; 10 | private final int from; 11 | private final int to; 12 | private final Format format; 13 | 14 | public GetJobsParameters(String username, int limit, int skip, int from, int to, Format format) { 15 | this.username = username; 16 | this.limit = limit; 17 | this.skip = skip; 18 | this.from = from; 19 | this.to = to; 20 | this.format = format; 21 | } 22 | 23 | private GetJobsParameters(Builder builder) { 24 | username = builder.username; 25 | limit = builder.limit; 26 | skip = builder.skip; 27 | from = builder.from; 28 | to = builder.to; 29 | format = builder.format; 30 | } 31 | 32 | public Map toMap() { 33 | Map parameters = new HashMap<>(); 34 | 35 | if (this.username != null) { 36 | parameters.put("username", this.username); 37 | } 38 | 39 | if (this.limit > 0) { 40 | parameters.put("limit", this.limit); 41 | } 42 | 43 | if (this.skip > 0) { 44 | parameters.put("skip", this.skip); 45 | } 46 | 47 | if (this.from > 0) { 48 | parameters.put("from", this.from); 49 | } 50 | 51 | if (this.to > 0) { 52 | parameters.put("to", this.to); 53 | } 54 | 55 | if (this.format != null) { 56 | parameters.put("format", this.format); 57 | } 58 | 59 | return parameters; 60 | } 61 | 62 | public enum Format { 63 | JSON("json"), 64 | CSV("csv"); 65 | 66 | private final String value; 67 | 68 | Format(String value) { 69 | this.value = value; 70 | } 71 | 72 | public String getValue() { 73 | return value; 74 | } 75 | } 76 | 77 | public static final class Builder { 78 | private String username; 79 | private int limit; 80 | private int skip; 81 | private int from; 82 | private int to; 83 | private Format format; 84 | 85 | public Builder setUsername(String val) { 86 | username = val; 87 | return this; 88 | } 89 | 90 | public Builder setLimit(int val) { 91 | limit = val; 92 | return this; 93 | } 94 | 95 | public Builder setSkip(int val) { 96 | skip = val; 97 | return this; 98 | } 99 | 100 | public Builder setFrom(int val) { 101 | from = val; 102 | return this; 103 | } 104 | 105 | public Builder setTo(int val) { 106 | to = val; 107 | return this; 108 | } 109 | 110 | public Builder setFormat(Format val) { 111 | format = val; 112 | return this; 113 | } 114 | 115 | public GetJobsParameters build() { 116 | return new GetJobsParameters(this); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/GoogChromeOptions.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | import java.util.List; 4 | 5 | public class GoogChromeOptions { 6 | 7 | public List args; 8 | public List extensions; 9 | 10 | public GoogChromeOptions() { 11 | } 12 | 13 | public GoogChromeOptions(List args, List extensions) { 14 | super(); 15 | this.args = args; 16 | this.extensions = extensions; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/Job.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | public class Job { 8 | public String status; 9 | public BaseConfig baseConfig; 10 | public CommandCounts commandCounts; 11 | public Object deletionTime; 12 | public Object url; 13 | public String orgId; 14 | public Integer creationTime; 15 | public String id; 16 | public String teamId; 17 | public Object performanceEnabled; 18 | public Object assignedTunnelId; 19 | public Boolean container; 20 | public String groupId; 21 | @SerializedName("public") 22 | public String _public; 23 | public Object breakpointed; 24 | public String browserShortVersion; 25 | public String videoUrl; 26 | @SerializedName("custom-data") 27 | public Map customData; 28 | public String browserVersion; 29 | public String owner; 30 | public String automationBackend; 31 | public Boolean collectsAutomatorLog; 32 | public Boolean recordScreenshots; 33 | public Boolean recordVideo; 34 | public Object build; 35 | public Boolean passed; 36 | public String logUrl; 37 | public Integer startTime; 38 | public Boolean proxied; 39 | public Integer modificationTime; 40 | public String name; 41 | public Integer commandsNotSuccessful; 42 | public String consolidatedStatus; 43 | public Object seleniumVersion; 44 | public Boolean manual; 45 | public Integer endTime; 46 | public Object error; 47 | public String os; 48 | public String browser; 49 | public List tags; 50 | public String videoSecret; 51 | 52 | public Job() { 53 | } 54 | 55 | public Job(String status, BaseConfig baseConfig, CommandCounts commandCounts, Object deletionTime, Object url, String orgId, Integer creationTime, String id, String teamId, Object performanceEnabled, Object assignedTunnelId, Boolean container, String groupId, String _public, Object breakpointed, String browserShortVersion, String videoUrl, Map customData, String browserVersion, String owner, String automationBackend, Boolean collectsAutomatorLog, Boolean recordScreenshots, Boolean recordVideo, Object build, Boolean passed, String logUrl, Integer startTime, Boolean proxied, Integer modificationTime, String name, Integer commandsNotSuccessful, String consolidatedStatus, Object seleniumVersion, Boolean manual, Integer endTime, Object error, String os, String browser, List tags, String videoSecret) { 56 | this.status = status; 57 | this.baseConfig = baseConfig; 58 | this.commandCounts = commandCounts; 59 | this.deletionTime = deletionTime; 60 | this.url = url; 61 | this.orgId = orgId; 62 | this.creationTime = creationTime; 63 | this.id = id; 64 | this.teamId = teamId; 65 | this.performanceEnabled = performanceEnabled; 66 | this.assignedTunnelId = assignedTunnelId; 67 | this.container = container; 68 | this.groupId = groupId; 69 | this._public = _public; 70 | this.breakpointed = breakpointed; 71 | this.browserShortVersion = browserShortVersion; 72 | this.videoUrl = videoUrl; 73 | this.customData = customData; 74 | this.browserVersion = browserVersion; 75 | this.owner = owner; 76 | this.automationBackend = automationBackend; 77 | this.collectsAutomatorLog = collectsAutomatorLog; 78 | this.recordScreenshots = recordScreenshots; 79 | this.recordVideo = recordVideo; 80 | this.build = build; 81 | this.passed = passed; 82 | this.logUrl = logUrl; 83 | this.startTime = startTime; 84 | this.proxied = proxied; 85 | this.modificationTime = modificationTime; 86 | this.name = name; 87 | this.commandsNotSuccessful = commandsNotSuccessful; 88 | this.consolidatedStatus = consolidatedStatus; 89 | this.seleniumVersion = seleniumVersion; 90 | this.manual = manual; 91 | this.endTime = endTime; 92 | this.error = error; 93 | this.os = os; 94 | this.browser = browser; 95 | this.tags = tags; 96 | this.videoSecret = videoSecret; 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/JobAssets.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import com.google.gson.annotations.SerializedName; 8 | 9 | public class JobAssets { 10 | 11 | @SerializedName("video.mp4") 12 | public String videoMp4; 13 | @SerializedName("selenium-log") 14 | public String seleniumLog; 15 | @SerializedName("ios-syslog.log") 16 | public String iosSyslogLog; 17 | @SerializedName("sauce-log") 18 | public String sauceLog; 19 | public String video; 20 | public List screenshots; 21 | @SerializedName("logcat.log") 22 | public String logcatLog; 23 | 24 | public JobAssets() { 25 | } 26 | 27 | public JobAssets(String videoMp4, String seleniumLog, String iosSyslogLog, String sauceLog, String video, List screenshots, String logcatLog) { 28 | super(); 29 | this.videoMp4 = videoMp4; 30 | this.seleniumLog = seleniumLog; 31 | this.iosSyslogLog = iosSyslogLog; 32 | this.sauceLog = sauceLog; 33 | this.video = video; 34 | this.screenshots = screenshots; 35 | this.logcatLog = logcatLog; 36 | } 37 | 38 | public Map getAvailableAssets() { 39 | Map assetMap = new HashMap<>(); 40 | 41 | // Duplicate video 42 | // if (this.videoMp4 != null) { 43 | // assetMap.put("video.mp4", this.videoMp4); 44 | // } 45 | 46 | if (this.seleniumLog != null) { 47 | assetMap.put("selenium-log", this.seleniumLog); 48 | } 49 | 50 | if (this.iosSyslogLog != null) { 51 | assetMap.put("ios-syslog.log", this.iosSyslogLog); 52 | } 53 | 54 | if (this.sauceLog != null) { 55 | assetMap.put("sauce-log", this.sauceLog); 56 | } 57 | 58 | if (this.video != null) { 59 | assetMap.put("video", this.video); 60 | } 61 | 62 | // Use different method to get screenshots 63 | // if (this.screenshots != null) { 64 | // assetMap.put("screenshots", this.screenshots); 65 | // } 66 | 67 | if (this.logcatLog != null) { 68 | assetMap.put("logcat.log", this.logcatLog); 69 | } 70 | 71 | return assetMap; 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/SauceOptions.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | import java.util.List; 4 | 5 | public class SauceOptions { 6 | 7 | public List tags; 8 | public String build; 9 | public String name; 10 | 11 | public SauceOptions() { 12 | } 13 | 14 | public SauceOptions(List tags, String build, String name) { 15 | super(); 16 | this.tags = tags; 17 | this.build = build; 18 | this.name = name; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/jobs/UpdateJobParameter.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.jobs; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import com.saucelabs.saucerest.JobVisibility; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class UpdateJobParameter { 10 | private final String name; 11 | private final List tags; 12 | @SerializedName("public") 13 | private final JobVisibility visibility; 14 | private final Boolean passed; 15 | private final String build; 16 | @SerializedName("custom-data") 17 | private final Map customData; 18 | 19 | public UpdateJobParameter(String name, List tags, JobVisibility visibility, boolean passed, String build, Map customData) { 20 | this.name = name; 21 | this.tags = tags; 22 | this.visibility = visibility; 23 | this.passed = passed; 24 | this.build = build; 25 | this.customData = customData; 26 | } 27 | 28 | private UpdateJobParameter(Builder builder) { 29 | name = builder.name; 30 | tags = builder.tags; 31 | visibility = builder.visibility; 32 | passed = builder.passed; 33 | build = builder.build; 34 | customData = builder.customData; 35 | } 36 | 37 | public static final class Builder { 38 | private String name; 39 | private List tags; 40 | private JobVisibility visibility; 41 | private Boolean passed; 42 | private String build; 43 | private Map customData; 44 | 45 | public Builder setName(String val) { 46 | name = val; 47 | return this; 48 | } 49 | 50 | public Builder setTags(List val) { 51 | tags = val; 52 | return this; 53 | } 54 | 55 | public Builder setVisibility(JobVisibility val) { 56 | visibility = val; 57 | return this; 58 | } 59 | 60 | public Builder setPassed(boolean val) { 61 | passed = val; 62 | return this; 63 | } 64 | 65 | public Builder setBuild(String val) { 66 | build = val; 67 | return this; 68 | } 69 | 70 | public Builder setCustomData(Map val) { 71 | customData = val; 72 | return this; 73 | } 74 | 75 | public UpdateJobParameter build() { 76 | return new UpdateJobParameter(this); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/platform/AppiumVersion.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.platform; 2 | 3 | public class AppiumVersion { 4 | 5 | private final String version; 6 | private final Integer timestamp; 7 | 8 | public AppiumVersion(String version, Integer timestamp) { 9 | this.version = version; 10 | this.timestamp = timestamp; 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/platform/EndOfLifeAppiumVersions.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.platform; 2 | 3 | import java.util.List; 4 | 5 | public class EndOfLifeAppiumVersions { 6 | 7 | private final List appiumVersions; 8 | 9 | public List getAppiumVersionList() { 10 | return appiumVersions; 11 | } 12 | 13 | public EndOfLifeAppiumVersions(List appiumVersions) { 14 | this.appiumVersions = appiumVersions; 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/platform/Platform.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.platform; 2 | 3 | import java.util.List; 4 | 5 | public class Platform { 6 | 7 | public String shortVersion; 8 | public String longName; 9 | public String apiName; 10 | public String longVersion; 11 | public String latestStableVersion; 12 | public String automationBackend; 13 | public String os; 14 | public List deprecatedBackendVersions = null; 15 | public String recommendedBackendVersion; 16 | public List supportedBackendVersions = null; 17 | public String device; 18 | 19 | public Platform() { 20 | } 21 | 22 | public Platform(String shortVersion, String longName, String apiName, String longVersion, String latestStableVersion, String automationBackend, String os, List deprecatedBackendVersions, String recommendedBackendVersion, List supportedBackendVersions, String device) { 23 | super(); 24 | this.shortVersion = shortVersion; 25 | this.longName = longName; 26 | this.apiName = apiName; 27 | this.longVersion = longVersion; 28 | this.latestStableVersion = latestStableVersion; 29 | this.automationBackend = automationBackend; 30 | this.os = os; 31 | this.deprecatedBackendVersions = deprecatedBackendVersions; 32 | this.recommendedBackendVersion = recommendedBackendVersion; 33 | this.supportedBackendVersions = supportedBackendVersions; 34 | this.device = device; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/platform/SupportedPlatforms.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.platform; 2 | 3 | import java.util.List; 4 | 5 | public class SupportedPlatforms { 6 | 7 | public List getPlatforms() { 8 | return platforms; 9 | } 10 | 11 | private final List platforms; 12 | 13 | public SupportedPlatforms(List platforms) { 14 | super(); 15 | this.platforms = platforms; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/platform/TestStatus.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.platform; 2 | 3 | public class TestStatus { 4 | 5 | public double waitTime; 6 | public boolean serviceOperational; 7 | public String statusMessage; 8 | 9 | public TestStatus() { 10 | 11 | } 12 | 13 | public TestStatus(double waitTime, boolean serviceOperational, String statusMessage) { 14 | this.waitTime = waitTime; 15 | this.serviceOperational = serviceOperational; 16 | this.statusMessage = statusMessage; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/ApplicationSummary.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | public class ApplicationSummary { 4 | 5 | public String appStorageId; 6 | public Integer groupId; 7 | public String filename; 8 | public String name; 9 | public String packageName; 10 | public String version; 11 | public String versionCode; 12 | public Object shortVersion; 13 | public Integer minSdkLevel; 14 | public Integer targetSdkLevel; 15 | public Object minOsVersion; 16 | public Object targetOsVersion; 17 | 18 | public ApplicationSummary() { 19 | } 20 | 21 | public ApplicationSummary(String appStorageId, Integer groupId, String filename, String name, String packageName, String version, String versionCode, Object shortVersion, Integer minSdkLevel, Integer targetSdkLevel, Object minOsVersion, Object targetOsVersion) { 22 | super(); 23 | this.appStorageId = appStorageId; 24 | this.groupId = groupId; 25 | this.filename = filename; 26 | this.name = name; 27 | this.packageName = packageName; 28 | this.version = version; 29 | this.versionCode = versionCode; 30 | this.shortVersion = shortVersion; 31 | this.minSdkLevel = minSdkLevel; 32 | this.targetSdkLevel = targetSdkLevel; 33 | this.minOsVersion = minOsVersion; 34 | this.targetOsVersion = targetOsVersion; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/AvailableDevices.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | import java.util.List; 4 | 5 | public class AvailableDevices { 6 | private final List availableDevicesList; 7 | 8 | public AvailableDevices(List availableDevicesList) { 9 | super(); 10 | this.availableDevicesList = availableDevicesList; 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/BaseConfig.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | public class BaseConfig { 4 | // model for API response 5 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/Concurrency.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | public class Concurrency { 4 | 5 | public Organization organization; 6 | 7 | /** 8 | * No args constructor for use in serialization 9 | */ 10 | public Concurrency() { 11 | } 12 | 13 | /** 14 | * @param organization 15 | */ 16 | public Concurrency(Organization organization) { 17 | super(); 18 | this.organization = organization; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/Device.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | import java.util.List; 4 | 5 | public class Device { 6 | 7 | public String abiType; 8 | public Integer apiLevel; 9 | public Integer cpuCores; 10 | public Integer cpuFrequency; 11 | public String defaultOrientation; 12 | public Integer dpi; 13 | public Boolean hasOnScreenButtons; 14 | public String id; 15 | public String internalOrientation; 16 | public Integer internalStorageSize; 17 | public Boolean isArm; 18 | public Boolean isKeyGuardDisabled; 19 | public Boolean isPrivate; 20 | public Boolean isRooted; 21 | public Boolean isTablet; 22 | public List manufacturer = null; 23 | public String modelNumber; 24 | public String name; 25 | public String os; 26 | public String osVersion; 27 | public Integer pixelsPerPoint; 28 | public Integer ramSize; 29 | public Integer resolutionHeight; 30 | public Integer resolutionWidth; 31 | public Float screenSize; 32 | public Integer sdCardSize; 33 | public Boolean supportsAppiumWebAppTesting; 34 | public Boolean supportsGlobalProxy; 35 | public Boolean supportsMinicapSocketConnection; 36 | public Boolean supportsMockLocations; 37 | public String cpuType; 38 | public String deviceFamily; 39 | public String dpiName; 40 | public Boolean isAlternativeIoEnabled; 41 | public Boolean supportsManualWebTesting; 42 | public Boolean supportsMultiTouch; 43 | public Boolean supportsXcuiTest; 44 | 45 | public Device() { 46 | } 47 | 48 | public Device(String abiType, Integer apiLevel, Integer cpuCores, Integer cpuFrequency, String defaultOrientation, Integer dpi, Boolean hasOnScreenButtons, String id, String internalOrientation, Integer internalStorageSize, Boolean isArm, Boolean isKeyGuardDisabled, Boolean isPrivate, Boolean isRooted, Boolean isTablet, List manufacturer, String modelNumber, String name, String os, String osVersion, Integer pixelsPerPoint, Integer ramSize, Integer resolutionHeight, Integer resolutionWidth, Float screenSize, Integer sdCardSize, Boolean supportsAppiumWebAppTesting, Boolean supportsGlobalProxy, Boolean supportsMinicapSocketConnection, Boolean supportsMockLocations, String cpuType, String deviceFamily, String dpiName, Boolean isAlternativeIoEnabled, Boolean supportsManualWebTesting, Boolean supportsMultiTouch, Boolean supportsXcuiTest) { 49 | super(); 50 | this.abiType = abiType; 51 | this.apiLevel = apiLevel; 52 | this.cpuCores = cpuCores; 53 | this.cpuFrequency = cpuFrequency; 54 | this.defaultOrientation = defaultOrientation; 55 | this.dpi = dpi; 56 | this.hasOnScreenButtons = hasOnScreenButtons; 57 | this.id = id; 58 | this.internalOrientation = internalOrientation; 59 | this.internalStorageSize = internalStorageSize; 60 | this.isArm = isArm; 61 | this.isKeyGuardDisabled = isKeyGuardDisabled; 62 | this.isPrivate = isPrivate; 63 | this.isRooted = isRooted; 64 | this.isTablet = isTablet; 65 | this.manufacturer = manufacturer; 66 | this.modelNumber = modelNumber; 67 | this.name = name; 68 | this.os = os; 69 | this.osVersion = osVersion; 70 | this.pixelsPerPoint = pixelsPerPoint; 71 | this.ramSize = ramSize; 72 | this.resolutionHeight = resolutionHeight; 73 | this.resolutionWidth = resolutionWidth; 74 | this.screenSize = screenSize; 75 | this.sdCardSize = sdCardSize; 76 | this.supportsAppiumWebAppTesting = supportsAppiumWebAppTesting; 77 | this.supportsGlobalProxy = supportsGlobalProxy; 78 | this.supportsMinicapSocketConnection = supportsMinicapSocketConnection; 79 | this.supportsMockLocations = supportsMockLocations; 80 | this.cpuType = cpuType; 81 | this.deviceFamily = deviceFamily; 82 | this.dpiName = dpiName; 83 | this.isAlternativeIoEnabled = isAlternativeIoEnabled; 84 | this.supportsManualWebTesting = supportsManualWebTesting; 85 | this.supportsMultiTouch = supportsMultiTouch; 86 | this.supportsXcuiTest = supportsXcuiTest; 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/DeviceDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | import java.util.List; 4 | 5 | public class DeviceDescriptor { 6 | 7 | public String abiType; 8 | public Integer apiLevel; 9 | public Integer cpuCores; 10 | public Integer cpuFrequency; 11 | public String defaultOrientation; 12 | public Integer dpi; 13 | public Boolean hasOnScreenButtons; 14 | public String id; 15 | public String internalOrientation; 16 | public Integer internalStorageSize; 17 | public Boolean isArm; 18 | public Boolean isKeyGuardDisabled; 19 | public Boolean isPrivate; 20 | public Boolean isRooted; 21 | public Boolean isTablet; 22 | public List manufacturer = null; 23 | public String modelNumber; 24 | public String name; 25 | public String os; 26 | public String osVersion; 27 | public Integer pixelsPerPoint; 28 | public Integer ramSize; 29 | public Integer resolutionHeight; 30 | public Integer resolutionWidth; 31 | public Float screenSize; 32 | public Integer sdCardSize; 33 | public Boolean supportsAppiumWebAppTesting; 34 | public Boolean supportsGlobalProxy; 35 | public Boolean supportsMinicapSocketConnection; 36 | public Boolean supportsMockLocations; 37 | public String cpuType; 38 | public String deviceFamily; 39 | public String dpiName; 40 | public Boolean isAlternativeIoEnabled; 41 | public Boolean supportsManualWebTesting; 42 | public Boolean supportsMultiTouch; 43 | public Boolean supportsXcuiTest; 44 | 45 | public DeviceDescriptor() { 46 | } 47 | 48 | public DeviceDescriptor(String abiType, Integer apiLevel, Integer cpuCores, Integer cpuFrequency, String defaultOrientation, Integer dpi, Boolean hasOnScreenButtons, String id, String internalOrientation, Integer internalStorageSize, Boolean isArm, Boolean isKeyGuardDisabled, Boolean isPrivate, Boolean isRooted, Boolean isTablet, List manufacturer, String modelNumber, String name, String os, String osVersion, Integer pixelsPerPoint, Integer ramSize, Integer resolutionHeight, Integer resolutionWidth, Float screenSize, Integer sdCardSize, Boolean supportsAppiumWebAppTesting, Boolean supportsGlobalProxy, Boolean supportsMinicapSocketConnection, Boolean supportsMockLocations, String cpuType, String deviceFamily, String dpiName, Boolean isAlternativeIoEnabled, Boolean supportsManualWebTesting, Boolean supportsMultiTouch, Boolean supportsXcuiTest) { 49 | super(); 50 | this.abiType = abiType; 51 | this.apiLevel = apiLevel; 52 | this.cpuCores = cpuCores; 53 | this.cpuFrequency = cpuFrequency; 54 | this.defaultOrientation = defaultOrientation; 55 | this.dpi = dpi; 56 | this.hasOnScreenButtons = hasOnScreenButtons; 57 | this.id = id; 58 | this.internalOrientation = internalOrientation; 59 | this.internalStorageSize = internalStorageSize; 60 | this.isArm = isArm; 61 | this.isKeyGuardDisabled = isKeyGuardDisabled; 62 | this.isPrivate = isPrivate; 63 | this.isRooted = isRooted; 64 | this.isTablet = isTablet; 65 | this.manufacturer = manufacturer; 66 | this.modelNumber = modelNumber; 67 | this.name = name; 68 | this.os = os; 69 | this.osVersion = osVersion; 70 | this.pixelsPerPoint = pixelsPerPoint; 71 | this.ramSize = ramSize; 72 | this.resolutionHeight = resolutionHeight; 73 | this.resolutionWidth = resolutionWidth; 74 | this.screenSize = screenSize; 75 | this.sdCardSize = sdCardSize; 76 | this.supportsAppiumWebAppTesting = supportsAppiumWebAppTesting; 77 | this.supportsGlobalProxy = supportsGlobalProxy; 78 | this.supportsMinicapSocketConnection = supportsMinicapSocketConnection; 79 | this.supportsMockLocations = supportsMockLocations; 80 | this.cpuType = cpuType; 81 | this.deviceFamily = deviceFamily; 82 | this.dpiName = dpiName; 83 | this.isAlternativeIoEnabled = isAlternativeIoEnabled; 84 | this.supportsManualWebTesting = supportsManualWebTesting; 85 | this.supportsMultiTouch = supportsMultiTouch; 86 | this.supportsXcuiTest = supportsXcuiTest; 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/DeviceJob.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | import java.util.List; 4 | 5 | public class DeviceJob { 6 | 7 | public ApplicationSummary applicationSummary; 8 | public Object assignedTunnelId; 9 | public String deviceType; 10 | public String ownerSauce; 11 | public String automationBackend; 12 | public BaseConfig baseConfig; 13 | public String build; 14 | public Boolean collectsAutomatorLog; 15 | public String consolidatedStatus; 16 | public Long creationTime; 17 | public DeviceDescriptor deviceDescriptor; 18 | public Long endTime; 19 | public Object error; 20 | public String id; 21 | public String frameworkLogUrl; 22 | public String deviceLogUrl; 23 | public String requestsUrl; 24 | public Object testCasesUrl; 25 | public Object junitLogUrl; 26 | public Boolean manual; 27 | public Long modificationTime; 28 | public String name; 29 | public String os; 30 | public String osVersion; 31 | public String deviceName; 32 | public Boolean passed; 33 | public Boolean proxied; 34 | public Boolean recordScreenshots; 35 | public List screenshots = null; 36 | public Boolean recordVideo; 37 | public Long startTime; 38 | public String status; 39 | public List tags = null; 40 | public String videoUrl; 41 | public String remoteAppFileUrl; 42 | public String appiumSessionId; 43 | public Object deviceSessionId; 44 | public String client; 45 | public String networkLogUrl; 46 | public String testfairyLogUrl; 47 | public String testReportType; 48 | public String crashLogUrl; 49 | public Boolean usedCachedDevice; 50 | public String backtraceUrl; 51 | public String appiumVersion; 52 | 53 | public DeviceJob() { 54 | } 55 | 56 | public DeviceJob(ApplicationSummary applicationSummary, Object assignedTunnelId, String deviceType, String ownerSauce, String automationBackend, BaseConfig baseConfig, String build, Boolean collectsAutomatorLog, String consolidatedStatus, Long creationTime, DeviceDescriptor deviceDescriptor, Long endTime, Object error, String id, String frameworkLogUrl, String deviceLogUrl, String requestsUrl, Object testCasesUrl, Object junitLogUrl, Boolean manual, Long modificationTime, String name, String os, String osVersion, String deviceName, Boolean passed, Boolean proxied, Boolean recordScreenshots, List screenshots, Boolean recordVideo, Long startTime, String status, List tags, String videoUrl, String remoteAppFileUrl, String appiumSessionId, Object deviceSessionId, String client, String networkLogUrl, String testfairyLogUrl, String testReportType, String crashLogUrl, Boolean usedCachedDevice, String backtraceUrl, String appiumVersion) { 57 | super(); 58 | this.applicationSummary = applicationSummary; 59 | this.assignedTunnelId = assignedTunnelId; 60 | this.deviceType = deviceType; 61 | this.ownerSauce = ownerSauce; 62 | this.automationBackend = automationBackend; 63 | this.baseConfig = baseConfig; 64 | this.build = build; 65 | this.collectsAutomatorLog = collectsAutomatorLog; 66 | this.consolidatedStatus = consolidatedStatus; 67 | this.creationTime = creationTime; 68 | this.deviceDescriptor = deviceDescriptor; 69 | this.endTime = endTime; 70 | this.error = error; 71 | this.id = id; 72 | this.frameworkLogUrl = frameworkLogUrl; 73 | this.deviceLogUrl = deviceLogUrl; 74 | this.requestsUrl = requestsUrl; 75 | this.testCasesUrl = testCasesUrl; 76 | this.junitLogUrl = junitLogUrl; 77 | this.manual = manual; 78 | this.modificationTime = modificationTime; 79 | this.name = name; 80 | this.os = os; 81 | this.osVersion = osVersion; 82 | this.deviceName = deviceName; 83 | this.passed = passed; 84 | this.proxied = proxied; 85 | this.recordScreenshots = recordScreenshots; 86 | this.screenshots = screenshots; 87 | this.recordVideo = recordVideo; 88 | this.startTime = startTime; 89 | this.status = status; 90 | this.tags = tags; 91 | this.videoUrl = videoUrl; 92 | this.remoteAppFileUrl = remoteAppFileUrl; 93 | this.appiumSessionId = appiumSessionId; 94 | this.deviceSessionId = deviceSessionId; 95 | this.client = client; 96 | this.networkLogUrl = networkLogUrl; 97 | this.testfairyLogUrl = testfairyLogUrl; 98 | this.testReportType = testReportType; 99 | this.crashLogUrl = crashLogUrl; 100 | this.usedCachedDevice = usedCachedDevice; 101 | this.backtraceUrl = backtraceUrl; 102 | this.appiumVersion = appiumVersion; 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/DeviceJobs.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | import java.util.List; 4 | 5 | import com.google.gson.annotations.SerializedName; 6 | 7 | public class DeviceJobs { 8 | 9 | public List entities; 10 | @SerializedName("metaData") 11 | public MetaData metaData; 12 | 13 | public DeviceJobs() { 14 | } 15 | 16 | public DeviceJobs(List entities, MetaData metaData) { 17 | this.entities = entities; 18 | this.metaData = metaData; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/Entity.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | public class Entity { 4 | 5 | public Object assignedTunnelId; 6 | public String automationBackend; 7 | public String consolidatedStatus; 8 | public Long creationTime; 9 | public String deviceName; 10 | public String deviceType; 11 | public Long endTime; 12 | public String id; 13 | public Boolean manual; 14 | public String name; 15 | public String os; 16 | public String osVersion; 17 | public String ownerSauce; 18 | public Long startTime; 19 | public String status; 20 | public String testReportType; 21 | public Boolean hasCrashed; 22 | 23 | public Entity() { 24 | } 25 | 26 | public Entity(Object assignedTunnelId, String automationBackend, String consolidatedStatus, Long creationTime, String deviceName, String deviceType, Long endTime, String id, Boolean manual, String name, String os, String osVersion, String ownerSauce, Long startTime, String status, String testReportType, Boolean hasCrashed) { 27 | super(); 28 | this.assignedTunnelId = assignedTunnelId; 29 | this.automationBackend = automationBackend; 30 | this.consolidatedStatus = consolidatedStatus; 31 | this.creationTime = creationTime; 32 | this.deviceName = deviceName; 33 | this.deviceType = deviceType; 34 | this.endTime = endTime; 35 | this.id = id; 36 | this.manual = manual; 37 | this.name = name; 38 | this.os = os; 39 | this.osVersion = osVersion; 40 | this.ownerSauce = ownerSauce; 41 | this.startTime = startTime; 42 | this.status = status; 43 | this.testReportType = testReportType; 44 | this.hasCrashed = hasCrashed; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/MetaData.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | public class MetaData { 4 | 5 | public Integer limit; 6 | public Boolean moreAvailable; 7 | public Integer offset; 8 | public String sortDirection; 9 | 10 | public MetaData() { 11 | } 12 | 13 | public MetaData(Integer limit, Boolean moreAvailable, Integer offset, String sortDirection) { 14 | super(); 15 | this.limit = limit; 16 | this.moreAvailable = moreAvailable; 17 | this.offset = offset; 18 | this.sortDirection = sortDirection; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/realdevices/Organization.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.realdevices; 2 | 3 | public class Organization { 4 | 5 | public Integer current; 6 | public Integer maximum; 7 | 8 | /** 9 | * No args constructor for use in serialization 10 | */ 11 | public Organization() { 12 | } 13 | 14 | /** 15 | * @param current 16 | * @param maximum 17 | */ 18 | public Organization(Integer current, Integer maximum) { 19 | super(); 20 | this.current = current; 21 | this.maximum = maximum; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Downloads.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class Downloads { 6 | 7 | public Linux linux; 8 | @SerializedName("linux-arm64") 9 | public LinuxArm64 linuxArm64; 10 | public Osx osx; 11 | public Win32 win32; 12 | 13 | /** 14 | * No args constructor for use in serialization 15 | */ 16 | public Downloads() { 17 | } 18 | 19 | /** 20 | * @param linuxArm64 21 | * @param osx 22 | * @param win32 23 | * @param linux 24 | */ 25 | public Downloads(Linux linux, LinuxArm64 linuxArm64, Osx osx, Win32 win32) { 26 | super(); 27 | this.linux = linux; 28 | this.linuxArm64 = linuxArm64; 29 | this.osx = osx; 30 | this.win32 = win32; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Instance.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class Instance { 4 | 5 | public String instanceId; 6 | public String allocationPrefix; 7 | public String status; 8 | 9 | /** 10 | * No args constructor for use in serialization 11 | */ 12 | public Instance() { 13 | } 14 | 15 | /** 16 | * @param allocationPrefix 17 | * @param instanceId 18 | * @param status 19 | */ 20 | public Instance(String instanceId, String allocationPrefix, String status) { 21 | super(); 22 | this.instanceId = instanceId; 23 | this.allocationPrefix = allocationPrefix; 24 | this.status = status; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/JobsForATunnel.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class JobsForATunnel { 4 | 5 | public String id; 6 | public Integer jobsRunning; 7 | 8 | /** 9 | * No args constructor for use in serialization 10 | */ 11 | public JobsForATunnel() { 12 | } 13 | 14 | /** 15 | * @param jobsRunning 16 | * @param id 17 | */ 18 | public JobsForATunnel(String id, Integer jobsRunning) { 19 | super(); 20 | this.id = id; 21 | this.jobsRunning = jobsRunning; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Linux.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class Linux { 4 | 5 | public String downloadUrl; 6 | 7 | public String sha256; 8 | 9 | /** No args constructor for use in serialization */ 10 | public Linux() {} 11 | 12 | /** 13 | * @param sha256 14 | * @param downloadUrl 15 | */ 16 | public Linux(String downloadUrl, String sha256) { 17 | super(); 18 | this.downloadUrl = downloadUrl; 19 | this.sha256 = sha256; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/LinuxArm64.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class LinuxArm64 { 4 | 5 | public String downloadUrl; 6 | 7 | public String sha256; 8 | 9 | /** No args constructor for use in serialization */ 10 | public LinuxArm64() {} 11 | 12 | /** 13 | * @param sha256 14 | * @param downloadUrl 15 | */ 16 | public LinuxArm64(String downloadUrl, String sha256) { 17 | super(); 18 | this.downloadUrl = downloadUrl; 19 | this.sha256 = sha256; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Metadata.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | import java.math.BigInteger; 4 | 5 | public class Metadata { 6 | 7 | public String hostname; 8 | public Long hostMemory; 9 | public String commandArgs; 10 | public String gitVersion; 11 | public String platform; 12 | public String command; 13 | public String build; 14 | public String externalProxy; 15 | public String release; 16 | public String hostCpu; 17 | public BigInteger nofileLimit; 18 | 19 | /** 20 | * No args constructor for use in serialization 21 | */ 22 | public Metadata() { 23 | } 24 | 25 | /** 26 | * @param hostname 27 | * @param gitVersion 28 | * @param externalProxy 29 | * @param build 30 | * @param commandArgs 31 | * @param release 32 | * @param nofileLimit 33 | * @param hostMemory 34 | * @param hostCpu 35 | * @param platform 36 | * @param command 37 | */ 38 | public Metadata(String hostname, Long hostMemory, String commandArgs, String gitVersion, String platform, String command, String build, String externalProxy, String release, String hostCpu, BigInteger nofileLimit) { 39 | super(); 40 | this.hostname = hostname; 41 | this.hostMemory = hostMemory; 42 | this.commandArgs = commandArgs; 43 | this.gitVersion = gitVersion; 44 | this.platform = platform; 45 | this.command = command; 46 | this.build = build; 47 | this.externalProxy = externalProxy; 48 | this.release = release; 49 | this.hostCpu = hostCpu; 50 | this.nofileLimit = nofileLimit; 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Osx.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class Osx { 4 | 5 | public String downloadUrl; 6 | 7 | public String sha256; 8 | 9 | /** No args constructor for use in serialization */ 10 | public Osx() {} 11 | 12 | /** 13 | * @param sha256 14 | * @param downloadUrl 15 | */ 16 | public Osx(String downloadUrl, String sha256) { 17 | super(); 18 | this.downloadUrl = downloadUrl; 19 | this.sha256 = sha256; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/StopTunnel.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class StopTunnel { 4 | 5 | public Boolean result; 6 | public String id; 7 | public Integer jobsRunning; 8 | 9 | /** 10 | * No args constructor for use in serialization 11 | */ 12 | public StopTunnel() { 13 | } 14 | 15 | /** 16 | * @param result 17 | * @param jobsRunning 18 | * @param id 19 | */ 20 | public StopTunnel(Boolean result, String id, Integer jobsRunning) { 21 | super(); 22 | this.result = result; 23 | this.id = id; 24 | this.jobsRunning = jobsRunning; 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Tags.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class Tags { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/TunnelDefault.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | import com.saucelabs.saucerest.model.storage.Item; 4 | public class TunnelDefault { 5 | public Item item; 6 | 7 | public TunnelDefault() { 8 | } 9 | 10 | public TunnelDefault(Item item) { 11 | super(); 12 | this.item = item; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/TunnelInformation.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | import java.util.List; 4 | 5 | public class TunnelInformation { 6 | 7 | public String allocationType; 8 | public String backend; 9 | public Integer build; 10 | public Integer creationTime; 11 | public Object directDomains; 12 | public Object domainNames; 13 | public String extraInfo; 14 | public String host; 15 | public String id; 16 | public String instance; 17 | public List instances = null; 18 | public String internalAddress; 19 | public Object ipAddress; 20 | public Boolean isReady; 21 | public Integer lastConnected; 22 | public Integer launchTime; 23 | public Metadata metadata; 24 | public Boolean noProxyCaching; 25 | public Object noSslBumpDomains; 26 | public String orgId; 27 | public String owner; 28 | public Boolean sharedTunnel; 29 | public Object shutdownReason; 30 | public Object shutdownTime; 31 | public Integer sshPort; 32 | public String status; 33 | public Tags tags; 34 | public List teamIds = null; 35 | public String tunnelIdentifier; 36 | public Object useCachingProxy; 37 | public Boolean useKgp; 38 | public Object userShutdown; 39 | public Object vmVersion; 40 | 41 | /** 42 | * No args constructor for use in serialization 43 | */ 44 | public TunnelInformation() { 45 | } 46 | 47 | /** 48 | * @param metadata 49 | * @param instance 50 | * @param creationTime 51 | * @param instances 52 | * @param isReady 53 | * @param useCachingProxy 54 | * @param orgId 55 | * @param internalAddress 56 | * @param tunnelIdentifier 57 | * @param lastConnected 58 | * @param host 59 | * @param backend 60 | * @param domainNames 61 | * @param id 62 | * @param shutdownTime 63 | * @param directDomains 64 | * @param owner 65 | * @param sshPort 66 | * @param userShutdown 67 | * @param useKgp 68 | * @param ipAddress 69 | * @param sharedTunnel 70 | * @param allocationType 71 | * @param teamIds 72 | * @param noProxyCaching 73 | * @param tags 74 | * @param launchTime 75 | * @param build 76 | * @param shutdownReason 77 | * @param vmVersion 78 | * @param noSslBumpDomains 79 | * @param extraInfo 80 | * @param status 81 | */ 82 | public TunnelInformation(String allocationType, String backend, Integer build, Integer creationTime, Object directDomains, Object domainNames, String extraInfo, String host, String id, String instance, List instances, String internalAddress, Object ipAddress, Boolean isReady, Integer lastConnected, Integer launchTime, Metadata metadata, Boolean noProxyCaching, Object noSslBumpDomains, String orgId, String owner, Boolean sharedTunnel, Object shutdownReason, Object shutdownTime, Integer sshPort, String status, Tags tags, List teamIds, String tunnelIdentifier, Object useCachingProxy, Boolean useKgp, Object userShutdown, Object vmVersion) { 83 | super(); 84 | this.allocationType = allocationType; 85 | this.backend = backend; 86 | this.build = build; 87 | this.creationTime = creationTime; 88 | this.directDomains = directDomains; 89 | this.domainNames = domainNames; 90 | this.extraInfo = extraInfo; 91 | this.host = host; 92 | this.id = id; 93 | this.instance = instance; 94 | this.instances = instances; 95 | this.internalAddress = internalAddress; 96 | this.ipAddress = ipAddress; 97 | this.isReady = isReady; 98 | this.lastConnected = lastConnected; 99 | this.launchTime = launchTime; 100 | this.metadata = metadata; 101 | this.noProxyCaching = noProxyCaching; 102 | this.noSslBumpDomains = noSslBumpDomains; 103 | this.orgId = orgId; 104 | this.owner = owner; 105 | this.sharedTunnel = sharedTunnel; 106 | this.shutdownReason = shutdownReason; 107 | this.shutdownTime = shutdownTime; 108 | this.sshPort = sshPort; 109 | this.status = status; 110 | this.tags = tags; 111 | this.teamIds = teamIds; 112 | this.tunnelIdentifier = tunnelIdentifier; 113 | this.useCachingProxy = useCachingProxy; 114 | this.useKgp = useKgp; 115 | this.userShutdown = userShutdown; 116 | this.vmVersion = vmVersion; 117 | } 118 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Versions.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | import java.util.List; 4 | 5 | public class Versions { 6 | 7 | public Downloads downloads; 8 | public String infoUrl; 9 | public String latestVersion; 10 | public List warning = null; 11 | 12 | /** 13 | * No args constructor for use in serialization 14 | */ 15 | public Versions() { 16 | } 17 | 18 | /** 19 | * @param downloads 20 | * @param infoUrl 21 | * @param latestVersion 22 | * @param warning 23 | */ 24 | public Versions(Downloads downloads, String infoUrl, String latestVersion, List warning) { 25 | super(); 26 | this.downloads = downloads; 27 | this.infoUrl = infoUrl; 28 | this.latestVersion = latestVersion; 29 | this.warning = warning; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/sauceconnect/Win32.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.sauceconnect; 2 | 3 | public class Win32 { 4 | 5 | public String downloadUrl; 6 | 7 | public String sha256; 8 | 9 | /** No args constructor for use in serialization */ 10 | public Win32() {} 11 | 12 | /** 13 | * @param sha256 14 | * @param downloadUrl 15 | */ 16 | public Win32(String downloadUrl, String sha256) { 17 | super(); 18 | this.downloadUrl = downloadUrl; 19 | this.sha256 = sha256; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Access.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import java.util.List; 4 | 5 | public class Access { 6 | 7 | public List teamIds = null; 8 | public List orgIds = null; 9 | 10 | public Access() { 11 | } 12 | 13 | public Access(List teamIds, List orgIds) { 14 | super(); 15 | this.teamIds = teamIds; 16 | this.orgIds = orgIds; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/DeleteAppFile.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class DeleteAppFile { 4 | 5 | public Item item; 6 | 7 | public DeleteAppFile() { 8 | } 9 | 10 | public DeleteAppFile(Item item) { 11 | super(); 12 | this.item = item; 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/DeleteAppGroupFiles.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class DeleteAppGroupFiles { 4 | 5 | public ItemInteger item; 6 | 7 | public DeleteAppGroupFiles() { 8 | } 9 | 10 | public DeleteAppGroupFiles(ItemInteger item) { 11 | super(); 12 | this.item = item; 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/EditAppGroupSettings.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import com.saucelabs.saucerest.ErrorExplainers; 4 | import com.saucelabs.saucerest.SauceException; 5 | import java.util.stream.Stream; 6 | 7 | public class EditAppGroupSettings { 8 | 9 | public Settings settings; 10 | public String kind; 11 | public String identifier; 12 | 13 | private EditAppGroupSettings(Builder builder) { 14 | settings = builder.settings; 15 | } 16 | 17 | public static final class Builder { 18 | private final Platform platform; 19 | private Settings settings; 20 | 21 | public Builder(Platform platform) { 22 | this.platform = platform; 23 | } 24 | 25 | public Builder setSettings(Settings val) { 26 | settings = val; 27 | return this; 28 | } 29 | 30 | public EditAppGroupSettings build() { 31 | if (platform.equals(Platform.IOS)) { 32 | if (settings.instrumentationEnabled != null || settings.instrumentation != null) { 33 | throw new SauceException.InstrumentationNotAllowed(ErrorExplainers.InstrumentationNotAllowed()); 34 | } 35 | 36 | if (settings.setupDeviceLock != null) { 37 | throw new SauceException.DeviceLockOnlyOnAndroid(ErrorExplainers.DeviceLockOnlyOnAndroid()); 38 | } 39 | } 40 | 41 | if (platform.equals(Platform.ANDROID)) { 42 | if (settings.resigningEnabled != null || settings.resigning != null) { 43 | throw new SauceException.ResigningNotAllowed(ErrorExplainers.ResigningNotAllowed()); 44 | } 45 | } 46 | 47 | return new EditAppGroupSettings(this); 48 | } 49 | 50 | public enum Platform { 51 | IOS, ANDROID, OTHER; 52 | 53 | public static Platform fromString(String platform) { 54 | return Stream.of(values()).filter(p -> p.name().equalsIgnoreCase(platform)).findFirst().orElse(OTHER); 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/EditFileDescription.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class EditFileDescription { 4 | 5 | public Item item; 6 | public Boolean changed; 7 | 8 | public EditFileDescription() { 9 | } 10 | 11 | public EditFileDescription(Item item, Boolean changed) { 12 | super(); 13 | this.item = item; 14 | this.changed = changed; 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/GetAppFiles.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import java.util.List; 4 | 5 | public class GetAppFiles { 6 | 7 | public List items = null; 8 | public Links links; 9 | public Integer page; 10 | public Integer perPage; 11 | public Integer totalItems; 12 | 13 | public GetAppFiles() { 14 | } 15 | 16 | public GetAppFiles(List items, Links links, Integer page, Integer perPage, Integer totalItems) { 17 | super(); 18 | this.items = items; 19 | this.links = links; 20 | this.page = page; 21 | this.perPage = perPage; 22 | this.totalItems = totalItems; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/GetAppStorageGroupSettings.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class GetAppStorageGroupSettings { 4 | 5 | public Settings settings; 6 | public String kind; 7 | public String identifier; 8 | 9 | private GetAppStorageGroupSettings(Builder builder) { 10 | settings = builder.settings; 11 | kind = builder.kind; 12 | identifier = builder.identifier; 13 | } 14 | 15 | public static final class Builder { 16 | private Settings settings; 17 | private String kind; 18 | private String identifier; 19 | 20 | public Builder setSettings(Settings val) { 21 | settings = val; 22 | return this; 23 | } 24 | 25 | public Builder setKind(String val) { 26 | kind = val; 27 | return this; 28 | } 29 | 30 | public Builder setIdentifier(String val) { 31 | identifier = val; 32 | return this; 33 | } 34 | 35 | public GetAppStorageGroupSettings build() { 36 | return new GetAppStorageGroupSettings(this); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/GetAppStorageGroups.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import java.util.List; 4 | 5 | public class GetAppStorageGroups { 6 | 7 | public List items; 8 | public Links links; 9 | public Integer page; 10 | public Integer perPage; 11 | public Integer totalItems; 12 | public Boolean isSimulator; 13 | 14 | public GetAppStorageGroups() { 15 | } 16 | 17 | public GetAppStorageGroups(List items, Links links, Integer page, Integer perPage, Integer totalItems, boolean isSimulator) { 18 | super(); 19 | this.items = items; 20 | this.links = links; 21 | this.page = page; 22 | this.perPage = perPage; 23 | this.totalItems = totalItems; 24 | this.isSimulator = isSimulator; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/GetAppStorageGroupsParameters.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class GetAppStorageGroupsParameters { 7 | private final String q; 8 | private final String kind; 9 | private final String[] groupIds; 10 | private final int page; 11 | private String perPage; 12 | 13 | private GetAppStorageGroupsParameters(Builder builder) { 14 | q = builder.q; 15 | kind = builder.kind; 16 | groupIds = builder.groupIds; 17 | page = builder.page; 18 | } 19 | 20 | public Map toMap() { 21 | Map parameters = new HashMap<>(); 22 | 23 | if (this.q != null) { 24 | parameters.put("q", this.q); 25 | } 26 | 27 | if (this.kind != null) { 28 | parameters.put("kind", this.kind); 29 | } 30 | 31 | // Default is returning results on page 1. Set to 1 in build() 32 | if (this.page != 0 && this.page != 1) { 33 | parameters.put("page", this.page); 34 | } 35 | 36 | if (this.perPage != null) { 37 | parameters.put("per_page", this.perPage); 38 | } 39 | 40 | if (this.groupIds != null) { 41 | parameters.put("group_id", this.groupIds); 42 | } 43 | 44 | return parameters; 45 | } 46 | 47 | public static final class Builder { 48 | private String q; 49 | private String kind; 50 | private String[] groupIds; 51 | private int page; 52 | 53 | public Builder setQ(String val) { 54 | q = val; 55 | return this; 56 | } 57 | 58 | public Builder setKind(String val) { 59 | kind = val; 60 | return this; 61 | } 62 | 63 | public Builder setGroupIds(String[] val) { 64 | groupIds = val; 65 | return this; 66 | } 67 | 68 | public Builder setPage(int val) { 69 | page = val; 70 | return this; 71 | } 72 | 73 | public GetAppStorageGroupsParameters build() { 74 | return new GetAppStorageGroupsParameters(this); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Instrumentation.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Instrumentation { 4 | 5 | public Boolean imageInjection; 6 | public Boolean bypassScreenshotRestriction; 7 | public Boolean biometrics; 8 | public Boolean networkCapture; 9 | 10 | private Instrumentation(Builder builder) { 11 | imageInjection = builder.imageInjection; 12 | bypassScreenshotRestriction = builder.bypassScreenshotRestriction; 13 | biometrics = builder.biometrics; 14 | networkCapture = builder.networkCapture; 15 | } 16 | 17 | public static final class Builder { 18 | private Boolean imageInjection; 19 | private Boolean bypassScreenshotRestriction; 20 | private Boolean biometrics; 21 | private Boolean networkCapture; 22 | 23 | public Builder setImageInjection(Boolean val) { 24 | imageInjection = val; 25 | return this; 26 | } 27 | 28 | public Builder setBypassScreenshotRestriction(Boolean val) { 29 | bypassScreenshotRestriction = val; 30 | return this; 31 | } 32 | 33 | public Builder setBiometrics(Boolean val) { 34 | biometrics = val; 35 | return this; 36 | } 37 | 38 | public Builder setNetworkCapture(Boolean val) { 39 | networkCapture = val; 40 | return this; 41 | } 42 | 43 | public Instrumentation build() { 44 | return new Instrumentation(this); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Item.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Item { 4 | 5 | public String id; 6 | public Owner owner; 7 | public String name; 8 | public Integer uploadTimestamp; 9 | public String etag; 10 | public String kind; 11 | public Integer groupId; 12 | public Integer size; 13 | public String description; 14 | public Metadata metadata; 15 | public Access access; 16 | public String sha256; 17 | public String[] tags; 18 | 19 | public Item() { 20 | } 21 | 22 | public Item(String id, Owner owner, String name, Integer uploadTimestamp, String etag, String kind, Integer groupId, Integer size, String description, Metadata metadata, Access access, String sha256, String[] tags) { 23 | super(); 24 | this.id = id; 25 | this.owner = owner; 26 | this.name = name; 27 | this.uploadTimestamp = uploadTimestamp; 28 | this.etag = etag; 29 | this.kind = kind; 30 | this.groupId = groupId; 31 | this.size = size; 32 | this.description = description; 33 | this.metadata = metadata; 34 | this.access = access; 35 | this.sha256 = sha256; 36 | this.tags = tags; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/ItemInteger.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | /** 4 | * 2 endpoints return ID as an Int instead of String. 5 | */ 6 | public class ItemInteger { 7 | 8 | public Integer id; 9 | public String name; 10 | public Recent recent; 11 | public Integer count; 12 | public Access access; 13 | public Settings settings; 14 | public String projectPath; 15 | 16 | public ItemInteger() { 17 | } 18 | 19 | public ItemInteger(Integer id, String name, Recent recent, Integer count, Access access, Settings settings, String projectPath) { 20 | super(); 21 | this.id = id; 22 | this.name = name; 23 | this.recent = recent; 24 | this.count = count; 25 | this.access = access; 26 | this.settings = settings; 27 | this.projectPath = projectPath; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Links.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Links { 4 | 5 | public String prev; 6 | public String next; 7 | public String self; 8 | 9 | public Links() { 10 | } 11 | 12 | public Links(String prev, String next, String self) { 13 | super(); 14 | this.prev = prev; 15 | this.next = next; 16 | this.self = self; 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Metadata.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import java.util.List; 4 | 5 | public class Metadata { 6 | 7 | public String identifier; 8 | public String name; 9 | public String version; 10 | public Boolean isTestRunner; 11 | public String icon; 12 | public String shortVersion; 13 | public Boolean isSimulator; 14 | public String minOs; 15 | public String targetOs; 16 | public Object testRunnerPluginPath; 17 | public List deviceFamily = null; 18 | public Integer versionCode; 19 | public Integer minSdk; 20 | public Integer targetSdk; 21 | public Object testRunnerClass; 22 | public String iconHash; 23 | 24 | public Metadata() { 25 | } 26 | 27 | public Metadata(String identifier, String name, String version, Boolean isTestRunner, String icon, String shortVersion, Boolean isSimulator, String minOs, String targetOs, Object testRunnerPluginPath, List deviceFamily, Integer versionCode, Integer minSdk, Integer targetSdk, Object testRunnerClass, String iconHash) { 28 | super(); 29 | this.identifier = identifier; 30 | this.name = name; 31 | this.version = version; 32 | this.isTestRunner = isTestRunner; 33 | this.icon = icon; 34 | this.shortVersion = shortVersion; 35 | this.isSimulator = isSimulator; 36 | this.minOs = minOs; 37 | this.targetOs = targetOs; 38 | this.testRunnerPluginPath = testRunnerPluginPath; 39 | this.deviceFamily = deviceFamily; 40 | this.versionCode = versionCode; 41 | this.minSdk = minSdk; 42 | this.targetSdk = targetSdk; 43 | this.testRunnerClass = testRunnerClass; 44 | this.iconHash = iconHash; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Owner.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Owner { 4 | 5 | public String id; 6 | public String orgId; 7 | 8 | public Owner() { 9 | } 10 | 11 | public Owner(String id, String orgId) { 12 | super(); 13 | this.id = id; 14 | this.orgId = orgId; 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Proxy.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Proxy { 4 | 5 | public String host; 6 | public Integer port; 7 | 8 | private Proxy(Builder builder) { 9 | host = builder.host; 10 | port = builder.port; 11 | } 12 | 13 | public static final class Builder { 14 | private String host; 15 | private Integer port; 16 | 17 | public Builder setHost(String val) { 18 | host = val; 19 | return this; 20 | } 21 | 22 | public Builder setPort(Integer val) { 23 | port = val; 24 | return this; 25 | } 26 | 27 | public Proxy build() { 28 | return new Proxy(this); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Recent.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Recent { 4 | 5 | public String id; 6 | public Owner owner; 7 | public String name; 8 | public Integer uploadTimestamp; 9 | public String etag; 10 | public String kind; 11 | public Integer groupId; 12 | public Integer size; 13 | public String description; 14 | public Metadata metadata; 15 | public Access access; 16 | public String sha256; 17 | public String[] tags; 18 | 19 | public Recent() { 20 | } 21 | 22 | public Recent(String id, Owner owner, String name, Integer uploadTimestamp, String etag, String kind, Integer groupId, Integer size, String description, Metadata metadata, Access access, String sha256, String[] tags) { 23 | super(); 24 | this.id = id; 25 | this.owner = owner; 26 | this.name = name; 27 | this.uploadTimestamp = uploadTimestamp; 28 | this.etag = etag; 29 | this.kind = kind; 30 | this.groupId = groupId; 31 | this.size = size; 32 | this.description = description; 33 | this.metadata = metadata; 34 | this.access = access; 35 | this.sha256 = sha256; 36 | this.tags = tags; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Resigning.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Resigning { 4 | 5 | public Boolean imageInjection; 6 | public Boolean groupDirectory; 7 | public Boolean biometrics; 8 | public Boolean sysAlertsDelay; 9 | public Boolean networkCapture; 10 | 11 | private Resigning(Builder builder) { 12 | imageInjection = builder.imageInjection; 13 | groupDirectory = builder.groupDirectory; 14 | biometrics = builder.biometrics; 15 | sysAlertsDelay = builder.sysAlertsDelay; 16 | networkCapture = builder.networkCapture; 17 | } 18 | 19 | public static final class Builder { 20 | private Boolean imageInjection; 21 | private Boolean groupDirectory; 22 | private Boolean biometrics; 23 | private Boolean sysAlertsDelay; 24 | private Boolean networkCapture; 25 | 26 | public Builder setImageInjection(Boolean val) { 27 | imageInjection = val; 28 | return this; 29 | } 30 | 31 | public Builder setGroupDirectory(Boolean val) { 32 | groupDirectory = val; 33 | return this; 34 | } 35 | 36 | public Builder setBiometrics(Boolean val) { 37 | biometrics = val; 38 | return this; 39 | } 40 | 41 | public Builder setSysAlertsDelay(Boolean val) { 42 | sysAlertsDelay = val; 43 | return this; 44 | } 45 | 46 | public Builder setNetworkCapture(Boolean val) { 47 | networkCapture = val; 48 | return this; 49 | } 50 | 51 | public Resigning build() { 52 | return new Resigning(this); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/Settings.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class Settings { 4 | 5 | public Proxy proxy; 6 | public Boolean audioCapture; 7 | public Boolean proxyEnabled; 8 | public String lang; 9 | public String orientation; 10 | public Boolean resigningEnabled; 11 | public Resigning resigning; 12 | public Instrumentation instrumentation; 13 | public Boolean setupDeviceLock; 14 | public Boolean instrumentationEnabled; 15 | 16 | private Settings(Builder builder) { 17 | proxy = builder.proxy; 18 | audioCapture = builder.audioCapture; 19 | proxyEnabled = builder.proxyEnabled; 20 | lang = builder.lang; 21 | orientation = builder.orientation; 22 | resigningEnabled = builder.resigningEnabled; 23 | resigning = builder.resigning; 24 | instrumentation = builder.instrumentation; 25 | setupDeviceLock = builder.setupDeviceLock; 26 | instrumentationEnabled = builder.instrumentationEnabled; 27 | } 28 | 29 | public static final class Builder { 30 | private Proxy proxy; 31 | private Boolean audioCapture; 32 | private Boolean proxyEnabled; 33 | private String lang; 34 | private String orientation; 35 | private Boolean resigningEnabled; 36 | private Resigning resigning; 37 | private Instrumentation instrumentation; 38 | private Boolean setupDeviceLock; 39 | private Boolean instrumentationEnabled; 40 | 41 | public Builder setProxy(Proxy val) { 42 | proxy = val; 43 | return this; 44 | } 45 | 46 | public Builder setAudioCapture(Boolean val) { 47 | audioCapture = val; 48 | return this; 49 | } 50 | 51 | public Builder setProxyEnabled(Boolean val) { 52 | proxyEnabled = val; 53 | return this; 54 | } 55 | 56 | public Builder setLang(String val) { 57 | lang = val; 58 | return this; 59 | } 60 | 61 | public Builder setOrientation(String val) { 62 | orientation = val; 63 | return this; 64 | } 65 | 66 | public Builder setResigningEnabled(Boolean val) { 67 | resigningEnabled = val; 68 | return this; 69 | } 70 | 71 | public Builder setResigning(Resigning val) { 72 | resigning = val; 73 | return this; 74 | } 75 | 76 | public Builder setInstrumentation(Instrumentation val) { 77 | instrumentation = val; 78 | return this; 79 | } 80 | 81 | public Builder setSetupDeviceLock(Boolean val) { 82 | setupDeviceLock = val; 83 | return this; 84 | } 85 | 86 | public Builder setInstrumentationEnabled(Boolean val) { 87 | instrumentationEnabled = val; 88 | return this; 89 | } 90 | 91 | public Settings build() { 92 | if (proxy != null) { 93 | proxyEnabled = true; 94 | } 95 | 96 | if (instrumentation != null) { 97 | instrumentationEnabled = true; 98 | } 99 | 100 | if (resigning != null) { 101 | resigningEnabled = true; 102 | } 103 | 104 | return new Settings(this); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/StorageParameter.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class StorageParameter { 7 | private final String q; 8 | private final String name; 9 | private final String[] kind; 10 | private final String[] fileId; 11 | private final String sha256; 12 | private final String[] teamId; 13 | private final String[] orgId; 14 | private final int page; 15 | private final String perPage; 16 | private final String[] groupIds; 17 | 18 | private StorageParameter(Builder builder) { 19 | q = builder.q; 20 | name = builder.name; 21 | kind = builder.kind; 22 | fileId = builder.fileId; 23 | sha256 = builder.sha256; 24 | teamId = builder.teamId; 25 | orgId = builder.orgId; 26 | page = builder.page; 27 | perPage = builder.perPage; 28 | groupIds = builder.groupIds; 29 | } 30 | 31 | /** 32 | * @return A map to be used as parameter when using an endpoint that takes query parameters. 33 | */ 34 | public Map toMap() { 35 | Map parameters = new HashMap<>(); 36 | 37 | if (this.q != null) { 38 | parameters.put("q", this.q); 39 | } 40 | 41 | if (this.name != null) { 42 | parameters.put("name", this.name); 43 | } 44 | 45 | if (this.kind != null) { 46 | parameters.put("kind", this.kind); 47 | } 48 | 49 | if (this.fileId != null) { 50 | parameters.put("file_id", this.fileId); 51 | } 52 | 53 | if (this.sha256 != null) { 54 | parameters.put("sha256", this.sha256); 55 | } 56 | 57 | if (this.teamId != null) { 58 | parameters.put("team_id", this.teamId); 59 | } 60 | 61 | if (this.orgId != null) { 62 | parameters.put("org_id", this.orgId); 63 | } 64 | 65 | // Default is returning results on page 1. Set to 1 in build() 66 | if (this.page != 0 && this.page != 1) { 67 | parameters.put("page", this.page); 68 | } 69 | 70 | if (this.perPage != null) { 71 | parameters.put("per_page", this.perPage); 72 | } 73 | 74 | if (this.groupIds != null) { 75 | parameters.put("group_id", this.groupIds); 76 | } 77 | 78 | return parameters; 79 | } 80 | 81 | public static final class Builder { 82 | private String q; 83 | private String name; 84 | private String[] kind; 85 | private String[] fileId; 86 | private String sha256; 87 | private String[] teamId; 88 | private String[] orgId; 89 | private int page; 90 | private String perPage; 91 | private String[] groupIds; 92 | 93 | public Builder setQ(String val) { 94 | q = val; 95 | return this; 96 | } 97 | 98 | public Builder setName(String val) { 99 | name = val; 100 | return this; 101 | } 102 | 103 | public Builder setKind(String[] val) { 104 | kind = val; 105 | return this; 106 | } 107 | 108 | public Builder setFileId(String[] val) { 109 | fileId = val; 110 | return this; 111 | } 112 | 113 | public Builder setSha256(String val) { 114 | sha256 = val; 115 | return this; 116 | } 117 | 118 | public Builder setTeamId(String[] val) { 119 | teamId = val; 120 | return this; 121 | } 122 | 123 | public Builder setOrgId(String[] val) { 124 | orgId = val; 125 | return this; 126 | } 127 | 128 | public Builder setPage(int val) { 129 | page = val; 130 | return this; 131 | } 132 | 133 | public Builder setPerPage(String val) { 134 | perPage = val; 135 | return this; 136 | } 137 | 138 | public Builder setGroupIds(String[] val) { 139 | groupIds = val; 140 | return this; 141 | } 142 | 143 | public StorageParameter build() { 144 | if (page == 0) { 145 | page = 1; 146 | } 147 | 148 | return new StorageParameter(this); 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /src/main/java/com/saucelabs/saucerest/model/storage/UploadFileApp.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.model.storage; 2 | 3 | public class UploadFileApp { 4 | 5 | public Item item; 6 | 7 | public UploadFileApp() { 8 | } 9 | 10 | public UploadFileApp(Item item) { 11 | super(); 12 | this.item = item; 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/.properties: -------------------------------------------------------------------------------- 1 | saucerest.version=${project.version} -------------------------------------------------------------------------------- /src/main/resources/com/saucelabs/saucerest/BuildUtils.template: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | public class BuildUtils 4 | { 5 | // ------------------------------------------------------------------------------------------------------- Constants 6 | 7 | private static final String version = "@VERSION@"; 8 | 9 | // -------------------------------------------------------------------------------------------------- Public Methods 10 | public static String getCurrentVersion() 11 | { 12 | return version; 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/Helper.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.util.Objects; 8 | import java.util.stream.Collectors; 9 | 10 | public class Helper { 11 | /** 12 | * Reads given resource file as a string. 13 | * 14 | * @param fileName path to the resource file 15 | * @return the file's contents 16 | * @throws IOException if read fails for any reason 17 | * @see https://stackoverflow.com/a/46613809 18 | */ 19 | public static String getResourceFileAsString(String fileName) throws IOException { 20 | if (fileName == null || fileName.isEmpty()) { 21 | throw new IllegalArgumentException("File name cannot be null or empty."); 22 | } 23 | 24 | try (InputStream is = Objects.requireNonNull(Helper.class.getResource(fileName), "File not found: " + fileName).openStream()) { 25 | 26 | try (InputStreamReader isr = new InputStreamReader(is); 27 | BufferedReader reader = new BufferedReader(isr)) { 28 | return reader.lines().collect(Collectors.joining(System.lineSeparator())); 29 | } 30 | } catch (IOException e) { 31 | String errorMessage = String.format("Error reading file %s: %s", fileName, e.getMessage()); 32 | throw new IOException(errorMessage, e); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/integration/BuildsEndpointTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.integration; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertFalse; 5 | import static org.junit.jupiter.api.Assertions.assertNotNull; 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | import com.saucelabs.saucerest.DataCenter; 9 | import com.saucelabs.saucerest.JobSource; 10 | import com.saucelabs.saucerest.SauceREST; 11 | import com.saucelabs.saucerest.api.BuildsEndpoint; 12 | import com.saucelabs.saucerest.model.builds.Build; 13 | import com.saucelabs.saucerest.model.builds.JobsInBuild; 14 | import com.saucelabs.saucerest.model.builds.LookupBuildsParameters; 15 | import com.saucelabs.saucerest.model.builds.LookupJobsParameters; 16 | import com.saucelabs.saucerest.model.builds.Status; 17 | 18 | import java.io.IOException; 19 | import java.util.List; 20 | import org.junit.jupiter.params.ParameterizedTest; 21 | import org.junit.jupiter.params.provider.EnumSource; 22 | 23 | public class BuildsEndpointTest { 24 | @ParameterizedTest 25 | @EnumSource(DataCenter.class) 26 | public void lookupBuildsTest(DataCenter dataCenter) throws IOException { 27 | SauceREST sauceREST = new SauceREST(dataCenter); 28 | BuildsEndpoint buildsEndpoint = sauceREST.getBuildsEndpoint(); 29 | 30 | List builds = buildsEndpoint.lookupBuilds(JobSource.VDC); 31 | 32 | assertFalse(builds.isEmpty()); 33 | } 34 | 35 | @ParameterizedTest 36 | @EnumSource(DataCenter.class) 37 | public void lookupBuildsTestWithParameter(DataCenter dataCenter) throws IOException { 38 | SauceREST sauceREST = new SauceREST(dataCenter); 39 | BuildsEndpoint buildsEndpoint = sauceREST.getBuildsEndpoint(); 40 | 41 | LookupBuildsParameters parameters = 42 | new LookupBuildsParameters.Builder() 43 | .setLimit(1) 44 | .setStatus(new Status[] {Status.complete, Status.success}) 45 | .build(); 46 | 47 | List builds = buildsEndpoint.lookupBuilds(JobSource.VDC, parameters); 48 | 49 | assertEquals(1, builds.size()); 50 | assertEquals(JobSource.VDC.value, builds.get(0).source); 51 | assertTrue( 52 | builds.get(0).status.equalsIgnoreCase(Status.complete.value) 53 | || builds.get(0).status.equalsIgnoreCase(Status.success.value)); 54 | } 55 | 56 | @ParameterizedTest 57 | @EnumSource(DataCenter.class) 58 | public void getSpecificBuildTest(DataCenter dataCenter) throws IOException { 59 | SauceREST sauceREST = new SauceREST(dataCenter); 60 | BuildsEndpoint buildsEndpoint = sauceREST.getBuildsEndpoint(); 61 | 62 | LookupBuildsParameters parameters = new LookupBuildsParameters.Builder().setLimit(1).build(); 63 | 64 | List builds = buildsEndpoint.lookupBuilds(JobSource.VDC, parameters); 65 | 66 | assertFalse(builds.isEmpty()); 67 | 68 | Build build = buildsEndpoint.getSpecificBuild(JobSource.VDC, builds.get(0).id); 69 | 70 | assertEquals(builds.get(0).id, build.id); 71 | } 72 | 73 | @ParameterizedTest 74 | @EnumSource(DataCenter.class) 75 | public void lookupJobsForBuild(DataCenter dataCenter) throws IOException { 76 | SauceREST sauceREST = new SauceREST(dataCenter); 77 | BuildsEndpoint endpoint = sauceREST.getBuildsEndpoint(); 78 | 79 | LookupBuildsParameters parameters = new LookupBuildsParameters.Builder().setLimit(1).build(); 80 | List builds = endpoint.lookupBuilds(JobSource.VDC, parameters); 81 | assertFalse(builds.isEmpty()); 82 | 83 | Build build = endpoint.getSpecificBuild(JobSource.VDC, builds.get(0).id); 84 | 85 | LookupJobsParameters jobsParameters = new LookupJobsParameters.Builder().build(); 86 | JobsInBuild jobsInBuild = endpoint.lookupJobsForBuild(JobSource.VDC, build.id, jobsParameters); 87 | assertFalse(jobsInBuild.jobs.isEmpty()); 88 | assertNotNull(jobsInBuild.jobs.get(0).id); 89 | assertNotNull(jobsInBuild.jobs.get(0).state); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/integration/InsightsEndpointTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.integration; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import com.saucelabs.saucerest.DataCenter; 6 | import com.saucelabs.saucerest.SauceREST; 7 | import com.saucelabs.saucerest.api.InsightsEndpoint; 8 | import com.saucelabs.saucerest.model.insights.TestResult; 9 | import com.saucelabs.saucerest.model.insights.TestResultParameter; 10 | import java.io.IOException; 11 | import java.time.LocalDateTime; 12 | import org.junit.jupiter.params.ParameterizedTest; 13 | import org.junit.jupiter.params.provider.EnumSource; 14 | 15 | public class InsightsEndpointTest { 16 | @ParameterizedTest 17 | @EnumSource(DataCenter.class) 18 | public void getTestResultTest(DataCenter dataCenter) throws IOException { 19 | SauceREST sauceREST = new SauceREST(dataCenter); 20 | InsightsEndpoint insightsEndpoint = sauceREST.getInsightsEndpoint(); 21 | 22 | int startYear = LocalDateTime.now().getYear(); 23 | int startMonth = LocalDateTime.now().getMonthValue(); 24 | 25 | TestResultParameter parameter = new TestResultParameter.Builder() 26 | .setStart(LocalDateTime.of(startYear, startMonth, 1, 0, 0, 0)) 27 | .setEnd(LocalDateTime.now()) 28 | .build(); 29 | TestResult testResult = insightsEndpoint.getTestResults(parameter); 30 | 31 | assertTrue(testResult.items.size() > 0); 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/integration/PlatformEndpointTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.integration; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import com.saucelabs.saucerest.DataCenter; 6 | import com.saucelabs.saucerest.SauceREST; 7 | import com.saucelabs.saucerest.api.PlatformEndpoint; 8 | import com.saucelabs.saucerest.model.platform.EndOfLifeAppiumVersions; 9 | import com.saucelabs.saucerest.model.platform.SupportedPlatforms; 10 | import com.saucelabs.saucerest.model.platform.TestStatus; 11 | import java.io.IOException; 12 | import org.junit.jupiter.api.Assertions; 13 | import org.junit.jupiter.params.ParameterizedTest; 14 | import org.junit.jupiter.params.provider.EnumSource; 15 | 16 | public class PlatformEndpointTest { 17 | private final ThreadLocal platform = new ThreadLocal<>(); 18 | 19 | public void setup(DataCenter dataCenter) { 20 | platform.set(new SauceREST(dataCenter).getPlatformEndpoint()); 21 | } 22 | 23 | @ParameterizedTest 24 | @EnumSource(DataCenter.class) 25 | public void getTestStatus(DataCenter dataCenter) throws IOException { 26 | setup(dataCenter); 27 | 28 | TestStatus testStatus = platform.get().getTestStatus(); 29 | 30 | assertNotNull(testStatus); 31 | assertNotNull(testStatus.statusMessage); 32 | } 33 | 34 | @ParameterizedTest 35 | @EnumSource(DataCenter.class) 36 | public void getAllSupportedPlatforms(DataCenter dataCenter) throws IOException { 37 | setup(dataCenter); 38 | 39 | SupportedPlatforms supportedPlatforms = platform.get().getSupportedPlatforms("all"); 40 | 41 | assertNotNull(supportedPlatforms); 42 | supportedPlatforms.getPlatforms().forEach(platform -> assertTrue((platform.automationBackend.equals("appium")) || (platform.automationBackend.equals("webdriver")))); 43 | } 44 | 45 | @ParameterizedTest 46 | @EnumSource(DataCenter.class) 47 | public void getAppiumSupportedPlatforms(DataCenter dataCenter) throws IOException { 48 | setup(dataCenter); 49 | 50 | SupportedPlatforms supportedPlatforms = platform.get().getSupportedPlatforms("appium"); 51 | 52 | assertNotNull(supportedPlatforms); 53 | supportedPlatforms.getPlatforms().forEach(platform -> Assertions.assertEquals("appium", platform.automationBackend)); 54 | } 55 | 56 | @ParameterizedTest 57 | @EnumSource(DataCenter.class) 58 | public void getWebdriverSupportedPlatforms(DataCenter dataCenter) throws IOException { 59 | setup(dataCenter); 60 | 61 | SupportedPlatforms supportedPlatforms = platform.get().getSupportedPlatforms("webdriver"); 62 | 63 | assertNotNull(supportedPlatforms); 64 | supportedPlatforms.getPlatforms().forEach(platform -> Assertions.assertEquals("webdriver", platform.automationBackend)); 65 | } 66 | 67 | @ParameterizedTest 68 | @EnumSource(DataCenter.class) 69 | public void getEndOfLifeAppiumVersions(DataCenter dataCenter) throws IOException { 70 | setup(dataCenter); 71 | 72 | EndOfLifeAppiumVersions endOfLifeAppiumVersions = platform.get().getEndOfLifeAppiumVersions(); 73 | 74 | assertNotEquals(0, endOfLifeAppiumVersions.getAppiumVersionList().size()); 75 | } 76 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/integration/StorageTestHelper.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.integration; 2 | 3 | import java.io.File; 4 | import java.util.Objects; 5 | 6 | public class StorageTestHelper { 7 | public File getAppFile(AppFile appFile) { 8 | return new File(Objects.requireNonNull(getClass().getResource("/AppFiles/" + appFile.fileName)).getFile()); 9 | } 10 | 11 | enum AppFile { 12 | IPA("iOS-Real-Device-MyRNDemoApp.ipa"), 13 | ZIP("iOS-Simulator-MyRNDemoApp.zip"), 14 | APK("Android-MyDemoAppRN.apk"), 15 | IPA_NATIVE("iOS-Real-Device-MyNativeDemoApp.ipa"), 16 | APK_NATIVE("Android-MyDemoAppNative.apk"); 17 | 18 | public final String fileName; 19 | 20 | AppFile(String fileName) { 21 | this.fileName = fileName; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/integration/TeamDeletionHelper.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.integration; 2 | 3 | import com.saucelabs.saucerest.api.AccountsEndpoint; 4 | import com.saucelabs.saucerest.model.accounts.Result; 5 | import java.io.IOException; 6 | import java.util.List; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | import okhttp3.Response; 10 | 11 | public class TeamDeletionHelper { 12 | private static final Logger logger = Logger.getLogger(TeamDeletionHelper.class.getName()); 13 | 14 | public static void deleteTeamsWithPrefix(List teams, AccountsEndpoint accountsEndpoint) throws IOException { 15 | for (Result team : teams) { 16 | if (team.name.startsWith("000")) { 17 | deleteTeam(team, accountsEndpoint); 18 | } 19 | } 20 | } 21 | 22 | private static void deleteTeam(Result team, AccountsEndpoint accountsEndpoint) throws IOException { 23 | try (Response response = accountsEndpoint.deleteTeam(team.id)) { 24 | String responseCode = String.valueOf(response.code()); 25 | 26 | if (responseCode.startsWith("2")) { 27 | logger.log(Level.INFO, "Deleted team " + team.name); 28 | } else { 29 | logger.log(Level.WARNING, "Failed to delete team " + team.name + " with response code " + responseCode); 30 | } 31 | } catch (IOException e) { 32 | logger.log(Level.SEVERE, "Failed to delete team " + team.name, e); 33 | throw e; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/AutomationBackendTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertAll; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import com.saucelabs.saucerest.AutomationBackend; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class AutomationBackendTest { 10 | @Test 11 | public void testLabel() { 12 | assertAll("AutomationBackend label", 13 | () -> assertEquals("appium", AutomationBackend.APPIUM.label), 14 | () -> assertEquals("webdriver", AutomationBackend.WEBDRIVER.label) 15 | ); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/DataCenterTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import com.saucelabs.saucerest.DataCenter; 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.params.ParameterizedTest; 8 | import org.junit.jupiter.params.provider.CsvSource; 9 | import org.junit.jupiter.params.provider.EnumSource; 10 | 11 | class DataCenterTest { 12 | @ParameterizedTest 13 | @CsvSource({ 14 | "US_WEST, US_WEST", 15 | "us_WeSt, US_WEST", 16 | "EU_CENTRAL, EU_CENTRAL", 17 | "Eu_central, EU_CENTRAL", 18 | }) 19 | void testFromString(String input, DataCenter expected) { 20 | assertEquals(expected, DataCenter.fromString(input)); 21 | } 22 | 23 | @Test 24 | void testInvalidString() { 25 | assertNull(DataCenter.fromString("unknown")); 26 | } 27 | 28 | @ParameterizedTest 29 | @EnumSource(DataCenter.class) 30 | void testEdsServer(DataCenter datacenter) { 31 | assertTrue(datacenter.edsServer().endsWith("saucelabs.com/v1/eds/")); 32 | } 33 | 34 | @Test 35 | void testFromStringNullAndEmpty() { 36 | assertNull(DataCenter.fromString(null)); 37 | assertNull(DataCenter.fromString("")); 38 | } 39 | 40 | @Test 41 | void testFromStringInvalid() { 42 | assertNull(DataCenter.fromString("unknown")); 43 | assertNull(DataCenter.fromString("random")); 44 | } 45 | 46 | @Test 47 | void testEdsServerFormat() { 48 | DataCenter dataCenter = DataCenter.US_WEST; 49 | String edsServerUrl = dataCenter.edsServer(); 50 | 51 | assertTrue(edsServerUrl.startsWith("https://api.us-west-1.saucelabs.com/v1/eds/")); 52 | assertTrue(edsServerUrl.endsWith("/v1/eds/")); 53 | } 54 | 55 | @Test 56 | void testEdsServerNonEmpty() { 57 | for (DataCenter dataCenter : DataCenter.values()) { 58 | assertNotNull(dataCenter.edsServer()); 59 | assertTrue(dataCenter.edsServer().length() > 0); 60 | } 61 | } 62 | 63 | @Test 64 | void testServerUrls() { 65 | assertEquals("https://saucelabs.com/", DataCenter.US_WEST.server()); 66 | assertEquals("https://api.us-west-1.saucelabs.com/", DataCenter.US_WEST.apiServer()); 67 | assertEquals("https://app.saucelabs.com/", DataCenter.US_WEST.appServer()); 68 | 69 | assertEquals("https://eu-central-1.saucelabs.com/", DataCenter.EU_CENTRAL.server()); 70 | assertEquals("https://api.eu-central-1.saucelabs.com/", DataCenter.EU_CENTRAL.apiServer()); 71 | assertEquals("https://app.eu-central-1.saucelabs.com/", DataCenter.EU_CENTRAL.appServer()); 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/ErrorExplainerTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import com.saucelabs.saucerest.ErrorExplainers; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class ErrorExplainerTest { 9 | @Test 10 | void errorMessageBuilder_shouldJoinTwoStrings() { 11 | String errorReason = "error reason"; 12 | String errorExplanation = "error explanation"; 13 | String expected = errorReason + System.lineSeparator() + errorExplanation; 14 | String actual = ErrorExplainers.errorMessageBuilder(errorReason, errorExplanation); 15 | assertEquals(expected, actual); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/HelperTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertThrows; 5 | 6 | import com.saucelabs.saucerest.Helper; 7 | import java.io.IOException; 8 | import org.junit.jupiter.api.Test; 9 | 10 | class HelperTest { 11 | 12 | @Test 13 | void testGetResourceFileAsStringWithValidFile() throws IOException { 14 | // Test for valid file 15 | String fileName = "/testfile.txt"; 16 | String expectedContent = "This is a test file.\nIt has multiple lines."; 17 | String actualContent = Helper.getResourceFileAsString(fileName); 18 | assertEquals(expectedContent, actualContent); 19 | } 20 | 21 | @Test 22 | void testGetResourceFileAsStringWithNonexistentFile() { 23 | // Test for nonexistent file 24 | String fileName = "/nonexistentfile.txt"; 25 | assertThrows(NullPointerException.class, () -> Helper.getResourceFileAsString(fileName)); 26 | } 27 | 28 | @Test 29 | void testGetResourceFileAsStringWithNullFileName() { 30 | // Test for null file name 31 | String fileName = null; 32 | assertThrows(IllegalArgumentException.class, () -> Helper.getResourceFileAsString(fileName)); 33 | } 34 | 35 | @Test 36 | void testGetResourceFileAsStringWithEmptyFileName() { 37 | // Test for empty file name 38 | String fileName = ""; 39 | assertThrows(IllegalArgumentException.class, () -> Helper.getResourceFileAsString(fileName)); 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/HttpMethodTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertAll; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import com.saucelabs.saucerest.HttpMethod; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class HttpMethodTest { 10 | @Test 11 | public void testLabel() { 12 | assertAll("HttpMethod label", 13 | () -> assertEquals("GET", HttpMethod.GET.label), 14 | () -> assertEquals("POST", HttpMethod.POST.label), 15 | () -> assertEquals("PUT", HttpMethod.PUT.label), 16 | () -> assertEquals("DELETE", HttpMethod.DELETE.label), 17 | () -> assertEquals("PATCH", HttpMethod.PATCH.label), 18 | () -> assertEquals("HEAD", HttpMethod.HEAD.label), 19 | () -> assertEquals("OPTIONS", HttpMethod.OPTIONS.label) 20 | ); 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/JobSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import com.saucelabs.saucerest.JobSource; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class JobSourceTest { 9 | @Test 10 | public void testValues() { 11 | assertAll("JobSource values", 12 | () -> assertSame(JobSource.RDC, JobSource.values()[0]), 13 | () -> assertSame(JobSource.VDC, JobSource.values()[1]) 14 | ); 15 | assertEquals(2, JobSource.values().length); 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/LogEntryTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import com.saucelabs.saucerest.LogEntry; 6 | import org.junit.jupiter.api.Test; 7 | 8 | public class LogEntryTest { 9 | 10 | @Test 11 | public void testConstructorAndGetters() { 12 | String time = "2022-05-05T12:34:56Z"; 13 | String level = "INFO"; 14 | String message = "Application started"; 15 | LogEntry logEntry = new LogEntry(time, level, message); 16 | assertEquals(time, logEntry.getTime()); 17 | assertEquals(level, logEntry.getLevel()); 18 | assertEquals(message, logEntry.getMessage()); 19 | } 20 | 21 | @Test 22 | public void testToString() { 23 | String time = "2022-05-05T12:34:56Z"; 24 | String level = "INFO"; 25 | String message = "Application started"; 26 | LogEntry logEntry = new LogEntry(time, level, message); 27 | assertEquals(time + " " + level + " " + message, logEntry.toString()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/LookupBuildsParametersTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import com.saucelabs.saucerest.model.builds.LookupBuildsParameters; 6 | import com.saucelabs.saucerest.model.builds.Status; 7 | import java.util.Map; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class LookupBuildsParametersTest { 11 | 12 | @Test 13 | public void testToMap() { 14 | LookupBuildsParameters params = new LookupBuildsParameters.Builder() 15 | .setUserID("user123") 16 | .setOrgID("org456") 17 | .setStatus(new Status[]{Status.success, Status.failed}) 18 | .setStart(0) 19 | .setEnd(10) 20 | .setLimit(50) 21 | .setName("build-1") 22 | .setOffset(10) 23 | .build(); 24 | 25 | Map map = params.toMap(); 26 | assertEquals("user123", map.get("user_id")); 27 | assertEquals("org456", map.get("org_id")); 28 | assertArrayEquals(new Status[]{Status.success, Status.failed}, (Status[]) map.get("status")); 29 | assertEquals(0, map.get("start")); 30 | assertEquals(10, map.get("end")); 31 | assertEquals(50, map.get("limit")); 32 | assertEquals("build-1", map.get("name")); 33 | assertEquals(10, map.get("offset")); 34 | } 35 | 36 | @Test 37 | public void testToMapWithNullValues() { 38 | LookupBuildsParameters params = new LookupBuildsParameters.Builder() 39 | .setUserID(null) 40 | .setOrgID(null) 41 | .setStatus(null) 42 | .setStart(null) 43 | .setEnd(null) 44 | .setLimit(null) 45 | .setName(null) 46 | .setOffset(null) 47 | .setSort(null) 48 | .build(); 49 | 50 | Map map = params.toMap(); 51 | assertTrue(map.isEmpty()); 52 | } 53 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/ResponseHandlerTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static com.saucelabs.saucerest.api.ResponseHandler.responseHandler; 4 | import static org.junit.jupiter.api.Assertions.assertThrows; 5 | 6 | import com.saucelabs.saucerest.DataCenter; 7 | import com.saucelabs.saucerest.HttpMethod; 8 | import com.saucelabs.saucerest.SauceException; 9 | import com.saucelabs.saucerest.api.AbstractEndpoint; 10 | import com.saucelabs.saucerest.api.JobsEndpoint; 11 | import com.saucelabs.saucerest.api.SauceConnectEndpoint; 12 | import okhttp3.Protocol; 13 | import okhttp3.Request; 14 | import okhttp3.Response; 15 | import org.junit.jupiter.api.Test; 16 | import org.mockito.Mockito; 17 | 18 | class ResponseHandlerTest { 19 | 20 | @Test 21 | public void tunnelNotFoundTest() { 22 | Response response = getMockResponse(getMockRequest("https://saucelabs.com/rest/v1/fakeuser/tunnels/1234", HttpMethod.DELETE), 404); 23 | 24 | assertThrows(SauceException.NotFound.class, () -> responseHandler(new SauceConnectEndpoint(DataCenter.EU_CENTRAL), response)); 25 | } 26 | 27 | @Test 28 | public void notAuthorizedTest() { 29 | Response response = getMockResponse(getMockRequest("https://fakewebsite.com", HttpMethod.GET), 401); 30 | 31 | assertThrows(SauceException.NotAuthorized.class, () -> responseHandler(getMockAbstractEndpoint("user", "key"), response)); 32 | } 33 | 34 | @Test 35 | public void jobNotFinishedTest() { 36 | Response response = getMockResponse(getMockRequest("https://saucelabs.com/rest/v1/fakeuser/jobs/1234", HttpMethod.GET), 400, "Job hasn't finished running"); 37 | 38 | assertThrows(SauceException.NotYetDone.class, () -> responseHandler(getMockJob("fakeuser", "fakeaccesskey"), response)); 39 | } 40 | 41 | @Test 42 | public void defaultExceptionTest() { 43 | Response response = getMockResponse(getMockRequest("https://saucelabs.com", HttpMethod.GET), 500); 44 | 45 | assertThrows(RuntimeException.class, () -> responseHandler(getMockAbstractEndpoint("fakeuser", "fakeaccesskey"), response)); 46 | } 47 | 48 | private AbstractEndpoint getMockAbstractEndpoint(String username, String accessKey) { 49 | return Mockito.mock( 50 | AbstractEndpoint.class, 51 | Mockito.withSettings() 52 | .useConstructor(username, accessKey, "null") 53 | .defaultAnswer(Mockito.CALLS_REAL_METHODS) 54 | ); 55 | } 56 | 57 | private JobsEndpoint getMockJob(String username, String accessKey) { 58 | return Mockito.mock( 59 | JobsEndpoint.class, 60 | Mockito.withSettings() 61 | .useConstructor(username, accessKey, "apiserver") 62 | .defaultAnswer(Mockito.CALLS_REAL_METHODS) 63 | ); 64 | } 65 | 66 | private Request getMockRequest(String url, HttpMethod httpMethod) { 67 | return new Request.Builder() 68 | .url(url) 69 | .method(httpMethod.label, null) 70 | .build(); 71 | } 72 | 73 | private Response getMockResponse(Request request, int code, String message) { 74 | return new Response.Builder() 75 | .request(request) 76 | .protocol(Protocol.HTTP_1_1) 77 | .code(code) 78 | .message(message) 79 | .build(); 80 | } 81 | 82 | private Response getMockResponse(Request request, int code) { 83 | return getMockResponse(request, code, ""); 84 | } 85 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/SauceConnectEndpointTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.mockito.Mockito.doReturn; 4 | import static org.mockito.Mockito.mock; 5 | import static org.mockito.Mockito.when; 6 | 7 | import java.io.IOException; 8 | import java.util.List; 9 | 10 | import com.saucelabs.saucerest.DataCenter; 11 | import com.saucelabs.saucerest.Helper; 12 | import com.saucelabs.saucerest.HttpMethod; 13 | import com.saucelabs.saucerest.api.SauceConnectEndpoint; 14 | import com.saucelabs.saucerest.model.sauceconnect.TunnelInformation; 15 | 16 | import org.junit.jupiter.api.Assertions; 17 | import org.junit.jupiter.api.Test; 18 | import org.junit.jupiter.api.extension.ExtendWith; 19 | import org.mockito.Spy; 20 | import org.mockito.junit.jupiter.MockitoExtension; 21 | 22 | import okhttp3.Response; 23 | import okhttp3.ResponseBody; 24 | 25 | @ExtendWith(MockitoExtension.class) 26 | class SauceConnectEndpointTest { 27 | 28 | @Spy 29 | private SauceConnectEndpoint sauceConnectEndpoint = new SauceConnectEndpoint("username", "access-key", 30 | DataCenter.EU_CENTRAL); 31 | 32 | @Test 33 | void getTunnelsInformationForAUserTest() throws IOException { 34 | Response response = mock(); 35 | ResponseBody responseBody = mock(); 36 | when(response.body()).thenReturn(responseBody); 37 | when(responseBody.string()).thenReturn(Helper.getResourceFileAsString("/tunnelsResponse.json")); 38 | doReturn(response).when(sauceConnectEndpoint).request( 39 | "https://api.eu-central-1.saucelabs.com/rest/v1/username/tunnels?full=true", HttpMethod.GET); 40 | List tunnelsInfo = sauceConnectEndpoint.getTunnelsInformationForAUser(); 41 | 42 | Assertions.assertFalse(tunnelsInfo.isEmpty()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/SauceShareableLinkTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import com.saucelabs.saucerest.DataCenter; 6 | import com.saucelabs.saucerest.SauceShareableLink; 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class SauceShareableLinkTest { 10 | @Test 11 | void testGetShareableLinkWithValidInputs() { 12 | String shareableLink = SauceShareableLink.getShareableLink("1234", DataCenter.EU_CENTRAL); 13 | 14 | assertAll( 15 | () -> assertNotNull(shareableLink), 16 | () -> assertFalse(shareableLink.isEmpty()), 17 | () -> assertTrue(shareableLink.contains("1234")), 18 | () -> assertTrue(shareableLink.contains(DataCenter.EU_CENTRAL.appServer)) 19 | ); 20 | } 21 | 22 | @Test 23 | void testGetShareableLinkWithDefaultCredentials() { 24 | String shareableLink = SauceShareableLink.getShareableLink("username", "accessKey", "1234", DataCenter.EU_CENTRAL); 25 | String expectedShareableLink = "https://app.eu-central-1.saucelabs.com/tests/1234?auth=6cfae591bc67fc04059684ce9b737f81"; 26 | 27 | assertAll( 28 | () -> assertNotNull(shareableLink), 29 | () -> assertFalse(shareableLink.isEmpty()), 30 | () -> assertTrue(shareableLink.contains("1234")), 31 | () -> assertTrue(shareableLink.contains(DataCenter.EU_CENTRAL.appServer)), 32 | () -> assertEquals(expectedShareableLink, shareableLink) 33 | ); 34 | } 35 | 36 | @Test 37 | void testGetShareableLinkWithEmptySauceJobId() { 38 | assertThrows(IllegalArgumentException.class, () -> { 39 | SauceShareableLink.getShareableLink(null, null, "", DataCenter.EU_CENTRAL); 40 | }); 41 | } 42 | 43 | @Test 44 | void testGetShareableLinkWithNullDataCenter() { 45 | assertThrows(IllegalArgumentException.class, () -> { 46 | SauceShareableLink.getShareableLink("username", "accessKey", "1234", null); 47 | }); 48 | } 49 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/StorageEndpointParameterTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import com.saucelabs.saucerest.model.storage.StorageParameter; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.params.ParameterizedTest; 7 | import org.junit.jupiter.params.provider.ValueSource; 8 | 9 | public class StorageEndpointParameterTest { 10 | 11 | @Test 12 | public void pageNotSet() { 13 | StorageParameter storageParameter = new StorageParameter.Builder() 14 | .setQ("bla") 15 | .build(); 16 | 17 | Assertions.assertNull(storageParameter.toMap().get("page")); 18 | } 19 | 20 | @ParameterizedTest 21 | @ValueSource(ints = {0, 1}) 22 | public void pageDefaultToNull(int page) { 23 | StorageParameter storageParameter = new StorageParameter.Builder() 24 | .setQ("bla") 25 | .setPage(page) 26 | .build(); 27 | 28 | Assertions.assertNull(storageParameter.toMap().get("page")); 29 | } 30 | 31 | @Test 32 | public void pageSet() { 33 | StorageParameter storageParameter = new StorageParameter.Builder() 34 | .setQ("bla") 35 | .setPage(5) 36 | .build(); 37 | 38 | Assertions.assertEquals(5, storageParameter.toMap().get("page")); 39 | } 40 | } -------------------------------------------------------------------------------- /src/test/java/com/saucelabs/saucerest/unit/TestAssetTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.saucerest.unit; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import com.saucelabs.saucerest.TestAsset; 6 | import java.util.Arrays; 7 | import java.util.Optional; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class TestAssetTest { 11 | @Test 12 | void testAllEnumValues() { 13 | Arrays.stream(TestAsset.values()).forEach(asset -> { 14 | String label = asset.label; 15 | Optional optionalAsset = TestAsset.get(label); 16 | assertAll( 17 | () -> assertTrue(optionalAsset.isPresent(), String.format("Asset %s not found", label)), 18 | () -> assertEquals(asset, optionalAsset.get(), String.format("Expected asset %s but found %s", asset, optionalAsset.get())) 19 | ); 20 | }); 21 | } 22 | 23 | @Test 24 | public void testGetExistingTestAsset() { 25 | Optional asset = TestAsset.get("log.json"); 26 | assertTrue(asset.isPresent()); 27 | assertEquals(TestAsset.SAUCE_LOG, asset.get()); 28 | } 29 | 30 | @Test 31 | public void testGetNonExistingTestAsset() { 32 | Optional asset = TestAsset.get("non-existing-asset"); 33 | assertFalse(asset.isPresent()); 34 | } 35 | } -------------------------------------------------------------------------------- /src/test/resources/AppFiles/Android-MyDemoAppNative.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saucelabs/saucerest-java/04a21b292d74e2bdb4953b7664d7f895e8fa4979/src/test/resources/AppFiles/Android-MyDemoAppNative.apk -------------------------------------------------------------------------------- /src/test/resources/AppFiles/Android-MyDemoAppRN.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saucelabs/saucerest-java/04a21b292d74e2bdb4953b7664d7f895e8fa4979/src/test/resources/AppFiles/Android-MyDemoAppRN.apk -------------------------------------------------------------------------------- /src/test/resources/AppFiles/iOS-Real-Device-MyNativeDemoApp.ipa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saucelabs/saucerest-java/04a21b292d74e2bdb4953b7664d7f895e8fa4979/src/test/resources/AppFiles/iOS-Real-Device-MyNativeDemoApp.ipa -------------------------------------------------------------------------------- /src/test/resources/AppFiles/iOS-Real-Device-MyRNDemoApp.ipa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saucelabs/saucerest-java/04a21b292d74e2bdb4953b7664d7f895e8fa4979/src/test/resources/AppFiles/iOS-Real-Device-MyRNDemoApp.ipa -------------------------------------------------------------------------------- /src/test/resources/AppFiles/iOS-Simulator-MyRNDemoApp.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saucelabs/saucerest-java/04a21b292d74e2bdb4953b7664d7f895e8fa4979/src/test/resources/AppFiles/iOS-Simulator-MyRNDemoApp.zip -------------------------------------------------------------------------------- /src/test/resources/appium-server.log: -------------------------------------------------------------------------------- 1 | 2020-10-21 15:23:34:612 - [Appium] Welcome to Appium v1.8.0 -------------------------------------------------------------------------------- /src/test/resources/assets.json: -------------------------------------------------------------------------------- 1 | {"video.mp4": "video.mp4", "selenium-log": "selenium-server.log", "sauce-log": "log.json", "video": "video.mp4", "logcat.log": "logcat.log", "screenshots": ["0000screenshot.png", "0001screenshot.png", "0002screenshot.png", "0003screenshot.png", "0004screenshot.png", "0005screenshot.png", "0006screenshot.png"]} -------------------------------------------------------------------------------- /src/test/resources/buildsResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "builds": [ 3 | { 4 | "creation_time": 1683527266, 5 | "deletion_time": null, 6 | "end_time": 1683527449, 7 | "group_id": "GROUP_ID_1", 8 | "id": "BUILD_ID_2", 9 | "jobs": { 10 | "completed": 0, 11 | "errored": 0, 12 | "failed": 0, 13 | "finished": 4, 14 | "passed": 4, 15 | "public": 0, 16 | "queued": 0, 17 | "running": 0 18 | }, 19 | "modification_time": 1683527454, 20 | "name": "MyDemoApp-EmuSim-1.6606", 21 | "org_id": "ORG_ID_1", 22 | "owner_id": "OWNER_ID_1", 23 | "passed": null, 24 | "public": false, 25 | "run": 0, 26 | "source": "vdc", 27 | "start_time": 1683527265, 28 | "status": "success", 29 | "team_id": "TEAM_ID_1" 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /src/test/resources/buildsResponses.json: -------------------------------------------------------------------------------- 1 | { 2 | "builds": [ 3 | { 4 | "creation_time": 1683570254, 5 | "deletion_time": null, 6 | "end_time": 1683570276, 7 | "group_id": "GROUP_ID_1", 8 | "id": "BUILD_ID_1", 9 | "jobs": { 10 | "completed": 0, 11 | "errored": 0, 12 | "failed": 0, 13 | "finished": 28, 14 | "passed": 28, 15 | "public": 0, 16 | "queued": 0, 17 | "running": 4 18 | }, 19 | "modification_time": 1683570281, 20 | "name": "Smoke-Tests-1.6620", 21 | "org_id": "ORG_ID_1", 22 | "owner_id": "OWNER_ID_1", 23 | "passed": null, 24 | "public": false, 25 | "run": 0, 26 | "source": "vdc", 27 | "start_time": 1683570255, 28 | "status": "running", 29 | "team_id": "TEAM_ID_1" 30 | }, 31 | { 32 | "creation_time": 1683527266, 33 | "deletion_time": null, 34 | "end_time": 1683527449, 35 | "group_id": "GROUP_ID_1", 36 | "id": "BUILD_ID_2", 37 | "jobs": { 38 | "completed": 0, 39 | "errored": 0, 40 | "failed": 0, 41 | "finished": 4, 42 | "passed": 4, 43 | "public": 0, 44 | "queued": 0, 45 | "running": 0 46 | }, 47 | "modification_time": 1683527454, 48 | "name": "MyDemoApp-EmuSim-1.6606", 49 | "org_id": "ORG_ID_1", 50 | "owner_id": "OWNER_ID_1", 51 | "passed": null, 52 | "public": false, 53 | "run": 0, 54 | "source": "vdc", 55 | "start_time": 1683527265, 56 | "status": "success", 57 | "team_id": "TEAM_ID_1" 58 | } 59 | ] 60 | } -------------------------------------------------------------------------------- /src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.execution.parallel.enabled=true 2 | junit.jupiter.execution.parallel.mode.default=concurrent 3 | junit.jupiter.execution.parallel.mode.classes.default=concurrent -------------------------------------------------------------------------------- /src/test/resources/sauce-connect-config-apac-southeast.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | region: 'apac-southeast' -------------------------------------------------------------------------------- /src/test/resources/sauce-connect-config-eu-central.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | region: 'eu-central' -------------------------------------------------------------------------------- /src/test/resources/sauce-connect-config-us-west.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | region: 'us-west' -------------------------------------------------------------------------------- /src/test/resources/selenium-server.log: -------------------------------------------------------------------------------- 1 | 15:41:11.042 INFO - Launching a standalone Selenium Server -------------------------------------------------------------------------------- /src/test/resources/testfile.txt: -------------------------------------------------------------------------------- 1 | This is a test file. 2 | It has multiple lines. -------------------------------------------------------------------------------- /src/test/resources/tunnelsResponse.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "creation_time": 1717539836, 4 | "direct_domains": null, 5 | "domain_names": null, 6 | "extra_info": "{\"runner\": \"false\", \"tunnel_cert\": \"public\", \"inject_job_id\": true, \"backend\": \"kgp\"}", 7 | "host": "maki3763.eu-central-1.miso.saucelabs.com", 8 | "id": "1aea0ee5dd7945d6bcdc016006de543a", 9 | "ip_address": null, 10 | "is_ready": true, 11 | "last_connected": 1717539848, 12 | "launch_time": 1717539846, 13 | "metadata": { 14 | "hostname": "fv-az731-352", 15 | "host_memory": 17179398144, 16 | "command_args": "{\"api-key\":\"****\",\"auth\":[],\"autodetect\":true,\"cainfo\":\"\",\"capath\":\"\",\"certificate\":\"\",\"config-file\":\"\",\"default-rest-url\":\"\",\"direct-domains\":[],\"dns\":[],\"doctor\":false,\"experimental\":[],\"ext\":\"127.0.0.1\",\"ext-port\":0,\"extra-info\":\"{\\\"runner\\\": \\\"false\\\"}\",\"fast-fail-regexps\":[],\"jobwaittimeout\":300,\"key\":\"\",\"kgp-handshake-timeout\":\"15s\",\"kgp-host\":\"\",\"kgp-hostname\":\"\",\"kgp-port\":443,\"log-stats\":\"0\",\"logfile\":\"\",\"max-logsize\":0,\"max-missed-acks\":300,\"metadata\":[],\"metrics-address\":\"\",\"no-autodetect\":false,\"no-cert-verify\":false,\"no-experimental\":false,\"no-http-cert-verify\":false,\"no-ocsp-verify\":false,\"no-proxy-caching\":false,\"no-remove-colliding-tunnels\":false,\"no-ssl-bump-domains\":[\"example.com\"],\"ocsp\":\"log-only\",\"output-config\":false,\"output-format\":\"pretty\",\"pac\":\"file:///C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\pac-saucelabs-98153760-7114-4eea-9a7b-c4048a20f2758181849572523160372.js\",\"pac-auth\":[],\"pidfile\":\"C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\sc_client-98153760-7114-4eea-9a7b-c4048a20f275-5957454500542236775.pid\",\"proxy\":\"\",\"proxy-localhost\":true,\"proxy-tunnel\":false,\"proxy-userpwd\":\"\",\"readyfile\":\"\",\"reconnect\":true,\"region\":\"\",\"rest-url\":\"https://api.eu-central-1.saucelabs.com/rest/v1\",\"scproxy-port\":0,\"scproxy-read-limit\":0,\"scproxy-write-limit\":0,\"se-port\":59428,\"server\":false,\"shared-tunnel\":false,\"start-timeout\":\"45s\",\"status-address\":\"\",\"tls-legacy\":false,\"tunnel-cainfo\":\"\",\"tunnel-capath\":\"\",\"tunnel-cert\":\"public\",\"tunnel-cert-suffix\":\"_maki12\",\"tunnel-domains\":[],\"tunnel-identifier\":\"\",\"tunnel-name\":\"98153760-7114-4eea-9a7b-c4048a20f275\",\"tunnel-pool\":true,\"user\":\"***\",\"verbose\":\"0\",\"vm-version\":\"\"}", 17 | "git_version": "b491a8aa ", 18 | "platform": "Windows_NT 6.2.9200 i386 25", 19 | "command": "C:\\Users\\runneradmin\\sc-4.9.2-win32\\bin\\sc.exe -u *** -k **** -P 59428 --proxy-localhost --no-ssl-bump-domains example.com --tunnel-name 98153760-7114-4eea-9a7b-c4048a20f275 --pidfile C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\sc_client-98153760-7114-4eea-9a7b-c4048a20f275-5957454500542236775.pid --pac file:///C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\pac-saucelabs-98153760-7114-4eea-9a7b-c4048a20f2758181849572523160372.js --rest-url https://api.eu-central-1.saucelabs.com/rest/v1 --tunnel-pool --extra-info {\"runner\": \"false\"}", 20 | "build": "2637", 21 | "external_proxy": "{\"kgpProxy\":\"None\",\"restProxy\":\"PAC\"}", 22 | "release": "4.9.2", 23 | "host_cpu": "cpus:1,cores:4,model:AMD EPYC 7763 64-Core Processor ", 24 | "nofile_limit": 18446744073709551615 25 | }, 26 | "no_proxy_caching": false, 27 | "no_ssl_bump_domains": [ 28 | "example.com" 29 | ], 30 | "owner": "***", 31 | "protocol": "kgp", 32 | "shared_tunnel": false, 33 | "shutdown_reason": null, 34 | "shutdown_time": null, 35 | "ssh_port": 443, 36 | "status": "running", 37 | "team_ids": [ 38 | "edd5e0dc2c724547b5b8b5b093c2a374" 39 | ], 40 | "tunnel_identifier": "98153760-7114-4eea-9a7b-c4048a20f275", 41 | "use_caching_proxy": null, 42 | "use_kgp": true, 43 | "user_shutdown": null, 44 | "vm_version": null 45 | } 46 | ] 47 | -------------------------------------------------------------------------------- /src/test/resources/user_test.json: -------------------------------------------------------------------------------- 1 | {"domain": null, "last_name": null, "creation_time": 1265155800, "user_type": "free", "concurrency_limit": {"mac": 2, "scout": 2, "overall": 2, "real_device": 0}, "manual_minutes": 45, "can_run_manual": true, "prevent_emails": ["marketing"], "id": "test", "first_name": null, "verified": false, "subscribed": false, "title": null, "ancestor_allows_subaccounts": true, "email": "test@test.com", "username": "test", "vm_lockdown": false, "parent": null, "is_admin": null, "access_key": "this-is-a-fake-access-key", "name": null, "is_sso": false, "entity_type": "individual", "ancestor_concurrency_limit": {"mac": 2, "scout": 2, "overall": 2, "real_device": 0}, "minutes": 160} -------------------------------------------------------------------------------- /src/test/resources/users_test_concurrency.json: -------------------------------------------------------------------------------- 1 | {"timestamp":1447392030.111457,"concurrency":{"organization":{"current":{"vms":1,"rds":0,"mac_vms":0},"id":"ca8b135d2e7e456385344811e05d84a6","allowed":{"vms":100,"rds":2,"mac_vms":100}},"team":{"current":{"vms":1,"rds":0,"mac_vms":0},"id":"7e3beebb84bf4efaadffbbbbe780f294","allowed":{"vms":100,"rds":2,"mac_vms":100}}}} 2 | --------------------------------------------------------------------------------