Преглед изворни кода

Add test for login flow

Signed-off-by: Tim Krüger <t@timkrueger.me>
Tim Krüger пре 3 година
родитељ
комит
81734bd647

+ 18 - 22
.drone.yml

@@ -47,28 +47,24 @@ steps:
       - scripts/wait_for_emulator.sh
       - ./gradlew --console=plain testGplayDebugUnitTest connectedGplayDebugAndroidTest
 
-#services:
-#  - name: server
-#    image: nextcloudci/server:server-17 # also change in updateScreenshots.sh
-#    environment:
-#      EVAL: true
-#    commands:
-#      - BRANCH='stable22' /usr/local/bin/initnc.sh
-#      - echo 127.0.0.1 server >> /etc/hosts
-#      - su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1"
-#      - su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2"
-#      - su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3"
-#      - su www-data -c "php /var/www/html/occ user:setting user2 files quota 1G"
-#      - su www-data -c "php /var/www/html/occ group:add users"
-#      - su www-data -c "php /var/www/html/occ group:adduser users user1"
-#      - su www-data -c "php /var/www/html/occ group:adduser users user2"
-#      - su www-data -c "git clone -b stable22 https://github.com/nextcloud/activity.git /var/www/html/apps/activity/"
-#      - su www-data -c "php /var/www/html/occ app:enable activity"
-#      - su www-data -c "git clone -b stable22 https://github.com/nextcloud/text.git /var/www/html/apps/text/"
-#      - su www-data -c "php /var/www/html/occ app:enable text"
-#      - su www-data -c "git clone -b stable22 https://github.com/nextcloud/end_to_end_encryption.git /var/www/html/apps/end_to_end_encryption/"
-#      - su www-data -c "php /var/www/html/occ app:enable end_to_end_encryption"
-#      - /usr/local/bin/run.sh
+services:
+  - name: server
+    image: nextcloudci/server:server-17
+    environment:
+      EVAL: "true"
+    commands:
+      - BRANCH='stable23' /usr/local/bin/initnc.sh
+      - echo 127.0.0.1 server >> /etc/hosts
+      - su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1"
+      - su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2"
+      - su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3"
+      - su www-data -c "php /var/www/html/occ user:setting user2 files quota 1G"
+      - su www-data -c "php /var/www/html/occ group:add users"
+      - su www-data -c "php /var/www/html/occ group:adduser users user1"
+      - su www-data -c "php /var/www/html/occ group:adduser users user2"
+      - su www-data -c "git clone -b stable23 https://github.com/nextcloud/spreed.git /var/www/html/apps/spreed/"
+      - su www-data -c "php /var/www/html/occ app:enable spreed"
+      - /usr/local/bin/run.sh
 
 trigger:
   branch:

+ 11 - 4
app/build.gradle

@@ -87,6 +87,10 @@ android {
                 ]
             }
         }
+
+        testInstrumentationRunnerArgument "TEST_SERVER_URL", "${NC_TEST_SERVER_BASEURL}"
+        testInstrumentationRunnerArgument "TEST_SERVER_USERNAME", "${NC_TEST_SERVER_USERNAME}"
+        testInstrumentationRunnerArgument "TEST_SERVER_PASSWORD", "${NC_TEST_SERVER_PASSWORD}"
     }
 
     dexOptions {
@@ -297,16 +301,19 @@ dependencies {
     testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}"
     testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}"
 
+
+    androidTestImplementation "androidx.test:core:1.4.0"
+
+
     // Espresso core
-    androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
+    androidTestImplementation ("androidx.test.espresso:espresso-core:$espressoVersion", {
+        exclude group: 'com.android.support', module: 'support-annotations'
+    })
     androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
     androidTestImplementation "androidx.test.espresso:espresso-web:$espressoVersion"
     androidTestImplementation "androidx.test.espresso:espresso-accessibility:$espressoVersion"
     androidTestImplementation('com.android.support.test.espresso:espresso-intents:3.0.2')
 
-    androidTestImplementation ('androidx.test.espresso:espresso-core:3.4.0', {
-        exclude group: 'com.android.support', module: 'support-annotations'
-    })
     spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.11.0'
     spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.7'
 

+ 3 - 3
app/src/androidTest/java/com/nextcloud/talk/activities/MainActivityTest.kt

@@ -5,7 +5,7 @@ import androidx.test.espresso.intent.rule.IntentsTestRule
 import com.nextcloud.talk.models.database.UserEntity
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.schedulers.Schedulers
-import junit.framework.Assert.assertTrue
+import org.junit.Assert.assertTrue
 import org.junit.Rule
 import org.junit.Test
 
