forked from nextcloud/android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5716e23
commit 7548fe2
Showing
26 changed files
with
1,279 additions
and
13 deletions.
There are no files selected for viewing
115 changes: 115 additions & 0 deletions
115
app/src/androidTest/java/com/nmc/android/ui/ClickableSpanTestHelper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package com.nmc.android.ui | ||
|
||
import android.text.Spannable | ||
import android.text.style.ClickableSpan | ||
import android.view.View | ||
import android.widget.TextView | ||
import androidx.test.espresso.UiController | ||
import androidx.test.espresso.ViewAction | ||
import androidx.test.espresso.ViewInteraction | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.matcher.BoundedMatcher | ||
import androidx.test.espresso.matcher.ViewMatchers | ||
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom | ||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed | ||
import org.hamcrest.Description | ||
import org.hamcrest.Matcher | ||
|
||
object ClickableSpanTestHelper { | ||
|
||
/** | ||
* method to get clickable span form a text view | ||
* example: val clickableSpan = getClickableSpan("Link text", onView(withId(R.id.text_id))) | ||
*/ | ||
fun getClickableSpan(spanText: String, matcher: ViewInteraction?): ClickableSpan? { | ||
val clickableSpans = arrayOf<ClickableSpan?>(null) | ||
|
||
// Get the SpannableString from the TextView | ||
matcher?.check(matches(isDisplayed())) | ||
matcher?.perform(object : ViewAction { | ||
override fun getConstraints(): Matcher<View> { | ||
return isAssignableFrom(TextView::class.java) | ||
} | ||
|
||
override fun getDescription(): String { | ||
return "get text from TextView" | ||
} | ||
|
||
override fun perform(uiController: UiController, view: View) { | ||
val textView = view as TextView | ||
val text = textView.text | ||
if (text is Spannable) { | ||
val spans = text.getSpans( | ||
0, text.length, | ||
ClickableSpan::class.java | ||
) | ||
for (span in spans) { | ||
val start = text.getSpanStart(span) | ||
val end = text.getSpanEnd(span) | ||
val spanString = text.subSequence(start, end).toString() | ||
if (spanString == spanText) { | ||
clickableSpans[0] = span | ||
return | ||
} | ||
} | ||
} | ||
throw java.lang.RuntimeException("ClickableSpan not found") | ||
} | ||
}) | ||
return clickableSpans[0] | ||
} | ||
|
||
/** | ||
* perform click on the spanned string | ||
* @link getClickableSpan() method to get clickable span | ||
*/ | ||
fun performClickSpan(clickableSpan: ClickableSpan?): ViewAction { | ||
return object : ViewAction { | ||
override fun getConstraints(): Matcher<View> { | ||
return ViewMatchers.isAssignableFrom(TextView::class.java) | ||
} | ||
|
||
override fun getDescription(): String { | ||
return "clicking on a span" | ||
} | ||
|
||
override fun perform(uiController: UiController, view: View) { | ||
val textView = view as TextView | ||
val spannable = textView.text as Spannable | ||
val spans = spannable.getSpans( | ||
0, spannable.length, | ||
ClickableSpan::class.java | ||
) | ||
for (span in spans) { | ||
if (span == clickableSpan) { | ||
span.onClick(textView) | ||
return | ||
} | ||
} | ||
throw RuntimeException("ClickableSpan not found") | ||
} | ||
} | ||
} | ||
|
||
fun verifyClickSpan(clickableSpan: ClickableSpan?): Matcher<View?> { | ||
return object : BoundedMatcher<View?, TextView>(TextView::class.java) { | ||
override fun describeTo(description: Description) { | ||
description.appendText("clickable span") | ||
} | ||
|
||
override fun matchesSafely(textView: TextView): Boolean { | ||
val spannable = textView.text as Spannable | ||
val spans = spannable.getSpans( | ||
0, spannable.length, | ||
ClickableSpan::class.java | ||
) | ||
for (span in spans) { | ||
if (span == clickableSpan) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
} | ||
} | ||
} |
109 changes: 109 additions & 0 deletions
109
app/src/androidTest/java/com/nmc/android/ui/LoginPrivacySettingsActivityIT.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package com.nmc.android.ui | ||
|
||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.Espresso.pressBack | ||
import androidx.test.espresso.action.ViewActions.click | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.intent.Intents | ||
import androidx.test.espresso.intent.Intents.intended | ||
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent | ||
import androidx.test.espresso.matcher.ViewMatchers.isClickable | ||
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed | ||
import androidx.test.espresso.matcher.ViewMatchers.withId | ||
import androidx.test.ext.junit.rules.ActivityScenarioRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import com.nextcloud.client.preferences.AppPreferencesImpl | ||
import com.nmc.android.ui.ClickableSpanTestHelper.getClickableSpan | ||
import com.owncloud.android.AbstractIT | ||
import com.owncloud.android.R | ||
import com.owncloud.android.ui.activity.ExternalSiteWebView | ||
import com.owncloud.android.ui.activity.FileDisplayActivity | ||
import org.junit.Assert.* | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class LoginPrivacySettingsActivityIT : AbstractIT() { | ||
|
||
@get:Rule | ||
val activityRule = ActivityScenarioRule(LoginPrivacySettingsActivity::class.java) | ||
|
||
@Test | ||
fun verifyNothingHappensOnBackPress() { | ||
pressBack() | ||
shortSleep() | ||
|
||
//check any one view to check the activity is not destroyed | ||
onView(withId(R.id.tv_privacy_setting_title)).check(matches(isCompletelyDisplayed())) | ||
} | ||
|
||
@Test | ||
fun verifyUIElements() { | ||
onView(withId(R.id.ic_privacy)).check(matches(isCompletelyDisplayed())) | ||
|
||
onView(withId(R.id.tv_privacy_setting_title)).check(matches(isCompletelyDisplayed())) | ||
|
||
onView(withId(R.id.tv_login_privacy_intro_text)).check(matches(isCompletelyDisplayed())) | ||
|
||
onView(withId(R.id.privacy_accept_btn)).check(matches(isCompletelyDisplayed())) | ||
onView(withId(R.id.privacy_accept_btn)).check(matches(isClickable())) | ||
} | ||
|
||
@Test | ||
fun verifyAcceptButtonRedirection() { | ||
Intents.init() | ||
onView(withId(R.id.privacy_accept_btn)).perform(click()) | ||
|
||
//check if the policy action saved correct --> 2 for Accept action | ||
assertEquals(2, AppPreferencesImpl.fromContext(targetContext).privacyPolicyAction) | ||
|
||
intended(hasComponent(FileDisplayActivity::class.java.canonicalName)) | ||
Intents.release() | ||
} | ||
|
||
@Test | ||
fun verifySettingsTextClick() { | ||
Intents.init() | ||
val settingsClickableSpan = getClickableSpan("Settings", onView(withId(R.id.tv_login_privacy_intro_text))) | ||
onView(withId(R.id.tv_login_privacy_intro_text)).perform( | ||
ClickableSpanTestHelper.performClickSpan( | ||
settingsClickableSpan | ||
) | ||
) | ||
intended(hasComponent(PrivacySettingsActivity::class.java.canonicalName)) | ||
Intents.release() | ||
} | ||
|
||
@Test | ||
fun verifyPrivacyPolicyTextClick() { | ||
Intents.init() | ||
val privacyPolicyClickableSpan = | ||
getClickableSpan("Privacy Policy", onView(withId(R.id.tv_login_privacy_intro_text))) | ||
onView(withId(R.id.tv_login_privacy_intro_text)).perform( | ||
ClickableSpanTestHelper.performClickSpan( | ||
privacyPolicyClickableSpan | ||
) | ||
) | ||
intended(hasComponent(ExternalSiteWebView::class.java.canonicalName)) | ||
Intents.release() | ||
} | ||
|
||
@Test | ||
fun verifyRejectTextClick() { | ||
Intents.init() | ||
val rejectClickableSpan = | ||
getClickableSpan("reject", onView(withId(R.id.tv_login_privacy_intro_text))) | ||
onView(withId(R.id.tv_login_privacy_intro_text)).perform( | ||
ClickableSpanTestHelper.performClickSpan( | ||
rejectClickableSpan | ||
) | ||
) | ||
|
||
//check if the policy action saved correct --> 1 for Reject action | ||
assertEquals(1, AppPreferencesImpl.fromContext(targetContext).privacyPolicyAction) | ||
|
||
intended(hasComponent(FileDisplayActivity::class.java.canonicalName)) | ||
Intents.release() | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
app/src/androidTest/java/com/nmc/android/ui/PrivacySettingsActivityIT.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.nmc.android.ui | ||
|
||
import android.content.Intent | ||
import androidx.test.core.app.ActivityScenario | ||
import androidx.test.core.app.launchActivity | ||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.action.ViewActions.click | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.matcher.ViewMatchers.isChecked | ||
import androidx.test.espresso.matcher.ViewMatchers.isClickable | ||
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed | ||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed | ||
import androidx.test.espresso.matcher.ViewMatchers.isEnabled | ||
import androidx.test.espresso.matcher.ViewMatchers.withId | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import com.owncloud.android.AbstractIT | ||
import com.owncloud.android.R | ||
import org.hamcrest.CoreMatchers.not | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class PrivacySettingsActivityIT : AbstractIT() { | ||
|
||
private fun getIntent(showSettingsButton: Boolean): Intent = | ||
Intent(targetContext, PrivacySettingsActivity::class.java) | ||
.putExtra("show_settings_button", showSettingsButton) | ||
|
||
lateinit var activityRule: ActivityScenario<PrivacySettingsActivity> | ||
|
||
@Before | ||
fun setUp() { | ||
activityRule = launchActivity(getIntent(false)) | ||
} | ||
|
||
@Test | ||
fun verifyUIElements() { | ||
onView(withId(R.id.tv_privacy_intro_text)).check(matches(isCompletelyDisplayed())) | ||
|
||
onView(withId(R.id.switch_data_collection)).check(matches(isCompletelyDisplayed())) | ||
onView(withId(R.id.switch_data_collection)).check(matches(not(isEnabled()))) | ||
onView(withId(R.id.switch_data_collection)).check(matches(isChecked())) | ||
|
||
onView(withId(R.id.switch_data_analysis)).check(matches(isCompletelyDisplayed())) | ||
onView(withId(R.id.switch_data_analysis)).check(matches(isEnabled())) | ||
//by-default the analysis switch will be checked as per #AppPreferences.isDataAnalysisEnabled will return true | ||
onView(withId(R.id.switch_data_analysis)).check(matches(isChecked())) | ||
onView(withId(R.id.switch_data_analysis)).check(matches(isClickable())) | ||
|
||
onView(withId(R.id.privacy_save_settings_btn)).check(matches(not(isDisplayed()))) | ||
} | ||
|
||
@Test | ||
fun verifyDataCollectionSwitchToggle() { | ||
//since this button is disabled performing click operation should do nothing | ||
//and switch will be in checked state only | ||
onView(withId(R.id.switch_data_collection)).perform(click()) | ||
onView(withId(R.id.switch_data_collection)).check(matches(isChecked())) | ||
|
||
onView(withId(R.id.switch_data_collection)).perform(click()) | ||
onView(withId(R.id.switch_data_collection)).check(matches(isChecked())) | ||
} | ||
|
||
@Test | ||
fun verifyDataAnalysisSwitchToggle() { | ||
onView(withId(R.id.switch_data_analysis)).perform(click()) | ||
onView(withId(R.id.switch_data_analysis)).check(matches(not(isChecked()))) | ||
|
||
onView(withId(R.id.switch_data_analysis)).perform(click()) | ||
onView(withId(R.id.switch_data_analysis)).check(matches(isChecked())) | ||
} | ||
|
||
@Test | ||
fun verifySaveSettingsButton() { | ||
//button not shown on the basis of extras passed to intent | ||
onView(withId(R.id.privacy_save_settings_btn)).check(matches(not(isDisplayed()))) | ||
//close the activity already open | ||
activityRule.close() | ||
|
||
//launch activity with extras as true | ||
activityRule = launchActivity(getIntent(true)) | ||
//button will be shown if extras is true | ||
onView(withId(R.id.privacy_save_settings_btn)).check(matches(isDisplayed())) | ||
} | ||
|
||
@After | ||
fun tearDown() { | ||
activityRule.close() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.