├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── NOTICE ├── README.md ├── package.json └── sample-code ├── apps ├── ApiDemos │ └── bin │ │ └── ApiDemos-debug.apk ├── ContactManager │ ├── ContactManager-selendroid.apk │ ├── ContactManager.apk │ └── README.md ├── RobotCalibration │ ├── RobotCalibration.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── RobotCalibration │ │ ├── Default-568h@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── RCAppDelegate.h │ │ ├── RCAppDelegate.m │ │ ├── RCViewController.h │ │ ├── RCViewController.m │ │ ├── RobotCalibration-Info.plist │ │ ├── RobotCalibration-Prefix.pch │ │ ├── en.lproj │ │ │ ├── InfoPlist.strings │ │ │ ├── MainStoryboard_iPad.storyboard │ │ │ └── MainStoryboard_iPhone.storyboard │ │ └── main.m │ └── RobotCalibrationTests │ │ ├── RobotCalibrationTests-Info.plist │ │ ├── RobotCalibrationTests.h │ │ ├── RobotCalibrationTests.m │ │ └── en.lproj │ │ └── InfoPlist.strings ├── RottenTomatoes.zip ├── RottenTomatoesPageSnapshot.html ├── RottenTomatoesSnapshot.html ├── TestApp │ ├── .DS_Store │ ├── .gitignore │ ├── README.md │ └── build │ │ └── Release-iphonesimulator │ │ └── TestApp-iphonesimulator.app │ │ ├── Default-568h@2x.png │ │ ├── GestureTestViewController.nib │ │ ├── Info.plist │ │ ├── PkgInfo │ │ ├── TestApp │ │ ├── _CodeSignature │ │ └── CodeResources │ │ └── en.lproj │ │ ├── InfoPlist.strings │ │ ├── Localizable.strings │ │ └── MyViewControllerViewController.nib ├── ToggleTest │ ├── .gitignore │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── libs │ │ └── android-support-v4.jar │ ├── res │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── layout │ │ │ └── activity_main.xml │ │ ├── menu │ │ │ └── main.xml │ │ ├── values-sw600dp │ │ │ └── dimens.xml │ │ ├── values-sw720dp-land │ │ │ └── dimens.xml │ │ ├── values-v11 │ │ │ └── styles.xml │ │ ├── values-v14 │ │ │ └── styles.xml │ │ └── values │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── src │ │ └── com │ │ └── example │ │ └── toggletest │ │ └── MainActivity.java ├── UICatalog.zip ├── VodQA.apk ├── VodQAReactNative.zip ├── WebViewApp │ ├── WebViewApp.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── WebViewApp │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Default-568h@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── ViewController.h │ │ ├── ViewController.m │ │ ├── WebViewApp-Info.plist │ │ ├── WebViewApp-Prefix.pch │ │ ├── cybervillainsCA.cer │ │ ├── en.lproj │ │ ├── InfoPlist.strings │ │ ├── MainStoryboard_iPad.storyboard │ │ └── MainStoryboard_iPhone.storyboard │ │ └── main.m ├── android-rottentomatoes-demo-debug.apk ├── chromedriver ├── chromedriverWin └── selendroid-test-app.apk └── examples ├── C# └── CalculatorTest │ ├── BasicScenarios.cs │ ├── CalculatorTest.csproj │ ├── CalculatorTest.sln │ ├── Properties │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── RobotFramework ├── test_android_contact_resource.txt ├── test_android_contacts.txt └── windows_calculatortest.txt ├── dotnet ├── .gitignore ├── AppiumDotNetSample.sln ├── AppiumDotNetSample │ ├── Android │ │ ├── AndroidActivityTest.cs │ │ ├── AndroidAppStringsTest.cs │ │ ├── AndroidConnectionTest.cs │ │ ├── AndroidElementTest.cs │ │ ├── AndroidEmulatorDeviceTime.cs │ │ ├── AndroidGestureTest.cs │ │ ├── AndroidKeyPressTest.cs │ │ ├── AndroidLocationTest.cs │ │ ├── AndroidLockDeviceTest.cs │ │ ├── AndroidOrientationTest.cs │ │ ├── AndroidSearchingTest.cs │ │ ├── AndroidSessionTest.cs │ │ ├── AndroidTouchActionTest.cs │ │ ├── AndroidWebviewTest.cs │ │ ├── FileInteractionTest.cs │ │ ├── HideKeyboardTestCase.cs │ │ └── IntentAndroidTest.cs │ ├── AppiumDotNetSample.csproj │ ├── PageObjectTests │ │ ├── Android │ │ │ ├── AndroidNativeAppAttributesTest.cs │ │ │ ├── AndroidTestThatChecksAttributeMix1.cs │ │ │ ├── AndroidTestThatChecksAttributeMix2.cs │ │ │ ├── AndroidTestThatChecksAttributeMix3SelendroidMode.cs │ │ │ ├── AndroidWebViewTest.cs │ │ │ └── SeleniumAttributesCompatipilityTest.cs │ │ ├── DesktopBrowserCompatibility │ │ │ └── DesktopBrowserCompatibilityTest.cs │ │ ├── IOS │ │ │ ├── IOSNativeAppAttributesTest.cs │ │ │ └── IOSTestThatChecksAttributeMix.cs │ │ ├── README.md │ │ └── TimeOutManagement │ │ │ └── TimeOutManagementTest.cs │ ├── PageObjects │ │ ├── AndroidPageObjectChecksAttributeMixOnNativeApp1.cs │ │ ├── AndroidPageObjectChecksAttributeMixOnNativeApp2.cs │ │ ├── AndroidPageObjectChecksAttributesForNativeAndroidApp.cs │ │ ├── AndroidPageObjectChecksSelendroidModeOnNativeApp.cs │ │ ├── AndroidPageObjectChecksSeleniumFindsByCompatibility.cs │ │ ├── AndroidWebView.cs │ │ ├── IOSPageObjectChecksAttributeMixOnNativeApp.cs │ │ ├── IOSPageObjectChecksAttributesForNativeIOSApp.cs │ │ └── README.md │ ├── Properties │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Resources │ │ ├── ApiDemos-debug.apk │ │ ├── IntentExample.apk │ │ ├── PathToLinuxNode │ │ ├── PathToMacOSNode │ │ ├── PathToWindowsNode │ │ ├── TestApp7.1.app.zip │ │ ├── UICatalog.zip │ │ ├── WebViewApp7.1.app.zip │ │ └── selendroid-test-app-0.10.0.apk │ ├── ServerTests │ │ ├── AppiumLocalServerLaunchingTest.cs │ │ └── StartingAppLocallyTest.cs │ ├── env.json.sample │ ├── helpers │ │ ├── AppiumServers.cs │ │ ├── Apps.cs │ │ ├── Caps.cs │ │ └── Env.cs │ ├── iOS │ │ ├── IOSLocationTest.cs │ │ ├── IOSScrollingSearchingTest.cs │ │ ├── IosGestureTest.cs │ │ ├── IosOrientationTest.cs │ │ ├── IosWebviewTest.cs │ │ ├── iOSAlertTest.cs │ │ ├── iOSAppStringsTest.cs │ │ ├── iOSElementTest.cs │ │ ├── iOSLockDeviceTest.cs │ │ ├── iOSSearchingTest.cs │ │ └── iOSTouchActionTest.cs │ └── packages.config ├── README.md └── assets │ └── index.html ├── java ├── Windows │ ├── pom.xml │ └── src │ │ └── test │ │ └── java │ │ └── CalculatorTest.java ├── appium-generic-test │ └── src │ │ └── test │ │ └── java │ │ ├── AndoridBrowserLocalTest.java │ │ ├── AndroidBrowserSaucelabsTest.java │ │ ├── IOSBrowserLocalTest.java │ │ ├── IOSBrowserSaucelabsTest.java │ │ └── SimpleIOSSauceTests.java ├── generic │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── Main.java │ │ └── test │ │ └── java │ │ ├── AndoridBrowserLocalTest.java │ │ ├── AndroidBrowserSaucelabsTest.java │ │ ├── IOSBrowserLocalTest.java │ │ ├── IOSBrowserSaucelabsTest.java │ │ └── SimpleIOSSauceTests.java └── junit │ ├── README.md │ ├── pom.xml │ └── src │ └── test │ └── java │ └── com │ └── saucelabs │ └── appium │ ├── AndroidDragAndDrop.java │ ├── AndroidPageObjectTest_ByAllPossible.java │ ├── AndroidPageObjectTest_Chained.java │ ├── AndroidPageObjectTest_PageObjectLikeComplexElement.java │ ├── AndroidPageObjectTest_Simple.java │ ├── AndroidPageObjectTest_TimeOutManagement.java │ ├── AndroidSlideTest.java │ ├── AndroidTest.java │ ├── AndroidWebViewTest.java │ ├── BaseCrossPlatformDriver.java │ ├── BaseDriver.java │ ├── GestureTest.java │ ├── MobileFindJavaTest.java │ ├── SafariTest.java │ ├── SauceTest.java │ ├── SimpleTest.java │ ├── UICatalogTest.java │ ├── driver_service │ ├── DriverServiceSample.java │ └── custom_node_path.properties │ ├── iOSPageObjectTest.java │ └── page_object │ ├── PageObjectWithCustomizedTimeOuts.java │ ├── android │ ├── ApiDemosListViewScreenByAllPossible.java │ ├── ApiDemosListViewScreenChaided.java │ └── ApiDemosListViewScreenSimple.java │ ├── ios │ └── TestAppScreenSimple.java │ └── widgets │ ├── AndroidOverrideWidgetTest.java │ ├── HtmlOverrideWidgetTest.java │ ├── IOSOverrideWidgetTest.java │ ├── Movie.java │ ├── Movies.java │ ├── README.md │ ├── Review.java │ ├── RottenTomatoes.java │ ├── SelendroidOverrideWidgetTest.java │ ├── WidgetTest.java │ ├── android │ ├── AndroidWidgetTest.java │ ├── RottenTomatoesApp.java │ ├── annotated │ │ ├── AnnotatedAndroidMovie.java │ │ ├── AnnotatedAndroidMovies.java │ │ └── AnnotatedAndroidReview.java │ ├── extended │ │ ├── ExtendedAndroidMovies.java │ │ └── ExtendedAndroidReview.java │ └── simple │ │ ├── AndroidMovie.java │ │ ├── AndroidMovies.java │ │ └── AndroidReview.java │ ├── combined │ ├── AndroidCombinedWidgetTest.java │ ├── HtmlCombinedWidgetTest.java │ ├── RottenTomatoesAppWithCombinedWidgets.java │ ├── SelendroidCombinedWidgetTest.java │ ├── annotated │ │ ├── AnnotatedCombinedMovie.java │ │ ├── AnnotatedCombinedMovies.java │ │ └── AnnotatedCombinedReview.java │ ├── extended │ │ ├── ExtendedCombinedMovies.java │ │ └── ExtendedCombinedReview.java │ └── simple │ │ ├── CombinedMovie.java │ │ ├── CombinedMovies.java │ │ └── CombinedReview.java │ ├── html │ ├── HtmlWidgetTest.java │ ├── RottenTomatoesSite.java │ ├── annotated │ │ ├── AnnotatedHtmlMovie.java │ │ ├── AnnotatedHtmlMovies.java │ │ └── AnnotatedHtmlReview.java │ ├── extended │ │ ├── ExtendedHtmlMovies.java │ │ └── ExtendedHtmlReview.java │ └── simple │ │ ├── HtmlMovie.java │ │ ├── HtmlMovies.java │ │ └── HtmlReview.java │ ├── ios │ ├── IOSWidgetTest.java │ ├── RottenTomatoesIOSApp.java │ ├── annotated │ │ ├── AnnotatedIOSMovie.java │ │ ├── AnnotatedIOSMovies.java │ │ └── AnnotatedIOSReview.java │ ├── extended │ │ ├── ExtendedIOSMovies.java │ │ └── ExtendedIOSReview.java │ └── simple │ │ ├── IOSMovie.java │ │ ├── IOSMovies.java │ │ └── IOSReview.java │ └── selendroid │ ├── RottenTomatoesSelendroidApp.java │ ├── SelendroidWidgetTest.java │ ├── annotated │ ├── AnnotatedSelendroidMovie.java │ ├── AnnotatedSelendroidMovies.java │ └── AnnotatedSelendroidReview.java │ ├── extended │ ├── ExtendedSelendroidMovies.java │ └── ExtendedSelendroidReview.java │ └── simple │ ├── SelendroidMovie.java │ ├── SelendroidMovies.java │ └── SelendroidReview.java ├── node ├── .gitignore ├── .jshintrc ├── README.md ├── android-complex.js ├── android-local-server.js ├── android-simple.js ├── android-webview.js ├── assets │ └── index.html ├── helpers │ ├── actions.js │ ├── appium-servers.js │ ├── apps.js │ ├── caps.js │ ├── local-server.js │ ├── logging.js │ ├── promise-utils.js │ └── setup.js ├── ios-actions.js ├── ios-complex.js ├── ios-local-server.js ├── ios-safari.js ├── ios-selenium-webdriver-bridge.js ├── ios-simple.js ├── ios-webview.js ├── ios-yiewd.js ├── package.json ├── protractor-bridge │ ├── conf.js │ └── example_spec.js ├── selendroid-simple.js └── temp-output.txt ├── perl └── ios_simple.pl ├── php ├── SauceTest.php ├── SimpleTest.php └── composer.json ├── python ├── .cache │ └── v │ │ └── cache │ │ └── lastfailed ├── README.md ├── android_complex.py ├── android_contacts.py ├── android_gestures_sauce.py ├── android_sauce.py ├── android_simple.py ├── android_webview.py ├── ios_complex.py ├── ios_sauce.py ├── ios_sauce_webview.py ├── ios_simple.py ├── ios_webview.py ├── pytest │ ├── README.md │ ├── conftest.py │ ├── helpers.py │ ├── requirements.txt │ ├── test_android_contacts.py │ └── test_android_simple_with_logs.py ├── sauce_connect.py ├── selendroid_simple.py └── windows_calculatortest.py └── ruby ├── Gemfile ├── Gemfile.lock ├── README.md ├── UICatalog.app.zip ├── android_on_sauce.rb ├── arc_android └── appium.txt ├── arc_ios_calc └── appium.txt ├── arc_ios_catalog └── appium.txt ├── cucumber_android └── features │ ├── settings.feature │ ├── step_definitions │ └── steps.rb │ └── support │ ├── appium.txt │ └── env.rb ├── cucumber_ios ├── config │ └── cucumber.yml └── features │ ├── calculator.feature │ ├── step_definitions │ └── steps.rb │ └── support │ ├── appium.txt │ ├── env.rb │ ├── ipadsim │ └── appium.txt │ └── iphonesim │ └── appium.txt ├── sauce_example.rb ├── simple_test.rb ├── u_i_catalog.rb ├── windows_CalculatorTest.rb └── xunit_android.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | /.config 4 | /coverage/ 5 | /InstalledFiles 6 | /pkg/ 7 | /spec/reports/ 8 | /test/tmp/ 9 | /test/version_tmp/ 10 | /tmp/ 11 | 12 | ## Specific to RubyMotion: 13 | .dat* 14 | .repl_history 15 | build/ 16 | 17 | ## Documentation cache and generated files: 18 | /.yardoc/ 19 | /_yardoc/ 20 | /doc/ 21 | /rdoc/ 22 | 23 | ## Environment normalisation: 24 | /.bundle/ 25 | /lib/bundler/man/ 26 | 27 | # for a library or gem, you might want to ignore these files since the code is 28 | # intended to run in multiple environments; otherwise, check them in: 29 | # Gemfile.lock 30 | # .ruby-version 31 | # .ruby-gemset 32 | 33 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 34 | .rvmrc 35 | 36 | *.xcuserdatad 37 | 38 | # Eclipse 39 | .classpath 40 | .project 41 | .settings/ 42 | 43 | # Intellij 44 | .idea/ 45 | *.iml 46 | *.iws 47 | 48 | # VSCode 49 | .vscode/ 50 | 51 | # Mac 52 | .DS_Store 53 | 54 | # Maven 55 | log/ 56 | target/ 57 | 58 | # npm 59 | node_modules 60 | 61 | # Python 62 | __pycache__ 63 | *.pyc 64 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch", 6 | "type": "node", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/index.js", 9 | "stopOnEntry": false, 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "preLaunchTask": null, 13 | "runtimeExecutable": null, 14 | "runtimeArgs": [ 15 | "--nolazy" 16 | ], 17 | "env": { 18 | "NODE_ENV": "development" 19 | }, 20 | "console": "internalConsole", 21 | "sourceMaps": false, 22 | "outFiles": [] 23 | }, 24 | { 25 | "name": "Attach", 26 | "type": "node", 27 | "request": "attach", 28 | "port": 5858, 29 | "address": "localhost", 30 | "restart": false, 31 | "sourceMaps": false, 32 | "outFiles": [], 33 | "localRoot": "${workspaceRoot}", 34 | "remoteRoot": null 35 | }, 36 | { 37 | "name": "Attach to Process", 38 | "type": "node", 39 | "request": "attach", 40 | "processId": "${command.PickProcess}", 41 | "port": 5858, 42 | "sourceMaps": false, 43 | "outFiles": [] 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Appium Sample Code (https://github.com/appium/sample-code) 2 | 3 | Cross Platform Application for Android/iOS 4 | https://github.com/saikrishna321/VodQAReactNative 5 | 6 | vodQA - Sample cross platform app built using reactNative. 7 | Reason for building the cross platform app using reactNative is to get over the obstacles of automating apps 8 | built using react native and to write a single script to automate cross platform apps using Appium. 9 | vodQA app code is open sourced here and same was used for various appium workshops conducted by ThoughtWorks. 10 | 11 | Same is available for all community activities without any license required/ involved. 12 | 13 | Application holds all possible gestures like slide, swipe, longpress, doubletap, DragAndDrop and also webview. 14 | 15 | Copyright 2016-2017 Appium Contributors 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Refer https://github.com/appium/appium/tree/master/sample-code instead of this repository** 2 | 3 | # sample-code 4 | 5 | This repository contains sample applications which are used mostly by appium functional tests. 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appium-sample-code", 3 | "version": "1.0.0", 4 | "description": "Code examples for Appium", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/appium/sample-code.git" 12 | }, 13 | "keywords": [ 14 | "appium", 15 | "testcode" 16 | ], 17 | "author": "appium", 18 | "license": "Apache-2.0", 19 | "bugs": { 20 | "url": "https://github.com/appium/sample-code/issues" 21 | }, 22 | "homepage": "https://github.com/appium/sample-code" 23 | } 24 | -------------------------------------------------------------------------------- /sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk -------------------------------------------------------------------------------- /sample-code/apps/ContactManager/ContactManager-selendroid.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ContactManager/ContactManager-selendroid.apk -------------------------------------------------------------------------------- /sample-code/apps/ContactManager/ContactManager.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ContactManager/ContactManager.apk -------------------------------------------------------------------------------- /sample-code/apps/ContactManager/README.md: -------------------------------------------------------------------------------- 1 | # ContactManager 2 | 3 | ContactManager.apk only runs with UIAutomator and not with seledroid due to absence of 4 | INTERNET permission to use ContactManager with selendroid use ContactManger-selendroid.apk 5 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/RobotCalibration/RobotCalibration/Default-568h@2x.png -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/RobotCalibration/RobotCalibration/Default.png -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/RobotCalibration/RobotCalibration/Default@2x.png -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/RCAppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Appium Committers 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | @interface RCAppDelegate : UIResponder 25 | 26 | @property (strong, nonatomic) UIWindow *window; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/RCViewController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Appium Committers 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | @interface RCViewController : UIViewController 25 | @property (strong, nonatomic) IBOutlet UITapGestureRecognizer *tapRecognizer; 26 | @property (strong, nonatomic) IBOutlet UILabel *coordinateLabel; 27 | @property (strong, nonatomic) IBOutlet UISwipeGestureRecognizer *swipeRecognizer; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/RobotCalibration-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | Appium.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | MainStoryboard_iPhone 29 | UIMainStoryboardFile~ipad 30 | MainStoryboard_iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | UIInterfaceOrientationPortraitUpsideDown 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/RobotCalibration-Prefix.pch: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Appium Committers 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | #ifndef __IPHONE_5_0 25 | #warning "This project uses features only available in iOS SDK 5.0 and later." 26 | #endif 27 | 28 | #ifdef __OBJC__ 29 | #import 30 | #import 31 | #endif 32 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibration/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Appium Committers 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | #import "RCAppDelegate.h" 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | @autoreleasepool { 29 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([RCAppDelegate class])); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibrationTests/RobotCalibrationTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | Appium.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibrationTests/RobotCalibrationTests.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Appium Committers 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | @interface RobotCalibrationTests : SenTestCase 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibrationTests/RobotCalibrationTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Appium Committers 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import "RobotCalibrationTests.h" 23 | 24 | @implementation RobotCalibrationTests 25 | 26 | - (void)setUp 27 | { 28 | [super setUp]; 29 | 30 | // Set-up code here. 31 | } 32 | 33 | - (void)tearDown 34 | { 35 | // Tear-down code here. 36 | 37 | [super tearDown]; 38 | } 39 | 40 | - (void)testExample 41 | { 42 | STFail(@"Unit tests are not implemented yet in RobotCalibrationTests"); 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /sample-code/apps/RobotCalibration/RobotCalibrationTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /sample-code/apps/RottenTomatoes.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/RottenTomatoes.zip -------------------------------------------------------------------------------- /sample-code/apps/RottenTomatoesPageSnapshot.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/RottenTomatoesPageSnapshot.html -------------------------------------------------------------------------------- /sample-code/apps/RottenTomatoesSnapshot.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/RottenTomatoesSnapshot.html -------------------------------------------------------------------------------- /sample-code/apps/TestApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/.DS_Store -------------------------------------------------------------------------------- /sample-code/apps/TestApp/.gitignore: -------------------------------------------------------------------------------- 1 | xcshareddata 2 | -------------------------------------------------------------------------------- /sample-code/apps/TestApp/README.md: -------------------------------------------------------------------------------- 1 | ## Repository 2 | - https://github.com/appium/ios-test-app 3 | 4 | ## Copy from Simulator 5 | ``` 6 | $ cp path/to/ios-test-app/build path/to/sample-code/apps/TestApp/build 7 | ``` 8 | 9 | - `path/to` is an arbitrary path. 10 | - `ios-test-app/build` is the result of `npm install` in `ios-test-app` 11 | - `sample-code/apps/TestApp/build` is this direstory. 12 | -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/Default-568h@2x.png -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/GestureTestViewController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/GestureTestViewController.nib -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/Info.plist -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/TestApp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/TestApp -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/en.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/en.lproj/MyViewControllerViewController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/TestApp/build/Release-iphonesimulator/TestApp-iphonesimulator.app/en.lproj/MyViewControllerViewController.nib -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/.gitignore: -------------------------------------------------------------------------------- 1 | ant.properties 2 | bin 3 | build.xml 4 | gen 5 | local.properties 6 | proguard-project.txt 7 | project.properties 8 | tests/ant.properties 9 | tests/build.xml 10 | tests/local.properties 11 | tests/proguard-project.txt 12 | tests/project.properties 13 | out 14 | .settings/ 15 | *.apk 16 | lint.xml 17 | .idea/* -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ToggleTest/ic_launcher-web.png -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ToggleTest/libs/android-support-v4.jar -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ToggleTest/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ToggleTest/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ToggleTest/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/ToggleTest/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ToggleTest 5 | Settings 6 | Hello world! 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample-code/apps/ToggleTest/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample-code/apps/UICatalog.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/UICatalog.zip -------------------------------------------------------------------------------- /sample-code/apps/VodQA.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/VodQA.apk -------------------------------------------------------------------------------- /sample-code/apps/VodQAReactNative.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/VodQAReactNative.zip -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WebViewApp 4 | // 5 | // Created by Jonathan Lipps on 2/5/13. 6 | // Copyright (c) 2013 Appium Committers. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WebViewApp 4 | // 5 | // Created by Jonathan Lipps on 2/5/13. 6 | // Copyright (c) 2013 Appium Committers. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/WebViewApp/WebViewApp/Default-568h@2x.png -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/WebViewApp/WebViewApp/Default.png -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/WebViewApp/WebViewApp/Default@2x.png -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WebViewApp 4 | // 5 | // Created by Jonathan Lipps on 2/5/13. 6 | // Copyright (c) 2013 Appium Committers. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | @property (weak, nonatomic) IBOutlet UITextField *urlField; 13 | @property (weak, nonatomic) IBOutlet UIWebView *mainWebView; 14 | @property UIActivityIndicatorView *pageLoadingIndicator; 15 | - (IBAction)navBtnClicked:(id)sender; 16 | - (IBAction)urlEditBegin:(id)sender; 17 | - (BOOL)textFieldShouldReturn:(UITextField *)textField; 18 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 19 | - (void)webViewDidFinishLoad:(UIWebView *)webView; 20 | - (void)webViewDidStartLoad:(UIWebView *)webView; 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/WebViewApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | io.appium.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | MainStoryboard_iPhone 29 | UIMainStoryboardFile~ipad 30 | MainStoryboard_iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/WebViewApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'WebViewApp' target in the 'WebViewApp' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_5_0 8 | #warning "This project uses features only available in iOS SDK 5.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/cybervillainsCA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/WebViewApp/WebViewApp/cybervillainsCA.cer -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /sample-code/apps/WebViewApp/WebViewApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WebViewApp 4 | // 5 | // Created by Jonathan Lipps on 2/5/13. 6 | // Copyright (c) 2013 Appium Committers. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample-code/apps/android-rottentomatoes-demo-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/android-rottentomatoes-demo-debug.apk -------------------------------------------------------------------------------- /sample-code/apps/chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/chromedriver -------------------------------------------------------------------------------- /sample-code/apps/chromedriverWin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/chromedriverWin -------------------------------------------------------------------------------- /sample-code/apps/selendroid-test-app.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/apps/selendroid-test-app.apk -------------------------------------------------------------------------------- /sample-code/examples/C#/CalculatorTest/CalculatorTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorTest", "CalculatorTest.csproj", "{B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B2C5ADFF-D6B5-48C1-BB8C-571BFD583D7F}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /sample-code/examples/C#/CalculatorTest/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sample-code/examples/C#/CalculatorTest/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample-code/examples/RobotFramework/test_android_contact_resource.txt: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library AppiumLibrary 3 | 4 | *** Variables *** 5 | ${REMOTE_URL} http://localhost:4723/wd/hub 6 | ${PLATFORM_NAME} Android 7 | ${PLATFORM_VERSION} 4.2.2 8 | ${DEVICE_NAME} Android Emulator 9 | ${APP} ../../../sample-code/apps/ContactManager/ContactManager.apk 10 | 11 | *** Keywords *** 12 | add new contact 13 | [Arguments] ${contact_name} ${contact_phone} ${contact_email} 14 | Open Application ${REMOTE_URL} platformName=Android platformVersion=${PLATFORM_VERSION} deviceName=192.168.58.101:5555 app=${APP} automationName=appium appPackage=com.example.android.contactmanager 15 | Click Element accessibility_id=Add Contact 16 | Input Text xpath=//android.widget.TableLayout[@index='0']/android.widget.TableRow[@index='3']/android.widget.EditText[@index='0'] ${contact_name} 17 | Input Text xpath=//android.widget.TableLayout[@index='0']/android.widget.TableRow[@index='5']/android.widget.EditText[@index='0'] ${contact_phone} 18 | Input Text xpath=//android.widget.TableLayout[@index='0']/android.widget.TableRow[@index='7']/android.widget.EditText[@index='0'] ${contact_email} 19 | Click Element accessibility_id=Save 20 | -------------------------------------------------------------------------------- /sample-code/examples/RobotFramework/test_android_contacts.txt: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource test_android_contact_resource.txt 3 | 4 | *** Test Cases *** 5 | add_contact 6 | [Documentation] demo for android_contacts(https://github.com/appium/sample-code/blob/master/sample-code/examples/python/android_contacts.py) 7 | [Tags] demo 8 | add new contact Appium User someone@appium.io 5555555555 9 | Page Should Contain Text Appium User 10 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | AppiumDotNetSample/bin 2 | AppiumDotNetSample/obj 3 | AppiumDotNetSample/Obj 4 | AppiumDotNetSample/TestResults 5 | AppiumDotNetSample/test-results 6 | *.csproj.user 7 | *.suo 8 | *.cache 9 | *~ 10 | *.swp 11 | *.userprefs 12 | *.pidb 13 | packages 14 | *.nupkg 15 | AppiumDotNetSample/env.json 16 | 17 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppiumDotNetSample", "AppiumDotNetSample\AppiumDotNetSample.csproj", "{7A830071-06AC-4E20-9FBB-CAA395387A7C}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {7A830071-06AC-4E20-9FBB-CAA395387A7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {7A830071-06AC-4E20-9FBB-CAA395387A7C}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {7A830071-06AC-4E20-9FBB-CAA395387A7C}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {7A830071-06AC-4E20-9FBB-CAA395387A7C}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(MonoDevelopProperties) = preSolution 18 | StartupItem = AppiumDotNetSample\AppiumDotNetSample.csproj 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Android/AndroidAppStringsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using OpenQA.Selenium.Appium; 3 | using OpenQA.Selenium; 4 | using NUnit.Framework; 5 | using OpenQA.Selenium.Remote; 6 | using OpenQA.Selenium.Appium.Android; 7 | using Appium.Samples.Helpers; 8 | 9 | namespace Appium.Samples.Android 10 | { 11 | [TestFixture] 12 | public class AndroidAppStringsTest 13 | { 14 | private AppiumDriver driver; 15 | 16 | [TestFixtureSetUp] 17 | public void BeforeAll() 18 | { 19 | DesiredCapabilities capabilities = Env.isSauce() ? 20 | Caps.getAndroid501Caps(Apps.get("androidApiDemos")) : 21 | Caps.getAndroid19Caps(Apps.get("androidApiDemos")); 22 | if (Env.isSauce()) 23 | { 24 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 25 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 26 | capabilities.SetCapability("name", "android - complex"); 27 | capabilities.SetCapability("tags", new string[] { "sample" }); 28 | } 29 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIAndroid; 30 | driver = new AndroidDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 31 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 32 | } 33 | 34 | [TestFixtureTearDown] 35 | public void AfterAll() 36 | { 37 | if (driver != null) 38 | { 39 | driver.Quit(); 40 | } 41 | if (!Env.isSauce()) 42 | { 43 | AppiumServers.StopLocalService(); 44 | } 45 | } 46 | 47 | [Test] 48 | public void GetAppStrings() { 49 | Assert.AreNotSame(0, driver.GetAppStringDictionary ().Count); 50 | } 51 | 52 | [Test] 53 | public void GetAppStringsUsingLang() { 54 | Assert.AreNotSame(0, driver.GetAppStringDictionary ("en").Count); 55 | } 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Android/AndroidEmulatorDeviceTime.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Android; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | 8 | namespace Appium.Samples.Android 9 | { 10 | class AndroidEmulatorDeviceTime 11 | { 12 | private AppiumDriver driver; 13 | 14 | [SetUp] 15 | public void BeforeAll() 16 | { 17 | DesiredCapabilities capabilities = Env.isSauce() ? 18 | Caps.getAndroid501Caps(Apps.get("androidApiDemos")) : 19 | Caps.getAndroid19Caps(Apps.get("androidApiDemos")); 20 | if (Env.isSauce()) 21 | { 22 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 23 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 24 | capabilities.SetCapability("name", "android - complex"); 25 | capabilities.SetCapability("tags", new string[] { "sample" }); 26 | } 27 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIAndroid; 28 | driver = new AndroidDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 29 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 30 | } 31 | 32 | [TearDown] 33 | public void AfterEach() 34 | { 35 | if (driver != null) 36 | { 37 | driver.Quit(); 38 | } 39 | if (!Env.isSauce()) 40 | { 41 | AppiumServers.StopLocalService(); 42 | } 43 | } 44 | 45 | [Test()] 46 | public void DeviceTimeTest() 47 | { 48 | string time = driver.DeviceTime; 49 | Console.WriteLine(time); 50 | Assert.AreEqual(true, time.Length == 28); 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Android/AndroidLocationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.Android; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | 8 | namespace Appium.Samples.Android 9 | { 10 | [TestFixture()] 11 | class AndroidLocationTest 12 | { 13 | private AppiumDriver driver; 14 | 15 | [SetUp] 16 | public void BeforeAll() 17 | { 18 | DesiredCapabilities capabilities = Env.isSauce() ? 19 | Caps.getAndroid501Caps(Apps.get("androidApiDemos")) : 20 | Caps.getAndroid19Caps(Apps.get("androidApiDemos")); 21 | if (Env.isSauce()) 22 | { 23 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 24 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 25 | capabilities.SetCapability("name", "android - complex"); 26 | capabilities.SetCapability("tags", new string[] { "sample" }); 27 | } 28 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIAndroid; 29 | driver = new AndroidDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 30 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 31 | } 32 | 33 | [TearDown] 34 | public void AfterEach() 35 | { 36 | if (driver != null) 37 | { 38 | driver.Quit(); 39 | } 40 | if (!Env.isSauce()) 41 | { 42 | AppiumServers.StopLocalService(); 43 | } 44 | } 45 | 46 | [Test()] 47 | public void setLocationTest() 48 | { 49 | var l = new Location(); 50 | l.Altitude = 10; 51 | l.Longitude = 10; 52 | l.Latitude = 10; 53 | driver.Location = l; 54 | //var l1 = driver.Location; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Android/AndroidLockDeviceTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium.Android; 4 | using OpenQA.Selenium.Remote; 5 | using System; 6 | 7 | namespace Appium.Samples.Android 8 | { 9 | class AndroidLockDeviceTest 10 | { 11 | private AndroidDriver driver; 12 | 13 | [SetUp] 14 | public void BeforeAll() 15 | { 16 | DesiredCapabilities capabilities = Env.isSauce() ? 17 | Caps.getAndroid501Caps(Apps.get("androidApiDemos")) : 18 | Caps.getAndroid19Caps(Apps.get("androidApiDemos")); 19 | if (Env.isSauce()) 20 | { 21 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 22 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 23 | capabilities.SetCapability("name", "android - complex"); 24 | capabilities.SetCapability("tags", new string[] { "sample" }); 25 | } 26 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIAndroid; 27 | driver = new AndroidDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 28 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 29 | } 30 | 31 | [TearDown] 32 | public void AfterEach() 33 | { 34 | if (driver != null) 35 | { 36 | driver.Quit(); 37 | } 38 | if (!Env.isSauce()) 39 | { 40 | AppiumServers.StopLocalService(); 41 | } 42 | } 43 | 44 | [Test()] 45 | public void LockTest() 46 | { 47 | driver.Lock(); 48 | Assert.AreEqual(true, driver.IsLocked()); 49 | driver.Unlock(); 50 | Assert.AreEqual(false, driver.IsLocked()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Android/AndroidOrientationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium.Android; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | 8 | namespace Appium.Samples.Android 9 | { 10 | [TestFixture()] 11 | class AndroidOrientationTest 12 | { 13 | private IWebDriver driver; 14 | 15 | [TestFixtureSetUp] 16 | public void BeforeAll() 17 | { 18 | DesiredCapabilities capabilities = Env.isSauce() ? 19 | Caps.getAndroid501Caps(Apps.get("androidApiDemos")) : 20 | Caps.getAndroid19Caps(Apps.get("androidApiDemos")); 21 | if (Env.isSauce()) 22 | { 23 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 24 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 25 | capabilities.SetCapability("name", "android - complex"); 26 | capabilities.SetCapability("tags", new string[] { "sample" }); 27 | } 28 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIAndroid; 29 | driver = new AndroidDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 30 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 31 | } 32 | 33 | [TestFixtureTearDown] 34 | public void AfterAll() 35 | { 36 | if (driver != null) 37 | { 38 | driver.Quit(); 39 | } 40 | if (!Env.isSauce()) 41 | { 42 | AppiumServers.StopLocalService(); 43 | } 44 | } 45 | 46 | [Test] 47 | public void OrientationTest() 48 | { 49 | IRotatable rotatable = ((IRotatable) driver); 50 | rotatable.Orientation = ScreenOrientation.Portrait; 51 | Assert.AreEqual(ScreenOrientation.Portrait, rotatable.Orientation); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Android/HideKeyboardTestCase.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Appium.Android; 6 | using OpenQA.Selenium.Remote; 7 | using System; 8 | 9 | namespace Appium.Samples.Android 10 | { 11 | class HideKeyboardTestCase 12 | { 13 | private AndroidDriver driver; 14 | 15 | [TestFixtureSetUp] 16 | public void BeforeAll() 17 | { 18 | DesiredCapabilities capabilities = Env.isSauce() ? 19 | Caps.getAndroid501Caps(Apps.get("androidApiDemos")) : 20 | Caps.getAndroid19Caps(Apps.get("androidApiDemos")); 21 | if (Env.isSauce()) 22 | { 23 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 24 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 25 | capabilities.SetCapability("name", "android - complex"); 26 | capabilities.SetCapability("tags", new string[] { "sample" }); 27 | } 28 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIAndroid; 29 | driver = new AndroidDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 30 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 31 | } 32 | 33 | [TestFixtureTearDown] 34 | public void AfterAll() 35 | { 36 | if (driver != null) 37 | { 38 | driver.Quit(); 39 | } 40 | if (!Env.isSauce()) 41 | { 42 | AppiumServers.StopLocalService(); 43 | } 44 | } 45 | 46 | [Test()] 47 | public void HideKeyBoardTestCase() 48 | { 49 | driver.StartActivity("io.appium.android.apis", ".app.CustomTitle"); 50 | driver.FindElement(By.Id("io.appium.android.apis:id/left_text_edit")).Clear(); 51 | driver.HideKeyboard(); 52 | } 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/PageObjectTests/README.md: -------------------------------------------------------------------------------- 1 | This package shows all capabilities of Appium solution that allows to design and develop page objects specially for mobile and web testing. 2 | [Page object design pattern]((https://code.google.com/p/selenium/wiki/PageObjects). [Information about PageFactory. Here is java version. Sorry. The .Net version works the similar way.](https://code.google.com/p/selenium/wiki/PageFactory) 3 | [About details please read here](https://github.com/appium/appium-dotnet-driver/wiki/Page-objects) -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/PageObjects/AndroidWebView.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | using OpenQA.Selenium.Appium.PageObjects.Attributes; 3 | using OpenQA.Selenium.Support.PageObjects; 4 | using OpenQA.Selenium.Support.UI; 5 | using System; 6 | 7 | namespace Appium.Samples.PageObjects 8 | { 9 | public class AndroidWebView 10 | { 11 | [FindsBy(How = How.Id, Using = "name_input")] 12 | [FindsByAndroidUIAutomator(AndroidUIAutomator = "new UiSelector().resourceId(\"android:id/fakeID\")")] 13 | private IWebElement name; 14 | 15 | [FindsBy(How = How.Name, Using = "car")] 16 | [FindsByAndroidUIAutomator(AndroidUIAutomator = "new UiSelector().resourceId(\"android:id/fakeID\")")] 17 | [FindsByIOSUIAutomation(IosUIAutomation = ".elements()[0]")] 18 | private IWebElement carSelect; 19 | 20 | [FindsByAndroidUIAutomator(AndroidUIAutomator = "new UiSelector().resourceId(\"android:id/fakeID\")")] 21 | [FindsByIOSUIAutomation(IosUIAutomation = ".elements()[0]")] 22 | [FindsBy(How = How.XPath, Using =".//*[@type=\"submit\"]")] 23 | private IWebElement sendMeYourName; 24 | 25 | public void SetName(string name){ 26 | this.name. Clear(); 27 | this.name.SendKeys(name); 28 | } 29 | 30 | public void SelectCar(String car){ 31 | SelectElement select = new SelectElement(carSelect); 32 | select.SelectByValue(car); 33 | } 34 | 35 | public void SendMeYourName() { 36 | sendMeYourName.Submit(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/PageObjects/README.md: -------------------------------------------------------------------------------- 1 | This package shows all capabilities of Appium solution that allows to design and develop page objects specially for mobile and web testing. 2 | [Page object design pattern]((https://code.google.com/p/selenium/wiki/PageObjects). [Information about PageFactory. Here is java version. Sorry. The .Net version works the similar way.](https://code.google.com/p/selenium/wiki/PageFactory) 3 | [About details please read here](https://github.com/appium/appium-dotnet-driver/wiki/Page-objects) -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/ApiDemos-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/dotnet/AppiumDotNetSample/Resources/ApiDemos-debug.apk -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/IntentExample.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/dotnet/AppiumDotNetSample/Resources/IntentExample.apk -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/PathToLinuxNode: -------------------------------------------------------------------------------- 1 | /Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/PathToMacOSNode: -------------------------------------------------------------------------------- 1 | /Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/PathToWindowsNode: -------------------------------------------------------------------------------- 1 | C:/Program Files (x86)/Appium/node_modules/appium/bin/appium.js -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/TestApp7.1.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/dotnet/AppiumDotNetSample/Resources/TestApp7.1.app.zip -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/UICatalog.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/dotnet/AppiumDotNetSample/Resources/UICatalog.zip -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/WebViewApp7.1.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/dotnet/AppiumDotNetSample/Resources/WebViewApp7.1.app.zip -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/Resources/selendroid-test-app-0.10.0.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/dotnet/AppiumDotNetSample/Resources/selendroid-test-app-0.10.0.apk -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/env.json.sample: -------------------------------------------------------------------------------- 1 | { 2 | "DEV": false, 3 | "SAUCE": false, 4 | "SAUCE_USERNAME": "", 5 | "SAUCE_ACCESS_KEY": "" 6 | } 7 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/helpers/Env.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.MultiTouch; 5 | using OpenQA.Selenium.Appium.Interfaces; 6 | using System.IO; 7 | using System.Reflection; 8 | using System.Web.Script.Serialization; 9 | 10 | namespace Appium.Samples.Helpers 11 | { 12 | public class Env 13 | { 14 | public static TimeSpan INIT_TIMEOUT_SEC = TimeSpan.FromSeconds(180); 15 | public static TimeSpan IMPLICIT_TIMEOUT_SEC = TimeSpan.FromSeconds(5); 16 | public static string ASSETS_ROOT_DIR = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "../../assets"); 17 | 18 | private static Dictionary env; 19 | private static bool initialized = false; 20 | private static void Init() { 21 | try { 22 | if(!initialized) 23 | { 24 | initialized = true; 25 | string path = AppDomain.CurrentDomain.BaseDirectory + "../../"; 26 | StreamReader sr = new StreamReader(path + "env.json"); 27 | string jsonString = sr.ReadToEnd(); 28 | JavaScriptSerializer ser = new JavaScriptSerializer(); 29 | env = ser.Deserialize>(jsonString); 30 | } 31 | } catch { 32 | env = new Dictionary (); 33 | } 34 | } 35 | 36 | private static bool isTrue(string val) { 37 | if (val != null) { 38 | val = val.ToLower ().Trim (); 39 | } 40 | return (val == "true") || (val == "1"); 41 | } 42 | 43 | static public bool isSauce() { 44 | Init (); 45 | return (env.ContainsKey("SAUCE") && isTrue(env["SAUCE"])) || isTrue( Environment.GetEnvironmentVariable ("SAUCE") ); 46 | } 47 | 48 | static public bool isDev() { 49 | Init (); 50 | return (env.ContainsKey("DEV") && isTrue(env["DEV"])) || isTrue( Environment.GetEnvironmentVariable ("DEV") ); 51 | } 52 | 53 | static public string getEnvVar(string name){ 54 | if (env.ContainsKey(name) && (env [name] != null)) { 55 | return env [name]; 56 | } else { 57 | return Environment.GetEnvironmentVariable (name); 58 | } 59 | } 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/iOS/IOSLocationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium.Appium; 4 | using OpenQA.Selenium.Appium.iOS; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | 8 | namespace Appium.Samples.iOS 9 | { 10 | [TestFixture()] 11 | class iOSLocationTest 12 | { 13 | private AppiumDriver driver; 14 | 15 | [TestFixtureSetUp] 16 | public void beforeAll() 17 | { 18 | DesiredCapabilities capabilities = Caps.getIos92Caps(Apps.get("iosTestApp")); 19 | if (Env.isSauce()) 20 | { 21 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 22 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 23 | capabilities.SetCapability("name", "ios - complex"); 24 | capabilities.SetCapability("tags", new string[] { "sample" }); 25 | } 26 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIForIOS; 27 | driver = new IOSDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 28 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 29 | } 30 | 31 | [TestFixtureTearDown] 32 | public void afterAll() 33 | { 34 | if (driver != null) 35 | { 36 | driver.Quit(); 37 | } 38 | if (!Env.isSauce()) 39 | { 40 | AppiumServers.StopLocalService(); 41 | } 42 | } 43 | 44 | [Test()] 45 | public void SetLocationTest() 46 | { 47 | var l = new Location(); 48 | l.Altitude = 10; 49 | l.Longitude = 10; 50 | l.Latitude = 10; 51 | driver.Location = l; 52 | //var l1 = driver.Location; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/iOS/IosOrientationTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Samples.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium.iOS; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | 8 | namespace Appium.Samples.iOS 9 | { 10 | [TestFixture ()] 11 | public class iOSOrientationTest 12 | { 13 | private IWebDriver driver; 14 | 15 | [TestFixtureSetUp] 16 | public void beforeAll(){ 17 | DesiredCapabilities capabilities = Caps.getIos92Caps (Apps.get("iosTestApp")); 18 | if (Env.isSauce ()) { 19 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 20 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 21 | capabilities.SetCapability("name", "ios - complex"); 22 | capabilities.SetCapability("tags", new string[]{"sample"}); 23 | } 24 | Uri serverUri = Env.isSauce () ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIForIOS; 25 | driver = new IOSDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 26 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 27 | } 28 | 29 | [TestFixtureTearDown] 30 | public void afterAll(){ 31 | if (driver != null) 32 | { 33 | driver.Quit(); 34 | } 35 | if (!Env.isSauce()) 36 | { 37 | AppiumServers.StopLocalService(); 38 | } 39 | } 40 | 41 | [Test] 42 | public void OrientationTest() 43 | { 44 | IRotatable rotatable = ((IRotatable) driver); 45 | rotatable.Orientation = ScreenOrientation.Landscape; 46 | Assert.AreEqual(ScreenOrientation.Landscape, rotatable.Orientation); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/iOS/IosWebviewTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using Appium.Samples.Helpers; 4 | using OpenQA.Selenium.Appium; 5 | using OpenQA.Selenium.Remote; 6 | using OpenQA.Selenium; 7 | using System.Threading; 8 | using OpenQA.Selenium.Appium.iOS; 9 | 10 | namespace Appium.Samples.iOS 11 | { 12 | [TestFixture ()] 13 | public class iOSWebviewTest 14 | { 15 | private AppiumDriver driver; 16 | 17 | [TestFixtureSetUp] 18 | public void BeforeAll(){ 19 | DesiredCapabilities capabilities = Caps.getIos92Caps (Apps.get("iosWebviewApp")); 20 | if (Env.isSauce ()) { 21 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 22 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 23 | capabilities.SetCapability("name", "ios - webview"); 24 | capabilities.SetCapability("tags", new string[]{"sample"}); 25 | } 26 | Uri serverUri = Env.isSauce () ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIForIOS; 27 | driver = new IOSDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 28 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 29 | } 30 | 31 | [TestFixtureTearDown] 32 | public void AfterAll(){ 33 | if (driver != null) 34 | { 35 | driver.Quit(); 36 | } 37 | if (!Env.isSauce()) 38 | { 39 | AppiumServers.StopLocalService(); 40 | } 41 | } 42 | 43 | [Test ()] 44 | public void GetPageTestCase () 45 | { 46 | driver.FindElementByXPath("//UIATextField[@value='Enter URL']") 47 | .SendKeys("www.google.com"); 48 | driver.FindElementByClassName ("UIAButton").Click (); 49 | driver.FindElementByClassName ("UIAWebView").Click (); // dismissing keyboard 50 | Thread.Sleep(10000); 51 | driver.Context = "WEBVIEW"; 52 | Thread.Sleep (3000); 53 | var el = driver.FindElementByClassName ("gsfi"); 54 | el.SendKeys ("Appium"); 55 | el.SendKeys(Keys.Return); 56 | Thread.Sleep (1000); 57 | Assert.IsTrue (driver.Title.Contains("Appium")); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/iOS/iOSAppStringsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using OpenQA.Selenium.Appium; 3 | using OpenQA.Selenium; 4 | using NUnit.Framework; 5 | using OpenQA.Selenium.Remote; 6 | using Appium.Integration.Tests.Helpers; 7 | using OpenQA.Selenium.Appium.iOS; 8 | 9 | namespace Appium.Integration.Tests.iOS 10 | { 11 | public class iOSAppStringsTest 12 | { 13 | private AppiumDriver driver; 14 | 15 | [TestFixtureSetUp] 16 | public void BeforeAll() 17 | { 18 | DesiredCapabilities capabilities = Caps.getIos92Caps(Apps.get("iosTestApp")); 19 | if (Env.isSauce()) 20 | { 21 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 22 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 23 | capabilities.SetCapability("name", "ios - complex"); 24 | capabilities.SetCapability("tags", new string[] { "sample" }); 25 | } 26 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIForIOS; 27 | driver = new IOSDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 28 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 29 | } 30 | 31 | [TestFixtureTearDown] 32 | public void AfterEach() 33 | { 34 | if (driver != null) 35 | { 36 | driver.Quit(); 37 | } 38 | if (!Env.isSauce()) 39 | { 40 | AppiumServers.StopLocalService(); 41 | } 42 | } 43 | 44 | [Test] 45 | public void GetAppStrings() { 46 | Assert.AreNotSame(0, driver.GetAppStringDictionary ().Count); 47 | } 48 | 49 | [Test] 50 | public void GetAppStringsUsingLang() { 51 | Assert.AreNotSame(0, driver.GetAppStringDictionary ("en").Count); 52 | } 53 | 54 | [Test] 55 | public void GetAppStringsUsingLangAndFileStrings() { 56 | Assert.AreNotSame(0, driver.GetAppStringDictionary ("en", "Localizable.strings").Count); 57 | } 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/iOS/iOSLockDeviceTest.cs: -------------------------------------------------------------------------------- 1 | using Appium.Integration.Tests.Helpers; 2 | using NUnit.Framework; 3 | using OpenQA.Selenium; 4 | using OpenQA.Selenium.Appium.iOS; 5 | using OpenQA.Selenium.Remote; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace Appium.Integration.Tests.iOS 12 | { 13 | class iOSLockDeviceTest 14 | { 15 | private IOSDriver driver; 16 | 17 | [TestFixtureSetUp] 18 | public void BeforeAll() 19 | { 20 | DesiredCapabilities capabilities = Caps.getIos92Caps(Apps.get("iosWebviewApp")); 21 | if (Env.isSauce()) 22 | { 23 | capabilities.SetCapability("username", Env.getEnvVar("SAUCE_USERNAME")); 24 | capabilities.SetCapability("accessKey", Env.getEnvVar("SAUCE_ACCESS_KEY")); 25 | capabilities.SetCapability("tags", new string[] { "sample" }); 26 | } 27 | Uri serverUri = Env.isSauce() ? AppiumServers.sauceURI : AppiumServers.LocalServiceURIForIOS; 28 | driver = new IOSDriver(serverUri, capabilities, Env.INIT_TIMEOUT_SEC); 29 | driver.Manage().Timeouts().ImplicitlyWait(Env.IMPLICIT_TIMEOUT_SEC); 30 | } 31 | 32 | [TestFixtureTearDown] 33 | public void AfterAll() 34 | { 35 | if (driver != null) 36 | { 37 | driver.Quit(); 38 | } 39 | if (!Env.isSauce()) 40 | { 41 | AppiumServers.StopLocalService(); 42 | } 43 | } 44 | 45 | [Test()] 46 | public void LockTest() 47 | { 48 | driver.Lock(20); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/AppiumDotNetSample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/README.md: -------------------------------------------------------------------------------- 1 | # Appium DotNet samples 2 | 3 | ## Run locally 4 | 5 | ### Download apps (default) 6 | 7 | - Start Appium. 8 | - Run the tests in NUnit. 9 | 10 | ### Use Appium dev apps 11 | 12 | - Build dev version of appium `./reset.sh --android --ios --dev --hardcore` 13 | - `cp AppiumDotNetSample/env.json.sample AppiumDotNetSample/env.json` 14 | - Update `AppiumDotNetSample/env.json` set DEV=true 15 | - Start appium: `node .` 16 | - Run the tests in NUnit. 17 | 18 | ## Run on Sauce Labs 19 | 20 | - `cp AppiumDotNetSample/env.json.sample AppiumDotNetSample/env.json` 21 | - Update `AppiumDotNetSample/env.json` set SAUCE=true, and configure your Sauce credentials. 22 | - Run the tests in NUnit. 23 | -------------------------------------------------------------------------------- /sample-code/examples/dotnet/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Appium Rocks 4 | 5 | 6 | 7 |