@@ -23,7 +23,7 @@ class MainActivityTest {
         sut.userUtils.createOrUpdateUser(
             "test",
             "test",
-            "http://10.0.2.2/nc",
+            "http://server/nc",
             "test",
             null,
             true,
@@ -49,7 +49,7 @@ class MainActivityTest {
 
         sut.runOnUiThread { sut.resetConversationsList() }
 
-        assertTrue(sut.userUtils.getIfUserWithUsernameAndServer("test", "http://10.0.2.2/nc"))
+        assertTrue(sut.userUtils.getIfUserWithUsernameAndServer("test", "http://server/nc"))
 
         try {
         } catch (e: InterruptedException) {

+ 152 - 0
app/src/androidTest/java/com/nextcloud/talk/ui/LoginIT.java

@@ -0,0 +1,152 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Tobias Kaminsky
+ * @author Tim Krüger
+ * Copyright (C) 2021 Tim Krüger
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+package com.nextcloud.talk.ui;
+
+import android.os.Bundle;
+
+import com.nextcloud.talk.R;
+import com.nextcloud.talk.activities.MainActivity;
+
+import junit.framework.AssertionFailedError;
+
+import org.junit.Test;
+
+import java.util.Objects;
+
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.web.webdriver.DriverAtoms;
+import androidx.test.espresso.web.webdriver.Locator;
+import androidx.test.filters.LargeTest;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.typeText;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.web.sugar.Web.onWebView;
+import static androidx.test.espresso.web.webdriver.DriverAtoms.findElement;
+import static androidx.test.espresso.web.webdriver.DriverAtoms.webClick;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+
+
+@LargeTest
+public class LoginIT {
+
+    @Test
+    public void login() throws InterruptedException {
+
+        ActivityScenario<MainActivity> activityScenario = ActivityScenario.launch(MainActivity.class);
+
+        Bundle arguments = androidx.test.platform.app.InstrumentationRegistry.getArguments();
+
+        String baseUrl = arguments.getString("TEST_SERVER_URL");
+        String loginName = arguments.getString("TEST_SERVER_USERNAME");
+        String password = arguments.getString("TEST_SERVER_PASSWORD");
+
+        Thread.sleep(2000);
+
+        try {
+            onView(withId(R.id.serverEntryTextInputEditText)).check(matches(isDisplayed()));
+        } catch (NoMatchingViewException e) {
+            try {
+                // can happen that an invalid account from previous tests is existing
+                onView(withText(R.string.nc_settings_remove_account)).perform(click());
+                Thread.sleep(2000);
+            } catch (NoMatchingViewException ie) {
+                // is OK if the dialog is not shown
+            }
+
+            try {
+                // Delete account if exists
+                onView(withId(R.id.switch_account_button)).perform(click());
+                onView(withId(R.id.manage_settings)).perform(click());
+                onView(withId(R.id.settings_remove_account)).perform(click());
+                onView(withText(R.string.nc_settings_remove)).perform(click());
+                // The remove button must be clicked two times
+                onView(withId(R.id.settings_remove_account)).perform(click());
+                // And yes: The button must be clicked two times
+                onView(withText(R.string.nc_settings_remove)).perform(click());
+                onView(withText(R.string.nc_settings_remove)).perform(click());
+            } catch (Exception ie2) {
+                // ignore
+            } finally {
+                Thread.sleep(2000);
+            }
+
+        }
+
+        onView(withId(R.id.serverEntryTextInputEditText)).perform(typeText(baseUrl));
+        // Click on EditText's drawable right
+        onView(withContentDescription(R.string.nc_server_connect)).perform(click());
+
+        Thread.sleep(4000);
+
+        onWebView().forceJavascriptEnabled();
+
+        // click on login
+        onWebView()
+            .withElement(findElement(Locator.XPATH, "//p[@id='redirect-link']/a"))
+            .perform(webClick());
+
+        // username
+        onWebView()
+            .withElement(findElement(Locator.XPATH, "//input[@id='user']"))
+            .perform(DriverAtoms.webKeys(loginName));
+
+        // password
+        onWebView()
+            .withElement(findElement(Locator.XPATH, "//input[@id='password']"))
+            .perform(DriverAtoms.webKeys(password));
+
+        // click login
+        onWebView()
+            .withElement(findElement(Locator.XPATH, "//input[@id='submit-form']"))
+            .perform(webClick());
+
+        Thread.sleep(2000);
+
+        // grant access
+        onWebView()
+            .withElement(findElement(Locator.XPATH, "//input[@type='submit']"))
+            .perform(webClick());
+
+        Thread.sleep(5 * 1000);
+
+        onView(withId(R.id.switch_account_button)).perform(click());
+        onView(withId(R.id.user_name)).check(matches(withText("User One")));
+
+        activityScenario.onActivity(activity -> {
+            assertEquals(loginName, Objects.requireNonNull(activity.userUtils.getCurrentUser()).getUserId());
+        });
+
+    }
+
+
+}

+ 6 - 0
gradle.properties

@@ -2,6 +2,8 @@
 # Nextcloud Talk application
 #
 # @author Mario Danic
+# @author Tim Krüger
+# Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
 # Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
 #
 # This program is free software: you can redistribute it and/or modify
@@ -39,3 +41,7 @@ org.gradle.daemon=true
 org.gradle.configureondemand=true
 org.gradle.caching=true
 org.gradle.parallel=true
+
+NC_TEST_SERVER_BASEURL=http://server
+NC_TEST_SERVER_USERNAME=user1
+NC_TEST_SERVER_PASSWORD=user1