SlideShare a Scribd company logo
Appium Automation with Kotlin
Appium Automation with Kotlin
© RapidValue Solutions 2
Appium Automation with Kotlin
Pre-requisites:
Following are the pre-requisites to start Appium with Kotlin:
 Install Java SDK 8 and above.
 Install Eclipse or IntelliJ IDEA IDEs.
 Install the Kotlin plugin in IDEs. Here I am using Eclipse as IDE and Kotlin plugin for Eclipse
downloaded from https://marketplace.eclipse.org/content/kotlin-plugin-eclipse
 The latest version of following maven dependencies:
o testing
o selenium-java
o selenium-server
o java-client
o kotlin-test
o kotlin-stdlib-jdk8
o extentreports
Step-by-step Procedure
Step 1: Create a maven project and add the above dependencies in pom.xml of the project.
Step 2: Create a Kotlin class to keep the logic to initiate the driver and start the Appium server. Let’s say the
class name is AutomationBase. We are defining this class as an abstract class. So, it is easy to extend by
other classes. We have implemented startApplication, startAppiumServer, getPort, getNodePath,
getJSPath, getDriverInstance and setDriverInstance methods in the AutomationBase class. Below are
the sample code snippets:
fun startApplication() {
try {
var service: AppiumDriverLocalService = startAppiumServer()
var capabilities = DesiredCapabilities()
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, “One Plus”)
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, “Android”)
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, “10”)
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME,
AutomationName.ANDROID_UIAUTOMATOR2)
capabilities.setCapability(AndroidMobileCapabilityType.AUTO_GRANT_PERMISSIONS, true)
capabilities.setCapability(“newCommandTimeout”, 180)
capabilities.setCapability(“udid”, “e6916f40”)
capabilities.setCapability(MobileCapabilityType.APP, “YOUR_APP_PATH”)
capabilities.setCapability(MobileCapabilityType.NO_RESET, true)
if(!service.toString().isEmpty()){
driver = AndroidDriver(service.getUrl(), capabilities)
}
} catch (e: Exception) {
Appium Automation with Kotlin
© RapidValue Solutions 3
e.printStackTrace()
}
}
private fun startAppiumServer(): AppiumDriverLocalService {
var IP_ADDRESS: String = “127.0.0.1”
var bootStrapPort: String
var chromePort: String
var port: Int
if (!File(System.getProperty(“user.dir”) + “LogsAppium_logs”).exists()) {
(File(System.getProperty(“user.dir”) + “Logs”)).mkdir()
(File(System.getProperty(“user.dir”) + “LogsAppium_logs”)).mkdir()
}
port = getPort()
bootStrapPort = Integer.toString(getPort())
chromePort = Integer.toString(getPort())
var service = AppiumDriverLocalService.buildService(
AppiumServiceBuilder().withAppiumJS(File(getJSPath()))
.usingDriverExecutable(File(getNodePath())).withIPAddress(IP_ADDRESS).usingPort(port)
.withArgument(AndroidServerFlag.BOOTSTRAP_PORT_NUMBER, bootStrapPort)
.withArgument(AndroidServerFlag.CHROME_DRIVER_PORT, chromePort)
.withLogFile(File(System.getProperty(“user.dir”) + “LogsAppium_logsappiumLogs.txt”)))
service.start()
if (service.isRunning()) {
System.out.println(“Server is running
..” + service)
} else {
System.out.println(“Server startup failed
..”)
System.exit(0)
}
return service
}
private fun getPort(): Int {
var port: Int = 0
try {
var socket = ServerSocket(0)
socket.setReuseAddress(true)
port = socket.getLocalPort()
socket.close()
} catch (e: Exception) {
e.printStackTrace()
}
return port
}
private fun getNodePath(): String {
var nodePath: String
var p: Process
var reader: BufferedReader
var command: String
Appium Automation with Kotlin
© RapidValue Solutions 4
var operatingSystem: String = System.getProperty(“os.name”)
if (operatingSystem.contains(“Win”)) {
command = “where” + ” ” + “node”
} else {
command = “which ” + “node”
}
p = Runtime.getRuntime().exec(command)
reader = BufferedReader(InputStreamReader(p.getInputStream()))
nodePath = reader.readLine()
p.waitFor()
p.destroy()
return nodePath
}
fun getJSPath(): String {
var jsPaths: String
lateinit var actualJSPath: String
var command: String
var operatingSystem: String = System.getProperty(“os.name”)
if (operatingSystem.contains(“Win”)) {
command = “where” + ” ” + “appium”
var p: Process = Runtime.getRuntime().exec(command)
var stdInput: BufferedReader = BufferedReader(InputStreamReader(p.getInputStream()))
jsPaths = stdInput.readLine()
actualJSPath = jsPaths.replace(“appium”, “node_modulesappiumbuildlibmain.js”)
p.waitFor()
p.destroy()
} else {
actualJSPath = “//usr//local//lib//node_modules//appium//build//lib//main.js”
}
return actualJSPath
}
fun getDriverInstance(): WebDriver {
return this.driver
}
fun setDriverInstance(driver: WebDriver) {
this.driver = driver
}
startApplication method helps to instantiate driver sessions based on the specified capabilities.
startAppiumServer method helps to start the Appium server and also, create and write server logs to a text
file. getPort method helps to create the dynamic network port that supports the startAppiumServer
method. getNodePath method helps to get the node path and it supports the startAppiumServer method.
getJSPath method helps to get the Appium main.js path and it supports the startAppiumServer method.
Step 3: Create a TestRunner class and it extends AutomationBase class. This class holds TestNG
annotations @Listeners, @BeforeClass, and @AfterSuite. Below are the complete code snippets:
Appium Automation with Kotlin
© RapidValue Solutions 5
@Listeners(AutomationReport::class)
open class TestRunner : AutomationBase() {
@BeforeClass
fun setUp() {
startApplication()
}
@AfterSuite
fun tearDown() {
Thread.sleep(3000)
driver.quit()
}
}
Step 4: Create a sample test class to keep the test cases. Let’s call it SampleTests and it
extends TestRunner class. Following are the sample code snippets:
class SampleTests : TestRunner() {
@Test
fun TC001_testEnterPincode() {
SampleTestsHelper.enterPinCode(driver, “682030”)
}
@Test
fun TC002_testSearchFail() {
Assert.fail()
}
}
Step 5: Create a Kotlin class which should act as a helper class of test class. Let’s call it
SampleTestsHelper and define this SampleTestsHelper as object. So, Kotlin will create an instance
automatically when we invoke the methods of SampleTestsHelper. No need to create a separate instance to
invoke the methods of the helper class. Below are the complete code snippets:
object SampleTestsHelper {
/**
* This method used to enter pin code
*
* @author sanojs
* @since 01-09-2020
*/
fun enterPinCode(driver: WebDriver, valueToSearch: String) {
Appium Automation with Kotlin
© RapidValue Solutions 6
try {
driver.findElement(By.id(“in.dmart:id/et_activity_pincode_pincode”)).sendKeys(pincod)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
Step 6: Create a Kotlin class to keep the logic to generate an Automation test execution report in HTML
format. Let’s say the class name as AutomationReport. Here, we are using extentreports library to
generate an HTML report. Also, we are using ITestListener interface to control the executions and results.
Below are the complete code snippets of the AutomationReport class,
class AutomationReport : ITestListener {
public lateinit var sparkReporter: ExtentSparkReporter
public lateinit var extentReport: ExtentReports
public lateinit var extentTest: ExtentTest
/**
* This override method used to create HTML template for the test report
*
* @author sanojs
* @since 01-09-2020
*/
override fun onStart(testContext: ITestContext) {
try {
sparkReporter = ExtentSparkReporter(System.getProperty(“user.dir”) + “/AutomationReport/”)
sparkReporter.config().setDocumentTitle(“Appium Kotlin Automation”)
sparkReporter.config().setReportName(“Automation Execution Report”)
sparkReporter.config().setTheme(com.aventstack.extentreports.reporter.configuration.Theme.DARK)
extentReport = ExtentReports()
extentReport.attachReporter(sparkReporter)
extentReport.setSystemInfo(“Application Name”, “Kotlin Appium Demo”)
extentReport.setSystemInfo(“Platform”, System.getProperty(“os.name”))
extentReport.setSystemInfo(“Environment”, “QA”)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* This override method used to collect current test case name add to the report
*
* @author sanojs
* @since 01-09-2020
*/
override fun onTestStart(result: ITestResult) {
var testName: String = result.getMethod().getMethodName()
extentTest = extentReport.createTest(testName)
Appium Automation with Kotlin
© RapidValue Solutions 7
}
/**
* This override method used to add pass status to the report
*
* @author sanojs
* @since 01-09-2020
*/
override fun onTestSuccess(result: ITestResult) {
var testName: String = result.getMethod().getMethodName()
try {
extentTest.log(
Status.PASS,
MarkupHelper.createLabel(testName + ” Test Case PASSED”, ExtentColor.GREEN)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* This override method used to add fail status to the report
*
* @author sanojs
* @since 01-09-2020
*/
override fun onTestFailure(result: ITestResult) {
var driver: WebDriver
var currentClass = result.getInstance()
var testName: String = result.getMethod().getMethodName()
try {
driver = (currentClass as AutomationBase).getDriverInstance()
var screenshotPath = Utilities().screenshotCapture(driver, result.getName())
extentTest.log(
Status.FAIL,
MarkupHelper.createLabel(testName + ” Test Case FAILED”, ExtentColor.RED)
)
extentTest.log(
Status.FAIL,
MarkupHelper.createLabel(“Reason for Failure: ” + result.getThrowable().toString(),
ExtentColor.RED)
)
extentTest.addScreenCaptureFromPath(screenshotPath)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* This override method used to add skip status to the report
*
* @author sanojs
* @since 01-09-2020
*/
Appium Automation with Kotlin
© RapidValue Solutions 8
override fun onTestSkipped(result: ITestResult) {
var testName: String = result.getMethod().getMethodName()
try {
extentTest.log(
Status.SKIP,
MarkupHelper.createLabel(testName + ” Test Case SKIPPED”, ExtentColor.ORANGE)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* This override method used to store HTML report to the specified path and flush extent report
instance
*
* @author sanojs
* @since 01-09-2020
*/
override fun onFinish(testContext: ITestContext) {
try {
extentReport.flush()
val dateFormat = SimpleDateFormat(“dd-MMM-yyyy_HH-mm-ss”)
val date = Date()
val filePathdate: String = dateFormat.format(date).toString()
var actualReportPath: String = System.getProperty(“user.dir”) + “/AutomationReport/” +
“index.html”
File(actualReportPath).renameTo(
File(
System.getProperty(“user.dir”) + “/AutomationReport/”
+ “Automation_Report_” + filePathdate + “.html”
)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
Step 7: Create another class called Utilities to keep common utility functions required for automation. Here,
we just added one utility to capture the screenshot. Below is the code snippet to capture the screenshot,
fun screenshotCapture(driver: WebDriver, fileName: String): String {
var destination: String = “”
try {
var scrFile = (driver as TakesScreenshot).getScreenshotAs(OutputType.FILE)
var dateFormat = SimpleDateFormat(“yyyyMMddHHmmss”)
var cal = Calendar.getInstance()
var path = File(“Failure_Screenshots”).getAbsolutePath()
destination = path + “/” + fileName + dateFormat.format(cal.getTime()) + “.png”
scrFile.copyTo(File(destination))
Appium Automation with Kotlin
© RapidValue Solutions 9
} catch (e: Exception) {
e.printStackTrace()
}
return destination
}
Step 8: Add a testng.xml file into the project structure and map your test classes into the testng.xml to run
the test cases. Once the execution is complete, the HTML report will get generated inside
the AutomationReport folder in the project structure.
Below is the overall project structure of Appium with Kotlin:
NOTE:
 Kotlin Runtime Library will automatically get added to the build path of the project when you create
a Kotlin class under any package.
 Kotlin class extension is .kt
 The semicolon is not mandatory to end the statements in the class.
 While inheriting a class from a parent class you have to declare the parent class as open, using
an open keyword or you can declare the parent class as abstract using abstract. You can’t inherit a
singleton class. So avoid extending the class which is declared as object in Kotlin.
 If you declare a class with an object keyword then no need to create an instance. Kotlin will create
an instance to access the methods or variables of that class.
Appium Automation with Kotlin
© RapidValue Solutions 10
Conclusion
Kotlin is a general-purpose, open-source, statically typed programming language that combines object-
oriented and functional programming features. So, Kotlin is a strong and powerful language that helps the
automation engineers to write their automation script for Appium. This article aims to help the Appium
automation engineers to upskill and write their scripting in a different language such as Kotlin.
By,
Sanoj S, Test Architect, RapidValue
Appium Automation with Kotlin
© RapidValue Solutions 11
About RapidValue
RapidValue is a global leader in digital product engineering solutions including mobility, omni-channel, IoT, AI, RPA
and cloud to enterprises worldwide. RapidValue offers its digital services to the world’s top brands, Fortune 1000
companies and innovative emerging start-ups. With offices in the United States, the United Kingdom, Germany and
India and operations spread across the Middle-East, Europe and Canada, RapidValue delivers enterprise services
and solutions across various industry verticals.
Disclaimer:
This document contains information that is confidential and proprietary to RapidValue Solutions Inc. No part of it may be used, circulated, quoted,
or reproduced for distribution outside RapidValue. If you are not the intended recipient of this report, you are hereby notified that the use,
circulation, quoting, or reproducing of this report is strictly prohibited and may be unlawful.
www.rapidvaluesolutions.com/blogwww.rapidvaluesolutions.com
+1 877.643.1850 contactus@rapidvaluesolutions.com

More Related Content

PDF
Bitcoin: The Internet of Money
PPTX
Cryptocurrency
PDF
Blueprint for Security Architecture & Strategy.pdf
PPTX
Iso iec 27001 foundation training course by interprom
PDF
Intelligence Failures of Lincolns Top Spies: What CTI Analysts Can Learn Fro...
PDF
Ethereum Blockchain explained
PPTX
Securing Your Public Cloud Infrastructure
 
PDF
Crypto currencies presentation by Dr. Andre Gholam
Bitcoin: The Internet of Money
Cryptocurrency
Blueprint for Security Architecture & Strategy.pdf
Iso iec 27001 foundation training course by interprom
Intelligence Failures of Lincolns Top Spies: What CTI Analysts Can Learn Fro...
Ethereum Blockchain explained
Securing Your Public Cloud Infrastructure
 
Crypto currencies presentation by Dr. Andre Gholam

What's hot (20)

PDF
An Introduction to Blockchain Technology
PPTX
Découvrir le Bitcoin
PDF
MITRE ATT&CKcon 2.0: Prioritizing ATT&CK Informed Defenses the CIS Way; Phili...
PDF
BSidesLV 2018 - Katie Nickels and John Wunder - ATT&CKing the Status Quo
PDF
Mapping to MITRE ATT&CK: Enhancing Operations Through the Tracking of Interac...
PDF
Oscp preparation
PDF
SACON - Threat hunting (Chandra Prakash)
PPTX
Estrategia para aprobar el examen CDMP
PDF
MITRE ATT&CKcon 2.0: ATT&CK Updates - Cyber Analytics Repository (CAR); Ivan ...
PPTX
Cism course ppt
PDF
PDF
PDF
Technology Alignment Framework
PPTX
Chapter 5 - Identity Management
PPTX
Cryptocurrency Exchanges - An Introduction
PPTX
Crypto currency
PDF
Ethereum Mining How To
PDF
An Overview of Stablecoin
PDF
Upgrade Your SOC with Cortex XSOAR & Elastic SIEM
PPTX
Introduction Ă  itil v3
An Introduction to Blockchain Technology
Découvrir le Bitcoin
MITRE ATT&CKcon 2.0: Prioritizing ATT&CK Informed Defenses the CIS Way; Phili...
BSidesLV 2018 - Katie Nickels and John Wunder - ATT&CKing the Status Quo
Mapping to MITRE ATT&CK: Enhancing Operations Through the Tracking of Interac...
Oscp preparation
SACON - Threat hunting (Chandra Prakash)
Estrategia para aprobar el examen CDMP
MITRE ATT&CKcon 2.0: ATT&CK Updates - Cyber Analytics Repository (CAR); Ivan ...
Cism course ppt
Technology Alignment Framework
Chapter 5 - Identity Management
Cryptocurrency Exchanges - An Introduction
Crypto currency
Ethereum Mining How To
An Overview of Stablecoin
Upgrade Your SOC with Cortex XSOAR & Elastic SIEM
Introduction Ă  itil v3
Ad

Similar to Appium Automation with Kotlin (20)

PDF
Guide to Generate Extent Report in Kotlin
PPTX
Mastering the Sling Rewriter by Justin Edelson
PPTX
Mastering the Sling Rewriter
PDF
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
PPT
J Unit
PPTX
Protractor framework architecture with example
PDF
Angular Optimization Web Performance Meetup
PDF
Angular performance slides
PPT
æŻ”XMLæ›Žć„œç”šçš„Java Annotation
PDF
Migration to Extent Report 4
PDF
Workshop 23: ReactJS, React & Redux testing
PPTX
Alteryx SDK
ODP
Bring the fun back to java
PDF
Threads, Queues, and More: Async Programming in iOS
PDF
PDF
Testing in android
PDF
Why Spring <3 Kotlin
PPTX
[NDC 2019] Enterprise-Grade Serverless
PPTX
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
PPTX
Designing REST API automation tests in Kotlin
Guide to Generate Extent Report in Kotlin
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
J Unit
Protractor framework architecture with example
Angular Optimization Web Performance Meetup
Angular performance slides
æŻ”XMLæ›Žć„œç”šçš„Java Annotation
Migration to Extent Report 4
Workshop 23: ReactJS, React & Redux testing
Alteryx SDK
Bring the fun back to java
Threads, Queues, and More: Async Programming in iOS
Testing in android
Why Spring <3 Kotlin
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
Designing REST API automation tests in Kotlin
Ad

More from RapidValue (20)

PDF
How to Build a Micro-Application using Single-Spa
PDF
Play with Jenkins Pipeline
PDF
Accessibility Testing using Axe
PDF
Automation in Digital Cloud Labs
PDF
Microservices Architecture - Top Trends & Key Business Benefits
PDF
Uploading Data Using Oracle Web ADI
PDF
Build UI of the Future with React 360
PDF
Python Google Cloud Function with CORS
PDF
Real-time Automation Result in Slack Channel
PDF
Automation Testing with KATALON Cucumber BDD
PDF
How to Implement Micro Frontend Architecture using Angular Framework
PDF
Video Recording of Selenium Automation Flows
PDF
JMeter JMX Script Creation via BlazeMeter
PDF
The Definitive Guide to Implementing Shift Left Testing in QA
PDF
Data Seeding via Parameterized API Requests
PDF
Test Case Creation in Katalon Studio
PDF
How to Perform Memory Leak Test Using Valgrind
PDF
DevOps Continuous Integration & Delivery - A Whitepaper by RapidValue
PDF
A Technology Backgrounder to Serverless Architecture - A Whitepaper by RapidV...
PDF
MS Azure: Soaring High in the Cloud - An Infographic by RapidValue
How to Build a Micro-Application using Single-Spa
Play with Jenkins Pipeline
Accessibility Testing using Axe
Automation in Digital Cloud Labs
Microservices Architecture - Top Trends & Key Business Benefits
Uploading Data Using Oracle Web ADI
Build UI of the Future with React 360
Python Google Cloud Function with CORS
Real-time Automation Result in Slack Channel
Automation Testing with KATALON Cucumber BDD
How to Implement Micro Frontend Architecture using Angular Framework
Video Recording of Selenium Automation Flows
JMeter JMX Script Creation via BlazeMeter
The Definitive Guide to Implementing Shift Left Testing in QA
Data Seeding via Parameterized API Requests
Test Case Creation in Katalon Studio
How to Perform Memory Leak Test Using Valgrind
DevOps Continuous Integration & Delivery - A Whitepaper by RapidValue
A Technology Backgrounder to Serverless Architecture - A Whitepaper by RapidV...
MS Azure: Soaring High in the Cloud - An Infographic by RapidValue

Recently uploaded (20)

PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
PDF
Nekopoi APK 2025 free lastest update
PDF
AutoCAD Professional Crack 2025 With License Key
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
medical staffing services at VALiNTRY
PPTX
Transform Your Business with a Software ERP System
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
DOCX
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
Salesforce Agentforce AI Implementation.pdf
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
Advanced SystemCare Ultimate Crack + Portable (2025)
17 Powerful Integrations Your Next-Gen MLM Software Needs
Design an Analysis of Algorithms I-SECS-1021-03
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
Nekopoi APK 2025 free lastest update
AutoCAD Professional Crack 2025 With License Key
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
medical staffing services at VALiNTRY
Transform Your Business with a Software ERP System
wealthsignaloriginal-com-DS-text-... (1).pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
How to Choose the Right IT Partner for Your Business in Malaysia
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
Designing Intelligence for the Shop Floor.pdf
Salesforce Agentforce AI Implementation.pdf
Digital Systems & Binary Numbers (comprehensive )
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx

Appium Automation with Kotlin

  • 2. Appium Automation with Kotlin © RapidValue Solutions 2 Appium Automation with Kotlin Pre-requisites: Following are the pre-requisites to start Appium with Kotlin:  Install Java SDK 8 and above.  Install Eclipse or IntelliJ IDEA IDEs.  Install the Kotlin plugin in IDEs. Here I am using Eclipse as IDE and Kotlin plugin for Eclipse downloaded from https://marketplace.eclipse.org/content/kotlin-plugin-eclipse  The latest version of following maven dependencies: o testing o selenium-java o selenium-server o java-client o kotlin-test o kotlin-stdlib-jdk8 o extentreports Step-by-step Procedure Step 1: Create a maven project and add the above dependencies in pom.xml of the project. Step 2: Create a Kotlin class to keep the logic to initiate the driver and start the Appium server. Let’s say the class name is AutomationBase. We are defining this class as an abstract class. So, it is easy to extend by other classes. We have implemented startApplication, startAppiumServer, getPort, getNodePath, getJSPath, getDriverInstance and setDriverInstance methods in the AutomationBase class. Below are the sample code snippets: fun startApplication() { try { var service: AppiumDriverLocalService = startAppiumServer() var capabilities = DesiredCapabilities() capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, “One Plus”) capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, “Android”) capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, “10”) capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2) capabilities.setCapability(AndroidMobileCapabilityType.AUTO_GRANT_PERMISSIONS, true) capabilities.setCapability(“newCommandTimeout”, 180) capabilities.setCapability(“udid”, “e6916f40”) capabilities.setCapability(MobileCapabilityType.APP, “YOUR_APP_PATH”) capabilities.setCapability(MobileCapabilityType.NO_RESET, true) if(!service.toString().isEmpty()){ driver = AndroidDriver(service.getUrl(), capabilities) } } catch (e: Exception) {
  • 3. Appium Automation with Kotlin © RapidValue Solutions 3 e.printStackTrace() } } private fun startAppiumServer(): AppiumDriverLocalService { var IP_ADDRESS: String = “127.0.0.1” var bootStrapPort: String var chromePort: String var port: Int if (!File(System.getProperty(“user.dir”) + “LogsAppium_logs”).exists()) { (File(System.getProperty(“user.dir”) + “Logs”)).mkdir() (File(System.getProperty(“user.dir”) + “LogsAppium_logs”)).mkdir() } port = getPort() bootStrapPort = Integer.toString(getPort()) chromePort = Integer.toString(getPort()) var service = AppiumDriverLocalService.buildService( AppiumServiceBuilder().withAppiumJS(File(getJSPath())) .usingDriverExecutable(File(getNodePath())).withIPAddress(IP_ADDRESS).usingPort(port) .withArgument(AndroidServerFlag.BOOTSTRAP_PORT_NUMBER, bootStrapPort) .withArgument(AndroidServerFlag.CHROME_DRIVER_PORT, chromePort) .withLogFile(File(System.getProperty(“user.dir”) + “LogsAppium_logsappiumLogs.txt”))) service.start() if (service.isRunning()) { System.out.println(“Server is running
..” + service) } else { System.out.println(“Server startup failed
..”) System.exit(0) } return service } private fun getPort(): Int { var port: Int = 0 try { var socket = ServerSocket(0) socket.setReuseAddress(true) port = socket.getLocalPort() socket.close() } catch (e: Exception) { e.printStackTrace() } return port } private fun getNodePath(): String { var nodePath: String var p: Process var reader: BufferedReader var command: String
  • 4. Appium Automation with Kotlin © RapidValue Solutions 4 var operatingSystem: String = System.getProperty(“os.name”) if (operatingSystem.contains(“Win”)) { command = “where” + ” ” + “node” } else { command = “which ” + “node” } p = Runtime.getRuntime().exec(command) reader = BufferedReader(InputStreamReader(p.getInputStream())) nodePath = reader.readLine() p.waitFor() p.destroy() return nodePath } fun getJSPath(): String { var jsPaths: String lateinit var actualJSPath: String var command: String var operatingSystem: String = System.getProperty(“os.name”) if (operatingSystem.contains(“Win”)) { command = “where” + ” ” + “appium” var p: Process = Runtime.getRuntime().exec(command) var stdInput: BufferedReader = BufferedReader(InputStreamReader(p.getInputStream())) jsPaths = stdInput.readLine() actualJSPath = jsPaths.replace(“appium”, “node_modulesappiumbuildlibmain.js”) p.waitFor() p.destroy() } else { actualJSPath = “//usr//local//lib//node_modules//appium//build//lib//main.js” } return actualJSPath } fun getDriverInstance(): WebDriver { return this.driver } fun setDriverInstance(driver: WebDriver) { this.driver = driver } startApplication method helps to instantiate driver sessions based on the specified capabilities. startAppiumServer method helps to start the Appium server and also, create and write server logs to a text file. getPort method helps to create the dynamic network port that supports the startAppiumServer method. getNodePath method helps to get the node path and it supports the startAppiumServer method. getJSPath method helps to get the Appium main.js path and it supports the startAppiumServer method. Step 3: Create a TestRunner class and it extends AutomationBase class. This class holds TestNG annotations @Listeners, @BeforeClass, and @AfterSuite. Below are the complete code snippets:
  • 5. Appium Automation with Kotlin © RapidValue Solutions 5 @Listeners(AutomationReport::class) open class TestRunner : AutomationBase() { @BeforeClass fun setUp() { startApplication() } @AfterSuite fun tearDown() { Thread.sleep(3000) driver.quit() } } Step 4: Create a sample test class to keep the test cases. Let’s call it SampleTests and it extends TestRunner class. Following are the sample code snippets: class SampleTests : TestRunner() { @Test fun TC001_testEnterPincode() { SampleTestsHelper.enterPinCode(driver, “682030”) } @Test fun TC002_testSearchFail() { Assert.fail() } } Step 5: Create a Kotlin class which should act as a helper class of test class. Let’s call it SampleTestsHelper and define this SampleTestsHelper as object. So, Kotlin will create an instance automatically when we invoke the methods of SampleTestsHelper. No need to create a separate instance to invoke the methods of the helper class. Below are the complete code snippets: object SampleTestsHelper { /** * This method used to enter pin code * * @author sanojs * @since 01-09-2020 */ fun enterPinCode(driver: WebDriver, valueToSearch: String) {
  • 6. Appium Automation with Kotlin © RapidValue Solutions 6 try { driver.findElement(By.id(“in.dmart:id/et_activity_pincode_pincode”)).sendKeys(pincod) } catch (e: Exception) { e.printStackTrace() } } } Step 6: Create a Kotlin class to keep the logic to generate an Automation test execution report in HTML format. Let’s say the class name as AutomationReport. Here, we are using extentreports library to generate an HTML report. Also, we are using ITestListener interface to control the executions and results. Below are the complete code snippets of the AutomationReport class, class AutomationReport : ITestListener { public lateinit var sparkReporter: ExtentSparkReporter public lateinit var extentReport: ExtentReports public lateinit var extentTest: ExtentTest /** * This override method used to create HTML template for the test report * * @author sanojs * @since 01-09-2020 */ override fun onStart(testContext: ITestContext) { try { sparkReporter = ExtentSparkReporter(System.getProperty(“user.dir”) + “/AutomationReport/”) sparkReporter.config().setDocumentTitle(“Appium Kotlin Automation”) sparkReporter.config().setReportName(“Automation Execution Report”) sparkReporter.config().setTheme(com.aventstack.extentreports.reporter.configuration.Theme.DARK) extentReport = ExtentReports() extentReport.attachReporter(sparkReporter) extentReport.setSystemInfo(“Application Name”, “Kotlin Appium Demo”) extentReport.setSystemInfo(“Platform”, System.getProperty(“os.name”)) extentReport.setSystemInfo(“Environment”, “QA”) } catch (e: Exception) { e.printStackTrace() } } /** * This override method used to collect current test case name add to the report * * @author sanojs * @since 01-09-2020 */ override fun onTestStart(result: ITestResult) { var testName: String = result.getMethod().getMethodName() extentTest = extentReport.createTest(testName)
  • 7. Appium Automation with Kotlin © RapidValue Solutions 7 } /** * This override method used to add pass status to the report * * @author sanojs * @since 01-09-2020 */ override fun onTestSuccess(result: ITestResult) { var testName: String = result.getMethod().getMethodName() try { extentTest.log( Status.PASS, MarkupHelper.createLabel(testName + ” Test Case PASSED”, ExtentColor.GREEN) ) } catch (e: Exception) { e.printStackTrace() } } /** * This override method used to add fail status to the report * * @author sanojs * @since 01-09-2020 */ override fun onTestFailure(result: ITestResult) { var driver: WebDriver var currentClass = result.getInstance() var testName: String = result.getMethod().getMethodName() try { driver = (currentClass as AutomationBase).getDriverInstance() var screenshotPath = Utilities().screenshotCapture(driver, result.getName()) extentTest.log( Status.FAIL, MarkupHelper.createLabel(testName + ” Test Case FAILED”, ExtentColor.RED) ) extentTest.log( Status.FAIL, MarkupHelper.createLabel(“Reason for Failure: ” + result.getThrowable().toString(), ExtentColor.RED) ) extentTest.addScreenCaptureFromPath(screenshotPath) } catch (e: Exception) { e.printStackTrace() } } /** * This override method used to add skip status to the report * * @author sanojs * @since 01-09-2020 */
  • 8. Appium Automation with Kotlin © RapidValue Solutions 8 override fun onTestSkipped(result: ITestResult) { var testName: String = result.getMethod().getMethodName() try { extentTest.log( Status.SKIP, MarkupHelper.createLabel(testName + ” Test Case SKIPPED”, ExtentColor.ORANGE) ) } catch (e: Exception) { e.printStackTrace() } } /** * This override method used to store HTML report to the specified path and flush extent report instance * * @author sanojs * @since 01-09-2020 */ override fun onFinish(testContext: ITestContext) { try { extentReport.flush() val dateFormat = SimpleDateFormat(“dd-MMM-yyyy_HH-mm-ss”) val date = Date() val filePathdate: String = dateFormat.format(date).toString() var actualReportPath: String = System.getProperty(“user.dir”) + “/AutomationReport/” + “index.html” File(actualReportPath).renameTo( File( System.getProperty(“user.dir”) + “/AutomationReport/” + “Automation_Report_” + filePathdate + “.html” ) ) } catch (e: Exception) { e.printStackTrace() } } } Step 7: Create another class called Utilities to keep common utility functions required for automation. Here, we just added one utility to capture the screenshot. Below is the code snippet to capture the screenshot, fun screenshotCapture(driver: WebDriver, fileName: String): String { var destination: String = “” try { var scrFile = (driver as TakesScreenshot).getScreenshotAs(OutputType.FILE) var dateFormat = SimpleDateFormat(“yyyyMMddHHmmss”) var cal = Calendar.getInstance() var path = File(“Failure_Screenshots”).getAbsolutePath() destination = path + “/” + fileName + dateFormat.format(cal.getTime()) + “.png” scrFile.copyTo(File(destination))
  • 9. Appium Automation with Kotlin © RapidValue Solutions 9 } catch (e: Exception) { e.printStackTrace() } return destination } Step 8: Add a testng.xml file into the project structure and map your test classes into the testng.xml to run the test cases. Once the execution is complete, the HTML report will get generated inside the AutomationReport folder in the project structure. Below is the overall project structure of Appium with Kotlin: NOTE:  Kotlin Runtime Library will automatically get added to the build path of the project when you create a Kotlin class under any package.  Kotlin class extension is .kt  The semicolon is not mandatory to end the statements in the class.  While inheriting a class from a parent class you have to declare the parent class as open, using an open keyword or you can declare the parent class as abstract using abstract. You can’t inherit a singleton class. So avoid extending the class which is declared as object in Kotlin.  If you declare a class with an object keyword then no need to create an instance. Kotlin will create an instance to access the methods or variables of that class.
  • 10. Appium Automation with Kotlin © RapidValue Solutions 10 Conclusion Kotlin is a general-purpose, open-source, statically typed programming language that combines object- oriented and functional programming features. So, Kotlin is a strong and powerful language that helps the automation engineers to write their automation script for Appium. This article aims to help the Appium automation engineers to upskill and write their scripting in a different language such as Kotlin. By, Sanoj S, Test Architect, RapidValue
  • 11. Appium Automation with Kotlin © RapidValue Solutions 11 About RapidValue RapidValue is a global leader in digital product engineering solutions including mobility, omni-channel, IoT, AI, RPA and cloud to enterprises worldwide. RapidValue offers its digital services to the world’s top brands, Fortune 1000 companies and innovative emerging start-ups. With offices in the United States, the United Kingdom, Germany and India and operations spread across the Middle-East, Europe and Canada, RapidValue delivers enterprise services and solutions across various industry verticals. Disclaimer: This document contains information that is confidential and proprietary to RapidValue Solutions Inc. No part of it may be used, circulated, quoted, or reproduced for distribution outside RapidValue. If you are not the intended recipient of this report, you are hereby notified that the use, circulation, quoting, or reproducing of this report is strictly prohibited and may be unlawful. www.rapidvaluesolutions.com/blogwww.rapidvaluesolutions.com +1 877.643.1850 [email protected]