├── packageTest.sh ├── readme_images └── appium-tests.gif ├── start-appium-android.sh ├── src ├── test │ └── java │ │ ├── Pages │ │ ├── WaitConfig.java │ │ ├── Native │ │ │ ├── MediaPlayerPage.java │ │ │ ├── ImageGalleryPage.java │ │ │ ├── CameraPage.java │ │ │ ├── ContentScrollingPage.java │ │ │ └── OutOfViewPage.java │ │ ├── CrashPage.java │ │ ├── HomePage.java │ │ ├── Inputs │ │ │ ├── EditTextPage.java │ │ │ ├── CheckBoxPage.java │ │ │ ├── ToggleButtonPage.java │ │ │ ├── PullToRefreshPage.java │ │ │ ├── RadioButtonPage.java │ │ │ ├── SpinnerPage.java │ │ │ └── GesturesPage.java │ │ ├── TabViewPage.java │ │ ├── LocalWebViewPage.java │ │ ├── AlertPage.java │ │ ├── FixturesPage.java │ │ ├── NavigationPage.java │ │ ├── LoginPage.java │ │ ├── BasePage.java │ │ ├── NestedViewsPage.java │ │ └── WebViewPage.java │ │ └── Tests │ │ ├── AbstractBaseTests │ │ ├── InputTests.java │ │ ├── NativeTests.java │ │ ├── TabTestBase.java │ │ └── TestBase.java │ │ ├── Native │ │ ├── ImageGalleryTest.java │ │ ├── OutOfViewTest.java │ │ ├── ScrollViewTest.java │ │ ├── CameraTest.java │ │ └── MediaPlayerTest.java │ │ ├── AlertPageTest.java │ │ ├── Inputs │ │ ├── CheckboxTest.java │ │ ├── RadioButtonTest.java │ │ ├── SpinnerTest.java │ │ ├── EditTextTest.java │ │ ├── PullToRefreshTest.java │ │ ├── ToggleButtonTest.java │ │ └── GesturesTest.java │ │ ├── HomePageTest.java │ │ ├── WebViewTest.java │ │ ├── FixturesTest.java │ │ ├── LoginTest.java │ │ └── NestedViewsTest.java └── main │ └── assembly │ └── zip.xml ├── .gitignore ├── pom.xml ├── LICENSE.txt └── README.md /packageTest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mvn clean package -DskipTests=true -------------------------------------------------------------------------------- /readme_images/appium-tests.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-device-farm-appium-tests-for-sample-app/HEAD/readme_images/appium-tests.gif -------------------------------------------------------------------------------- /start-appium-android.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function die { 4 | echo $1 5 | exit 1 6 | } 7 | 8 | pkg_root_dir=`find $PWD | grep "/Config$" | head -n 1 | xargs dirname` 9 | app_filename="$pkg_root_dir/app/app.apk" 10 | ls -1 $app_filename || die "Did not find app in $pkg_root_dir" 11 | 12 | appium --pre-launch --app-pkg com.amazonaws.devicefarm.android.referenceapp --app-activity .Activities.MainActivity --platform-name Android --app $app_filename 13 | -------------------------------------------------------------------------------- /src/test/java/Pages/WaitConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | public class WaitConfig { 19 | public static final int DRAWER_ANIMATION_WAIT = 2000; 20 | public static final int VIEWPAGE_BEFORE_WAIT = 1000; 21 | public static final int VIEWPAGE_BEFORE_AFTER = 4000; 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/Tests/AbstractBaseTests/InputTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.AbstractBaseTests; 17 | 18 | /** 19 | * This class sets the category name for all of the 20 | * Input Controls viewpager tabs 21 | */ 22 | public abstract class InputTests extends TabTestBase { 23 | @Override 24 | public String getName() { 25 | return "Input Controls"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/Tests/AbstractBaseTests/NativeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.AbstractBaseTests; 17 | 18 | /** 19 | * This class set's the Category name for all of the 20 | * Native Components viewpager tabs. 21 | */ 22 | public abstract class NativeTests extends TabTestBase { 23 | @Override 24 | public String getName() { 25 | return "Native Components"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Maven template 3 | target/ 4 | pom.xml.tag 5 | pom.xml.releaseBackup 6 | pom.xml.versionsBackup 7 | pom.xml.next 8 | release.properties 9 | dependency-reduced-pom.xml 10 | buildNumber.properties 11 | .mvn/timing.properties 12 | 13 | 14 | ### JetBrains template 15 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion 16 | 17 | *.iml 18 | 19 | ## Directory-based project format: 20 | .idea/ 21 | # if you remove the above rule, at least ignore the following: 22 | 23 | # User-specific stuff: 24 | # .idea/workspace.xml 25 | # .idea/tasks.xml 26 | # .idea/dictionaries 27 | 28 | # Sensitive or high-churn files: 29 | # .idea/dataSources.ids 30 | # .idea/dataSources.xml 31 | # .idea/sqlDataSources.xml 32 | # .idea/dynamic.xml 33 | # .idea/uiDesigner.xml 34 | 35 | # Gradle: 36 | # .idea/gradle.xml 37 | # .idea/libraries 38 | 39 | # Mongo Explorer plugin: 40 | # .idea/mongoSettings.xml 41 | 42 | ## File-based project format: 43 | *.ipr 44 | *.iws 45 | 46 | ## Plugin-specific files: 47 | 48 | # IntelliJ 49 | /out/ 50 | 51 | # mpeltonen/sbt-idea plugin 52 | .idea_modules/ 53 | 54 | # JIRA plugin 55 | atlassian-ide-plugin.xml 56 | 57 | # Crashlytics plugin (for Android Studio and IntelliJ) 58 | com_crashlytics_export_strings.xml 59 | crashlytics.properties 60 | crashlytics-build.properties 61 | 62 | app/ 63 | 64 | .DS_Store 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/test/java/Pages/Native/MediaPlayerPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Native; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | /** 24 | * A page for a media file 25 | */ 26 | public class MediaPlayerPage extends BasePage { 27 | /** 28 | * The media player 29 | */ 30 | @AndroidFindBy(accessibility = "Content Playing") 31 | private MobileElement videoView; 32 | 33 | public MediaPlayerPage(AppiumDriver driver) { 34 | super(driver); 35 | } 36 | 37 | /** 38 | * 39 | * @return content description of the media player 40 | */ 41 | public String getMediaPlayerStatus() { 42 | return videoView.getAttribute("name"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/Pages/Native/ImageGalleryPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Native; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | /** 24 | * A page for a image gallery (in a grid view) 25 | */ 26 | public class ImageGalleryPage extends BasePage { 27 | /** 28 | * the image gallery grid view 29 | */ 30 | @AndroidFindBy(className = "android.widget.GridView") 31 | private MobileElement imageGalley; 32 | 33 | public ImageGalleryPage(AppiumDriver driver) { 34 | super(driver); 35 | } 36 | 37 | /** 38 | * 39 | * @return if the grid view is displayed 40 | */ 41 | public boolean imageGalleryIsDisplayed() { 42 | return imageGalley.isDisplayed(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/Pages/Native/CameraPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Native; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | /** 24 | * A page for a camera preview 25 | */ 26 | public class CameraPage extends BasePage { 27 | /** 28 | * The camera preview 29 | */ 30 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/camera_surface_view") 31 | private MobileElement cameraPreview; 32 | 33 | public CameraPage(AppiumDriver driver) { 34 | super(driver); 35 | } 36 | 37 | /** 38 | * 39 | * @return the content description of the camera preview 40 | */ 41 | public String getCameraStatus(){ 42 | return cameraPreview.getAttribute("name"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/Pages/CrashPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.pagefactory.AndroidFindBy; 20 | import org.openqa.selenium.WebElement; 21 | 22 | /** 23 | * A page representing a crash 24 | * 25 | */ 26 | public class CrashPage extends BasePage { 27 | /** 28 | * The crash button 29 | */ 30 | @AndroidFindBy(name = "Crash Button") 31 | private WebElement crashButton; 32 | 33 | /** 34 | * The crash message 35 | */ 36 | @AndroidFindBy(name = "Unfortunately, ReferenceApp has stopped.") 37 | private WebElement crashMessage; 38 | 39 | public CrashPage(AppiumDriver driver) { 40 | super(driver); 41 | } 42 | 43 | /** 44 | * pressed a crash button 45 | */ 46 | public void clickCrashButton() { 47 | crashButton.click(); 48 | } 49 | 50 | /** 51 | * 52 | * @return the crash message 53 | */ 54 | public String getCrashMessage(){ 55 | return crashMessage.getText(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/Pages/Native/ContentScrollingPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2066 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Native; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.SwipeElementDirection; 22 | import io.appium.java_client.pagefactory.AndroidFindBy; 23 | 24 | /** 25 | * A page for a scroll view 26 | */ 27 | public class ContentScrollingPage extends BasePage { 28 | /** 29 | * Scroll view 30 | */ 31 | @AndroidFindBy(className = "android.widget.ScrollView") 32 | private MobileElement scrollView; 33 | 34 | public ContentScrollingPage(AppiumDriver driver) { 35 | super(driver); 36 | } 37 | 38 | /** 39 | * Scroll down 40 | */ 41 | public void scrollDown(){ 42 | scrollView.swipe(SwipeElementDirection.UP, 10, 10, 10000); 43 | } 44 | 45 | /** 46 | * 47 | * @return if the scrollview is displayed 48 | */ 49 | public boolean scrollViewDisplayed(){ 50 | return scrollView.isDisplayed(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/assembly/zip.xml: -------------------------------------------------------------------------------- 1 | 15 | 20 | zip 21 | 22 | zip 23 | 24 | false 25 | 26 | 27 | ${project.build.directory} 28 | ./ 29 | 30 | *.jar 31 | 32 | 33 | 34 | ${project.build.directory} 35 | ./ 36 | 37 | /dependency-jars/ 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/test/java/Pages/HomePage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.pagefactory.AndroidFindBy; 20 | import org.openqa.selenium.WebElement; 21 | 22 | /** 23 | * A page representing a static homepage 24 | */ 25 | public class HomePage extends BasePage{ 26 | 27 | /** 28 | * The headline of the homepage 29 | */ 30 | @AndroidFindBy(accessibility = "Homepage Headline") 31 | private WebElement headline; 32 | 33 | /** 34 | * the subheader of the homepage 35 | */ 36 | @AndroidFindBy(id = "Homepage Subheader") 37 | private WebElement subheader; 38 | 39 | public HomePage(AppiumDriver driver) { 40 | super(driver); 41 | } 42 | 43 | /** 44 | * 45 | * @return the header text content 46 | */ 47 | public String getHeadlineValue() { 48 | return headline.getText(); 49 | } 50 | 51 | /** 52 | * 53 | * @return the subheader text content 54 | */ 55 | public String getSubheaderValue() { 56 | return subheader.getText(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/Tests/Native/ImageGalleryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Native; 17 | 18 | import Pages.Native.ImageGalleryPage; 19 | import Tests.AbstractBaseTests.NativeTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for image gallery 26 | */ 27 | public class ImageGalleryTest extends NativeTests { 28 | private ImageGalleryPage imageGalleryPage; 29 | 30 | /** 31 | * Sets the page view index so it can be navigated to 32 | * 33 | * @return the pageview index 34 | */ 35 | @Override 36 | public int pageIndex() { 37 | return 0; 38 | } 39 | 40 | /** 41 | * Sets up the image gallery page 42 | */ 43 | @BeforeTest 44 | @Override 45 | public void setUpPage() { 46 | imageGalleryPage = new ImageGalleryPage(driver); 47 | } 48 | 49 | /** 50 | * Check if the image grid view is displayed 51 | */ 52 | @Test 53 | public void checkIfImageGalleryDisplayed() { 54 | Assert.assertTrue(imageGalleryPage.imageGalleryIsDisplayed()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/EditTextPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | /** 24 | * A page for a text input 25 | */ 26 | public class EditTextPage extends BasePage { 27 | /** 28 | * The text input 29 | */ 30 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_edit_text") 31 | private MobileElement textBox; 32 | 33 | public EditTextPage(AppiumDriver driver) { 34 | super(driver); 35 | } 36 | 37 | /** 38 | * Input text 39 | * 40 | * @param text to input 41 | * 42 | * @return true, if text properly entered, else false. 43 | */ 44 | public boolean enterText(String text) throws InterruptedException { 45 | return sendKeysToElement(text, textBox, false); 46 | } 47 | 48 | /** 49 | * 50 | * @return the contents of the text box 51 | */ 52 | public String getTextBoxText(){ 53 | return textBox.getText(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/Tests/AbstractBaseTests/TabTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.AbstractBaseTests; 17 | 18 | import Pages.TabViewPage; 19 | import Pages.WaitConfig; 20 | import org.testng.annotations.BeforeClass; 21 | 22 | /** 23 | * This class is a base class for a page view pased page 24 | */ 25 | public abstract class TabTestBase extends TestBase { 26 | private TabViewPage tabViewPage; 27 | 28 | /** 29 | * This gets the page's index so it can be swiped to before the 30 | * test begins. 31 | * 32 | * @return the page's index 33 | */ 34 | public abstract int pageIndex(); 35 | 36 | /** 37 | * Navigates to the class' page 38 | * 39 | * @throws InterruptedException 40 | */ 41 | @BeforeClass 42 | @Override 43 | public void navigateTo() throws InterruptedException { 44 | super.navigateTo(); 45 | tabViewPage = new TabViewPage(driver); 46 | Thread.sleep(WaitConfig.VIEWPAGE_BEFORE_WAIT); 47 | for (int i = 0; i < pageIndex(); i++) { 48 | tabViewPage.turnPageLeft(); 49 | Thread.sleep(WaitConfig.VIEWPAGE_BEFORE_AFTER); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/Tests/Native/OutOfViewTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Native; 17 | 18 | import Pages.Native.OutOfViewPage; 19 | import Tests.AbstractBaseTests.NativeTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | public class OutOfViewTest extends NativeTests { 25 | private OutOfViewPage outOfViewPage; 26 | 27 | /** 28 | * Sets the page view index so it can be navigated to 29 | * 30 | * @return the pageview index 31 | */ 32 | @Override 33 | public int pageIndex() { 34 | return 4; 35 | } 36 | 37 | /** 38 | * Sets up the out of view page 39 | */ 40 | @BeforeTest 41 | @Override 42 | public void setUpPage() { 43 | outOfViewPage = new OutOfViewPage(driver); 44 | } 45 | 46 | /** 47 | * tests the scrollview by scrolling down and checking if the hidden text is 48 | * displayed. 49 | */ 50 | @Test 51 | public void scrollOutOfView() { 52 | outOfViewPage.scrollDownToHiddenText(); 53 | Assert.assertTrue(outOfViewPage.isHiddenTextDisplayed()); 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/CheckBoxPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | /** 24 | * A page for a check box control 25 | */ 26 | public class CheckBoxPage extends BasePage { 27 | /** 28 | * The checkbox control 29 | */ 30 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_checkbox") 31 | private MobileElement checkBox; 32 | 33 | /** 34 | * The display for the status 35 | */ 36 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_checkbox_status") 37 | private MobileElement display; 38 | 39 | 40 | public CheckBoxPage(AppiumDriver driver) { 41 | super(driver); 42 | } 43 | 44 | /** 45 | * Clicks the checkbox 46 | */ 47 | public void touchCheckBox() { 48 | checkBox.click(); 49 | } 50 | 51 | /** 52 | * 53 | * @return the text from the display 54 | */ 55 | public String getCheckBoxDisplay(){ 56 | return display.getText(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/Tests/AlertPageTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests; 17 | 18 | import Pages.AlertPage; 19 | import Tests.AbstractBaseTests.TestBase; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for alert page 26 | */ 27 | public class AlertPageTest extends TestBase { 28 | private static final String ALERT_MESSAGE = "This is the alert message"; 29 | private AlertPage alertPage; 30 | 31 | @Override 32 | public String getName() { 33 | return "Alerts"; 34 | } 35 | 36 | /** 37 | * Sets up the alert view page 38 | */ 39 | @BeforeTest 40 | @Override 41 | public void setUpPage() { 42 | alertPage = new AlertPage(driver); 43 | } 44 | 45 | /** 46 | * Tests the alert view by clicking the alert view button, 47 | * then verifying the alert view message, and then 48 | * accepting the alert view message. 49 | */ 50 | @Test 51 | public void testAlertMessage(){ 52 | alertPage.clickAlertsButton(); 53 | Assert.assertEquals(alertPage.getAlertText(), ALERT_MESSAGE); 54 | alertPage.acceptAlertMessage(); 55 | } 56 | } -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/ToggleButtonPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * A page for a toggle button control 27 | */ 28 | public class ToggleButtonPage extends BasePage { 29 | /** 30 | * The toggle switch 31 | */ 32 | @AndroidFindBy(className = "android.widget.Switch") 33 | private MobileElement toggleSwitch; 34 | 35 | public ToggleButtonPage(AppiumDriver driver) { 36 | super(driver); 37 | } 38 | 39 | /** 40 | * toggle the toggle button 41 | */ 42 | public void toggleSwitch() { 43 | toggleSwitch.click(); 44 | } 45 | 46 | /** 47 | * 48 | * @return the display 49 | */ 50 | public String getToggleDisplayStatus() { 51 | List frameLayouts = driver.findElementsByClassName("android.widget.FrameLayout"); 52 | MobileElement toggleDisplay = (MobileElement) frameLayouts.get(frameLayouts.size() - 1); 53 | return toggleDisplay.getAttribute("name"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/Tests/Native/ScrollViewTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Native; 17 | 18 | import Pages.Native.ContentScrollingPage; 19 | import Tests.AbstractBaseTests.NativeTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for the scroll view 26 | */ 27 | public class ScrollViewTest extends NativeTests { 28 | private ContentScrollingPage contentScrollingPage; 29 | 30 | /** 31 | * Sets the page view index so it can be navigated to 32 | * 33 | * @return the pageview index 34 | */ 35 | @Override 36 | public int pageIndex() { 37 | return 1; 38 | } 39 | 40 | /** 41 | * Sets up the scrollview page 42 | */ 43 | @BeforeTest 44 | @Override 45 | public void setUpPage() { 46 | contentScrollingPage = new ContentScrollingPage(driver); 47 | } 48 | 49 | /** 50 | * Tests by scrolling down and checking if the scrollview is still displayed 51 | */ 52 | @Test 53 | public void testScroll() { 54 | contentScrollingPage.scrollDown(); 55 | Assert.assertTrue(contentScrollingPage.scrollViewDisplayed()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/Tests/Native/CameraTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Native; 17 | 18 | import Pages.Native.CameraPage; 19 | import Tests.AbstractBaseTests.NativeTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests to test a camera preview 26 | */ 27 | public class CameraTest extends NativeTests { 28 | private static final String CAMERA_ON_STATUS = "Camera Preview Streaming"; 29 | 30 | private CameraPage cameraPage; 31 | 32 | /** 33 | * Sets the page view index so it can be navigated to 34 | * 35 | * @return the pageview index 36 | */ 37 | @Override 38 | public int pageIndex() { 39 | return 3; 40 | } 41 | 42 | @BeforeTest 43 | @Override 44 | public void setUpPage() { 45 | cameraPage = new CameraPage(driver); 46 | } 47 | 48 | /** 49 | * Tests a camera preview by checking if the preview's content description 50 | * indicates that the camera is on and streaming. Fails on devices with no camera support. 51 | */ 52 | @Test 53 | public void testCameraStatus() { 54 | Assert.assertEquals(cameraPage.getCameraStatus(), CAMERA_ON_STATUS); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/Tests/Native/MediaPlayerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Native; 17 | 18 | import Pages.Native.MediaPlayerPage; 19 | import Tests.AbstractBaseTests.NativeTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for media player 26 | */ 27 | public class MediaPlayerTest extends NativeTests { 28 | private static final String MEDIA_PLAYER_CONTENT_DESCRIPTION = "Content Playing"; 29 | private MediaPlayerPage mediaPlayerPage; 30 | 31 | /** 32 | * Sets the page view index so it can be navigated to 33 | * 34 | * @return the pageview index 35 | */ 36 | @Override 37 | public int pageIndex() { 38 | return 2; 39 | } 40 | 41 | /** 42 | * Creates media player page 43 | */ 44 | @BeforeTest 45 | @Override 46 | public void setUpPage() { 47 | mediaPlayerPage = new MediaPlayerPage(driver); 48 | } 49 | 50 | /** 51 | * Test if the media player's content description is playing 52 | */ 53 | @Test 54 | public void testIfMediaPlayerIsPlaying() { 55 | Assert.assertEquals(mediaPlayerPage.getMediaPlayerStatus(), MEDIA_PLAYER_CONTENT_DESCRIPTION); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/CheckboxTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | import Pages.Inputs.CheckBoxPage; 19 | import Tests.AbstractBaseTests.InputTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests the checkbox 26 | */ 27 | public class CheckboxTest extends InputTests { 28 | private static final String CHECKED_VALUE = "Checked"; 29 | 30 | /** 31 | * Checkbox page 32 | */ 33 | private CheckBoxPage checkBoxPage; 34 | 35 | /** 36 | * Sets the page view index so it can be navigated to 37 | * 38 | * @return the pageview index 39 | */ 40 | @Override 41 | public int pageIndex() { 42 | return 1; 43 | } 44 | 45 | /** 46 | * Creates the checkbox page 47 | */ 48 | @BeforeTest 49 | @Override 50 | public void setUpPage() { 51 | checkBoxPage = new CheckBoxPage(driver); 52 | } 53 | 54 | /** 55 | * Verifies whether checked message appears on the screen once 56 | * the checkbox is checked. 57 | */ 58 | @Test 59 | public void testCheckBox() { 60 | checkBoxPage.touchCheckBox(); 61 | Assert.assertEquals(checkBoxPage.getCheckBoxDisplay(), CHECKED_VALUE); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/Tests/HomePageTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests; 17 | 18 | import Pages.HomePage; 19 | import Tests.AbstractBaseTests.TestBase; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for homepage 26 | */ 27 | public class HomePageTest extends TestBase { 28 | private static final String HOMEPAGE_HEADLINE = "AWS Device Farm Sample App for Android"; 29 | private static final String HOMEPAGE_SUBHEADER = "version 1"; 30 | 31 | private HomePage homePageTest; 32 | 33 | /** 34 | * Sets up homepage 35 | */ 36 | @BeforeTest 37 | @Override 38 | public void setUpPage() { 39 | homePageTest = new HomePage(driver); 40 | } 41 | 42 | /** 43 | * Asserts the homepage headline 44 | */ 45 | @Test 46 | public void testHomePageHeadline() { 47 | Assert.assertEquals(homePageTest.getHeadlineValue(), HOMEPAGE_HEADLINE); 48 | } 49 | 50 | /** 51 | * Asserts the homepage subheader 52 | */ 53 | @Test 54 | public void testHomePageSubheader() { 55 | Assert.assertEquals(homePageTest.getSubheaderValue(), HOMEPAGE_SUBHEADER); 56 | } 57 | 58 | @Override 59 | public String getName() { 60 | return "Home"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/RadioButtonTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | import Pages.Inputs.RadioButtonPage; 19 | import Tests.AbstractBaseTests.InputTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | public class RadioButtonTest extends InputTests { 25 | private RadioButtonPage radioButtonPage; 26 | 27 | /** 28 | * Sets the page view index so it can be navigated to 29 | * 30 | * @return the pageview index 31 | */ 32 | @Override 33 | public int pageIndex() { 34 | return 2; 35 | } 36 | 37 | @BeforeTest 38 | @Override 39 | public void setUpPage() { 40 | radioButtonPage = new RadioButtonPage(driver); 41 | } 42 | 43 | @Test 44 | public void testFirstRadio() { 45 | radioButtonPage.clickRadioButton1(); 46 | Assert.assertEquals(radioButtonPage.getRadioText(), "Amazon"); 47 | } 48 | 49 | @Test 50 | public void testSecondRadio() { 51 | radioButtonPage.clickRadioButton2(); 52 | Assert.assertEquals(radioButtonPage.getRadioText(), "Web"); 53 | } 54 | 55 | @Test 56 | public void testThirdRadio() { 57 | radioButtonPage.clickRadioButton3(); 58 | Assert.assertEquals(radioButtonPage.getRadioText(), "Services"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/PullToRefreshPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.SwipeElementDirection; 22 | import io.appium.java_client.pagefactory.AndroidFindBy; 23 | 24 | /** 25 | * A page for a pull to refresh control 26 | */ 27 | public class PullToRefreshPage extends BasePage 28 | { 29 | /** 30 | * The scrollview 31 | */ 32 | @AndroidFindBy(className = "android.widget.ScrollView") 33 | private MobileElement scrollView; 34 | 35 | /** 36 | * The display 37 | */ 38 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_refresh_display") 39 | private MobileElement display; 40 | 41 | public PullToRefreshPage(AppiumDriver driver) { 42 | super(driver); 43 | } 44 | 45 | /** 46 | * Pulls down to refresh 47 | */ 48 | public void pullToRefresh() { 49 | try { 50 | scrollView.swipe(SwipeElementDirection.DOWN, 10, 10, 100); 51 | } catch (Exception e) {} // Catch "The swipe did not complete successfully" error 52 | } 53 | 54 | /** 55 | * 56 | * @return the display text 57 | */ 58 | public String getDisplayText(){ 59 | return display.getText(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/SpinnerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | 19 | import Pages.Inputs.SpinnerPage; 20 | import Tests.AbstractBaseTests.InputTests; 21 | import org.testng.Assert; 22 | import org.testng.annotations.BeforeTest; 23 | import org.testng.annotations.Test; 24 | 25 | /** 26 | * Tests for the spinner control 27 | */ 28 | public class SpinnerTest extends InputTests { 29 | private static final String SPINNER_BASE_STRING = "Selected: %s"; 30 | 31 | private SpinnerPage spinnerPage; 32 | 33 | /** 34 | * Sets the page view index so it can be navigated to 35 | * 36 | * @return the pageview index 37 | */ 38 | @Override 39 | public int pageIndex() { 40 | return 4; 41 | } 42 | 43 | /** 44 | * Creates the spinner page 45 | */ 46 | @BeforeTest 47 | @Override 48 | public void setUpPage() { 49 | spinnerPage = new SpinnerPage(driver); 50 | } 51 | 52 | /** 53 | * Tests a spinner control by selecting the spinner at a specific index then verifying if the selected 54 | * text appears in the text view 55 | */ 56 | @Test 57 | public void checkIndex() { 58 | spinnerPage.selectSpinnerAtIndex(3); 59 | Assert.assertEquals(spinnerPage.getDisplayText(), String.format(SPINNER_BASE_STRING, spinnerPage.getSelectedEntry())); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/RadioButtonPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | 23 | public class RadioButtonPage extends BasePage { 24 | 25 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/radio_button_1") 26 | private MobileElement radioButton1; 27 | 28 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/radio_button_2") 29 | private MobileElement radioButton2; 30 | 31 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/radio_button_3") 32 | private MobileElement radioButton3; 33 | 34 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_radio_button_display") 35 | private MobileElement radioText; 36 | 37 | public RadioButtonPage(AppiumDriver driver) { 38 | super(driver); 39 | } 40 | 41 | public String getRadioText() { 42 | return radioText.getText(); 43 | } 44 | 45 | public void clickRadioButton1() { 46 | radioButton1.click(); 47 | } 48 | 49 | public void clickRadioButton2() { 50 | radioButton2.click(); 51 | } 52 | 53 | public void clickRadioButton3() { 54 | radioButton3.click(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/Tests/WebViewTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests; 17 | 18 | import Pages.WebViewPage; 19 | import Tests.AbstractBaseTests.TestBase; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for a webview 26 | */ 27 | public class WebViewTest extends TestBase { 28 | private static final String FULL_URL = "http://docs.aws.amazon.com"; 29 | private static final String BAD_INTERNET_CONNECTION_MSG = "Bad internet connection or hybrid view is bugged on this device (6.x)"; 30 | private static final String BAD_URL_ENTRY_MSG = "Url was not sent to navigation bar properly"; 31 | private WebViewPage webViewPage; 32 | 33 | @Override 34 | public String getName() { 35 | return "Web"; 36 | } 37 | 38 | /** 39 | * Sets up the webview page 40 | */ 41 | @BeforeTest 42 | @Override 43 | public void setUpPage() { 44 | webViewPage = new WebViewPage(driver); 45 | } 46 | 47 | /** 48 | * Inputs navigates to a URL and then checks if the url is loaded by 49 | * checking the webview's content description 50 | */ 51 | @Test 52 | public void testWebView() throws InterruptedException { 53 | Assert.assertTrue(webViewPage.goToUrl(FULL_URL), BAD_URL_ENTRY_MSG); 54 | Assert.assertTrue(webViewPage.webDescriptionIsLoaded(), BAD_INTERNET_CONNECTION_MSG); 55 | } 56 | } -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/EditTextTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | import Pages.Inputs.EditTextPage; 19 | import Tests.AbstractBaseTests.InputTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for a text input 26 | */ 27 | public class EditTextTest extends InputTests { 28 | private static final String TEXT_TO_INPUT = "Something"; 29 | private static final String TEXT_ENTRY_ERROR_MSG = "Text was not entered properly"; 30 | 31 | /** 32 | * A edit text page 33 | */ 34 | private EditTextPage editTextPage; 35 | 36 | /** 37 | * Sets the page view index so it can be navigated to 38 | * 39 | * @return the pageview index 40 | */ 41 | @Override 42 | public int pageIndex() { 43 | return 0; 44 | } 45 | 46 | /** 47 | * Creates the edit text page 48 | */ 49 | @BeforeTest 50 | @Override 51 | public void setUpPage() { 52 | editTextPage = new EditTextPage(driver); 53 | } 54 | 55 | /** 56 | * Tests input to the edit text box and then verifies if the text is there 57 | */ 58 | @Test 59 | public void testTextBox() throws InterruptedException { 60 | Assert.assertTrue(editTextPage.enterText(TEXT_TO_INPUT), TEXT_ENTRY_ERROR_MSG); 61 | Assert.assertTrue(editTextPage.getTextBoxText().contains(TEXT_TO_INPUT)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/PullToRefreshTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | import Pages.Inputs.PullToRefreshPage; 19 | import Tests.AbstractBaseTests.InputTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for pull to refresh 26 | */ 27 | public class PullToRefreshTest extends InputTests { 28 | private PullToRefreshPage pullToRefreshPage; 29 | 30 | /** 31 | * Sets the page view index so it can be navigated to 32 | * 33 | * @return the pageview index 34 | */ 35 | @Override 36 | public int pageIndex() { 37 | return 5; 38 | } 39 | 40 | /** 41 | * Creates pull to refresh page 42 | */ 43 | @BeforeTest 44 | @Override 45 | public void setUpPage() { 46 | pullToRefreshPage = new PullToRefreshPage(driver); 47 | } 48 | 49 | /** 50 | * The pull to refresh displays the device's time if the working properly. 51 | * 52 | * Tests a pull to refresh control by pulling to refresh, waiting 53 | * then checks if a time appears. 54 | * 55 | * 56 | * @throws InterruptedException 57 | */ 58 | @Test 59 | public void testPullToRefresh() throws InterruptedException { 60 | pullToRefreshPage.pullToRefresh(); 61 | Thread.sleep(3000); 62 | Assert.assertTrue(pullToRefreshPage.getDisplayText().matches("\\d{2}:\\d{2}:\\d{2} (AM|PM)")); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/ToggleButtonTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | import Pages.Inputs.ToggleButtonPage; 19 | import Tests.AbstractBaseTests.InputTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for a toggle button 26 | */ 27 | public class ToggleButtonTest extends InputTests { 28 | private static final String TOGGLE_ACTIVATED_TEXT = "ON"; 29 | private static final String TOGGLE_DEACTIVATED_TEXT = "OFF"; 30 | 31 | private ToggleButtonPage toggleButtonPage; 32 | 33 | /** 34 | * Sets the page view index so it can be navigated to 35 | * 36 | * @return the pageview index 37 | */ 38 | @Override 39 | public int pageIndex() { 40 | return 3; 41 | } 42 | 43 | /** 44 | * Creates the toggle button page 45 | */ 46 | @BeforeTest 47 | @Override 48 | public void setUpPage() { 49 | toggleButtonPage = new ToggleButtonPage(driver); 50 | } 51 | 52 | /** 53 | * Tests toggle switch by touching the switch, then verifying that the 54 | * activated element appears 55 | */ 56 | @Test 57 | public void testToggle() { 58 | toggleButtonPage.toggleSwitch(); 59 | Assert.assertEquals(toggleButtonPage.getToggleDisplayStatus(), TOGGLE_ACTIVATED_TEXT); 60 | toggleButtonPage.toggleSwitch(); 61 | Assert.assertEquals(toggleButtonPage.getToggleDisplayStatus(), TOGGLE_DEACTIVATED_TEXT); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/Pages/Native/OutOfViewPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Native; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.SwipeElementDirection; 22 | import io.appium.java_client.pagefactory.AndroidFindBy; 23 | import org.openqa.selenium.WebElement; 24 | 25 | /** 26 | * A page for a element hidden from the screen inside a scrollview 27 | */ 28 | public class OutOfViewPage extends BasePage { 29 | /** 30 | * The scrollview 31 | */ 32 | @AndroidFindBy(className = "android.widget.ScrollView") 33 | private MobileElement scrollView; 34 | 35 | public OutOfViewPage(AppiumDriver driver) { 36 | super(driver); 37 | } 38 | 39 | /** 40 | * 41 | * @return if the hidden element is displayed 42 | */ 43 | public boolean isHiddenTextDisplayed() { 44 | WebElement outOfViewText = driver.findElementById("com.amazonaws.devicefarm.android.referenceapp:id/hidden_text"); 45 | return outOfViewText.isDisplayed(); 46 | } 47 | 48 | /** 49 | * Scrolls to the bottom of the scrollview 50 | */ 51 | public void scrollDownToHiddenText() { 52 | try { 53 | scrollView.swipe(SwipeElementDirection.UP, 10, 10, 1000); 54 | scrollView.swipe(SwipeElementDirection.UP, 10, 10, 1000); 55 | scrollView.swipe(SwipeElementDirection.UP, 10, 10, 1000); 56 | } catch (Exception e) {} // Catch "The swipe did not complete successfully" error 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/Tests/FixturesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests; 17 | 18 | import Pages.FixturesPage; 19 | import Tests.AbstractBaseTests.TestBase; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for Device Farm fixtures 26 | */ 27 | public class FixturesTest extends TestBase { 28 | private static final String BOOLEAN_SELECTOR = "true|false"; 29 | private FixturesPage fixturesPage; 30 | 31 | @Override 32 | public String getName() { 33 | return "Fixtures"; 34 | } 35 | 36 | /** 37 | * Creates a fixture page 38 | */ 39 | @BeforeTest 40 | @Override 41 | public void setUpPage() { 42 | fixturesPage = new FixturesPage(driver); 43 | } 44 | 45 | /** 46 | * Tests to see if wifi is on 47 | */ 48 | @Test 49 | public void testWifiOn() { 50 | Assert.assertTrue(fixturesPage.getWifi().matches(BOOLEAN_SELECTOR)); 51 | } 52 | 53 | /** 54 | * Tests to see if the bluetooth is on 55 | */ 56 | @Test 57 | public void testBluetoothOn() { 58 | Assert.assertTrue(fixturesPage.getBluetooth().matches(BOOLEAN_SELECTOR)); 59 | } 60 | 61 | /** 62 | * Tests to see if the GPS is on 63 | */ 64 | @Test 65 | public void testGPSOn() { 66 | Assert.assertTrue(fixturesPage.getGps().matches(BOOLEAN_SELECTOR)); 67 | } 68 | 69 | /** 70 | * Tests to see if NFC is on. Fails on devices with no NFC support. 71 | */ 72 | @Test 73 | public void testNFCOn() { 74 | Assert.assertTrue(fixturesPage.getNfc().matches(BOOLEAN_SELECTOR)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/Pages/TabViewPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.MobileElement; 20 | import io.appium.java_client.pagefactory.AndroidFindBy; 21 | import org.openqa.selenium.Dimension; 22 | import org.openqa.selenium.WebElement; 23 | 24 | public class TabViewPage extends BasePage{ 25 | private static final double START_OFFSET = 0.95; 26 | private static final double END_OFFSET = 0.05; 27 | private static final int SWIPE_DURATION = 1000; 28 | private static final int ALERT_POP_UP_DELAY = 1000; 29 | private static final String BAD_VIDEO_TEXT = "Can't play this video."; 30 | private static final String OK_BUTTON_NAME = "OK"; 31 | 32 | @AndroidFindBy(id = "container_body") 33 | private MobileElement tabViewContainer; 34 | 35 | 36 | public TabViewPage(AppiumDriver driver) { 37 | super(driver); 38 | } 39 | 40 | public void turnPageLeft() throws InterruptedException { 41 | acceptBadVideoAlert(); 42 | Dimension size = driver.manage().window().getSize(); 43 | int startX = (int) (size.width * START_OFFSET); 44 | int endX = (int) (size.width * END_OFFSET); 45 | int startY = size.height / 4; 46 | driver.swipe(startX, startY, endX, startY, SWIPE_DURATION); 47 | 48 | acceptBadVideoAlert(); 49 | } 50 | 51 | private void acceptBadVideoAlert() throws InterruptedException { 52 | Thread.sleep(ALERT_POP_UP_DELAY); 53 | 54 | if (!driver.findElementsById("android:id/message").isEmpty()) { 55 | WebElement okButton = driver.findElementById("android:id/button1"); 56 | okButton.click(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/Pages/LocalWebViewPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.pagefactory.AndroidFindAll; 20 | import io.appium.java_client.pagefactory.AndroidFindBy; 21 | import org.openqa.selenium.WebElement; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * A Page representing a local web view 27 | */ 28 | public class LocalWebViewPage extends BasePage { 29 | /** 30 | * All of the text inputs 31 | */ 32 | @AndroidFindAll( 33 | @AndroidFindBy(className = "android.widget.EditText") 34 | ) 35 | private List inputs; 36 | 37 | /** 38 | * All of the views 39 | */ 40 | @AndroidFindAll( 41 | @AndroidFindBy(className = "android.view.View") 42 | ) 43 | private List output; 44 | 45 | 46 | public LocalWebViewPage(AppiumDriver driver) { 47 | super(driver); 48 | } 49 | 50 | /** 51 | * Enter the a name into the text fields 52 | * 53 | * @param first first name 54 | * @param last last name 55 | * 56 | * @return true if names entered in correctly, else false. 57 | */ 58 | public boolean enterName(String first, String last) throws InterruptedException { 59 | boolean firstNameStatus = sendKeysToElement(first, inputs.get(0), false); 60 | boolean lastNameStatus = sendKeysToElement(last, inputs.get(1), false); 61 | 62 | return firstNameStatus && lastNameStatus; 63 | } 64 | 65 | /** 66 | * 67 | * @return full name text 68 | */ 69 | public String getFullName() { 70 | return output.get(output.size()-1).getAttribute("content-desc").split("Hello!")[1]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/Pages/AlertPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.MobileElement; 20 | import io.appium.java_client.pagefactory.AndroidFindBy; 21 | 22 | /** 23 | * A page for alerts 24 | */ 25 | public class AlertPage extends BasePage { 26 | /** 27 | * The alert button 28 | */ 29 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/notifications_alert_button") 30 | private MobileElement alertButton; 31 | 32 | /** 33 | * The toast button 34 | */ 35 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/notifications_toast_button") 36 | private MobileElement toastButton; 37 | 38 | public AlertPage(AppiumDriver driver) { 39 | super(driver); 40 | } 41 | 42 | /** 43 | * Toast isn't directly supported by Appium. The recommended way is to 44 | * take a screen shot and use a OCR program to read the toast content 45 | */ 46 | public void clickToastButton() { 47 | toastButton.click(); 48 | } 49 | 50 | /** 51 | * clicks the alert button 52 | */ 53 | public void clickAlertsButton() { 54 | alertButton.click(); 55 | } 56 | 57 | /** 58 | * 59 | * @return the message within the alert 60 | */ 61 | public String getAlertText() { 62 | MobileElement alertMessage = (MobileElement) driver.findElementsByClassName("android.widget.TextView").get(1); 63 | return alertMessage.getText(); 64 | } 65 | 66 | /** 67 | * accepts the alert 68 | */ 69 | public void acceptAlertMessage() { 70 | MobileElement alertOkButton = (MobileElement) driver.findElementsByClassName("android.widget.Button").get(0); 71 | alertOkButton.click(); 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/SpinnerPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.pagefactory.AndroidFindBy; 22 | import org.openqa.selenium.WebElement; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * A page for a spinner control 28 | */ 29 | public class SpinnerPage extends BasePage{ 30 | /** 31 | * saves the last entry 32 | */ 33 | private String selectedEntry; 34 | 35 | /** 36 | * The spinner control 37 | */ 38 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_spinner") 39 | private MobileElement spinner; 40 | 41 | /** 42 | * The text display 43 | */ 44 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_spinner_message") 45 | private MobileElement display; 46 | 47 | public SpinnerPage(AppiumDriver driver) { 48 | super(driver); 49 | selectedEntry = null; 50 | } 51 | 52 | /** 53 | * Selects a specific item from the spinner control 54 | * 55 | * @param index of the spinner items 56 | */ 57 | public void selectSpinnerAtIndex(int index) { 58 | spinner.click(); 59 | List entries = driver.findElementsByClassName("android.widget.TextView"); 60 | selectedEntry = entries.get(index).getText(); 61 | entries.get(index).click(); 62 | } 63 | 64 | /** 65 | * 66 | * @return the selected entry 67 | */ 68 | public String getSelectedEntry() { 69 | return selectedEntry; 70 | } 71 | 72 | /** 73 | * 74 | * @return the text from the display 75 | */ 76 | public String getDisplayText() { 77 | return display.getText(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/Pages/Inputs/GesturesPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages.Inputs; 17 | 18 | import Pages.BasePage; 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.MobileElement; 21 | import io.appium.java_client.SwipeElementDirection; 22 | import io.appium.java_client.TouchAction; 23 | import io.appium.java_client.pagefactory.AndroidFindBy; 24 | 25 | /** 26 | * A page for gestures 27 | */ 28 | public class GesturesPage extends BasePage { 29 | /** 30 | * A page that performs specific gestures 31 | */ 32 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_gesture_action_pad") 33 | private MobileElement gestureBox; 34 | 35 | /** 36 | * The displays which lists the performed gestures 37 | */ 38 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/input_gesture_content") 39 | private MobileElement display; 40 | 41 | 42 | public GesturesPage(AppiumDriver driver) { 43 | super(driver); 44 | } 45 | 46 | /** 47 | * Performs a single press 48 | */ 49 | public void singlePress() { 50 | gestureBox.click(); 51 | } 52 | 53 | /** 54 | * Performs a long press 55 | */ 56 | public void longPress() { 57 | TouchAction touchAction = new TouchAction(driver); 58 | touchAction.longPress(gestureBox).perform(); 59 | } 60 | 61 | /** 62 | * performs a fling gesture 63 | */ 64 | public void flingGesture() { 65 | try { 66 | gestureBox.swipe(SwipeElementDirection.UP, 10, 10, 100); 67 | } catch (Exception e) {} // Catch "The swipe did not complete successfully" error 68 | } 69 | 70 | /** 71 | * 72 | * @return the text of the last action performed 73 | */ 74 | public String getLastAction(){ 75 | String[] entries = display.getText().split("\n"); 76 | return entries[entries.length - 1]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/test/java/Pages/FixturesPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.MobileElement; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * A page representing the fixtures 25 | */ 26 | public class FixturesPage extends BasePage { 27 | 28 | public FixturesPage(AppiumDriver driver) { 29 | super(driver); 30 | } 31 | 32 | /** 33 | * 34 | * @return wifi status 35 | */ 36 | public String getWifi() { 37 | return getStatus("Wifi:"); 38 | } 39 | 40 | /** 41 | * 42 | * @return bluetooth status 43 | */ 44 | public String getBluetooth() { 45 | return getStatus("Bluetooth:"); 46 | } 47 | 48 | /** 49 | * 50 | * @return gps status 51 | */ 52 | public String getGps() { 53 | return getStatus("GPS:"); 54 | } 55 | 56 | /** 57 | * 58 | * @return nfc status 59 | */ 60 | public String getNfc() { 61 | return getStatus("NFC:"); 62 | } 63 | 64 | /** 65 | * Helper function to retrieve the status of inputted radio name. 66 | * 67 | * @param radioName should be followed by a colon, for example: "NFC:" 68 | * @return status of radio signal as a String 69 | */ 70 | private String getStatus(String radioName) { 71 | driver.scrollTo(radioName); 72 | List textViews = driver.findElementsByClassName("android.widget.TextView"); 73 | 74 | int idx; 75 | 76 | // Retrieve index of desired radio text view 77 | for (idx = textViews.size() - 1; idx >= 0; idx--) { 78 | if (((MobileElement) textViews.get(idx)).getText().equals(radioName)) { 79 | break; 80 | } 81 | } 82 | 83 | // Desired radio status comes immediately after its name. For example: NFC: true 84 | return ((MobileElement) textViews.get(idx + 1)).getText(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/Pages/NavigationPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.pagefactory.AndroidFindBy; 20 | import org.openqa.selenium.NoSuchElementException; 21 | import org.openqa.selenium.WebElement; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | /** 27 | * A page for navigation drawer 28 | */ 29 | public class NavigationPage extends BasePage{ 30 | 31 | private final int TRIES = 5; 32 | 33 | /** 34 | * Get the toggle button 35 | */ 36 | @AndroidFindBy(accessibility = "ReferenceApp") 37 | private WebElement toggle; 38 | 39 | public NavigationPage(AppiumDriver driver) { 40 | super(driver); 41 | } 42 | 43 | /** 44 | * Go to a specific category within the navigation drawer 45 | * 46 | * @param categoryName category 47 | */ 48 | public void gotoCategory(String categoryName) { 49 | int counter = 0; 50 | toggle.click(); 51 | try { 52 | Thread.sleep(WaitConfig.DRAWER_ANIMATION_WAIT); 53 | } catch (InterruptedException e) { 54 | e.printStackTrace(); 55 | } 56 | 57 | WebElement categoryElement = null; 58 | List categoryElements; 59 | 60 | while (categoryElement == null) { 61 | counter++; 62 | if (counter == TRIES) 63 | return; 64 | categoryElements = driver.findElementsById("com.amazonaws.devicefarm.android.referenceapp:id/drawer_row_title"); 65 | for (WebElement categoryTitleElement: categoryElements){ 66 | String titleText = categoryTitleElement.getText(); 67 | if (titleText.equalsIgnoreCase(categoryName)) categoryElement = categoryTitleElement; 68 | 69 | } 70 | if (categoryElement == null) { 71 | driver.scrollTo(categoryName); 72 | } 73 | } 74 | 75 | categoryElement.click(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/Tests/Inputs/GesturesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.Inputs; 17 | 18 | import Pages.Inputs.GesturesPage; 19 | import Tests.AbstractBaseTests.InputTests; 20 | import org.testng.Assert; 21 | import org.testng.annotations.BeforeTest; 22 | import org.testng.annotations.Test; 23 | 24 | /** 25 | * Tests for Gestures 26 | */ 27 | public class GesturesTest extends InputTests { 28 | private static final String FLING_COMMAND = "Fling"; 29 | private static final String LONG_COMMAND = "Long Press"; 30 | private static final String SINGLE_TAP_COMMAND = "Single tap confirmed"; 31 | 32 | private GesturesPage gesturesPage; 33 | 34 | /** 35 | * Sets the page view index so it can be navigated to 36 | * 37 | * @return the pageview index 38 | */ 39 | @Override 40 | public int pageIndex() { 41 | return 9; 42 | } 43 | 44 | /** 45 | * Creates a Gestures page 46 | */ 47 | @BeforeTest 48 | @Override 49 | public void setUpPage() { 50 | gesturesPage = new GesturesPage(driver); 51 | } 52 | 53 | /** 54 | * Performs a fling and verifies if the action was registered 55 | * by checking if its command name is shown. 56 | */ 57 | @Test 58 | public void testFling() { 59 | gesturesPage.flingGesture(); 60 | Assert.assertEquals(gesturesPage.getLastAction(), FLING_COMMAND); 61 | } 62 | 63 | /** 64 | * Performs a long press and verifies if the action was registered 65 | * by checking if its command name is shown. 66 | */ 67 | @Test 68 | public void testLongPress() { 69 | gesturesPage.longPress(); 70 | Assert.assertEquals(gesturesPage.getLastAction(), LONG_COMMAND); 71 | } 72 | 73 | /** 74 | * Performs a single press and verifies if the action was registered 75 | * by checking if its command name is shown. 76 | */ 77 | @Test 78 | public void testSinglePress() { 79 | gesturesPage.singlePress(); 80 | Assert.assertEquals(gesturesPage.getLastAction(), SINGLE_TAP_COMMAND); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/Tests/LoginTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests; 17 | 18 | import Pages.LoginPage; 19 | import Tests.AbstractBaseTests.TestBase; 20 | import org.testng.Assert; 21 | import org.testng.annotations.AfterMethod; 22 | import org.testng.annotations.BeforeTest; 23 | import org.testng.annotations.Test; 24 | 25 | /** 26 | * Tests for a login page 27 | */ 28 | public class LoginTest extends TestBase { 29 | private static final String LOGIN_SUCCESS_MESSAGE = "You are logged on as admin"; 30 | private static final String LOGIN_FAIL_MESSAGE = "You gave me the wrong username and password"; 31 | private static final String CORRECT_USER_NAME = "admin"; 32 | private static final String CORRECT_PASSWORD = "password"; 33 | private static final String FAIL_USER_NAME = "Wrong User"; 34 | private static final String FAIL_PASSWORD = "12345"; 35 | private static final String BAD_TEXT_ENTRY_MSG = "Username sent to text field incorrectly"; 36 | 37 | private LoginPage loginPage; 38 | 39 | @Override 40 | public String getName() { 41 | return "Login Page"; 42 | } 43 | 44 | /** 45 | * Creates a login 46 | */ 47 | @BeforeTest 48 | @Override 49 | public void setUpPage() { 50 | loginPage = new LoginPage(driver); 51 | } 52 | 53 | /** 54 | * Tests logging in with valid credentials by verifying if the login message is correct 55 | */ 56 | @Test 57 | public void loginSuccess() throws InterruptedException { 58 | Assert.assertTrue(loginPage.login(CORRECT_USER_NAME, CORRECT_PASSWORD), BAD_TEXT_ENTRY_MSG); 59 | Assert.assertEquals(loginPage.getMessage(), LOGIN_SUCCESS_MESSAGE); 60 | } 61 | 62 | /** 63 | * Tests logging in with invalid credentials by verifying if the error message is correct 64 | */ 65 | @Test 66 | public void loginFail() throws InterruptedException { 67 | Assert.assertTrue(loginPage.login(FAIL_USER_NAME, FAIL_PASSWORD), BAD_TEXT_ENTRY_MSG); 68 | Assert.assertEquals(loginPage.getMessage(), LOGIN_FAIL_MESSAGE); 69 | } 70 | 71 | /** 72 | * After each test method, logout or try again 73 | */ 74 | @AfterMethod 75 | public void logOut() { 76 | loginPage.pressAltButton(); 77 | Assert.assertTrue(loginPage.checkIfBackAtLogin()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/Pages/LoginPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.MobileElement; 20 | import io.appium.java_client.pagefactory.AndroidFindBy; 21 | 22 | /** 23 | * A login page 24 | */ 25 | public class LoginPage extends BasePage { 26 | private static final int KEYBOARD_ANIMATION_DELAY = 1000; 27 | 28 | /** 29 | * The login button 30 | */ 31 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/login_button") 32 | private MobileElement loginButton; 33 | 34 | /** 35 | * The user name input 36 | */ 37 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/username_text_input") 38 | private MobileElement usernameField; 39 | 40 | /** 41 | * The password input 42 | */ 43 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/password_text_input") 44 | private MobileElement passwordField; 45 | 46 | public LoginPage(AppiumDriver driver) { 47 | super(driver); 48 | } 49 | 50 | /** 51 | * Tries to login with a set of credentials 52 | * 53 | * @param username the username 54 | * @param password the password 55 | * 56 | * @return true if username was entered in correctly, else false. 57 | */ 58 | public boolean login(String username, String password) throws InterruptedException { 59 | boolean usernameStatus = sendKeysToElement(username, usernameField, false); 60 | 61 | passwordField.click(); 62 | Thread.sleep(KEYBOARD_ANIMATION_DELAY); 63 | passwordField.sendKeys(password); 64 | 65 | loginButton.click(); 66 | 67 | return usernameStatus; 68 | } 69 | 70 | /** 71 | * 72 | * @return the login message 73 | */ 74 | public String getMessage() { 75 | return driver.findElementById("Alt Message").getText(); 76 | } 77 | 78 | /** 79 | * Checks to see if back at login page 80 | * 81 | * @return is back at login 82 | */ 83 | public boolean checkIfBackAtLogin() { 84 | return loginButton.isDisplayed() && usernameField.isDisplayed() && passwordField.isDisplayed(); 85 | } 86 | 87 | /** 88 | * Presses the logout/try again button 89 | */ 90 | public void pressAltButton() { 91 | driver.findElementById("Alt Button").click(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/Pages/BasePage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | 19 | import io.appium.java_client.AppiumDriver; 20 | import io.appium.java_client.pagefactory.AppiumFieldDecorator; 21 | import org.openqa.selenium.WebElement; 22 | import org.openqa.selenium.support.PageFactory; 23 | 24 | import java.util.concurrent.TimeUnit; 25 | 26 | /** 27 | * A base for all the pages within the suite 28 | */ 29 | public abstract class BasePage { 30 | private static final int KEYBOARD_ANIMATION_DELAY = 1000; 31 | private static final int XML_REFRESH_DELAY = 1000; 32 | 33 | /** 34 | * The driver 35 | */ 36 | protected final AppiumDriver driver; 37 | 38 | /** 39 | * A base constructor that sets the page's driver 40 | * 41 | * The page structure is being used within this test in order to separate the 42 | * page actions from the tests. 43 | * 44 | * Please use the AppiumFieldDecorator class within the page factory. This way annotations 45 | * like @AndroidFindBy within the page objects. 46 | * 47 | * @param driver the appium driver created in the beforesuite method. 48 | */ 49 | protected BasePage(AppiumDriver driver){ 50 | this.driver = driver; 51 | PageFactory.initElements(new AppiumFieldDecorator(driver, 5, TimeUnit.SECONDS), this); 52 | } 53 | 54 | /** 55 | * Tries three times to send text to element properly. 56 | * 57 | * Note: This method was needed because Appium sometimes sends text to textboxes incorrectly. 58 | * 59 | * @param input String to be sent 60 | * @param element WebElement to receive text, cannot be a secure text field. 61 | * @param appendNewLine true to append a new line character to incoming string when sending to element, else false 62 | * 63 | * @return true if keys were successfully sent, otherwise false. 64 | */ 65 | protected boolean sendKeysToElement(String input, WebElement element, boolean appendNewLine) throws InterruptedException { 66 | final int MAX_ATTEMPTS = 3; 67 | int attempts = 0; 68 | 69 | do { 70 | element.clear(); 71 | Thread.sleep(KEYBOARD_ANIMATION_DELAY); 72 | 73 | if (appendNewLine) { 74 | element.sendKeys(input + "\n"); 75 | } else { 76 | element.sendKeys(input); 77 | } 78 | 79 | Thread.sleep(XML_REFRESH_DELAY); 80 | } while (!element.getText().contains(input) && ++attempts < MAX_ATTEMPTS); 81 | 82 | return element.getText().contains(input); 83 | } 84 | } -------------------------------------------------------------------------------- /src/test/java/Pages/NestedViewsPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.AppiumDriver; 19 | import io.appium.java_client.MobileElement; 20 | import io.appium.java_client.pagefactory.AndroidFindBy; 21 | 22 | import java.util.List; 23 | 24 | /** 25 | * Nested Views Page 26 | */ 27 | public class NestedViewsPage extends BasePage { 28 | /** 29 | * Up option button 30 | */ 31 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/nested_up_button") 32 | private MobileElement upButton; 33 | 34 | /** 35 | * Back option button 36 | */ 37 | @AndroidFindBy(id = "com.amazonaws.devicefarm.android.referenceapp:id/nested_back_button") 38 | private MobileElement backButton; 39 | 40 | public NestedViewsPage(AppiumDriver driver) { 41 | super(driver); 42 | } 43 | 44 | /** 45 | * Press the back button category 46 | */ 47 | public void pressBackButtonCategory() { 48 | backButton.click(); 49 | } 50 | 51 | /** 52 | * Press the up button category 53 | */ 54 | public void pressUpButtonCategory() { 55 | upButton.click(); 56 | } 57 | 58 | /** 59 | * 60 | * @return up message text 61 | */ 62 | public String getUpMessage() { 63 | List textViews = driver.findElementsByClassName("android.widget.TextView"); 64 | return ((MobileElement) textViews.get(textViews.size() - 1)).getText(); 65 | } 66 | 67 | /** 68 | * Presses the next button 69 | */ 70 | public void pressNextUpButton() { 71 | driver.findElementById("com.amazonaws.devicefarm.android.referenceapp:id/nested_up_button").click(); 72 | } 73 | 74 | /** 75 | * Presses the up button in the toolbar 76 | */ 77 | public void navigateUp() { 78 | driver.findElementByAccessibilityId("Navigate up").click(); 79 | } 80 | 81 | /** 82 | * Presses the back button 83 | */ 84 | public void pressBackButton() { 85 | driver.navigate().back(); 86 | } 87 | 88 | /** 89 | * Presses the next button 90 | */ 91 | public void pressNextBackButton() { 92 | driver.findElementById("com.amazonaws.devicefarm.android.referenceapp:id/back_navigation_next_button").click(); 93 | } 94 | 95 | /** 96 | * 97 | * @return the counter text 98 | */ 99 | public String getCounter() { 100 | return driver.findElementByAccessibilityId("Level Display").getText(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/Tests/NestedViewsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests; 17 | 18 | import Pages.NestedViewsPage; 19 | import Tests.AbstractBaseTests.TestBase; 20 | import org.testng.Assert; 21 | import org.testng.annotations.AfterMethod; 22 | import org.testng.annotations.BeforeTest; 23 | import org.testng.annotations.Test; 24 | 25 | /** 26 | * Tests for nested views 27 | */ 28 | public class NestedViewsTest extends TestBase { 29 | private NestedViewsPage nestedViewsPage; 30 | private static final String UP_MESSAGE_1 = "Press to go to the next level"; 31 | private static final String UP_MESSAGE_2 = "Final Level"; 32 | 33 | private static final int NUMBER_NEXT_BACK_BUTTON = 8; 34 | private static final int NUMBER_BACK_BUTTON = 6; 35 | private static final String NEXT_BACK_BUTTON_COUNTER_BEFORE = "9"; 36 | private static final String NEXT_BACK_BUTTON_COUNTER_AFTER = "3"; 37 | 38 | @Override 39 | public String getName() { 40 | return "Nested Views"; 41 | } 42 | 43 | @BeforeTest 44 | @Override 45 | public void setUpPage() { 46 | nestedViewsPage = new NestedViewsPage(driver); 47 | } 48 | 49 | /** 50 | * Tests the back button by going up a specific amount, 51 | * going back to a by a specific amount, and then asserting 52 | * the difference 53 | */ 54 | @Test 55 | public void testBackButton() { 56 | nestedViewsPage.pressBackButtonCategory(); 57 | 58 | for (int i = 0; i < NUMBER_NEXT_BACK_BUTTON; i++) { 59 | nestedViewsPage.pressNextBackButton(); 60 | } 61 | 62 | Assert.assertEquals(nestedViewsPage.getCounter(), NEXT_BACK_BUTTON_COUNTER_BEFORE); 63 | 64 | for (int i = 0; i < NUMBER_BACK_BUTTON; i++) { 65 | nestedViewsPage.pressBackButton(); 66 | } 67 | 68 | Assert.assertEquals(nestedViewsPage.getCounter(), NEXT_BACK_BUTTON_COUNTER_AFTER); 69 | } 70 | 71 | /** 72 | * Tests the up button by going up 73 | */ 74 | @Test 75 | public void testUpButton() { 76 | nestedViewsPage.pressUpButtonCategory(); 77 | 78 | Assert.assertEquals(nestedViewsPage.getUpMessage(), UP_MESSAGE_1); 79 | 80 | nestedViewsPage.pressNextUpButton(); 81 | 82 | Assert.assertEquals(nestedViewsPage.getUpMessage(), UP_MESSAGE_2); 83 | 84 | nestedViewsPage.navigateUp(); 85 | 86 | Assert.assertEquals(nestedViewsPage.getUpMessage(), UP_MESSAGE_1); 87 | } 88 | 89 | /** 90 | * Navigate up to reset the test 91 | */ 92 | @AfterMethod 93 | public void goBackToMenu() { 94 | nestedViewsPage.navigateUp(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.amazon.aws.adf.referenceapp.appium.test 8 | Referenceapp-Appium-Test 9 | 1.0-SNAPSHOT 10 | jar 11 | ReferenceAppAppiumTests 12 | http://maven.apache.org 13 | 14 | 15 | 16 | org.testng 17 | testng 18 | 6.8.8 19 | test 20 | 21 | 22 | io.appium 23 | java-client 24 | 3.1.0 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-jar-plugin 33 | 2.6 34 | 35 | 36 | 37 | test-jar 38 | 39 | 40 | 41 | 42 | 43 | org.apache.maven.plugins 44 | maven-dependency-plugin 45 | 2.10 46 | 47 | 48 | copy-dependencies 49 | package 50 | 51 | copy-dependencies 52 | 53 | 54 | ${project.build.directory}/dependency-jars/ 55 | 56 | 57 | 58 | 59 | 60 | maven-assembly-plugin 61 | 2.5.4 62 | 63 | 64 | package 65 | 66 | single 67 | 68 | 69 | zip-with-dependencies 70 | false 71 | 72 | src/main/assembly/zip.xml 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/test/java/Tests/AbstractBaseTests/TestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Tests.AbstractBaseTests; 17 | 18 | import Pages.NavigationPage; 19 | import io.appium.java_client.MobileElement; 20 | import io.appium.java_client.android.AndroidDriver; 21 | import org.openqa.selenium.remote.DesiredCapabilities; 22 | import org.testng.annotations.*; 23 | 24 | import java.net.MalformedURLException; 25 | import java.net.URL; 26 | import java.util.concurrent.TimeUnit; 27 | 28 | /** 29 | * An abstract base for all of the Android tests within this package 30 | * 31 | * Responsible for setting up the Appium test Driver 32 | */ 33 | public abstract class TestBase { 34 | /** 35 | * Make the driver static. This allows it to be created only once 36 | * and used across all of the test classes. 37 | */ 38 | public static AndroidDriver driver; 39 | 40 | /** 41 | * This allows the navigation to work within the app. 42 | * The category name is returned so we can navigate to it from the navigation 43 | * drawer. 44 | * 45 | * @return The name of the Android category 46 | */ 47 | public abstract String getName(); 48 | 49 | /** 50 | * A page containing the navigation drawer 51 | */ 52 | private NavigationPage navigationPage; 53 | 54 | /** 55 | * Method to initialize the test's page 56 | */ 57 | @BeforeTest 58 | public abstract void setUpPage(); 59 | 60 | /** 61 | * This method runs before any other method. 62 | * 63 | * Appium follows a client - server model: 64 | * We are setting up our appium client in order to connect to Device Farm's appium server. 65 | * 66 | * We do not need to and SHOULD NOT set our own DesiredCapabilities 67 | * Device Farm creates custom settings at the server level. Setting your own DesiredCapabilities 68 | * will result in unexpected results and failures. 69 | * 70 | * @throws MalformedURLException An exception that occurs when the URL is wrong 71 | */ 72 | @BeforeSuite 73 | public void setUpAppium() throws MalformedURLException { 74 | 75 | final String URL_STRING = "http://127.0.0.1:4723/wd/hub"; 76 | 77 | URL url = new URL(URL_STRING); 78 | 79 | //Use a empty DesiredCapabilities object 80 | DesiredCapabilities capabilities = new DesiredCapabilities(); 81 | 82 | driver = new AndroidDriver(url, capabilities); 83 | 84 | //Use a higher value if your mobile elements take time to show up 85 | driver.manage().timeouts().implicitlyWait(35, TimeUnit.SECONDS); 86 | } 87 | 88 | /** 89 | * Always remember to quit 90 | */ 91 | @AfterSuite 92 | public void tearDownAppium() { 93 | driver.quit(); 94 | } 95 | 96 | /** 97 | * 98 | * Creates a navigation page and navigates to the Class' category 99 | * within the navigation drawer 100 | * 101 | */ 102 | @BeforeClass 103 | public void navigateTo() throws InterruptedException { 104 | navigationPage = new NavigationPage(driver); 105 | navigationPage.gotoCategory(getName()); 106 | } 107 | 108 | /** 109 | * Restart the app after every test class to go back to the main 110 | * screen and to reset the behavior 111 | */ 112 | @AfterClass 113 | public void restartApp() { 114 | driver.resetApp(); 115 | } 116 | } -------------------------------------------------------------------------------- /src/test/java/Pages/WebViewPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | package Pages; 17 | 18 | import io.appium.java_client.android.AndroidDriver; 19 | import org.openqa.selenium.*; 20 | import org.openqa.selenium.support.ui.ExpectedConditions; 21 | import org.openqa.selenium.support.ui.WebDriverWait; 22 | 23 | /** 24 | * Web page representation. 25 | */ 26 | public class WebViewPage extends BasePage { 27 | private static final String WEB_HEADER_CSS_NAME = "a[name=\"AWS_Documentation\"]"; 28 | private static final String TEXT_FIELD_CLASS = "android.widget.EditText"; 29 | private static final int MAX_WEBSITE_LOAD_TIME = 10; 30 | 31 | public WebViewPage(AndroidDriver driver) { 32 | super(driver); 33 | } 34 | 35 | /** 36 | * Navigates to URL, sleeps for WEBSITE_LOAD_TIME. 37 | * 38 | * @param url String must be in format "http://____" 39 | * @throws InterruptedException 40 | */ 41 | public boolean goToUrl(String url) throws InterruptedException { 42 | WebElement navBar = driver.findElementByClassName(TEXT_FIELD_CLASS); 43 | return sendKeysToElement(url, navBar, true); 44 | } 45 | 46 | /** 47 | * Checks if web description is loaded. 48 | * 49 | * Note: Will fail if Android version is < 4.4 or >= 6.0. Hybrid views are not compatible with 50 | * versions < 4.4 and Appium context switching is currently buggy on devices running versions >= 6.0. 51 | * 52 | * @return true if it is, else false. 53 | */ 54 | public boolean webDescriptionIsLoaded() throws InterruptedException { 55 | Object[] contextHandles = driver.getContextHandles().toArray(); 56 | String androidVersion = driver.getCapabilities().getCapability("platformVersion").toString(); 57 | 58 | if (versionLessThan(androidVersion, "4.4")) { 59 | return true; 60 | } else if (versionGreaterThanOrEqual(androidVersion, "6.0")) { 61 | return false; 62 | } 63 | 64 | String webViewContent = (String) contextHandles[contextHandles.length - 1]; 65 | WebDriver webDriver = driver.context(webViewContent); 66 | 67 | try { 68 | WebDriverWait wait = new WebDriverWait(webDriver, MAX_WEBSITE_LOAD_TIME); 69 | wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(WEB_HEADER_CSS_NAME))); 70 | wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(WEB_HEADER_CSS_NAME))); 71 | } catch (TimeoutException e) { 72 | return false; // MAX_WEBSITE_LOAD_TIME timeout exceeded - bad internet connection. 73 | } 74 | 75 | WebElement webHeader = webDriver.findElement(By.cssSelector(WEB_HEADER_CSS_NAME)); 76 | return webHeader.isDisplayed(); 77 | } 78 | 79 | /** 80 | * Helper function that compares Android versions. 81 | * 82 | * @param version1 Numbers separated by period, i.e. "1.2.3" 83 | * @param version2 Numbers separated by period, i.e. "1.2.3" 84 | * 85 | * @return -1 if version1 is smaller, 0 if same, 1 if version1 is bigger. 86 | */ 87 | private int compareVersions(String version1, String version2) { 88 | String[] versions1 = version1.split("\\."); 89 | String[] versions2 = version2.split("\\."); 90 | 91 | int maxLength = Math.max(versions1.length, versions2.length); 92 | 93 | for (int i = 0; i < maxLength; i++) { 94 | int versionNumber1 = i < versions1.length ? Integer.parseInt(versions1[i]) : -1; 95 | int versionNumber2 = i < versions2.length ? Integer.parseInt(versions2[i]) : -1; 96 | 97 | if (versionNumber1 < versionNumber2) { 98 | return -1; 99 | } else if (versionNumber1 > versionNumber2) { 100 | return 1; 101 | } 102 | } 103 | 104 | return 0; 105 | } 106 | 107 | /** 108 | * Checks if version1 is greater than or equal to version2. 109 | * 110 | * @param version1 Numbers separated by period, i.e. "1.2.3" 111 | * @param version2 Numbers separated by period, i.e. "1.2.3" 112 | * 113 | * @return version1 >= version2 114 | */ 115 | private boolean versionGreaterThanOrEqual(String version1, String version2) { 116 | return compareVersions(version1, version2) >= 0; 117 | } 118 | 119 | /** 120 | * Checks if version1 is less than version2. 121 | * 122 | * @param version1 Numbers separated by period, i.e. "1.2.3" 123 | * @param version2 Numbers separated by period, i.e. "1.2.3" 124 | * 125 | * @return version1 < version2 126 | */ 127 | private boolean versionLessThan(String version1, String version2) { 128 | return compareVersions(version1, version2) == -1; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Appium Sample Tests for AWS Device Farm Sample App 2 | This is a collection of example Appium TestNG tests written for the AWS Device Farm [Android](https://github.com/awslabs/aws-device-farm-sample-app-for-android) sample app. Please use these tests as a reference for your own AWS Device Farm Appium TestNG tests. 3 | 4 | **This test suite uses the [Appium page model](http://appium.io/slate/en/tutorial/android?java#page-object-pattern) in order to separate the tests from the logic.** 5 | 6 | # Android 7 | ## Getting Started 8 | 1. Follow the **[official Appium getting started guide](http://appium.io/slate/en/tutorial/android.html?java#getting-started-with-appium)** and install the Appium server and dependencies. 9 | 10 | **AWS Device Farm supports Appium version 1.7.2. Using a different version locally may cause unexpected results when running Appium tests on AWS Device Farm.** 11 | 2. In order to use 1.7.2, download Appium through NPM with this command: 12 | ``` 13 | npm install -g appium@1.7.2 14 | ``` 15 | 3. Verify that you have Appium installed with this command: 16 | ``` 17 | appium -v 18 | ``` 19 | You should get "1.7.2" as the output 20 | 21 | ## Creating a new Java Appium Test Project Using Maven 22 | 1. Create a new Maven project using a Java IDE. **The example in this tutorial is for [IntelliJ IDEA Community Edition](http://www.jetbrains.com/idea/download/)**. 23 | 24 | 2. Set up your POM file using the official AWS Device Farm documentation for [TestNG](http://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-android-appium-java-testng.html) 25 | - You will need the following dependencies in your POM file 26 | 27 | ``` 28 | 29 | 30 | org.testng 31 | testng 32 | 6.11 33 | test 34 | 35 | 36 | io.appium 37 | java-client 38 | 4.1.2 39 | 40 | 41 | ``` 42 | 43 | ### Running Your Tests Locally 44 | First, make sure that you have followed all the steps in the [Appium getting started guide](http://appium.io/slate/en/tutorial/android.html?java#getting-started-with-appium). 45 | 46 | Use the script [start-appium-android.sh](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/start-appium-android.sh) to run the Appium server locally. Once the server has started, run the TestNG tests within your IDE. 47 | 48 | For example, if your package name is **com.appium.example**, your main activity name is **.Activities.MainActivity**, and the absolute filepath to your APK is **~/Desktop/appium/app.apk**, you would run the following command. 49 | 50 | ``` 51 | appium --pre-launch --app-pkg com.appium.example --app-activity .Activities.MainActivity --platform-name Android --app ~/Desktop/appium/app.apk 52 | ``` 53 | 54 | ### Running Your Tests on AWS Device Farm 55 | #### Step 1: Verify the Project Set-up 56 | First Read the [Device Farm documentation](http://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-android-calabash.html). Ensure that all the steps are completed and that your project and POM file are set up correctly. 57 | 58 | #### Step 2: Go into your Maven Appium Directory 59 | Go into your Appium Maven project directory in the terminal or command prompt. 60 | 61 | #### Step 3: Package the Test Content 62 | Run the following Maven command to package the test content. 63 | ``` 64 | mvn clean package -DskipTests=true 65 | ``` 66 | #### Step 4: Locate the zip-with-dependencies.zip file 67 | Once the Maven command above is finished it will produce a "zip-with-dependencies.zip" file in your target folder. You will upload this file when [creating a run](http://docs.aws.amazon.com/devicefarm/latest/developerguide/how-to-create-test-run.html) on AWS Device Farm. 68 | 69 | 70 | 71 | ## Examples For Android 72 | ### Examples for Testing Specific Scenarios 73 | |Component|Android Implementation|Tests| 74 | |----------|----------------------|-------| 75 | |Alerts: [Toasts](http://developer.android.com/guide/topics/ui/notifiers/toasts.html) and [Dialogs](http://developer.android.com/guide/topics/ui/dialogs.html) | [source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/NotificationsFragment.java) |[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/AlertPageTest.java)| 76 | |Fixtures|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/FixturesFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/FixturesTest.java)| 77 | |Static Page: [TextView](http://developer.android.com/reference/android/widget/TextView.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/res/layout/fragment_homepage.xml)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/HomePageTest.java)| 78 | |Login Page|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/LoginFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/LoginTest.java)| 79 | |Nested Views: [Back and Up Navigation](http://developer.android.com/design/patterns/navigation.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/NestedFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/NestedViewsTest.java)| 80 | |[Web Views](http://developer.android.com/reference/android/webkit/WebView.html)||
  • Hybrid Web Views (Not implemented)
  • Web View
| 81 | | An Expected Crash|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/crashFragment.java)|Not implemented| 82 | 83 | ### Strategies for Native Features 84 | |Feature|Android Implementation|Tests| 85 | |--------|----------------------|-------| 86 | |[Camera](http://developer.android.com/guide/topics/media/camera.html) |[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Native/Native_CameraFragment.java) |[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Native/CameraTest.java)| 87 | |[Image Collection Grid](http://developer.android.com/guide/topics/ui/layout/gridview.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Native/Native_ImageGalleryFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Native/ImageGalleryTest.java)| 88 | |[Scroll View](http://developer.android.com/reference/android/widget/ScrollView.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/res/layout/native_content_scrolling.xml)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Native/ScrollViewTest.java) 89 | |Out of View Content|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/res/layout/native_out_of_view_scrolling.xml)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Native/OutOfViewTest.java)| 90 | |[Video](http://developer.android.com/reference/android/media/MediaPlayer.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Native/Native_MediaPlayer.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Native/MediaPlayerTest.java)| 91 | 92 | ### Examples for Testing Inputs 93 | |Component|Android Implementation|Tests| 94 | |--------------|---------|----------| 95 | |[Checkbox](http://developer.android.com/reference/android/widget/CheckBox.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_CheckBoxFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/CheckboxTest.java)| 96 | |[DatePicker](http://developer.android.com/reference/android/widget/DatePicker.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_DatePickerFragment.java)|Not implemented (not directly supported by Appium)| 97 | |[EditText](http://developer.android.com/reference/android/widget/EditText.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/res/layout/input_textfield.xml)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/EditTextTest.java)| 98 | |[Gestures Input](http://developer.android.com/training/gestures/index.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_GestureFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/GesturesTest.java)| 99 | |[Pull to Refresh](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_RefreshButtonFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/PullToRefreshTest.java)| 100 | |[Radio Buttons](http://developer.android.com/guide/topics/ui/controls/radiobutton.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_RadioButtonFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/RadioButtonTest.java)| 101 | |[TimePicker](http://developer.android.com/reference/android/widget/TimePicker.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_TimePickerFragment.java)|Not implemented (not directly supported by Appium)| 102 | |[Toggle Button](http://developer.android.com/guide/topics/ui/controls/togglebutton.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_Toggle_ButtonFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/ToggleButtonTest.java)| 103 | |[Spinner Input](http://developer.android.com/guide/topics/ui/controls/spinner.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_SpinnerFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/Inputs/SpinnerTest.java)| 104 | |[Buttons](http://developer.android.com/reference/android/widget/Button.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/Tabs/Inputs/Input_SubmitButtonFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Pages/AlertPage.java)| 105 | 106 | ### Examples for Automated Navigation 107 | |Component|Android Implementation|Tests| 108 | |--------------|---------|----------| 109 | |[Navigation Drawer](https://developer.android.com/training/implementing-navigation/nav-drawer.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/NavigationDrawerFragment.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Pages/NavigationPage.java)| 110 | |[ViewPager](http://developer.android.com/reference/android/support/v4/view/ViewPager.html)|[source code](https://github.com/awslabs/aws-device-farm-sample-app-for-android/blob/master/app/src/main/java/com/amazonaws/devicefarm/android/referenceapp/Fragments/TabFragmentContainer.java)|[source code](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Pages/TabViewPage.java)| 111 | 112 | ## Tips and Tricks 113 | #### Driver Configuration 114 | Remember to set up your Appium driver correctly. AWS Device Farm takes care of the configuration for you, and you don't need to set any of the DesiredCapabilities when creating the driver. Refer to **[this example](https://github.com/awslabs/aws-device-farm-appium-tests-for-sample-app/blob/master/src/test/java/Tests/AbstractBaseTests/TestBase.java#L75)**. 115 | --------------------------------------------------------------------------------