diff --git a/CHANGELOG.md b/CHANGELOG.md index a957b74..0ad4515 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ #### Fixed #### Changes +- [app-demo][tinkoff-id] redesign TinkoffIdSignInButton MC-6146 #### Additions ## 1.0.2 diff --git a/README.md b/README.md index cd0cf68..575c8e1 100644 --- a/README.md +++ b/README.md @@ -82,28 +82,35 @@ tinkoffIdAuth.obtainTokenPayload(refreshToken) ### UI -Чтобы подробнее ознакомиться со стайлгайдом по размещению кнопок перейдите по [ссылке](https://www.figma.com/file/TsgXOeAqFEePVIosk0W7kP/Tinkoff-ID) +Чтобы подробнее ознакомиться со стайлгайдом по размещению кнопок перейдите по [ссылке](https://www.figma.com/file/Yj3o7yQotahvBxfIKhBmJc/Tinkoff-ID-guide) Библиотека предоставляет кнопку `TinkoffIdSignInButton.kt`. -Пример по ее настройке доступен в `PartnerActivity.kt` и `activity_partner.xml`. Размер кнопки настраивается через атрибут -`app:tinkoff_id_size`, который может иметь значение `compact` или `standard` (по умолчанию). Подробное описание -различий находится в комментарии в `TinkoffIdSignInButton.kt`. +Пример по ее настройке доступен в `PartnerActivity.kt` и `activity_partner.xml`. +Форма кнопки настраивается через атрибут `app:tinkoff_id_compact`, который может иметь значение `true` или `false` (по умолчанию). +Стиль кнопки можно изменить с помощью атрибута `app:tinkoff_id_style`, который может иметь значение `black` / `gray` / `yellow` (по умолчанию). +Если кнопка имеет стандартную форму, то можно дополнительно настроить основной текст (`app:tinkoff_id_title`), дополнительный текст на бейдже (`app:tinkoff_id_badge`), радиусы углов (`app:tinkoff_id_corner_radius`) и шрифт текста (`app:tinkoff_id_font`). Пример добавления кнопки: ```xml - + android:layout_height="60dp" + app:tinkoff_id_compact="false" + app:tinkoff_id_title="Sign in with" + app:tinkoff_id_badge="Cashback up to 5%" + app:tinkoff_id_style="yellow" + app:tinkoff_id_corner_radius="8dp" + app:tinkoff_id_font="@font/neue_haas_unica_w1g"/> ``` Виды кнопок: - compact - ![compact.png](imgs/tinkoff_id_sign_in_button/compact.png) + compact + ![compact.png](imgs/tinkoff_id_sign_in_button/compact.png) - standard - ![standard.png](imgs/tinkoff_id_sign_in_button/standard.png) + standard + ![standard.png](imgs/tinkoff_id_sign_in_button/standard.png) ## Структура публичной части SDK diff --git a/app-demo/build.gradle b/app-demo/build.gradle index f1cd99b..51e30ca 100644 --- a/app-demo/build.gradle +++ b/app-demo/build.gradle @@ -37,4 +37,8 @@ dependencies { //rx api "io.reactivex.rxjava2:rxjava:$rxJavaVersion" api "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion" + //tests + androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion" + androidTestImplementation "androidx.test:rules:$testRuleVersion" + androidTestImplementation "androidx.test.uiautomator:uiautomator:$uiautomatorVersion" } diff --git a/app-demo/src/androidTest/java/ru/tinkoff/core/app_demo_partner/TinkoffIdSignInButtonTest.kt b/app-demo/src/androidTest/java/ru/tinkoff/core/app_demo_partner/TinkoffIdSignInButtonTest.kt new file mode 100644 index 0000000..07d1702 --- /dev/null +++ b/app-demo/src/androidTest/java/ru/tinkoff/core/app_demo_partner/TinkoffIdSignInButtonTest.kt @@ -0,0 +1,110 @@ +package ru.tinkoff.core.app_demo_partner + +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import androidx.test.rule.ActivityTestRule +import androidx.test.runner.AndroidJUnitRunner +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import ru.tinkoff.core.tinkoffId.ui.TinkoffIdSignInButton + +/** + * @author k.voskrebentsev + */ +@RunWith(AndroidJUnit4ClassRunner::class) +class TinkoffIdSignInButtonTest : AndroidJUnitRunner() { + + @get:Rule + val activityRule = ActivityTestRule(PartnerActivity::class.java, false, true) + + lateinit var standardButton: TinkoffIdSignInButton + + @Before + fun setUp() { + runOnMainThread { + standardButton = activityRule.activity.findViewById(standardButtonId) + } + } + + @Test + fun testStandardButtonTextPresence() { + checkPresenceTextOnScreen(createFinalTitle(originalTitlePart)) + } + + @Test + fun testStandardButtonTextUpdate() { + runOnMainThread { + standardButton.title = SOME_TEXT + } + + checkPresenceTextOnScreen(createFinalTitle(SOME_TEXT)) + } + + @Test + fun testStandardButtonTextAbsence() { + runOnMainThread { + standardButton.title = null + } + + checkPresenceTextOnScreen(permanentTitlePart) + } + + @Test + fun testStandardButtonBadgePresence() { + checkPresenceTextOnScreen(originalBadge) + } + + @Test + fun testStandardButtonBadgeUpdate() { + runOnMainThread { + standardButton.badgeText = SOME_TEXT + } + + checkPresenceTextOnScreen(SOME_TEXT) + } + + @Test + fun testStandardButtonBadgeAbsence() { + runOnMainThread { + standardButton.badgeText = null + } + + checkAbsenceTextOnScreen(originalBadge) + } + + @Test + fun testStandardButtonAbsenceElements() { + runOnMainThread { + standardButton.isCompact = true + } + + checkAbsenceTextOnScreen(createFinalTitle(originalTitlePart)) + checkAbsenceTextOnScreen(originalBadge) + } + + private fun checkPresenceTextOnScreen(text: String) { + assertTrue("Not found text \"$text\" on screen", UiDevice.getInstance(getInstrumentation()).hasObject(By.textContains(text))) + } + private fun checkAbsenceTextOnScreen(text: String) { + assertTrue("Found text \"$text\" on screen", !UiDevice.getInstance(getInstrumentation()).hasObject(By.textContains(text))) + } + private fun createFinalTitle(titlePart: String) = "$titlePart $permanentTitlePart" + private fun runOnMainThread(block: () -> Unit) { + activityRule.runOnUiThread(block) + } + + private companion object { + private const val SOME_TEXT = "test" + + private const val standardButtonId = R.id.standardButtonTinkoffAuth + + private val originalTitlePart = getInstrumentation().targetContext.resources.getString(R.string.partner_auth_sign_in_button_title) + private val permanentTitlePart = getInstrumentation().targetContext.resources.getString(ru.tinkoff.core.tinkoffId.R.string.tinkoff_id_tinkoff_text) + private val originalBadge = getInstrumentation().targetContext.resources.getString(R.string.partner_auth_sign_in_button_badge) + } +} diff --git a/app-demo/src/main/java/ru/tinkoff/core/app_demo_partner/PartnerActivity.kt b/app-demo/src/main/java/ru/tinkoff/core/app_demo_partner/PartnerActivity.kt index cb5336d..e798675 100644 --- a/app-demo/src/main/java/ru/tinkoff/core/app_demo_partner/PartnerActivity.kt +++ b/app-demo/src/main/java/ru/tinkoff/core/app_demo_partner/PartnerActivity.kt @@ -9,6 +9,7 @@ import android.widget.EditText import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import ru.tinkoff.core.tinkoffId.TinkoffIdAuth +import ru.tinkoff.core.tinkoffId.ui.TinkoffIdSignInButton import kotlin.LazyThreadSafetyMode.NONE class PartnerActivity : AppCompatActivity() { @@ -29,8 +30,12 @@ class PartnerActivity : AppCompatActivity() { private val redirectUriEditText by lazy(NONE) { findViewById(R.id.etRedirectUri) } private val reset by lazy(NONE) { findViewById