mirror of
https://github.com/hmalik144/Driver.git
synced 2025-12-10 02:45:20 +00:00
- screenshot library setup
- pull screenshot after tests - update to fastfile to produce bundles instead of .apks Took 4 hours 17 minutes
This commit is contained in:
@@ -65,6 +65,9 @@ jobs:
|
|||||||
test-command: ./gradlew connected<< parameters.flavour >>DebugAndroidTest
|
test-command: ./gradlew connected<< parameters.flavour >>DebugAndroidTest
|
||||||
system-image: system-images;android-25;google_apis;x86
|
system-image: system-images;android-25;google_apis;x86
|
||||||
max-tries: 1
|
max-tries: 1
|
||||||
|
pull-data: true
|
||||||
|
pull-data-path: storage/emulated/0/Android/data/h_mal.appttude.com.driver.admin/files/screengrab/en-US/images/screenshots
|
||||||
|
pull-data-target: "."
|
||||||
# store test reports
|
# store test reports
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: app/build/reports/androidTests/connected
|
path: app/build/reports/androidTests/connected
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -16,10 +16,13 @@
|
|||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
*.log
|
*.log
|
||||||
local
|
local
|
||||||
|
# Circleci
|
||||||
/.circleci/local_config.yml
|
/.circleci/local_config.yml
|
||||||
/.circleci/run_local.bash
|
/.circleci/run_local.bash
|
||||||
|
# Gem/fastlane
|
||||||
/Gemfile.lock
|
/Gemfile.lock
|
||||||
/playstore.json
|
/playstore.json
|
||||||
|
/fastlane/report.xml
|
||||||
|
# Firebase emulator
|
||||||
database-debug.log
|
database-debug.log
|
||||||
firebase-debug.log
|
firebase-debug.log
|
||||||
|
|||||||
@@ -36,18 +36,18 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// signingConfigs {
|
signingConfigs {
|
||||||
// release {
|
release {
|
||||||
// storePassword relStorePassword
|
storePassword relStorePassword
|
||||||
// keyPassword relKeyPassword
|
keyPassword relKeyPassword
|
||||||
// keyAlias relKeyAlias
|
keyAlias relKeyAlias
|
||||||
// storeFile file(relStoreFile)
|
storeFile file(relStoreFile)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
@@ -162,6 +162,6 @@ dependencies {
|
|||||||
def retrofit_version = "2.9.0"
|
def retrofit_version = "2.9.0"
|
||||||
androidTestImplementation "com.squareup.retrofit2:retrofit:$retrofit_version"
|
androidTestImplementation "com.squareup.retrofit2:retrofit:$retrofit_version"
|
||||||
androidTestImplementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
|
androidTestImplementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
|
||||||
/ * Spoon screenshot library */
|
/ * screenshot library */
|
||||||
androidTestImplementation 'com.squareup.spoon:spoon-client:1.1.1'
|
androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/buttonContainer"
|
app:layout_constraintBottom_toTopOf="@id/buttonContainer"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:layout="@layout/fragment_driver_license" />
|
app:layout_constraintVertical_bias="0.0"
|
||||||
|
tools:layout="@layout/fragment_private_hire_license" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/buttonContainer"
|
android:id="@+id/buttonContainer"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package h_mal.appttude.com.driver
|
package h_mal.appttude.com.driver
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
||||||
import android.R
|
import android.R
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -10,23 +9,15 @@ import android.view.View
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.test.core.app.ActivityScenario
|
import androidx.test.core.app.ActivityScenario
|
||||||
|
import androidx.test.espresso.*
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.Espresso.setFailureHandler
|
|
||||||
import androidx.test.espresso.IdlingRegistry
|
|
||||||
import androidx.test.espresso.IdlingResource
|
|
||||||
import androidx.test.espresso.Root
|
|
||||||
import androidx.test.espresso.UiController
|
|
||||||
import androidx.test.espresso.ViewAction
|
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.*
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||||
import androidx.test.rule.GrantPermissionRule
|
import androidx.test.rule.GrantPermissionRule
|
||||||
import h_mal.appttude.com.driver.base.BaseActivity
|
import h_mal.appttude.com.driver.base.BaseActivity
|
||||||
import h_mal.appttude.com.driver.helpers.BaseViewAction
|
import h_mal.appttude.com.driver.helpers.BaseViewAction
|
||||||
import h_mal.appttude.com.driver.helpers.SpoonFailureHandler
|
import h_mal.appttude.com.driver.helpers.SnapshotRule
|
||||||
import org.hamcrest.CoreMatchers
|
import org.hamcrest.CoreMatchers
|
||||||
import org.hamcrest.Description
|
import org.hamcrest.Description
|
||||||
import org.hamcrest.Matcher
|
import org.hamcrest.Matcher
|
||||||
@@ -34,7 +25,11 @@ import org.hamcrest.TypeSafeMatcher
|
|||||||
import org.hamcrest.core.AllOf
|
import org.hamcrest.core.AllOf
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.ClassRule
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
import tools.fastlane.screengrab.Screengrab
|
||||||
|
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
|
||||||
|
import tools.fastlane.screengrab.locale.LocaleTestRule
|
||||||
|
|
||||||
|
|
||||||
open class BaseUiTest<T : BaseActivity<*, *>>(
|
open class BaseUiTest<T : BaseActivity<*, *>>(
|
||||||
@@ -46,13 +41,19 @@ open class BaseUiTest<T : BaseActivity<*, *>>(
|
|||||||
|
|
||||||
private lateinit var currentActivity: Activity
|
private lateinit var currentActivity: Activity
|
||||||
|
|
||||||
@JvmField
|
@get:Rule
|
||||||
|
var permissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
var snapshotRule: SnapshotRule = SnapshotRule()
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
var permissionWrite = GrantPermissionRule.grant(WRITE_EXTERNAL_STORAGE)
|
@JvmField
|
||||||
|
var localeTestRule = LocaleTestRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
setFailureHandler(SpoonFailureHandler(getInstrumentation().targetContext))
|
Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())
|
||||||
beforeLaunch()
|
beforeLaunch()
|
||||||
mActivityScenarioRule = ActivityScenario.launch(activity)
|
mActivityScenarioRule = ActivityScenario.launch(activity)
|
||||||
mActivityScenarioRule.onActivity {
|
mActivityScenarioRule.onActivity {
|
||||||
|
|||||||
@@ -1,27 +1,23 @@
|
|||||||
package h_mal.appttude.com.driver.helpers
|
package h_mal.appttude.com.driver.helpers
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.test.espresso.FailureHandler
|
import androidx.test.espresso.FailureHandler
|
||||||
import androidx.test.espresso.base.DefaultFailureHandler
|
import androidx.test.espresso.base.DefaultFailureHandler
|
||||||
import com.squareup.spoon.Spoon
|
|
||||||
import org.hamcrest.Matcher
|
import org.hamcrest.Matcher
|
||||||
|
import tools.fastlane.screengrab.Screengrab
|
||||||
|
|
||||||
|
|
||||||
class SpoonFailureHandler(targetContext: Context) : FailureHandler {
|
class CustomFailureHandler(targetContext: Context) : FailureHandler {
|
||||||
private val delegate: FailureHandler
|
private val delegate: FailureHandler
|
||||||
private val context: Context
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
delegate = DefaultFailureHandler(targetContext)
|
delegate = DefaultFailureHandler(targetContext)
|
||||||
context = targetContext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(error: Throwable?, viewMatcher: Matcher<View?>?) {
|
override fun handle(error: Throwable, viewMatcher: Matcher<View>) {
|
||||||
delegate.handle(error, viewMatcher)
|
delegate.handle(error, viewMatcher)
|
||||||
if (context is Activity) {
|
// Catch a screenshot on failure
|
||||||
Spoon.screenshot(context, "error")
|
Screengrab.screenshot("error")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package h_mal.appttude.com.driver.helpers
|
||||||
|
|
||||||
|
import org.junit.rules.TestWatcher
|
||||||
|
import org.junit.runner.Description
|
||||||
|
import tools.fastlane.screengrab.Screengrab
|
||||||
|
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Junit rule that takes a screenshot when a test fails.
|
||||||
|
*/
|
||||||
|
class SnapshotRule : TestWatcher() {
|
||||||
|
override fun failed(e: Throwable, description: Description) {
|
||||||
|
// Catch a screenshot on failure
|
||||||
|
Screengrab.screenshot("FAILURE-" + getScreenshotName(description))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getScreenshotName(description: Description): String {
|
||||||
|
return description.className.replace(".", "-") + "_" + description.methodName.replace(".", "-")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,18 @@
|
|||||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
<manifest xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<!-- Allows unlocking your device and activating its screen so UI tests can succeed -->
|
||||||
|
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||||
|
|
||||||
|
<!-- Allows for storing and retrieving screenshots -->
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<!-- Allows changing locales -->
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<application
|
<application
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
tools:ignore="MissingApplicationIcon" />
|
tools:ignore="MissingApplicationIcon" />
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:maxWidth="350dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
app:cardCornerRadius="28dp"
|
app:cardCornerRadius="28dp"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
@@ -18,11 +19,11 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView2"
|
android:id="@+id/imageView2"
|
||||||
android:layout_width="200dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="200dp"
|
android:layout_height="200dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@drawable/choice_img_round"
|
tools:src="@drawable/driver_license_private_hire"
|
||||||
android:contentDescription="@string/image_description" />
|
android:contentDescription="@string/image_description" />
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@
|
|||||||
android:text="@string/upload_private_hire_photo"
|
android:text="@string/upload_private_hire_photo"
|
||||||
app:layout_constraintBottom_toTopOf="@id/til_submission"
|
app:layout_constraintBottom_toTopOf="@id/til_submission"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent" />
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/til_submission"
|
android:id="@+id/til_submission"
|
||||||
@@ -48,7 +50,8 @@
|
|||||||
style="@style/EditTextStyle"
|
style="@style/EditTextStyle"
|
||||||
android:hint="@string/private_hire_license_no"
|
android:hint="@string/private_hire_license_no"
|
||||||
android:importantForAutofill="no"
|
android:importantForAutofill="no"
|
||||||
tools:ignore="TextFields" />
|
tools:ignore="TextFields"
|
||||||
|
tools:text="987651"/>
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
@@ -63,7 +66,8 @@
|
|||||||
android:id="@+id/ph_expiry"
|
android:id="@+id/ph_expiry"
|
||||||
style="@style/EditTextStyle.Date"
|
style="@style/EditTextStyle.Date"
|
||||||
android:hint="@string/private_hire_license_expiry"
|
android:hint="@string/private_hire_license_expiry"
|
||||||
android:autofillHints="date" />
|
android:autofillHints="date"
|
||||||
|
tools:text="30/12/2018"/>
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
@@ -76,6 +80,7 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/til_submission"
|
app:layout_constraintTop_toBottomOf="@+id/til_submission"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintVertical_bias="0.8" />
|
app:layout_constraintVertical_bias="0.8"
|
||||||
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -32,13 +32,13 @@ platform :android do
|
|||||||
|
|
||||||
desc "Deploy a new version of Driver to the Google Play"
|
desc "Deploy a new version of Driver to the Google Play"
|
||||||
lane :deployDriver do
|
lane :deployDriver do
|
||||||
gradle(task: "clean assemble", flavor: "driver", build_type: "Release")
|
gradle(task: "clean bundle", flavor: "driver", build_type: "Release")
|
||||||
upload_to_play_store(apk: "app/build/outputs/apk/driver/release/app-driver-release.apk", json_key: "playstore.json", package_name: "h_mal.appttude.com.driver")
|
upload_to_play_store(aab: "app/build/outputs/bundle/driverRelease/app-driver-release.aab", json_key: "playstore.json", package_name: "h_mal.appttude.com.driver")
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Deploy a new version of Admin to the Google Play"
|
desc "Deploy a new version of Admin to the Google Play"
|
||||||
lane :deployDriver do
|
lane :deployAdmin do
|
||||||
gradle(task: "clean assemble", flavor: "admin", build_type: "Release")
|
gradle(task: "clean bundle", flavor: "admin", build_type: "Release")
|
||||||
upload_to_play_store(apk: "app/build/outputs/apk/admin/release/app-admin-release.apk", json_key: "playstore.json", package_name: "h_mal.appttude.com.driver.admin")
|
upload_to_play_store(aab: "app/build/outputs/bundle/adminRelease/app-admin-release.aab", json_key: "playstore.json", package_name: "h_mal.appttude.com.driver.admin")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,19 +5,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.0030572">
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.002655">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: clean assembledriverRelease" time="50.9029889">
|
<testcase classname="fastlane.lanes" name="1: clean bundleadminRelease" time="86.6186667">
|
||||||
|
|
||||||
</testcase>
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="16.3554569">
|
|
||||||
|
|
||||||
<failure message="C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:229:in `chdir' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:229:in `execute_action' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing' Fastfile:42:in `block (2 levels) in parsing_binding' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/lane.rb:33:in `call' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:49:in `block in execute' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:45:in `chdir' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:45:in `execute' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/commander-4.6.0/lib/commander/command.rb:187:in `call' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/commander-4.6.0/lib/commander/command.rb:157:in `run' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/commands_generator.rb:354:in `run' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/commands_generator.rb:43:in `start' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off' C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/fastlane-2.212.1/bin/fastlane:23:in `<top (required)>' C:/Ruby31-x64/bin/fastlane:32:in `load' C:/Ruby31-x64/bin/fastlane:32:in `<main>' Google Api Error: Invalid request - Cannot update a published APK." />
|
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user