├── settings.gradle ├── app ├── src │ └── androidTest │ │ └── java │ │ └── ru │ │ └── skillbranch │ │ └── devintensive │ │ ├── TestUtils.kt │ │ ├── Task5.kt │ │ ├── Task4.kt │ │ ├── Task3.kt │ │ ├── Task8.kt │ │ ├── Task1.kt │ │ ├── Task6.kt │ │ ├── Task7.kt │ │ └── Task2.kt └── build.gradle └── README.md /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/TestUtils.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.app.Activity 4 | import android.content.pm.ActivityInfo 5 | import androidx.test.platform.app.InstrumentationRegistry 6 | import androidx.test.rule.ActivityTestRule 7 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 8 | 9 | fun rotateScreen(activity: Activity, isLandscape: Boolean){ 10 | InstrumentationRegistry.getInstrumentation().runOnMainSync { 11 | activity.requestedOrientation = if (isLandscape) ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE else ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 12 | } 13 | InstrumentationRegistry.getInstrumentation().waitForIdleSync() 14 | Thread.sleep(2000) 15 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task5.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.rule.ActivityTestRule 5 | import org.junit.Assert.* 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.runner.RunWith 9 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 10 | 11 | @RunWith(AndroidJUnit4::class) 12 | class Task5 { 13 | @Rule 14 | @JvmField 15 | val rule = ActivityTestRule(ProfileActivity::class.java) 16 | 17 | @Test 18 | fun splashScreenTest(){ 19 | val loaderTheme = rule.activity.packageManager.getActivityInfo(rule.activity.componentName, 0).themeResource 20 | assertEquals(R.style.SplashTheme, loaderTheme) 21 | 22 | val clazz = ProfileActivity::class.java 23 | val method = clazz.getMethod("getThemeResId") 24 | method.isAccessible = true 25 | val activityThemeResId = method.invoke(rule.activity) as Int 26 | assertEquals(R.style.AppTheme, activityThemeResId) 27 | } 28 | } -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 28 9 | defaultConfig { 10 | applicationId "ru.skillbranch.devintensive" 11 | minSdkVersion 23 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "1.0" 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 28 | implementation 'androidx.appcompat:appcompat:1.0.2' 29 | implementation 'androidx.core:core-ktx:1.0.2' 30 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 31 | implementation 'com.google.android.material:material:1.0.0' 32 | implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' 33 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'androidx.test:rules:1.2.0' 36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 37 | androidTestImplementation 'androidx.test:runner:1.2.0' 38 | androidTestImplementation group: 'androidx.test.ext', name: 'junit', version: '1.1.1' 39 | androidTestImplementation 'com.android.support:palette-v7:28.0.0' 40 | } 41 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task4.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.graphics.Color 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | import androidx.test.rule.ActivityTestRule 6 | import org.junit.Assert.assertEquals 7 | import org.junit.Rule 8 | import org.junit.Test 9 | import org.junit.runner.RunWith 10 | import ru.skillbranch.devintensive.ui.custom.CircleImageView 11 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 12 | 13 | @RunWith(AndroidJUnit4::class) 14 | class Task4 { 15 | @Rule 16 | @JvmField 17 | val rule = ActivityTestRule(ProfileActivity::class.java) 18 | 19 | @Test 20 | fun circleImageViewTest(){ 21 | val avatarViewId = rule.activity.resources.getIdentifier("iv_avatar", "id", rule.activity.packageName) 22 | val avatarView = rule.activity.findViewById(avatarViewId) 23 | 24 | assertEquals(2, avatarView.getBorderWidth()) 25 | assertEquals(-1, avatarView.getBorderColor()) 26 | 27 | rule.activity.runOnUiThread { 28 | avatarView.setBorderWidth(0) 29 | assertEquals(0, avatarView.getBorderWidth()) 30 | 31 | avatarView.setBorderWidth(23) 32 | assertEquals(23, avatarView.getBorderWidth()) 33 | 34 | val colorAccent = rule.activity.resources.getIdentifier("color_accent", "color", rule.activity.packageName) 35 | avatarView.setBorderColor(colorAccent) 36 | val color = rule.activity.resources.getColor(colorAccent, rule.activity.theme) 37 | assertEquals(color, avatarView.getBorderColor()) 38 | 39 | avatarView.setBorderColor("#FC4C4C") 40 | assertEquals(Color.parseColor("#FC4C4C"), avatarView.getBorderColor()) 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HomeTask_4: тесты на задания "Dev Intensive 2019" от Skill Branch 2 | 3 | ВНИМАНИЕ! Если вы делаете мои тесты впервые, ознакомьтесь с первоначальной инструкцией [здесь](https://github.com/russdreamer/dev-intensive-2019-tests/tree/hometask_3_tests) ! 4 | 5 | ВНИМАНИЕ! Я у себя обновил build.gradle на runner от androidx, проверяйте свои импорты. Мой gradle так же выложен. 6 | 7 | ВНИМАНИЕ! Добавлена новая зависимость для тестов:
8 | > ` androidTestImplementation 'com.android.support:palette-v7:28.0.0' ` 9 | 10 | ВНИМАНИЕ! если у вас ошибки в запуске или импортах, то внимательно читайте [здесь](https://github.com/russdreamer/dev-intensive-2019-tests/tree/hometask_3_tests) ! Если не помогло - пишите в личку в телеграмм. 11 |

12 | * Здесь лежат тесты уже для всех заданий. 13 | * Для вашего удобства тесты разбиты по названию в соответствии с нумерацией заданий. 14 | * Методы, на которые составлены тесты, успешно прошли проверку ботом. 15 | * Так как функционал классов и методов от урока к уроку может отличаться, каждый этап будет в отдельной ветке. 16 | * Ветки нумеруются согласно рабочим веткам. Т.е. hometask_4 в вашем репозитории == hometask_4_tests этого репозитория. 17 | * Тесты можно и нужно дополнять, если хотите - можете форкаться, можете писать в телеграмме (@Igatroll), а можете просто подписываться на репу и пользоваться. 18 | 19 | ОШИБКИ:
20 | Если тест падает с ошибкой "Error performing 'single click'", то варианта 2:
21 | а) вы тестируете на эмуляторе/устройстве, на котором не влезает весь ваш интерфейс и поэтому невозможно нажать на какие-то поля/кнопки. В таком случае тесты на сервере пройдут.
22 | б) у вас такой же эмулятор/устройство, как у ментора, но из-за плохой верстки или вылезающей клавиатуры прячутся кнопки или поля. В таком случае тесты на сервере тоже свалятся. 23 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task3.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.content.res.Configuration 4 | import android.graphics.Color 5 | import android.util.TypedValue 6 | import androidx.test.espresso.Espresso 7 | import androidx.test.espresso.action.ViewActions 8 | import androidx.test.espresso.matcher.ViewMatchers 9 | import androidx.test.ext.junit.runners.AndroidJUnit4 10 | import androidx.test.rule.ActivityTestRule 11 | import org.junit.Assert.* 12 | import org.junit.Rule 13 | import org.junit.Test 14 | import org.junit.runner.RunWith 15 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 16 | 17 | @RunWith(AndroidJUnit4::class) 18 | class Task3 { 19 | @Rule 20 | @JvmField 21 | val rule = ActivityTestRule(ProfileActivity::class.java) 22 | 23 | @Test 24 | fun checkDayThemeColorsTest(){ 25 | var curTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 26 | if (curTheme == Configuration.UI_MODE_NIGHT_YES) 27 | switchTheme() 28 | 29 | curTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 30 | assertEquals(curTheme, Configuration.UI_MODE_NIGHT_NO) 31 | 32 | checkColors("#473770", "#9CA9BA", "#1F000000") 33 | } 34 | 35 | @Test 36 | fun checkNightThemeColorsTest(){ 37 | var curTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 38 | if (curTheme == Configuration.UI_MODE_NIGHT_NO) 39 | switchTheme() 40 | 41 | curTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 42 | assertEquals(curTheme, Configuration.UI_MODE_NIGHT_YES) 43 | 44 | checkColors("#1FFFFFFF", "#ffffffff", "#1F000000") 45 | } 46 | 47 | @Test 48 | fun saveThemeOnExitTest(){ 49 | val prevTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 50 | switchTheme() 51 | 52 | val intent = rule.activity.intent 53 | rule.finishActivity() 54 | Thread.sleep(1000) 55 | rule.launchActivity(intent) 56 | Thread.sleep(1000) 57 | 58 | val newTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 59 | assertNotEquals(prevTheme, newTheme) 60 | } 61 | 62 | private fun checkColors(surface: String, icon: String, divider: String) { 63 | val typedValue = TypedValue() 64 | val colorAccentedSurface = rule.activity.resources.getIdentifier("colorAccentedSurface", "attr", rule.activity.packageName) 65 | rule.activity.theme.resolveAttribute(colorAccentedSurface, typedValue, true) 66 | var color = typedValue.data 67 | assertEquals(color, Color.parseColor(surface)) 68 | 69 | val colorIcon = rule.activity.resources.getIdentifier("colorIcon", "attr", rule.activity.packageName) 70 | rule.activity.theme.resolveAttribute(colorIcon, typedValue, true) 71 | color = typedValue.data 72 | assertEquals(color, Color.parseColor(icon)) 73 | 74 | val colorDivider = rule.activity.resources.getIdentifier("colorDivider", "attr", rule.activity.packageName) 75 | rule.activity.theme.resolveAttribute(colorDivider, typedValue, true) 76 | color = typedValue.data 77 | assertEquals(color, Color.parseColor(divider)) 78 | } 79 | 80 | private fun switchTheme() { 81 | val switchThemeBtnId = rule.activity.resources.getIdentifier("btn_switch_theme", "id", rule.activity.packageName) 82 | Espresso.onView(ViewMatchers.withId(switchThemeBtnId)).perform(ViewActions.click()) 83 | } 84 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task8.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.content.res.Configuration 4 | import android.graphics.Color 5 | import android.support.v7.graphics.Palette 6 | import androidx.core.graphics.drawable.toBitmap 7 | import androidx.test.espresso.Espresso 8 | import androidx.test.espresso.action.ViewActions 9 | import androidx.test.espresso.matcher.ViewMatchers 10 | import androidx.test.ext.junit.runners.AndroidJUnit4 11 | import androidx.test.rule.ActivityTestRule 12 | import org.junit.Assert.assertEquals 13 | import org.junit.Rule 14 | import org.junit.Test 15 | import org.junit.runner.RunWith 16 | import ru.skillbranch.devintensive.ui.custom.CircleImageView 17 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 18 | 19 | @RunWith(AndroidJUnit4::class) 20 | class Task8 { 21 | @Rule 22 | @JvmField 23 | val rule = ActivityTestRule(ProfileActivity::class.java) 24 | 25 | var editBtnId: Int? = null 26 | var firstNameId: Int? = null 27 | var lastNameId: Int? = null 28 | var avaId: Int? = null 29 | var ava: CircleImageView? = null 30 | 31 | @Test 32 | fun circleImageViewTest(){ 33 | updateFields() 34 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 35 | Espresso.onView(ViewMatchers.withId(firstNameId!!)).perform(ViewActions.replaceText("Anton")) 36 | Espresso.onView(ViewMatchers.withId(lastNameId!!)).perform(ViewActions.replaceText("Karton")) 37 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 38 | 39 | val curTheme = rule.activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 40 | if (curTheme == Configuration.UI_MODE_NIGHT_YES) { 41 | switchTheme() 42 | updateFields() 43 | } 44 | 45 | var palette = Palette.from(ava!!.drawable.toBitmap()).generate() 46 | var color = palette.getDominantColor(0) 47 | assertEquals(-505784, color) 48 | switchTheme() 49 | updateFields() 50 | 51 | palette = Palette.from(ava!!.drawable.toBitmap()).generate() 52 | color = palette.getDominantColor(0) 53 | assertEquals(-14642960, color) 54 | 55 | rule.activity.runOnUiThread { 56 | assertEquals(2, ava!!.getBorderWidth()) 57 | assertEquals(Color.WHITE, ava!!.getBorderColor()) 58 | ava!!.setBorderColor(R.color.color_gray_dark) 59 | ava!!.setBorderWidth(20) 60 | 61 | color = rule.activity.resources.getColor(R.color.color_gray_dark, rule.activity.theme) 62 | assertEquals(color, ava!!.getBorderColor()) 63 | assertEquals(20, ava!!.getBorderWidth()) 64 | 65 | ava!!.setBorderColor("#1ab33e") 66 | assertEquals(-15027394, ava!!.getBorderColor()) 67 | } 68 | } 69 | 70 | private fun switchTheme() { 71 | val switchThemeBtnId = rule.activity.resources.getIdentifier("btn_switch_theme", "id", rule.activity.packageName) 72 | Espresso.onView(ViewMatchers.withId(switchThemeBtnId)).perform(ViewActions.click()) 73 | } 74 | 75 | private fun updateFields(){ 76 | editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 77 | firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 78 | lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 79 | avaId = rule.activity.resources.getIdentifier("iv_avatar", "id", rule.activity.packageName) 80 | ava = rule.activity.findViewById(avaId!!) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task1.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.view.View 4 | import android.widget.EditText 5 | import android.widget.ImageButton 6 | import android.widget.ImageView 7 | import android.widget.TextView 8 | import androidx.test.ext.junit.runners.AndroidJUnit4 9 | import androidx.test.rule.ActivityTestRule 10 | import com.google.android.material.textfield.TextInputLayout 11 | import org.junit.Assert.* 12 | import org.junit.Rule 13 | import org.junit.Test 14 | import org.junit.runner.RunWith 15 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 16 | 17 | @RunWith(AndroidJUnit4::class) 18 | class Task1 { 19 | @Rule 20 | @JvmField 21 | val rule = ActivityTestRule(ProfileActivity::class.java) 22 | 23 | @Test 24 | fun projectStructureTest(){ 25 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 26 | val editBtn = rule.activity.findViewById(editBtnId) 27 | assertTrue(editBtn is ImageButton) 28 | 29 | val switchThemeBtnId = rule.activity.resources.getIdentifier("btn_switch_theme", "id", rule.activity.packageName) 30 | val switchThemeBtn = rule.activity.findViewById(switchThemeBtnId) 31 | assertTrue(switchThemeBtn is ImageButton) 32 | 33 | val avatarViewId = rule.activity.resources.getIdentifier("iv_avatar", "id", rule.activity.packageName) 34 | val avatarView = rule.activity.findViewById(avatarViewId) 35 | assertTrue(avatarView is ImageView) 36 | 37 | val nickNameTextId = rule.activity.resources.getIdentifier("tv_nick_name", "id", rule.activity.packageName) 38 | val nickNameText = rule.activity.findViewById(nickNameTextId) 39 | assertTrue(nickNameText is TextView) 40 | 41 | val rankTextId = rule.activity.resources.getIdentifier("tv_rank", "id", rule.activity.packageName) 42 | val rankText = rule.activity.findViewById(rankTextId) 43 | assertTrue(rankText is TextView) 44 | 45 | val ratingTextId = rule.activity.resources.getIdentifier("tv_rating", "id", rule.activity.packageName) 46 | val ratingText = rule.activity.findViewById(ratingTextId) 47 | assertTrue(ratingText is TextView) 48 | 49 | val respectTextId = rule.activity.resources.getIdentifier("tv_respect", "id", rule.activity.packageName) 50 | val respectText = rule.activity.findViewById(respectTextId) 51 | assertTrue(respectText is TextView) 52 | 53 | val firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 54 | val firstName = rule.activity.findViewById(firstNameId) 55 | assertTrue(firstName is EditText) 56 | 57 | val lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 58 | val lastName = rule.activity.findViewById(lastNameId) 59 | assertTrue(lastName is EditText) 60 | 61 | val aboutId = rule.activity.resources.getIdentifier("et_about", "id", rule.activity.packageName) 62 | val about = rule.activity.findViewById(aboutId) 63 | assertTrue(about is EditText) 64 | 65 | val wrAboutId = rule.activity.resources.getIdentifier("wr_about", "id", rule.activity.packageName) 66 | val wrAbout = rule.activity.findViewById(wrAboutId) 67 | assertTrue(wrAbout is TextInputLayout) 68 | 69 | val repoId = rule.activity.resources.getIdentifier("et_repository", "id", rule.activity.packageName) 70 | val repo = rule.activity.findViewById(repoId) 71 | assertTrue(repo is EditText) 72 | 73 | val weRepoId = rule.activity.resources.getIdentifier("wr_repository", "id", rule.activity.packageName) 74 | val weRepo = rule.activity.findViewById(weRepoId) 75 | assertTrue(weRepo is TextInputLayout) 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task6.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.widget.EditText 4 | import android.widget.TextView 5 | import androidx.test.espresso.Espresso 6 | import androidx.test.espresso.action.ViewActions 7 | import androidx.test.espresso.matcher.ViewMatchers 8 | import androidx.test.rule.ActivityTestRule 9 | import org.junit.Assert.assertEquals 10 | import org.junit.Before 11 | import org.junit.Rule 12 | import org.junit.Test 13 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 14 | 15 | class Task6 { 16 | @Rule 17 | @JvmField 18 | val rule = ActivityTestRule(ProfileActivity::class.java) 19 | 20 | var nickNameTextId: Int? = null 21 | var nickNameText: TextView? = null 22 | var firstNameId: Int? = null 23 | var firstName: EditText? = null 24 | var lastNameId: Int? = null 25 | var lastName: EditText? = null 26 | var editBtnId: Int? = null 27 | 28 | @Before 29 | fun beforeTest(){ 30 | updateFields() 31 | } 32 | 33 | @Test 34 | fun nickNameTest(){ 35 | fillInfo("", "") 36 | assertEquals("", nickNameText!!.text) 37 | fillInfo("Женя", "Стереотипов") 38 | assertEquals("Zhenya_Stereotipov", nickNameText!!.text) 39 | fillInfo("Amazing", "Петр") 40 | assertEquals("Amazing_Petr", nickNameText!!.text) 41 | fillInfo("иВан", "Стереотижов") 42 | assertEquals("iVan_Stereotizhov", nickNameText!!.text) 43 | fillInfo("Amazing", "ПеЖр") 44 | assertEquals("Amazing_PeZhr", nickNameText!!.text) 45 | fillInfo("", "аАбБвВгГдДеЕёЁжЖзЗиИйЙкКлЛ") 46 | assertEquals("aAbBvVgGdDeEeEzhZhzZiIiIkKlL", nickNameText!!.text) 47 | fillInfo("аАбБвВгГдДеЕёЁжЖзЗиИйЙкКлЛ", "") 48 | assertEquals("aAbBvVgGdDeEeEzhZhzZiIiIkKlL", nickNameText!!.text) 49 | fillInfo("", "мМнНоОпПрРсСтТуУфФхХцЦшШщЩ") 50 | assertEquals("mMnNoOpPrRsStTuUfFhHcCshShsh'Sh'", nickNameText!!.text) 51 | fillInfo("ъЪьЬэЭюЮяЯ", "") 52 | assertEquals("eEyuYuyaYa", nickNameText!!.text) 53 | fillInfo("123", "!,^-=+>(nickNameTextId!!) 90 | firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 91 | firstName = rule.activity.findViewById(firstNameId!!) 92 | lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 93 | lastName = rule.activity.findViewById(lastNameId!!) 94 | editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 95 | } 96 | 97 | private fun fillInfo(firstName: String, secondName: String) { 98 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 99 | Espresso.onView(ViewMatchers.withId(firstNameId!!)).perform(ViewActions.replaceText(firstName)) 100 | Espresso.onView(ViewMatchers.withId(lastNameId!!)).perform(ViewActions.replaceText(secondName)) 101 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 102 | } 103 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task7.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import android.widget.EditText 4 | import androidx.test.espresso.Espresso 5 | import androidx.test.espresso.action.ViewActions 6 | import androidx.test.espresso.assertion.ViewAssertions 7 | import androidx.test.espresso.matcher.ViewMatchers 8 | import androidx.test.ext.junit.runners.AndroidJUnit4 9 | import androidx.test.rule.ActivityTestRule 10 | import com.google.android.material.textfield.TextInputLayout 11 | import org.hamcrest.CoreMatchers.not 12 | import org.junit.Assert.* 13 | import org.junit.Before 14 | import org.junit.Rule 15 | import org.junit.Test 16 | import org.junit.runner.RunWith 17 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 18 | 19 | @RunWith(AndroidJUnit4::class) 20 | class Task7 { 21 | @Rule 22 | @JvmField 23 | val rule = ActivityTestRule(ProfileActivity::class.java) 24 | 25 | var repoId: Int? = null 26 | var repo: EditText? = null 27 | var weRepoId: Int? = null 28 | var weRepo: TextInputLayout? = null 29 | var editBtnId: Int? = null 30 | var eyeId: Int? = null 31 | 32 | @Before 33 | fun beforeTest(){ 34 | updateFields() 35 | } 36 | 37 | @Test 38 | fun validateRepoTest(){ 39 | check("https://anyDomain.github.com/johnDoe", false) 40 | check("https://github.com/johnDoe", true) 41 | check("https://github5com/johnDoe", false) 42 | check("https://github.com/", false) 43 | check("https://www.github.com/johnDoe", true) 44 | check("https://www4github.com/johnDoe", false) 45 | check("https://github.com", false) 46 | check("www.github.com/johnDoe", true) 47 | check("https://github.com/johnDoe/tree", false) 48 | check("github.com/johnDoe", true) 49 | check("https://github.com/johnDoe/tree/something", false) 50 | check("https://github.com/john-Doe", true) 51 | check("https://github.com/johnDoe/", true) 52 | check("https://github.com/enterprise", false) 53 | check("", true) 54 | check("https://github.com/pricing", false) 55 | check("https://github.com/surpricing", true) 56 | check("https://github.com/join", false) 57 | check("https://github.com/join2", true) 58 | check("https://github.com/features", false) 59 | check("https://github.com/ufeatures", true) 60 | check("https://github.com/topics", false) 61 | check("https://github.com/topics-knopics", true) 62 | check("https://github.com/collections", false) 63 | check("https://github.com/my-collections", true) 64 | check("https://github.com/trending", false) 65 | check("https://github.com/events", false) 66 | check("https://github.com/marketplace", false) 67 | check("https://github.com/nonprofit", false) 68 | check("https://github.com/johnDoe123", true) 69 | check("https://github.com/customer-stories", false) 70 | check("https://github.com/security", false) 71 | check("https://github.com/securitys", true) 72 | check("https://github.com/ myrep", false) 73 | check("https://github.com/my_rep", false) 74 | check("https://github.com/my rep", false) 75 | check("https://github.com/myrep _", false) 76 | check("https://github.com//myrep", false) 77 | check("https://github.com/myrep//", false) 78 | check("/myrep", false) 79 | check("myrep", false) 80 | } 81 | 82 | /* ВНИМАНИЕ!!! Этот тест не является обязательным. Но соответствует реальной валидации на github 83 | * Можете проверить лишь для себя */ 84 | @Test 85 | fun fullValidationTest() { 86 | check("github.com/_myrep", false) 87 | check("github.com/myrep_", false) 88 | check("github.com/my_rep", false) 89 | check("github.com/my--rep", false) 90 | check("github.com/-myrep", false) 91 | check("github.com/myrep-", false) 92 | check("github.com/myrep!", false) 93 | check("github.com/+myrep", false) 94 | } 95 | 96 | 97 | @Test 98 | fun saveOnRotate() { 99 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 100 | typeRepo("https://www.github.com/johnDoe") 101 | rotateScreen(rule.activity, true) 102 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).check(ViewAssertions.matches(ViewMatchers.isDisplayed())) 103 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 104 | } 105 | 106 | private fun check(text: String, isValid: Boolean) { 107 | checkEye(true) 108 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 109 | checkEye(false) 110 | typeRepo(text) 111 | checkEye(false) 112 | checkError(isValid) 113 | rotateScreen(rule.activity, true) 114 | Espresso.onView(ViewMatchers.withId(editBtnId!!)).perform(ViewActions.click()) 115 | rotateScreen(rule.activity, false) 116 | updateFields() 117 | checkSave(isValid, text) 118 | checkExit(isValid, text) 119 | } 120 | 121 | private fun checkEye(isVisible: Boolean) { 122 | if (isVisible) 123 | Espresso.onView(ViewMatchers.withId(eyeId!!)).check(ViewAssertions.matches(ViewMatchers.isDisplayed())) 124 | else 125 | Espresso.onView(ViewMatchers.withId(eyeId!!)).check(ViewAssertions.matches(not(ViewMatchers.isDisplayed()))) 126 | } 127 | 128 | private fun checkExit(isValid: Boolean, text: String) { 129 | val intent = rule.activity.intent 130 | rule.finishActivity() 131 | Thread.sleep(1000) 132 | rule.launchActivity(intent) 133 | Thread.sleep(1000) 134 | updateFields() 135 | 136 | checkSave(isValid, text) 137 | } 138 | 139 | private fun checkSave(isValid: Boolean, text: String) { 140 | if (isValid) 141 | assertEquals(text, repo!!.text.toString()) 142 | else 143 | assertEquals("", repo!!.text.toString()) 144 | 145 | assertTrue(weRepo!!.error == null) 146 | assertTrue(weRepo!!.isErrorEnabled.not()) 147 | } 148 | 149 | private fun checkError(isValid: Boolean) { 150 | if (!isValid){ 151 | assertEquals("Невалидный адрес репозитория", weRepo!!.error.toString()) 152 | assertTrue(weRepo!!.isErrorEnabled) 153 | assertTrue(weRepo!!.error != null) 154 | } 155 | else { 156 | assertTrue(weRepo!!.error == null) 157 | assertTrue(weRepo!!.isErrorEnabled.not()) 158 | } 159 | } 160 | 161 | private fun typeRepo(text: String) { 162 | Espresso.onView(ViewMatchers.withId(repoId!!)).perform(ViewActions.replaceText("")) 163 | Espresso.onView(ViewMatchers.withId(repoId!!)).perform(ViewActions.typeText(text)) 164 | Espresso.onView(ViewMatchers.withId(repoId!!)).perform(ViewActions.closeSoftKeyboard()) 165 | } 166 | 167 | private fun updateFields() { 168 | repoId = rule.activity.resources.getIdentifier("et_repository", "id", rule.activity.packageName) 169 | repo = rule.activity.findViewById(repoId!!) 170 | weRepoId = rule.activity.resources.getIdentifier("wr_repository", "id", rule.activity.packageName) 171 | weRepo = rule.activity.findViewById(weRepoId!!) 172 | editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 173 | eyeId = rule.activity.resources.getIdentifier("ic_eye", "id", rule.activity.packageName) 174 | } 175 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/ru/skillbranch/devintensive/Task2.kt: -------------------------------------------------------------------------------- 1 | package ru.skillbranch.devintensive 2 | 3 | import androidx.test.espresso.Espresso 4 | import androidx.test.espresso.action.ViewActions 5 | import androidx.test.espresso.assertion.ViewAssertions.matches 6 | import androidx.test.espresso.matcher.ViewMatchers 7 | import androidx.test.espresso.matcher.ViewMatchers.withText 8 | import androidx.test.ext.junit.runners.AndroidJUnit4 9 | import androidx.test.rule.ActivityTestRule 10 | import org.junit.Rule 11 | import org.junit.Test 12 | import org.junit.runner.RunWith 13 | import ru.skillbranch.devintensive.ui.profile.ProfileActivity 14 | 15 | @RunWith(AndroidJUnit4::class) 16 | class Task2 { 17 | @Rule 18 | @JvmField 19 | val rule = ActivityTestRule(ProfileActivity::class.java) 20 | 21 | @Test 22 | fun saveInfoTest(){ 23 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 24 | clearInfo() 25 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 26 | fillInfo() 27 | checkInfo() 28 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 29 | checkInfo() 30 | } 31 | 32 | @Test 33 | fun saveInfoRotateTest(){ 34 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 35 | clearInfo() 36 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 37 | fillInfo() 38 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 39 | rotateScreen(rule.activity, true) 40 | rotateScreen(rule.activity, false) 41 | checkInfo() 42 | } 43 | 44 | @Test 45 | fun editableOnRotateTest(){ 46 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 47 | clearInfo() 48 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 49 | rotateScreen(rule.activity, true) 50 | rotateScreen(rule.activity, false) 51 | fillInfo() 52 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 53 | checkInfo() 54 | } 55 | 56 | @Test 57 | fun saveOnExitTest(){ 58 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 59 | clearInfo() 60 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 61 | fillInfo() 62 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 63 | val intent = rule.activity.intent 64 | rule.finishActivity() 65 | Thread.sleep(1000) 66 | rule.launchActivity(intent) 67 | Thread.sleep(1000) 68 | checkInfo() 69 | } 70 | 71 | @Test 72 | fun saveEmptyOnExitTest(){ 73 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 74 | clearInfo() 75 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 76 | fillInfo() 77 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 78 | checkInfo() 79 | 80 | var intent = rule.activity.intent 81 | rule.finishActivity() 82 | Thread.sleep(1000) 83 | rule.launchActivity(intent) 84 | Thread.sleep(1000) 85 | 86 | checkInfo() 87 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 88 | clearInfo() 89 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 90 | checkEmptyInfo() 91 | 92 | intent = rule.activity.intent 93 | rule.finishActivity() 94 | Thread.sleep(1000) 95 | rule.launchActivity(intent) 96 | Thread.sleep(1000) 97 | 98 | checkEmptyInfo() 99 | } 100 | 101 | @Test 102 | fun saveAfterRotate(){ 103 | val editBtnId = rule.activity.resources.getIdentifier("btn_edit", "id", rule.activity.packageName) 104 | clearInfo() 105 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 106 | fillInfo() 107 | rotateScreen(rule.activity, true) 108 | Espresso.onView(ViewMatchers.withId(editBtnId)).perform(ViewActions.click()) 109 | checkInfo() 110 | } 111 | 112 | private fun checkInfo() { 113 | val firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 114 | Espresso.onView(ViewMatchers.withId(firstNameId)).check(matches(withText("Anton"))) 115 | 116 | val lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 117 | Espresso.onView(ViewMatchers.withId(lastNameId)).check(matches(withText("Karton"))) 118 | 119 | val aboutId = rule.activity.resources.getIdentifier("et_about", "id", rule.activity.packageName) 120 | Espresso.onView(ViewMatchers.withId(aboutId)).check(matches(withText("1\n2\n3"))) 121 | 122 | val repoId = rule.activity.resources.getIdentifier("et_repository", "id", rule.activity.packageName) 123 | Espresso.onView(ViewMatchers.withId(repoId)).check(matches(withText("github.com/bender"))) 124 | } 125 | 126 | private fun checkEmptyInfo() { 127 | val firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 128 | Espresso.onView(ViewMatchers.withId(firstNameId)).check(matches(withText(""))) 129 | 130 | val lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 131 | Espresso.onView(ViewMatchers.withId(lastNameId)).check(matches(withText(""))) 132 | 133 | val aboutId = rule.activity.resources.getIdentifier("et_about", "id", rule.activity.packageName) 134 | Espresso.onView(ViewMatchers.withId(aboutId)).check(matches(withText(""))) 135 | 136 | val repoId = rule.activity.resources.getIdentifier("et_repository", "id", rule.activity.packageName) 137 | Espresso.onView(ViewMatchers.withId(repoId)).check(matches(withText(""))) 138 | } 139 | 140 | private fun fillInfo() { 141 | val firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 142 | Espresso.onView(ViewMatchers.withId(firstNameId)).perform(ViewActions.typeText("Anton")) 143 | Espresso.onView(ViewMatchers.withId(firstNameId)).perform(ViewActions.closeSoftKeyboard()) 144 | 145 | val lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 146 | Espresso.onView(ViewMatchers.withId(lastNameId)).perform(ViewActions.typeText("Karton")) 147 | Espresso.onView(ViewMatchers.withId(lastNameId)).perform(ViewActions.closeSoftKeyboard()) 148 | 149 | val aboutId = rule.activity.resources.getIdentifier("et_about", "id", rule.activity.packageName) 150 | Espresso.onView(ViewMatchers.withId(aboutId)).perform(ViewActions.typeText("1\n2\n3")) 151 | Espresso.onView(ViewMatchers.withId(aboutId)).perform(ViewActions.closeSoftKeyboard()) 152 | 153 | val repoId = rule.activity.resources.getIdentifier("et_repository", "id", rule.activity.packageName) 154 | Espresso.onView(ViewMatchers.withId(repoId)).perform(ViewActions.typeText("github.com/bender")) 155 | Espresso.onView(ViewMatchers.withId(repoId)).perform(ViewActions.closeSoftKeyboard()) 156 | } 157 | 158 | private fun clearInfo() { 159 | val firstNameId = rule.activity.resources.getIdentifier("et_first_name", "id", rule.activity.packageName) 160 | Espresso.onView(ViewMatchers.withId(firstNameId)).perform(ViewActions.replaceText("")) 161 | 162 | val lastNameId = rule.activity.resources.getIdentifier("et_last_name", "id", rule.activity.packageName) 163 | Espresso.onView(ViewMatchers.withId(lastNameId)).perform(ViewActions.replaceText("")) 164 | 165 | val aboutId = rule.activity.resources.getIdentifier("et_about", "id", rule.activity.packageName) 166 | Espresso.onView(ViewMatchers.withId(aboutId)).perform(ViewActions.replaceText("")) 167 | 168 | val repoId = rule.activity.resources.getIdentifier("et_repository", "id", rule.activity.packageName) 169 | Espresso.onView(ViewMatchers.withId(repoId)).perform(ViewActions.replaceText("")) 170 | } 171 | } --------------------------------------------------------------------------------