diff --git a/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt b/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt index ee4e79ec82..31479aa1b7 100644 --- a/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt +++ b/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt @@ -32,6 +32,7 @@ import okio.IOException import okio.buffer import java.io.File import java.nio.file.Path +import java.util.Scanner import kotlin.io.path.absolutePathString import kotlin.io.path.exists import kotlin.time.Duration.Companion.minutes @@ -331,7 +332,7 @@ class ApiClient( } val url = if (projectId != null) { - "$baseUrl/runMaestroTest" + "$baseUrl/v2/project/$projectId/runMaestroTest" } else { "$baseUrl/v2/upload" } @@ -351,6 +352,50 @@ class ApiClient( if (!response.isSuccessful) { val errorMessage = response.body?.string().takeIf { it?.isNotEmpty() == true } ?: "Unknown" + if (response.code == 403 && errorMessage.contains("Your trial has not started yet", ignoreCase = true)) { + println("\n\u001B[31;1m[ERROR]\u001B[0m Your trial has not started yet.") + print("\u001B[34;1m[INPUT]\u001B[0m Please enter your company name to start the trial: ") + + val scanner = Scanner(System.`in`) + val companyName = scanner.nextLine().trim() + + if (companyName.isNotEmpty()) { + println("\u001B[33;1m[INFO]\u001B[0m Starting your trial for company: \u001B[36;1m$companyName\u001B[0m...") + + val isTrialStarted = startTrial(authToken, companyName); + if(isTrialStarted) { + println("\u001B[32;1m[SUCCESS]\u001B[0m Trial successfully started. Enjoy your 7-day free trial!\n") + return upload( + authToken = authToken, + appFile = appFile, + workspaceZip = workspaceZip, + uploadName = uploadName, + mappingFile = mappingFile, + repoOwner = repoOwner, + repoName = repoName, + branch = branch, + commitSha = commitSha, + pullRequestId = pullRequestId, + env = env, + androidApiLevel = androidApiLevel, + iOSVersion = iOSVersion, + includeTags = includeTags, + excludeTags = excludeTags, + maxRetryCount = maxRetryCount, + completedRetries = completedRetries + 1, + progressListener = progressListener, + appBinaryId = appBinaryId, + disableNotifications = disableNotifications, + deviceLocale = deviceLocale, + ) + } else { + println("\u001B[31;1m[ERROR]\u001B[0m Failed to start trial. Please check your details and try again.") + } + } else { + println("\u001B[31;1m[ERROR]\u001B[0m Company name is required for starting a trial.") + } + } + if (response.code >= 500) { return retry("Upload failed with status code ${response.code}: $errorMessage") } else { @@ -368,6 +413,28 @@ class ApiClient( } } + private fun startTrial(authToken: String, companyName: String): Boolean { + println("Starting your trial...") + val url = "$baseUrl/v2/start-trial" + + val jsonBody = """{ "companyName": "$companyName" }""".toRequestBody("application/json".toMediaType()) + val trialRequest = Request.Builder() + .header("Authorization", "Bearer $authToken") + .url(url) + .post(jsonBody) + .build() + + try { + val response = client.newCall(trialRequest).execute() + if (response.isSuccessful) return true; + println("\u001B[31m${response.body?.string()}\u001B[0m"); + return false + } catch (e: IOException) { + println("\u001B[31;1m[ERROR]\u001B[0m We're experiencing connectivity issues, please try again in sometime, reach out to the slack channel in case if this doesn't work.") + return false + } + } + private fun parseRobinUploadResponse(responseBody: Map<*, *>): UploadResponse { @Suppress("UNCHECKED_CAST") val orgId = responseBody["orgId"] as String diff --git a/maestro-cli/src/main/java/maestro/cli/command/CloudCommand.kt b/maestro-cli/src/main/java/maestro/cli/command/CloudCommand.kt index a2bb60c7c0..0c0d3f6e9d 100644 --- a/maestro-cli/src/main/java/maestro/cli/command/CloudCommand.kt +++ b/maestro-cli/src/main/java/maestro/cli/command/CloudCommand.kt @@ -182,7 +182,7 @@ class CloudCommand : Callable { // Upload val apiUrl = apiUrl ?: run { if (projectId != null) { - "https://api.copilot.mobile.dev/v2/project/$projectId" + "https://api.copilot.mobile.dev" } else { throw CliError("You need to specify a Robin project with --projectId") }