Appium Rocks

8 | 9 |
10 |

11 | Wow this is so cool! 12 |

13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sample-code/examples/java/Windows/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | CalculatorTest 8 | CalculatorTest 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.seleniumhq.selenium 14 | selenium-java 15 | 2.53.0 16 | 17 | 18 | junit 19 | junit 20 | 4.11 21 | 22 | 23 | io.appium 24 | java-client 25 | 3.4.1 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /sample-code/examples/java/appium-generic-test/src/test/java/AndoridBrowserLocalTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | import io.appium.java_client.android.AndroidDriver; 12 | import io.appium.java_client.remote.MobileCapabilityType; 13 | 14 | /** 15 | * Android Browser Local Test. 16 | */ 17 | public class AndoridBrowserLocalTest 18 | { 19 | public static AndroidDriver mobiledriver; 20 | @BeforeTest 21 | public void beforeTest( ) throws MalformedURLException { 22 | DesiredCapabilities capabilities = new DesiredCapabilities(); 23 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 24 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); 25 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android"); 26 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Appium"); 27 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); 28 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser"); 29 | capabilities.setCapability("newCommandTimeout", 2000); 30 | mobiledriver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 31 | } 32 | 33 | @AfterTest 34 | public void afterTest( ) { 35 | mobiledriver.quit(); 36 | } 37 | 38 | @Test 39 | public void launchBrowser() { 40 | mobiledriver.get("http://appium.io/"); 41 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 42 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 43 | } 44 | } -------------------------------------------------------------------------------- /sample-code/examples/java/appium-generic-test/src/test/java/AndroidBrowserSaucelabsTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | 12 | import io.appium.java_client.android.AndroidDriver; 13 | import io.appium.java_client.remote.MobileCapabilityType; 14 | 15 | /** 16 | * Android Browser Sauce Labs Test. 17 | */ 18 | public class AndroidBrowserSaucelabsTest{ 19 | public static final String USERNAME = "YOUR_USERNAME"; 20 | public static final String ACCESS_KEY = "YOUR_ACESS_KEY"; 21 | public static final String URL = "https://"+USERNAME+":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub"; 22 | public static AndroidDriver mobiledriver; 23 | 24 | @BeforeTest 25 | public void beforeTest( ) throws MalformedURLException { 26 | DesiredCapabilities capabilities = new DesiredCapabilities(); 27 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 28 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); 29 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android"); 30 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Appium"); 31 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Samsung Galaxy S4 Emulator"); 32 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser"); 33 | capabilities.setCapability("newCommandTimeout", 2000); 34 | mobiledriver = new AndroidDriver<>(new URL(URL), capabilities); 35 | } 36 | 37 | @AfterTest 38 | public void afterTest( ){ 39 | mobiledriver.quit(); 40 | } 41 | 42 | @Test 43 | public static void launchBrowser(){ 44 | mobiledriver.get("http://appium.io/"); 45 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 46 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample-code/examples/java/appium-generic-test/src/test/java/IOSBrowserLocalTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | 12 | import io.appium.java_client.ios.IOSDriver; 13 | import io.appium.java_client.remote.MobileCapabilityType; 14 | 15 | /** 16 | * IOS Browser Local Test. 17 | */ 18 | public class IOSBrowserLocalTest 19 | { 20 | public static IOSDriver mobiledriver; 21 | 22 | @BeforeTest 23 | public void beforeTest( ) throws MalformedURLException 24 | { 25 | DesiredCapabilities capabilities = new DesiredCapabilities(); 26 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 27 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.2"); 28 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS"); 29 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"XCUITest"); 30 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 7"); 31 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari"); 32 | capabilities.setCapability("newCommandTimeout", 2000); 33 | mobiledriver = new IOSDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 34 | } 35 | 36 | @AfterTest 37 | public void afterTest( ) 38 | { 39 | mobiledriver.quit(); 40 | } 41 | @Test 42 | public static void launchBrowser() throws InterruptedException 43 | { 44 | mobiledriver.get("http://appium.io/"); 45 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 46 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 47 | } 48 | } -------------------------------------------------------------------------------- /sample-code/examples/java/appium-generic-test/src/test/java/IOSBrowserSaucelabsTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | 12 | import io.appium.java_client.ios.IOSDriver; 13 | import io.appium.java_client.remote.MobileCapabilityType; 14 | 15 | /** 16 | * IOS Browser Sauce Labs Test. 17 | */ 18 | public class IOSBrowserSaucelabsTest 19 | { 20 | public static final String USERNAME = "YOUR_USERNAME"; 21 | public static final String ACCESS_KEY = "YOUR_ACESS_KEY"; 22 | public static final String URL = "https://"+USERNAME+":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub"; 23 | public static IOSDriver mobiledriver; 24 | 25 | @BeforeTest 26 | public void beforeTest( ) throws MalformedURLException { 27 | DesiredCapabilities capabilities = new DesiredCapabilities(); 28 | 29 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 30 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.2.2"); 31 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS"); 32 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"XCUITest"); 33 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator"); 34 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari"); 35 | capabilities.setCapability("newCommandTimeout", 2000); 36 | mobiledriver = new IOSDriver<>(new URL(URL), capabilities); 37 | 38 | } 39 | 40 | @AfterTest 41 | public void afterTest( ) { 42 | mobiledriver.quit(); 43 | } 44 | 45 | @Test 46 | public static void launchBrowser(){ 47 | mobiledriver.get("http://appium.io/"); 48 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 49 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sample-code/examples/java/generic/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.appium 7 | appium-generic-test 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 12 | saucelabs-repository 13 | https://repository-saucelabs.forge.cloudbees.com/release 14 | 15 | true 16 | 17 | 18 | true 19 | 20 | 21 | 22 | 23 | 24 | 25 | io.appium 26 | java-client 27 | 5.0.1 28 | 29 | 30 | org.testng 31 | testng 32 | compile 33 | 6.10 34 | 35 | 36 | com.saucelabs 37 | sauce_junit 38 | 2.1.11 39 | test 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /sample-code/examples/java/generic/src/test/java/AndoridBrowserLocalTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | import io.appium.java_client.android.AndroidDriver; 12 | import io.appium.java_client.remote.MobileCapabilityType; 13 | 14 | /** 15 | * Android Browser Local Test. 16 | */ 17 | public class AndoridBrowserLocalTest 18 | { 19 | public static AndroidDriver mobiledriver; 20 | @BeforeTest 21 | public void beforeTest( ) throws MalformedURLException { 22 | DesiredCapabilities capabilities = new DesiredCapabilities(); 23 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 24 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); 25 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android"); 26 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Appium"); 27 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); 28 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser"); 29 | capabilities.setCapability("newCommandTimeout", 2000); 30 | mobiledriver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 31 | } 32 | 33 | @AfterTest 34 | public void afterTest( ) { 35 | mobiledriver.quit(); 36 | } 37 | 38 | @Test 39 | public void launchBrowser() { 40 | mobiledriver.get("http://appium.io/"); 41 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 42 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sample-code/examples/java/generic/src/test/java/AndroidBrowserSaucelabsTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | 12 | import io.appium.java_client.android.AndroidDriver; 13 | import io.appium.java_client.remote.MobileCapabilityType; 14 | 15 | /** 16 | * Android Browser Sauce Labs Test. 17 | */ 18 | public class AndroidBrowserSaucelabsTest{ 19 | public static final String USERNAME = "YOUR_USERNAME"; 20 | public static final String ACCESS_KEY = "YOUR_ACESS_KEY"; 21 | public static final String URL = "https://"+USERNAME+":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub"; 22 | public static AndroidDriver mobiledriver; 23 | 24 | @BeforeTest 25 | public void beforeTest( ) throws MalformedURLException { 26 | DesiredCapabilities capabilities = new DesiredCapabilities(); 27 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 28 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4"); 29 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android"); 30 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Appium"); 31 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Samsung Galaxy S4 Emulator"); 32 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Browser"); 33 | capabilities.setCapability("newCommandTimeout", 2000); 34 | mobiledriver = new AndroidDriver<>(new URL(URL), capabilities); 35 | } 36 | 37 | @AfterTest 38 | public void afterTest( ){ 39 | mobiledriver.quit(); 40 | } 41 | 42 | @Test 43 | public static void launchBrowser(){ 44 | mobiledriver.get("http://appium.io/"); 45 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 46 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample-code/examples/java/generic/src/test/java/IOSBrowserLocalTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | 12 | import io.appium.java_client.ios.IOSDriver; 13 | import io.appium.java_client.remote.MobileCapabilityType; 14 | 15 | /** 16 | * IOS Browser Local Test. 17 | */ 18 | public class IOSBrowserLocalTest 19 | { 20 | public static IOSDriver mobiledriver; 21 | 22 | @BeforeTest 23 | public void beforeTest( ) throws MalformedURLException 24 | { 25 | DesiredCapabilities capabilities = new DesiredCapabilities(); 26 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 27 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.2"); 28 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS"); 29 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"XCUITest"); 30 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone 7"); 31 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari"); 32 | capabilities.setCapability("newCommandTimeout", 2000); 33 | mobiledriver = new IOSDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 34 | } 35 | 36 | @AfterTest 37 | public void afterTest( ) 38 | { 39 | mobiledriver.quit(); 40 | } 41 | @Test 42 | public static void launchBrowser() throws InterruptedException 43 | { 44 | mobiledriver.get("http://appium.io/"); 45 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 46 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 47 | } 48 | } -------------------------------------------------------------------------------- /sample-code/examples/java/generic/src/test/java/IOSBrowserSaucelabsTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import org.openqa.selenium.remote.DesiredCapabilities; 7 | import org.testng.Assert; 8 | import org.testng.annotations.AfterTest; 9 | import org.testng.annotations.BeforeTest; 10 | import org.testng.annotations.Test; 11 | 12 | import io.appium.java_client.ios.IOSDriver; 13 | import io.appium.java_client.remote.MobileCapabilityType; 14 | 15 | /** 16 | * IOS Browser Sauce Labs Test. 17 | */ 18 | public class IOSBrowserSaucelabsTest 19 | { 20 | public static final String USERNAME = "YOUR_USERNAME"; 21 | public static final String ACCESS_KEY = "YOUR_ACESS_KEY"; 22 | public static final String URL = "https://"+USERNAME+":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub"; 23 | public static IOSDriver mobiledriver; 24 | 25 | @BeforeTest 26 | public void beforeTest( ) throws MalformedURLException { 27 | DesiredCapabilities capabilities = new DesiredCapabilities(); 28 | 29 | capabilities.setCapability(MobileCapabilityType.APPIUM_VERSION, "1.7.2"); 30 | capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.2.2"); 31 | capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS"); 32 | capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,"XCUITest"); 33 | capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator"); 34 | capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari"); 35 | capabilities.setCapability("newCommandTimeout", 2000); 36 | mobiledriver = new IOSDriver<>(new URL(URL), capabilities); 37 | 38 | } 39 | 40 | @AfterTest 41 | public void afterTest( ) { 42 | mobiledriver.quit(); 43 | } 44 | 45 | @Test 46 | public static void launchBrowser(){ 47 | mobiledriver.get("http://appium.io/"); 48 | Assert.assertEquals(mobiledriver.getCurrentUrl(), "http://appium.io/", "URL Mismatch"); 49 | Assert.assertEquals(mobiledriver.getTitle(), "Appium: Mobile App Automation Made Awesome.", "Title Mismatch"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/README.md: -------------------------------------------------------------------------------- 1 | Sample Appium JUnit project 2 | --- 3 | 4 | This contains the source code for running sample [Appium](http://github.com/appium/appium) tests using [JUnit](http://www.junit.org). 5 | 6 | In order to run the tests, you will need to install [Apache Maven](http://maven.apache.org), and Appium (according to the Appium [installation instructions](https://github.com/appium/appium). 7 | 8 | You will then need to start appium, eg: 9 | 10 | appium 11 | 12 | To compile and run all tests, run: 13 | 14 | mvn test 15 | 16 | To run a single test, run: 17 | 18 | mvn -Dtest=com.saucelabs.appium.SimpleTest test 19 | 20 | To run a single test on specific platform(android/ios) 21 | 22 | mvn clean -Dtest=AndroidDragAndDrop test -Dplatform=android 23 | 24 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/AndroidDragAndDrop.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium; 2 | 3 | import io.appium.java_client.MobileBy; 4 | import io.appium.java_client.MobileElement; 5 | import io.appium.java_client.TouchAction; 6 | import org.junit.Test; 7 | import org.openqa.selenium.support.ui.ExpectedConditions; 8 | import org.openqa.selenium.support.ui.WebDriverWait; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class AndroidDragAndDrop extends BaseCrossPlatformDriver { 13 | @Test 14 | public void testDragAndDrop() throws InterruptedException { 15 | login(); 16 | driver.findElementByAccessibilityId("dragAndDrop").click(); 17 | MobileElement dragMe = (MobileElement) new WebDriverWait(driver, 30) 18 | .until(ExpectedConditions 19 | .elementToBeClickable(MobileBy.AccessibilityId("dragMe"))); 20 | new TouchAction(driver).press(dragMe).waitAction(3000) 21 | .moveTo(driver.findElementByAccessibilityId("dropzone")).release().perform(); 22 | String expected = driver.findElementByAccessibilityId("success").getText(); 23 | assertEquals(expected,"Circle dropped"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/AndroidSlideTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium; 2 | 3 | import io.appium.java_client.TouchAction; 4 | import org.junit.Test; 5 | import org.openqa.selenium.Dimension; 6 | import org.openqa.selenium.Point; 7 | import org.openqa.selenium.WebElement; 8 | 9 | public class AndroidSlideTest extends BaseDriver { 10 | 11 | @Test 12 | public void testSlider(){ 13 | scrollTo("Views").click(); 14 | scrollTo("Seek Bar").click(); 15 | 16 | WebElement slider = driver.findElementById("io.appium.android.apis:id/seek"); 17 | Point sliderLocation = getCenter(slider); 18 | new TouchAction(driver).press(sliderLocation.getX(),sliderLocation.getY()) 19 | .moveTo(sliderLocation.getX() / 2 , sliderLocation.getY()).perform().release(); 20 | 21 | } 22 | 23 | private Point getCenter(WebElement element) { 24 | 25 | Point upperLeft = element.getLocation(); 26 | Dimension dimensions = element.getSize(); 27 | return new Point(upperLeft.getX() + dimensions.getWidth()/2, upperLeft.getY() + dimensions.getHeight()/2); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/AndroidTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium; 2 | 3 | import org.junit.Test; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebElement; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | 11 | public class AndroidTest extends BaseDriver{ 12 | 13 | 14 | @Test 15 | public void apiDemo(){ 16 | WebElement el = driver.findElement(By.xpath(".//*[@text='Animation']")); 17 | assertEquals("Animation", el.getText()); 18 | el = driver.findElementByClassName("android.widget.TextView"); 19 | assertEquals("API Demos", el.getText()); 20 | el = driver.findElement(By.xpath(".//*[@text='App']")); 21 | el.click(); 22 | List els = driver.findElementsByClassName("android.widget.TextView"); 23 | assertEquals("Activity", els.get(2).getText()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/MobileFindJavaTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium; 2 | 3 | import io.appium.java_client.AppiumDriver; 4 | import io.appium.java_client.android.AndroidDriver; 5 | 6 | import java.net.URL; 7 | 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.openqa.selenium.remote.DesiredCapabilities; 12 | 13 | public class MobileFindJavaTest { 14 | 15 | private AppiumDriver driver; 16 | private static final String url = "http://127.0.0.1:4723/wd/hub"; 17 | 18 | @Test 19 | public void apiDemo() throws Exception { 20 | //driver.scrollTo("about phone"); 21 | //driver.scrollTo("bluetooth"); 22 | } 23 | 24 | 25 | @Before 26 | public void setUp() throws Exception { 27 | final DesiredCapabilities capabilities = new DesiredCapabilities(); 28 | capabilities.setCapability("deviceName", "Android Emulator"); 29 | capabilities.setCapability("appPackage", "com.android.settings"); 30 | capabilities.setCapability("appActivity", ".Settings"); 31 | driver = new AndroidDriver<>(new URL(url), capabilities); 32 | } 33 | 34 | @After 35 | public void tearDown() throws Exception { 36 | driver.quit(); 37 | } 38 | } -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/driver_service/custom_node_path.properties: -------------------------------------------------------------------------------- 1 | path.to.custom.node.win=C:/Program Files (x86)/Appium/node_modules/appium/bin/appium.js 2 | path.to.custom.node.macos=/usr/local/lib/node_modules/appium/build/lib/main.js 3 | path.to.custom.node.linux=specify your path on your own -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/PageObjectWithCustomizedTimeOuts.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object; 2 | 3 | import io.appium.java_client.MobileElement; 4 | import io.appium.java_client.pagefactory.WithTimeout; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | import java.util.List; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class PageObjectWithCustomizedTimeOuts { 11 | 12 | /** 13 | * Page Object best practice is to describe interactions with target 14 | * elements by methods. This methods describe business logic of the page/screen. 15 | * Here lazy instantiated elements are public. 16 | * It was done so just for obviousness 17 | */ 18 | 19 | @FindBy(className = "OneClassWhichDoesNotExist") 20 | public List stubElements; 21 | 22 | /*Any timeout of the waiting for element/list of elements 23 | can be customized if the general time duration is 24 | not suitable. E.g. the element is rendered for a long time 25 | or the element is used just for instant checkings/assertions 26 | */ 27 | @WithTimeout(time = 5, unit = TimeUnit.SECONDS) 28 | @FindBy(className = "OneAnotherClassWhichDoesNotExist") 29 | public List stubElements2; 30 | } 31 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/Movie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets; 2 | 3 | import io.appium.java_client.pagefactory.Widget; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public abstract class Movie extends Widget { 7 | protected Movie(WebElement element) { 8 | super(element); 9 | } 10 | 11 | public abstract String title(); 12 | 13 | public abstract String score(); 14 | 15 | public abstract Object getPoster(); 16 | 17 | public abstract void goToReview(); 18 | } 19 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/Movies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets; 2 | 3 | import io.appium.java_client.pagefactory.Widget; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public abstract class Movies extends Widget { 7 | 8 | protected Movies(WebElement element) { 9 | super(element); 10 | } 11 | 12 | public abstract int getMovieCount(); 13 | 14 | public abstract Movie getMovie(int index); 15 | } 16 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/README.md: -------------------------------------------------------------------------------- 1 | This package shows how to use an extension of Page Obgect design pattern. These features were designed to simplify 2 | the modeling of interaction with a target app and to be reused in desktop/mobile browser testing/testing of mobile apps. 3 | 4 | Details please read here: [#267](https://github.com/appium/java-client/pull/267) -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/Review.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets; 2 | 3 | import io.appium.java_client.pagefactory.Widget; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public abstract class Review extends Widget { 7 | 8 | protected Review(WebElement element) { 9 | super(element); 10 | } 11 | 12 | public abstract String title(); 13 | 14 | public abstract String score(); 15 | 16 | public abstract String info(); 17 | 18 | public abstract Object getPoster(); 19 | } 20 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/WidgetTest.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets; 2 | 3 | public interface WidgetTest { 4 | 5 | public void checkACommonWidget(); 6 | 7 | public void checkAnAnnotatedWidget(); 8 | 9 | public void checkAnExtendedWidget(); 10 | 11 | public void checkTheLocatorOverridingOnAWidget(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/annotated/AnnotatedAndroidMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.android.simple.AndroidMovie; 4 | import io.appium.java_client.pagefactory.AndroidFindBy; 5 | import org.openqa.selenium.WebElement; 6 | 7 | @AndroidFindBy(className = "android.widget.RelativeLayout") 8 | public class AnnotatedAndroidMovie extends AndroidMovie { 9 | protected AnnotatedAndroidMovie(WebElement element) { 10 | super(element); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/annotated/AnnotatedAndroidMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import com.saucelabs.appium.page_object.widgets.Movies; 5 | import io.appium.java_client.pagefactory.AndroidFindBy; 6 | import org.openqa.selenium.WebElement; 7 | 8 | import java.util.List; 9 | 10 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/lvMovies") 11 | public class AnnotatedAndroidMovies extends Movies { 12 | 13 | List movieList; 14 | 15 | /* 16 | There could be additional behavior. 17 | But for test it is enough. 18 | */ 19 | 20 | protected AnnotatedAndroidMovies(WebElement element) { 21 | super(element); 22 | } 23 | 24 | @Override 25 | public int getMovieCount() { 26 | return movieList.size(); 27 | } 28 | 29 | @Override 30 | public Movie getMovie(int index) { 31 | return movieList.get(index); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/annotated/AnnotatedAndroidReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.android.simple.AndroidReview; 4 | import io.appium.java_client.pagefactory.AndroidFindBy; 5 | import io.appium.java_client.pagefactory.AndroidFindBys; 6 | import org.openqa.selenium.WebElement; 7 | 8 | @AndroidFindBys({@AndroidFindBy(id = "android:id/content"), 9 | @AndroidFindBy(className = "android.widget.RelativeLayout")}) 10 | public class AnnotatedAndroidReview extends AndroidReview { 11 | 12 | protected AnnotatedAndroidReview(WebElement element) { 13 | super(element); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/extended/ExtendedAndroidMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.android.annotated.AnnotatedAndroidMovies; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedAndroidMovies extends AnnotatedAndroidMovies { 7 | 8 | protected ExtendedAndroidMovies(WebElement element) { 9 | super(element); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/extended/ExtendedAndroidReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.android.annotated.AnnotatedAndroidReview; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedAndroidReview extends AnnotatedAndroidReview { 7 | 8 | protected ExtendedAndroidReview(WebElement element) { 9 | super(element); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/simple/AndroidMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import io.appium.java_client.android.AndroidElement; 5 | import io.appium.java_client.pagefactory.AndroidFindBy; 6 | import org.openqa.selenium.WebElement; 7 | 8 | public class AndroidMovie extends Movie { 9 | 10 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvTitle") 11 | private AndroidElement title; 12 | 13 | @AndroidFindBy(uiAutomator = "resourceId(\"com.codepath.example.rottentomatoes:id/tvCriticsScore\")") 14 | private AndroidElement score; 15 | 16 | @AndroidFindBy(accessibility = "poster image") 17 | private AndroidElement poster; 18 | 19 | protected AndroidMovie(WebElement element) { 20 | super(element); 21 | } 22 | 23 | @Override 24 | public String title() { 25 | return title.getText(); 26 | } 27 | 28 | @Override 29 | public String score() { 30 | return score.getText(); 31 | } 32 | 33 | @Override 34 | public Object getPoster() { 35 | return poster.getSize(); 36 | } 37 | 38 | @Override 39 | public void goToReview() { 40 | ((AndroidElement) getWrappedElement()).tap(1, 1500); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/simple/AndroidMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Movie; 5 | import com.saucelabs.appium.page_object.widgets.Movies; 6 | import io.appium.java_client.pagefactory.AndroidFindBy; 7 | import org.openqa.selenium.WebElement; 8 | 9 | import java.util.List; 10 | 11 | public class AndroidMovies extends Movies { 12 | 13 | @AndroidFindBy(className = "android.widget.RelativeLayout") 14 | List movieList; 15 | 16 | /* 17 | There could be additional behavior. 18 | But for test it is enough. 19 | */ 20 | 21 | protected AndroidMovies(WebElement element) { 22 | super(element); 23 | } 24 | 25 | @Override 26 | public int getMovieCount() { 27 | return movieList.size(); 28 | } 29 | 30 | @Override 31 | public Movie getMovie(int index) { 32 | return movieList.get(index); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/android/simple/AndroidReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.android.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Review; 5 | import io.appium.java_client.android.AndroidElement; 6 | import io.appium.java_client.pagefactory.AndroidFindBy; 7 | import org.openqa.selenium.WebElement; 8 | 9 | public class AndroidReview extends Review { 10 | 11 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvTitle") 12 | private AndroidElement title; 13 | 14 | @AndroidFindBy(uiAutomator = "resourceId(\"com.codepath.example.rottentomatoes:id/tvCriticsScore\")") 15 | private AndroidElement score; 16 | 17 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvSynopsis") 18 | private AndroidElement synopsis; 19 | 20 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/ivPosterImage") 21 | private AndroidElement poster; 22 | 23 | 24 | protected AndroidReview(WebElement element) { 25 | super(element); 26 | } 27 | 28 | @Override 29 | public String title() { 30 | return title.getText(); 31 | } 32 | 33 | @Override 34 | public String score() { 35 | return score.getText(); 36 | } 37 | 38 | @Override 39 | public String info() { 40 | return synopsis.getText(); 41 | } 42 | 43 | @Override 44 | public Object getPoster() { 45 | return poster.getSize(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/annotated/AnnotatedCombinedMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.combined.simple.CombinedMovie; 4 | import io.appium.java_client.pagefactory.AndroidFindBy; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | 8 | @AndroidFindBy(className = "android.widget.RelativeLayout") 9 | @FindBy(className = "mb-movie") 10 | public class AnnotatedCombinedMovie extends CombinedMovie { 11 | protected AnnotatedCombinedMovie(WebElement element) { 12 | super(element); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/annotated/AnnotatedCombinedMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.annotated; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Movie; 5 | import com.saucelabs.appium.page_object.widgets.Movies; 6 | import io.appium.java_client.pagefactory.AndroidFindBy; 7 | import io.appium.java_client.pagefactory.SelendroidFindBy; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.support.FindBy; 10 | 11 | import java.util.List; 12 | 13 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/lvMovies") 14 | @SelendroidFindBy(id = "lvMovies") 15 | @FindBy(id = "movies-collection") 16 | public class AnnotatedCombinedMovies extends Movies { 17 | 18 | List movieList; 19 | 20 | /* 21 | There could be additional behavior. 22 | But for test it is enough. 23 | */ 24 | 25 | protected AnnotatedCombinedMovies(WebElement element) { 26 | super(element); 27 | } 28 | 29 | @Override 30 | public int getMovieCount() { 31 | return movieList.size(); 32 | } 33 | 34 | @Override 35 | public Movie getMovie(int index) { 36 | return movieList.get(index); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/annotated/AnnotatedCombinedReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.annotated; 2 | 3 | 4 | 5 | import com.saucelabs.appium.page_object.widgets.combined.simple.CombinedReview; 6 | import io.appium.java_client.pagefactory.AndroidFindBy; 7 | import io.appium.java_client.pagefactory.AndroidFindBys; 8 | import io.appium.java_client.pagefactory.SelendroidFindBy; 9 | import org.openqa.selenium.WebElement; 10 | import org.openqa.selenium.support.FindBy; 11 | 12 | @FindBy(id = "main_container") 13 | @SelendroidFindBy(className = "android.widget.RelativeLayout") 14 | @AndroidFindBys({@AndroidFindBy(id = "android:id/content"), 15 | @AndroidFindBy(className = "android.widget.RelativeLayout")}) 16 | public class AnnotatedCombinedReview extends CombinedReview { 17 | protected AnnotatedCombinedReview(WebElement element) { 18 | super(element); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/extended/ExtendedCombinedMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.combined.annotated.AnnotatedCombinedMovies; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedCombinedMovies extends AnnotatedCombinedMovies { 7 | protected ExtendedCombinedMovies(WebElement element) { 8 | super(element); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/extended/ExtendedCombinedReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.combined.annotated.AnnotatedCombinedReview; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedCombinedReview extends AnnotatedCombinedReview { 7 | protected ExtendedCombinedReview(WebElement element) { 8 | super(element); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/simple/CombinedMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import io.appium.java_client.pagefactory.AndroidFindBy; 5 | import io.appium.java_client.pagefactory.SelendroidFindBy; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.remote.RemoteWebElement; 8 | import org.openqa.selenium.support.FindBy; 9 | 10 | public class CombinedMovie extends Movie { 11 | 12 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvTitle") 13 | @SelendroidFindBy(id = "tvTitle") 14 | @FindBy(className = "movieTitle") 15 | private RemoteWebElement title; 16 | 17 | @AndroidFindBy(uiAutomator = "resourceId(\"com.codepath.example.rottentomatoes:id/tvCriticsScore\")") 18 | @FindBy(className = "tMeterScore") 19 | @SelendroidFindBy(id = "tvCriticsScore") 20 | private RemoteWebElement score; 21 | 22 | @AndroidFindBy(accessibility = "poster image") 23 | @SelendroidFindBy(id = "ivPosterImage") 24 | @FindBy(className = "poster_container") 25 | private RemoteWebElement poster; 26 | 27 | @AndroidFindBy(accessibility = "poster image") 28 | @SelendroidFindBy(id = "ivPosterImage") 29 | @FindBy(xpath = ".//*[@class=\"movie_info\"]/a/h3") 30 | private RemoteWebElement movieSwitcher; 31 | 32 | protected CombinedMovie(WebElement element) { 33 | super(element); 34 | } 35 | 36 | @Override 37 | public String title() { 38 | return title.getText(); 39 | } 40 | 41 | @Override 42 | public String score() { 43 | return score.getText(); 44 | } 45 | 46 | @Override 47 | public Object getPoster() { 48 | return poster.getSize(); 49 | } 50 | 51 | @Override 52 | public void goToReview() { 53 | movieSwitcher.click(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/simple/CombinedMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Movie; 5 | import com.saucelabs.appium.page_object.widgets.Movies; 6 | import io.appium.java_client.pagefactory.AndroidFindBy; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.support.FindBy; 9 | 10 | import java.util.List; 11 | 12 | public class CombinedMovies extends Movies { 13 | 14 | @AndroidFindBy(className = "android.widget.RelativeLayout") 15 | @FindBy(className = "mb-movie") 16 | List movieList; 17 | 18 | /* 19 | There could be additional behavior. 20 | But for test it is enough. 21 | */ 22 | 23 | protected CombinedMovies(WebElement element) { 24 | super(element); 25 | } 26 | 27 | @Override 28 | public int getMovieCount() { 29 | return movieList.size(); 30 | } 31 | 32 | @Override 33 | public Movie getMovie(int index) { 34 | return movieList.get(index); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/combined/simple/CombinedReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.combined.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Review; 5 | import io.appium.java_client.pagefactory.AndroidFindBy; 6 | import io.appium.java_client.pagefactory.SelendroidFindBy; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.remote.RemoteWebElement; 9 | import org.openqa.selenium.support.FindBy; 10 | 11 | public class CombinedReview extends Review { 12 | 13 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvTitle") 14 | @FindBy(id = "movie-title") 15 | @SelendroidFindBy(id = "tvTitle") 16 | private RemoteWebElement title; 17 | 18 | @AndroidFindBy(uiAutomator = "resourceId(\"com.codepath.example.rottentomatoes:id/tvCriticsScore\")") 19 | @SelendroidFindBy(id = "tvCriticsScore") 20 | @FindBy(xpath = ".//*[@id=\"tomato_meter_link\"]//*[@itemprop=\"ratingValue\"]") 21 | private RemoteWebElement score; 22 | 23 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvSynopsis") 24 | @SelendroidFindBy(id = "tvSynopsis") 25 | private RemoteWebElement movieSynopsis; 26 | 27 | @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/ivPosterImage") 28 | @SelendroidFindBy(id = "ivPosterImage") 29 | @FindBy(className = "videoPic") 30 | private RemoteWebElement poster; 31 | 32 | 33 | protected CombinedReview(WebElement element) { 34 | super(element); 35 | } 36 | 37 | @Override 38 | public String title() { 39 | return title.getText(); 40 | } 41 | 42 | @Override 43 | public String score() { 44 | return score.getText(); 45 | } 46 | 47 | @Override 48 | public String info() { 49 | return movieSynopsis.getText(); 50 | } 51 | 52 | @Override 53 | public Object getPoster() { 54 | return poster.getSize(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/annotated/AnnotatedHtmlMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.html.simple.HtmlMovie; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | @FindBy(className = "mb-movie") 8 | public class AnnotatedHtmlMovie extends HtmlMovie { 9 | protected AnnotatedHtmlMovie(WebElement element) { 10 | super(element); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/annotated/AnnotatedHtmlMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import com.saucelabs.appium.page_object.widgets.Movies; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | 8 | import java.util.List; 9 | 10 | @FindBy(id = "movies-collection") 11 | public class AnnotatedHtmlMovies extends Movies { 12 | List movieList; 13 | 14 | /* 15 | There could be additional behavior. 16 | But for test it is enough. 17 | */ 18 | 19 | protected AnnotatedHtmlMovies(WebElement element) { 20 | super(element); 21 | } 22 | 23 | @Override 24 | public int getMovieCount() { 25 | return movieList.size(); 26 | } 27 | 28 | @Override 29 | public Movie getMovie(int index) { 30 | return movieList.get(index); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/annotated/AnnotatedHtmlReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.html.simple.HtmlReview; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | @FindBy(id = "main_container") 8 | public class AnnotatedHtmlReview extends HtmlReview { 9 | protected AnnotatedHtmlReview(WebElement element) { 10 | super(element); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/extended/ExtendedHtmlMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.html.annotated.AnnotatedHtmlMovies; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedHtmlMovies extends AnnotatedHtmlMovies { 7 | protected ExtendedHtmlMovies(WebElement element) { 8 | super(element); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/extended/ExtendedHtmlReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.html.annotated.AnnotatedHtmlReview; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedHtmlReview extends AnnotatedHtmlReview { 7 | protected ExtendedHtmlReview(WebElement element) { 8 | super(element); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/simple/HtmlMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class HtmlMovie extends Movie { 8 | 9 | @FindBy(className = "movieTitle") 10 | private WebElement title; 11 | 12 | @FindBy(className = "tMeterScore") 13 | private WebElement score; 14 | 15 | @FindBy(className = "poster_container") 16 | private WebElement poster; 17 | 18 | @FindBy(xpath = ".//*[@class=\"movie_info\"]/a/h3") 19 | private WebElement linkToMovie; 20 | 21 | 22 | 23 | protected HtmlMovie(WebElement element) { 24 | super(element); 25 | } 26 | 27 | @Override 28 | public String title() { 29 | return title.getText(); 30 | } 31 | 32 | @Override 33 | public String score() { 34 | return score.getText(); 35 | } 36 | 37 | @Override 38 | public Object getPoster() { 39 | return poster.getSize(); 40 | } 41 | 42 | @Override 43 | public void goToReview() { 44 | linkToMovie.click(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/simple/HtmlMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import com.saucelabs.appium.page_object.widgets.Movies; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | 8 | import java.util.List; 9 | 10 | public class HtmlMovies extends Movies { 11 | 12 | @FindBy(className = "mb-movie") 13 | List movieList; 14 | 15 | /* 16 | There could be additional behavior. 17 | But for test it is enough. 18 | */ 19 | 20 | protected HtmlMovies(WebElement element) { 21 | super(element); 22 | } 23 | 24 | @Override 25 | public int getMovieCount() { 26 | return movieList.size(); 27 | } 28 | 29 | @Override 30 | public Movie getMovie(int index) { 31 | return movieList.get(index); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/html/simple/HtmlReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.html.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Review; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class HtmlReview extends Review { 8 | 9 | @FindBy(id = "movie-title") 10 | private WebElement title; 11 | 12 | @FindBy(xpath = ".//*[@id=\"tomato_meter_link\"]//*[@itemprop=\"ratingValue\"]") 13 | private WebElement score; 14 | 15 | private WebElement movieSynopsis; 16 | 17 | @FindBy(className = "videoPic") 18 | private WebElement poster; 19 | 20 | 21 | protected HtmlReview(WebElement element) { 22 | super(element); 23 | } 24 | 25 | @Override 26 | public String title() { 27 | return title.getText(); 28 | } 29 | 30 | @Override 31 | public String score() { 32 | return score.getText(); 33 | } 34 | 35 | @Override 36 | public String info() { 37 | return movieSynopsis.getText(); 38 | } 39 | 40 | @Override 41 | public Object getPoster() { 42 | return poster.getSize(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/annotated/AnnotatedIOSMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.ios.simple.IOSMovie; 4 | import io.appium.java_client.pagefactory.iOSFindBy; 5 | import org.openqa.selenium.WebElement; 6 | 7 | @iOSFindBy(className = "UIATableCell") 8 | public class AnnotatedIOSMovie extends IOSMovie { 9 | protected AnnotatedIOSMovie(WebElement element) { 10 | super(element); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/annotated/AnnotatedIOSMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import com.saucelabs.appium.page_object.widgets.Movies; 5 | import io.appium.java_client.pagefactory.iOSFindBy; 6 | import org.openqa.selenium.WebElement; 7 | 8 | import java.util.List; 9 | 10 | @iOSFindBy(className = "UIATableView") 11 | public class AnnotatedIOSMovies extends Movies { 12 | 13 | List movieList; 14 | 15 | /* 16 | There could be additional behavior. 17 | But for test it is enough. 18 | */ 19 | 20 | protected AnnotatedIOSMovies(WebElement element) { 21 | super(element); 22 | } 23 | 24 | @Override 25 | public int getMovieCount() { 26 | return movieList.size(); 27 | } 28 | 29 | @Override 30 | public Movie getMovie(int index) { 31 | return movieList.get(index); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/annotated/AnnotatedIOSReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.annotated; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.ios.simple.IOSReview; 5 | import io.appium.java_client.pagefactory.iOSFindBy; 6 | import org.openqa.selenium.WebElement; 7 | 8 | @iOSFindBy(className = "UIAWindow") 9 | public class AnnotatedIOSReview extends IOSReview { 10 | protected AnnotatedIOSReview(WebElement element) { 11 | super(element); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/extended/ExtendedIOSMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.ios.annotated.AnnotatedIOSMovies; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedIOSMovies extends AnnotatedIOSMovies { 7 | protected ExtendedIOSMovies(WebElement element) { 8 | super(element); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/extended/ExtendedIOSReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.ios.annotated.AnnotatedIOSReview; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedIOSReview extends AnnotatedIOSReview { 7 | protected ExtendedIOSReview(WebElement element) { 8 | super(element); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/simple/IOSMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import io.appium.java_client.ios.IOSElement; 5 | import io.appium.java_client.pagefactory.iOSFindBy; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.remote.RemoteWebElement; 8 | 9 | public class IOSMovie extends Movie { 10 | 11 | @iOSFindBy(className = "UIAStaticText") 12 | private IOSElement staticText; 13 | 14 | protected IOSMovie(WebElement element) { 15 | super(element); 16 | } 17 | 18 | @Override 19 | public String title() { 20 | return staticText.getText().split(",")[0]; 21 | } 22 | 23 | @Override 24 | public String score() { 25 | return staticText.getText().split(",")[3]; 26 | } 27 | 28 | @Override 29 | public Object getPoster() { 30 | return ((RemoteWebElement) getWrappedElement()).getSize(); 31 | } 32 | 33 | @Override 34 | public void goToReview() { 35 | ((IOSElement) getWrappedElement()).tap(1, 1500); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/simple/IOSMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import com.saucelabs.appium.page_object.widgets.Movies; 5 | import io.appium.java_client.pagefactory.iOSFindBy; 6 | import org.openqa.selenium.WebElement; 7 | 8 | import java.util.List; 9 | 10 | //classNme = UIATableView 11 | public class IOSMovies extends Movies { 12 | 13 | @iOSFindBy(className = "UIATableCell") 14 | List movieList; 15 | 16 | /* 17 | There could be additional behavior. 18 | But for test it is enough. 19 | */ 20 | 21 | protected IOSMovies(WebElement element) { 22 | super(element); 23 | } 24 | 25 | @Override 26 | public int getMovieCount() { 27 | return movieList.size(); 28 | } 29 | 30 | @Override 31 | public Movie getMovie(int index) { 32 | return movieList.get(index); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/ios/simple/IOSReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.ios.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Review; 5 | import io.appium.java_client.ios.IOSElement; 6 | import io.appium.java_client.pagefactory.iOSFindBy; 7 | import io.appium.java_client.pagefactory.iOSFindBys; 8 | import org.openqa.selenium.WebElement; 9 | 10 | //className = UIAWindow 11 | public class IOSReview extends Review { 12 | 13 | @iOSFindBys({@iOSFindBy(className = "UIANavigationBar"), 14 | @iOSFindBy(className = "UIAStaticText")}) 15 | private IOSElement title; 16 | 17 | @iOSFindBys({@iOSFindBy(className = "UIAScrollView"), 18 | @iOSFindBy(className = "UIAStaticText")}) 19 | private IOSElement synopsis; 20 | 21 | @iOSFindBy(className = "UIAImage") 22 | private IOSElement poster; 23 | 24 | 25 | protected IOSReview(WebElement element) { 26 | super(element); 27 | } 28 | 29 | @Override 30 | public String title() { 31 | return title.getText(); 32 | } 33 | 34 | @Override 35 | public String score() { 36 | return "100"; 37 | } 38 | 39 | @Override 40 | public String info() { 41 | return synopsis.getText(); 42 | } 43 | 44 | @Override 45 | public Object getPoster() { 46 | return poster.getSize(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/annotated/AnnotatedSelendroidMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.annotated; 2 | 3 | import com.saucelabs.appium.page_object.widgets.selendroid.simple.SelendroidMovie; 4 | import io.appium.java_client.pagefactory.SelendroidFindBy; 5 | import org.openqa.selenium.WebElement; 6 | 7 | @SelendroidFindBy(className = "android.widget.RelativeLayout") 8 | public class AnnotatedSelendroidMovie extends SelendroidMovie { 9 | 10 | protected AnnotatedSelendroidMovie(WebElement element) { 11 | super(element); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/annotated/AnnotatedSelendroidMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.annotated; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Movie; 5 | import com.saucelabs.appium.page_object.widgets.Movies; 6 | import io.appium.java_client.pagefactory.SelendroidFindBy; 7 | import org.openqa.selenium.WebElement; 8 | 9 | import java.util.List; 10 | 11 | @SelendroidFindBy(id = "lvMovies") 12 | public class AnnotatedSelendroidMovies extends Movies { 13 | 14 | List movieList; 15 | 16 | /* 17 | There could be additional behavior. 18 | But for test it is enough. 19 | */ 20 | 21 | protected AnnotatedSelendroidMovies(WebElement element) { 22 | super(element); 23 | } 24 | 25 | @Override 26 | public int getMovieCount() { 27 | return movieList.size(); 28 | } 29 | 30 | @Override 31 | public Movie getMovie(int index) { 32 | return movieList.get(index); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/annotated/AnnotatedSelendroidReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.annotated; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.selendroid.simple.SelendroidReview; 5 | import io.appium.java_client.pagefactory.SelendroidFindBy; 6 | import org.openqa.selenium.WebElement; 7 | 8 | 9 | @SelendroidFindBy(className = "android.widget.RelativeLayout") 10 | public class AnnotatedSelendroidReview extends SelendroidReview { 11 | 12 | protected AnnotatedSelendroidReview(WebElement element) { 13 | super(element); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/extended/ExtendedSelendroidMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.selendroid.annotated.AnnotatedSelendroidMovies; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedSelendroidMovies extends AnnotatedSelendroidMovies { 7 | 8 | protected ExtendedSelendroidMovies(WebElement element) { 9 | super(element); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/extended/ExtendedSelendroidReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.extended; 2 | 3 | import com.saucelabs.appium.page_object.widgets.selendroid.annotated.AnnotatedSelendroidReview; 4 | import org.openqa.selenium.WebElement; 5 | 6 | public class ExtendedSelendroidReview extends AnnotatedSelendroidReview { 7 | 8 | protected ExtendedSelendroidReview(WebElement element) { 9 | super(element); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/simple/SelendroidMovie.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.simple; 2 | 3 | import com.saucelabs.appium.page_object.widgets.Movie; 4 | import io.appium.java_client.pagefactory.SelendroidFindBy; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.remote.RemoteWebElement; 7 | 8 | public class SelendroidMovie extends Movie { 9 | 10 | @SelendroidFindBy(id = "tvTitle") 11 | private RemoteWebElement title; 12 | 13 | @SelendroidFindBy(id = "tvCriticsScore") 14 | private RemoteWebElement score; 15 | 16 | @SelendroidFindBy(id = "ivPosterImage") 17 | private RemoteWebElement poster; 18 | 19 | protected SelendroidMovie(WebElement element) { 20 | super(element); 21 | } 22 | 23 | @Override 24 | public String title() { 25 | return title.getText(); 26 | } 27 | 28 | @Override 29 | public String score() { 30 | return score.getText(); 31 | } 32 | 33 | @Override 34 | public Object getPoster() { 35 | return poster.getSize(); 36 | } 37 | 38 | @Override 39 | public void goToReview() { 40 | getWrappedElement().click(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/simple/SelendroidMovies.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Movie; 5 | import com.saucelabs.appium.page_object.widgets.Movies; 6 | import io.appium.java_client.pagefactory.SelendroidFindBy; 7 | import org.openqa.selenium.WebElement; 8 | 9 | import java.util.List; 10 | 11 | public class SelendroidMovies extends Movies { 12 | 13 | @SelendroidFindBy(className = "android.widget.RelativeLayout") 14 | List movieList; 15 | 16 | /* 17 | There could be additional behavior. 18 | But for test it is enough. 19 | */ 20 | 21 | protected SelendroidMovies(WebElement element) { 22 | super(element); 23 | } 24 | 25 | @Override 26 | public int getMovieCount() { 27 | return movieList.size(); 28 | } 29 | 30 | @Override 31 | public Movie getMovie(int index) { 32 | return movieList.get(index); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sample-code/examples/java/junit/src/test/java/com/saucelabs/appium/page_object/widgets/selendroid/simple/SelendroidReview.java: -------------------------------------------------------------------------------- 1 | package com.saucelabs.appium.page_object.widgets.selendroid.simple; 2 | 3 | 4 | import com.saucelabs.appium.page_object.widgets.Review; 5 | import io.appium.java_client.pagefactory.SelendroidFindBy; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.remote.RemoteWebElement; 8 | 9 | public class SelendroidReview extends Review { 10 | 11 | @SelendroidFindBy(id = "tvTitle") 12 | private RemoteWebElement title; 13 | 14 | @SelendroidFindBy(id = "tvCriticsScore") 15 | private RemoteWebElement score; 16 | 17 | @SelendroidFindBy(id = "tvSynopsis") 18 | private RemoteWebElement synopsis; 19 | 20 | @SelendroidFindBy(id = "ivPosterImage") 21 | private RemoteWebElement poster; 22 | 23 | 24 | protected SelendroidReview(WebElement element) { 25 | super(element); 26 | } 27 | 28 | @Override 29 | public String title() { 30 | return title.getText(); 31 | } 32 | 33 | @Override 34 | public String score() { 35 | return score.getText(); 36 | } 37 | 38 | @Override 39 | public String info() { 40 | return synopsis.getText(); 41 | } 42 | 43 | @Override 44 | public Object getPoster() { 45 | return poster.getSize(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /sample-code/examples/node/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | -------------------------------------------------------------------------------- /sample-code/examples/node/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "laxcomma": true, 3 | "strict": true, 4 | "undef": true, 5 | "unused": true, 6 | "trailing": true, 7 | "node": true, 8 | "eqeqeq": true, 9 | "expr": true, 10 | "white": true, 11 | "indent": 2, 12 | "globals": { 13 | "describe": true, 14 | "it": true, 15 | "before": true, 16 | "after": true, 17 | "beforeEach": true, 18 | "afterEach": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample-code/examples/node/README.md: -------------------------------------------------------------------------------- 1 | # Node.js samples 2 | 3 | ## Prerequisites 4 | 5 | Install local packages: 6 | 7 | ``` 8 | npm install 9 | ``` 10 | 11 | ### To run tests using Sauce Labs cloud 12 | 13 | [Sign up here](https://saucelabs.com/signup/trial) 14 | 15 | Then when running the tests, add your Sauce Labs credentials as npm config parameters, example : 16 | 17 | ``` 18 | npm run ios-simple --appium-sample-code:sauce=1 --appium-sample-code:username= --appium-sample-code:key= 19 | 20 | ``` 21 | 22 | Or set the config parameters directly in package.json : 23 | 24 | ``` 25 | // package.json 26 | 27 | ... 28 | "config":{ 29 | "sauce":"1", 30 | "sauce_username":"", 31 | "sauce_access_key":"" 32 | }, 33 | ... 34 | ``` 35 | 36 | If you also want to use Sauce Connect (secure tunelling): 37 | 38 | - [Read the doc here](https://saucelabs.com/docs/connect) 39 | - Install and start the Sauce Connect client 40 | 41 | 42 | ### To run tests locally 43 | 44 | Install appium and start the appium server for your device, please refer to: 45 | 46 | - http://appium.io 47 | - https://github.com/appium/appium/blob/master/README.md 48 | 49 | ## Running tests 50 | 51 | ### iOS 52 | 53 | ``` 54 | npm run ios-simple 55 | npm run ios-complex 56 | npm run ios-webview 57 | npm run ios-actions 58 | npm run ios-local-server 59 | npm run ios-selenium-webdriver-bridge 60 | ``` 61 | 62 | ### Android 63 | 64 | ``` 65 | npm run android-simple 66 | npm run android-complex 67 | npm run android-webview 68 | npm run android-local-server 69 | ``` 70 | 71 | ### Selendroid 72 | 73 | ``` 74 | npm run selendroid-simple 75 | ``` 76 | 77 | ### Node.js 0.11 + Generator with Yiewd 78 | 79 | prerequisite: switch to node > 0.11 80 | 81 | ``` 82 | npm run ios-yiewd 83 | ``` 84 | -------------------------------------------------------------------------------- /sample-code/examples/node/android-local-server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("./helpers/setup"); 4 | 5 | var wd = require("wd"), 6 | _ = require('underscore'), 7 | serverConfigs = require('./helpers/appium-servers'), 8 | localServer = require('./helpers/local-server'); 9 | 10 | describe("android local server", function () { 11 | this.timeout(300000); 12 | var driver; 13 | var allPassed = true; 14 | 15 | before(function () { 16 | localServer.start(); 17 | var serverConfig = process.env.npm_package_config_sauce ? 18 | serverConfigs.sauce : serverConfigs.local; 19 | driver = wd.promiseChainRemote(serverConfig); 20 | require("./helpers/logging").configure(driver); 21 | 22 | var desired = process.env.npm_package_config_sauce ? 23 | _.clone(require("./helpers/caps").android18) : 24 | _.clone(require("./helpers/caps").android19); 25 | desired.app = require("./helpers/apps").androidApiDemosLocal; 26 | if (process.env.npm_package_config_sauce) { 27 | desired.name = 'android - local server'; 28 | desired.tags = ['sample']; 29 | } 30 | return driver.init(desired); 31 | }); 32 | 33 | after(function () { 34 | localServer.stop(); 35 | return driver 36 | .quit() 37 | .finally(function () { 38 | if (process.env.npm_package_config_sauce) { 39 | return driver.sauceJobStatus(allPassed); 40 | } 41 | }); 42 | }); 43 | 44 | afterEach(function () { 45 | allPassed = allPassed && this.currentTest.state === 'passed'; 46 | }); 47 | 48 | 49 | it("should open the app", function () { 50 | return driver 51 | .elementByAccessibilityId('Graphics') 52 | .should.eventually.exist; 53 | }); 54 | 55 | }); 56 | -------------------------------------------------------------------------------- /sample-code/examples/node/android-simple.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("./helpers/setup"); 4 | 5 | var wd = require("wd"), 6 | _ = require('underscore'), 7 | serverConfigs = require('./helpers/appium-servers'); 8 | 9 | describe("android simple", function () { 10 | this.timeout(300000); 11 | var driver; 12 | var allPassed = true; 13 | 14 | before(function () { 15 | var serverConfig = process.env.npm_package_config_sauce ? 16 | serverConfigs.sauce : serverConfigs.local; 17 | driver = wd.promiseChainRemote(serverConfig); 18 | require("./helpers/logging").configure(driver); 19 | 20 | var desired = process.env.npm_package_config_sauce ? 21 | _.clone(require("./helpers/caps").android18) : 22 | _.clone(require("./helpers/caps").android19); 23 | desired.app = require("./helpers/apps").androidApiDemos; 24 | if (process.env.npm_package_config_sauce) { 25 | desired.name = 'android - simple'; 26 | desired.tags = ['sample']; 27 | } 28 | return driver 29 | .init(desired) 30 | .setImplicitWaitTimeout(3000); 31 | }); 32 | 33 | after(function () { 34 | return driver 35 | .quit() 36 | .finally(function () { 37 | if (process.env.npm_package_config_sauce) { 38 | return driver.sauceJobStatus(allPassed); 39 | } 40 | }); 41 | }); 42 | 43 | afterEach(function () { 44 | allPassed = allPassed && this.currentTest.state === 'passed'; 45 | }); 46 | 47 | it("should find an element", function () { 48 | return driver 49 | .elementByAccessibilityId('Graphics') 50 | .click() 51 | .elementByAccessibilityId('Arcs') 52 | .should.eventually.exist 53 | .back() 54 | .elementByName('App') 55 | .should.eventually.exist 56 | .elementsByAndroidUIAutomator('new UiSelector().clickable(true)') 57 | .should.eventually.have.length(12) 58 | .elementsByAndroidUIAutomator('new UiSelector().enabled(true)') 59 | .should.eventually.have.length.above(20) 60 | .elementByXPath('//android.widget.TextView[@text=\'API Demos\']') 61 | .should.exists; 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /sample-code/examples/node/android-webview.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("./helpers/setup"); 4 | 5 | var wd = require("wd"), 6 | _ = require('underscore'), 7 | serverConfigs = require('./helpers/appium-servers'); 8 | 9 | describe("android webview", function () { 10 | this.timeout(300000); 11 | var driver; 12 | var allPassed = true; 13 | 14 | before(function () { 15 | var serverConfig = process.env.npm_package_config_sauce ? 16 | serverConfigs.sauce : serverConfigs.local; 17 | driver = wd.promiseChainRemote(serverConfig); 18 | require("./helpers/logging").configure(driver); 19 | 20 | var desired = process.env.npm_package_config_sauce ? 21 | _.clone(require("./helpers/caps").android18) : 22 | _.clone(require("./helpers/caps").android19); 23 | desired.app = require("./helpers/apps").selendroidTestApp; 24 | if (process.env.npm_package_config_sauce) { 25 | desired.name = 'android - webview'; 26 | desired.tags = ['sample']; 27 | } 28 | return driver 29 | .init(desired) 30 | .setImplicitWaitTimeout(3000); 31 | }); 32 | 33 | after(function () { 34 | return driver 35 | .quit() 36 | .finally(function () { 37 | if (process.env.npm_package_config_sauce) { 38 | return driver.sauceJobStatus(allPassed); 39 | } 40 | }); 41 | }); 42 | 43 | afterEach(function () { 44 | allPassed = allPassed && this.currentTest.state === 'passed'; 45 | }); 46 | 47 | it("should switch to webview", function () { 48 | return driver 49 | .elementById('buttonStartWebviewCD') 50 | .click() 51 | .sleep(5000) 52 | .contexts() 53 | .then(function (ctxs) { 54 | console.log(ctxs); 55 | return driver.context(ctxs[ctxs.length - 1]); 56 | }) 57 | .elementById('name_input') 58 | .clear() 59 | .sendKeys('Appium User') 60 | .sendKeys(wd.SPECIAL_KEYS.Return) 61 | .sleep(1000) 62 | .source().then(function (source) { 63 | source.should.include('This is my way of saying hello'); 64 | source.should.include('Appium User'); 65 | }); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /sample-code/examples/node/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Appium Rocks 4 | 5 | 6 | 7 |

