From 07c805a019a14bbf201e6f5a4e553156176c7ec9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Nov 2020 23:22:12 +0100 Subject: [PATCH] Create sanity test with all screens path Introduce `com.schibsted.spain:barista` --- vector/build.gradle | 4 + .../java/im/vector/app/RegistrationTest.kt | 6 +- .../im/vector/app/SecurityBootstrapTest.kt | 2 +- .../im/vector/app/VerificationTestBase.kt | 116 +------ .../app/VerifySessionInteractiveTest.kt | 6 +- .../vector/app/VerifySessionPassphraseTest.kt | 6 +- .../vector/app/espresso/tools/WaitActivity.kt | 25 ++ .../vector/app/ui/UiAllScreensSanityTest.kt | 322 ++++++++++++++++++ .../java/im/vector/app/ui/UiTestBase.kt | 90 +++++ .../main/res/layout/fragment_home_detail.xml | 2 +- .../main/res/layout/fragment_room_list.xml | 3 +- 11 files changed, 462 insertions(+), 120 deletions(-) create mode 100644 vector/src/androidTest/java/im/vector/app/espresso/tools/WaitActivity.kt create mode 100644 vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt create mode 100644 vector/src/androidTest/java/im/vector/app/ui/UiTestBase.kt diff --git a/vector/build.gradle b/vector/build.gradle index ca7cb12e31..037b049a76 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -461,6 +461,10 @@ dependencies { androidTestImplementation "androidx.arch.core:core-testing:$arch_version" // Plant Timber tree for test androidTestImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1' + // "The one who serves a great Espresso" + androidTestImplementation('com.schibsted.spain:barista:3.7.0') { + exclude group: 'org.jetbrains.kotlin' + } } if (getGradle().getStartParameter().getTaskRequests().toString().contains("Gplay")) { diff --git a/vector/src/androidTest/java/im/vector/app/RegistrationTest.kt b/vector/src/androidTest/java/im/vector/app/RegistrationTest.kt index b88356db59..73ca94b148 100644 --- a/vector/src/androidTest/java/im/vector/app/RegistrationTest.kt +++ b/vector/src/androidTest/java/im/vector/app/RegistrationTest.kt @@ -67,7 +67,7 @@ class RegistrationTest { .perform(click()) // Enter local synapse - onView((withId(R.id.loginServerUrlFormHomeServerUrl))) + onView(withId(R.id.loginServerUrlFormHomeServerUrl)) .perform(typeText(homeServerUrl)) // Click on continue @@ -87,7 +87,7 @@ class RegistrationTest { .check(matches(isDisplayed())) // Ensure user id - onView((withId(R.id.loginField))) + onView(withId(R.id.loginField)) .perform(typeText(userId)) // Ensure login button not yet enabled @@ -95,7 +95,7 @@ class RegistrationTest { .check(matches(not(isEnabled()))) // Ensure password - onView((withId(R.id.passwordField))) + onView(withId(R.id.passwordField)) .perform(closeSoftKeyboard(), typeText(password)) // Submit diff --git a/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt b/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt index 3ab8fe7dd9..0d0ec3dd2b 100644 --- a/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt +++ b/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt @@ -79,7 +79,7 @@ class SecurityBootstrapTest : VerificationTestBase() { fun testBasicBootstrap() { val userId: String = existingSession!!.myUserId - doLogin(homeServerUrl, userId, password) + uiTestBase.login(userId = userId, password = password, homeServerUrl = homeServerUrl) // Thread.sleep(6000) withIdlingResource(activityIdlingResource(HomeActivity::class.java)) { diff --git a/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt b/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt index 2a1b6d802f..a4b9983ff4 100644 --- a/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt +++ b/vector/src/androidTest/java/im/vector/app/VerificationTestBase.kt @@ -18,15 +18,11 @@ package im.vector.app import android.net.Uri import androidx.lifecycle.Observer -import androidx.test.espresso.Espresso -import androidx.test.espresso.action.ViewActions -import androidx.test.espresso.assertion.ViewAssertions -import androidx.test.espresso.matcher.ViewMatchers +import im.vector.app.ui.UiTestBase import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import org.hamcrest.CoreMatchers import org.junit.Assert import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.MatrixCallback @@ -43,108 +39,12 @@ abstract class VerificationTestBase { val password = "password" val homeServerUrl: String = "http://10.0.2.2:8080" - fun doLogin(homeServerUrl: String, userId: String, password: String) { - Espresso.onView(ViewMatchers.withId(R.id.loginSplashSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .check(ViewAssertions.matches(ViewMatchers.withText(R.string.login_splash_submit))) + protected val uiTestBase = UiTestBase() - Espresso.onView(ViewMatchers.withId(R.id.loginSplashSubmit)) - .perform(ViewActions.click()) - - Espresso.onView(ViewMatchers.withId(R.id.loginServerTitle)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .check(ViewAssertions.matches(ViewMatchers.withText(R.string.login_server_title))) - - // Chose custom server - Espresso.onView(ViewMatchers.withId(R.id.loginServerChoiceOther)) - .perform(ViewActions.click()) - - // Enter local synapse - Espresso.onView((ViewMatchers.withId(R.id.loginServerUrlFormHomeServerUrl))) - .perform(ViewActions.typeText(homeServerUrl)) - - Espresso.onView(ViewMatchers.withId(R.id.loginServerUrlFormSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isEnabled())) - .perform(ViewActions.closeSoftKeyboard(), ViewActions.click()) - - // Click on the signin button - Espresso.onView(ViewMatchers.withId(R.id.loginSignupSigninSignIn)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .perform(ViewActions.click()) - - // Ensure password flow supported - Espresso.onView(ViewMatchers.withId(R.id.loginField)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - Espresso.onView(ViewMatchers.withId(R.id.passwordField)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - - Espresso.onView((ViewMatchers.withId(R.id.loginField))) - .perform(ViewActions.typeText(userId)) - Espresso.onView(ViewMatchers.withId(R.id.loginSubmit)) - .check(ViewAssertions.matches(CoreMatchers.not(ViewMatchers.isEnabled()))) - - Espresso.onView((ViewMatchers.withId(R.id.passwordField))) - .perform(ViewActions.closeSoftKeyboard(), ViewActions.typeText(password)) - - Espresso.onView(ViewMatchers.withId(R.id.loginSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isEnabled())) - .perform(ViewActions.closeSoftKeyboard(), ViewActions.click()) - } - - private fun createAccount(userId: String = "UiAutoTest", password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") { - Espresso.onView(ViewMatchers.withId(R.id.loginSplashSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .check(ViewAssertions.matches(ViewMatchers.withText(R.string.login_splash_submit))) - - Espresso.onView(ViewMatchers.withId(R.id.loginSplashSubmit)) - .perform(ViewActions.click()) - - Espresso.onView(ViewMatchers.withId(R.id.loginServerTitle)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .check(ViewAssertions.matches(ViewMatchers.withText(R.string.login_server_title))) - - // Chose custom server - Espresso.onView(ViewMatchers.withId(R.id.loginServerChoiceOther)) - .perform(ViewActions.click()) - - // Enter local synapse - Espresso.onView((ViewMatchers.withId(R.id.loginServerUrlFormHomeServerUrl))) - .perform(ViewActions.typeText(homeServerUrl)) - - Espresso.onView(ViewMatchers.withId(R.id.loginServerUrlFormSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isEnabled())) - .perform(ViewActions.closeSoftKeyboard(), ViewActions.click()) - - // Click on the signup button - Espresso.onView(ViewMatchers.withId(R.id.loginSignupSigninSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .perform(ViewActions.click()) - - // Ensure password flow supported - Espresso.onView(ViewMatchers.withId(R.id.loginField)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - Espresso.onView(ViewMatchers.withId(R.id.passwordField)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - - Espresso.onView((ViewMatchers.withId(R.id.loginField))) - .perform(ViewActions.typeText(userId)) - Espresso.onView(ViewMatchers.withId(R.id.loginSubmit)) - .check(ViewAssertions.matches(CoreMatchers.not(ViewMatchers.isEnabled()))) - - Espresso.onView((ViewMatchers.withId(R.id.passwordField))) - .perform(ViewActions.typeText(password)) - - Espresso.onView(ViewMatchers.withId(R.id.loginSubmit)) - .check(ViewAssertions.matches(ViewMatchers.isEnabled())) - .perform(ViewActions.closeSoftKeyboard(), ViewActions.click()) - - Espresso.onView(ViewMatchers.withId(R.id.homeDrawerFragmentContainer)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - } - - fun createAccountAndSync(matrix: Matrix, userName: String, - password: String, - withInitialSync: Boolean): Session { + fun createAccountAndSync(matrix: Matrix, + userName: String, + password: String, + withInitialSync: Boolean): Session { val hs = createHomeServerConfig() doSync { @@ -174,7 +74,7 @@ abstract class VerificationTestBase { return session } - fun createHomeServerConfig(): HomeServerConnectionConfig { + private fun createHomeServerConfig(): HomeServerConnectionConfig { return HomeServerConnectionConfig.Builder() .withHomeServerUri(Uri.parse(homeServerUrl)) .build() @@ -200,7 +100,7 @@ abstract class VerificationTestBase { return result!! } - fun syncSession(session: Session) { + private fun syncSession(session: Session) { val lock = CountDownLatch(1) GlobalScope.launch(Dispatchers.Main) { session.open() } diff --git a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt index d218b6ef7e..d9005e4a63 100644 --- a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt +++ b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt @@ -78,7 +78,7 @@ class VerifySessionInteractiveTest : VerificationTestBase() { fun checkVerifyPopup() { val userId: String = existingSession!!.myUserId - doLogin(homeServerUrl, userId, password) + uiTestBase.login(userId = userId, password = password, homeServerUrl = homeServerUrl) // Thread.sleep(6000) withIdlingResource(activityIdlingResource(HomeActivity::class.java)) { @@ -215,10 +215,10 @@ class VerifySessionInteractiveTest : VerificationTestBase() { } fun signout() { - onView((withId(R.id.groupToolbarAvatarImageView))) + onView(withId(R.id.groupToolbarAvatarImageView)) .perform(click()) - onView((withId(R.id.homeDrawerHeaderSettingsView))) + onView(withId(R.id.homeDrawerHeaderSettingsView)) .perform(click()) onView(withText("General")) diff --git a/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt b/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt index f8c2a89ea8..8a21260ac7 100644 --- a/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt +++ b/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt @@ -88,7 +88,7 @@ class VerifySessionPassphraseTest : VerificationTestBase() { fun checkVerifyWithPassphrase() { val userId: String = existingSession!!.myUserId - doLogin(homeServerUrl, userId, password) + uiTestBase.login(userId = userId, password = password, homeServerUrl = homeServerUrl) // Thread.sleep(6000) withIdlingResource(activityIdlingResource(HomeActivity::class.java)) { @@ -137,10 +137,10 @@ class VerifySessionPassphraseTest : VerificationTestBase() { onView(withId(R.id.ssss__root)).check(matches(isDisplayed())) } - onView((withId(R.id.ssss_passphrase_enter_edittext))) + onView(withId(R.id.ssss_passphrase_enter_edittext)) .perform(typeText(passphrase)) - onView((withId(R.id.ssss_passphrase_submit))) + onView(withId(R.id.ssss_passphrase_submit)) .perform(click()) System.out.println("*** passphrase 1") diff --git a/vector/src/androidTest/java/im/vector/app/espresso/tools/WaitActivity.kt b/vector/src/androidTest/java/im/vector/app/espresso/tools/WaitActivity.kt new file mode 100644 index 0000000000..2cdca62c74 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/espresso/tools/WaitActivity.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.espresso.tools + +import android.app.Activity +import im.vector.app.activityIdlingResource +import im.vector.app.withIdlingResource + +inline fun waitUntilActivityVisible(noinline block: (() -> Unit)) { + withIdlingResource(activityIdlingResource(T::class.java), block) +} diff --git a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt new file mode 100644 index 0000000000..e237a103e4 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.ui + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.action.ViewActions.closeSoftKeyboard +import androidx.test.espresso.action.ViewActions.longClick +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.hasDescendant +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.rules.ActivityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +import com.schibsted.spain.barista.assertion.BaristaListAssertions.assertListItemCount +import com.schibsted.spain.barista.assertion.BaristaVisibilityAssertions.assertDisplayed +import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickBack +import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.schibsted.spain.barista.interaction.BaristaDialogInteractions.clickDialogNegativeButton +import com.schibsted.spain.barista.interaction.BaristaDialogInteractions.clickDialogPositiveButton +import com.schibsted.spain.barista.interaction.BaristaEditTextInteractions.writeTo +import com.schibsted.spain.barista.interaction.BaristaListInteractions.clickListItem +import com.schibsted.spain.barista.interaction.BaristaListInteractions.clickListItemChild +import com.schibsted.spain.barista.interaction.BaristaMenuClickInteractions.clickMenu +import com.schibsted.spain.barista.interaction.BaristaMenuClickInteractions.openMenu +import im.vector.app.EspressoHelper +import im.vector.app.R +import im.vector.app.SleepViewAction +import im.vector.app.activityIdlingResource +import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.features.MainActivity +import im.vector.app.features.createdirect.CreateDirectRoomActivity +import im.vector.app.features.home.HomeActivity +import im.vector.app.features.home.room.detail.RoomDetailActivity +import im.vector.app.features.login.LoginActivity +import im.vector.app.features.roomdirectory.RoomDirectoryActivity +import im.vector.app.initialSyncIdlingResource +import im.vector.app.withIdlingResource +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import java.util.UUID + +/** + * This test aim to open every possible screen of the application + */ +@RunWith(AndroidJUnit4::class) +@LargeTest +class UiAllScreensSanityTest { + + @get:Rule + val activityRule = ActivityScenarioRule(MainActivity::class.java) + + private val uiTestBase = UiTestBase() + + @Test + fun allScreensTest() { + // Create an account + val userId = "UiTest_" + UUID.randomUUID().toString() + uiTestBase.createAccount(userId = userId) + + withIdlingResource(activityIdlingResource(HomeActivity::class.java)) { + assertDisplayed(R.id.roomListContainer) + closeSoftKeyboard() + } + + val activity = EspressoHelper.getCurrentActivity()!! + val uiSession = (activity as HomeActivity).activeSessionHolder.getActiveSession() + + withIdlingResource(initialSyncIdlingResource(uiSession)) { + assertDisplayed(R.id.roomListContainer) + } + + assertDisplayed(R.id.bottomNavigationView) + + // Settings + navigateToSettings() + + // Create DM + clickOn(R.id.bottom_action_people) + createDm() + + // Create Room + // First navigate to the other tab + clickOn(R.id.bottom_action_rooms) + createRoom() + + assertDisplayed(R.id.bottomNavigationView) + + // Long click on the room + onView(withId(R.id.roomListView)) + .perform( + actionOnItem( + hasDescendant(withText(R.string.room_displayname_empty_room)), + longClick() + ) + ) + pressBack() + + uiTestBase.signout() + + // We have sent a message in a e2e room, accept to loose it + clickOn(R.id.exitAnywayButton) + // Dark pattern + clickDialogNegativeButton() + + // Login again on the same account + waitUntilActivityVisible { + assertDisplayed(R.id.loginSplashLogo) + } + + uiTestBase.login(userId) + ignoreVerification() + + uiTestBase.signout() + clickDialogPositiveButton() + } + + private fun ignoreVerification() { + Thread.sleep(6000) + val activity = EspressoHelper.getCurrentActivity()!! + + val popup = activity.findViewById(com.tapadoo.alerter.R.id.llAlertBackground) + activity.runOnUiThread { + popup.performClick() + } + + assertDisplayed(R.id.bottomSheetFragmentContainer) + + onView(ViewMatchers.isRoot()).perform(SleepViewAction.sleep(2000)) + + clickOn(R.string.skip) + assertDisplayed(R.string.are_you_sure) + clickOn(R.string.skip) + } + + private fun createRoom() { + clickOn(R.id.createGroupRoomButton) + waitUntilActivityVisible { + assertDisplayed(R.id.publicRoomsList) + } + clickOn(R.string.create_new_room) + + // Create + assertListItemCount(R.id.createRoomForm, 10) + clickListItemChild(R.id.createRoomForm, 9, R.id.form_submit_button) + + waitUntilActivityVisible { + assertDisplayed(R.id.roomDetailContainer) + } + + clickOn(R.id.attachmentButton) + clickBack() + + // Send a message + writeTo(R.id.composerEditText, "Hello world!") + clickOn(R.id.sendButton) + + navigateToRoomSettings() + + // Long click on the message + onView(withId(R.id.recyclerView)) + .perform( + actionOnItem( + hasDescendant(withText("Hello world!")), + longClick() + ) + ) + pressBack() + + // Menu + openMenu() + pressBack() + clickMenu(R.id.voice_call) + pressBack() + clickMenu(R.id.video_call) + pressBack() + + pressBack() + } + + private fun navigateToRoomSettings() { + clickOn(R.id.roomToolbarTitleView) + assertDisplayed(R.id.roomProfileAvatarView) + + // Room settings + clickListItem(R.id.matrixProfileRecyclerView, 3) + pressBack() + + // Notifications + clickListItem(R.id.matrixProfileRecyclerView, 5) + pressBack() + + assertDisplayed(R.id.roomProfileAvatarView) + + // People + clickListItem(R.id.matrixProfileRecyclerView, 7) + assertDisplayed(R.id.inviteUsersButton) + navigateToRoomPeople() + // Fab + navigateToInvite() + pressBack() + pressBack() + + assertDisplayed(R.id.roomProfileAvatarView) + + // Uploads + clickListItem(R.id.matrixProfileRecyclerView, 9) + // File tab + clickOn(R.string.uploads_files_title) + pressBack() + + assertDisplayed(R.id.roomProfileAvatarView) + + // Leave + clickListItem(R.id.matrixProfileRecyclerView, 13) + clickDialogNegativeButton() + + // Menu share + // clickMenu(R.id.roomProfileShareAction) + // pressBack() + + pressBack() + } + + private fun navigateToInvite() { + assertDisplayed(R.id.inviteUsersButton) + clickOn(R.id.inviteUsersButton) + closeSoftKeyboard() + pressBack() + } + + private fun navigateToRoomPeople() { + // Open first user + clickListItem(R.id.recyclerView, 1) + assertDisplayed(R.id.memberProfilePowerLevelView) + + // Verification + clickListItem(R.id.matrixProfileRecyclerView, 1) + clickBack() + + // Role + clickListItem(R.id.matrixProfileRecyclerView, 3) + clickDialogNegativeButton() + + clickBack() + } + + private fun createDm() { + clickOn(R.id.createChatRoomButton) + + withIdlingResource(activityIdlingResource(CreateDirectRoomActivity::class.java)) { + assertDisplayed(R.id.addByMatrixId) + } + + closeSoftKeyboard() + pressBack() + pressBack() + } + + private fun navigateToSettings() { + clickOn(R.id.groupToolbarAvatarImageView) + clickOn(R.id.homeDrawerHeaderSettingsView) + + clickOn(R.string.settings_general_title) + // TODO + pressBack() + + clickOn(R.string.settings_notifications) + // TODO + pressBack() + + clickOn(R.string.settings_preferences) + // TODO + pressBack() + + clickOn(R.string.preference_voice_and_video) + // TODO + pressBack() + + clickOn(R.string.settings_ignored_users) + // TODO + pressBack() + + clickOn(R.string.settings_security_and_privacy) + // TODO + pressBack() + + clickOn(R.string.room_settings_labs_pref_title) + // TODO + pressBack() + + clickOn(R.string.settings_advanced_settings) + // TODO + pressBack() + + clickOn(R.string.preference_root_help_about) + // TODO + pressBack() + + pressBack() + } +} diff --git a/vector/src/androidTest/java/im/vector/app/ui/UiTestBase.kt b/vector/src/androidTest/java/im/vector/app/ui/UiTestBase.kt new file mode 100644 index 0000000000..ed174b50a2 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/UiTestBase.kt @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.ui + +import androidx.test.espresso.Espresso.closeSoftKeyboard +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.matcher.ViewMatchers.isRoot +import androidx.test.espresso.matcher.ViewMatchers.withId +import com.schibsted.spain.barista.assertion.BaristaEnabledAssertions.assertDisabled +import com.schibsted.spain.barista.assertion.BaristaEnabledAssertions.assertEnabled +import com.schibsted.spain.barista.assertion.BaristaVisibilityAssertions.assertDisplayed +import com.schibsted.spain.barista.interaction.BaristaClickInteractions.clickOn +import com.schibsted.spain.barista.interaction.BaristaEditTextInteractions.writeTo +import im.vector.app.R +import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.features.home.HomeActivity +import im.vector.app.waitForView + +class UiTestBase { + fun createAccount(userId: String, password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") { + initSession(true, userId, password, homeServerUrl) + } + + fun login(userId: String, password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") { + initSession(false, userId, password, homeServerUrl) + } + + private fun initSession(createAccount: Boolean, + userId: String, + password: String, + homeServerUrl: String) { + assertDisplayed(R.id.loginSplashSubmit, R.string.login_splash_submit) + clickOn(R.id.loginSplashSubmit) + assertDisplayed(R.id.loginServerTitle, R.string.login_server_title) + // Chose custom server + clickOn(R.id.loginServerChoiceOther) + // Enter local synapse + writeTo(R.id.loginServerUrlFormHomeServerUrl, homeServerUrl) + assertEnabled(R.id.loginServerUrlFormSubmit) + closeSoftKeyboard() + clickOn(R.id.loginServerUrlFormSubmit) + onView(isRoot()).perform(waitForView(withId(R.id.loginSignupSigninSubmit))) + + if (createAccount) { + // Click on the signup button + assertDisplayed(R.id.loginSignupSigninSubmit) + clickOn(R.id.loginSignupSigninSubmit) + } else { + // Click on the signin button + assertDisplayed(R.id.loginSignupSigninSignIn) + clickOn(R.id.loginSignupSigninSignIn) + } + + // Ensure password flow supported + assertDisplayed(R.id.loginField) + assertDisplayed(R.id.passwordField) + + writeTo(R.id.loginField, userId) + assertDisabled(R.id.loginSubmit) + writeTo(R.id.passwordField, password) + assertEnabled(R.id.loginSubmit) + + closeSoftKeyboard() + clickOn(R.id.loginSubmit) + + // Wait + waitUntilActivityVisible { + assertDisplayed(R.id.homeDetailFragmentContainer) + } + } + + fun signout() { + clickOn(R.id.groupToolbarAvatarImageView) + clickOn(R.id.homeDrawerHeaderSignoutView) + } +} diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index 83bb9994f8..d9a2470343 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -105,7 +105,7 @@ + android:overScrollMode="always" + tools:listitem="@layout/item_room" />