From 226590a1f44b0ded244fcc4bfb45cdee62f70ae7 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:03:04 -0700 Subject: Add a test for setting the host color to red --- .../java/org/connectbot/ConnectbotMatchers.java | 97 ++++++++++++++++++ .../java/org/connectbot/StartupTest.java | 108 ++++++++++----------- 2 files changed, 148 insertions(+), 57 deletions(-) create mode 100644 app/src/androidTest/java/org/connectbot/ConnectbotMatchers.java (limited to 'app/src') diff --git a/app/src/androidTest/java/org/connectbot/ConnectbotMatchers.java b/app/src/androidTest/java/org/connectbot/ConnectbotMatchers.java new file mode 100644 index 0000000..85a071d --- /dev/null +++ b/app/src/androidTest/java/org/connectbot/ConnectbotMatchers.java @@ -0,0 +1,97 @@ +package org.connectbot; + +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.test.espresso.matcher.BoundedMatcher; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import org.connectbot.bean.HostBean; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static org.hamcrest.CoreMatchers.allOf; + +public class ConnectbotMatchers { + /** + * Matches the nickname of a {@link HostBean}. + */ + @NonNull + public static Matcher withHostNickname(final String content) { + return new BoundedMatcher(HostBean.class) { + @Override + public boolean matchesSafely(HostBean host) { + return host.getNickname().matches(content); + } + + @Override + public void describeTo(Description description) { + description.appendText("with host nickname '" + content + "'"); + } + }; + } + + /** + * Matches the drawable state on an ImageView that is set with setImageState. + */ + @NonNull + public static Matcher withDrawableState(final int expectedState) { + return new TypeSafeMatcher() { + @Override + public boolean matchesSafely(View view) { + if (!(view instanceof ImageView)) { + return false; + } + + int[] states = view.getDrawableState(); + for (int state : states) { + if (state == expectedState) { + return true; + } + } + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("with drawable state '" + expectedState + "'"); + } + }; + } + + @NonNull + public static Matcher withTextColor(@ColorInt final int expectedColor) { + return new TypeSafeMatcher() { + @Override + public boolean matchesSafely(View view) { + if (!(view instanceof TextView)) { + return false; + } + + TextView tv = (TextView) view; + return tv.getCurrentTextColor() == expectedColor; + } + + @Override + public void describeTo(Description description) { + description.appendText("with color '" + Integer.toHexString(expectedColor) + "'"); + } + }; + } + + @NonNull + public static Matcher hostDisconnected() { + return hasDescendant(allOf(withId(android.R.id.icon), + withDrawableState(android.R.attr.state_expanded))); + } + + @NonNull + public static Matcher hostConnected() { + return hasDescendant(allOf(withId(android.R.id.icon), + withDrawableState(android.R.attr.state_checked))); + } +} diff --git a/app/src/androidTest/java/org/connectbot/StartupTest.java b/app/src/androidTest/java/org/connectbot/StartupTest.java index 0eb9c11..8025517 100644 --- a/app/src/androidTest/java/org/connectbot/StartupTest.java +++ b/app/src/androidTest/java/org/connectbot/StartupTest.java @@ -11,7 +11,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import android.content.Intent; +import android.content.res.Resources; +import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.intent.Intents; import android.support.test.espresso.matcher.BoundedMatcher; @@ -19,6 +23,7 @@ import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.view.View; import android.widget.ImageView; +import android.widget.TextView; import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; @@ -36,6 +41,10 @@ import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.connectbot.ConnectbotMatchers.hostConnected; +import static org.connectbot.ConnectbotMatchers.hostDisconnected; +import static org.connectbot.ConnectbotMatchers.withHostNickname; +import static org.connectbot.ConnectbotMatchers.withTextColor; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; @@ -87,10 +96,51 @@ public class StartupTest { .check(matches(hostDisconnected())); } + @Test + public void localConnectionCanChangeToRed() throws Exception { + startNewLocalConnectionAndGoBack("Local1"); + changeColor("Local1", R.color.red, R.string.color_red); + } + + /** + * Changes the color of {@code hostName} from the {@link HostListActivity} to the {@code color} + * from {@code R.color.[color]} with identifying {@code stringForColor} from + * {@code R.string.[colorname]}. + */ + private void changeColor(String hostName, @ColorRes int color, @StringRes int stringForColor) { + // Bring up the context menu. + onData(withHostNickname(hostName)).inAdapterView(withId(android.R.id.list)) + .perform(longClick()); + onView(withText(R.string.list_host_edit)).perform(click()); + + // Click on the color category and select the desired one. + onView(withText(R.string.hostpref_color_title)).perform(click()); + onView(withText(stringForColor)).perform(click()); + + // Go back to the host list. + onView(withText(R.string.hostpref_color_title)).perform(pressBack()); + + Resources res = InstrumentationRegistry.getTargetContext().getResources(); + onData(withHostNickname(hostName)).inAdapterView(withId(android.R.id.list)) + .check(matches(hasDescendant(allOf(withId(android.R.id.text1), + withTextColor(res.getColor(color)))))); + } + + private void startNewLocalConnectionAndGoBack(String name) { + startNewLocalConnection(name); + onView(withId(R.id.console_flip)).perform(closeSoftKeyboard(), pressBack()); + onData(withHostNickname(name)).inAdapterView(withId(android.R.id.list)) + .check(matches(isDisplayed())); + } + private void startNewLocalConnection() { + startNewLocalConnection("Local"); + } + + private void startNewLocalConnection(String name) { onView(withId(R.id.transport_selection)).perform(click()); onData(allOf(is(instanceOf(String.class)), is("local"))).perform(click()); - onView(withId(R.id.front_quickconnect)).perform(typeText("Local")); + onView(withId(R.id.front_quickconnect)).perform(typeText(name)); Intents.init(); try { @@ -103,60 +153,4 @@ public class StartupTest { onView(withId(R.id.console_flip)).check(matches( hasDescendant(allOf(isDisplayed(), withId(R.id.terminal_view))))); } - - /** - * Matches the nickname of a {@link HostBean}. - */ - public static Matcher withHostNickname(final String content) { - return new BoundedMatcher(HostBean.class) { - @Override - public boolean matchesSafely(HostBean host) { - return host.getNickname().matches(content); - } - - @Override - public void describeTo(Description description) { - description.appendText("with host nickname '" + content + "'"); - } - }; - } - - /** - * Matches the drawable state on an ImageView that is set with setImageState. - */ - public static Matcher withDrawableState(final int expectedState) { - return new TypeSafeMatcher() { - @Override - public boolean matchesSafely(View view) { - if (!(view instanceof ImageView)) { - return false; - } - - int[] states = view.getDrawableState(); - for (int state : states) { - if (state == expectedState) { - return true; - } - } - return false; - } - - @Override - public void describeTo(Description description) { - description.appendText("with drawable state '" + expectedState + "'"); - } - }; - } - - @NonNull - private Matcher hostDisconnected() { - return hasDescendant(allOf(withId(android.R.id.icon), - withDrawableState(android.R.attr.state_expanded))); - } - - @NonNull - private Matcher hostConnected() { - return hasDescendant(allOf(withId(android.R.id.icon), - withDrawableState(android.R.attr.state_checked))); - } } -- cgit v1.2.3 From 6765dc2863a29c2dbbd11c93c4f2445a580723c2 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:03:42 -0700 Subject: Reset host text entry when creating a new connection --- app/src/main/java/org/connectbot/HostListActivity.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'app/src') diff --git a/app/src/main/java/org/connectbot/HostListActivity.java b/app/src/main/java/org/connectbot/HostListActivity.java index 1fe634e..32eda82 100644 --- a/app/src/main/java/org/connectbot/HostListActivity.java +++ b/app/src/main/java/org/connectbot/HostListActivity.java @@ -475,6 +475,9 @@ public class HostListActivity extends ListActivity implements OnHostStatusChange intent.setData(uri); startActivity(intent); + // Clear the input box for the next entry. + quickconnect.setText(""); + return true; } -- cgit v1.2.3 From b4c5b9102d6c7dbc7e37c0f883a0980292e31be4 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:25:39 -0700 Subject: ActionBar can be null, so check first --- .../main/java/org/connectbot/ConsoleActivity.java | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/org/connectbot/ConsoleActivity.java b/app/src/main/java/org/connectbot/ConsoleActivity.java index 95d21d8..289cc2a 100644 --- a/app/src/main/java/org/connectbot/ConsoleActivity.java +++ b/app/src/main/java/org/connectbot/ConsoleActivity.java @@ -605,18 +605,20 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne actionBar = getSupportActionBar(); - actionBar.setDisplayHomeAsUpEnabled(true); - if (titleBarHide) { - actionBar.hide(); - } - actionBar.addOnMenuVisibilityListener(new ActionBar.OnMenuVisibilityListener() { - public void onMenuVisibilityChanged(boolean isVisible) { - inActionBarMenu = isVisible; - if (isVisible == false) { - hideEmulatedKeys(); - } + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + if (titleBarHide) { + actionBar.hide(); } - }); + actionBar.addOnMenuVisibilityListener(new ActionBar.OnMenuVisibilityListener() { + public void onMenuVisibilityChanged(boolean isVisible) { + inActionBarMenu = isVisible; + if (isVisible == false) { + hideEmulatedKeys(); + } + } + }); + } final HorizontalScrollView keyboardScroll = (HorizontalScrollView) findViewById(R.id.keyboard_hscroll); if (!hardKeyboard) { -- cgit v1.2.3 From 760841799903a0ef9459bee08857bb58a00b3db3 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:28:27 -0700 Subject: Factor out actionBar hiding method --- app/src/main/java/org/connectbot/ConsoleActivity.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/org/connectbot/ConsoleActivity.java b/app/src/main/java/org/connectbot/ConsoleActivity.java index 289cc2a..950e64a 100644 --- a/app/src/main/java/org/connectbot/ConsoleActivity.java +++ b/app/src/main/java/org/connectbot/ConsoleActivity.java @@ -154,7 +154,7 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne private ImageView mKeyboardButton; - private ActionBar actionBar; + @Nullable private ActionBar actionBar; private boolean inActionBarMenu = false; private boolean titleBarHide; @@ -380,7 +380,11 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne autoHideEmulatedKeys(); terminal.bridge.tryKeyVibrate(); - if (titleBarHide) { + hideActionBarIfRequested(); + } + + private void hideActionBarIfRequested() { + if (titleBarHide && actionBar != null) { actionBar.hide(); } } @@ -436,9 +440,7 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne keyboardGroup.startAnimation(keyboard_fade_out); keyboardGroup.setVisibility(View.GONE); - if (titleBarHide) { - actionBar.hide(); - } + hideActionBarIfRequested(); keyboardGroupHider = null; } }; @@ -449,9 +451,7 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne if (keyboardGroupHider != null) handler.removeCallbacks(keyboardGroupHider); keyboardGroup.setVisibility(View.GONE); - if (titleBarHide) { - actionBar.hide(); - } + hideActionBarIfRequested(); } @Override -- cgit v1.2.3 From 50d2cb33beff7d542332eb998ddb9854c96894a6 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:29:04 -0700 Subject: Use a style for the host list text coloring Fixes #191 --- .../main/java/org/connectbot/HostListActivity.java | 35 +++++++++++----------- app/src/main/res/values-v11/styles.xml | 12 ++++++-- app/src/main/res/values/styles.xml | 24 +++++++++++++++ 3 files changed, 52 insertions(+), 19 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/org/connectbot/HostListActivity.java b/app/src/main/java/org/connectbot/HostListActivity.java index 32eda82..0e6fa3e 100644 --- a/app/src/main/java/org/connectbot/HostListActivity.java +++ b/app/src/main/java/org/connectbot/HostListActivity.java @@ -43,6 +43,7 @@ import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.preference.PreferenceManager; +import android.support.annotation.StyleRes; import android.text.format.DateUtils; import android.util.Log; import android.view.ContextMenu; @@ -620,26 +621,26 @@ public class HostListActivity extends ListActivity implements OnHostStatusChange break; } - ColorStateList chosen = null; - if (HostDatabase.COLOR_RED.equals(host.getColor())) - chosen = this.red; - else if (HostDatabase.COLOR_GREEN.equals(host.getColor())) - chosen = this.green; - else if (HostDatabase.COLOR_BLUE.equals(host.getColor())) - chosen = this.blue; - - Context context = convertView.getContext(); - - if (chosen != null) { - // set color normally if not selected - holder.nickname.setTextColor(chosen); - holder.caption.setTextColor(chosen); + @StyleRes final int chosenStyleFirstLine; + @StyleRes final int chosenStyleSecondLine; + if (HostDatabase.COLOR_RED.equals(host.getColor())) { + chosenStyleFirstLine = R.style.ListItemFirstLineText_Red; + chosenStyleSecondLine = R.style.ListItemSecondLineText_Red; + } else if (HostDatabase.COLOR_GREEN.equals(host.getColor())) { + chosenStyleFirstLine = R.style.ListItemFirstLineText_Green; + chosenStyleSecondLine = R.style.ListItemSecondLineText_Green; + } else if (HostDatabase.COLOR_BLUE.equals(host.getColor())) { + chosenStyleFirstLine = R.style.ListItemFirstLineText_Blue; + chosenStyleSecondLine = R.style.ListItemSecondLineText_Blue; } else { - // selected, so revert back to default black text - holder.nickname.setTextAppearance(context, android.R.style.TextAppearance_Large); - holder.caption.setTextAppearance(context, android.R.style.TextAppearance_Small); + chosenStyleFirstLine = R.style.ListItemFirstLineText; + chosenStyleSecondLine = R.style.ListItemSecondLineText; } + holder.nickname.setTextAppearance(chosenStyleFirstLine); + holder.caption.setTextAppearance(chosenStyleSecondLine); + + Context context = convertView.getContext(); CharSequence nice = context.getString(R.string.bind_never); if (host.getLastConnect() > 0) { nice = DateUtils.getRelativeTimeSpanString(host.getLastConnect() * 1000); diff --git a/app/src/main/res/values-v11/styles.xml b/app/src/main/res/values-v11/styles.xml index 9f8d6a0..8522aae 100644 --- a/app/src/main/res/values-v11/styles.xml +++ b/app/src/main/res/values-v11/styles.xml @@ -17,6 +17,14 @@ */ --> - + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index a850d38..13a424f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -39,4 +39,28 @@ ?android:textColorSecondary 14sp + + + + + + + + + + + + -- cgit v1.2.3 From 437fd1038cfddc6932650735f1a2bc40677d55b9 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:40:29 -0700 Subject: Re-indent host item layout and add sample text --- app/src/main/res/layout/item_host.xml | 101 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 50 deletions(-) (limited to 'app/src') diff --git a/app/src/main/res/layout/item_host.xml b/app/src/main/res/layout/item_host.xml index 56c3d34..8c9f9fc 100644 --- a/app/src/main/res/layout/item_host.xml +++ b/app/src/main/res/layout/item_host.xml @@ -17,60 +17,61 @@ --> + android:id="@android:id/content" + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:minHeight="72dp" + > - + - + - + - + - + -- cgit v1.2.3 From dfd58000537ea4ee49d6eaf07e59f62fd37d6f04 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:44:51 -0700 Subject: URI for ConsoleActivity can be null If we're rotating before we finished, the URI will be null. Don't bother to set the requested bridge name. --- app/src/main/java/org/connectbot/ConsoleActivity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'app/src') diff --git a/app/src/main/java/org/connectbot/ConsoleActivity.java b/app/src/main/java/org/connectbot/ConsoleActivity.java index 950e64a..7ed9076 100644 --- a/app/src/main/java/org/connectbot/ConsoleActivity.java +++ b/app/src/main/java/org/connectbot/ConsoleActivity.java @@ -488,7 +488,10 @@ public class ConsoleActivity extends AppCompatActivity implements BridgeDisconne if (icicle == null) { requested = getIntent().getData(); } else { - requested = Uri.parse(icicle.getString(STATE_SELECTED_URI)); + String uri = icicle.getString(STATE_SELECTED_URI); + if (uri != null) { + requested = Uri.parse(uri); + } } inflater = LayoutInflater.from(this); -- cgit v1.2.3 From f7f760e0faab25e735d6b4eca186c786ac5be682 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 5 Sep 2015 22:59:18 -0700 Subject: Add test for deleting host --- app/src/androidTest/java/org/connectbot/StartupTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'app/src') diff --git a/app/src/androidTest/java/org/connectbot/StartupTest.java b/app/src/androidTest/java/org/connectbot/StartupTest.java index 8025517..a60d00e 100644 --- a/app/src/androidTest/java/org/connectbot/StartupTest.java +++ b/app/src/androidTest/java/org/connectbot/StartupTest.java @@ -34,6 +34,7 @@ import static android.support.test.espresso.action.ViewActions.pressBack; import static android.support.test.espresso.action.ViewActions.pressImeActionButton; import static android.support.test.espresso.action.ViewActions.pressMenuKey; import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.intent.Intents.intended; import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; @@ -96,6 +97,15 @@ public class StartupTest { .check(matches(hostDisconnected())); } + @Test + public void localConnectionCanDelete() { + startNewLocalConnectionAndGoBack("Local"); + onData(withHostNickname("Local")).inAdapterView(withId(android.R.id.list)) + .perform(longClick()); + onView(withText(R.string.list_host_delete)).perform(click()); + onView(withText(R.string.delete_pos)).perform(click()); + } + @Test public void localConnectionCanChangeToRed() throws Exception { startNewLocalConnectionAndGoBack("Local1"); -- cgit v1.2.3