Appium Rocks

8 | 9 |
10 |

11 | Wow this is so cool! 12 |

13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/actions.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var wd = require('wd'), 4 | Q = require('q'); 5 | 6 | exports.swipe = function (opts) { 7 | var action = new wd.TouchAction(); 8 | action 9 | .press({x: opts.startX, y: opts.startY}) 10 | .wait(opts.duration) 11 | .moveTo({x: opts.endX, y: opts.endY}) 12 | .release(); 13 | return this.performTouchAction(action); 14 | }; 15 | 16 | exports.pinch = function (el) { 17 | return Q.all([ 18 | el.getSize(), 19 | el.getLocation(), 20 | ]).then(function (res) { 21 | var size = res[0]; 22 | var loc = res[1]; 23 | var center = { 24 | x: loc.x + size.width / 2, 25 | y: loc.y + size.height / 2 26 | }; 27 | var a1 = new wd.TouchAction(this); 28 | a1.press({el: el, x: center.x, y: center.y - 100}).moveTo({el: el}).release(); 29 | var a2 = new wd.TouchAction(this); 30 | a2.press({el: el, x: center.x, y: center.y + 100}).moveTo({el: el}).release(); 31 | var m = new wd.MultiAction(this); 32 | m.add(a1, a2); 33 | return m.perform(); 34 | }.bind(this)); 35 | }; 36 | 37 | exports.zoom = function (el) { 38 | return Q.all([ 39 | this.getWindowSize(), 40 | this.getLocation(el), 41 | ]).then(function (res) { 42 | var size = res[0]; 43 | var loc = res[1]; 44 | var center = { 45 | x: loc.x + size.width / 2, 46 | y: loc.y + size.height / 2 47 | }; 48 | var a1 = new wd.TouchAction(this); 49 | a1.press({el: el}).moveTo({el: el, x: center.x, y: center.y - 100}).release(); 50 | var a2 = new wd.TouchAction(this); 51 | a2.press({el: el}).moveTo({el: el, x: center.x, y: center.y + 100}).release(); 52 | var m = new wd.MultiAction(this); 53 | m.add(a1, a2); 54 | return m.perform(); 55 | }.bind(this)); 56 | }; 57 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/appium-servers.js: -------------------------------------------------------------------------------- 1 | 2 | exports.local = { 3 | host: 'localhost', 4 | port: 4723 5 | }; 6 | 7 | exports.sauce = { 8 | host: 'ondemand.saucelabs.com', 9 | port: 80, 10 | auth: process.env.npm_package_config_username + ":" + process.env.npm_package_config_key 11 | }; 12 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/apps.js: -------------------------------------------------------------------------------- 1 | if (process.env.DEV) { 2 | exports.iosTestApp = "sample-code/apps/TestApp/build/release-iphonesimulator/TestApp-iphonesimulator.app"; 3 | exports.iosWebviewApp = "sample-code/apps/WebViewApp/build/release-iphonesimulator/WebViewApp.app"; 4 | exports.iosUICatalogApp = "sample-code/apps/UICatalog/build/release-iphonesimulator/UICatalog.app"; 5 | exports.androidApiDemos = "sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk"; 6 | exports.selendroidTestApp = "sample-code/apps/selendroid-test-app.apk"; 7 | } else { 8 | exports.iosTestApp = "http://appium.github.io/appium/assets/TestApp7.1.app.zip"; 9 | exports.iosWebviewApp = "http://appium.github.io/appium/assets/WebViewApp7.1.app.zip"; 10 | exports.iosUICatalogApp = "http://appium.github.io/appium/assets/UICatalog7.1.app.zip"; 11 | exports.androidApiDemos = "http://appium.github.io/appium/assets/ApiDemos-debug.apk"; 12 | exports.selendroidTestApp = "http://appium.github.io/appium/assets/selendroid-test-app-0.10.0.apk"; 13 | 14 | exports.iosWebviewAppLocal = "http://localhost:3000/WebViewApp7.1.app.zip"; 15 | exports.androidApiDemosLocal = "http://localhost:3000/ApiDemos-debug.apk"; 16 | } 17 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/caps.js: -------------------------------------------------------------------------------- 1 | exports.ios92 = { 2 | browserName: '', 3 | 'appium-version': '1.6', 4 | platformName: 'iOS', 5 | platformVersion: '10.1', 6 | deviceName: 'iPhone 5s', 7 | app: undefined // will be set later 8 | }; 9 | 10 | exports.ios81 = { 11 | browserName: '', 12 | 'appium-version': '1.6', 13 | platformName: 'iOS', 14 | platformVersion: '10.1', 15 | deviceName: 'iPhone Simulator', 16 | app: undefined // will be set later 17 | }; 18 | 19 | exports.android18 = { 20 | browserName: '', 21 | 'appium-version': '1.6', 22 | platformName: 'Android', 23 | platformVersion: '5.1', 24 | deviceName: 'Android Emulator', 25 | app: undefined // will be set later 26 | }; 27 | 28 | exports.android19 = { 29 | browserName: '', 30 | 'appium-version': '1.6', 31 | platformName: 'Android', 32 | platformVersion: '5.1', 33 | deviceName: 'Android Emulator', 34 | app: undefined // will be set later 35 | }; 36 | 37 | exports.selendroid16 = { 38 | browserName: '', 39 | 'appium-version': '1.6', 40 | platformName: 'Android', 41 | platformVersion: '5.1', 42 | automationName: 'selendroid', 43 | deviceName: 'Android Emulator', 44 | app: undefined // will be set later 45 | }; 46 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/local-server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var express = require('express'), 4 | app = express(), 5 | path = require('path'); 6 | 7 | app.use(express.static(__dirname + '/static')); 8 | 9 | app.get('/index.html', function (req, res) { 10 | res.sendFile(path.resolve(__dirname, '../assets/index.html')); 11 | }); 12 | 13 | app.get('/WebViewApp7.1.app.zip', function (req, res) { 14 | res.sendFile(path.resolve(__dirname, '../dotnet/AppiumDotNetSample/Resources/WebViewApp7.1.app.zip')); 15 | }); 16 | 17 | app.get('/ApiDemos-debug.apk', function (req, res) { 18 | res.sendFile(path.resolve(__dirname, '../../../apps/ApiDemos/bin/ApiDemos-debug.apk')); 19 | }); 20 | 21 | var server; 22 | 23 | exports.start = function () { 24 | server = app.listen(3000); 25 | }; 26 | 27 | exports.stop = function () { 28 | server.close(); 29 | }; 30 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/logging.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.configure = function (driver) { 4 | // See whats going on 5 | driver.on('status', function (info) { 6 | console.log(info.cyan); 7 | }); 8 | driver.on('command', function (meth, path, data) { 9 | console.log(' > ' + meth.yellow, path.grey, data || ''); 10 | }); 11 | driver.on('http', function (meth, path, data) { 12 | console.log(' > ' + meth.magenta, path, (data || '').grey); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/promise-utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Q = require('q'), 4 | _ = require('underscore'); 5 | 6 | exports.each = function (fn) { 7 | return function (els) { 8 | var seq = _(els).map(function (el, i) { 9 | return function () { 10 | return fn(el, i); 11 | }; 12 | }); 13 | // iterating 14 | return seq.reduce(Q.when, new Q()).then(function () { 15 | return els; 16 | }); 17 | }; 18 | }; 19 | 20 | exports.filter = function (fn) { 21 | return function (els) { 22 | var seq = _(els).map(function (el, i) { 23 | return function (filteredEls) { 24 | return fn(el, i).then(function (isOk) { 25 | if (isOk) filteredEls.push(el); 26 | return filteredEls; 27 | }); 28 | }; 29 | }); 30 | // iterating 31 | return seq.reduce(Q.when, new Q([])); 32 | }; 33 | }; 34 | 35 | exports.printNames = exports.each(function (el, i) { 36 | return el.getAttribute('name').print(i + "--> "); 37 | }); 38 | 39 | exports.filterDisplayed = exports.filter(function (el) { 40 | return el.isDisplayed(); 41 | }); 42 | 43 | exports.filterWithName = function (name) { 44 | return exports.filter(function (el) { 45 | return el.getAttribute('name').then(function (_name) { 46 | return _name === name; 47 | }); 48 | }); 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /sample-code/examples/node/helpers/setup.js: -------------------------------------------------------------------------------- 1 | var wd = require("wd"); 2 | 3 | require('colors'); 4 | var chai = require("chai"); 5 | var chaiAsPromised = require("chai-as-promised"); 6 | chai.use(chaiAsPromised); 7 | var should = chai.should(); 8 | chaiAsPromised.transferPromiseness = wd.transferPromiseness; 9 | 10 | if (process.env.npm_package_config_sauce) { 11 | process.env.SAUCE_USERNAME = process.env.npm_package_config_sauce_username; 12 | process.env.SAUCE_ACCESS_KEY = process.env.npm_package_config_sauce_access_key; 13 | } 14 | 15 | exports.should = should; 16 | -------------------------------------------------------------------------------- /sample-code/examples/node/ios-local-server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("./helpers/setup"); 4 | 5 | var wd = require("wd"), 6 | _ = require('underscore'), 7 | serverConfigs = require('./helpers/appium-servers'), 8 | localServer = require('./helpers/local-server'); 9 | 10 | describe("ios local server", function () { 11 | this.timeout(300000); 12 | var driver; 13 | var allPassed = true; 14 | 15 | before(function () { 16 | localServer.start(); 17 | var serverConfig = process.env.npm_package_config_sauce ? 18 | serverConfigs.sauce : serverConfigs.local; 19 | driver = wd.promiseChainRemote(serverConfig); 20 | require("./helpers/logging").configure(driver); 21 | 22 | var desired = _.clone(require("./helpers/caps").ios81); 23 | desired.app = require("./helpers/apps").iosWebviewAppLocal; 24 | if (process.env.npm_package_config_sauce) { 25 | desired.name = 'ios - local server'; 26 | desired.tags = ['sample']; 27 | } 28 | return driver.init(desired); 29 | }); 30 | 31 | after(function () { 32 | localServer.stop(); 33 | return driver 34 | .quit() 35 | .finally(function () { 36 | if (process.env.npm_package_config_sauce) { 37 | return driver.sauceJobStatus(allPassed); 38 | } 39 | }); 40 | }); 41 | 42 | afterEach(function () { 43 | allPassed = allPassed && this.currentTest.state === 'passed'; 44 | }); 45 | 46 | 47 | it("should get the url", function () { 48 | return driver 49 | .elementByXPath('//UIATextField[@value=\'Enter URL\']') 50 | .sendKeys('http://localhost:3000/index.html') 51 | .elementByName('Go').click() 52 | .elementByClassName('UIAWebView').click() // dismissing keyboard 53 | .context('WEBVIEW') 54 | .sleep(3000) 55 | .waitForElementById('wow') 56 | .text().should.eventually.include('so cool'); 57 | }); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /sample-code/examples/node/ios-webview.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("./helpers/setup"); 4 | 5 | var wd = require("wd"), 6 | _ = require('underscore'), 7 | serverConfigs = require('./helpers/appium-servers'); 8 | 9 | describe("ios webview", function () { 10 | this.timeout(300000); 11 | var driver; 12 | var allPassed = true; 13 | 14 | before(function () { 15 | var serverConfig = process.env.npm_package_config_sauce ? 16 | serverConfigs.sauce : serverConfigs.local; 17 | driver = wd.promiseChainRemote(serverConfig); 18 | require("./helpers/logging").configure(driver); 19 | 20 | var desired = _.clone(require("./helpers/caps").ios81); 21 | desired.app = require("./helpers/apps").iosWebviewApp; 22 | if (process.env.npm_package_config_sauce) { 23 | desired.name = 'ios - webview'; 24 | desired.tags = ['sample']; 25 | } 26 | return driver.init(desired); 27 | }); 28 | 29 | after(function () { 30 | return driver 31 | .quit() 32 | .finally(function () { 33 | if (process.env.npm_package_config_sauce) { 34 | return driver.sauceJobStatus(allPassed); 35 | } 36 | }); 37 | }); 38 | 39 | afterEach(function () { 40 | allPassed = allPassed && this.currentTest.state === 'passed'; 41 | }); 42 | 43 | 44 | it("should get the url", function () { 45 | return driver 46 | .elementByXPath('//UIATextField[@value=\'Enter URL\']') 47 | .sendKeys('www.google.com') 48 | .elementByName('Go').click() 49 | .sleep(20000) 50 | .source().then(console.log) 51 | .elementByClassName('UIAWebView').click() // dismissing keyboard 52 | .sleep(10000) 53 | .context('WEBVIEW') 54 | .sleep(1000) 55 | .waitForElementByName('q', 5000) 56 | .sendKeys('sauce labs') 57 | .sendKeys(wd.SPECIAL_KEYS.Return) 58 | .sleep(1000) 59 | .title().should.eventually.include('sauce labs'); 60 | }); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /sample-code/examples/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "appium-sample-code", 3 | "version": "1.0.0", 4 | "description": "Appium Sample Code", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/appium/sample-code.git" 9 | }, 10 | "keywords": [ 11 | "appium", 12 | "sampl", 13 | "examples" 14 | ], 15 | "author": "sebv", 16 | "license": "Apache-2.0", 17 | "bugs": { 18 | "url": "https://github.com/appium/sample-code/issues" 19 | }, 20 | "homepage": "https://github.com/appium/sample-code", 21 | "devDependencies": { 22 | "chai": "^2.2.0", 23 | "chai-as-promised": "^5.0.0", 24 | "colors": "^1.0.3", 25 | "express": "^4.12.3", 26 | "mocha": "^2.4.5", 27 | "q": "^2.0.2", 28 | "underscore": "^1.8.3", 29 | "wd": "^0.3.11" 30 | }, 31 | "scripts": { 32 | "ios-simple": "mocha ios-simple.js", 33 | "ios-complex": "mocha ios-complex.js", 34 | "ios-webview": "mocha ios-webview.js", 35 | "ios-actions": "mocha ios-actions.js", 36 | "ios-local-server": "mocha ios-local-server.js", 37 | "ios-selenium-webdriver-bridge": "mocha ios-selenium-webdriver-bridge.js", 38 | "ios-yiewd": "mocha --harmony ios-yiewd.js", 39 | "android-simple": "mocha android-simple.js", 40 | "android-complex": "mocha android-complex.js", 41 | "android-webview": "mocha android-webview.js", 42 | "android-local-server": "mocha android-local-server.js", 43 | "selendroid-simple": "mocha selendroid-simple.js" 44 | }, 45 | "dependencies": { 46 | "selenium-webdriver": "^3.0.0-beta-3", 47 | "wd-bridge": "0.0.2", 48 | "yiewd": "^0.6.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /sample-code/examples/node/protractor-bridge/conf.js: -------------------------------------------------------------------------------- 1 | /* 2 | The appium specific methods are not yet implemented by selenium-webdriver, 3 | and therefore not available in Protractor. However it is possible to attach 4 | an existing Protractor session to a wd browser instance as below. 5 | 6 | prerequisites: 7 | npm install protractor 8 | npm install -g protractor 9 | */ 10 | 11 | "use strict"; 12 | 13 | var wd = require('wd'), 14 | wdBridge = require('wd-bridge')(require('protractor'), wd), 15 | _ = require('underscore'); 16 | 17 | // An example configuration file. 18 | var config = { 19 | seleniumAddress: 'http://localhost:4723/wd/hub', 20 | 21 | // Capabilities to be passed to the webdriver instance. 22 | capabilities: _({}).chain() 23 | .extend(require("../helpers/caps").ios81) 24 | .extend({'browserName': 'safari'}) 25 | .omit('app').value(), 26 | // Spec patterns are relative to the current working directly when 27 | // protractor is called. 28 | specs: ['example_spec.js'], 29 | 30 | // Options to be passed to Jasmine-node. 31 | jasmineNodeOpts: { 32 | showColors: true, 33 | defaultTimeoutInterval: 30000 34 | }, 35 | 36 | // configuring wd in onPrepare 37 | onPrepare: function () { 38 | wdBridge.initFromProtractor(config); 39 | } 40 | 41 | }; 42 | 43 | exports.config = config; 44 | -------------------------------------------------------------------------------- /sample-code/examples/node/selendroid-simple.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("./helpers/setup"); 4 | 5 | var wd = require("wd"), 6 | _ = require('underscore'), 7 | serverConfigs = require('./helpers/appium-servers'); 8 | 9 | describe("selendroid simple", function () { 10 | this.timeout(300000); 11 | var driver; 12 | var allPassed = true; 13 | 14 | before(function () { 15 | var serverConfig = process.env.npm_package_config_sauce ? 16 | serverConfigs.sauce : serverConfigs.local; 17 | driver = wd.promiseChainRemote(serverConfig); 18 | require("./helpers/logging").configure(driver); 19 | 20 | var desired = _.clone(require("./helpers/caps").selendroid16); 21 | desired.app = require("./helpers/apps").androidApiDemos; 22 | if (process.env.npm_package_config_sauce) { 23 | desired.name = 'selendroid - simple'; 24 | desired.tags = ['sample']; 25 | } 26 | return driver 27 | .init(desired) 28 | .setImplicitWaitTimeout(3000); 29 | }); 30 | 31 | after(function () { 32 | return driver 33 | .quit() 34 | .finally(function () { 35 | if (process.env.npm_package_config_sauce) { 36 | return driver.sauceJobStatus(allPassed); 37 | } 38 | }); 39 | }); 40 | 41 | afterEach(function () { 42 | allPassed = allPassed && this.currentTest.state === 'passed'; 43 | }); 44 | 45 | it("should find elements", function () { 46 | return driver 47 | .waitForElementByName('Animation') 48 | .text().should.become('Animation') 49 | .elementByClassName('android.widget.TextView') 50 | .text().should.eventually.match(/Accessibility|API Demos/) 51 | .elementByName('App').click() 52 | .waitForElementByXPath('//TextView[@name=\'Action Bar\']') 53 | .elementsByClassName('android.widget.TextView') 54 | .should.eventually.have.length.above(20) 55 | .back() 56 | .sleep(3000) 57 | .waitForElementByName('Animation', 5000, 500) 58 | .text().should.become('Animation'); 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /sample-code/examples/perl/ios_simple.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More; 6 | use Cwd qw/getcwd abs_path/; 7 | use Selenium::Remote::Driver 0.20; 8 | 9 | my $app = getcwd() . '/../../apps/TestApp/build/release-iphonesimulator/TestApp-iphonesimulator.app'; 10 | my $caps = { 11 | app => abs_path($app), 12 | browserName => "", 13 | deviceName => "iPhone 6", 14 | platformName => "iOS", 15 | platformVersion => "8.1" 16 | }; 17 | 18 | my $driver = Selenium::Remote::Driver->new_from_caps( 19 | remote_server_addr => "127.0.0.1", 20 | port => 4723, 21 | desired_capabilities => $caps 22 | ); 23 | 24 | ok(defined $driver, 'Instantiated an iOS driver!'); 25 | 26 | my $expected_sum; 27 | foreach (qw/1 2/) { 28 | my $text_field = $driver->find_element('TextField' . $_, 'name'); 29 | my $rand = int(rand(20)); 30 | $expected_sum += $rand; 31 | $text_field->send_keys($rand); 32 | } 33 | 34 | my $compute_button = $driver->find_element('ComputeSumButton', 'name'); 35 | $compute_button->click; 36 | 37 | my $sum_element = $driver->find_element($expected_sum, 'name'); 38 | ok($sum_element->get_text eq $expected_sum, 'We can do addition!'); 39 | 40 | $driver->quit; 41 | 42 | done_testing; 43 | -------------------------------------------------------------------------------- /sample-code/examples/php/SauceTest.php: -------------------------------------------------------------------------------- 1 | '', 16 | 'seleniumServerRequestsTimeout' => 240, 17 | 'desiredCapabilities' => array( 18 | 'platform' => 'Mac 10.8', 19 | 'device' => 'iPhone Simulator', 20 | 'app' => APP_URL, 21 | 'version' => '6.1', 22 | ) 23 | ) 24 | ); 25 | 26 | public function elemsByTag($tag) 27 | { 28 | return $this->elements($this->using('tag name')->value($tag)); 29 | } 30 | 31 | protected function populate() 32 | { 33 | $elems = $this->elemsByTag('textField'); 34 | foreach ($elems as $elem) { 35 | $randNum = rand(0, 10); 36 | $elem->value($randNum); 37 | $this->numValues[] = $randNum; 38 | } 39 | } 40 | 41 | public function testUiComputation() 42 | { 43 | $this->populate(); 44 | $buttons = $this->elemsByTag('button'); 45 | $buttons[0]->click(); 46 | $texts = $this->elemsByTag('staticText'); 47 | $this->assertEquals(array_sum($this->numValues), (int)($texts[0]->text())); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample-code/examples/php/SimpleTest.php: -------------------------------------------------------------------------------- 1 | true, 20 | 'port' => 4723, 21 | 'browserName' => '', 22 | 'desiredCapabilities' => array( 23 | 'deviceName' => '=iPhone 5s', 24 | 'version' => '8.4 Simulator', 25 | 'platformName' => 'iOS', 26 | 'app' => APP_PATH 27 | ) 28 | ) 29 | ); 30 | 31 | public function elemsByTag($tag) 32 | { 33 | return $this->elements($this->using('class name')->value($tag)); 34 | } 35 | 36 | protected function populate() 37 | { 38 | $elems = $this->elemsByTag('UIATextField'); 39 | foreach ($elems as $elem) { 40 | $randNum = rand(0, 10); 41 | $elem->value($randNum); 42 | $this->numValues[] = $randNum; 43 | } 44 | } 45 | 46 | public function testUiComputation() 47 | { 48 | $this->populate(); 49 | $buttons = $this->elemsByTag('UIAButton'); 50 | $buttons[0]->click(); 51 | $texts = $this->elemsByTag('UIAStaticText'); 52 | $this->assertEquals(array_sum($this->numValues), (int)($texts[0]->text())); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample-code/examples/php/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "sauce/sausage": ">=0.6.0" 4 | } 5 | } -------------------------------------------------------------------------------- /sample-code/examples/python/.cache/v/cache/lastfailed: -------------------------------------------------------------------------------- 1 | { 2 | "ios_simple.py::SimpleIOSTests::test_scroll": true, 3 | "ios_simple.py::SimpleIOSTests::test_ui_computation": true 4 | } -------------------------------------------------------------------------------- /sample-code/examples/python/README.md: -------------------------------------------------------------------------------- 1 | Python samples 2 | ============== 3 | 4 | These are simple samples of how to use Python to run Appium tests. It is suggested that you use a test runner such as pytest or nose. 5 | 6 | Sauce Labs examples require at least version 0.12 of the Appium Python Client, which includes the `appium.SauceTestCase` base class. 7 | 8 | Install appium client library: 9 | 10 | ```shell 11 | pip install Appium-Python-Client 12 | pip install pytest 13 | ``` 14 | 15 | Usage: 16 | 17 | ```shell 18 | py.test ios_simple.py 19 | py.test -n2 --boxed ios_simple.py 20 | ``` 21 | -------------------------------------------------------------------------------- /sample-code/examples/python/android_contacts.py: -------------------------------------------------------------------------------- 1 | import os 2 | import unittest 3 | from appium import webdriver 4 | from time import sleep 5 | 6 | # Returns abs path relative to this file and not cwd 7 | PATH = lambda p: os.path.abspath( 8 | os.path.join(os.path.dirname(__file__), p) 9 | ) 10 | 11 | class ContactsAndroidTests(unittest.TestCase): 12 | def setUp(self): 13 | desired_caps = {} 14 | desired_caps['platformName'] = 'Android' 15 | desired_caps['platformVersion'] = '4.2' 16 | desired_caps['deviceName'] = 'Android Emulator' 17 | desired_caps['app'] = PATH( 18 | '../../../sample-code/apps/ContactManager/ContactManager.apk' 19 | ) 20 | desired_caps['appPackage'] = 'com.example.android.contactmanager' 21 | desired_caps['appActivity'] = '.ContactManager' 22 | 23 | self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 24 | 25 | def tearDown(self): 26 | self.driver.quit() 27 | 28 | def test_add_contacts(self): 29 | el = self.driver.find_element_by_accessibility_id("Add Contact") 30 | el.click() 31 | 32 | textfields = self.driver.find_elements_by_class_name("android.widget.EditText") 33 | textfields[0].send_keys("Appium User") 34 | textfields[2].send_keys("someone@appium.io") 35 | 36 | self.assertEqual('Appium User', textfields[0].text) 37 | self.assertEqual('someone@appium.io', textfields[2].text) 38 | 39 | self.driver.find_element_by_accessibility_id("Save").click() 40 | 41 | # for some reason "save" breaks things 42 | alert = self.driver.switch_to_alert() 43 | 44 | # no way to handle alerts in Android 45 | self.driver.find_element_by_android_uiautomator('new UiSelector().clickable(true)').click() 46 | 47 | self.driver.press_keycode(3) 48 | 49 | 50 | 51 | if __name__ == '__main__': 52 | suite = unittest.TestLoader().loadTestsFromTestCase(ContactsAndroidTests) 53 | unittest.TextTestRunner(verbosity=2).run(suite) 54 | -------------------------------------------------------------------------------- /sample-code/examples/python/android_sauce.py: -------------------------------------------------------------------------------- 1 | from appium import webdriver 2 | from appium import SauceTestCase, on_platforms 3 | 4 | 5 | app = "http://appium.s3.amazonaws.com/NotesList.apk" 6 | platforms = [{ 7 | "platformName": "Android", 8 | "platformVersion": "4.4", 9 | "deviceName": "Android Emulator", 10 | "appPackage": "com.example.android.notepad", 11 | "appActivity": ".NotesList", 12 | "app": app, 13 | "appiumVersion": "1.3.4" 14 | }] 15 | 16 | @on_platforms(platforms) 17 | class SimpleAndroidSauceTests(SauceTestCase): 18 | 19 | def test_create_note(self): 20 | el = self.driver.find_element_by_accessibility_id("New note") 21 | el.click() 22 | 23 | el = self.driver.find_element_by_class_name("android.widget.EditText") 24 | el.send_keys("This is a new note!") 25 | 26 | el = self.driver.find_element_by_accessibility_id("Save") 27 | el.click() 28 | 29 | els = self.driver.find_elements_by_class_name("android.widget.TextView") 30 | self.assertEqual(els[2].text, "This is a new note!") 31 | 32 | els[2].click() 33 | -------------------------------------------------------------------------------- /sample-code/examples/python/android_simple.py: -------------------------------------------------------------------------------- 1 | import os 2 | from time import sleep 3 | 4 | import unittest 5 | 6 | from appium import webdriver 7 | 8 | # Returns abs path relative to this file and not cwd 9 | PATH = lambda p: os.path.abspath( 10 | os.path.join(os.path.dirname(__file__), p) 11 | ) 12 | 13 | class SimpleAndroidTests(unittest.TestCase): 14 | def setUp(self): 15 | desired_caps = {} 16 | desired_caps['platformName'] = 'Android' 17 | desired_caps['platformVersion'] = '4.2' 18 | desired_caps['deviceName'] = 'Android Emulator' 19 | desired_caps['app'] = PATH( 20 | '../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk' 21 | ) 22 | 23 | self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 24 | 25 | def tearDown(self): 26 | # end the session 27 | self.driver.quit() 28 | 29 | def test_find_elements(self): 30 | el = self.driver.find_element_by_accessibility_id('Graphics') 31 | el.click() 32 | el = self.driver.find_element_by_accessibility_id('Arcs') 33 | self.assertIsNotNone(el) 34 | 35 | self.driver.back() 36 | 37 | el = self.driver.find_element_by_accessibility_id("App") 38 | self.assertIsNotNone(el) 39 | 40 | els = self.driver.find_elements_by_android_uiautomator("new UiSelector().clickable(true)") 41 | self.assertGreaterEqual(12, len(els)) 42 | 43 | self.driver.find_element_by_android_uiautomator('text("API Demos")') 44 | 45 | 46 | def test_simple_actions(self): 47 | el = self.driver.find_element_by_accessibility_id('Graphics') 48 | el.click() 49 | 50 | el = self.driver.find_element_by_accessibility_id('Arcs') 51 | el.click() 52 | 53 | self.driver.find_element_by_android_uiautomator('new UiSelector().text("Graphics/Arcs")') 54 | 55 | 56 | if __name__ == '__main__': 57 | suite = unittest.TestLoader().loadTestsFromTestCase(SimpleAndroidTests) 58 | unittest.TextTestRunner(verbosity=2).run(suite) 59 | -------------------------------------------------------------------------------- /sample-code/examples/python/android_webview.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import unittest 4 | from time import sleep 5 | 6 | from appium import webdriver 7 | 8 | PLATFORM_VERSION = '4.4' 9 | 10 | 11 | class AndroidWebViewTests(unittest.TestCase): 12 | 13 | def setUp(self): 14 | app = os.path.abspath( 15 | os.path.join(os.path.dirname(__file__), 16 | '../../apps/selendroid-test-app.apk')) 17 | desired_caps = { 18 | 'app': app, 19 | 'appPackage': 'io.selendroid.testapp', 20 | 'appActivity': '.HomeScreenActivity', 21 | 'platformName': 'Android', 22 | 'platformVersion': PLATFORM_VERSION, 23 | 'deviceName': 'Android Emulator' 24 | } 25 | 26 | if (PLATFORM_VERSION != '4.4'): 27 | desired_caps['automationName'] = 'selendroid' 28 | 29 | self.driver = webdriver.Remote('http://localhost:4723/wd/hub', 30 | desired_caps) 31 | 32 | def test_webview(self): 33 | if (PLATFORM_VERSION == '4.4'): 34 | button = self.driver.find_element_by_accessibility_id('buttonStartWebviewCD') 35 | else: 36 | button = self.driver.find_element_by_name('buttonStartWebviewCD') 37 | button.click() 38 | 39 | self.driver.switch_to.context('WEBVIEW_0') 40 | 41 | input_field = self.driver.find_element_by_id('name_input') 42 | sleep(1) 43 | input_field.clear() 44 | input_field.send_keys('Appium User') 45 | input_field.submit() 46 | 47 | # test that everything is a-ok 48 | source = self.driver.page_source 49 | self.assertNotEqual(-1, source.find('This is my way of saying hello')) 50 | self.assertNotEqual(-1, source.find('"Appium User"')) 51 | 52 | def tearDown(self): 53 | self.driver.quit() 54 | 55 | 56 | if __name__ == '__main__': 57 | suite = unittest.TestLoader().loadTestsFromTestCase(AndroidWebViewTests) 58 | unittest.TextTestRunner(verbosity=2).run(suite) 59 | -------------------------------------------------------------------------------- /sample-code/examples/python/ios_sauce.py: -------------------------------------------------------------------------------- 1 | """An example of Appium running on Sauce. 2 | 3 | This test assumes SAUCE_USERNAME and SAUCE_ACCESS_KEY are environment variables 4 | set to your Sauce Labs username and access key.""" 5 | 6 | from random import randint 7 | from appium import webdriver 8 | from appium import SauceTestCase, on_platforms 9 | 10 | 11 | platforms = [{ 12 | 'platformName': 'iOS', 13 | 'platformVersion': '7.1', 14 | 'deviceName': 'iPhone Simulator', 15 | 'app': 'http://appium.s3.amazonaws.com/TestApp6.0.app.zip', 16 | 'appiumVersion': '1.3.4' 17 | }] 18 | 19 | @on_platforms(platforms) 20 | class SimpleIOSSauceTests(SauceTestCase): 21 | 22 | def _populate(self): 23 | # populate text fields with two random numbers 24 | els = self.driver.find_elements_by_class_name('UIATextField') 25 | 26 | self._sum = 0 27 | for i in range(2): 28 | rnd = randint(0, 10) 29 | els[i].send_keys(rnd) 30 | self._sum += rnd 31 | 32 | def test_ui_computation(self): 33 | # populate text fields with values 34 | self._populate() 35 | 36 | # trigger computation by using the button 37 | self.driver.find_element_by_accessibility_id('ComputeSumButton').click() 38 | 39 | # is sum equal ? 40 | sum = self.driver.find_elements_by_class_name("UIAStaticText")[0].text 41 | self.assertEqual(int(sum), self._sum) 42 | -------------------------------------------------------------------------------- /sample-code/examples/python/ios_sauce_webview.py: -------------------------------------------------------------------------------- 1 | """An example of Appium running on Sauce, with a webview. 2 | 3 | This test assumes SAUCE_USERNAME and SAUCE_ACCESS_KEY are environment variables 4 | set to your Sauce Labs username and access key.""" 5 | 6 | from random import randint 7 | from appium import webdriver 8 | from appium import SauceTestCase, on_platforms 9 | from time import sleep 10 | 11 | from selenium.webdriver.common.keys import Keys 12 | 13 | app = 'http://appium.s3.amazonaws.com/WebViewApp6.0.app.zip' 14 | platforms = [{ 15 | 'platformName': 'iOS', 16 | 'platformVersion': '7.1', 17 | 'deviceName': 'iPhone Simulator', 18 | 'appiumVersion': '1.3.4', 19 | 'app': app 20 | }] 21 | 22 | @on_platforms(platforms) 23 | class WebViewIOSSauceTests(SauceTestCase): 24 | 25 | def test_get_url(self): 26 | url_el = self.driver.find_element_by_xpath('//UIAApplication[1]/UIAWindow[1]/UIATextField[1]') 27 | url_el.send_keys('http://www.google.com') 28 | 29 | go_el = self.driver.find_element_by_accessibility_id('Go') 30 | go_el.click() 31 | 32 | self.driver.switch_to.context('WEBVIEW') 33 | 34 | search = self.driver.find_element_by_name('q') 35 | search.send_keys('sauce labs') 36 | search.send_keys(Keys.RETURN) 37 | 38 | # allow the page to load 39 | sleep(1) 40 | 41 | self.assertEquals('sauce labs', self.driver.title[:10]) 42 | 43 | -------------------------------------------------------------------------------- /sample-code/examples/python/ios_webview.py: -------------------------------------------------------------------------------- 1 | """ 2 | Simple iOS WebView tests. 3 | """ 4 | import unittest 5 | import os 6 | from random import randint 7 | from appium import webdriver 8 | from time import sleep 9 | 10 | from selenium.webdriver.common.keys import Keys 11 | 12 | class WebViewIOSTests(unittest.TestCase): 13 | 14 | def setUp(self): 15 | # set up appium 16 | app = os.path.join(os.path.dirname(__file__), 17 | '../../apps/WebViewApp/build/release-iphonesimulator', 18 | 'WebViewApp.app') 19 | app = os.path.abspath(app) 20 | self.driver = webdriver.Remote( 21 | command_executor='http://127.0.0.1:4723/wd/hub', 22 | desired_capabilities={ 23 | 'app': app, 24 | 'deviceName': 'iPhone Simulator', 25 | 'platformName': 'iOS', 26 | 'platformVersion': '7.1' 27 | }) 28 | 29 | def tearDown(self): 30 | self.driver.quit() 31 | 32 | def test_get_url(self): 33 | url_el = self.driver.find_element_by_xpath('//UIAApplication[1]/UIAWindow[1]/UIATextField[1]') 34 | url_el.send_keys('http://www.google.com') 35 | 36 | go_el = self.driver.find_element_by_accessibility_id('Go') 37 | go_el.click() 38 | sleep(1) 39 | 40 | self.driver.switch_to.context('WEBVIEW') 41 | 42 | search = self.driver.find_element_by_name('q') 43 | search.send_keys('sauce labs') 44 | search.send_keys(Keys.RETURN) 45 | 46 | # allow the page to load 47 | sleep(1) 48 | 49 | self.assertEquals('sauce labs - Google Search', self.driver.title) 50 | 51 | 52 | if __name__ == '__main__': 53 | suite = unittest.TestLoader().loadTestsFromTestCase(WebViewIOSTests) 54 | unittest.TextTestRunner(verbosity=2).run(suite) 55 | -------------------------------------------------------------------------------- /sample-code/examples/python/pytest/README.md: -------------------------------------------------------------------------------- 1 | Python Pytest samples 2 | ============== 3 | 4 | Tested on Python 3.5 5 | pip install -r requirements.txt 6 | 7 | # Run Syntax: 8 | py.test test_android_simple.py -v 9 | 10 | Output will be in the format: 11 | 12 | test_android_simple.py::TestSimpleAndroid::test_find_elements PASSED 13 | test_android_simple.py::TestSimpleAndroid::test_simple_actions PASSED 14 | 15 | For more documentation please refer to http://doc.pytest.org/en/latest/ -------------------------------------------------------------------------------- /sample-code/examples/python/pytest/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import datetime 3 | import os 4 | from helpers import ensure_dir 5 | 6 | 7 | def pytest_configure(config): 8 | if not hasattr(config, "slaveinput"): 9 | current_day = (datetime.datetime.now().strftime("%Y_%m_%d_%H_%S")) 10 | ensure_dir("results") 11 | ensure_dir(os.path.join("results", current_day)) 12 | result_dir = os.path.join(os.path.dirname(__file__), "results", current_day) 13 | ensure_dir(result_dir) 14 | result_dir_test_run = result_dir 15 | ensure_dir(os.path.join(result_dir_test_run, "screenshots")) 16 | ensure_dir(os.path.join(result_dir_test_run, "logcat")) 17 | config.screen_shot_dir = os.path.join(result_dir_test_run, "screenshots") 18 | config.logcat_dir = os.path.join(result_dir_test_run, "logcat") 19 | 20 | 21 | class DeviceLogger: 22 | def __init__(self, logcat_dir, screenshot_dir): 23 | self.screenshot_dir = screenshot_dir 24 | self.logcat_dir = logcat_dir 25 | 26 | 27 | @pytest.fixture(scope="session") 28 | def device_logger(request): 29 | logcat_dir = request.config.logcat_dir 30 | screenshot_dir = request.config.screen_shot_dir 31 | return DeviceLogger(logcat_dir, screenshot_dir) 32 | -------------------------------------------------------------------------------- /sample-code/examples/python/pytest/helpers.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def ensure_dir(directory): 5 | if not os.path.exists(directory): 6 | os.makedirs(directory) 7 | 8 | 9 | def take_screenhot_and_logcat(driver, device_logger, calling_request): 10 | logcat_dir = device_logger.logcat_dir 11 | screenshot_dir = device_logger.screenshot_dir 12 | driver.save_screenshot(os.path.join(screenshot_dir, calling_request + ".png")) 13 | logcat_file = open(os.path.join(logcat_dir, calling_request + "_logcat.log"), 'wb') 14 | logcat_data = driver.get_log('logcat') 15 | for data in logcat_data: 16 | data_string = str(data['timestamp']) + ": " + str(data['message']) 17 | logcat_file.write((data_string + '\n').encode("UTF-8")) 18 | logcat_file.close() 19 | -------------------------------------------------------------------------------- /sample-code/examples/python/pytest/requirements.txt: -------------------------------------------------------------------------------- 1 | Appium-Python-Client 2 | pytest -------------------------------------------------------------------------------- /sample-code/examples/python/pytest/test_android_contacts.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | 4 | from appium import webdriver 5 | 6 | # Returns abs path relative to this file and not cwd 7 | PATH = lambda p: os.path.abspath( 8 | os.path.join(os.path.dirname(__file__), p) 9 | ) 10 | APPIUM_LOCAL_HOST_URL = 'http://localhost:4723/wd/hub' 11 | PLATFORM_VERSION = '6.0' 12 | 13 | 14 | class TestWebViewAndroid(): 15 | @pytest.fixture(scope="function") 16 | def driver(self, request): 17 | desired_caps = { 18 | 'appPackage': 'com.example.android.contactmanager', 19 | 'appActivity': '.ContactManager', 20 | 'platformName': 'Android', 21 | 'platformVersion': PLATFORM_VERSION, 22 | 'deviceName': 'Android Emulator', 23 | 'app': PATH('../../../../sample-code/apps/ContactManager/ContactManager.apk') 24 | } 25 | driver = webdriver.Remote(APPIUM_LOCAL_HOST_URL, desired_caps) 26 | 27 | def fin(): 28 | driver.quit() 29 | 30 | request.addfinalizer(fin) 31 | return driver # provide the fixture value 32 | 33 | def test_add_contacts(self, driver): 34 | el = driver.find_element_by_accessibility_id("Add Contact") 35 | el.click() 36 | 37 | textfields = driver.find_elements_by_class_name("android.widget.EditText") 38 | textfields[0].send_keys("Appium User") 39 | textfields[2].send_keys("someone@appium.io") 40 | 41 | assert 'Appium User' == textfields[0].text 42 | assert 'someone@appium.io' == textfields[2].text 43 | 44 | driver.find_element_by_accessibility_id("Save").click() 45 | 46 | # for some reason "save" breaks things 47 | alert = driver.switch_to_alert() 48 | 49 | # no way to handle alerts in Android 50 | driver.find_element_by_android_uiautomator('new UiSelector().clickable(true)').click() 51 | 52 | driver.press_keycode(3) -------------------------------------------------------------------------------- /sample-code/examples/python/pytest/test_android_simple_with_logs.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | 4 | from appium import webdriver 5 | from helpers import take_screenhot_and_logcat 6 | 7 | # Returns abs path relative to this file and not cwd 8 | PATH = lambda p: os.path.abspath( 9 | os.path.join(os.path.dirname(__file__), p) 10 | ) 11 | APPIUM_LOCAL_HOST_URL = 'http://localhost:4723/wd/hub' 12 | 13 | 14 | class TestSimpleAndroid(): 15 | @pytest.fixture(scope="function") 16 | def driver(self, request, device_logger): 17 | desired_caps = { 18 | 'platformName': 'Android', 19 | 'platformVersion': '6.0', 20 | 'deviceName': 'Android Emulator', 21 | 'app': PATH('../../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk') 22 | } 23 | calling_request = request._pyfuncitem.name 24 | driver = webdriver.Remote(APPIUM_LOCAL_HOST_URL, desired_caps) 25 | 26 | def fin(): 27 | take_screenhot_and_logcat(driver, device_logger, calling_request) 28 | driver.quit() 29 | 30 | request.addfinalizer(fin) 31 | return driver # provide the fixture value 32 | 33 | def test_find_elements(self, driver): 34 | el = driver.find_element_by_accessibility_id('Graphics') 35 | el.click() 36 | el = driver.find_element_by_accessibility_id('Arcs') 37 | assert el is not None 38 | driver.back() 39 | 40 | el = driver.find_element_by_accessibility_id("App") 41 | assert el is not None 42 | 43 | els = driver.find_elements_by_android_uiautomator("new UiSelector().clickable(true)") 44 | assert len(els) >= 12 45 | driver.find_element_by_android_uiautomator('text("API Demos")') 46 | 47 | def test_simple_actions(self, driver): 48 | el = driver.find_element_by_accessibility_id('Graphics') 49 | el.click() 50 | 51 | el = driver.find_element_by_accessibility_id('Arcs') 52 | el.click() 53 | 54 | driver.find_element_by_android_uiautomator('new UiSelector().text("Graphics/Arcs")') 55 | -------------------------------------------------------------------------------- /sample-code/examples/python/selendroid_simple.py: -------------------------------------------------------------------------------- 1 | import os 2 | from time import sleep 3 | import unittest 4 | 5 | from appium import webdriver 6 | 7 | # Returns abs path relative to this file and not cwd 8 | PATH = lambda p: os.path.abspath( 9 | os.path.join(os.path.dirname(__file__), p) 10 | ) 11 | 12 | # think times can be useful e.g. when testing with an emulator 13 | THINK_TIME = 5. 14 | 15 | class SimpleSalendroidTests(unittest.TestCase): 16 | def setUp(self): 17 | desired_caps = {} 18 | desired_caps['platformName'] = 'Android' 19 | desired_caps['platformVersion'] = '4.1' 20 | desired_caps['deviceName'] = 'Android Emulator' 21 | desired_caps['automationName'] = "selendroid" 22 | desired_caps['app'] = PATH( 23 | '../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk' 24 | ) 25 | 26 | self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) 27 | 28 | def tearDown(self): 29 | # end the session 30 | self.driver.quit() 31 | 32 | def test_selendroid(self): 33 | el = self.driver.find_element_by_name("Animation") 34 | # assert el.text == "Animation" 35 | self.assertEqual('Animation', el.text) 36 | 37 | el = self.driver.find_element_by_class_name("android.widget.TextView") 38 | # assert el.text == "Accessibility" 39 | self.assertEqual('Accessibility', el.text) 40 | 41 | el = self.driver.find_element_by_name("App") 42 | el.click() 43 | sleep(THINK_TIME) 44 | 45 | els = self.driver.find_elements_by_class_name("android.widget.TextView") 46 | # Selendroid gets all the elements, not just the visible ones 47 | self.assertLessEqual(30, len(els)) 48 | 49 | self.driver.find_element_by_name('Action Bar') 50 | 51 | self.driver.back() 52 | sleep(THINK_TIME) 53 | 54 | el = self.driver.find_element_by_name("Animation") 55 | self.assertEqual('Animation', el.text) 56 | 57 | 58 | if __name__ == '__main__': 59 | suite = unittest.TestLoader().loadTestsFromTestCase(SimpleSalendroidTests) 60 | unittest.TextTestRunner(verbosity=2).run(suite) 61 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://www.rubygems.org' 2 | 3 | gem 'appium_lib', '~> 9.7.4' 4 | gem 'rest-client', '~> 2.0.2' 5 | gem 'rspec', '~> 3.6.0' 6 | gem 'cucumber', '~> 2.4.0' 7 | gem 'rspec-expectations', '~> 3.6.0' 8 | gem 'spec', '~> 5.3.4' 9 | gem 'sauce_whisk', '~> 0.0.13' 10 | gem 'test-unit', '~> 2.5.5' # required for bundle exec ruby xunit_android.rb 11 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/UICatalog.app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appium-boneyard/sample-code/f3ed882ec9e6318c4150e515e162b579fd4752b1/sample-code/examples/ruby/UICatalog.app.zip -------------------------------------------------------------------------------- /sample-code/examples/ruby/android_on_sauce.rb: -------------------------------------------------------------------------------- 1 | # This example automates a test of the Android example notepad app. 2 | # 3 | # To run this example, make sure you've run: 4 | # $ bundle install 5 | # 6 | # And set the environment variables: 7 | # SAUCE_USERNAME = your-sauce-username 8 | # SAUCE_ACCESS_KEY = your-sauce-key 9 | # 10 | # Then just: 11 | # bundle exec ruby android_on_sauce.rb 12 | # 13 | # Of note compared to the iOS example, here we're giving the package and 14 | # activity, no OS and an empty browserName 15 | # 16 | # Of note compared to the non-sauce examples, you need to host your app 17 | # somewhere Sauce Labs' cloud can fetch it for your test. 18 | 19 | require 'rubygems' 20 | require 'spec' 21 | require 'appium_lib' 22 | require 'sauce_whisk' 23 | 24 | describe 'Notepad' do 25 | def desired_caps 26 | { 27 | caps: { 28 | :'appium-version' => '1.3.4', 29 | platformName: 'Android', 30 | platformVersion: '4.3', 31 | deviceName: 'Android Emulator', 32 | app: 'http://appium.s3.amazonaws.com/NotesList.apk', 33 | name: 'Ruby Appium Android example' 34 | }, 35 | appium_lib: { 36 | wait: 60 37 | } 38 | } 39 | end 40 | 41 | before do 42 | Appium::Driver.new(desired_caps).start_driver 43 | end 44 | 45 | after do 46 | driver_quit 47 | end 48 | 49 | it 'can create and save new notes' do 50 | find('New note').click 51 | first_textfield.type 'This is a new note, from Ruby' 52 | 53 | find('Save').click 54 | 55 | note_count = ids('android:id/text1').length 56 | note_count.must_equal 1 57 | texts.last.text.must_equal 'This is a new note, from Ruby' 58 | end 59 | end 60 | 61 | passed = Minitest.run_specs({ :trace => [__FILE__] }).first 62 | 63 | # Because WebDriver doesn't have the concept of test failure, use the Sauce 64 | # Labs REST API to record job success or failure 65 | user = ENV['SAUCE_USERNAME'] 66 | key = ENV['SAUCE_ACCESS_KEY'] 67 | if user && !user.empty? && key && !key.empty? 68 | passed = passed.failures == 0 && passed.errors == 0 69 | SauceWhisk::Jobs.change_status $driver.driver.session_id, passed 70 | end 71 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/arc_android/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "android" 3 | deviceName = "Nexus 7" 4 | appPackage = "com.android.settings" 5 | appActivity = ".Settings" 6 | 7 | [appium_lib] 8 | sauce_username = "" 9 | sauce_access_key = "" 10 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/arc_ios_calc/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "ios" 3 | deviceName = "iPhone 6" 4 | platformVersion = "8.1" 5 | app = "../../../apps/TestApp/build/release-iphonesimulator/TestApp-iphonesimulator.app" 6 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/arc_ios_catalog/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "ios" 3 | deviceName = "iPhone 6" 4 | platformVersion = "8.1" 5 | app = "../UICatalog.app.zip" -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_android/features/settings.feature: -------------------------------------------------------------------------------- 1 | # WHAT ARE FEATURES? 2 | # ------------------ 3 | # Features describe what something should allow a user to accomplish. They're 4 | # high-level things, like you'd put in your manual or marketing copy. Each 5 | # line describes a "step" which should pass for the feature to be 6 | # implemented. They're usually written with non-developers in mind, so should 7 | # be nice, plain and English like. 8 | # 9 | # WHAT ARE THE OTHER FILES? 10 | # ------------------------- 11 | # The 'steps' are implemented in a step definition file, which is created by 12 | # developers. Ideally, once steps have been created, anyone can write a 13 | # feature by using step definitions to do so. The step definitions for this 14 | # example can be found in the cucumber/features/step_definitions/steps.rb file. 15 | # 16 | # RUNNING THE TEST: 17 | # ----------------- 18 | # Assuming you've (successfully) run the examples in the simple_test.rb file, 19 | # all you should need for Cucumber is: 20 | # 21 | # 1. Start Appium in a terminal window 22 | # 2. From another terminal window, open the cucumber example directory at 23 | # appium/sample-code/examples/ruby/cucumber_android/ 24 | # 3. type 'cucumber' and hit enter 25 | # 4. If you see '1 scenario (1 passed)' and some other stuff, SUCCESS! The 26 | # test passed. If you didn't, BOOOO, that's not right. Make sure you've 27 | # followed all the instructions for setup in the simple_test.rb file and 28 | # give it another shot. If that doesn't work, log a support ticket on 29 | # Github at https://github.com/appium/appium/issues/new 30 | # 31 | # ADDITIONAL INFORMATION: 32 | # ----------------------- 33 | # 34 | # For more information about features, check out the documentation at: 35 | # https://github.com/cucumber/cucumber/wiki/Feature-Introduction 36 | 37 | 38 | Feature: Version check 39 | Settings must display the Android version 40 | 41 | Scenario: Settings 42 | Given I click about phone 43 | Then the Android version is a number 44 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_android/features/step_definitions/steps.rb: -------------------------------------------------------------------------------- 1 | # These are the 'step definitions' which Cucumber uses to implement features. 2 | # 3 | # Each step starts with a regular expression matching the step you write in 4 | # your feature description. Any variables are parsed out and passed to the 5 | # step block. 6 | # 7 | # The instructions in the step are then executed with those variables. 8 | # 9 | # In this example, we're using rspec's assertions to test that things are happening, 10 | # but you can use any ruby code you want in the steps. 11 | # 12 | # The '$driver' object is the appium_lib driver, set up in the cucumber/support/env.rb 13 | # file, which is a convenient place to put it as we're likely to use it often. 14 | # This is a different use to most of the examples; Cucumber steps are instances 15 | # of `Object`, and extending Object with Appium methods (through 16 | # `promote_appium_methods`) is a bad idea. 17 | # 18 | # For more on step definitions, check out the documentation at 19 | # https://github.com/cucumber/cucumber/wiki/Step-Definitions 20 | # 21 | # For more on rspec assertions, check out 22 | # https://www.relishapp.com/rspec/rspec-expectations/docs 23 | 24 | Given /^I click about phone$/ do 25 | scroll_to('About phone').click 26 | end 27 | 28 | Given /^the Android version is a number$/ do 29 | android_version = 'Android version' 30 | scroll_to android_version 31 | 32 | view = 'android.widget.TextView' 33 | version = xpath(%Q(//#{view}[preceding-sibling::#{view}[@text="#{android_version}"]])).text 34 | valid = !version.match(/\d/).nil? 35 | 36 | expect(valid).to eq(true) 37 | end -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_android/features/support/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "Android" 3 | deviceName = "Nexus 7" 4 | appActivity = ".Settings" 5 | appPackage = "com.android.settings" 6 | 7 | [appium_lib] 8 | sauce_username = false 9 | sauce_access_key = false 10 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_android/features/support/env.rb: -------------------------------------------------------------------------------- 1 | # This file provides setup and common functionality across all features. It's 2 | # included first before every test run, and the methods provided here can be 3 | # used in any of the step definitions used in a test. This is a great place to 4 | # put shared data like the location of your app, the capabilities you want to 5 | # test with, and the setup of selenium. 6 | 7 | require 'rspec/expectations' 8 | require 'appium_lib' 9 | require 'cucumber/ast' 10 | 11 | # Create a custom World class so we don't pollute `Object` with Appium methods 12 | class AppiumWorld 13 | end 14 | 15 | # Load the desired configuration from appium.txt, create a driver then 16 | # Add the methods to the world 17 | caps = Appium.load_appium_txt file: File.expand_path('./', __FILE__), verbose: true 18 | Appium::Driver.new(caps) 19 | Appium.promote_appium_methods AppiumWorld 20 | 21 | World do 22 | AppiumWorld.new 23 | end 24 | 25 | Before { $driver.start_driver } 26 | After { $driver.driver_quit } 27 | 28 | 29 | =begin 30 | # If you wanted one env.rb for both android and iOS, you could use logic similar to this: 31 | 32 | world_class = ENV['PLATFORM_NAME'] == 'iOS' ? IosWorld : AndroidWorld 33 | 34 | # each world class defines the `caps` method specific to that platform 35 | Appium::Driver.new world_class.caps 36 | Appium.promote_appium_methods world_class 37 | World { world_class.new } 38 | 39 | Before { $driver.start_driver } 40 | After { $driver.driver_quit } 41 | =end 42 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_ios/config/cucumber.yml: -------------------------------------------------------------------------------- 1 | # config/cucumber.yml 2 | ##YAML Template 3 | --- 4 | ipadsim: IDEVICENAME='ipad simulator' 5 | iphonesim: IDEVICENAME='iphone simulator' 6 | 7 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_ios/features/step_definitions/steps.rb: -------------------------------------------------------------------------------- 1 | # These are the 'step definitions' which Cucumber uses to implement features. 2 | # 3 | # Each step starts with a regular expression matching the step you write in 4 | # your feature description. Any variables are parsed out and passed to the 5 | # step block. 6 | # 7 | # The instructions in the step are then executed with those variables. 8 | # 9 | # In this example, we're using rspec's assertions to test that things are happening, 10 | # but you can use any ruby code you want in the steps. 11 | # 12 | # The '$driver' object is the appium_lib driver, set up in the cucumber/support/env.rb 13 | # file, which is a convenient place to put it as we're likely to use it often. 14 | # This is a different use to most of the examples; Cucumber steps are instances 15 | # of `Object`, and extending Object with Appium methods (through 16 | # `promote_appium_methods`) is a bad idea. 17 | # 18 | # For more on step definitions, check out the documentation at 19 | # https://github.com/cucumber/cucumber/wiki/Step-Definitions 20 | # 21 | # For more on rspec assertions, check out 22 | # https://www.relishapp.com/rspec/rspec-expectations/docs 23 | 24 | Given /^I have entered (\d+) into field (\d+) of the calculator$/ do |value, field| 25 | # Get a textfield by index 26 | textfield(field.to_i).type value 27 | end 28 | 29 | Given /^I have entered (\d+) into a field of the calculator showing (\w+)$/ do |value, field| 30 | # Get a textfield by string 31 | textfield(field).type value 32 | end 33 | 34 | And /^I press button (\d+)$/ do |button_index| 35 | # Find a button by index 36 | button(button_index.to_i).click 37 | end 38 | 39 | And /^I press a button labelled (\w+)$/ do |button_text| 40 | # Find a button by text 41 | button(button_text).click 42 | end 43 | 44 | Then /^the result should be displayed as (\d+)$/ do |expected| 45 | # You can get just the first of a class of elements 46 | expect(first_text.value).to eq expected 47 | end 48 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_ios/features/support/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "ios" 3 | deviceName = "iPhone 6" 4 | platformVersion = "10.2" 5 | app = "../../../apps/TestApp/build/release-iphonesimulator/TestApp-iphonesimulator.app" 6 | automationName = 'XCUITest' 7 | 8 | [appium_lib] 9 | sauce_username = false 10 | sauce_access_key = false 11 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_ios/features/support/env.rb: -------------------------------------------------------------------------------- 1 | # This file provides setup and common functionality across all features. It's 2 | # included first before every test run, and the methods provided here can be 3 | # used in any of the step definitions used in a test. This is a great place to 4 | # put shared data like the location of your app, the capabilities you want to 5 | # test with, and the setup of selenium. 6 | 7 | require 'rspec/expectations' 8 | require 'appium_lib' 9 | require 'cucumber/ast' 10 | 11 | # Create a custom World class so we don't pollute `Object` with Appium methods 12 | class AppiumWorld 13 | end 14 | 15 | # Load the desired configuration from appium.txt, create a driver then 16 | # Add the methods to the world 17 | if ENV['IDEVICENAME']=='ipad simulator' 18 | caps = Appium.load_appium_txt file: File.expand_path("./../ipadsim/appium.txt", __FILE__), verbose: true 19 | elsif ENV['IDEVICENAME']=='iphone simulator' 20 | caps = Appium.load_appium_txt file: File.expand_path("./../iphonesim/appium.txt", __FILE__), verbose: true 21 | else 22 | caps = Appium.load_appium_txt file: File.expand_path('../appium.txt', __FILE__), verbose: true 23 | end 24 | Appium::Driver.new(caps) 25 | Appium.promote_appium_methods AppiumWorld 26 | 27 | World do 28 | AppiumWorld.new 29 | end 30 | 31 | Before { $driver.start_driver } 32 | After { $driver.driver_quit } 33 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_ios/features/support/ipadsim/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "ios" 3 | deviceName = "iPad Air" 4 | platformVersion = "10.2" 5 | app = "../../../apps/TestApp/build/release-iphonesimulator/TestApp-iphonesimulator.app" 6 | automationName = 'XCUITest' 7 | 8 | [appium_lib] 9 | sauce_username = false 10 | sauce_access_key = false 11 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/cucumber_ios/features/support/iphonesim/appium.txt: -------------------------------------------------------------------------------- 1 | [caps] 2 | platformName = "ios" 3 | deviceName = "iPhone 6" 4 | platformVersion = "10.2" 5 | app = "../../../apps/TestApp/build/release-iphonesimulator/TestApp-iphonesimulator.app" 6 | automationName = 'XCUITest' 7 | 8 | [appium_lib] 9 | sauce_username = false 10 | sauce_access_key = false 11 | -------------------------------------------------------------------------------- /sample-code/examples/ruby/xunit_android.rb: -------------------------------------------------------------------------------- 1 | # this test show you how to use scroll and locate element by xpath 2 | # it open the system settings ui, and click the 'About phone' item to find android version 3 | # create by testerhome.com 4 | # author: seveniruby 5 | # 6 | # run using: 7 | # bundle exec ruby xunit_android.rb 8 | 9 | require 'rubygems' 10 | require 'test/unit' 11 | require 'appium_lib' 12 | 13 | class SettingsTest < Test::Unit::TestCase 14 | def setup 15 | caps = { caps: { platformName: 'Android', 16 | deviceName: 'Nexus 7', 17 | appActivity: '.Settings', 18 | appPackage: 'com.android.settings' }, 19 | appium_lib: { sauce_username: nil, 20 | sauce_access_key: nil } } 21 | driver = Appium::Driver.new(caps, true) 22 | Appium.promote_appium_methods self.class 23 | driver.start_driver.manage.timeouts.implicit_wait = 20 # seconds 24 | end 25 | 26 | def teardown 27 | driver_quit 28 | end 29 | 30 | def test_about_phone_version 31 | # This may be 'About phone' or 'About tablet' 32 | # search for About to work on both phones & tablets. 33 | scroll_to('About ').click 34 | android_version = 'Android version' 35 | scroll_to android_version 36 | 37 | view = 'android.widget.TextView' 38 | version = xpath(%Q(//#{view}[preceding-sibling::#{view}[@text="#{android_version}"]])).text 39 | valid = !version.match(/\d/).nil? 40 | 41 | puts "Version is: #{version}" 42 | assert_equal true, valid 43 | end 44 | end --------------------------------------------------------------------------------