appium essentials - wordpress.com · appium essentials credits about the author about the reviewers...
TRANSCRIPT
AppiumEssentials
TableofContents
AppiumEssentials
Credits
AbouttheAuthor
AbouttheReviewers
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
Preface
Whatthisbookcovers
Whatyouneedforthisbook
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Errata
Piracy
Questions
1.Appium–ImportantConceptualBackground
Appiumarchitecture
AppiumoniOS
AppiumonAndroid
TheSeleniumJSONwireprotocol
Appiumsession
Desiredcapabilities
Androidcapabilities
iOScapabilities
TheAppiumserveranditsclientlibraries
Summary
2.GettingStartedwithAppium
Appium–prosandcons
SystemrequirementsforAndroid/iOS
AndroidrequirementsonWindowsandMac
iOSrequirements
Installingdifferentsoftware
AppiuminstallationforAndroid
InstallingJDKonWindows
InstallingtheAndroidSDK
SettingthesystemvariablesforMac
AppiumforiOS
InstallingXcode
InstallingHomebrew
Nodeandnpm
AppiumfordifferentOSes
AppiumforWindows
AppiumforMac
DownloadingthenecessaryJARfiles
Creatingemulatorsandsimulators
AniOSsimulator
AnAndroidemulator
SettingupanEclipseJavaproject
Summary
3.TheAppiumGUI
TheAppiumserver
TheAppiumGUIforWindows
AndroidSettings
Application
LaunchDevice
Capabilities
Advanced
GeneralSettings
Server
Logging
Developersettings
About
Inspector
TheLaunch/Stopbutton
TheClearbutton
TheAppiumGUIforMac
AndroidSettings
iOSSettings
Application
DeviceSettings
Advanced
RobotSettings
Save/Openconfiguration
Appiumdoctor
Inspector
TheRecordingpanel
Summary
4.FindingElementswithDifferentLocators
FindingelementsforAndroidweb-basedappsusingtheChromeADBplugin
FindingelementsforiOSweb-basedappsusingSafari’sDevelopoption
FindingelementsbyID
Findingelementsbyname
FindingelementsbylinkText
FindingelementsbyXpath
FindingelementsbycssSelector
Findingelementsfornativeandhybridapps
FindingelementswithUIAutomatorviewer
FindingelementsbyID
Findingelementsbyname
FindingelementsbyclassName
FindingelementsbyAccessibilityId
FindingelementsbyAndroidUIAutomator
FindingelementswithAppiumInspector
FindingelementsbyXpath
Findingelementsbyname
FindingelementsbyIosUIAutomation
Summary
5.WorkingwithAppium
Importantinitialpoints
NecessarydesiredcapabilitiesforAndroidandinitiatingtheAndroiddriver
Desiredcapabilitiesfornativeandhybridapps
Desiredcapabilitiesforwebapps
NecessarydesiredcapabilitiesforiOSandinitiatingtheiOSdriver
Desiredcapabilitiesfornativeandhybridapps
Desiredcapabilitiesforwebapps
Automatingnativeapps
NativeAndroidapps
NativeiOSapps
Workingwithweb-apps
WebappsonAndroid
WebappsoniOS
Hybridapps’automation
Androidhybridapps
iOShybridapps
Summary
6.DrivingAppiumonRealDevices
Importantinitialpoints
DesiredcapabilitiesforAndroidandinitiatingtheAndroiddriver
Desiredcapabilitiesfornativeandhybridapps
Desiredcapabilitiesforwebapps
Installingprovisionalprofile,SafariLauncher,andios-webkit-debug-proxy
Provisionalprofile
SafariLauncherappandios-webkit-debug-proxy
DesiredcapabilitiesforiOSandinitiatingtheiOSdriver
DesiredcapabilitiesfornativeandhybridApps
Desiredcapabilitiesforwebapps
Automatingnativeapps
Androidnativeapps
iOSnativeapps
Workingwithwebapps
WebappsonAndroid
WebappsoniOS
Automatinghybridapps
Androidhybridapps
iOShybridapps
Summary
7.AdvancedUserInteractions
Exploringadvanceduserinteractions
Longpress
Scrollandswipe
Draganddrop
Pinchandzoom
Alerts
Spinners
Theswitchbutton
TheslideSeekBar
Capturingscreenshots
Capturingscreenshotsontestfailure
Summary
Index
AppiumEssentials
AppiumEssentialsCopyright©2015PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:April2015
Productionreference:1060415
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78439-248-2
www.packtpub.com
CreditsAuthor
ManojHans
Reviewers
ShankarGarg
PetroPodrezo
YalçınYenigün
CommissioningEditor
AmitGhodake
AcquisitionEditor
ReshmaRaman
ContentDevelopmentEditor
RitikaSingh
TechnicalEditor
MananPatel
CopyEditor
DiptiKapadia
ProjectCoordinator
AboliAmbardekar
JudieJose
Proofreaders
SimranBhogal
LesleyHarrison
Indexer
PriyaSane
ProductionCoordinator
KomalRamchandani
CoverWork
KomalRamchandani
AbouttheAuthorManojHansisaseniorQAengineerwhohasrichexperienceinsoftwaretesting.Apartfromtesting,hehasworkedinotherareasofITsuchaswebhosting,development,andsoftwareconfiguration.
HewasinterviewedfortheSeptember2013editionofSoftwareDeveloper’sJOURNALmagazineforSeleniumtraininginIndia.Manojispassionateaboutautomationtestingandlovestoautomatethings.
IwouldliketothankmyfamilyfortheircontinuedsupportwhileIspenteveningsandweekendsonthecomputer.IalsowanttothankUjjawalKumar,NishankJangra,andthePacktPublishingteamfortheirsupportduringthewritingofthisbook.
AbouttheReviewersShankarGargisanagileenthusiast,withexpertiseinautomationtesting.Currently,heworksasaseniorconsultantwithXebiaITArchitectsIndiaPvt.Ltd.
HestartedhiscareerasaJavadeveloper,buthisloveforbreakingthingsgothimintotesting.Hehasworkedontheautomationofmanyprojectsforweb,mobile,andSOAtechnologies.Rightnow,heisinlovewithCucumber,Selenium,Appium,andGroovy.
PriortoworkingwithXebia,hehasworkedforJabong.com,Honeywell,andTataConsultancyServices(TCS).
HeisaCertifiedScrumMaster(CSM),certifiedtester(ISTQB),aswellasacertifiedprogrammerforJava(SCJP5.0)andOracle9i(OCA).
IwouldliketothankmyfamilyforsupportingmewhenIwasreviewingthisbookandmakingsurethatIcompletedthingsontime.
PetroPodrezoisasoftwareconsultantfromToronto,Canada.HeholdsanHBScdegreefromtheUniversityofTorontoincomputerscienceandhasspecializedinsoftwareengineering.Hisworkismostlybasedonwebdevelopment,butoccasionally,itstretchesintotherealmofmobileapplicationsdevelopment.Apartfromwork,Petroenjoyscontributingtovariousopensourceprojectsanddevelopingwebappsassideprojects.
YalçınYenigünhasbeenworkingintheITindustrysince2009.Heearnedhisbachelor’sdegreeincomputerengineeringfromtheUniversityofGalatasaray,Istanbul.Hehasexperienceinobject-orienteddesign,analysis,agile,test-drivendevelopment,andJava/J2EE,inthefulllifecycleofthesoftwaredesignprocess.HehasworkedforZeroBufferandVodafoneasasoftwareengineerandimplementedvariouslarge-scaleprojects.
YalçıncurrentlyworksasasoftwaredevelopmentunitmanagerinBilgeAdam,whereheisresponsibleforpeoplemanagement,foradivisionofmorethan10softwareengineers.HeisatrainerofJavaprogramming,EffectiveJavaprogramming,JavaEnterpriseEdition,JavaWebServices,Androidprogramming,andtheProfessionalSCRUMDevelopercoursesforcorporates.HehasbeensponsoredbyTheScientificandTechnologicalResearchCouncilofTurkeyforopensourceresearchprojectsaswell.
Iwouldliketothankmyfriend,AbdullahAydeğer;mymathematicianbrother,OrçunYenigün;andmybestfriend,CansınAldanmaz,fortheirsupportthroughoutthereviewingofthisbook.Ialsoowethankstomyfather,ÜnalYenigün,andmother,HanifeYenigün,fortheirunconditionallove.
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmoreForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
https://www2.packtpub.com/books/subscription/packtlib
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
PrefaceTheideaofmobileautomationusingtheSeleniumsyntaxfirstcameaboutattheSeleniumConferenceinApril2012inLondonbyDanCuellar.Duringthepresentation,heshowedtheautomationofiOSusingtheSeleniumsyntax.Peoplewhoattendedtheconferencewereexcitedaboutthetool’spossibilities.
AfewmonthsaftertheSeleniumconference,JasonHugginscontactedDanabouthisprojectonmobileautomation.JasonencouragedDantoreleasehiscodeunderanopensourcelicense.InAugustthatyear,DanreleasedthesourcecodeonGitHub.JasonthendecidedtointroducetheprojectinMobileTestingSummitinNovember2012,buttheprojectneededanewnamefirst.Thus,thenameAppiumwasborn.
AppiumistheoneofthemostpopulartoolsformobileautomationandisusedfortestingapplicationsoniOS,Android,andFirefoxplatforms.Itcanautomatenative,hybrid,andwebmobileapps.
InJanuary2013,SauceLabsdecidedtofullybackAppiumandcreatedateamtosupportAppium.Theteam,whichincludedJonathanLipps(thecurrentprojectlead),decidedthatAppiumneededarebirthandultimatelysettledonNode.jsastheframeworktobeused.
Appium,withitsnewdesign,debutedinGoogleTestAutomationConference2013andwasreleasedwithAndroidandSelendroidsupportafewmonthslater,tomakeAppiumthefirstcross-platformautomationframework.InMay2014,Appiumreleasedversion1.0withstabilityimprovements,bugfixes,andaddedfeatures.IfyouwanttoreadmoreaboutAppium’shistorythenyoucanvisittheofficialwebsitehttp://appium.io/history.html.
ThisbookwillhelpyouperformmobileautomationtestinganduseAppiumdrivesonbothemulators/simulatorsandrealdevices.Youwillalsohaveagoodunderstandingofmobileautomationconceptsonceyou’rethroughwithit.
WhatthisbookcoversChapter1,Appium–ImportantConceptualBackground,explainstheJSONwireprotocolandAppiumsessions,andyouwillgettoknowthe“desiredcapabilities”thatarerequiredbeforeyoustartusingAppium.AbriefintroductiontotheAppiumserverandtheclientlibraryarealsoprovidedinthechapter.
Chapter2,GettingStartedwithAppium,explainsthesystemrequirementsforbothAndroidandiOSplatformsandtheadvantagesofusingAppiumoverotherexistingtools.YouwillalsounderstandtheprerequisitestogetstartedwithAppium.Inthischapter,youwilllearnhowtoinstallandsetupthesoftwarewithsystemvariablesandcreatethedevelopmentenvironment.
Chapter3,TheAppiumGUI,explainsallthefunctionalitiesofthebuttonsandgeneralsettingsusingtheAppiumGUI.
Chapter4,FindingElementswithDifferentLocators,explainsthestepstofindelementsinordertointeractwithmobileapplications.Youwillalsobeacquaintedwithhowtousedifferentlocatorsandtechniquestofindtheelements.
Chapter5,WorkingwithAppium,explainsscriptwritingfordifferentmobileapplicationsthataresupportedbyAppium.Youalsogettoknowabouthowtoinstallmobileappsinanemulator.
Chapter6,DrivingAppiumonRealDevices,introducesuserstotestingmobileapplicationsonrealdevices.ThischapteralsoincludesthegeneralsettingsrequiredforrealdevicestoworkwithAppium.
Chapter7,AdvancedUserInteractions,explorestheAppiumclientlibraryandmobilegestures,suchasscroll,zoom,andswipe.YouwillalsolearnhowtocapturescreenshotsandtheusesoftheTestNGListenerfortakingscreenshotsontestfailure.
WhatyouneedforthisbookYouwillneedthefollowingsoftwaretogetstartedwiththeexamplesinthisbook:
Java(version7orlater)TheAndroidSDKAPIVersion17orlaterTheEclipseIDETestNGTheAppiumServerTheAppiumclientlibrary(Java)TheSeleniumServerandWebDriverJavalibraryTheADBpluginonChromebrowserWindows7orlaterMacOS10.7orlaterXcode(4.6.3oralaterversion;5.1isrecommended)
WhothisbookisforAppiumEssentialsisintendedforautomationtestersanddeveloperswhowanttoenhancetheirskillsinweb-basedautomationaswellasmobileapplicationautomationusingAppium.Itisassumedthatyouhavebasicknowledgeofmobileapplicationtesting,SeleniumWebDriver,andprogramming.
ConventionsInthisbook,youwillfindanumberofstylesoftextthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestyles,andanexplanationoftheirmeaning.
Codewordsintextareshownasfollows:“Afterinstallation,runthecommandappium-doctortoensurethatwearereadywithAppium.”
Ablockofcodeissetasfollows:
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
//Setupdesiredcapabilities
DesiredCapabilitiescaps=newDesiredCapabilities();
Fileapp=newFile("pathoftheapk");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Androidemulator");
caps.setCapability("avd","NameoftheAVDtolaunch");
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"packagenameof
yourapp(youcangetitfromapkinfoapp)");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,"Launchactivityof
yourapp(youcangetitfromapkinfoapp)");
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Browser");
//Incaseofweb-apps
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
Anycommand-lineinputoroutputiswrittenasfollows:
androidcreateavd–n<nameoftheAVD>-t<targetID>
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,inmenusordialogboxesforexample,appearinthetextlikethis:“ClickonAdvancedsystemsettings.”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.
Tosendusgeneralfeedback,simplye-mail<[email protected]>,andmentionthebook’stitleinthesubjectofyourmessage.
Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.
CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.
DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.comforallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.
Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.
PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.
Pleasecontactusat<[email protected]>withalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.
QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<[email protected]>,andwewilldoourbesttoaddresstheproblem.
Chapter1.Appium–ImportantConceptualBackgroundInthischapter,wewilllearnabouttheAppiumarchitecture,JavaScriptObjectNotation(JSON)wireprotocol,andAppiumsessionsaswellasgainanunderstandingofthedesiredcapabilitiesbeforestartingAppium.ThischapterwillalsotouchuponthetopicsoftheAppiumserveranditsclientlibrary.
Inshort,wewillcoverthefollowingtopics:
Appium’sarchitectureTheSeleniumJSONwireprotocolAppiumsessionsDesiredcapabilitiesTheAppiumserveranditsclientlibrary
AppiumarchitectureAppiumisanHTTPserverwritteninNode.jsthatcreatesandhandlesWebDriversessions.TheAppiumwebserverfollowsthesameapproachastheSeleniumWebDriver,whichreceivesHTTPrequestsfromclientlibrariesthroughJSONandthenhandlesthoserequestsindifferentways,dependingontheplatformitisrunningon.
Let’sdiscusshowAppiumworksiniOSandAndroid.
AppiumoniOSOnaniOSdevice,AppiumusesApple’sUIAutomationAPItointeractwiththeUIelements.UIAutomationisaJavaScriptlibraryprovidedbyAppletowritetestscripts;AppiumutilizesthesesamelibrariestoautomateiOSapps.
Let’stakealookatthearchitecture,whichisshowninthefollowingdiagram:
Intheprecedingdiagram,whenweexecutethetestscripts,itgoesintheformofJSONthroughanHTTPrequesttotheAppiumserver.TheAppiumserversendsthecommandtotheinstruments,andtheinstrumentslookforthebootstrap.jsfile,whichispushedbytheAppiumservertotheiOSdevice.Then,thesecommandsexecuteinthebootstrap.jsfilewithintheiOSinstruments’environment.Aftertheexecutionofthecommand,theclientsendsbackthemessagetotheAppiumserverwiththelogdetailsoftheexecutedcommand.
AsimilarkindofarchitecturefollowsinthecaseofAndroidappautomation.Let’sdiscusstheAppiumarchitectureforAndroid.
AppiumonAndroidOnanAndroiddevice,AppiumusestheUIAutomatorframeworktoautomatetheapps.UIAutomatorisaframeworkthatisdevelopedbytheAndroiddeveloperstotesttheAndroiduserinterface.
Let’stakealookatthearchitecture,whichisshowninthefollowingdiagram:
Intheprecedingdiagram,wehaveaUIAutomator/SelendroidinplaceofAppleinstrumentsandbootstrap.jarinplaceofthebootstrap.jsfile.
AppiumsupportsAndroidversionsgreaterthanorequalto17;forearlierversions,itusestheSelendroidframework.Whenweexecutethetestscripts,AppiumsendsthecommandtotheUIAutomatororSelendroidonthebasisoftheAndroidversion.
Here,bootstrap.jarplaystheroleofaTCPserver,whichwecanusetosendthetestcommandinordertoperformtheactionontheAndroiddeviceusingUIAutomator/Selendroid.
TheSeleniumJSONwireprotocolTheJSONwireprotocol(JSONWP)isatransportmechanismcreatedbyWebDriverdevelopers.Thiswireprotocolisaspecificsetofpredefined,standardizedendpointsexposedviaaRESTfulAPI.ThepurposeofWebDriverandJSONWPistheautomatedtestingofwebsitesviaabrowsersuchasFirefoxdriver,IEdriver,andChromedriver.
AppiumimplementstheMobileJSONWP,theextensiontotheSeleniumJSONWP,anditcontrolsthedifferentmobiledevicebehaviors,suchasinstalling/uninstallingappsoverthesession.
Let’shavealookatsomeoftheendpointsfromtheAPIwhichareusedtointeractwithmobileapplications:
/session/:sessionId
/session/:sessionId/element
/session/:sessionId/elements
/session/:sessionId/element/:id/click
/session/:sessionId/source
/session/:sessionId/url
/session/:sessionId/timeouts/implicit_wait
NoteThecompletelistofendpointsisavailableathttps://code.google.com/p/selenium/wiki/JsonWireProtocolandhttps://code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile.
AppiumprovidesclientlibrariessimilartoWebDriverthatactasaninterfacetotheRESTAPI.Theselibrarieshavefunctionssimilartothefollowingmethod:
AppiumDriver.getPageSource();
ThismethodwillissueanHTTPrequesttotheJSONWP,anditgetstheresponsefromtheapplicableAPIendpoint.Inthiscase,theAPIendpointthathandlesthegetPageSourcemethodisasfollows:
/session/:sessionId/source
ThedriverwillexecutethetestscriptthatcomesintheJSONformatfromtheAppiumDriverservertogetthesource.Itwillreturnthepagesourceinthestringformat.Incaseofnon-HTML(nativemobileapps)platforms,theAppiumlibrarywillrespondwithanXMLdocumentrepresentationoftheUIhierarchy.Thespecificstructureofthedocumentmayvaryfromplatformtoplatform.
AppiumsessionAsessionisamediumtosendcommandstothespecifictestapplication;acommandisalwaysperformedinthecontextofasession.Aswesawintheprevioussection,aclientusesthesessionidentifierasthesessionIdparameterbeforeperforminganycommand.Theclientlibraryrequeststheservertocreateasession.TheserverwillthenrespondwithasessionIdendpoint,whichisusedtosendmorecommandstointeractwiththeapplication(s)beingtested.
DesiredcapabilitiesDesiredcapabilitiesisaJSONobject(asetofkeysandvalues)sentbytheclienttotheserver.Itdescribesthecapabilitiesfortheautomationsessioninwhichweareinterested.
Let’sdiscussthecapabilitiesonebyone;first,wewillseetheAppiumserver’scapabilities:
Weneedtoimport“importorg.openqa.Selenium.remote.DesiredCapabilities”libraryforJavatoworkwiththedesiredcapabilities.
Capability Explanation
automationName
Thiscapabilityisusedtodefinetheautomationengine.IfyouwanttoworkwithanAndroidSDKversionlessthan17,thenyouneedtodefinethevalueasSelendroid;otherwise,thecapabilitytakesthedefaultvalueasAppium.Let’sseehowwecanimplementitpractically:
DesiredCapabilitiescaps=newDesiredCapabilities();//creatinganobject
caps.setCapability("automationName","Selendroid");
//tosetcapabilityvalue
WecanalsosetthecapabilitiesusingAppium’sclientlibrary.Forthis,usersneedtoimport“importio.appium.java_client.remote.MobileCapabilityType”library:
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Selendroid");
There’snoneedtousethiscapabilityinthecaseofiOS.
platformName
ItisusedtosetthemobileOSplatform.ItusesthevalueasiOS,Android,orFirefoxOS:
caps.setCapability("platformName","Android");
IncaseoftheAppiumclientlibrary,youcanusethis:
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
platformVersion
TosetthemobileOSversion,forexample,7.1,4.4.4,usethefollowingcommand:
caps.setCapability("platformVersion","4.4.4");
Alternatively,youcanusethefollowingcommandaswell:
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4.4");
deviceName
Wecandefinethetypeofmobiledeviceoremulatortouse,usingthefollowingcommand,forexample,iPhoneSimulator,iPadSimulator,iPhoneRetina4-inch,AndroidEmulator,Motox,Nexus5,andsoon:
caps.setCapability("deviceName","Nexus5");
Youcanusethefollowingcommandaswell:
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Nexus5");
app
WecanaddtheabsolutelocalpathorremoteHTTPURLofthe.ipa,.apk,or.zipfile.Appiumwillinstalltheappbinaryontheappropriatedevicefirst.NotethatinthecaseofAndroid,ifyouspecifytheappPackageandappActivity(boththecapabilitieswillbediscussedlaterinthissection)capabilities,thenthiscapabilityshownhereisnotrequired:
caps.setCapability("app","/apps/demo/demo.apkorhttp://app.com/app.ipa");
Alternatively,youcanusethefollowingcommand:
caps.setCapability(MobileCapabilityType.APP,"/apps/demo/demo.apkor
http://app.com/app.ipa");
browserName
Ifyouwanttoautomatemobilewebapplications,thenyouhavetousethiscapabilitytodefinethebrowser.
ForSafarioniOS,youcanusethis:
caps.setCapability("browserName","Safari");
Also,youcanusethefollowingcommand:
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");
ForChromeonAndroid,youcanusethis:
caps.setCapability("browserName","Chrome");
Alternatively,youcanusethefollowingcommand:
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Chrome");
newCommandTimeout
Toendthesession,Appiumwillwaitforafewsecondsforanewcommandfromtheclientbeforeassumingthattheclientquit.Thedefaultvalueis60.Tosetthistime,youcanusethefollowingcommand:
caps.setCapability("newCommandTimeout","30");
Youcanalsousethiscommandtoendthesession:
caps.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT,"30");
autoLaunch
Thiscapabilityisusedtoinstallandlaunchtheappautomatically.Thedefaultvalueissettotrue.Youcansetthecapabilitywiththefollowingcommand:
caps.setCapability("autoLaunch","false");
language
Thisisusedtosetthelanguageonthesimulator/emulator,forexample,fr,es,andsoon.Thefollowingcommandwillworkonlyonthesimulator/emulator:
caps.setCapability("language","fr");
localeThisisusedtosetthelocaleforthesimulator/emulator,forexample,fr_CA,tr_TR,andsoon:
caps.setCapability("locale","fr_CA");
udid
Auniquedeviceidentifier(udid)isbasicallyusedtoidentifyiOSphysicaldevice.Itisa40characterlongvalue(forexample,1be204387fc072g1be204387fc072g4387fc072g).ThiscapabilityisusedwhenyouareautomatingappsoniOSphysicaldevice.WecaneasilygetthedeviceudidfromiTunes,byclickingonSerialNumber:
caps.setCapability("udid","1be204387fc072g1be204387fc072g4387fc072g");
orientation
Thisisusedtostartinacertainorientationinsimulator/emulatoronly,forexample,LANDSCAPEorPORTRAIT:
caps.setCapability("orientation","PORTRAIT");
autoWebview
IfyouareautomatinghybridappsandwanttomovedirectlyintotheWebviewcontext,thenyoucansetitbyusingthiscapability;thedefaultvalueisfalse:
caps.setCapability("autoWebview","true");
noResetThiscapabilityisusedtoresettheapp’sstatebeforethesessionstarts;thedefaultvalueisfalse:
caps.setCapability("noReset"-,"true");
fullReset
IniOS,thiswilldeletetheentiresimulatorfolder.InAndroid,youcanresettheapp’sstatebyuninstallingtheappinsteadofclearingtheappdata;also,itwillremovetheappafterthesessioniscomplete.Thedefaultvalueisfalse.ThefollowingisthecommandforfullReset:
caps.setCapability("fullReset","true");
AndroidcapabilitiesNow,let’sdiscusstheAndroidcapabilities,asshowninthefollowingtable:
Capability Explanation
appPackage
ThiscapabilityisfortheJavapackageoftheAndroidappthatyouwanttorun,forexample,com.android.calculator2,com.android.settings,andsoon:
caps.setCapability("appPackage","com.android.calculator2");
Alternatively,youcanusethiscommand:
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"com.android.calculator2");
appActivity
Byusingthiscapability,youcanspecifytheAndroidactivitythatyouwanttolaunchfromyourpackage,forexample,MainActivity,.Settings,com.android.calculator2.Calculator,andsoon:
caps.setCapability("appActivity","com.android.calculator2.Calculator");
Youcanalsousethefollowingcommand:
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,"com.android.calculator2.Calculator");
appWaitActivity
Androidactivityforwhichtheuserwantstowaitcanbedefinedusingthiscapability:
caps.setCapability("appWaitActivity","com.android.calculator2.Calculator");
Alternatively,youcanalsousethiscommand:
caps.setCapability(MobileCapabilityType.APP_WAIT_ACTIVITY,"com.android.calculator2.Calculator");
appWaitPackage
TheJavapackageoftheAndroidappyouwanttowaitforcanbedefinedusingthefollowingcapability,forexample,com.example.android.myApp,com.android.settings,andsoon:
caps.setCapability("appWaitPackage","com.example.android.myApp");
deviceReadyTimeout
Youcansetthetimeout(inseconds)whilewaitingforthedevicetobeready,asfollows;thedefaultvalueisseconds:
caps.setCapability("deviceReadyTimeout","10");
Alternatively,youcanalsousethiscommand:
caps.setCapability(MobileCapabilityType.DEVICE_READY_TIMEOUT,"10");
enablePerformanceLogging
YoucanenabletheChromedriver’sperformanceloggingbytheuseofthiscapability.ItwillenableloggingonlyforChromeandwebview;thedefaultvalueisfalse:
caps.setCapability("enablePerformanceLogging","true");
androidDeviceReadyTimeoutTosetthetimeoutinsecondsforadevicetobecomereadyafterbooting,youcanusethefollowingcapability:
caps.setCapability("androidDeviceReadyTimeout","20");
androidDeviceSocket
ThiscapabilityisusedtosetDevToolssocketname.ItisonlyneededwhenanappisaChromium-embeddingbrowser.ThesocketisopenedbythebrowserandtheChromeDriverconnectstoitasaDevToolsclient,forexample,chrome_DevTools_remote:
caps.setCapability("androidDeviceSocket","chrome_DevTools_remote");
AvdUsingthiscapability,youcanspecifythenameofavdthatyouwanttolaunch,forexample,
caps.setCapability("avd","AVD_NEXUS_5");
avdLaunchTimeout
Thiscapabilitywillhelpyoudefinehowlongyouneedtowait(inmilliseconds)foranavdtotheAndroidDebugBridge(ADB)(thedefaultvalueis120000):
caps.setCapability("avdLaunchTimeout","230000");
avdReadyTimeout
Youcanspecifythewaittime(inmilliseconds)foranavdtofinishitsbootanimationsusingthefollowingcapability;thedefaultwaittimeoutis120000:
caps.setCapability("avdReadyTimeout","240000");
avdArgs
Topasstheadditionalemulatorargumentswhenlaunchinganavd,usethefollowingcapability,forexample,netfast:
caps.setCapability("avdArgs","netfast");
chromedriverExecutable
YoucangivetheabsolutelocalpathtotheWebDriverexecutable(iftheChromiumembedderprovidesitsownWebDriver,itshouldbeusedinsteadoftheoriginalChromeDriverbundledwithAppium)usingthefollowingcapability:
caps.setCapability("chromedriverExecutable","/abs/path/to/webdriver");
autoWebviewTimeout
Thefollowingcapabilityallowsyoutosetthetime(inmilliseconds)forwhichyouneedtowaitfortheWebviewcontexttobecomeactive;thedefaultvalueis2000:
caps.setCapability("autoWebviewTimeout","3000");
intentAction
Intentactionisbasicallyusedtostartanactivity,asshowninthefollowingcode.Thedefaultvalueisandroid.intent.action.MAIN.Forexample,android.intent.action.MAIN,android.intent.action.VIEWsoon:
caps.setCapability("intentAction","android.intent.action.VIEW");
intentCategory
Thisprovidestheintentcategorythatwillbeusedtostarttheactivity(thedefaultisandroid.intent.category.LAUNCHER),forexample,android.intent.category.LAUNCHERandroid.intent.category.APP_CONTACTS:
caps.setCapability("intentCategory","android.intent.category.APP_CONTACTS");
intentFlagsFlagsareusedtostartanactivity(thedefaultis0x10200000),forexample,0x10200000:
caps.setCapability("intentFlags","0x10200000");
unicodeKeyboardYoucanenableUnicodeinputbyusingthefollowingcode;thedefaultvalueisfalse:
caps.setCapability("unicodeKeyboard","true");
resetKeyboardYoucanresetthekeyboardtoitsoriginalstatebyusingthiscapability.Thedefaultvalueis
caps.setCapability("resetKeyboard","true");
iOScapabilitiesLet’sdiscusstheiOScapabilities,asshowninthefollowingtable:
Capability Explanation
calendarFormat
ThisisusedtosetthecalendarformatfortheiOSsimulator.Itappliesonlytoasimulator,forexample,Gregorian:
caps.setCapability("calendarFormat","Gregorian");
bundleId
BundleIdisbasicallyusedtostartanapponarealdeviceortouseotherappsthatrequirethebundleIdduringtheteststartup,forexample,io.appium.TestApp:
caps.setCapability("bundleId","io.appium.TestApp");
launchTimeout
Thisisusedtospecifytheamountoftime(inmillisecond)youneedtowaitforInstrumentsbeforeassumingthatithungandthesessionfailed.Thiscanbedoneusingthefollowingcommand:
caps.setCapability("launchTimeout","30000");
locationServicesEnabled
Thiscapabilityisusedtoenablelocationservices.Youcanapplyitonlyonasimulator;youcangivetheBooleanvalue,asfollows:
caps.setCapability("locationServicesEnabled","false");
locationServicesAuthorized
Ifyouwanttousethiscapability,youmustprovidethebundleIdbyusingthebundleIdcapability.Youcanusethiscapabilityonasimulator.Aftersettingthis,thelocationservicesalertdoesn’tpopup.Thedefaultisthecurrentsimulatorsettinganditsvalueisfalse:
caps.setCapability("locationServicesAuthorized","true");
autoAcceptAlerts
Usingthiscapability,youcanacceptprivacypermissionalertsautomatically,suchaslocation,contacts,photos,andsoon,iftheyarise;thedefaultvalueisfalse:
caps.setCapability("autoAcceptAlerts","true");
nativeInstrumentsLibYoucanusethenativeinstrumentslibrarybysettingupthiscapability:
caps.setCapability("nativeInstrumentsLib","true");
nativeWebTap
ThiscanbeusedtoenablerealwebtapsinSafari,whicharenon-JavaScriptbased.Thedefaultvalueisfalse.Letmewarnyouthatthismightnotperfectlydealwithanelement;itdependsontheviewport’ssize/ratio:
caps.setCapability("nativeWebTap","false");
safariAllowPopups
Youcanusethiscapabilityonasimulatoronly.ItallowsJavaScripttoopennewwindowsinSafari.Thedefaultisthecurrentsimulatorsetting.Todothis,youcanusethefollowingcommand:
caps.setCapability("safariAllowPopups","false");
safariIgnoreFraudWarning
Thiscapabilitycanbeusedonlyonasimulator.ItprohibitsSafarifromdisplayingafraudulentwebsitewarning.Thedefaultvalueisthecurrentsimulatorsetting,asfollows:
caps.setCapability("safariIgnoreFraudWarning","false");
safariOpenLinksInBackground
ThiscapabilityenablesSafaritoopenlinksinnewwindows;thedefaultkeepsthecurrentsimulatorsettings:
caps.setCapability("safariOpenLinksInBackground","true");
keepKeyChains
Whetheryouneedtokeepkeychains(Library/Keychains)whenanAppiumsessionisstarted/finishedcanbedefinedusingthiscapability.Youcanapplyitonasimulator,asfollows:
caps.setCapability("keepKeyChains","true");
processArguments
ThiscapabilityallowsyoutopassargumentswhileAUTusinginstruments,forexample,myflag:
caps.setCapability("processArguments","myflag");
interKeyDelay
Youcandelaythekeystrokessenttoanelementwhentypingusesthiscapability.Ittakesthevalueinmilliseconds:
caps.setCapability("interKeyDelay","100");
WehaveseenallthedesiredcapabilitiesthatareusedinAppium.Now,wewilltalkinbriefabouttheAppiumserveranditsclientlibrary.
TheAppiumserveranditsclientlibrariesTheAppiumserverisusedtointeractwithdifferentplatformssuchasiOSandAndroid.Itcreatesasessiontointeractwithmobileapps,whicharenotsupportedonanyplatform.ItisanHTTPserverwritteninNode.jsandusesthesameconceptastheSeleniumServer,whichidentifiestheHTTPrequestsfromtheclientlibrariesandsendstheserequeststotheappropriateplatform.TostarttheAppiumserver,usersneedtodownloadthesourceorinstallitdirectlyfromnpm.AppiumalsoprovidestheGUIversionoftheserver.YoucandownloaditfromtheofficialAppiumsite,http://appium.io.Inthenextchapter,wewilldiscusstheGUIversioninmoredetail.
OneofthebiggestadvantagesofAppiumisbecauseitissimplyaRESTAPIatitscore,thecodeyouusetointeractwithitiswritteninanumberoflanguagessuchasJava,C#,Ruby,Python,andothers.AppiumextendstheWebDriverclientlibrariesandaddstheextracommandsinittoworkwithmobiledevices.ItprovidesclientlibrariesthatsupportAppiumextensionstotheWebDriverprotocol.Becauseoftheseextensionstotheprotocol,itisimportanttouseAppium-specificclientlibrariestowriteautomationtestsorprocedures,insteadofgenericWebDriverclientlibraries.
Appiumaddedsomeinterestingfunctionalityforworkingcloselywithmobiledevices,suchasmultitouchgesturesandscreenorientation.Wewillseethepracticalimplementationofthesefunctionalitieslater.
SummaryWeshouldnowhaveanunderstandingoftheAppiumarchitecture,JSONwireprotocol,desiredcapabilities,anditsuses.WealsolearnedabouttheAppiumserveranditslanguage-specificclientlibraryinthischapter.
Specifically,wedoveintoJSONWPandAppiumsession,whichareusedtosendfurthercommandsinordertointeractwiththeapplication.Wealsosetupautomationsessionsusingthedesiredcapabilities.Inthelastsection,wegraspedsomeinformationabouttheAppiumserveranditslanguage-specificclientlibraries.
Inthenextchapter,wewilltakealookatwhatwerequiretogetstartedwithAppium.
Chapter2.GettingStartedwithAppiumToday,alotisgoingoninthefieldofmobiledevelopment,andweneedtotestthesedevelopmentstomeettheexpectationsoftheendusers.Itisthisprogressthathascontributedtothegrowthofmobileautomation.DanCuellarcameupwithabrilliantideathatinvolvedintegratingthetoolwithSelenium,postwhichhecreatedAppium.Appiumisagoodtoolandiswidelyusedtoautomatemobileapps.Thebestpartisthatitisopensource.
Inthischapter,wewilllearnthefollowing:
TheadvantagesofAppiumSystemrequirementsforAndroid/iOSInstallingdifferentsoftwareCreatingemulatorsandsimulatorsSettingupanEclipseJavaproject
Appium–prosandconsAppiumisanopensourcetoolforautomatingmobileapps,suchasnative,web-based,andhybridapplicationsdesignedfortheAndroid,iOS,andFirefoxOSplatforms.
BeforedivingintoAppium’sadvantages,let’sdiscussitsshortcomings,asfollows:
NodirectsupportforAndroidAlertHandling:AlerthandlingisnotimplementedyetfornativeappsviaAlertAPIbut,wehaveanalternativetohandleitwhichwewillseeinChapter7,AdvancedUserInteractions.Hopefully,alerthandlingwillbeimplementedsoon.LimitedsupportforAndroidversions:AppiumdirectlysupportsAndroidVersion17orlater,butifwewanttoworkwithversionsolderthanversion17,thenwecanusetheintegratedtoolSelendroid.Lackofimagerecognition:Wecan’tlocateimages;toworkwithimages,wehavetoworkwithscreencoordinates,whichisnotthebestwaybutagainit’sintheirroadmaptoapplythelocatorstrategytofindimages.Mobilegesturessupport:Someofthegesturesupportsarenotimplementedyet,suchasdouble-clickingintheJavaclientlibrary,buttheyareimplementedinotherclientlibraries.HopefullythegesturesupportwillbeimplementedsoonintheJavaclientlibraryaswell.
Now,let’sdiscussAppium’sadvantagesonthebasisofitsphilosophy.
TheAppiumphilosophyhasadifferentappealfromothercompetitors.Theofficialphilosophy(http://appium.io/slate/en/master/?java#appium-philosophy)isasfollows:
Youshouldn’trecompileyourappormodifyitinanywayinordertoautomateitYoushouldn’tbelockedintoaspecificlanguageorframeworktowriteandrunyourtestsAmobileautomationframeworkshouldn’treinventthewheelwhenitcomestoautomationAPIsAmobileautomationframeworkshouldbeopensourceinspiritandpracticeaswellasinname
Appiumusesvendor-providedframeworksunderthehood,whichmeetsthefirstrequirement,sowedon’tneedthird-partycodetocompiletheapp.Wecantestthesamebuildoftheappthatwearegoingtosubmitinthemarketplace.Foroursecondrequirement,AppiumextendstheWebDriverclientlibraries,whicharealreadywritteninmostpopularprogramminglanguages.So,wearefreetouseanyprogramminglanguageinordertowritetheautomationtestscripts.
AppiumextendstheexistingWebDriverJSONWPwithadditionalAPImethodsthatareconvenientformobileautomation.So,AppiumhasthesamestandardasWebDriverandnoreinventionforthemobileautomationframework,whichmeetsthethirdrequirement.Lastbutnotleast,itisopensource.
Itprovidescross-platformsolutionsfornativeandhybridmobileapps,whichmeansthat
thesametestcaseswillworkonmultipleplatforms.IfyouarefamiliarwithSeleniumWebDriver,youwillfeelathomewithAppium,otherwiseyouwillfirstneedtolearnWebDriverforabetterunderstanding.AppiumusesthesamescriptingasWebDriver.AppiumallowsyoutotalktootherAndroidappsthatareintegratedwithAppUnderTest(AUT).Forexample,youcanhitanotherappfromtheAUTsuchasacameraapp.Italsosupportscloud-basedtesting;youcanrunyourtestscriptsinthecloudusingservicessuchasSauceLabsandTestdroid.Theyprovideservicestoruntestsonrealdevicesorsimulators.
Theseadvantagesmakeitsuperioroverothermobileautomationtools.ThefollowingtableshowsAppium’sadvantagesoverothertoolsbasedonitsphilosophy:
Tools R1 R2 R3 R4
Calabash No No No Yes
iOSdriver Yes Yes Yes No
Robotium No No Yes No
Selendroid No Yes Yes No
Appium Yes Yes Yes Yes
NoteR1,R2,R3,andR4aretheAppiumphilosophy,whichwediscussedearlierinthissection.
SystemrequirementsforAndroid/iOSWehavereadaboutAppium;now,it’stimetoknowaboutthesystemrequirementsforAndroid/iOS.
AndroidrequirementsonWindowsandMacThefollowingarethesystemrequirementsforAppiumonAndroid:
Java(version7orlater)AndroidSDKAPI(version17orlater)AndroidVirtualDevice(AVD)orrealdevice
iOSrequirementsThesearethesystemrequirementsforiOSdevicestostartwithAppium:
MacOSX10.7orlaterXcode(greaterthanorequalto4.6.3;5.1isrecommended)withthecommand-linebuildtoolJavaversion7orlaterHomebrewNodeandnpm
Inthefollowingsection,wewilllookathowtoinstalldifferentsoftware.
InstallingdifferentsoftwareTogetstartedwithAppium,weneedtoinstallsomesoftwareonourmachines.Let’sstarttheinstallationprocessondifferentmachines.
AppiuminstallationforAndroidTheprerequisitesfortheinstallationofAppiumonAndroidareasfollows:
JDK(Javadevelopmentkit)AndroidSDK(Softwaredevelopmentkit)AppiumfordifferentOSes
InstallingJDKonWindowsInordertoinstalltheJDK,youcanvisithttp://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html.
AfterinstallingtheJDK,youneedtosettheenvironmentvariables.Todothis,performthefollowingsteps:
1. OpenSystemPropertiesbypressingtheWindowslogo+Pausekeyorright-clickonMyComputerandthenclickonProperties.
2. ClickonAdvancedsystemsettings.3. ClickonEnvironmentVariables.4. UnderUservariables,clickonNew.Then,youwillgetthefollowingscreenshot:
5. EntertheVariablenameasJAVA_HOME.6. EntertheVariablevalueastheinstallationpathfortheJDK,forexample,
C:\ProgramFiles\Java\jdk1.8.0_20\jre.7. IntheSystemvariablessection,double-clickonPath;then,inVariablevalue,add
thenewpath%JAVA_HOME%\bin.Justensurethatthereisasemicolonseparatingthisentryfromthepreexistingvalue,asshowninthefollowingscreenshot:
8. Finally,clickontheOKbuttontoapplythechanges.
Now,openthecommandpromptandenterthecommandjava-versiontochecktheJavapathsetting.ThiswillreturntheJavaversionavailableonthesystem.
InstallingtheAndroidSDKWeneedtoinstalltheAndroidSDKtodrivethetestscriptsondevices.YoucandownloadtheAndroidSDKfromhttp://developer.android.com/sdk/index.htmlforyouroperatingsystem.
WewillsetthesystemvariablesforWindowsusingthefollowingsteps:
1. Followsteps1to4fromtheprecedingsection,inwhichwesetthepathforJava.2. TypeVariablenameasANDROID_HOMEandentertheVariablevalueofwhereyou
haveyourAndroidSDKinstalled.Forexample,C:\android-sdk.3. Now,weneedtoaddthepaths%ANDROID_HOME%\platform-toolsand
%ANDROID_HOME%\toolstothePathvariableunderSystemVariables.4. ClickontheOKbuttontoapplythechanges.
ToverifytheAndroidpath,typeandroidonthecommandpromptandpressEnter.Thefollowingwindowwillappear:
Installthepackages,asshownintheprecedingscreenshot.IfyouaretestingAPI19,thenyoujustneedtoinstallSDKtools(22.6),Platform-tools(19.0.1),Build-tools(19.0.3),andAndroid4.4.2.
SettingthesystemvariablesforMacIfyouaresettingthesystemvariablesforthefirsttime,thenyouneedtocreatethe.bash_profilefilewiththehelpoffollowingsteps:
1. Opentheterminal.2. Typetouch~/.bash_profileandpressenter/return.3. Typeopen~/.bash_profile.Thesystemwillopenthebash_profilefile.
Now,wehaveabash_profilefile.InordertosettheJavaandAndroidSDKpaths,weneedtoconfiguretheJAVA_HOMEandANDROID_HOMEvariablesinbash_profile.Addthefollowingpathsintothefile:
exportJAVA_HOME=path/to/the/java/home
exportANDROID_HOME=path/to/the/android/sdk
exportPATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
Onceyouhavecompletedallthesteps,typejava–versionintheterminaltochecktheJavapathsetting.ThiswillreturntheJavaversionavailableonthesystem;typeandroidontheterminalandinstallthedesiredAndroidpackages.
AppiumforiOSThefollowingaretheprerequisitesforinstallingAppiumoniOS:
XcodeHomebrewNodeandnpm
InstallingXcodeWeneedtoperformthefollowingstepstoinstallXcode:
1. Visithttps://itunes.apple.com/us/app/xcode/id497799835toinstallXcode.Then,clickonViewinMacAppStore.
2. ThesystemwilllaunchtheAppStoreautomaticallyonyourMacandopentheXcodepage.
3. Now,clickontheFreebuttonandthenclickonInstallApp.
TolaunchXcode,youcangototheApplicationsfolderandthendouble-clickonXcode.Nowyouaredonewiththeinstallation.
InstallingHomebrewHomebrewisasoftwarepackagemanagementsystemforMac,whichisusedtoinstallthestuffyouneedthatAppledidn’tprovide.WithHomebrew,youcaninstallmanyopensourcetools.PerformthefollowingstepstoinstallHomebrew:
1. Opentheterminalandenterthefollowingcommand:
ruby-e"$(curl-fsSL
https://raw.githubusercontent.com/Homebrew/install/master/install)".
2. Followtheinstructionspromptedbytheterminal.3. AfterinstallingtheHomebrew,runthecommandbrewdoctor.Youwillgetthe
messageYoursystemisreadytobrew;ifyoudon’t,thentrytofixthewarningsanderrorsusingthebrewdoctor.
NodeandnpmnpmisaNode.jspackagemanager;itisanonlinerepositoryofopensourceNode.jsprojects.Itiscommand-lineutilitytopackageinstallation.
TheAppiumserveriswritteninNode.js;that’swhyweneedittodownloadAppium.ThereareotherwaystodownloadtheAppiumserveraswell,whichwillbediscussedlater.
Let’sinstallNodeusingbrewcommands.YouneedtorunthefollowingcommandtoinstallNode:
brewinstallnode
AppiumfordifferentOSesTherearedifferentmethodstoinstalltheAppiumserveronWindows/iOS.Let’sdiscussthemonebyone.
AppiumforWindowsYoucandownloadAppiumforWindowsdirectlyfromAppium’sofficialwebsite(http://appium.io/),oryoucancloneAppiumfromhttps://github.com/appium/appium.git.
JusttoensurethatwearereadytostartwiththeAppiumserver,enterthefollowingcommandontheCommandPrompt:
nodeAppium-doctor
Youdon’tneedtodownloadNode;youcangetitfromtheAppiumbundle.ToruntheNodecommands,youneedtosetthepathforNode(forexample,C:\AppiumForWindows).Beforerunningthecommand,setthedirectoryasC:\AppiumForWindows\node_modules\appium\bin.
AppiumforMacAppiumforMaccanbedownloadedfromtheAppiumwebsite,alternativelyyoucandownloaditusingnpmcommands.
RunthefollowingcommandtoinstallAppium:
npminstall–gappium
Afterinstallation,runtheappium-doctorcommandtoensurethatwearereadytouseAppium.
NoteMakesureyouhavenotinstalledAppiumwithsudo,otherwiseyouwillfaceauthorizationproblemswhilerunningAppium.
DownloadingthenecessaryJARfilesWeneedtodownloadsomeexecutablebinariestoworkwithAppium.Theyarelistedasfollows:
SeleniumServerandWebDriverJavaclient(https://selenium-release.storage.googleapis.com/index.html)AppiumJavaclient(http://search.maven.org/#search|ga|1|appium%20java%20client)Gson(http://mvnrepository.com/artifact/com.google.code.gson)
TipThedownloadlinkscanbechanged;Isuggestyouvisittheofficialwebsitesinthecaseofanaddresschange.
CreatingemulatorsandsimulatorsWe’llnowlookathowwecancreateemulatorsandsimulators,startingwithaniOSsimulatorandthenmoveontoanAndroidsimulator.
AniOSsimulatorWedon’tneedtocreateasimulatorforMac;italreadycomeswithXcodeunderdevelopertools.WhenyoustarttheAppiumserverforthefirsttime,itwillpromptyoutoauthorizetheuseofInstruments,orifyouarerunningitfromnpm,runsudoauthorize_iostoworkwiththesimulator.
AnAndroidemulatorTherearetwowaystocreateanAVDfortestingandroidapps:
CreatetheAVDfromthecommandlineCreatetheAVDusingtheAVDManager
Let’screateAVDusingthecommandline,asfollows:
1. OpentheCommandPromptandtypeandroidlisttargets;thiswillgeneratealistofavailabletargets.
2. Runandroidcreateavd–n<nameoftheAVD>-t<targetIDwhichyoucangetfromthefirststep>--abi<againyoucangetitfromfirststep>.
NoteYoucanalsocustomizetheAVDwithoptions;visithttp://developer.android.com/tools/devices/managing-avds-cmdline.htmlformoredetails.
Theprecedinglinkcanchange;ifithaschanged,thenyoucansearchonGooglewiththekeywords“avdscommandline”.
Second,wecancreatetheAVDfromtheAVDManager(youcanfindthisundertheAndroidSDKfolder).WeneedtoperformthefollowingstepstocreatetheAVD:
1. Double-clickonAVDManagerandclickontheNewbutton.Thefollowingscreenwillbedisplayed:
2. Enterthenameofthedeviceandthenecessarydetails.3. ClickontheOKbutton.
Afteryoucompletethesesteps,theemulatorwillbedisplayedundertheAndroidVirtualDevicestab.
SettingupanEclipseJavaprojectWeneedanintegrateddevelopmentenvironment(IDE)towritetestscripts;inthemarket,therearealotofopensourceIDE’ssuchasEclipse,NetBeans,IntelliJIDEA,andothers.HerewearegoingtouseanEclipseIDE.IfyouhavedownloadedtheAndroidADTbundle,thenyouwillgetEclipsealongwithit.Otherwise,youcandownloaditfromhttp://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/lunasr1a.
OnceyouhavedownloadedtheIDE,launchitbydouble-clickingontheeclipse.exeicon.
Afterthis,youneedtoperformthefollowingstepstosetuptheJavaproject:
1. Afterclickingontheicon,itwillaskyouforaWorkspacelocation.EnterthelocationandclickontheOKbutton,asshownhere:
2. ClickontheWorkbenchicononthewelcomescreen,whichisatthetop-rightcornerofthescreen.
3. Createanewprojectbyclickingontheshortcuticon;youcanalsodothisbynavigatingtoFile|New|Project.Adialogboxwillappear.
4. SelectJavaProjectundertheJavafolderandclickontheNextButton,asshowninthefollowingscreenshot:
5. EntertheProjectname,forexample,AppiumTest,andclickonUseaprojectspecificJREorUsedefaultJRE.ThenclickontheFinishbutton,asshownhere:
6. Eclipsewillpromptyoutoopentheprojectinperspectiveview;youneedtoclickontheNobutton:
7. YouhavesuccessfullycreatedtheJavaproject.Now,createapackagebyright-clickingonsrc;then,gotoNew|Packageandenterthepackagename,forexample,com.example.appium.Now,clickontheFinishbutton,asshowninthefollowingscreenshot:
8. Thefollowingwindowwillopen:
9. Now,createtheclassbyright-clickingoncom.example.appium;gotoNew|Class
andtypethenameoftheclass,forexample,FirstScript.Next,clickontheFinishbutton,asshownhere:
10. Beforewritingthetestscripts,weneedtoaddsomeexternalJARfiles,whichareshowninthefollowingscreenshot.InordertoaddJARfiles,right-clickonAppiumTestandnavigatetoBuildPath|ConfigureBuildPath.Eclipsewillopenadialogbox;selecttheLibrariestabandthenclickonAddExternalJARs…,asshowninthefollowingscreenshot:
11. YouneedtoaddtheJARfilesshownintheprecedingscreenshot.AfteraddingtheJARfiles,clickontheOKbutton.
WehavecreatedaJavaprojectandsuccessfullyconfiguredallthenecessaryJARfiles.AswearegoingtouseTestNGastheunittestingframework,weneedtoinstallTestNGasanEclipseplugin.
InordertoinstallTestNG,weneedtoperformthefollowingsteps:
1. ClickontheHelptabandthenclickonInstallNewSoftware;youwillgetthefollowinginstallationwindow:
2. TypetheaddressinWorkwithashttp://beust.com/eclipse.TestNGwillappearintheframe;justselectTestNGandclickontheNextbutton.Now,youneedtofollowtheinstructionstoinstalltheTestNGplugin.
3. TheTestNGpluginwillbedisplayedinPreferencesunderWindowonceyouhavecompletedtheinstallation,asshownhere:
NowwearereadytowriteourfirstAppiumtestscript.
SummaryWelearnedalotinthischapter,startingwiththeprosandconsofAppiumandmovingontothesystemrequirementsforAndroidandiOS.WethenlookedattheinstallationofJDK,AndroidSDK,WebDriverclient,Seleniumserverbinaries,Homebrew,Nodeandnpm,aswellasAppiumanditsclientlibrary.Wealsolearnedaboutthesystem’senvironmentvariables.Lastly,wecreatedanemulatortotesttheappsandsetupanEclipseJavaproject.
Inthenextchapter,wearegoingtolearnhowtousetheAppiumGUI.
Chapter3.TheAppiumGUIThischapterfocusesontheGUIfortheAppiumserver.Bytheendofthischapter,weshouldgetanunderstandingofallthetermsthatareavailableintheapplication.
Inthischapter,wewilllearnaboutthefollowingtopics:
TheAppiumGUIforWindowsTheAppiumGUIforMac
TheAppiumserverInthepreviouschapter,wedownloadedtheAppiumserver.Wehavetwowaystostarttheserver:eitherusingtheAppiumGUIorusingCommandPrompt/Terminal.Nowlet’sdiscusstheAppiumGUI.
TheAppiumGUIforWindowsAppiumdevelopershavecreatedthewell-designedserverGUI,usingwhichwecaneasilystarttheserveralongwiththedesiredsettings.ThisGUIgivesusalotofoptionstosetuptheenvironmentinordertostartwithautomationtesting.
TheAppiumGUIhasthefollowingicons/buttons:
AndroidSettingsGeneralSettingsDeveloperSettingsAboutInspectorLaunch/StopClear
Thesebuttons/iconscanbeseeninthefollowingscreenshot:
AndroidSettingsUnderAndroidSettings,wehavemultipleoptionswhichweneedbeforewestartwiththeautomationofmobileapps.JustclickonthefirsticonfromtheAppiumGUI;thiswillopenthepop-upwindowalongwithalotoffields.ThesefieldsarecategorizedusingheadingssuchasApplication,LaunchDevice,Capabilities,andAdvanced,asshowninthefollowingscreenshot:
Application
TheApplicationpanecontainsvariousfields,whicharelistedinthefollowingtable:
Field Description
ApplicationPath
Inthisfield,youcangivethepathoftheAndroidAPKthatyouwanttotest.Youhavetwooptionstosettheapp’spath:eithertoclickontheChoosebuttonordirectlytypeintothebox.
Package ThisfieldisfortheAndroidapppackage.Forexample,com.android.calculator2.
WaitforPackage Thiscapabilitywillwaitfortheapplicationpackage,whichweprovideinthePackagecapability.
LaunchActivity Typetheactivitythatyouwanttolaunchinthemobiledevice,forexample,MainActivity.
WaitforActivity Thisisthesameasthewaitforpackagefunctionality;itwillwaitfortheappactivity.
Use
Browser Selectthebrowserfromthedropdown,whichyouwishtolaunch.
FullReset Thiswilluninstalltheappafterthesessioniscomplete.
NoReset Thiswillpreventthedevicefromresetting.
IntentAction Thiswillbeusedtostarttheactivity.
IntentCategory Here,wecanspecifytheappactivitythatwewanttostart.
IntentFlags Thisdenotestheintentflagsusedtostarttheactivity.
IntentArguments Here,youcanpassadditionalargumentstostarttheactivity.
LaunchDevice
TheLaunchDevicepanecontainsalotoffields,whicharelistedinthefollowingtable:
Field Description
LaunchAVD Here,youneedtotypethenameoftheAVDtobelaunched.
DeviceReadyTimeout Here,mentionthetimeout(inseconds)towaitforthedevicetobeready.
Arguments WecanpassadditionalemulatorargumentstolaunchtheAVDinthisfield.
Capabilities
TheCapabilitiespanecontainsthefieldslistedinthefollowingtable:
Field Description
PlatformName Thisdenotesthenameofthemobileplatform.
AutomationName Youcanselectthisfromthedropdown.
PlatformVersion Here,selecttheandroidversioninwhichyouwishtotestthemobileapp.
DeviceName Thisdenotesthenameofthedevicetobeused.
Language ThisisusedtosetthelanguagefortheAndroiddevice.
Locale ThisisusedtosetthelocalefortheAndroiddevice.
Advanced
TheAdvancedpanecontainsthefieldslistedinthefollowingtable,alongwiththeirdescriptions:
Field Description
SDKPath ThisdenotestheAndroidSDKpath.
CoverageClass Here,wecanpassafullyqualifiedinstrumentationclass.
BootstrapPort Here,settheportnumbertotalktoAppium.
SelendroidPort Here,wecansettheportnumberforSelendroid.
ChromedriverPort Here,wesettheportinwhichChromeDriverwillstart.
AnothertypeofsettingintheGUIisthedevelopersettings.
GeneralSettingsClickonthesecondiconintheGUItoopenthedevelopersettings.ThisalsocategorizesthefieldsintoheadingssuchasServerandLogging,asshowninthefollowingscreenshot:
Server
TheServerpanecontainsthefieldslistedinthefollowingtable,alongwiththeirdescriptions:
Field Description
ServerAddress TheIPaddressofthesystemonwhichtheAppiumserverisrunning.
Port TheportonwhichtheAppiumserverwilltalktotheWebDrivercommands.Thesystemtakesthedefaultport4723.
CheckforUpdates Ifyouclickonthis,thenAppiumwillautomaticallycheckforversionupdates.
Pre-LaunchApplication ThiscapabilitywilllaunchtheapplicationinthedevicebeforeitstartslisteningcommandsfromtheWebDriver.
OverrideExistingSession CheckingthiswilloverridetheAppiumsessions,iftheyexist.
UseRemoteServer IftheAppiumserverisrunningonanothermachine,thenyoucanusethisfunctionalitytoconnecttheAppiumInspector.
SeleniumGridConfigurationFile YoucanmentiontheSeleniumGridconfigurationfile’spath.
Logging
TheLoggingpanecontainsthefieldslistedinthefollowingtable,alongwiththeirdescriptions:
Field Description
QuietLogging Thiswillpreventaverboseloggingoutput.
ShowTimestamps Theconsoleoutputwillbedisplayedalongwithtimestamps.
LogtoFile Thelogoutputwillbestoredinthementionedfile(Forexample,C:\\appium\\abc.log).
LogtoWebHook ThelogoutputwillbesenttotheHTTPlistener.
UseLocalTimezone
Byclickingonthisoption,youcanuseyourlocaltimezone,otherwiseitwillusethenodeserver’stimezone.
DevelopersettingsIfyouclickonthehighlightedicon(shownhere)intheGUI,youwillgetthefollowingscreen:
TheDeveloperSettingspanewillcontaintheoptionslistedinthefollowingtable:
Field Description
Enabled Developersettingswillbedisplayediftheboxischecked.
UseExternalNodeJSBinary
IfyouhaveanotherNode.jsversioninsteadoftheapplicationitselfsuppliedhere,AppiumwillusethesameversionofNode.js.
UseExternalAppiumPackage YoucansupplytheAppiumpackagehere,ifyouhaveanotherone.
NodeJSDebugPort TheNode.jsdebuggingportiswherethedebuggerwillrun.
BreakonApplicationStart Whentheapplicationstarts,theNode.jsdebugserverwillbreak.
CustomServerFlags Here,youcanpasstheserverflags(Forexample,--device-nameNexus5).
AboutClickingonthisiconwilldisplaytheAppiumversionyouareusing,asshowninthefollowingscreenshot:
Now,let’stakealookattheAppiumInspector.
InspectorAppiumInspectorallowsustofindtheelementsthatwearelookingfor.ItalsocomeswitharecordandplaybackfunctionalitysimilartothatoftheSeleniumIDE,butcurrently,itdoesnotworkwellwithWindows.ToopentheInspector,wehavetoclickonthehighlightedicon,asshowninthefollowingscreenshot,butfirstapplicationshouldbeprelaunchedonthedevice:
ByusingtheInspector,wecangetthesourcecodeofaparticularapplication,butitishardtorecognizetheappelements.OnWindows,UIAutomatorismorepowerfulthanAppiumInspectorforinspectingtheelements.Inthenextchapter,wewilllearnmoreabouttheUIAutomator.
TheLaunch/Stopbutton
ThisisusedtostartandstoptheAppiumserver,whichisshowninthefollowingscreenshot:
TheClearbutton
Wecanfindthisbuttoninthebottom-rightcorneroftheserverscreen;itisusedtoclearconsolelogs.
TheAppiumGUIforMacSimilarly,MacalsohasanAppiumGUIforAndroidautomation;alotofoptionsarecommonwithWindows.Let’sdiscussallthesettingsthatarepresentintheGUI.ThefollowingisthescreenshotoftheAppiumGUIonMac
Itcontainsthefollowingicons:
AndroidSettingsiOSSettingsGeneralSettingsDeveloperSettingsRobotSettingsSaveconfigurationOpenconfigurationInspectorAppiumdoctorLaunch/StopDelete
AndroidSettingsWehavealreadyseenAndroidSettingsontheWindowsplatform;thesesettingsarethesameonMacOSaswell,buttherearesomeUIchangesintheAppiumserver,asshowninthefollowingscreenshot.TheAndroidSettingsaredividedintotwotabs,BasicandAdvanced.
iOSSettingsTosetuptheiOS,weneedtoclickontheiOSSettingsicon.Itcontainstwooptions,BasicandAdvanced.UnderBasic,wewillhavethesubheadingsApplicationandDeviceSettings,andunderAdvanced,wewillgettheadvancediOSsettings.
Application
TheoptionspresentundertheApplicationtabarelistedinthefollowingtable,alongwiththeirdescriptions:
Field Description
AppPath Inthisfield,wecanspecifythepathoftheiOSapplication(.app,.zip,or.ipa)thatwewanttotest.
Choose Thisisusedtobrowsethepathoftheapplication.
BundleID ThisdenotesthebundleIDoftheapplication.
UseMobileSafari
Inthecaseofmobilewebapps,wecanselectthisoptiontostarttheSafaribrowser.MakesureBundleIDandAppPathisunchecked.
DeviceSettings
TheoptionspresentundertheDeviceSettingstabarelistedinthefollowingtable,alongwiththeirdescriptions:
Field Description
ForceDevice YoucanselectthesimulatoriPhoneoriPadmodefromthedropdown.
PlatformVersion Thisisusedtoselectthemobileplatformversion.
ForceOrientation Thisisusedtosettheorientationofthesimulator.
ForceLanguage Thisisusedtosetthelanguageforthesimulator.
ForceCalendar Here,wecanchoosethecalendarformatforthesimulator.
ForceLocale Thisdenotesthelocaleforthesimulator.
UDID IftheUDIDboxischecked,thenAppiumwillruntheapplicationontheattachediOSdevice;youneedtomakesurethatbundleIDissuppliedandAppPathisunchecked.
FullReset Thiswilldeletetheentiresimulatorfolder.
NoReset Thisspecifiesthatthesimulatorshouldnotresettheappbetweensessions.
ShowSimulatorLog
Thiswillwritethesimulatorlogintheconsole,ifchecked.
Advanced
TheoptionspresentundertheAdvancedtabarelistedinthefollowingtable,alongwiththeirdescriptions:
Field Description
UseNativeInstrumentsLibrary
Ifthisboxischecked,AppiumwillusetheNativeInstrumentsLibraryratherthanthelibrarythatcomeswithAppium.
BackendRetries WecanspecifythenumbertoretrythelaunchingofInstrumentsbeforethereportingcrashesortimesout.
InstrumentsLaunchTimeout ThisdenotestheamountoftimetowaitfortheInstrumentstolaunch(inms).
TraceTemplatePath ThistracesthetemplatefiletousewithInstruments.
Choose Thisisusedtobrowsethetrace’stemplatepath.
XcodePath ThisdenotesthepathoftheXcodeapplication.
WehavealreadydiscussedGeneralSettings,DeveloperSettings,Launch,andDeletein
AppiumforWindows.Now,let’stakealookatRobotSettings.
RobotSettingsIfyouwantautomationusingarobot,thenyouneedtoenableRobotSettings.InRobotSettings,Appiumwillaskforthehostandportnumberswheretherobotisconnected,asshownhere:
Save/OpenconfigurationAppiumhasafeaturetosavethesettings;wedon’tneedtospecifythesettingsagainandagainwhiletestingtheapps.Itallowsyoutotagtheconfigurationfile,afterwhichyoucaneasilyfindoutthesavedfileonthebasisofthetagcolor.
Tosavetheconfigurationfile,weneedtoperformthefollowingsteps:
1. ClickontheSaveconfigurationicon;thiswillopenthepopup,asshownhere:
2. Specifythefilename:
3. ClickontheTagstextbox;itwilldisplaythelistoftags,asshowninthefollowingscreenshot.Wecanselectmorethanonetag.
4. Selectthelocationwhereyouwanttosavethefile.
Wejustsawhoweasyitistosavetheconfigurationfile.Usingthesavedfile,wecanquicklysettheconfigurationbyclickingontheOpenconfigurationicon(whichisvisibleintheleft-handsideoftheSaveconfigurationicon)andselectingthesavedfile.
AppiumdoctorItwilltellyouabouttheAppiumsetup;youcanverifythesetupusingtheAppiumdoctor.ClickontheDoctorbuttoninbetweentheInspectorandSavebuttons;thiswilldisplaytheinformationintheAppiumGUIconsole,asshownhere:
Ifyougetanyconfigurationerrorthatsomethingisnotbeingsetup,thentrytoresolveitbeforeyoustartwithAppium.
InspectorAppiumcomeswithagreatpieceoffunctionalitysuchantheInspector;itisarecordandplaybacktoollikeSeleniumIDE.Wecaneasilygeneratethetestscriptwithouthurdles.
Itshowsalltheelementsofthemobileapp,likeUIAutomatordoesinAndroid.Now,let’stakealookattheInspector.Here,wearegoingtotakeanexampleoftheBMIcalculatorappiniOS,whichisshowninthefollowingscreenshot.First,weneedtoclickontheSavebuttonbeforeclickingontheInspectorbutton,andwealsoneedtospecifytheapppath.
IntheAppiumInspectorwindow,wecanseethefollowingfields:
ShowDisabled:ThiswilldisplaytheelementsthatarenotenabledRecord:Thiswillopentherecordingpanelinthebottomofthewindow,asshowninthefollowingscreenshot,andyoucanperformactionsusingcontrolsintheAppiumInspector:
Refresh:ThiswillrefreshtheDOM3-columnaswellasthescreenshotScreenshot:Thisareawilldisplaythescreenshottakenfortheapp,andyoucanalso
clickintheareatoselectelementsintheDOMDetails:Thiswillcontaindetailsabouttheselectedelement
YouwillfindsomemoreoptionssuchastheTouchsection,Textsection,Alertssection,Locator,andMisc,whichwillfurthercategorizeintosomebuttonsthatcantakeanactionontheapplicationundertest.
Let’stakealookatthefollowingoptions:
Touch:Thiscontainsbuttonstoexecutetoucheventssuchastap,swipe,shake,andscrollText:Thiscontainsbuttonstoexecutetextevents,suchastypingandfiringtheJavaScriptLocator:ThisisausefuloptionprovidedbyAppium;byusingthis,wecancheckwhethertheelementsexistornotonthebasisoflocators.Misc:Thiscontainsthebuttonsthatcanhandlethealerts
TheRecordingpanelThispanelcontainsthetestscriptsgeneratedbytherecordedactionsthatareperformedontheapplication.Italsocontainssomeoptionsthatwecantakeontherecordedtestscripts.Let’stakealookatthepanel’soptions:
Adropdownforlanguageselection:Youcanchangetherecordedtestscripts’languagefromthedropdown(inthescreenshot,weselectedJava)AddBoilerplate:ThiswilldisplaythecodewiththeSeleniuminstancealongwiththerecordedscripts;otherwise,thiswillonlyshowthecodefromtheactionsyouhaverecordedXPathOnly:ThiswillgeneratethescriptsusingtheXPathidentifieronlyReplay:ByclickingontheReplaybutton,wecanexecutetherecordedscriptsUndo:ThiswilldeletethelastrecordedactionRedo:ThiswilladdthelastundoneactionbackClear:Thiswillcleartherecordedactions
SummaryInthischapter,welearnedabouttheAppiumGUI’sfeaturesonboththeWindowsandiOSplatforms.WealsolookedathowwecansettheAndroidandiOSsettingsusingtheAppiumGUI.
Inthenextchapter,wewilltakelookatdifferentstrategiesforidentifyingelements.
Chapter4.FindingElementswithDifferentLocatorsAppiumhasdifferentlocatorstofindelementsonthemobileappsthatcanbeusedwhiletesting.Inthischapter,wewilldiscusssometechniquestofindanelementfornativeandhybridappsusingtheuiautomatorandAppiuminspector.Tofindanelementforweb-basedapplications,wewillseeaChromeadd-ontoremotelyinspectthewebelements.
Inthischapter,wewilllearnthefollowingtopics:
FindingelementsusingtheChromeADBpluginFindingelementsusingtheSafariDevelopoptionFindingelementsusingUIAutomatorviewerandAppiumInspectorFindingelementsonmobileappsbyid,Name,LinkText,Xpath,cssSelector,ClassName,AccessibilityId,AndroidUIAutomator,andIosUIAutomation
FindingelementsforAndroidweb-basedappsusingtheChromeADBpluginTofindanelementforwebapps,weneedtoinstallanadd-oninordertoremotelyinspectthewebelements.TheChromebrowsergivesusanADB(add-on)toaccessthesourcecodeofthemobileappsremotely.Youcandownloaditfromhttps://chrome.google.com/webstore/detail/adb/dpngiggdglpdnjdoaefidgiigpemgage?hl=en-GB(Makesureyou’veinstalledChromeVersion32orlateronyourdesktop.).
Oncetheadd-onisinstalled,performthefollowingstepstosetupthedeviceforremotedebugging:
1. GotoSettings|AboutPhoneandtaponBuildnumberseventimes(assumingthatyouhaveAndroidVersion4.2ornewer).Then,returntothepreviousscreenandfindDeveloperoptions,asshowninthefollowingscreenshot:
NoteTheprecedingstepisnotthesameforallsmartphones;ifyoucan’tfindthisoption,thensearchHowtoenabledeveloperoptionsonGooglewithyourdevicemodel.
2. TaponDeveloperoptionsandclickonONinthedevelopersettings(youwillgetanalerttoallowdevelopersettings;justclickontheOKbutton);makesurethattheUSBdebuggingoptionischecked:
3. Now,gotoyourdesktopChromebrowser(assumingthatyou’vealreadyinstalledtheADBplugin),clickontheADBpluginicon—whichisinthetop-rightcornerofthescreen—andclickonViewInspectionTargets:
4. UseaUSBcabletoconnectyourAndroiddevicetothedesktop(makesureyou’veinstalledtheappropriateUSBdriverforyourdevice).Afteryouconnect,youwillgetanalertonyourdevicetoallowUSBdebugging;justtaponOK.
5. OpentheChromebrowseronyourdeviceandnavigatetothedesiredURL(wewillopenwww.google.com).
6. Onceyousetupyourdevicefordebugging,thenthechrome://inspect/#devicespagewilldisplayalltheconnecteddevicesalongwiththeopentabsandwebviews.MakesureDiscoverUSBdevicesischecked,asshownhere:
7. Now,clickontheinspectlinktoopenthedevelopertools;youwillgetthefollowingscreen.Now,clickonthescreencasticon,inthetop-rightcorner,todisplayyourdevice’sscreen:
NowwecaneasilyinspectelementswithChromeDevTools.
FindingelementsforiOSweb-basedappsusingSafari’sDevelopoptionSafaricomeswithabuilt-insolutionforfindingtheelementsforwebapps,butweneedtoperformthefollowingstepsinordertosetupthedeviceforremotedebugging:
1. NavigatetoSettings|Safari|Advanced:
2. Then,turnonWebInspector:
3. OpentheSafaribrowseronyourdevice/simulatorandnavigatetothedesiredURL(wearenavigatingtowww.google.com).
4. Now,gotoyourMacSafaribrowser,clickontheDevelopoptionfromthemenu,selectthedevice/simulator(assumingthatthedeviceisconnectedtoyourMac),andclickontheURL:
5. NowyouwillgetthefollowingscreenwiththeHTMLsourcecode:
Now,wecaneasilyinspectelementswithSafariDevTools.
FindingelementsbyIDTointeractwiththewebpage,firstweneedtofindanelementonthepage.AllthefunctionsoftheAppiumclientlibraryneedanelementtoperformtheactionsonthewebpage.
FindinganelementbyIDisusedtolocateonlyoneelementinthemobileapp.Thisishowthemethodsignaturetofindanelementlooks:
findElement(By.id(Stringid));
WeneedtopassanIDoftheelementwewanttointeractwith.Now,wearegoingtofindtheIDofanelementusingtheChromeADBpluginremotely.Here,wehavetakenanexampleoftheGooglesearchpage.Performthefollowingsteps:
1. Navigatetohttps://www.google.comonyourmobile’sChromebrowser.2. ClickontheinspectlinkfromtheADBpluginofyourdesktop’sChromebrowser.3. Clickontheinspectelementicon andmouseoverthesearchbox,asshowninthe
followingscreenshot:
Wecanusethehighlightedidtointeractwiththewebelement.Thisishowthecommandwilllook:
WebElementsearchBox=driver.findElement(By.id("lst-ib"));
Ifyouwanttotypeinthesearchbox,thenyoucanuseawebelementreference;forinstance,youcanuseareferencesuchassearchBox.sendKeys("ManojHans");.
Let’stakethesameexampletofindanelementbyIDontheSafaribrowserinaniOSdevice.Weneedtoperformthefollowingsteps:
1. Navigatetohttps://www.google.comonyourmobileSafaribrowser.2. ClickontheURLunderiOSsimulatorundertheDeveloptaboftheMacSafari
browser.
3. ClickontheInspecticonandthenclickonthesearchboxintheiOSsimulator,asshownhere:
Wecanusethehighlightedidtointeractwiththewebelement.Thisishowthecommandwilllook:
WebElementsearchBox=driver.findElement(By.id("lst-ib"));
Ifyouwanttotypeinthesearchbox,thenyoucanuseawebelementreference,suchassearchBox.sendKeys("ManojHans");.
FindingelementsbynameAnotherwaytofindanelementisbytheirname;elementscanhavenamestolocatethem.Thisishowthemethodsignaturewilllook:
findElement(By.name(StringName));
Sameasinthecaseofid,weneedtopassthenameattributeoftheelementwewanttolookfor.ItwillreturnaWebElementobjectthatwecanperformactionson.WecanagaintakeanexampleoftheGooglesearchpage,asthesearchboxalsohasaname.Allthestepswillbethesameastheoneswe’vetakentofindanelementbyID,asshowninthefollowingscreenshot:
Thisishowthecommandwilllook:
WebElementsearchBox=driver.findElement(By.name("q"));
FindingelementsbylinkTextThismethodisusefulwhenyouwanttolocatetheelementthathasahyperlink.Thisishowthemethodsignaturelooks:
findElement(By.linkText(Stringtext));
Weneedtopassthetextthathasahyperlink.ItwillreturnaWebElementobjectthatwecanperformactionson.AllthestepstolocatetheelementwillbethesameasthestepsperformedtofindanelementbyID.
WearegoingtofindtheImagestextontheGooglesearchpagethathavealink;thisishowthecommandwilllook:
WebElementimagesLink=driver.findElement(By.linkText("Images"));
FindingelementsbyXpathXpathworksonbothXMLandwell-formedHTMLstructurestofindelements.Itisabitslower(inthecaseswhereyougenerateditinacomplexmanner)thantheIDandnamemethods,butitisaveryusefulapproachtofindanelementonthewebpagewheretheelementIDisgenerateddynamically.Here,wearenotgoingtoteachyouaboutXpath,butifyouwanttolearnabouttheXpathstrategy,thenyoucansearchGoogleforatutorial.Thisishowthemethodsignaturewilllook:
findElement(By.xpath(StringXPath));
WeneedtopasstheXpathoftheelementwewanttolookfor.ItwillreturnaWebElementobjectthatwecanperformactionson.Here,wewillconstructtheXpathonthebasisofattributes.
WearegoingtoconstructanXpathoftheGooglesearchbox;thisishowthecommandwilllook:
WebElementsearchBox=driver.findElement(By.xpath("//input[@id='lst-ib']"));
FindingelementsbycssSelectorcssSelectorstrictlyoperatesonHTML,anditisfasterthanXpathinfindinganelementonthewebpage.Thisishowthemethodsignaturewilllook:
findElement(By.cssSelector(StringcssSelector);
WeneedtopassthecssSelectoroftheelementwewanttolookfor.ItwillreturnaWebElementobjectthatwecanperformactionson.Here,wewillconstructthecssSelectoronthebasisofattributes.
WearegoingtoconstructcssSelectoroftheGooglesearchbox;thisishowthecommandwilllook:
WebElementsearchBox=driver.findElement(By.cssSelector("#lst-ib"));
FindingelementsfornativeandhybridappsTherearemultiplewaystofindanelementfornativeandhybridapps,suchasUIAutomatorviewer(forAndroidonly)andAppiumInspector(forbothAndroidandiOS).Let’sstartwiththeuiautomator.
FindingelementswithUIAutomatorviewerWecanfindtheUIAutomatorviewerintheAndroidSDKfolderC:\android-sdk\tools(assumingthattheSDKlocatedintheCdrive);youcanfindthesameinMacaswellunderthetoolsfolder,asshowninthefollowingscreenshot:
Toopenuiautomatorviewer,youneedtodouble-clickonit.Youwillgetthefollowingscreen:
Now,wearegoingtotakeanexampleoffindinganelementoftheAndroidappcalculator.Weneedtoperformthefollowingsteps:
1. OpentheAndroidemulatororrealdevice(Forarealdevice,weneedtoenableUSBdebugging).
2. Openthecalculatorapp.3. Now,clickonthedevice’sscreenshoticon fromtheUIAutomatorViewer
window(Theprogressinformationboxwillbevisible.).Ifmorethanonedeviceisrunning,thenUIAutomatorviewerwillaskyoutoselectthedevicetocapturethescreenshot.Thefollowingisthescreenshotofthecalculator.
Youwillgetthescreenshotofthecalculatorsuccessfully.
Now,it’stimetofindanelementwithdifferentlocatorssupportedbytheAppiumdriver.
FindingelementsbyIDThemethodsignaturewillbethesameastheonewesawearliertofindanelementbyIDforwebapps:
findElement(By.id(Stringid));
WeneedtopasstheIDoftheelementwewanttointeractwith.Here,wearegoingtofindthedigit5fromthecalculatorappusingUIAutomatorViewer.Weneedtoperformthefollowingsteps:
1. Clickonthedigit5fromUIAutomatorViewer.2. UnderNodeDetails,youwillgetresource-idas
com.android.calculator2:id/digit5:
3. Wecanuseresource-idasanIDtoperformanactiononthedigit5.Thisishowthecommandwilllook:
WebElement
digit_5=driver.findElement(By.id("com.android.calculator2:id/digit5"));
4. Toclickonthedigit5,wecanusethefollowingcommand:
digit_5.click();
FindingelementsbynameThemethodsignaturewillbethesameastheonewesawearliertofindanelementbynameforwebapps:
findElement(By.name(StringName));
Weneedtopassthenameoftheelementwewanttointeractwith.Here,wearegoingtofindtheDELETEbuttonfromthecalculatorappusingUIAutomatorViewer.Weneedtoperformthefollowingsteps:
1. ClickonDELETEfromUIAutomatorViewer.2. UnderNodeDetails,youwillgetthetextasDELETE,asshownhere:
WecanusetheDELETEtexttolocatetheDELETEbuttonasName.Thisishowthecommandwilllook:
WebElementdelete=driver.findElement(By.name("DELETE"));
3. ToclickontheDELETEbutton,wecanusethefollowingcommand:
delete.click();
FindingelementsbyclassNameWecanfindanelementusingtheclassNamelocatoraswell.Thisishowthemethodsignaturelooks:
findElement(By.className(StringClassName));
WeneedtopasstheclassNameoftheelementwewanttointeractwith.Here,wearegoingtofindtheEditBoxfromthecalculatorappusingUIAutomatorViewer.Weneedtoperformthefollowingsteps:
1. ClickonEditBoxfromUIAutomatorViewer.2. UnderNodeDetail,youwillgettheclassasandroid.widget.EditText:
3. WecanuseclassasclassNametoperformanactiononEditBox.Thisishowthecommandwilllook:
WebElement
editBox=driver.findElement(By.className("android.widget.EditText"));
4. TogetthevaluefromtheEditBox,wecanusethefollowingcommand:
editBox.getText();
Ifthesameclassisusedformultipleelements,thenweneedtoselectanelementonthebasisofindexing.Forexample,ifwewanttoselectthedigit7onthebasisofclassName,thenthisishowthecodewilllook:
List<WebElement>
editBox=driver.findElements(By.className("android.widget.Button"));
editBox.get(1).click();
WeareusingfindElementsinplaceoffindElementintheprecedingcode;theprecedingcodewillreturnmorethanonevalue.Here,thedigit7hasanindexvalue1,sowehavetopassanindexvalueof1totakeanaction.
FindingelementsbyAccessibilityIdTheAppiumdeveloperswantedtogiveusmoreoptionstolocateanelement,sotheycreatedAccessibilityId.Itlocatestheelement,sameasIDandname.ThisishowthemethodsignatureforAccessibilityIdlooks:
findElement(By.AccessibilityId(StringAccId));
WeneedtopassanAccIdoftheelementwewanttointeractwith.Here,wearegoingtofindthe+signfromthecalculatorappusingUIAutomatorViewer.Weneedtoperformthefollowingsteps:
1. Clickonthe+signfromUIAutomatorViewer.2. UnderNodeDetails,youwillgetthecontent-descasplus:
3. Wecanusecontent-descasAccIdtoperformanactiononthe+sign.Thisishowthecommandwilllook:
WebElementplusSign=driver.findElementByAccessibilityId("plus");
4. Toclickonthe+sign,wecanusethefollowingcommand:
plusSign.click();
FindingelementsbyAndroidUIAutomatorAndroidUIAutomatorisaverypowerfullocatortofindanelement.ItusestheAndroidUIAutomatorlibrarytofindanelement.Themethodsignaturelookslikethis:
findElement(By.AndroidUIAutomator(StringUIAuto));
WeneedtopasstheUIAutoofanelementthatwewanttointeractwith.Here,wearegoingtofindthe=signfromthecalculatorappusingUIAutomatorViewer.Weneedtoperformthefollowingsteps:
1. Clickonthe=signfromUIAutomatorViewer.2. UndertheNodedetails,wecanpickanyofthevalues.Forexample,resource-idas
com.android.calculator2:id/equal.Wecanuseresource-idasUIAutotoperformanactiononthe=sign.Thisishowthecommandwilllook:
WebElementequal=driver.findElementByAndroidUIAutomator("new
UiSelector().resourceId(\"com.android.calculator2:id/equal\")";
3. Toclickonthe=sign,wecanusethefollowingcommand:
equal.click();
4. Anotherexampleistopickcontent-descasequals,sothecommandwilllooklikethis:
WebElementequal=driver.findElementBy.AndroidUIAutomator("new
UiSelector().description(\"equals\")");
NoteIfyouwanttofindoutmoreabouttheUIAutomatorlibrary,thenitmightbehelpfultocheckouthttp://developer.android.com/tools/testing/testing_ui.htmlandhttp://developer.android.com/tools/help/uiautomator/UiSelector.html.
FindingelementswithAppiumInspectorWelearnedinanearlierchapterthatAppiumInspectorworkswellontheMacplatform.So,wewillnowuseitonMactofindelements.
TostarttheAppiumInspectorforAndroid,weneedtoperformthefollowingsteps:
1. Weneedtospecifythepathoftheapplication,package,andactivitynameintheAppiumGUIincaseofanemulator.Inthecaseofarealdevice,thepackageandactivitynameissufficient.
NoteFromwherecanyoufindoutaboutthepackageandactivitynameoftheappiftheappisrunningonaphysicaldevice?
YoucaninstalltheAPKInfoappfromthePlayStore(https://play.google.com/store/apps/details?id=de.migali.soft.apkinfo&hl=en)toknowaboutthepackageandactivitynameoftheapp.Ifyouhaveanapponyourdesktop,thentheAppiumserverwillautomaticallyretrievethepackageandactivitynameoncetheapp’spathisspecified.
2. ThePrelaunchApplicationoptionshouldbecheckedunderGeneralSettings.3. Ifyouareworkingwithanemulator,thenitshouldbeopenortheLaunchAVD
optionshouldbecheckedunderAndroidSettings(assumingthatyouhavecreatedtheemulator).Ontheotherhand,ifyouareworkingwitharealdevice,thenthedeviceshouldbeconnectedandtheUSBdebuggingoptionshouldbechecked.
4. ClickontheLaunchbutton.5. ClickontheInspectoricon.Now,AppiumInspectorwillbelaunched,asshownin
thefollowingscreenshot.Again,let’staketheexampleofthecalculatorapp.
WehavealreadyseenalotofwaystofindanelementinUIAutomatorViewer;nowwearegoingtofindanelementwithXpath.
FindingelementsbyXpathXpathisbitslowerthantheIDandnamemethods,butitisaveryusefulapproachtofindanelement.Themethodsignaturewilllooklikethis:
findElement(By.xpath(StringXPath));
WeneedtopasstheXpathoftheelementwewanttolookfor.ItwillreturnaWebElementobjectthatwecanperformactionson.
WearegoingtousetheXpathofthedigit9;thisishowthecommandwilllook:
WebElement
digit_9=driver.findElement(By.xpath("//android.widget.LinearLayout[1]/
android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/
android.support.v4.view.viewPager[1]/android.widget.LinearLayout[1]/
android.widget.LinearLayout[1]/android.widget.Button[3]"));
YoucanusetheWebElementreference,digit_9,toperformanactiononthedigit9,whichhasbeenshownintheprecedingscreenshot.
WelearnedhowtofindanelementonAndroiddevices.Now,itistheturntoiOS.TostarttheAppiumInspectorforiOS,weneedtoperformthefollowingsteps:
1. WeneedtospecifythepathoftheapplicationintheAppiumGUI.2. ThePrelaunchApplicationoptionshouldbecheckedunderGeneralSettings.3. Ifyouareworkingwithasimulator,thenitshouldbeopenortheForceDevice
optionshouldbecheckedunderiOSSettingsandthenyouhavetochoosethedesirediOSsimulator.Ontheotherhand,ifyouareworkingwitharealdevice,thenthedeviceshouldbeconnectedandthedeviceUDIDshouldbespecified.
4. ClickontheLaunchbutton.5. ClickontheInspectoricon.
Here,wearegoingtotakeanexampleofTestApp,whichyoucandownloadfromtheAppiumGitHubrepository(https://github.com/appium/appium/blob/master/assets/TestApp7.1.app.zip?raw=true).ThankstoAppiumdevelopersforcreatingTestApp.
FindingelementsbynameThemethodsignaturewillbethesameaswetheonewesawearliertofindanelementbynameforwebapps:
findElement(By.name(StringName));
Weneedtopassthenameoftheelementwewanttointeractwith.Here,wearegoingtofindthesecondEditBoxfromtheTestAppusingtheAppiumInspector.Weneedtoperformthefollowingsteps:
1. ClickonthesecondEditBoxfromtheAppiumInspector.2. UndertheDetailstabyouwillgetthenameasIntegerB.WecanusenameasName
toidentifythe2ndEditBox.Thecommandwilllooklikethis:
WebElementeditBox=driver.findElement(By.name("IntegerB"));
3. TotypeintheEditBox,wecanusethefollowingcommand:
editBox.sendKeys("12");
FindingelementsbyIosUIAutomationUIAutomationisaJavaScriptlibrarythatisusedtofindanelementinApple’sAutomationInstruments.AppiumdevelopershavegivenusasimilarwaytofindanelementinAppiumusingIosUIAutomation.Thisishowthemethodsignaturelooks:
findElements(By.IosUIAutomation(StringIosUIAuto));
WeneedtoperformthefollowingstepsifwewanttousetheIosUIAutomation:
1. WeneedtopasstheIosUIAutovalueofanelementwewanttointeractwith.Here,wearegoingtofindthefirstEditBoxfromtheTestAppusingApple’sUIAutomationlibrary.
Forexample,tofindanelementonthebasisoftheUIAutomationlibraryusingelementsfunction,itwillreturnanelementsarray.Wecanfindtheelementusinganindex.
Thecommandwilllooklikethis:
WebElementeditBox=driver.findElements(By.IosUIAutomation(".elements()
[0]"));//Here'0'isanelementindex
2. TotypeinthefirstEditBox,wecanusethefollowingcommand:
editBox.sendKeys("10");
3. AnotherexampleistofindtheelementonthebasisofthetextFieldsobject,wherethecommandwilllooklikethis:
WebElementeditBox=driver.
findElements(By.IosUIAutomation(".textFields()[0]"));
NoteIfyouwanttoexploretheUIAutomationlibrarymore,thenitmightbehelpfultovisithttps://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAElementClassReference/index.html#//apple_ref/doc/uid/TP40009903-CH1-SW6.
SummaryWelearnedalotabouthowtofindanelementusingdifferentlocatorsandtechniques.Specifically,welearnedhowtoremotelyopentheFirebugformobilewebappstolocatethewebelementswithdifferenttypeoflocatorsandalsohowUIAutomatorViewercanbeusedtofindelements.WethenmovedontosearchingforelementsusingAppiumInspector,ID,name,Xpath,cssSelector,className,AccessibilityId,AndroidUIAutomator,and,lastbutnotleast,IosUIAutomation.
Welearnedalotaboutfindinganelement;nowit’stimetostartautomatingmobileapps.InthenextchapterwewillworkwiththeAppiumdriver.
Chapter5.WorkingwithAppiumNow,wearegoingtostartworkingwithAppiumondifferentmobileapps.Wewillbeacquaintedwithemulators/simulatorstoautomatemobileappsbyAppium.Wewilltakealookathowtoinstallappsfromacomputertoanemulator,movingontocallingtheChromebrowserinanAndroidemulatortosetupthedesiredcapabilitiesandtestwebapplications.Then,wewilllearnhowtostarttheSafaribrowserinasimulatorandsetupthedesiredcapabilitiestotestwebapplications.Wewillalsotakealookathowtowriteautomationscriptsfornativemobileapps.Lastly,wewillautomatethehybridappsandswitchfromnativetowebview.
Inthischapter,wewilllearnthefollowingtopics:
TheautomationofnativeappsTheautomationofhybridappsWorkingwithwebappsandanativebrowserWorkingwithwebappsandSafari
ImportantinitialpointsBeforestartingwithAppium,let’smakesurethatwehaveallthenecessarysoftwareinstalled.
TheprerequisitesforAndroidareasfollows:
Java(version7orlater)TheAndroidSDKAPI(version17orlater)AnemulatorEclipseTestNGTheAppiumserverTheAppiumclientlibrary(Java)TheSeleniumServerandWebDriverJavalibraryTheAPKInfoapp
TheprerequisitesforiOSareasfollows:
MacOS10.7orlaterXcode(version4.6.3orlater;5.1isrecommended)SimulatorSafarionsimulatorJavaVersion7EclipseTestNGTheAppiumServerTheAppiumclientlibrary(Java)TheSeleniumServerandWebDriverJavalibrary
WhenworkingwithAppium,weneedtosetthedesiredcapabilitiesandinitiateanAndroid/iOSdriver.First,weneedtounderstandthemonebyone.
NecessarydesiredcapabilitiesforAndroidandinitiatingtheAndroiddriverTherearetwowaystosetthedesiredcapabilities,onewiththeAppiumGUIandanotherbyinitiatingthedesiredcapabilitiesobject.Desiredcapabilitiesobjectwillbemorepreferable,otherwisewehavetochangethedesiredcapabilitiesintheGUIagainandagainwheneverwearetestinganothermobileapp.Let’sdiscussboththeseways.
Let’sseetheAndroidSettingsintheAppiumGUIsettingsfornativeandhybridapps:
Herearethestepsyouneedtoperformfornativeandhybridapps:
1. ClickontheAndroidSettingsicon.2. SelectApplicationpathandprovidethepathoftheapplication.3. SelectPackageandchooseitfromthedrop-down.4. SelectLaunchActivityandchooseanactivityfromthedrop-down.
NoteIfanapplicationisalreadyinstalledontheAVD,thenwedon’tneedtofollowsteps
2–4.Inthiscase,wehavetoinstalltheAPKinfoappontheAVDtoknowaboutthepackageandtheactivitiesoftheappandthensetthemusingthedesiredcapabilitiesobject(whichwewillseeinthenexttopic).
Here,thequestionishowtoinstallAPKintheemulator?Simplyperformthefollowingsteps:
1.Starttheemulator.
2.OpenCommandPrompt.
3.Typeadb-einstall[pathoftheapk].Forexample,adb–einstallc:\app\apkinfo.apk.
4.ClickontheEnterbutton;postthis,youwillgetasuccessmessage.
YouaredonewiththeAPKinstallation!
5. SelectLaunchAVDandchooseacreatedemulatorfromthelist.6. SelectPlatformVersionfromthedrop-downmenu.7. SelectDeviceNameandtypeAndroidemulator.8. Now,starttheAppiumServer.
Let’sseetheAndroidSettingsintheAppiumGUIsettingsforwebapps:
Herearethestepsthatyouneedtoperformforwebapps:
1. ClickontheAndroidSettingsicon.2. SelectLaunchAVDandchooseacreatedemulatorfromthelist.3. SelectPlatformVersionfromthedrop-down.4. SelectUseBrowserandchooseBrowserfromthedrop-down.5. SelectDeviceNameandtypeAndroidemulator.6. Now,starttheAppiumserver.
Let’sdiscusshowtoinitiatethedesiredcapabilitiesobjectandsetthecapabilities.
DesiredcapabilitiesfornativeandhybridappsWealreadydiscussedthedesiredcapabilitiesinChapter1,Appium–ImportantConceptualBackground,soherewewilldirectlydiveintothecodewithcomments.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesforthenativeandhybridapps,asshownhere:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
Fileapp=newFile("pathoftheapk");//Tocreatefileobjecttospecifythe
apppath
caps.setCapability(MobileCapabilityType.APP,app);//Ifappisalready
installedontheAVDthennoneedtosetthiscapability.
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");//Toset
theAndroidversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");//Toset
theOSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Android
emulator");//TosettheDevicename
caps.setCapability("avd","NameoftheAVDtolaunch");//TospecifytheAVD
whichwewanttolaunch
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"packagenameofyour
app(youcangetitfromapkinfoapp)");//Tospecifytheandroidapp
package
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,"Launchactivityof
yourapp(youcangetitfromapkinfoapp)");//Tospecifytheactivity
whichwewanttolaunch
DesiredcapabilitiesforwebappsInAndroidmobilewebapps,someofthecapabilitiesthatweusedinnativeandhybridappssuchasAPP,APPPACKAGE,andAPPACTIVITYarenotrequiredbecausewearelaunchingabrowserhere.Weneedtoimportthefollowingpackages:
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesforthewebapps,asfollows:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");//Toset
theandroidversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");//Toset
theOSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Android
emulator");//Tosetthedevicename
caps.setCapability("avd","NameoftheAVDtolaunch");//TospecifytheAVD
whichwewanttolaunch
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Browser");//To
launchtheNativebrowser
Wearedonewiththedesiredcapabilitiespart;now,wehavetoinitiatetheAndroidDrivertoconnectwiththeAppiumserver,butfirstweneedtoimportthefollowingpackages:
importio.appium.java_client.android.AndroidDriver;
importjava.net.URL;
Then,initiatetheAndroidDriver:
AndroidDriverdriver=newAndroidDriver(new
URL("http://127.0.0.1:4723/wd/hub"),caps);
ThiswilllaunchtheappintheAndroidemulatorusingtheconfigurationsspecifiedinthe
desiredcapabilities.
Now,youcanusethefollowingclasstowritethetestscriptswithTestNG:
importio.appium.java_client.android.AndroidDriver;
importio.appium.java_client.remote.MobileCapabilityType;
importjava.io.File;
importjava.net.MalformedURLException;
importjava.net.URL;
importjava.util.concurrent.TimeUnit;
importorg.openqa.selenium.remote.DesiredCapabilities;
importorg.testng.annotations.AfterClass;
importorg.testng.annotations.BeforeClass;
importorg.testng.annotations.Test;
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
//Setupdesiredcapabilities
DesiredCapabilitiescaps=newDesiredCapabilities();
Fileapp=newFile("pathoftheapk");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Androidemulator");
caps.setCapability("avd","NameoftheAVDtolaunch");
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"packagenameof
yourapp(youcangetitfromapkinfoapp)");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,"Launchactivityof
yourapp(youcangetitfromapkinfoapp)");
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Browser");//In
caseofwebapps
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
//Wewillputtestscriptshere
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();//CloseApp()functionisusedtoclosethemobile
nativeandhybridappswhilequit()andclose()isusedforwebapps
}
}
NecessarydesiredcapabilitiesforiOSandinitiatingtheiOSdriverSameasAndroid,wecansetthedesiredcapabilitiesusingtheAppiumGUIandbyinitiatingthedesiredcapabilitiesobject.Let’sdiscussboth.
iOSSettingsintheAppiumGUIsettingsfornativeandhybridapps:
Herearethestepsyouneedtoperformfornativeandhybridapps:
1. ClickontheiOSSettingsicon.2. SelectAppPathandprovidethepathoftheapplication.3. SelectForceDeviceandchooseasimulatorfromthelist.4. SelectPlatformVersionfromthedropdownoryoucanalsotypeinaversion(for
example,8.1).5. Now,starttheAppiumServer.
Let’sseetheiOSSettingsinAppiumGUIsettingsforwebapps:
Herearethestepsyouneedtoperformforwebapps:
1. ClickontheiOSSettingsicon.2. SelectUseMobileSafari.3. SelectForceDeviceandchooseasimulatorfromthelist.4. SelectPlatformVersionfromthedropdownoryoucanalsotypeinavalue(for
example,8.1).5. Now,starttheAppiumserver.
Let’sdiscusshowtoinitiatethedesiredcapabilitiesobjectandsetthecapabilities.
DesiredcapabilitiesfornativeandhybridappsWealreadydiscussedthedesiredcapabilitiesforiOSinChapter1,Appium–ImportantConceptualBackground,soherewewilldirectlydiveintothecodewithcomments.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesfornativeandhybridapps:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
ofdesiredcapabilities
Fileapp=newFile("pathofthe.app");//Tocreateafileobjecttospecify
theapppath
caps.setCapability(MobileCapabilityType.APP,app);//Tosettheapppath
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");//Toset
theiOSversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");//Tosetthe
OSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPhone5");//Type
validsimulatornameotherwiseappiumwillthrowanexception
DesiredcapabilitiesforwebappsIniOSmobilewebapps,someofthecapabilitiesthatweusedinnativeandhybridappssuchasAPP,APPPACKAGE,andAPPACTIVITYarenotrequiredbecausewearelaunchingabrowserhere.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapacitiesforthewebapps,asshownhere:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
ofdesiredcapabilities
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");//Toset
theiOSversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");//Tosetthe
OSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPhone5");//Type
validsimulatornameotherwiseAppiumwillthrowanexception
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");//To
launchtheSafaribrowser
Wearedonewiththedesiredcapabilitiespart;now,wehavetoinitiatetheiOSDrivertoconnectwiththeAppiumserver,butfirstweneedtoimportthefollowingpackages:
importio.appium.java_client.ios.IOSDriver;
importjava.net.URL;
Then,initiatetheiOSDriver:
IOSDriverdriver=newIOSDriver(new
URL("http://127.0.0.1:4723/wd/hub"),caps);
Thiswilllaunchtheappinthesimulatorusingtheconfigurationsspecifiedinthedesiredcapabilities.
Now,youcanusethefollowingclassfortestscriptswithTestNG:
importio.appium.java_client.ios.IOSDriver;
importio.appium.java_client.remote.MobileCapabilityType;
importjava.io.File;
importjava.net.MalformedURLException;
importjava.net.URL;
importjava.util.concurrent.TimeUnit;
importorg.openqa.selenium.remote.DesiredCapabilities;
importorg.testng.annotations.AfterClass;
importorg.testng.annotations.BeforeClass;
importorg.testng.annotations.Test;
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
//Setupdesiredcapabilities
DesiredCapabilitiescaps=newDesiredCapabilities();
Fileapp=newFile("pathofthe.app");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPhone5");
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");//In
caseofwebapps
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
//Wewillputtestscriptshere
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();//Incaseofnativeandhybridapp
//driver.quit();//Incaseofwebapps
}
}
AutomatingnativeappsNativeappsarebasicallydevelopedforaparticularplatform,andtheycantakeanadvantageofthedevice’sfeatures.Theycanworkoffline.Youcaninstallanativeappdirectlyontothedeviceorthroughanapplicationstore,suchasGooglePlayorAppleAppStore.
NativeAndroidappsHere,wearegoingtotakeanexampleoftheAndroidcalculatorapp,andinthissection,wewilltakealookattheadditionoftwonumbers.
Performthefollowingstepstoautomatethecalculatorapp:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchthecalculatorapp:
caps.setCapability("avd","AVD_Nexus_4");//MentionthecreatedAVDname
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.calculator2");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.calculator2.Calculator");
2. Now,weneedtofindthenumbers;wearegoingtofindthembyname:
WebElementfive=driver.findElement(By.name("5"));
WebElementfour=driver.findElement(By.name("4"));
3. Weneedtofindthe+signandthe=sign;wearegoingtofindthembynameandAccessabilityID,respectively:
WebElementplus=driver.findElement(By.name("+"));
WebElementequalTo=driver.findElementByAccessibilityId("equals"));
4. Now,weneedtoperformclickontheelement:
five.click();
plus.click();
four.click();
equalTo.click();
5. RunyourscriptusingTestNG;itshouldlooklikethefollowingblockofcode:
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Android
emulator");
caps.setCapability("avd","AVD_Nexus_4");//MentionthecreatedAVD
name
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.calculator2");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.calculator2.Calculator");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementfive=driver.findElement(By.name("5"));
five.click();
WebElementplus=driver.findElement(By.name("+"));
plus.click();
WebElementfour=driver.findElement(By.name("4"));
four.click();
WebElementequalTo=driver.findElementByAccessibilityId("equals"));
equalTo.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
NativeiOSappsHere,wearegoingtotakeanexampleofaniOSTestApp;youcangetitfromhttps://github.com/manojhans/Appium/blob/master/Application/iOS/Native/TestApp7.1.app.zip?raw=true.Afterdownloadingit,extractittoalocalfolder(forexample,/Users/mhans/appium/ios/TestApp.app).Thedownloadedappwilllooklikethefollowingscreenshot:
Inthissection,wewilltakealookattheadditionoftwonumbers.Todothis,performthefollowingsteps:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchtheTestApp:
Fileapp=newFile("/Users/mhans/appium/ios/TestApp.app");//Youcan
changeitwithyourappaddress
caps.setCapability(MobileCapabilityType.APP,app);
2. Now,wehavetofindelementstobetypedin;wearegoingtofindthembyname:
WebElementeditBox1=driver.findElement(By.name("TextField1"));
WebElementeditBox2=driver.findElement(By.name("TextField2"));
3. Now,weneedtofindthecomputebutton;wearegoingtofinditbyAccessibilityID:
WebElementcomputeSumBtn=driver.findElementByAccessibilityId("Compute
Sum"));
4. Now,typeavalueinthefirstbox:
editBox1.sendKeys("10");
5. Typeavalueinthesecondbox:
editBox2.sendKeys("20");
6. Now,clickontheComputeSumbutton:
computeSumBtn.click();
7. RunyourscriptusingTestNG;itshouldlooklikethefollowingcode:
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
Fileapp=newFile("/Users/mhans/appium/ios/TestApp.app");//Youcan
changeitwithyourappaddress
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPhone5");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementeditBox1=driver.findElement(By.name("TextField1"));
editBox1.sendKeys("10");
WebElementeditBox2=driver.findElement(By.name("TextField2"));
editBox2.sendKeys("20");
WebElementcomputeSumBtn=driver.findElementByAccessibilityId("Compute
Sum"));
computeSumBtn.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
Workingwithweb-appsWebappscanberunonanydeviceorplatform;theonlyrequirementisawebbrowserandanInternetconnection.Thebestpartisthatyoudon’tneedtoinstallweb-appsonthedevice.Theyaregenerallydesignedwithcross-browsercompatibilityinmind.
WebappsonAndroidWearegoingtotakeanexampleoftheGooglesearchpage.
Inthissection,wearegoingtotakealookathowtoloadthenativebrowseronanemulatorandthentypedataintheGooglesearchbox.Initially,wewillgetthenativebrowserasshowninfollowingscreenshot:
PerformthefollowingstepstoloadthenativebrowseronanemulatorandthentypedataintheGooglesearchbox:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchthenativebrowser:
caps.setCapability("avd","AVD_Nexus_4");//MentionthecreatedAVDname
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Browser");
2. Now,weneedtonavigatetohttps://www.google.comusingthefollowingcommand:
driver.get("https://www.google.com");//Onwebappsweneedtonavigate
theurltotestthedesiredwebsite
3. WeneedtofindthesearchBoxelement;inthissection,wearegoingtofindanelementbyname:
WebElementsearchBox=driver.findElement(By.name("q"));
4. Now,weneedtypeinthesearchbox:
searchBox.sendKeys("Appiumformobileautomation");
5. RunyourscriptusingTestNG;itshouldlooklikethefollowingblockofcode:
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Browser");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Android
emulator");
caps.setCapability("avd","AVD_Nexus_4");//MentionthecreatedAVD
name
driver=newAndroidDriver(new
URL("http://127.0.0.1:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
driver.get("https://www.google.com");
WebElementsearchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appiumformobileautomation");
}
@AfterClass
publicvoidtearDown(){
driver.quit();
}
}
Inthenextsection,wewillseehowthesametestscriptsrunondifferentplatforms;weonlyneedtochangethedesiredcapabilities,whichfulfillthepurpose(cross-platformtesting)ofusingAppium.
WebappsoniOSWearegoingtotaketheexampleoftheGooglesearchpage.Inthissection,wearegoingtotakealookathowtoloadthebrowseronthesimulatorandthentypedataintheGooglesearchbox.Initially,wewillgettheSafaribrowserinsimulatorasshowninthefollowingscreenshot:
1. PerformthefollowingstepstoloadthebrowseronthesimulatorandthentypedataintheGooglesearchboxUpdatethedesiredcapabilitiesinthesetup()methodtolaunchtheChromebrowser:
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");
2. Now,weneedtonavigatetohttps://www.google.comusingthefollowingcommand:
driver.get("https://www.google.com");
3. WeneedtofindasearchBoxelement;inthissection,wearegoingtofindanelementbyname:
WebElementsearchBox=driver.findElement(By.name("q"));
4. Typethefollowinginthesearchbox:
searchBox.sendKeys("Appiumformobileautomation");
5. RunyourscriptusingTestNG;itshouldlooklikethefollowingblockofcode:
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPhone5");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
driver.get("https://www.google.com");
WebElementsearchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appiumformobileautomation");
}
@AfterClass
publicvoidtearDown(){
driver.quit();
}
}
Hybridapps’automationHybridappsareacombinationofnativeandwebapps;similartonativeapps,youcangethybridappsthroughanapplicationstore.Nowadays,hybridappsareverypopularbecausetheygiveusacross-platformsolutionanddisplaythecontenttheygetfromtheWeb.
AndroidhybridappsHere,wearegoingtotakeanexampleoftestApp;youcangetitfromhttps://github.com/manojhans/Appium/blob/master/Application/Android/testApp.zip?raw=true.
IfyouareworkingwithanAndroidversionlessthan4.4,thenyouhavetouseSelendroid(inthatcase,youhavetosetthecapabilityascaps.setCapability(MobileCapabilityType.AUTOMATION_NAME,"Selendroid")),otherwiseAppiumhasabuilt-insupportthroughChromeDriver.
Whileworkingwithhybridapps,youneedtomakethechangesdefinedathttps://developer.chrome.com/devtools/docs/remote-debugging#configure-webview.WehavealreadymadethechangesintestApp.Initially,wewillgetthetestAppasshowninfollowingscreenshot:
Inthissection,wearegoingtotakealookatinteractingwiththewebview:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchthehybridapp,asfollows:
Fileapp=newFile("C:\\Appium_test\\testApp.apk");//(Onwindow
platform)
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability("avd","AVD_Nexus_4");//MentionthecreatedAVDname
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"
com.example.testapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,"MainActivity");
2. WeneedtofindtheEditboxtotypeinthedesiredURL(https://www.google.com)toopen;here,wearegoingtofindanelementbyID:
WebElement
editBox=driver.findElement(By.id("com.example.testapp:id/urlField"));
editBox.sendKeys("https://www.google.com");
3. Now,weneedtofindtheGobutton;inthissection,wearegoingtofindanelementbyname:
WebElementgoButton=driver.findElement(By.name("Go"));
4. ClickontheGobuttontoopentheURLinthewebview:
goButton.click();
5. Wethenneedtoswitchonthewebviewtotakefurtheraction.Wecangetthelistofcontextsusingthefollowingcommand:
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintthelistofcontextslike
NATIVE_APP\nWEBVIEW_com.example.testapp
}
6. Now,switchonthewebviewusingthiscommand:
driver.context("WEBVIEW_com.example.testapp");
Youcanalsousethis:
driver.context((String)contextNames.toArray()[1]);
7. Now,youcaninteractwiththeGooglepage;here,wearegoingtoclickontheImagestabandfindanelementbylinkText:
WebElementimages=driver.findElement(By.linkText("Images"));
images.click();
8. RunyourscriptusingTestNG;itshouldlooklikethefollowingblockofcode:
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
Fileapp=newFile("/Users/mhans/appium/ios/webViewApp.app");
caps.setCapability(MobileCapabilityType.APP,app");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,
"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"Android
emulator");
caps.setCapability("avd","AVD_Nexus_4");//Mentionthecreated
AVDname
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME,
"Appium");//UseSelendroidincaseof<4.4androidversion
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.example.testapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.example.testapp.MainActivity");
driver=newAndroidDriver(new
URL("http://127.0.0.1:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElement
editBox=driver.findElement(By.id("com.example.testapp:id/urlField"));
editBox.sendKeys("https://www.google.com");
WebElementgoButton=driver.findElement(By.name("Go"));
goButton.click();
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintNATIVE_APP\n
WEBVIEW_com.example.testapp
}
driver.context((String)contexts.toArray()[1]);
WebElementimages=driver.findElement(By.linkText("Images"));
images.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
iOShybridappsHere,wearegoingtotakeanexampleofWebViewApp.Youcangetitfromhttps://github.com/manojhans/Appium/blob/master/Application/iOS/Hybrid/WebViewApp7.1.app.zip?raw=true.Afterdownloadingit,extractittoalocalfolder(forexample,/Users/mhans/appium/ios/WebViewApp.app).Initially,thewebViewAppwilllooklikethefollowingscreenshot:
Inthissection,wearegoingtolookatinteractingwiththewebview:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchthehybridapp:
Fileapp=newFile("/Users/mhans/appium/ios/WebViewApp.app");
caps.setCapability(MobileCapabilityType.APP,app);
2. WeneedtofindtheeditboxtotypeinthedesiredURL(https://www.google.com)toopen;here,wearegoingtofindanelementbyclassName:
WebElementeditBox=driver.findElement(By.className("UIATextField"));
editBox.sendKeys("www.google.com");
3. Now,weneedtofindtheGobutton;wearegoingtofindanelementbyname:
WebElementgoButton=driver.findElement(By.name("Go"));
4. ClickontheGobuttontoopentheURLinthewebview:
goButton.click();
5. Now,weneedtoswitchonthewebviewtotakefurtheraction.Wecanviewthelistofcontextsusingthefollowingcommand:
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintthelistofcontextslike
NATIVE_APP\nWEBVIEW_1
}
6. Now,switchonthewebviewusingthiscommand:
driver.context("WEBVIEW_com.example.testapp");
Alternatively,youcanalsousethiscommand:
driver.context((String)contextNames.toArray()[1]);
7. NowyoucaninteractwiththeGooglepage.Here,wearegoingtoclickontheImagestab;let’sfindanelementusinglinkText:
WebElementimages=driver.findElement(By.linkText("Images"));
images.click();
8. RunyourscriptusingTestNG;itshouldlooklikethefollowingblockofcode:
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPhone5");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementeditBox=driver.findElement(By.className("UIATextField"));
editBox.sendKeys("https://www.google.com");
WebElementgoButton=driver.findElement(By.name("Go"));
goButton.click();
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintNATIVE_APP\n
WEBVIEW_com.example.testapp
}
driver.context((String)contexts.toArray()[1]);
WebElementimages=driver.findElement(By.linkText("Images"));
images.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
SummaryInthischapter,welookedathowtoexecutetestscriptsofnative,hybrid,andmobilewebappsonaniOSsimulatorandAndroidemulator.Welearnedhoweasilywecanperformactionsonnativemobileappsandalsolearnedaboutthedesiredcapabilitiesthatarerequired.WelearnedhowtoloadthenativebrowserinanAndroidemulatorandthenecessarycapabilitiestostartwith.
WesawhowwecanstarttheSafaribrowserinasimulatorandsetupthedesiredcapabilitiestotestwebapplications.Lastly,welookedathoweasilywecanautomatehybridappsandswitchfromnativetowebview.
Inthenextchapter,wewilltakealookatAppiumdriversonrealdevices.
Chapter6.DrivingAppiumonRealDevicesItisreallygoodtoknowthatwecanautomatemobileappsonrealdevices.Appiumprovidesthesupportforautomatingappsonrealdevices.Wecantesttheappsinaphysicaldeviceandexperiencethelookandfeelthatanenduserwould.
Inthischapter,wewilllearnthefollowingtopics:
DialerappautomationonanAndroidrealdeviceRegistrationformautomationonanAndroidrealdeviceGmailloginautomationwithChromebrowseronanAndroidrealdeviceBodyMassIndex(BMI)calculatorautomationonaniOSrealdeviceMobilehybridappautomationonaniOSrealdeviceWebappautomationwithSafarionaniOSrealdevice
ImportantinitialpointsBeforestartingwithAppium,makesurethatyouhaveallthenecessarysoftwareinstalled.Let’stakealookattheprerequisitesforAndroidandiOS:
PrerequisitesforAndroid PrerequisitesforiOS
Java(Version7orlater) MacOS(Version10.7orlater)
TheAndroidSDKAPI,Version17orhigher Xcode(Version4.6.3orhigher;5.1isrecommended)
ArealAndroiddevice AniOSprovisionalprofile
Chromebrowseronarealdevice AniOSrealdevice
Eclipse TheSafariLauncherapp
TestNG ios-webkit-debug-proxy
TheAppiumServer JavaVersion7
TheAppiumclientlibrary(Java) Eclipse
SeleniumServerandWebDriverJavalibrary TestNG
TheApkInfoapp TheAppiumserver
TheAppiumclientlibrary(Java)
SeleniumServerandWebDriverJavalibrary
WhileworkingwiththeAndroidrealdevice,weneedtoenableUSBdebuggingunderDeveloperoptions.ToenableUSBdebugging,wehavetoperformthefollowingsteps:
1. NavigatetoSettings|AboutPhoneandtaponBuildnumberseventimes(assumingthatyouhaveAndroidVersion4.2ornewer);then,returntothepreviousscreenandfindDeveloperoptions,asshowninthefollowingscreenshot:
2. TaponDeveloperoptionsandthentapontheONswitchtoswitchonthedevelopersettings(Youwillgetanalerttoallowdevelopersettings;justclickontheOKbutton.).MakesurethattheUSBdebuggingoptionischecked,asshownhere:
3. Afterperformingtheprecedingsteps,youhavetouseaUSBcabletoconnectyourAndroiddevicewiththedesktop.MakesureyouhaveinstalledtheappropriateUSB
driverforyourdevicebeforedoingthis.Afterconnecting,youwillgetanalertonyourdeviceaskingyoutoallowUSBdebugging;justtaponOK.
Toensurethatwearereadytoautomateappsonthedevice,performthefollowingsteps:
1. OpenCommandPromptorterminal(onMac).2. TypeadbdevicesandpresstheEnterbutton.
YouwillgetalistofAndroiddevices;ifnot,thentrytokillandstarttheadbserverwiththeadbkill-serverandadbstart-servercommands.
Now,we’vecometothecodingpart.First,weneedtosetthedesiredcapabilitiesandinitiateanAndroid/iOSdrivertoworkwithAppiumonarealdevice.Let’sdiscussthemonebyone.
DesiredcapabilitiesforAndroidandinitiatingtheAndroiddriverWehavetwowaystosetthedesiredcapabilities,onewiththeAppiumGUIandtheotherbyinitiatingthedesiredcapabilitiesobject.
Usingthedesiredcapabilitiesobjectispreferable;otherwise,wehavetochangethedesiredcapabilitiesintheGUIrepeatedlywheneverwearetestinganothermobileapp.
Let’stakealookattheAppiumGUIsettingsfornativeandhybridapps:
PerformthefollowingstepstosettheAndroidSettings:
1. ClickontheAndroidSettingsicon.2. SelectApplicationPathandprovidethepathoftheapp.3. ClickonPackageandchoosetheappropriatepackagefromthedrop-downmenu.4. ClickonLaunchActivityandchooseanactivityfromthedrop-downmenu.
NoteIftheapplicationisalreadyinstalledontherealdevice,thenwedon’tneedtofollow
steps2-4.Inthiscase,wehavetoinstalltheApkInfoapponthedevicetoknowthepackageandactivitiesoftheappandsetthemusingthedesiredcapabilitiesobject,whichwewillseeinthenextsection.Youcaneasilygetthe‘Apkinfo’appfromtheAndroidPlayStore.
5. SelectPlatformVersionfromthedropdown.6. SelectDeviceNameandtypeinadevicename(Forexample,MotoX).7. Now,starttheAppiumServer.
PerformthefollowingstepstosettheAndroidSettingsforwebapps:
1. ClickontheAndroidSettingsicon.2. SelectPlatformVersionfromthedropdown.3. SelectUseBrowserandchooseChromefromthedropdown.4. SelectDeviceNameandtypeinadevicename(Forexample,MotoX).5. Now,starttheAppiumServer.
Let’sdiscusshowtoinitiatethedesiredcapabilitiesobjectandsetthecapabilities.
DesiredcapabilitiesfornativeandhybridappsWehavealreadydiscusseddesiredcapabilitiesinChapter1,Appium–ImportantConceptualBackground,soherewewilldirectlydiveintothecodewithcomments.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesforthenativeandhybridapps:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
Fileapp=newFile("pathoftheapk");//Tocreatefileobjecttospecifythe
apppath
caps.setCapability(MobileCapabilityType.APP,app);//Ifappisalready
installedonthedevicethennoneedtosetthiscapability.
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");//Toset
theAndroidversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");//Toset
theOSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Youcan
changethedevicenameasyours.
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"packagenameofyour
app(youcangetitfromapkinfoapp)");//Tospecifytheandroidapp
package
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,"Launchactivityof
yourapp(youcangetitfromapkinfoapp)");//Tospecifytheactivity
whichwewanttolaunch
DesiredcapabilitiesforwebappsInAndroidmobilewebapps,someofthecapabilitiesthatweusedinnativeandhybridappssuchasAPP,APPPACKAGE,andAPPACTIVITYarenotneededbecausewelaunchabrowserhere.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesforthewebapps:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");//Toset
theandroidversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");//Toset
theOSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Youcan
changethedevicenameasyours
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Chrome");//To
launchtheChromebrowser
Wearedonewiththedesiredcapabilitypart;now,wehavetoinitiatetheAndroiddrivertoconnectwiththeAppiumServerbyimportingthefollowingpackages:
importio.appium.java_client.android.AndroidDriver;
importjava.net.URL;
Then,initiatetheAndroiddriverasshownhere:
AndroidDriverdriver=newAndroidDriver(new
URL("http://127.0.0.1:4723/wd/hub"),caps);//TOpasstheurlwhereAppium
serverisrunning
ThiswilllaunchtheappintheAndroidrealdeviceusingtheconfigurationsspecifiedinthedesiredcapabilities.
Installingprovisionalprofile,SafariLauncher,andios-webkit-debug-proxyBeforemovingontothedesiredcapabilitiesforiOS,wehavetomakesurethatwehavesetupaprovisionalprofileandinstalledtheSafariLauncherappandios-webkit-debug-proxytoworkwiththerealdevice.
First,let’sdiscusstheprovisionalprofile.
ProvisionalprofileThisprofileisusedtodeployanapponarealiOSdevice.Todothis,weneedtojointheiOSDeveloperProgram(https://developer.apple.com/programs/ios/).
Forthis,youwillhavetopayUSD99.Now,visithttps://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingProfiles/MaintainingProfiles.html#//apple_ref/doc/uid/TP40012582-CH30-SW24togeneratetheprofile.
Afterthis,youwillalsoneedtoinstallprovisionalprofileonyourrealdevice;todothis,performthefollowingsteps:
1. Downloadthegeneratedprovisionalprofile.2. ConnecttheiOSdevicetoaMacusingaUSBcable.3. OpenXcode(version6)andclickonDevicesundertheWindowmenu,asshown
here:
4. Now,contextclickontheconnecteddeviceandclickonShowProvisionalProfiles…:
5. Clickon+,selectthedownloadedprofile,andthenclickontheDonebutton,asshowninthefollowingscreenshot:
SafariLauncherappandios-webkit-debug-proxyTheSafariLauncherappisusedtolaunchtheSafaribrowseronarealdeviceforwebapptesting.YouwillneedtobuildanddeploytheSafariLauncherapponarealiOSdevicetoworkwiththeSafaribrowser.Todothis,youneedtoperformthefollowingsteps:
1. Downloadthesourcecodefromhttps://github.com/snevesbarros/SafariLauncher/archive/master.zip.
2. OpenXcodeandthenopentheSafariLauncherproject.3. Selectthedevicetodeploytheapponandclickonthebuildbutton.4. Afterthis,weneedtochangetheSafariLauncherappinAppium.dmg;todothis,
performthefollowingsteps:
1. Right-clickonAppium.dmg.2. ClickonShowPackageContentsandnavigateto
Contents/Resources/node_modules/appium/build/SafariLauncher.3. Now,extractSafariLauncher.zip.4. Navigatetosubmodules/SafariLauncher/build/Release-iphoneosand
replacetheSafariLauncherappwithyourapp.5. ZipsubmodulesandrenameitasSafariLauncher.zip.
Now,weneedtoinstalltheios-webkit-debug-proxyonMactoestablishaconnectioninordertoaccessthewebview.Toinstalltheproxy,youcanusebrewandrunthecommandbrewinstallios-webkit-debug-proxyintheterminal(thiswillinstallthelatesttaggedversion),oryoucancloneitfromGitandinstallitusingthefollowingsteps:
1. Opentheterminal,typegitclonehttps://github.com/google/ios-webkit-debug-proxy.git,andthenclickontheEnterbutton.
2. Then,enterthefollowingcommands:
cdios-webkit-debug-proxy
./autogen.sh
./configure
make
sudomakeinstall
Wearenowallsettotestwebandhybridapps.Next,it’stimetomoveontothedesiredcapabilitiesforiOS.
DesiredcapabilitiesforiOSandinitiatingtheiOSdriverSimilartoAndroid,wecansetthedesiredcapabilitiesusingtheAppiumGUIandbyinitiatingthedesiredcapabilitiesobject.Let’sdiscusstheAppiumGUIsettingsfornativeandhybridapps.ThefollowingscreenwillbedisplayedwhentheiOSSettingsiconisclicked:
PerformthefollowingstepstosettheiOSsettingsfornativeandhybridapps:
1. ClickontheiOSSettingsicon.2. SelectAppPathandprovidethepathoftheapplication.3. SelectUDIDandtypeinthedeviceidentifier.Forthedeviceidentifier,weneedto
performthefollowingsteps:
1. ConnectiOSdevicetoaMacusingaUSBcable.2. OpenXcode(Version6)andclickonDevicesfromtheWindowmenu.3. SelectConnecteddevice.4. UnderDeviceInformation,youwillgetanidentifier.WecanalsogettheUDID
fromiTunesbyclickingonSerialNumber.
4. UnderDeviceInformation,youwillgetanidentifier.5. SelectPlatformVersionfromthedropdown;youcanalsotypeintheplatform
version(forexample,8.1).6. Now,starttheAppiumServer.
Let’ssettheAppiumGUIsettingsforwebapps:
PerformthefollowingstepstosettheiOSsettingsforwebapps:
1. ClickontheiOSSettingsicon.2. SelectUseMobileSafari.3. SelectUDIDandtypeinthedeviceidentifier.4. SelectPlatformVersionfromthedropdownoryoucanalsotypeinone(for
example,8.1).5. Now,starttheAppiumServer.
Now,let’stakealookathowtoinitiatethedesiredcapabilitiesobjectandsetthecapabilities.
DesiredcapabilitiesfornativeandhybridAppsWehavealreadydiscussedthedesiredcapabilitiesforiOSinChapter1,Appium–ImportantConceptualBackground,soherewewilldirectlydiveintothecodewithcomments.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesforthenativeandhybridapps:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
ofdesiredcapabilities
Fileapp=newFile("pathofthe.app");//Tocreateafileobjecttospecify
theapppath
caps.setCapability(MobileCapabilityType.APP,app);//Tosettheapppath
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");//Toset
theiOSversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");//Tosetthe
OSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");//Typedevice
name
caps.setCapability("udid","RealDeviceId");//TospecifytheUDIDofthe
device
DesiredcapabilitiesforwebappsIniOSmobilewebapps,someofthecapabilitiesthatweusedinnativeandhybridappssuchasAPP,APPPACKAGE,andAPPACTIVITYarenotneededbecausewelaunchabrowserhere.First,weneedtoimportthefollowingpackages:
importjava.io.File;
importorg.openqa.selenium.remote.DesiredCapabilities;
importio.appium.java_client.remote.MobileCapabilityType;
Now,let’ssetthedesiredcapabilitiesforthewebapps:
DesiredCapabilitiescaps=newDesiredCapabilities();//Tocreateanobject
ofdesiredcapabilities
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");//Toset
theiOSversion
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");//Tosetthe
OSname
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");//Totypethe
devicename
caps.setCapability("udid","RealDeviceId");//TospecifytheUDIDofreal
device
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");//Tolaunch
theSafaribrowser
Wearedonewiththedesiredcapabilitiespart;now,wehavetoinitiatetheiOSdrivertoconnecttotheAppiumServerbyimportingthefollowingpackages:
importio.appium.java_client.ios.IOSDriver;
importjava.net.URL;
Then,initiatetheiOSDriverasshownhere:
IOSDriverdriver=newIOSDriver(new
URL("http://127.0.0.1:4723/wd/hub"),caps);//TopasstheurlwhereAppium
serverisrunning
Thiswilllaunchtheappinthesimulatorusingtheconfigurationsspecifiedinthedesiredcapabilities.Now,youcanusethefollowingclassforscriptswithTestNG:
importio.appium.java_client.ios.IOSDriver;
importio.appium.java_client.remote.MobileCapabilityType;
importjava.io.File;
importjava.net.MalformedURLException;
importjava.net.URL;
importjava.util.concurrent.TimeUnit;
importorg.openqa.selenium.remote.DesiredCapabilities;
importorg.testng.annotations.AfterClass;
importorg.testng.annotations.BeforeClass;
importorg.testng.annotations.Test;
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass//Itwillexecuteonetimebeforeexecutealltestcases
publicvoidsetUp()throwsMalformedURLException{
//Setupdesiredcapabilities
DesiredCapabilitiescaps=newDesiredCapabilities();
Fileapp=newFile("pathofthe.app");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","RealDeviceId");
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");//In
caseofweb-apps
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
//Wewillputtestscriptshere
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
//driver.quit();//incaseofwebapps
}
}
AutomatingnativeappsNativeappsarebasicallydevelopedforaparticularplatformandcantakeadvantageofthedevice’sfeatures.Oneimportantpointtonoteisthattheseappscanworkevenwhenyouareoffline.Youcaninstallthemdirectlyontothedeviceorthroughapplicationstores,suchasGooglePlayortheAppleAppStore.
AndroidnativeappsInthecaseofAndroidautomation,thesamecodethatwasusedinthepreviouschapterwillworkwhentestingwithanemulator,butweneedtoremovetheavdcapabilitiesfromtheemulatorautomationcode.
Here,wearegoingtotakeanexampleoftheAndroiddialerapp.Inthissection,wewillmakeacallwiththeAndroiddialerapp,whichisshowninthefollowingscreenshot:
Let’sstartwiththefollowingstepstoautomatethedialerapp:
1. Setthedesiredcapabilitiestolaunchthedialerapp,asfollows:
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.dialer");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.dialer.DialtactsActivity");
2. Now,weneedtofindthedialpadicon;wearegoingtofinditbyAccessibityId,asfollows:
WebElementdialPad=driver.findElementByAccessibilityId("dialpad"));
3. Now,weneedtoclickontheiconusing:
dialPad.click();
4. Weneedtofindthenumberskeyinordertodial.Here,wearegoingtoputsomelogictofindthenumbers(0to9)bynameandclickonthemonebyone:
for(intn=0;n<10;n++){
driver.findElement(By.name(""+n+"")).click();
}
Thisloopwillexecute10timesandwillpassthevalueinsidethelocatorfromthenumbers0to9.
5. Here,weareusingawrongphonenumbersothatthedevicedoesn’tmakeacalltoanyone;itwillendwithaninvalidnumber.
6. Now,weneedfindthedialicontomakethecall;wearegoingtofinditbyAccessibilityId:
WebElementdial=driver.findElementByAccessibilityId("dial"));
7. Now,clickontheicontomakethecall:
dial.click();
8. RunyourscriptusingTestNG;thisishowitshouldlook:
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.dialer");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.dialer.DailtactsActivity");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementdialPad=driver.findElementByAccessibilityId("dialpad");
dialPad.click();
for(intn=0;n<10;n++){
driver.findElement(By.name(""+n+"")).click();
}
WebElementdial=driver.findElementByAccessibilityId("dial");
dial.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
iOSnativeappsHere,wearegoingtotakeanexampleoftheBMIcalculator;youcangetitfromhttps://github.com/manojhans/Appium/blob/master/Application/iOS/Real_Device/Native/BMICalc.zip?raw=true.
Youcanalsodownloadthesourcecodefromhttps://github.com/soroushjp/BMICalc_iOS/archive/master.zipandbuilditforarealdevice.YoucanusethesamestepstobuildtheBMICalcthatweusedfortheSafariLaucherappearlierinthischapter.Initially,wewillgettheBMIcalculatorasshowninfollowingscreenshot:
Inthissection,wewillcalculatethebodymassindexaspertheheightandweight.Todothis,weneedtoperformthefollowingsteps:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchtheBMICalc:
Fileapp=newFile("/Users/mhans/appium/ios/BmiCalc.app");//Youcan
changeitwithyourappaddress
caps.setCapability(MobileCapabilityType.APP,app);//Tosettheapppath
2. Now,wehavetofindtheelementstotypeintheheightandweighttextbox;wewillfindthembyXpath:
WebElementheight=driver.findElement(By.xpath("(//UIATextField)[2]"));
WebElementweight=driver.findElement(By.xpath("(//UIATextField)[4]"));
3. Now,weneedtofindthecalculatebutton;wearegoingtofinditbyname:
WebElementcalculateBMI=driver.findElement(By.name("CalculateBMI"));
4. Nowtypeavalueinthefirstbox:
height.sendKeys("1.82");
5. Typeavalueinthesecondbox:
weight.sendKeys("75");
6. Now,clickontheCalculateBMIbutton:
calculateBMI.click();
7. RunyourscriptusingTestNG;thisishowitshouldlook:
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
Fileapp=newFile("/Users/mhans/appium/ios/BmiCalc.app");//Youcan
changeitwithyourappaddress
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","RealDeviceId");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementheight=driver.findElement(By.xpath("(//UIATextField)
[2]"));
height.sendKeys("1.82");
WebElementweight=driver.findElement(By.xpath("(//UIATextField)
[4]"));
weight.sendKeys("75");
WebElementcalculateBMI=driver.findElement(By.name("CalculateBMI"));
calculateBMI.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
WorkingwithwebappsWebappscanberunonanydeviceorplatform.TheonlyrequirementforrunningthemisawebbrowserandanInternetconnection;thebestpartisthatyoudon’tneedtoinstalltheapponthedevice.Webappsaregenerallydesignedwithcross-browsercompatibility.
WebappsonAndroidWewilltaketheexampleoftheGmailloginpage.Inthissection,wearegoingtotakealookathowtoloadtheChromebrowseronarealdeviceandthentypeininvalidcredentialsandclickontheSigninbuttonthatisshowninthefollowingscreenshot:
Let’sstartwiththefollowingstepstoautomatethewebapps:
1. SetthedesiredcapabilitiestolaunchtheChromebrowser:
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Chrome");
2. Now,weneedtonavigatetohttps://www.gmail.comusingthedriver.get("https://www.gmail.com");command.
3. Weneedtofindtheusernameboxelement(wecantakeareferencefromChapter4,FindingElementswithDifferentLocators,tofindanelement);inthissection,wearegoingtofindanelementbyname:
WebElementusername=driver.findElement(By.name("Email"));
4. Now,weneedtypeintotheusernamebox:
username.sendKeys("test");
5. Weneedtofindthepasswordboxelement;inthissection,wearegoingtofindanelementbyname:
WebElementpassword=driver.findElement(By.name("Passwd"));
6. Now,weneedtotypeintothepasswordboxelement:
password.sendKeys("test");
7. WeneedtofindtheSigninbutton;inthissection,wearegoingtofindanelementbyname:
WebElementsignIn=driver.findElement(By.name("signIn"));
8. Now,weneedtoperformaclickonit:
signIn.click();
9. RunyourscriptusingTestNG;thisishowitshouldlook:
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Chrome");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
driver.get("https://www.gmail.com");
WebElementusername=driver.findElement(By.name("Email"));
username.sendKeys("test");
WebElementpassword=driver.findElement(By.name("Passwd"));
password.sendKeys("test");
WebElementsignIn=driver.findElement(By.name("signIn"));
signIn.click();}
@AfterClass
publicvoidtearDown(){
driver.quit();
}
}
WebappsoniOSWearegoingtotakeanexampleoftheGooglesearchpage.Inthissection,wearegoingtotakealookathowtoloadthebrowseronarealiOSdeviceandthentypedataintheGooglesearchboxshowninthefollowingscreenshot:
Let’sstartwiththefollowingstepstoautomatewebapps:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchtheSafaribrowser:
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");
2. Now,weneedtonavigatetohttps://www.google.comusingthedriver.get("https://www.google.com");command.
3. WeneedtofindthesearchBoxelement;inthissection,wearegoingtofindanelementbyname:
WebElementsearchBox=driver.findElement(By.name("q"));
4. Now,weneedtotypeintothesearchbox:
searchBox.sendKeys("Appiumformobileautomation");
5. Beforerunningthetestscript,weneedtostarttheproxyusingthefollowingcommand:
ios_webkit_debug_proxy-c
2e5n6f615z66e98c1d07d22ee09658130d345443:27753–d
Replace2e5n6f615z66e98c1d07d22ee09658130d345443withtheattacheddevice’sUDIDandmakesurethattheportissetto27753.
6. MakesurethattheWebInspectoristurnedONonarealdevice(Settings|Safari|Advanced)andtheSafariLauncherappisinstalled:
7. RunyourscriptusingTestNG;thisishowitshouldlook:
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"Safari");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","RealDeviceIdentifier");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
driver.get("https://www.google.com");
WebElementsearchBox=driver.findElement(By.name("q"));
searchBox.sendKeys("Appiumformobileautomation");
}
@AfterClass
publicvoidtearDown(){
driver.quit();
}
}
AutomatinghybridappsAhybridappisacombinationofnativeandwebapps.Similartonativeapps,youcangethybridappsthroughanapplicationstore.Nowadays,hybridappsareverypopularbecausetheyprovideacross-platformsolutionanddisplaythecontentthattheygetfromtheWebratherthanthecontentsinstalledonthedeviceonly.
AndroidhybridappsHere,wewilltakeanexampleoftheHybridtestapp;youcangetitfromhttps://github.com/manojhans/Appium/blob/master/Application/Android/Hybrid/Hybridtestapp.zip?raw=true.
IfyouareworkingwithanAndroidversionhigherthan4.4,thenyouhavetouseSelendroid(inthatcase,youhavetosetthecapabilityas(MobileCapabilityType.AUTOMATION_NAME,"Selendroid"));otherwise,Appiumhasbuilt-insupportthroughtheChromeDriver.
Whileworkingwithhybridapps,youneedtomakethechangesdefinedathttps://developer.chrome.com/devtools/docs/remote-debugging#configure-webview.WehavealreadymadethesechangesinHybridtestapp.Initially,wewillgettheHybridtestappasshowninfollowingscreenshot:
Inthissection,wewillinteractwithwebviewandfilltheregistrationformbyperformingthefollowingsteps:
1. Setthedesiredcapabilitiestolaunchthehybridapp:
Fileapp=newFile("C:\\Appium_test\\HybridtestApp.apk");//(Onwindow
platform)
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.example.hybridtestapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.example.hybridtestapp.MainActivity");
2. Weneedtoswitchonthewebviewtotakeactionontheregistrationform.Wecanhavethelistofcontextsusingthefollowingcommand:
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintthelistofcontextslike
NATIVE_APP\nWEBVIEW_com.example.hybridtestapp
}
3. Now,switchonthewebviewusingthiscommand:
driver.context("WEBVIEW_com.example.hybridtestapp");
Alternatively,youcanusethefollowingcommand:
driver.context((String)contextNames.toArray()[1]);
Makesurethatalltheotherappsareclosedbeforeyouexecutethescripts.
4. Onceweareinsidewebview,weneedtofindtheFirstNameboxtotypein;here,wearegoingtofindanelementbyname:
WebElementfirstName=driver.findElement(By.name("fname"));
firstName.sendKeys("test");
5. WeneedtofindtheLastNameboxtotypein;here,wearegoingtofindanelementbyname:
WebElementlastName=driver.findElement(By.name("lname"));
lastName.sendKeys("test");
6. WeneedtofindtheAgeboxtotypein;here,wearegoingtofindanelementbyname:
WebElementage=driver.findElement(By.name("age"));
age.sendKeys("26");
7. WeneedtofindtheUserNameboxtotypein;here,wearegoingtofindanelementbyname:
WebElementusername=driver.findElement(By.name("username"));
username.sendKeys("appiumTester");
8. WeneedtofindthePasswordboxtotypein;here,wearegoingtofindanelementbyid:
WebElementpassword=driver.findElement(By.id("psw"));
password.sendKeys("appium@123");
9. WeneedtofindtheRegisterbuttontosubmittheform;wearegoingtofindanelementbyid:
WebElementregisterButton=driver.findElement(By.id("register"));
registerButton.click();
10. RunyourscriptusingTestNG;thisishowitshouldlook:
publicclassTestAppIication{
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
Fileapp=newFile("C:\\Appium_test\\HybridtestApp.apk");//
(Onwindowplatform)
caps.setCapability(MobileCapabilityType.APP,app);
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME,
"Appium");//UseSelendroidincaseof<4.4androidversion
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.example.hybridtestapp");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.example.hybridtestapp.MainActivity");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintNATIVE_APP\n
WEBVIEW_com.example.hybridtestapp
}
driver.context((String)contexts.toArray()[1]);
WebElementfirstName=driver.findElement(By.name("fname"));
firstName.sendKeys("test");
WebElementlastName=driver.findElement(By.name("lname"));
lastName.sendKeys("test");
WebElementage=driver.findElement(By.name("age"));
age.sendKeys("26");
WebElementusername=driver.findElement(By.name("username"));
username.sendKeys("appiumTester");
WebElementpassword=driver.findElement(By.id("psw"));
password.sendKeys("appium@123");
WebElementregisterButton=driver.findElement(By.id("register"));
registerButton.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
iOShybridappsHere,wearegoingtousetheexampleofaWebViewApp.Youcangetitfromhttps://github.com/manojhans/Appium/blob/master/Application/iOS/Real_Device/Hybrid/WebViewApp.zip?raw=trueordownloadthesourcecodefromhttps://github.com/appium/sample-code/archive/master.zipandbuildWebViewAppforrealdevices.
YoucanperformthesamestepstobuildWebViewAppthatyoutookfortheSafariLaucherappearlierinthischapter.Initially,wewillgettheWebViewAppasshowninfollowingscreenshot:
Inthissection,wearegoingtoseehowtointeractwithwebview,asfollows:
1. Updatethedesiredcapabilitiesinthesetup()methodtolaunchthehybridapp:
Fileapp=newFile("/Users/mhans/appium/ios/WebViewApp.app");//Changeit
withyourappaddress
caps.setCapability(MobileCapabilityType.APP,app);
2. WeneedtofindtheeditboxinordertotypeinthedesiredURL(www.google.com)toopen;here,wearegoingtofindanelementbyclassName:
WebElementeditBox=driver.findElement(By.className("UIATextField"));
editBox.sendKeys("www.google.com");
3. Now,weneedtofindtheGobutton;wearegoingtofindanelementbyname:
WebElementgoButton=driver.findElement(By.name("Go"));
ClickontheGobuttontoopentheURLinwebview:
goButton.click();
4. Now,weneedtoswitchonthewebviewtotakefurtheraction;wecanhavethelist
ofcontextsusingthefollowingcommand:
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintthelistofcontextslike
NATIVE_APP\nWEBVIEW_1
}
5. Now,switchonthewebviewusingthiscommand:
driver.context("WEBVIEW_com.example.testapp");
Youcanalsousethiscommandalternatively:
driver.context((String)contextNames.toArray()[1]);
6. Now,youcaninteractwiththeGooglepage.Here,wearegoingtoclickontheImagestab;let’sfindanelementbylinkText:
WebElementimages=driver.findElement(By.linkText("Images"));
images.click();
7. RunyourscriptusingTestNG.Beforerunningthetestscript,youneedtostarttheproxyusingtheios_webkit_debug_proxy-c2e5n6f615z66e98c1d07d22ee09658130d345443:27753–dcommand.ReplacetheUDIDwiththeattacheddeviceandmakesurethattheportissetto27753.
MakesurethatthewebinspectoristurnedONontherealdevice(Settings|Safari|Advanced)andtheSafariLauncherappisinstalled.Thisishowthetestscriptshouldlook:
publicclassTestAppIication{
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
Fileapp=newFile("/Users/mhans/appium/ios/WebViewApp.app");
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","RealDeviceIdentifier");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementeditBox=driver.findElement(By.className("UIATextField"));
editBox.sendKeys("https://www.google.com");
WebElementgoButton=driver.findElement(By.name("Go"));
goButton.click();
Set<String>contexts=driver.getContextHandles();
for(Stringcontext:contexts){
System.out.println(context);//itwillprintNATIVE_APP\n
WEBVIEW_com.example.testapp
}
driver.context((String)contexts.toArray()[1]);
WebElementimages=driver.findElement(By.linkText("Images"));
images.click();
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
}
SummaryInthischapter,welookedathowwecanexecutethetestscriptsofnative,hybrid,andwebmobileappsoniOSandAndroidrealdevices.Specifically,welearnedhowtoperformactionsonnativemobileappsandalsogottoknowaboutthedesiredcapabilitiesforrealdevices.WeranatestwiththeAndroidChromebrowserandlearnedhowtoloadtheChromebrowseronanAndroidrealdevicewiththenecessarycapabilities.
WethenmovedontostartingtheSafaribrowseronarealdeviceandsettingupthedesiredcapabilitiestotestwebapplications.Lastly,welookedathoweasilywecanautomatehybridappsandswitchfromnativetowebview.
Inthelastchapter,wewilltakealookatdifferentmobilegestures.
Chapter7.AdvancedUserInteractionsIntheprecedingchapters,wecoveredalotofthingsthatarequitestraightforwardwithAppium.Inthischapter,wewilltakealookatmobilegestures,suchaslongpress,zoom,andswipe.
Inthischapter,wewilllearnaboutthefollowingtopics:
TheadvanceduserinteractionsAPIMobilegestures,suchaslongpress,draganddrop,soonHandlingalerts,spinners(dropdowns),theswitchbutton,andtheslideseekBar.CapturingscreenshotsCapturingscreenshotsontestfailure
ExploringadvanceduserinteractionsInAppium,theadvanceduserinteractionsAPIallowsyoutoperformcomplexmobilegestures,suchasdraganddrop,swipe,andzoombyusingtheTouchActionandMultiTouchActionclasses.Itsimplybuildsacomplexchainofevents,similartowhatusersdomanuallyontheirmobiledevices.Intheupcomingsections,wewillseetheseclassesindetail.
LongpressLongpressisamobilegesturethatiswidelyusedbypeople.Itisawonderfulfeature;mostpeoplesaythatyoushouldtouchandholdinsteadofusinglongpress.Byusinglongpress,youcangetmoreinformationaboutaparticularfeature.Justlikeacontext-clickontheWeb,italsoenablesmultiselectioninmobileapps.
Let’stryandcreatealongpressexampleusingtheTouchActionclass.Here,wearegoingtotakeanexampleofadialerpadonanAndroidrealdevice.Inthissection,wewilllongpressthenumber0anditwillbeconvertedinto+.Todothis,weneedtoperformthefollowingsteps:
1. OpenupEclipseandcreateanAppiumproject.2. Createanewclassthathasthefollowingtestcode:
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.dialer");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.dialer.DialtactsActivity");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementdialPad=driver.findElementByAccessibilityId("dialpad");
dialPad.click();
TouchActiontAction=newTouchAction(driver);
tAction.longPress(driver.findElement(By.name("0"))).perform();
WebElementresults=
driver.findElementByClassName("android.widget.EditText");
assertresults.getText().equals("+"):"Actualvalueis:
"+results.getText()+"didnotmatchwithexpectedvalue:+";
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
3. Runthetestcode;initially,youshouldseethefollowingscreen:
4. Afterrunningthetestcode,youwillget+inthedialerbox,asshowninthefollowingscreen:
Wejustsawhoweasyitistoperformalongpressonthemobileapp.Forthis,weneedtocreateaTouchActionobjectandusingitsreference,callthelongpressfunction.WethenpasstheMobileElement,wherewewanttoperformthelongpress,andfinallycallperform()tosendtheactioncommandtothemobileapp.
Inthenextsection,wewilltakealookatanothermobilegesture:scrollandswipe.
ScrollandswipeIngeneral,scrollingistheprocessofmovingthevisualportionsofmobileappsinordertoseeadditionalinformation.
Onamobiledevice,youcanuseyourfingertoswipeupordowninordertoscrolldownorscrollupthescreen.Swipingyourfingerupwardswillleadtoascrolldownandswipingdownwillperformascrollup.
Here,wearegoingtotaketheexampleofacontactapptoviewthedesiredcontactdetailsonanAndroiddevice.Inthetestcode,wewillpassthenameNitika.
Let’sseethisinaction,asfollows:
1. CreateanewclassintheexistingAppiumprojectwiththefollowingtestcode:
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasaRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,"com.android.contac
ts");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.contacts.activities.PeopleActivity");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
driver.scrollTo("Nitika");//Youcankeepanothernamewhichisin
yourcontactlist
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
2. Runthetestcode;initially,youshouldseethefollowingscreen:
3. Aftertheexecutionofthetestcode,youshouldseesomethingsimilartothefollowingscreen:
Wehavejustseenscrollingonaparticulartextinthecontactlist.WeneedtocallthescrollTo("text")functionoftheAndroidDrivertoviewthedesiredcontact.Wehaveanotherfunction,scrollToExact("text"),toscrollonthepage,whichwewillseelaterinthischapterwhilehandlingspinners.
Let’screateanexampleofswipingusingthexandyoffsets.Wecanswipethescreenonthebasisofascreencoordinator.Here,wearetakinganexampleoftheGoogleNowLauncher.YoucandownloaditfromthePlayStoreandmakeityourdefaultlauncher.
Inthefollowingexample,wearegoingtoswipetotherightinordertoaccessGoogleNow:
1. Createanewclasswiththefollowingtestcode:
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasaRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.google.android.launcher");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.google.android.launcher.StubApp");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
TouchActiontAction=newTouchAction(driver);
tAction.press(300,500).moveTo(600,500).release().perform();//First
taponthescreenandswipeitrightusingmoveTofunction
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
2. Runthetestcode;initially,youshouldseethefollowingscreen:
3. Aftertheexecutionofthetestcode,youshouldseethefollowingscreen:
Wehavejustseenhoweasyitistodoascrollandswipeonthemobiledevice.Inthenextsection,wewilltakealookatthedraganddropgesture.
DraganddropAdraganddropoperationallowsyoutomoveobjectsfromonelocationtoanother.Itisoneofthosemobilegesturesthatcanreallysupportyoutomakeaninterfacesimpletouse.
OnAndroid,ifwepresstheappforashortwhile,itshowstheoptionsUninstallandAppinfoforthepressedapp.Let’swritethetestcodetogettheAppinfooption.Inthecaseofstockapps,youwillgetonlyoneoption,thatis,Appinfo.Here,wearegoingtodragthecalculatorappanddropitinAppinfousingthefollowingsteps.WeareassumingthatyoualreadyhaveGoogleNowLauncher:
1. Createanewclasswiththefollowingtestcode:
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasaRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.google.android.launcher");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.google.android.launcher.StubApp");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
MobileElementappsIcon=
(MobileElement)driver.findElementByAccessibilityId("Apps");
appsIcon.click();
MobileElementcalculator=
(MobileElement)driver.findElementByName("Calculator");
TouchActionact=newTouchAction(driver);
act.press(calculator).perform();//wearenotreleasingcalculator
icon
act.moveTo(driver.findElement(By.name("App
info"))).release().perform();//thenmovetheiconintoAppInfoand
nowreleasedtheicon
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
2. Runthetestcode;initially,youshouldseethefollowingscreen:
3. Aftertheexecutionofthetestcode,youshouldseethefollowingscreen:
Here,wesawhoweasilywecanperformadraganddropoperationonthemobiledevice.Intheprecedingtestcode,wepressedthecalculatorappuntiltheAppinfooptionbecamevisible;onceitwasvisible,wedroppedtheappinit.
Inthenextsection,wewillseeanotherusefulmobilegesture:pinchandzoom.
PinchandzoomThepinchandzoomgestureissimilartothedraggesture,butitstartswhenthesecondfingerispressedonthemobilescreen.Fortunately,AppiumalsosupportsmultitouchgesturesusingtheMultiTouchActionclass.YoucanaddmultipleactionssimultaneouslyusingtheMultiTouchActionclass.
Let’screateasequenceofactionsusingtheTouchActionschaingeneratorandthenaddtheseactionsusingtheMultiTouchActionclass.Here,wearetakinganexampleofaniOSapp,whichcanbedownloadedfromhttps://github.com/manojhans/Appium/blob/master/Application/iOS/Native/Zoom.zip?raw=true.
Initially,youwillseethefollowingimage:
Now,let’sperformthefollowingstepstopinchandzoom:
1. Createanewclasswiththefollowingcode:
IOSDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
Fileapp=newFile("/Users/mhans/appium/ios/Zoom.app");//Youcan
changeitwithyourappaddress
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"8.1");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"iPad");
caps.setCapability("udid","RealDeviceId");
driver=newIOSDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
intscrHeight=driver.manage().window().getSize().getHeight();//To
getthemobilescreenheight
intscrWidth=driver.manage().window().getSize().getWidth();//Toget
themobilescreenwidth
MultiTouchActionmultiTouch=newMultiTouchAction(driver);
TouchActiontAction0=newTouchAction(driver);
TouchActiontAction1=newTouchAction(driver);
tAction0.press(scrWidth/2,scrHeight/2).waitAction(1000).moveTo(0,60).re
lease();//pressfingercenterofthescreenandthenmoveyaxis
tAction1.press(scrWidth/2,scrHeight/2+40).waitAction(1000).moveTo(0,80)
.release();//pressthumbslightlydownonthecenterofthescreenand
thenmoveyaxis
multiTouch.add(tAction0).add(tAction1);
multiTouch.perform();//nowperformboththeactionssimultaneously
(tAction0andtAction1)
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
2. Afterthetestexecution,theimagewillbezoomedinandthisishowitwilllook:
WelearnedalotaboutadvanceduserinteractionsandhavefinisheddiscussingthecoreaspectsofAppium.Inthenextsection,wewilllearnhowtohandleanalertdialogbox.
AlertsAnalertisasmallwindowthatrequiresauseractiontomakeadecisionorentersomeextrainformation.Wecan’tinteractwiththeoriginalwindowwhilethealertdialogispresent;toworkwiththeoriginalwindow,weneedtoclosethealertdialog.
OniOS,analertdialogboxcanbehandledbytheSeleniumAlertAPIbutonAndroidOS,alerthandlingisnotyetimplementedfornativeapps.However,wehaveanalternativetohandlethealert.Wecanfindthebuttonsthatarepresentonthealertboxusinglocatorstrategy.
Let’stakeanexampleoftheAndroidUIapp,whichcanbedownloadedfromhttps://github.com/manojhans/Appium/blob/master/Application/Android/AndroidUI.zip?raw=true.Thedownloadedappwillbelooklike:
Now,let’sperformthefollowingstepstohandlethealert:
1. Createanewclasswiththefollowingcode:
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
Fileapp=newFile("C:\\mobileapp\\AndroidUI.apk");//Youcanchangeit
withyourappaddress
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.APP,app);
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasaRealDevice
caps.setCapability("appPackage","com.android.androidui");//Thisis
packagenameofyourapp(youcangetitfromapkinfoapp)
caps.setCapability("appActivity",
"com.android.androidui.MainActivity");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementshowAlert=driver.findElement(By.name("ShowAlert"));
showAlert.click();//itwillopentheAlertbox
WebElementyes=driver.findElement(By.name("Yes"));
yes.click();//ClickonYesbutton
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
2. Now,executethetestscript:
Wesawhowwecouldhandleanalertdialogboxbylocatingthebutton,butthisisnotthepreferredwaytohandleit.TheAppiumcommunityhopesthatwesoongetsomesupportviatheAlertAPI.
Inthecaseofhybridandwebapps,wefirstneedtoswitchfromwebviewtonativeapps,asshowninthefollowingsnippet:
Set<String>allContext=driver.getContextHandles();
for(Stringcontext:allContext){
if(context.contains("NATIVE")){
driver.context(context);//switchonthenativeapp
}
}
Then,wecanhandlethealertinthesamewayasanativeapp.Inthenextsection,wewilllearnhowtoselectavaluefromadrop-downlist.
SpinnersSpinnersallowyoutoselectavaluefromthedropdownlistandalsoshowthecurrentlyselectedvalue.Now,wearegoingtotakeanexampleoftheAndroidUIapp,whichweusedinalerthandling.
Now,let’sperformthefollowingstepstoselectthevaluefromdropdown:
1. First,weneedtofindthespinner;wewillfinditusingid:
WebElementspinner=driver.findElement(By.id("android:id/text1"));
Youshouldgetsomethingsimilartothefollowingscreen:
2. Now,clickonthespinner;itwillopenthelistofvalues:
spinner.click();
3. SelectthecountryasIndia,butfirstweneedtoscrollinordertoviewIndiaasname:
driver.scrollToExact("India");
WebElementoptionIndia=driver.findElement(By.name("India"));
optionIndia.click();
Youshouldgetsomethingsimilartothisscreen:
4. Thisishowthecodesnippetwilllook:
@Test
publicvoidtestExample(){
WebElementspinner=driver.findElement(By.id("android:id/text1"));
spinner.click();
driver.scrollToExact("India");
WebElementoptionIndia=driver.findElement(By.name("India"));
optionIndia.click();
}
Wejustsawhowtoselectavaluefromthedrop-downlist.Inthenextsection,wewilllearnhowtohandletheswitchbutton.
TheswitchbuttonSwitchesareusedtochangethesettingsoptions;thiscanbeeasilyhandledinAppium.
AswitchcanbeturnedON/OFFbyjustclickingonit.WecanusethefollowingcodesnippettohandleAndroidswitches(usingtheAndroidUIapp):
@Test
publicvoidtestExample(){
WebElementswitchbtn=driver.findElementById
("com.android.androidui:id/mySwitch");
switchbtn.click();
}
Youshouldgetthefollowingscreenshot:
WelearnedhowwecanhandletheAndroidswitches.Inthenextsection,wewilltakealookattheprogressbar(SeekBar).
TheslideSeekBarASeekBarisanextensionoftheprogressbar,whichallowsyoutosettheprogresslevelbyslidingittotheleftorrightusingthethumb.
ItisalittletrickytohandlethisinAppium;let’stakeanexamplethatshowshowtoslidetheSeekBar.Here,wearegoingtousetheAndroidUIappagain.
Todothis,weneedtoperformthefollowingsteps:
1. First,weneedtofindtheSeekBar;wewillfinditwithid:
WebElement
slider=driver.findElementById("com.android.androidui:id/seekBar1");
Then,weneedtogettheSeekBar’sstartpointandendpointlocations,asfollows:
intxAxisStartPoint=slider.getLocation().getX();
intxAxisEndPoint=xAxisStartPoint+slider.getSize().getWidth();
2. Now,gettheSeekBar’syaxis:
intyAxis=slider.getLocation().getY();
3. Now,wewillusethetouchActionclasstoslidetheSeekBar:
TouchActionact=newTouchAction(driver);
act.press(xAxisStartPoint,yAxis).moveTo(xAxisEndPoint-
1,yAxis).release().perform();
4. Thisishowthecodesnippetwilllook:
@Test
publicvoidtestExample(){
WebElement
slider=driver.findElementById("com.android.androidui:id/seekBar1");
intxAxisStartPoint=slider.getLocation().getX();
intxAxisEndPoint=xAxisStartPoint+slider.getSize().getWidth();
intyAxis=slider.getLocation().getY();
TouchActionact=newTouchAction(driver);
act.press(xAxisStartPoint,yAxis).moveTo(xAxisEndPoint-
1,yAxis).release().perform();//pressedxaxis&yaxisofseekbarand
moveseekbartilltheend
}
5. Afterexecutionofthetestcode,thisishowtheSeekBarwilllook:
WehavejustseenhowwecanslidetheSeekBarusingthetouchActionclass.Now,inthenextsection,wearegoingtolearnhowtocaptureascreenshotofamobileapp.
CapturingscreenshotsThistopicisnotnecessarytoshowAppiumfunctionalitiesbutwillbeconvenientwhenthereareproblemswithyourtestapplicationandyouwanthavemoreinformation.Basically,ascreenshotiscapturedforreportingpurposes,whenthetestfails.
Therearethreeapproachestotakingscreenshots:
ByteBase64File
Here,wewilluseafiletosaveascreenshot.Let’stakeascreenshotofthecalculatorapp,asshownhere:
1. Createanewclasswiththefollowingtestcode:
AndroidDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasaRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.calculator2");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.calculator2.Calculator");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample(){
WebElementfive=driver.findElement(By.name("5"));//thiselementis
usetowaitforappopen
FilescreenShot=driver.getScreenshotAs(OutputType.FILE);
Filelocation=newFile("screenshots");
String
screenShotName=location.getAbsolutePath()+File.separator+"testCalculato
r.png";
FileUtils.copyFile(screenShot,newFile(screenShotName));
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
2. Inthissection,wehavecapturedascreenshotandsaveditinaprojectunderthescreenshotsfolder:
Ifwecancapturescreenshotsontestfailure,itwillbetheicingonthecake!Inthenextsection,wewillseehowtotakeascreenshotontestfailure.
CapturingscreenshotsontestfailureNowthatwearefamiliarwithcapturingscreenshots,wearegoingtotakealookathowtocapturescreenshotsontestfailureinthissection.Here,wewilluseTestNGlisteners;listenersbasicallyrunonparticularevents.Aneventcanbeanythingsuchastestpassed,failed,orskipped.
TestNGgivesustheflexibilitytochooselistenersasperourrequirement,sowearegoingtouseTestListenerAdapter,whichhasmethodstooverridewhenthetestfails.So,let’swritethecodeforascreenshotontestfailure.
Weneedtocreatetwoclasses:oneforthelistenerandanotherforthetestcode;weneedtoimportthefollowingpackages:
importio.appium.java_client.AppiumDriver;
importjava.io.File;
importjava.io.IOException;
importorg.apache.commons.io.FileUtils;
importorg.openqa.selenium.OutputType;
importorg.testng.ITestResult;
importorg.testng.TestListenerAdapter;
Performthefollowingstepstocapturescreenshotsontestfailure:
1. Createanewclasswiththefollowingcode:
publicclassScreenshotListenerextendsTestListenerAdapter{
@Override
publicvoidonTestFailure(ITestResulttr){
AppiumDriverdriver=Screenshot.getDriver();//gettingdriverinstance
fromTestApplicationclass
Filelocation=newFile("screenshots");//itwillcreatescreenshots
folderintheproject
StringscreenShotName=location.getAbsolutePath()+File.separator+
tr.getMethod().getMethodName()+".png";
//GettingfailuremethodnameusingITestResult
FilescreenShot=driver.getScreenshotAs(OutputType.FILE);
try{
FileUtils.copyFile(screenShot,newFile(screenShotName));
}
catch(IOExceptione){
e.printStackTrace();
}
}
}
2. Wecanusethislistenerinanyclass,whichhasunittestcases,[email protected]’screateanotherclasstousethislistener,asshownhere:
@Listeners({ScreenshotListener.class})
publicclassScreenshot{
staticAppiumDriverdriver;
@BeforeClass
publicvoidsetUp()throwsMalformedURLException{
DesiredCapabilitiescaps=newDesiredCapabilities();
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION,"4.4");
caps.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME,"MotoX");//Iam
usingMotoXasaRealDevice
caps.setCapability(MobileCapabilityType.APP_PACKAGE,
"com.android.calculator2");
caps.setCapability(MobileCapabilityType.APP_ACTIVITY,
"com.android.calculator2.Calculator");
driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),
caps);
driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);
}
@Test
publicvoidtestExample()throwsIOException{
WebElementtwo=driver.findElement(By.name("2"));
two.click();
WebElementplus=driver.findElement(By.name("+"));
plus.click();
WebElementfour=driver.findElement(By.name("4"));
four.click();
WebElementequalTo=driver.findElement(By.name("="));
equalTo.click();
WebElement
result=driver.findElement(By.className("android.widget.EditText"));
//Checkthecalculatedvalueontheeditbox
assertresult.getText().equals("8"):"Actualvalueis:
"+result.getText()+"didnotmatchwithexpectedvalue:8";
}
@AfterClass
publicvoidtearDown(){
driver.closeApp();
}
publicstaticAppiumDrivergetDriver(){
returndriver;
}
}
3. Intheexample,weareputtingthefalseconditiontofailthetest;oncethetestfails,theScreenshotListenerclasswillbecalledautomaticallyandwilltakeascreenshotofthemobileapp:
NoteTolearnmoreaboutTestNGlisteners,youcanvisithttp://testng.org/doc/documentation-main.html#testng-listeners.
SummaryWelearnedhowtohandlemobilegesturesusingtheAppiumadvancedinteractionAPI,suchasTouchActionandMultiTouchAction.
WestartedoffbylearningabouttheadvanceduserinteractionsAPI.Wethenmovedontochainingmultipleactionsonmobileappsandobservedsomeactionsthatarefrequentlyusedonthemobile,withthehelpoftheAppiumclientlibrary.Wealsolookedathowtocapturescreenshotsandhowtosavethemtothedesiredlocation.Lastly,weusedtheTestNGlistenertocapturescreenshotsontestfailure.
Ihopethisbookhasassistedand/orinspiredyoutoperformmobileappsautomation.Intheend,ifyoustillhavequestionsrelatedtoappsautomation,shootmeane-mailat<[email protected]>;Iwillbehappytohelpyou!
IndexA
advanceduserinteractionsabout/Exploringadvanceduserinteractionslongpress,using/Longpressscrolling/Scrollandswipeswiping/Scrollandswipeswipingprocess/Scrollandswipedraganddropoperation/Draganddroppinchandzoomgesture/Pinchandzoomalertdialogbox/Alertsspinners/Spinnersswitchbutton/TheswitchbuttonslideSeekBar/TheslideSeekBarscreenshots,capturing/Capturingscreenshotsscreenshots,capturingontestfailure/Capturingscreenshotsontestfailure
alertdialogbox/AlertsAndroid
prerequisites/Importantinitialpoints,Importantinitialpointsdesiredcapabilities/NecessarydesiredcapabilitiesforAndroidandinitiatingtheAndroiddriver
Androidcapabilitiesabout/AndroidcapabilitiesappPackage/AndroidcapabilitiesappActivity/AndroidcapabilitiesappWaitActivity/AndroidcapabilitiesappWaitPackage/AndroidcapabilitiesdeviceReadyTimeout/AndroidcapabilitiesenablePerformanceLogging/AndroidcapabilitiesandroidDeviceReadyTimeout/AndroidcapabilitiesandroidDeviceSocket/AndroidcapabilitiesAvd/AndroidcapabilitiesavdLaunchTimeout/AndroidcapabilitiesavdReadyTimeout/AndroidcapabilitiesavdArgs/AndroidcapabilitieschromedriverExecutable/AndroidcapabilitiesautoWebviewTimeout/AndroidcapabilitiesintentAction/AndroidcapabilitiesintentCategory/AndroidcapabilitiesintentFlags/AndroidcapabilitiesunicodeKeyboard/AndroidcapabilitiesresetKeyboard/Androidcapabilities
Androiddriverinitiating/NecessarydesiredcapabilitiesforAndroidandinitiatingtheAndroiddriver,DesiredcapabilitiesforAndroidandinitiatingtheAndroiddriver
Androidemulator/AnAndroidemulatorAndroidhybridapp/AndroidhybridappsAndroidhybridapps
desiredcapabilities/Desiredcapabilitiesfornativeandhybridappsabout/Androidhybridapps
Androidnativeapp/AndroidnativeappsAndroidnativeapps
desiredcapabilities/Desiredcapabilitiesfornativeandhybridappsabout/NativeAndroidapps
Androidrequirements,onMacabout/AndroidrequirementsonWindowsandMac
Androidrequirements,onWindowsabout/AndroidrequirementsonWindowsandMac
AndroidSDKinstalling/InstallingtheAndroidSDKURL/InstallingtheAndroidSDK
AndroidSettings,AppiumGUIforMacabout/AndroidSettings
AndroidSettings,AppiumGUIforWindowsabout/AndroidSettingsApplicationpane/ApplicationLaunchDevicepane/LaunchDeviceCapabilitiespane/CapabilitiesAdvancedpane/Advanced
AndroidSettings,AppiumGUIsettings/NecessarydesiredcapabilitiesforAndroidandinitiatingtheAndroiddriverAndroidUIapp
URL/AlertsAndroidwebapp
desiredcapabilities/Desiredcapabilitiesforwebappsabout/WebappsonAndroid
Appiumarchitecture/Appiumarchitectureworking,iniOS/AppiumoniOSworking,inAndroid/AppiumonAndroidsession/Appiumsessionserver/TheAppiumserveranditsclientlibrariesclientlibraries/TheAppiumserveranditsclientlibrariesadvantages/TheAppiumserveranditsclientlibraries,Appium–prosandconsabout/Appium–prosandconsdisadvantages/Appium–prosandcons
installing,forAndroid/AppiuminstallationforAndroidURL/AppiumforWindows
Appiumdoctor,AppiumGUIforMac/AppiumdoctorAppiumGUI,forMac
about/TheAppiumGUIforMacAndroidSettings/AndroidSettingsiOSSettings/iOSSettingsRobotSettings/RobotSettingsSave/Openconfiguration/Save/OpenconfigurationAppiumdoctor/AppiumdoctorInspector/InspectorRecordingpanel/TheRecordingpanel
AppiumGUI,forWindowsabout/TheAppiumGUIforWindows,AboutAndroidSettings/AndroidSettingsGeneralSettings/GeneralSettingsDevelopersettings/DevelopersettingsInspector/Inspector
AppiumInspectorLaunch/Stopbutton/TheLaunch/StopbuttonClearbutton/TheClearbuttonelements,findingwith/FindingelementswithAppiumInspector
Appiuminstallation,forAndroidJDK,installingonWindows/InstallingJDKonWindowsAndroidSDK,installing/InstallingtheAndroidSDKsystemvariables,settingforMac/SettingthesystemvariablesforMac
Appiuminstallation,foriOSabout/AppiumforiOSXcode,installing/InstallingXcodeHomebrew,installing/InstallingHomebrewNode/Nodeandnpmnpm/Nodeandnpm
Appiuminstallation,forMacabout/AppiumforMac
Appiuminstallation,forWindowsabout/AppiumforWindows
AppiumJavaclientURL/DownloadingthenecessaryJARfiles
AppiumphilosophyURL/Appium–prosandcons
Appiumserverabout/TheAppiumserver
AppUnderTest(AUT)/Appium–prosandcons
BBMIcalculator
URL/iOSnativeapps
CChromeADBplugin
used,forfindingelements/FindingelementsforAndroidweb-basedappsusingtheChromeADBplugin
Clearbutton,AppiumInspector/TheClearbutton
Ddesiredcapabilities
about/DesiredcapabilitiesautomationName/DesiredcapabilitiesplatformName/DesiredcapabilitiesplatformVersion/DesiredcapabilitiesdeviceName/Desiredcapabilitiesapp/DesiredcapabilitiesbrowserName/DesiredcapabilitiesnewCommandTimeout/DesiredcapabilitiesautoLaunch/Desiredcapabilitieslanguage/Desiredcapabilitieslocale/Desiredcapabilitiesudid/Desiredcapabilitiesorientation/DesiredcapabilitiesautoWebview/DesiredcapabilitiesfullReset/DesiredcapabilitiesAndroidcapabilities/AndroidcapabilitiesiOScapabilities/iOScapabilitiesused,forAndroid/DesiredcapabilitiesforAndroidandinitiatingtheAndroiddriverused,fornativeapp/Desiredcapabilitiesfornativeandhybridapps,DesiredcapabilitiesfornativeandhybridAppsused,forhybridapp/Desiredcapabilitiesfornativeandhybridapps,DesiredcapabilitiesfornativeandhybridAppsused,forwebapps/Desiredcapabilitiesforwebapps,Desiredcapabilitiesforwebappsused,foriOS/DesiredcapabilitiesforiOSandinitiatingtheiOSdriveriOSdriver,initiating/DesiredcapabilitiesforiOSandinitiatingtheiOSdriver
Developersettings,AppiumGUIforWindows/DevelopersettingsDevelopoption,Safari
elements,findingforiOSweb-basedapps/FindingelementsforiOSweb-basedappsusingSafari’sDevelopoption
draganddropoperation/Draganddrop
EEclipseJavaproject
settingup/SettingupanEclipseJavaprojectURL/SettingupanEclipseJavaproject
elementsfinding,forAndroidweb-basedapps/FindingelementsforAndroidweb-basedappsusingtheChromeADBpluginfinding,foriOSweb-basedapps/FindingelementsforiOSweb-basedappsusingSafari’sDevelopoptionfinding,fornativeapp/Findingelementsfornativeandhybridappsfinding,forhybridapp/Findingelementsfornativeandhybridappsfinding,withUIAutomatorviewer/FindingelementswithUIAutomatorviewerfinding,withAppiumInspector/FindingelementswithAppiumInspector
elements,foriOSweb-basedappsfinding,byID/FindingelementsbyIDfinding,byname/Findingelementsbynamefinding,bylinkText/FindingelementsbylinkTextfinding,byXpath/FindingelementsbyXpathfinding,bycssSelector/FindingelementsbycssSelector
elements,withAppiumInspectorfinding,byXpath/FindingelementsbyXpathfinding,byname/Findingelementsbynamefinding,byIosUIAutomation/FindingelementsbyIosUIAutomation
elements,withUIAutomatorviewerfinding,byID/FindingelementsbyIDfinding,byname/Findingelementsbynamefinding,byclassName/FindingelementsbyclassNamefinding,byAccessibilityId/FindingelementsbyAccessibilityIdfinding,byAndroidUIAutomator/FindingelementsbyAndroidUIAutomator
emulatorscreating/CreatingemulatorsandsimulatorsAndroidemulator/AnAndroidemulator
endpointsURL/TheSeleniumJSONwireprotocol
Ffields,Advancedpane
SDKPath/AdvancedCoverageClass/AdvancedBootstrapPort/AdvancedSelendroidPort/AdvancedChromedriverPort/Advanced
fields,ApplicationpaneApplicationPath/ApplicationPackage/ApplicationWaitforPackage/ApplicationLaunchActivity/ApplicationWaitforActivity/ApplicationUseBrowser/ApplicationFullReset/ApplicationNoReset/ApplicationIntentAction/ApplicationIntentCategory/ApplicationIntentFlags/ApplicationIntentArguments/Application
fields,CapabilitiespanePlatformName/CapabilitiesAutomationName/CapabilitiesPlatformVersion/CapabilitiesDeviceName/CapabilitiesLanguage/CapabilitiesLocale/Capabilities
fields,DevelopersettingsEnabled/DevelopersettingsUseExternalNodeJSBinary/DevelopersettingsUseExternalAppiumPackage/DevelopersettingsNodeJSDebugPort/DevelopersettingsBreakonApplicationStart/DevelopersettingsCustomServerFlags/Developersettings
fields,LaunchDevicepaneLaunchAVD/LaunchDeviceDeviceReadyTimeout/LaunchDeviceArguments/LaunchDevice
fields,LoggingpaneQuietLogging/LoggingShowTimestamps/LoggingLogtoFile/LoggingLogtoWebHook/Logging
UseLocalTimezone/Loggingfields,Serverpane
ServerAddress/ServerPort/ServerCheckforUpdates/ServerOverrideExistingSession/ServerUseRemoteServer/ServerSeleniumGridConfigurationFile/Server
GGeneralSettings,AppiumGUIforWindows
about/GeneralSettingsServerpane/ServerLoggingpane/Logging
GsonURL/DownloadingthenecessaryJARfiles
HHomebrew
installing/InstallingHomebrewhybridapps
automating/AutomatinghybridappsAndroidhybridapp/AndroidhybridappsiOShybridapp/iOShybridapps
hybridappsautomationabout/Hybridapps’automationAndroidhybridapps/AndroidhybridappsiOShybridapps/iOShybridapps
IInspector,AppiumGUIforMac/InspectoriOS
prerequisites/Importantinitialpoints,Importantinitialpointsdesiredcapabilities/NecessarydesiredcapabilitiesforiOSandinitiatingtheiOSdriverinitiating/NecessarydesiredcapabilitiesforiOSandinitiatingtheiOSdriver
ios-webkit-debug-proxyinstalling/Installingprovisionalprofile,SafariLauncher,andios-webkit-debug-proxyabout/SafariLauncherappandios-webkit-debug-proxy
iOScapabilitiesabout/iOScapabilitiescalendarFormat/iOScapabilitiesbundleId/iOScapabilitieslaunchTimeout/iOScapabilitieslocationServicesEnabled/iOScapabilitieslocationServicesAuthorized/iOScapabilitiesautoAcceptAlerts/iOScapabilitiesnativeInstrumentsLib/iOScapabilitiesnativeWebTap/iOScapabilitiessafariAllowPopups/iOScapabilitiessafariIgnoreFraudWarning/iOScapabilitiessafariOpenLinksInBackground/iOScapabilitieskeepKeyChains/iOScapabilitiesprocessArguments/iOScapabilitiesinterKeyDelay/iOScapabilities
iOSDeveloperProgramURL/Provisionalprofile
iOShybridapp/iOShybridappsiOShybridapps
desiredcapabilities/Desiredcapabilitiesfornativeandhybridappsabout/iOShybridapps
iOSnativeapp/iOSnativeappsiOSnativeapps
about/NativeiOSappsiOSrequirements
about/iOSrequirementsiOSsettings
forwebapps/DesiredcapabilitiesforiOSandinitiatingtheiOSdriveriOSSettings,AppiumGUIforMac
about/iOSSettingsApplicationtab/Application
DeviceSettingstab/DeviceSettingsAdvancedtab/Advanced
iOSsimulator/AniOSsimulatoriOSTestApp
URL,forexample/NativeiOSappsiOSwebapps
desiredcapabilities/Desiredcapabilitiesforwebappsabout/WebappsoniOS
JJARfiles
downloading/DownloadingthenecessaryJARfilesJDK
installing,onWindows/InstallingJDKonWindowsJSONwireprotocol(JSONWP)/TheSeleniumJSONwireprotocol
LLaunch/Stopbutton,AppiumInspector/TheLaunch/Stopbuttonlongpress
using/Longpress
Nnativeapps
automating/Automatingnativeapps,AutomatingnativeappsAndroidnativeapps/NativeAndroidappsiOSnativeapps/NativeiOSappsAndroidnativeapp/AndroidnativeappsiOSnativeapp/iOSnativeapps
Ooptions,Advancedtab
UseNativeInstrumentsLibrary/AdvancedBackendRetries/AdvancedInstrumentsLaunchTimeout/AdvancedTraceTemplatePath/AdvancedChoose/AdvancedXcodePath/Advanced
options,ApplicationtabAppPath/ApplicationChoose/ApplicationBundleID/ApplicationUseMobileSafari/Application
options,DeviceSettingstabForceDevice/DeviceSettingsPlatformVersion/DeviceSettingsForceOrientation/DeviceSettingsForceLanguage/DeviceSettingsForceCalendar/DeviceSettingsForceLocale/DeviceSettingsUDID/DeviceSettingsFullReset/DeviceSettingsNoReset/DeviceSettingsShowSimulatorLog/DeviceSettings
Ppinchandzoomgesture/Pinchandzoomprovisionalprofile
installing/Installingprovisionalprofile,SafariLauncher,andios-webkit-debug-proxyabout/Provisionalprofile
RRecordingpanel,AppiumGUIforMac/TheRecordingpanelRobotSettings,AppiumGUIforMac/RobotSettings
SSafariLauncherapp
installing/Installingprovisionalprofile,SafariLauncher,andios-webkit-debug-proxyabout/SafariLauncherappandios-webkit-debug-proxy
Save/Openconfiguration,AppiumGUIforMac/Save/Openconfigurationscrollingprocess/ScrollandswipeSeleniumJSONwireprotocol
about/TheSeleniumJSONwireprotocolSeleniumServer
URL/DownloadingthenecessaryJARfilessimulators
creating/CreatingemulatorsandsimulatorsiOSsimulator/AniOSsimulator
slideSeekBar/TheslideSeekBarspinners/Spinnersswipingprocess/Scrollandswipeswitchbutton/Theswitchbuttonsystemrequirements,forAndroid
about/SystemrequirementsforAndroid/iOSsystemrequirements,foriOS
about/SystemrequirementsforAndroid/iOS
TtestApp,GitHub
URL,forexample/AndroidhybridappsTestNG
installing/SettingupanEclipseJavaprojectTestNGlisteners
URL/Capturingscreenshotsontestfailure
UUIAutomatorlibrary
URL/FindingelementsbyAndroidUIAutomatorUIAutomatorviewer
elements,findingwith/FindingelementswithUIAutomatorviewerUSBdebugging
enabling/Importantinitialpoints
Wweb-apps
workingwith/Workingwithweb-appswebapps
workingwith/WorkingwithwebappsonAndroid/WebappsonAndroidoniOS/WebappsoniOS
WebDriverJavaclientURL/DownloadingthenecessaryJARfiles
WebViewApp,GitHubURL,forexample/iOShybridapps
XXcode
installing/InstallingXcodeURL/InstallingXcode