mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-24 02:12:15 -05:00
Add end-to-end tests using Espresso
This commit is contained in:
parent
a725099693
commit
854b1b3ffc
21
build.gradle
21
build.gradle
@ -29,6 +29,25 @@ dependencies {
|
|||||||
compile 'com.beetstra.jutf7:jutf7:1.0.0'
|
compile 'com.beetstra.jutf7:jutf7:1.0.0'
|
||||||
compile 'com.android.support:support-v13:19.1.0'
|
compile 'com.android.support:support-v13:19.1.0'
|
||||||
compile 'net.sourceforge.htmlcleaner:htmlcleaner:2.2'
|
compile 'net.sourceforge.htmlcleaner:htmlcleaner:2.2'
|
||||||
|
|
||||||
|
androidTestCompile ('com.jakewharton.espresso:espresso:1.1-r3' ) {
|
||||||
|
// Note: some of these exclusions may become necessary. See the
|
||||||
|
// github site https://github.com/JakeWharton/double-espresso
|
||||||
|
// exclude group: 'com.squareup.dagger'
|
||||||
|
// exclude group: 'javax.inject'
|
||||||
|
// exclude group: 'javax.annotation'
|
||||||
|
// exclude group: 'com.google.guava'
|
||||||
|
exclude group: 'com.google.code.findbugs'
|
||||||
|
// exclude group: 'org.hamcrest'
|
||||||
|
}
|
||||||
|
|
||||||
|
androidTestCompile("com.icegreen:greenmail:1.3.1b") {
|
||||||
|
// Use a better, later version
|
||||||
|
exclude group: "javax.mail"
|
||||||
|
}
|
||||||
|
|
||||||
|
// this version avoids some "Ignoring InnerClasses attribute for an anonymous inner class" warnings
|
||||||
|
androidTestCompile "javax.mail:javax.mail-api:1.5.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.preDexLibs = !project.hasProperty('disablePreDex')
|
project.ext.preDexLibs = !project.hasProperty('disablePreDex')
|
||||||
@ -49,6 +68,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 17
|
targetSdkVersion 17
|
||||||
|
testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
dexOptions {
|
dexOptions {
|
||||||
@ -89,6 +109,7 @@ android {
|
|||||||
exclude 'META-INF/DEPENDENCIES'
|
exclude 'META-INF/DEPENDENCIES'
|
||||||
exclude 'META-INF/LICENSE'
|
exclude 'META-INF/LICENSE'
|
||||||
exclude 'META-INF/LICENSE.txt'
|
exclude 'META-INF/LICENSE.txt'
|
||||||
|
exclude 'LICENSE.txt'
|
||||||
exclude 'META-INF/NOTICE'
|
exclude 'META-INF/NOTICE'
|
||||||
exclude 'META-INF/NOTICE.txt'
|
exclude 'META-INF/NOTICE.txt'
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,15 @@
|
|||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="1.0">
|
android:versionName="1.0">
|
||||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
|
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
|
||||||
|
|
||||||
|
<!-- Allow debug trace to be written -->
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<!-- We add an application tag here just so that we can indicate that
|
<!-- We add an application tag here just so that we can indicate that
|
||||||
this package needs to link against the android.test library,
|
this package needs to link against the android.test library,
|
||||||
which is needed when building test cases. -->
|
which is needed when building test cases. -->
|
||||||
<application>
|
<application>
|
||||||
<uses-library android:name="android.test.runner" />
|
<uses-library android:name="android.test.runner" />
|
||||||
</application>
|
</application>
|
||||||
<!--
|
|
||||||
This declares that this application uses the instrumentation test runner targeting
|
|
||||||
the package of com.fsck.k9. To run the tests use the command:
|
|
||||||
"adb shell am instrument -w com.fsck.k9.tests/com.zutubi.android.junitreport.JUnitReportTestRunner"
|
|
||||||
-->
|
|
||||||
<instrumentation android:name="com.zutubi.android.junitreport.JUnitReportTestRunner"
|
|
||||||
android:targetPackage="com.fsck.k9"
|
|
||||||
android:label="Tests for com.fsck.k9"/>
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.fsck.k9.endtoend;
|
||||||
|
|
||||||
|
import com.fsck.k9.activity.setup.WelcomeMessage;
|
||||||
|
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new IMAP account via the getting started flow.
|
||||||
|
*/
|
||||||
|
public class A000_WelcomeAndSetupAccountIntegrationTest extends AbstractEndToEndTest<WelcomeMessage> {
|
||||||
|
|
||||||
|
public A000_WelcomeAndSetupAccountIntegrationTest() {
|
||||||
|
super(WelcomeMessage.class, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateAccount() throws Exception {
|
||||||
|
new AccountSetupFlow(this).setupAccountFromWelcomePage(new WelcomeMessagePage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateSecondAccount() throws Exception {
|
||||||
|
new AccountSetupFlow(this).setupAccountFromWelcomePage(new WelcomeMessagePage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.fsck.k9.endtoend;
|
||||||
|
|
||||||
|
import com.fsck.k9.activity.Accounts;
|
||||||
|
import com.fsck.k9.endtoend.framework.AccountForTest;
|
||||||
|
import com.fsck.k9.endtoend.framework.ApplicationState;
|
||||||
|
import com.fsck.k9.endtoend.pages.AccountsPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and removes accounts.
|
||||||
|
*
|
||||||
|
* Because of the way K-9 shows the start page, there must already be two accounts
|
||||||
|
* in existence for this test to work.
|
||||||
|
*/
|
||||||
|
public class A010_AccountIntegrationTest extends AbstractEndToEndTest<Accounts>{
|
||||||
|
|
||||||
|
public A010_AccountIntegrationTest() {
|
||||||
|
super(Accounts.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateAccountDirectly() throws Exception {
|
||||||
|
new AccountSetupFlow(this).setupAccountFromAccountsPage(new AccountsPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteAccount() {
|
||||||
|
|
||||||
|
AccountsPage accountsPage = new AccountsPage();
|
||||||
|
|
||||||
|
AccountForTest accountForTest = ApplicationState.getInstance().accounts.get(0);
|
||||||
|
accountsPage.assertAccountExists(accountForTest.description);
|
||||||
|
|
||||||
|
accountsPage.clickLongOnAccount(accountForTest);
|
||||||
|
|
||||||
|
accountsPage.clickRemoveInAccountMenu();
|
||||||
|
|
||||||
|
accountsPage.clickOK();
|
||||||
|
|
||||||
|
accountsPage.assertAccountDoesNotExist(accountForTest.description);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
60
tests/src/com/fsck/k9/endtoend/AbstractEndToEndTest.java
Normal file
60
tests/src/com/fsck/k9/endtoend/AbstractEndToEndTest.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package com.fsck.k9.endtoend;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.endtoend.framework.ApplicationState;
|
||||||
|
import com.fsck.k9.endtoend.framework.StubMailServer;
|
||||||
|
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
||||||
|
import com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
|
||||||
|
public abstract class AbstractEndToEndTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
|
||||||
|
|
||||||
|
private ApplicationState state = ApplicationState.getInstance();
|
||||||
|
private final boolean bypassWelcome;
|
||||||
|
|
||||||
|
public AbstractEndToEndTest(Class<T> activityClass) {
|
||||||
|
this(activityClass, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractEndToEndTest(Class<T> activityClass, boolean bypassWelcome) {
|
||||||
|
super(activityClass);
|
||||||
|
this.bypassWelcome = bypassWelcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
getActivity();
|
||||||
|
|
||||||
|
if (bypassWelcome) {
|
||||||
|
bypassWelcomeScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bypassWelcomeScreen() {
|
||||||
|
try {
|
||||||
|
onView(withId(R.id.welcome_message)).check(ViewAssertions.doesNotExist());
|
||||||
|
} catch (AssertionFailedError ex) {
|
||||||
|
/*
|
||||||
|
* The view doesn't NOT exist == the view exists, and needs to be bypassed!
|
||||||
|
*/
|
||||||
|
Log.d(getClass().getName(), "Bypassing welcome");
|
||||||
|
new AccountSetupFlow(this).setupAccountFromWelcomePage(new WelcomeMessagePage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StubMailServer setupMailServer() {
|
||||||
|
if (null == state.stubMailServer) {
|
||||||
|
state.stubMailServer = new StubMailServer();
|
||||||
|
}
|
||||||
|
return state.stubMailServer;
|
||||||
|
}
|
||||||
|
}
|
98
tests/src/com/fsck/k9/endtoend/AccountSetupFlow.java
Normal file
98
tests/src/com/fsck/k9/endtoend/AccountSetupFlow.java
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package com.fsck.k9.endtoend;
|
||||||
|
|
||||||
|
import com.fsck.k9.endtoend.framework.AccountForTest;
|
||||||
|
import com.fsck.k9.endtoend.framework.ApplicationState;
|
||||||
|
import com.fsck.k9.endtoend.framework.StubMailServer;
|
||||||
|
import com.fsck.k9.endtoend.framework.UserForImap;
|
||||||
|
import com.fsck.k9.endtoend.pages.AccountOptionsPage;
|
||||||
|
import com.fsck.k9.endtoend.pages.AccountSetupNamesPage;
|
||||||
|
import com.fsck.k9.endtoend.pages.AccountSetupPage;
|
||||||
|
import com.fsck.k9.endtoend.pages.AccountTypePage;
|
||||||
|
import com.fsck.k9.endtoend.pages.AccountsPage;
|
||||||
|
import com.fsck.k9.endtoend.pages.IncomingServerSettingsPage;
|
||||||
|
import com.fsck.k9.endtoend.pages.OutgoingServerSettingsPage;
|
||||||
|
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
||||||
|
import com.fsck.k9.mail.ConnectionSecurity;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulated the steps required to set up a new mail account.
|
||||||
|
*/
|
||||||
|
public class AccountSetupFlow {
|
||||||
|
|
||||||
|
static final String ACCOUNT_NAME = "sendAndReceiveTestName";
|
||||||
|
|
||||||
|
private final AbstractEndToEndTest test;
|
||||||
|
|
||||||
|
public AccountSetupFlow(AbstractEndToEndTest test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountsPage setupAccountFromWelcomePage(WelcomeMessagePage welcomeMessagePage) {
|
||||||
|
AccountSetupPage accountSetupPage = welcomeMessagePage.clickNext();
|
||||||
|
return setupAccountFromSetupNewAccountActivity(accountSetupPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountsPage setupAccountFromAccountsPage(AccountsPage accountPage) {
|
||||||
|
AccountSetupPage accountSetupPage = accountPage.clickAddNewAccount();
|
||||||
|
return setupAccountFromSetupNewAccountActivity(accountSetupPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountsPage setupAccountFromSetupNewAccountActivity(AccountSetupPage accountSetupPage) {
|
||||||
|
AccountTypePage accountTypePage = fillInCredentialsAndClickManualSetup(accountSetupPage);
|
||||||
|
|
||||||
|
IncomingServerSettingsPage incoming = accountTypePage.clickImap();
|
||||||
|
|
||||||
|
StubMailServer stubMailServer = test.setupMailServer();
|
||||||
|
|
||||||
|
OutgoingServerSettingsPage outgoing = setupIncomingServerAndClickNext(incoming, stubMailServer);
|
||||||
|
|
||||||
|
AccountOptionsPage accountOptionsPage = setupOutgoingServerAndClickNext(outgoing, stubMailServer);
|
||||||
|
|
||||||
|
AccountSetupNamesPage accountSetupNamesPage = accountOptionsPage.clickNext();
|
||||||
|
|
||||||
|
String accountDescription = tempAccountName();
|
||||||
|
accountSetupNamesPage.inputAccountDescription(accountDescription);
|
||||||
|
accountSetupNamesPage.inputAccountName(ACCOUNT_NAME);
|
||||||
|
|
||||||
|
AccountsPage accountsPage = accountSetupNamesPage.clickDone();
|
||||||
|
|
||||||
|
accountsPage.assertAccountExists(accountDescription);
|
||||||
|
|
||||||
|
ApplicationState.getInstance().accounts.add(new AccountForTest(ACCOUNT_NAME, accountDescription, stubMailServer));
|
||||||
|
|
||||||
|
return accountsPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String tempAccountName() {
|
||||||
|
return "sendAndReceiveTest-" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
private AccountTypePage fillInCredentialsAndClickManualSetup(AccountSetupPage page) {
|
||||||
|
return page
|
||||||
|
.inputEmailAddress(UserForImap.TEST_USER.emailAddress)
|
||||||
|
.inputPassword(UserForImap.TEST_USER.password)
|
||||||
|
.clickManualSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AccountOptionsPage setupOutgoingServerAndClickNext(OutgoingServerSettingsPage page, StubMailServer stubMailServer) {
|
||||||
|
return page
|
||||||
|
.inputSmtpServer(stubMailServer.getSmtpBindAddress())
|
||||||
|
.inputSmtpSecurity(ConnectionSecurity.NONE)
|
||||||
|
.inputPort(stubMailServer.getSmtpPort())
|
||||||
|
.inputRequireSignIn(false)
|
||||||
|
.clickNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private OutgoingServerSettingsPage setupIncomingServerAndClickNext(IncomingServerSettingsPage page, StubMailServer stubMailServer) {
|
||||||
|
return page
|
||||||
|
.inputImapServer(stubMailServer.getImapBindAddress())
|
||||||
|
.inputImapSecurity(ConnectionSecurity.NONE)
|
||||||
|
.inputPort(stubMailServer.getImapPort())
|
||||||
|
.inputUsername(UserForImap.TEST_USER.loginUsername)
|
||||||
|
.clickNext();
|
||||||
|
}
|
||||||
|
}
|
17
tests/src/com/fsck/k9/endtoend/framework/AccountForTest.java
Normal file
17
tests/src/com/fsck/k9/endtoend/framework/AccountForTest.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.fsck.k9.endtoend.framework;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An account that was added by a test.
|
||||||
|
*/
|
||||||
|
public class AccountForTest {
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
public final String description;
|
||||||
|
public final StubMailServer stubMailServer;
|
||||||
|
|
||||||
|
public AccountForTest(String name, String description, StubMailServer stubMailServer) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.stubMailServer = stubMailServer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.fsck.k9.endtoend.framework;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the state of the application from the point of view of end-to-end tests.
|
||||||
|
*/
|
||||||
|
public class ApplicationState {
|
||||||
|
|
||||||
|
private static final ApplicationState state = new ApplicationState();
|
||||||
|
|
||||||
|
public final List<AccountForTest> accounts = new ArrayList<AccountForTest>();
|
||||||
|
|
||||||
|
public StubMailServer stubMailServer;
|
||||||
|
|
||||||
|
public static ApplicationState getInstance() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
41
tests/src/com/fsck/k9/endtoend/framework/StubMailServer.java
Normal file
41
tests/src/com/fsck/k9/endtoend/framework/StubMailServer.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package com.fsck.k9.endtoend.framework;
|
||||||
|
|
||||||
|
import com.icegreen.greenmail.util.GreenMail;
|
||||||
|
import com.icegreen.greenmail.util.ServerSetup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration and management of a pair of stub servers for use by an account.
|
||||||
|
*/
|
||||||
|
public class StubMailServer {
|
||||||
|
private static final ServerSetup IMAP_SERVER_SETUP = new ServerSetup(10143, "127.0.0.2", ServerSetup.PROTOCOL_IMAP);
|
||||||
|
private static final ServerSetup SMTP_SERVER_SETUP = new ServerSetup(10587, "127.0.0.2", ServerSetup.PROTOCOL_SMTP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub server that speaks SMTP, IMAP etc., that K-9 can talk to.
|
||||||
|
*/
|
||||||
|
private GreenMail greenmail;
|
||||||
|
|
||||||
|
public StubMailServer() {
|
||||||
|
|
||||||
|
greenmail = new GreenMail(new ServerSetup[]{IMAP_SERVER_SETUP, SMTP_SERVER_SETUP});
|
||||||
|
greenmail.setUser(UserForImap.TEST_USER.emailAddress, UserForImap.TEST_USER.loginUsername, UserForImap.TEST_USER.password);
|
||||||
|
greenmail.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmtpBindAddress() {
|
||||||
|
return SMTP_SERVER_SETUP.getBindAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSmtpPort() {
|
||||||
|
return SMTP_SERVER_SETUP.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImapBindAddress() {
|
||||||
|
return IMAP_SERVER_SETUP.getBindAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getImapPort() {
|
||||||
|
return IMAP_SERVER_SETUP.getPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
tests/src/com/fsck/k9/endtoend/framework/UserForImap.java
Normal file
19
tests/src/com/fsck/k9/endtoend/framework/UserForImap.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.fsck.k9.endtoend.framework;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credentials for the stub IMAP/SMTP server
|
||||||
|
*/
|
||||||
|
public class UserForImap {
|
||||||
|
|
||||||
|
public static final UserForImap TEST_USER = new UserForImap("test-username", "test-password", "test-email@example.com");
|
||||||
|
|
||||||
|
public final String loginUsername;
|
||||||
|
public final String password;
|
||||||
|
public final String emailAddress;
|
||||||
|
|
||||||
|
private UserForImap(String loginUsername, String password, String emailAddress) {
|
||||||
|
this.loginUsername = loginUsername;
|
||||||
|
this.password = password;
|
||||||
|
this.emailAddress = emailAddress;
|
||||||
|
}
|
||||||
|
}
|
6
tests/src/com/fsck/k9/endtoend/pages/AbstractPage.java
Normal file
6
tests/src/com/fsck/k9/endtoend/pages/AbstractPage.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
public class AbstractPage {
|
||||||
|
|
||||||
|
// used to have some content. Now a placeholder class
|
||||||
|
}
|
17
tests/src/com/fsck/k9/endtoend/pages/AccountOptionsPage.java
Normal file
17
tests/src/com/fsck/k9/endtoend/pages/AccountOptionsPage.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
|
||||||
|
|
||||||
|
public class AccountOptionsPage extends AbstractPage {
|
||||||
|
|
||||||
|
public AccountSetupNamesPage clickNext() {
|
||||||
|
onView(withId(R.id.next)).perform(click());
|
||||||
|
return new AccountSetupNamesPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException;
|
||||||
|
import com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.clearText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.scrollTo;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.typeText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
|
||||||
|
|
||||||
|
public class AccountSetupNamesPage extends AbstractPage {
|
||||||
|
|
||||||
|
public AccountSetupNamesPage inputAccountName(String name) {
|
||||||
|
onView(withId(R.id.account_name))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(name));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountSetupNamesPage inputAccountDescription(String name) {
|
||||||
|
onView(withId(R.id.account_description))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(name));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountsPage clickDone() {
|
||||||
|
onView(withId(R.id.done))
|
||||||
|
.perform(click());
|
||||||
|
dismissChangelog();
|
||||||
|
return new AccountsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dismissChangelog() {
|
||||||
|
try {
|
||||||
|
onView(ViewMatchers.withText("OK")).perform(click());
|
||||||
|
} catch (NoMatchingViewException ex) {
|
||||||
|
// Ignored. Not the best way of doing this, but Espresso rightly makes
|
||||||
|
// conditional flow difficult.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
tests/src/com/fsck/k9/endtoend/pages/AccountSetupPage.java
Normal file
27
tests/src/com/fsck/k9/endtoend/pages/AccountSetupPage.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.typeText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
|
||||||
|
public class AccountSetupPage extends AbstractPage {
|
||||||
|
|
||||||
|
public AccountSetupPage inputEmailAddress(String emailAddress) {
|
||||||
|
onView(withId(R.id.account_email)).perform(typeText(emailAddress));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountSetupPage inputPassword(String password) {
|
||||||
|
onView(withId(R.id.account_password)).perform(typeText(password));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountTypePage clickManualSetup() {
|
||||||
|
onView(withId(R.id.manual_setup)).perform(click());
|
||||||
|
return new AccountTypePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
tests/src/com/fsck/k9/endtoend/pages/AccountTypePage.java
Normal file
14
tests/src/com/fsck/k9/endtoend/pages/AccountTypePage.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
public class AccountTypePage extends AbstractPage {
|
||||||
|
|
||||||
|
public IncomingServerSettingsPage clickImap() {
|
||||||
|
onView(withId(R.id.imap)).perform(click());
|
||||||
|
return new IncomingServerSettingsPage();
|
||||||
|
}
|
||||||
|
}
|
56
tests/src/com/fsck/k9/endtoend/pages/AccountsPage.java
Normal file
56
tests/src/com/fsck/k9/endtoend/pages/AccountsPage.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.endtoend.framework.AccountForTest;
|
||||||
|
import com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException;
|
||||||
|
import com.google.android.apps.common.testing.ui.espresso.ViewAssertion;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.longClick;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.scrollTo;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.doesNotExist;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.isDisplayed;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withText;
|
||||||
|
|
||||||
|
public class AccountsPage extends AbstractPage {
|
||||||
|
|
||||||
|
private void assertAccount(String accountDisplayName, boolean exists) {
|
||||||
|
ViewAssertion assertion = exists ? matches(isDisplayed()) : doesNotExist();
|
||||||
|
onView(withText(accountDisplayName)).check(assertion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountSetupPage clickAddNewAccount() {
|
||||||
|
// need to click twice for some reason?
|
||||||
|
onView(withId(R.id.add_new_account)).perform(click());
|
||||||
|
try {
|
||||||
|
onView(withId(R.id.add_new_account)).perform(click());
|
||||||
|
} catch (NoMatchingViewException ex) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
onView(withId(R.id.account_email)).perform(scrollTo());
|
||||||
|
return new AccountSetupPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertAccountExists(String accountDisplayName) {
|
||||||
|
assertAccount(accountDisplayName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertAccountDoesNotExist(String accountDisplayName) {
|
||||||
|
assertAccount(accountDisplayName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clickLongOnAccount(AccountForTest accountForTest) {
|
||||||
|
onView(withText(accountForTest.description)).perform(longClick());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clickRemoveInAccountMenu() {
|
||||||
|
onView(withText("Remove account")).perform(click());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clickOK() {
|
||||||
|
onView(withText("OK")).perform(click());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.mail.ConnectionSecurity;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onData;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.clearText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.scrollTo;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.typeText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.isClickable;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withText;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
public class IncomingServerSettingsPage extends AbstractPage {
|
||||||
|
|
||||||
|
public IncomingServerSettingsPage inputImapServer(String imapServer) {
|
||||||
|
onView(withId(R.id.account_server))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(imapServer));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IncomingServerSettingsPage inputImapSecurity(ConnectionSecurity security) {
|
||||||
|
onView(withId(R.id.account_security_type))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(click());
|
||||||
|
onData(allOf(is(instanceOf(ConnectionSecurity.class)), is(security))).perform(click());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IncomingServerSettingsPage inputPort(int port) {
|
||||||
|
onView(withId(R.id.account_port))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(String.valueOf(port)));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public OutgoingServerSettingsPage clickNext() {
|
||||||
|
onView(withId(R.id.next))
|
||||||
|
// .perform(scrollTo())
|
||||||
|
.check(matches(isClickable()))
|
||||||
|
.perform(click());
|
||||||
|
|
||||||
|
// We know this view is on the next page, this functions as a wait.
|
||||||
|
onView(withText("SMTP server")).perform(scrollTo());
|
||||||
|
return new OutgoingServerSettingsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IncomingServerSettingsPage inputUsername(String loginUsername) {
|
||||||
|
onView(withId(R.id.account_username))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(loginUsername));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.mail.ConnectionSecurity;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onData;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.clearText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.scrollTo;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.typeText;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
|
||||||
|
public class OutgoingServerSettingsPage extends AbstractPage {
|
||||||
|
|
||||||
|
public OutgoingServerSettingsPage inputSmtpServer(String serverAddress) {
|
||||||
|
onView(withId(R.id.account_server))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(serverAddress));
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutgoingServerSettingsPage inputSmtpSecurity(ConnectionSecurity security) {
|
||||||
|
onView(withId(R.id.account_security_type))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(click());
|
||||||
|
onData(allOf(is(instanceOf(ConnectionSecurity.class)), is(security))).perform(click());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutgoingServerSettingsPage inputPort(int port) {
|
||||||
|
onView(withId(R.id.account_port))
|
||||||
|
.perform(scrollTo())
|
||||||
|
.perform(clearText())
|
||||||
|
.perform(typeText(String.valueOf(port)));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutgoingServerSettingsPage inputRequireSignIn(boolean requireSignInInput) {
|
||||||
|
onView(withId(R.id.account_require_login))
|
||||||
|
.perform(scrollTo());
|
||||||
|
/*
|
||||||
|
* Make this smarter; click if necessary.
|
||||||
|
*/
|
||||||
|
if (!requireSignInInput) {
|
||||||
|
onView(withId(R.id.account_require_login))
|
||||||
|
.perform(click());
|
||||||
|
}
|
||||||
|
// Matcher<View> checkedOrNot = requireSignInInput ? isChecked(): isNotChecked();
|
||||||
|
// try {
|
||||||
|
// onView(withId(R.id.account_require_login)).check((matches(checkedOrNot)));
|
||||||
|
// } catch (AssertionFailedWithCauseError ex) {
|
||||||
|
// onView(withId(R.id.account_require_login)).perform(click());
|
||||||
|
// }
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountOptionsPage clickNext() {
|
||||||
|
onView(withId(R.id.next)).perform(click());
|
||||||
|
return new AccountOptionsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
tests/src/com/fsck/k9/endtoend/pages/WelcomeMessagePage.java
Normal file
15
tests/src/com/fsck/k9/endtoend/pages/WelcomeMessagePage.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
|
||||||
|
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
|
||||||
|
|
||||||
|
public class WelcomeMessagePage extends AbstractPage {
|
||||||
|
|
||||||
|
public final AccountSetupPage clickNext() {
|
||||||
|
onView(withId(R.id.next)).perform(click());
|
||||||
|
return new AccountSetupPage();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user