to
Appium's
Contributing
Open Source Ecosystem
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6239321/Planet_Website.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245851/ic_launcher.png)
I'm Srinivasan
Lead Consultant
@srinivasanskr
srinivasanTarget
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/8388127/8896549.jpeg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928495/images/8793124/pasted-from-clipboard.png)
Hello,
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247233/23681.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247225/github-octocat-vector-png--1600.png)
Problem Statement
Timed out waiting for Espresso Server to start due to Socket exception.
Android Architecture
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264773/javalogo.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264774/py.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264775/ruby.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264776/c_logo.png)
W3C
Server Request
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264784/androiddevice.png)
Server
Client
Appium Server
Driver(espresso)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264782/espressco.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264782/espressco.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245851/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/404812/images/8918576/plugin.png)
Server Request
Plugins
Appium Android Driver
Appium ADB
Appium Espresso Driver
Appium Base Driver
Appium UIA2 Driver
Appium Support
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245851/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6253282/relationship-lifecycle-management-header.png)
Initialisation
Creation
Instrumentation
Execution
Android Life Cycle
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("app", app.getAbsolutePath());
capabilities.setCapability("appPackage", "io.appium.android.apis");
capabilities.setCapability("appActivity", ".ApiDemos");
capabilities.setCapability("automationName", "Espresso"); driver = new AndroidDriver<WebElement>(getServiceUrl(), capabilities);
Intialization
Driver Creation
App Launch State
automationNameCap = automationNameCap.toLowerCase();
try {
const {driverPackage, driverClassName} = DRIVER_MAP[automationNameCap];
const driver = require('appium-espresso-driver')[driverClassName];
return {
driver,
version: this.getDriverVersion(driver.name, driverPackage),
};
} catch () {
Appium Base Driver
Protocol Proxy
UIA2 or
Espresso Driver
Espresso Driver
- EspressoDriver extends BaseDriver
-
Merges the default values with desired capability
async createSession (...args) {
try {
let [sessionId, caps] = await super.createSession(...args);
let serverDetails = {
platform: 'LINUX',
webStorageEnabled: false,
takesScreenshot: true,
javascriptEnabled: true,
databaseEnabled: false,
networkConnectionEnabled: true,
locationContextEnabled: false,
warnings: {},
desired: Object.assign({}, this.caps)
};
this.caps = Object.assign(serverDetails, this.caps);
Espresso Driver
async startEspressoSession () {
logger.info(`EspressoDriver version: ${version}`);
await helpers.getDeviceInfoFromCaps(this.opts);
....
await androidHelpers.createADB(this.opts);
....
this.initEspressoServer();
appium-android-driver
appium-adb
initEspressoServer () {
this.espresso = new EspressoRunner({
host: this.opts.remoteAdbHost || this.opts.host || 'localhost',
systemPort: this.opts.systemPort,
devicePort: DEVICE_PORT,
adb: this.adb,
apk: this.opts.app,
tmpDir: this.opts.tmpDir,
appPackage: this.opts.appPackage,
appActivity: this.opts.appActivity,
forceEspressoRebuild: !!this.opts.forceEspressoRebuild,
serverLaunchTimeout: this.opts.espressoServerLaunchTimeout,
androidInstallTimeout: this.opts.androidInstallTimeout,
});
this.proxyReqRes = this.espresso.proxyReqRes.bind(this.espresso);
}
espresso-driver/lib/driver.js
Espresso Session Creation
adb forward tcp:8300 tcp:6791
AUT
await this.adb.forwardPort(this.opts.systemPort, DEVICE_PORT);
await this.adb.install(this.modServerPath, { replace: false,timeout: this.androidInstallTimeout });
Instrumentation
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245679/source__2_.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245679/source__2_.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245844/pasted-from-clipboard.png)
async startSession (caps) {
await this.cleanupSessionLeftovers();
const cmd = [
'shell',
'am', 'instrument',
'-w',
'-e', 'debug', process.env.ESPRESSO_JAVA_DEBUG === 'true' ? 'true' : 'false',
`${TEST_APK_PKG}/androidx.test.runner.AndroidJUnitRunner`,
];
logger.info(`Starting Espresso Server v${version} with cmd: adb ${cmd.join(' ')}`);
Execution
try {
await retryInterval(20, 1000, async () => {
await this.jwproxy.command('/status', 'GET');
});
} catch (e) {
if (hasSocketError) {
logger.errorAndThrow('....');
} else {
logger.errorAndThrow(`Timed out waiting for Espresso Server to start. Original error: ${e.message}`);
}
}
await this.jwproxy.command('/session', 'POST', {desiredCapabilities: caps});
Execution
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
{
"desiredCapabilities": {
"desired": {
"platformName": "android",
"app": "/Users/saikrisv/git/VodQaAdvancedAppium/VodQA.apk",
"automationName": "Espresso",
"deviceName": "Android Emulator",
"launchTimeout": 900000
},
"platformName": "android",
"app": "/Users/saikrisv/git/VodQaAdvancedAppium/VodQA.apk",
"automationName": "Espresso",
"deviceName": "emulator-5554",
"launchTimeout": 900000,
"deviceUDID": "emulator-5554",
"appPackage": "com.vodqareactnative",
"appWaitPackage": "com.vodqareactnative",
"appActivity": "com.vodqareactnative.MainActivity",
"appWaitActivity": "com.vodqareactnative.MainActivity"
}
Execution
POST /wd/hub/session
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5597506/rocket-1.gif)
Demo
IOS Session Creation
Problem Statement
Unable to launch WebDriverAgent because of xcodebuild failure: "xcodebuild failed with code 65".
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264773/javalogo.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264774/py.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264775/ruby.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264776/c_logo.png)
W3C
Server Request
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5264784/androiddevice.png)
WDA
Appium XCUI driver
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5348676/apple-ios-logo-B63FD344C4-seeklogo.com.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/5348679/1000px-F_icon.svg.png)
IOS Architecture
Appium Server
Client
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245851/ic_launcher.png)
appium-ios-simulator
node-simctl
appium-xcode
appium-remote-debugger
Appium XCUI Driver
Appium IOS Driver
Appium Base Driver
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245851/ic_launcher.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6253282/relationship-lifecycle-management-header.png)
Intialization
APP & WDA
Execution
iOS Life Cycle
Creation
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "iOS");
caps.setCapability("platformVersion", "12.2");
caps.setCapability("deviceName", "iPhone Xs");
caps.setCapability(IOSMobileCapabilityType.BUNDLE_ID, BUNDLE_ID);
caps.setCapability("udid", "666B367A-62E7-45F1-B430-36C2A1971BB8");
driver = new IOSDriver<MobileElement>(new URL("http://localhost:4723/wd/hub"), caps);
Intialization
Driver Creation
App Launch State
Protocol Proxy
XCUI Driver
Appium Base Driver
let automationNameCap = caps.automationName;
automationNameCap = automationNameCap.toLowerCase();
try {
const {driverPackage, driverClassName} = DRIVER_MAP[automationNameCap];
return {
driver,
version: this.getDriverVersion(driver.name, driverPackage),
};
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
const driver = require['appium-xcuitest-driver'];
- XCUIDriver extends BaseDriver
-
Merges the default values to the user given capability
../appium-xcuitest-driver/lib/driver.js
XCUI Driver
// merge server capabilities + desired capabilities
caps = Object.assign({}, defaultServerCaps, caps);
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
async createSession (...args) {
this.lifecycleData = {};
try {
let [sessionId, caps] = await super.createSession(...args);
this.opts.sessionId = sessionId;
await this.start();
../appium-xcuitest-driver/lib/simulator-management.js
const {device, udid, realDevice} = await this.determineDevice();
return await getSimulator(appiumTestDevice.udid);
Device Name Platform Version
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
node-simctl
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
appium-ios-simulator
async function getExistingSim (opts) {
const devices = await getDevices(opts.platformVersion);
Simulators
Simulators/Real Device
log.debug(`Available devices: ${devices.join(', ')}`); if (!devices.includes(this.opts.udid)) { if (await simExists(this.opts.udid)) { return {device, realDevice: false, udid: this.opts.udid}; } throw new Error(`Unknown device or simulator UDID: '${this.opts.udid}'`); } } if (_.isEmpty(this.opts.platformVersion)) { log.info('Trying to determine platformVersion from ideviceinfo output'); try { const {stdout} = await exec('ideviceinfo', [ '-u', this.opts.udid, '-s', '-k', 'ProductVersion', ]); this.opts.platformVersion = util.coerceVersion(stdout.trim(), false); } catch (e) { log.warn(`Cannot determine real device platform version. Original error: ${e.message}`); } } return {device, realDevice: true, udid: this.opts.udid}; }
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
node-simctl
idevice_id
const device = await getSimulator(this.opts.udid);
const device = await getRealDeviceObj(this.opts.udid);
const devices = await getConnectedDevices();
App Installation
async function installToSimulator (device, app, bundleId, noReset = true) {
if (bundleId) {
if (await device.isAppInstalled(bundleId)) {
if (noReset) {
log.debug(`App '${bundleId}' is already installed. No need to reinstall.`);
return;
}
log.debug(`Reset requested. Removing app with id '${bundleId}' from the device`);
await device.removeApp(bundleId);
}
}
......
try {
} catch (e) {
}
log.info('Retrying application install');
....
}
log.debug('The app has been installed successfully.');
} finally {
if (tmpRoot && await fs.exists(tmpRoot)) {
await fs.rimraf(tmpRoot);
}
}
}
node-simctl
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
await device.installApp(app);
App Installation
ios-deploy
async function installToRealDevice (device, app, bundleId, noReset = true) { if (!device.udid || !app) { log.debug('No device id or app, not installing to real device.'); return; } if (await device.isAppInstalled(bundleId)) { if (noReset) { log.debug(`App '${bundleId}' is already installed. No need to reinstall.`); return; } log.debug(`Reset requested. Removing app with id '${bundleId}' from the device`); await device.remove(bundleId); } }
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
await device.install(app);
WDA Start
wdaLocalPort
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6207278/pasted-from-clipboard.png)
async start (buildOnly = false) {
Execution
this.xcodebuild.processExited = true;
if (this.xcodebuild._wda_error_occurred || (!signal && code !== 0)) {
return reject(new Error(`xcodebuild failed with code ${code}${EOL}` +
`xcodebuild error message:${EOL}${this.xcodebuild._wda_error_message}`));
}
this.xcodebuild = await this.createSubProcess(buildOnly);
this.xcodebuild._wda_error_message = '';
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
try {
await retryInterval(15, 1000, async () => {
try {
this.proxyCommand('/status', 'GET');
await this.startWdaSession(this.opts.bundleId, this.opts.processArguments);
} catch (err) {
originalStacktrace = err.stack;
log.debug(`Failed to create WDA session (${err.message}). Retrying...`);
throw err;
}
});
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6245645/source.gif)
Execution
FindElement
driver.findElement(By.accessibility)
[HTTP] --> POST /wd/hub/session/ca5d6df3-c557-40ae-973a-6620d4a9fc42/elements
[HTTP] {"using":"accessibility id","value":"login"}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6205964/Screen_Shot_2019-06-02_at_1.13.13_PM.png)
@saikrisv
saikrisv@thoughtworks.com
github.com/saikrishna321
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247225/github-octocat-vector-png--1600.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247233/23681.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247234/email_PNG55.png)
@srinivasanskr
sekars@thoughtworks.com
github.com/srinivasantarget
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247225/github-octocat-vector-png--1600.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247233/23681.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247234/email_PNG55.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247250/AppiumLogoTrans.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247288/twlogo-footer-snap-pink-868451df79dfdab302dcfc51e0d931f9.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247100/08_ThankYou.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/928493/images/6247134/LikableCelebratedHart-small.gif)
Contributing to Appium's Open Source Ecosystem
By Srinivasan Sekar
Contributing to Appium's Open Source Ecosystem
- 190