Sai Krishna and Srinivasan Sekar, Author at Automated Visual Testing | Applitools https://applitools.com/blog/author/saiandsrinivasan/ Applitools delivers the next generation of test automation powered by AI assisted computer vision technology known as Visual AI. Tue, 10 Jan 2023 01:49:31 +0000 en-US hourly 1 What’s New in Appium Java Client 8.0.0 https://applitools.com/blog/whats-new-appium-java-client-8/ Thu, 06 Jan 2022 02:24:16 +0000 https://applitools.com/?p=33588 Learn about the latest updates in the Appium Java Client 8.0.0 release, and how it affects your Appium mobile testing today.

The post What’s New in Appium Java Client 8.0.0 appeared first on Automated Visual Testing | Applitools.

]]>

Learn about the latest updates in the Appium Java Client 8.0.0 release, and how it affects your Appium mobile testing today. Sai Krishna and Srinivasan are members of the Appium team.

The Selenium team released Selenium 4 in September 2021 to much anticipation with tons of great features. Since then, the Appium team has been working on upgrading the Selenium dependency in all the clients of Appium to provide a seamless experience. Most of the Appium clients are updated and now in early beta, but with a lot of breaking changes. Let’s go through the changes introduced in Appium Java client 8.0.0 beta2 and what you would need to do.

WebDriver Protocol Compliance

With Appium 2.0, we on the Appium team are making sure we are strictly W3C compliant. Since the Java client supports Selenium 4.1.1, it’s strictly W3C compliant too. Methods that are non-w3c complaint are removed and the details can be seen here.

Driver-Specific Options Classes

It is now recommended to use driver-specific W3C option classes instead of Desired Capabilities. Below is the list of driver-specific classes.

  • XCUITestOptions to create an XCUITestDriver instance 
  • UiAutomator2Options to create a UIAutomator2Driver instance
  • EspressoOptions to create an EspressoDriver instance
  • WindowsOptions to create a WindowsDriver instance
  • Mac2Options to create a Mac2Driver instance
  • GeckoOptions to create a GeckoDriver instance
  • SafariOptions to create a SafariDriver instance

See the below example for changes required:

// From Appium Java Client version 8.0.0 Beta
UiAutomator2Options options = new UiAutomator2Options()
       .setDeviceName("Android Emulator")
       .setApp(System.getProperty("user.dir") + "/VodQA.apk")
       .eventTimings();
driver = new AndroidDriver(service.getUrl(), options);
// Older approach: Java Client version 7.X.X
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 700000);

Element Lookups

  • Like Selenium, Appium also removed all its findBy methods.
  • Since Appium supports both mobile and desktop platform applications, we replaced MobileBy with AppiumBy and introduced camelCase naming conventions. For example,  ​​MobileBy.AccessibilityId is now AppiumBy.accessibilityId. MobileBy is now deprecated.
  • windowsAutomation locator strategy is deprecated.

Starting Appium Server Programmatically

  • Java Client uses AppiumServiceBuilder to start a node server programmatically. With the updated version, it works slightly differently with different Appium server versions.
  • The default URL for the server has been changed at the server-side and it does not contain the /wd/hub by default.
  • Java Client starting from v8.0.0 has made required changes to align to Appium V2.
  • If you still would like to use Java Client v8 with Appium 1.2.X then consider providing the –base-path explicitly while building the AppiumServiceBuilder.
// From Appium 2.0 Beta
AppiumDriverLocalService service;
service = new AppiumServiceBuilder()
       .withIPAddress("127.0.0.1")
       .usingPort(4723)
       .build();
service.start();
// Older approach: Appium 1.22.X
AppiumDriverLocalService service;
service = new AppiumServiceBuilder()
       .withIPAddress("127.0.0.1")
       .withArgument(GeneralServerFlag.BASEPATH, "/wd/hub")
       .usingPort(4723)
       .build();
service.start();

Changes in Driver Classes

  • SelendroidDriver class is removed
  • Both GeckoDriver and SafariDriver are newly introduced drivers
    • GeckoDriver is an officially supported Appium driver to automate Mobile browsers and web views based on the gecko engine
    • SafariDriver is also an official driver for automating Safari on macOS and iOS

Changes in Element Classes

  • MobileElement classes including AndroidElement and iOSElement classes are removed. It is recommended to use WebElement instead.
  • replaceValue method is now called replaceElementvalue in AndroidDriver class
  • setValue method is removed in favor of the existing sendKeys method.

Touch Actions

The TouchActions and MultiTouchActions classes for automating gestures from your client code have been deprecated. Support for these actions will be removed from future Appium versions. It is recommended to use W3C Actions instead or the corresponding extension methods for the driver (if available). 

Point source = slider.getLocation();
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence sequence = new Sequence(finger, 1);
sequence.addAction(finger.createPointerMove(ofMillis(0),
       PointerInput.Origin.viewport(), source.x, source.y));
sequence.addAction(finger.createPointerDown(PointerInput.MouseButton.MIDDLE.asArg()));
sequence.addAction(new Pause(finger, ofMillis(600)));
sequence.addAction(finger.createPointerMove(ofMillis(600),
       PointerInput.Origin.viewport(), source.x + 400, source.y));
sequence.addAction(finger.createPointerUp(PointerInput.MouseButton.MIDDLE.asArg()));
driver.perform(singletonList(sequence));

Refer to the links below to know more about how to work with gestures:

  • https://www.youtube.com/watch?v=oAJ7jwMNFVU
  • https://appiumpro.com/editions/30-ios-specific-touch-action-methods
  • https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/android/android-mobile-gestures.md
  • https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/ios/ios-xctest-mobile-gestures.md
  • https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api for more details on how to properly apply W3C Actions to your automation context.

App Management

AppiumDriver methods like resetApp, closeApp and launchApp have been deprecated as they are going to be removed from the future Appium versions. Alternatively, the suggested approach is to use removeApp, installApp, and activateApp methods available here. The non-standard way for App Management in iOS is using the mobile: methods to remove the app then install the new application and launch it using the methods here. For Android UIAutomator2 backend, the non-standard mobile: methods like clearApp deletes all data associated with a package, and installMultipleApks allows users to install multiple applications at the same time.

Appium Event Listeners

The current event firing mechanism that Appium Java Client uses has been deprecated in favor of the one that Selenium 4 provides natively. Read The-event_firing.md for more details on how to use it.

Summary

There are a lot of great new changes in this latest Appium Java Client update. You can check out a detailed migration guide here in Appium’s Java Client for reference. Do let us know where there’s been a problem, and thank you. We only have a chance to improve when we know that there’s something that needs work!

The post What’s New in Appium Java Client 8.0.0 appeared first on Automated Visual Testing | Applitools.

]]>
How to Automate Gesture Testing with Appium https://applitools.com/blog/how-to-automate-gesture-testing-appium/ Wed, 13 Oct 2021 07:58:00 +0000 https://applitools.com/?p=31549 Learn the evolution of touch gestures and how you can simplify the way you perform automated tests for gestures using a new plugin in Appium 2.0.

The post How to Automate Gesture Testing with Appium appeared first on Automated Visual Testing | Applitools.

]]>

In the previous blog posts in this Appium series, we discussed step-by-step instructions for creating your own Appium 2.0 Plugins as well as Appium 2.0 Drivers and Plugins usage and its installation. This article discusses the evolution of touch gestures and how you can simplify the way you perform automated tests for gestures using a new plugin in Appium 2.0.

What are Touch Gestures?

Gestures are the new clicks. Gesture-driven devices changed the way we think about interaction. The success of mobile applications depends on how well the gestures are implemented into the user experience. The definitive guide for gestures by Luke Wroblewski details a lot of different actions and how they actually work.

​​

credit: Touch Gesture Reference Guide. Creative Commons

Animations, when paired with Gestures, make users believe in interacting with tangible objects. Appium handles these gestures using the Actions API defined in the W3C WebDriver Specification. It’s great that the API was designed thinking of all interfaces like touch, pen, mouse, etc., but it is hard to understand. Since Appium 1.8, Appium supports the W3C Actions API for building any kind of gesture in mobile devices.

Let’s consider a situation where the application sets specific values based on the slider movements.

Let’s see using Actions API how this situation can be handled.

View the code on Gist.

In the above code snippet, we have three actions to look at which are to get the element location using location API and create a sequence with actions which includes pointerMove, pointerDown, pause, pointerUp, and then perform the sequence. So in this case we need to add these actions in the right order to get the gesture to work. Let’s break down the above in detail to understand what happens under the hood.

  1. Identify the slider element using any locator strategy.
  2. Find the location of the slider element on the screen.
  3. Create a PointerInput object of type TOUCH with a unique id as a finger.
  4. Create a Sequence object with a PointerInput object.
  5. Add individual actions to the sequence.
    1. Pointer move to the slider element location.
    2. Pointer down on the slider element.
    3. Hold for a few milliseconds.
    4. Pointer move the slider to the destination location.
    5. Pointer up from the slider element.
  6. Perform the sequence by calling the Actions API.

Refer to the below image to understand how the element location can be calculated.

A diagram showing a horizontal x axis and a vertical y axis. (x1, y1) is in the top left corner, (x2, y1) is partway across the x axis.

This way any complex gestures can be automated using Actions API.

How the Appium Gestures Plugin Helps

Let’s look at how the gestures plugin from Appium 2.0 simplifies this entire process:

View the code on Gist.

Internally appium-gesture-plugin finds the given element location and does the target location calculation based on the given percentage. It also creates the sequence of actions to perform the gestures on both iOS and Android platforms.

Refer here for a working example of the above swipe gesture using the gestures plugin. Follow the instruction specified here to install the Appium gestures plugin.

For any simple gesture actions (swipe, drag and drop, long press, double-tap, etc.) we can use the gestures plugin. For more custom actions, like if your application has a feature on digital signature, we could still use the Actions API.

Apart from the Actions API, Appium also supports native gesture API which is exposed by Android and iOS platforms through non-standard endpoints like below:

View the code on Gist.

For more such APIs, check out Android non-standard gesture APIs and iOS non-standard gesture APIs.

The post How to Automate Gesture Testing with Appium appeared first on Automated Visual Testing | Applitools.

]]>
How to Build Your Own Appium Plugin https://applitools.com/blog/how-to-build-your-own-appium-plugin/ Mon, 16 Aug 2021 22:19:44 +0000 https://applitools.com/?p=30315 Appium 2.0 provides the ability for users to create their own custom Appium plugins. Learn how to make your own!

The post How to Build Your Own Appium Plugin appeared first on Automated Visual Testing | Applitools.

]]>

In the previous blog post we discussed Appium 2.0 Drivers and Plugins usage and its installation. This article is aimed at creating your own Appium Plugin and its use cases.

Plugins in Appium 2.0:

Appium plugins are here to help with the various use cases that require a change to Appium’s default behavior. 

  • Plugins add arbitrary functionality that executes before or after the actual appium commands
  • Plugins alter the Appium server to introduce new commands and distribute it.

There are already official Appium plugins created by the project, as well as community-created Appium plugins.

Build your own Appium plugin:

Let’s say we want to improve the way we write appium tests, for example, let appium server take care of element waits and we focus on the user journey in tests rather than element waits all over it.

Below are the steps to create a new plugin to wait for the presence of an element:

Initialize a new node project

 npm init

Install Appium base plugin as a dependency inside the new project created in above step 

npm i @appium/base-plugin

Navigate to the package.json and add an appium object as described below:

"appium": {
    "pluginName": "element-wait",
    "mainClass": "WaitCommandPlugin"
  }

Create a new file called plugin.js in the root directory of the project

In plugin.js, create a class which extends appium base plugin.

export default class WaitCommandPlugin extends BasePlugin {}

Here is the list of supported Appium commands. As per our use case, we need to override the appium findElement command.

Override the appium command implementation in our new class

async findElement(next, driver, ...args) {
    // Custom Implementation of Appium’s FindElement command
 }

We can extract strategy and selector from the arguments of the findElement command and then make an API call to the /element endpoint to check if it exists in the DOM (document object model):

const response = await fetch(
      `${baseUrl}wd/hub/session/${this.driver.sessionId}/element`,
      {
        body: JSON.stringify({
          strategy: this.strategy,
          selector: this.selector,
          context: '',
          multiple: false,
        }),
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
      }
    );

Keep polling the endpoint consistently for a constant period of time until the element exists, if it exists check for element displayed status as below:

const response = await fetch(
   `${baseUrl}wd/hub/session/${this.driver.sessionId}/element/${this.element}/attribute/displayed`,
      {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
      }
    );
    return await response.json();
  }

Call await next() to execute the default behaviour of the findElement command. Refer here for more details on plugin.js

Export the plugin

Create a new file called index.js in the root directory of the project to export the plugin

export default WaitCommandPlugin;

Install the plugin

Transpile and build the plugin using babel or Typescript. Install the plugin from local source using the below command:

appium plugin install --source=local <path to plugin>

Activate the plugin

The plugin can be activated using the following command while starting the Appium server. In this example, “element-wait” is the name of the plugin.

appium --plugins=element-wait

Plugin usage

The element wait plugin is activated while starting the appium server so the client code can be simplified without using webdriver waits.

Without Wait plugin

wait = new WebDriverWait(driver, 30);
wait.until(presenceOfElementLocated(MobileBy.AccessibilityId("login"))).click();
wait.until(presenceOfElementLocated(MobileBy.AccessibilityId("slider")));
driver.findElementByAccessibilityId("slider").click();

With Wait plugin

driver.findElementByAccessibilityId("login").click();
driver.findElementByAccessibilityId("slider").click();

In the example above, we altered the existing appium command to find an element, but Appium plugins can also be used to create our own custom commands on top of Appium supported commands.

To implement custom commands or adding new routes in appium we need to implement on both the Appium server and client-side.

A server-side plugin includes adding a new method map where we define the route and the new Appium command and its implementation.

static newMethodMap = {
    '/session/:sessionId/fake_data': {
      GET: {command: 'getFakeSessionData'}
    },
};

async getFakeSessionData (next, driver) {
    await B.delay(1);
    return driver.fakeSessionData || null;
}

As of today custom commands can be added only in Appium Ruby, Appium Python and in WebdriverIO. Below is an example from Appium Ruby client:

@driver.add_command(
              method: :post,
              url: 'session/:session_id/path/to/custom/bug/report,
              name: :bug_report
            ) do
              def bug_report(argument)
                execute(:bug_report, {}, { sample: argument })
              end
            end

 @driver.bug_report(1)

Using this approach, the Appium plugin adds custom commands and overrides or modifies the existing Appium commands.

Summary

Decoupled Appium 2.0 architecture will help create new plugins to solve many interesting use cases. For more on Appium 2.0, check out our talk at the Future of Testing event.

The post How to Build Your Own Appium Plugin appeared first on Automated Visual Testing | Applitools.

]]>
Appium vs Espresso vs XCUITest – Understanding how Appium Compares to Espresso & XCUITest https://applitools.com/blog/appium-vs-espresso-vs-xcui/ Fri, 12 Mar 2021 02:06:42 +0000 https://applitools.com/?p=27600 In this article we shall look at the Appium, Espresso and XCUITest test automation frameworks. We’ll learn the key differences between them, as well as when and why you should use...

The post Appium vs Espresso vs XCUITest – Understanding how Appium Compares to Espresso & XCUITest appeared first on Automated Visual Testing | Applitools.

]]>

In this article we shall look at the Appium, Espresso and XCUITest test automation frameworks. We’ll learn the key differences between them, as well as when and why you should use them in your own testing environment.

What is Appium

Appium is an open source test automation framework which is completely maintained by the community. Appium can automate Native, Hybrid, mWeb, Mac Apps and Windows Apps. Appium follows the Selenium W3C protocol which enables the use of the same test code for both Android and iOS applications.

Under the hood Appium uses Espresso or UIAutomator2 as the mode of communication to Android Apps and XCUI for iOS. In a nutshell, Appium provides a stable webdriver interface on top of automation backends provided by Google and Apple.

Installing Appium was a bit of hassle for a long time, hence from Appium 2.0 architecturally we could choose to install the drivers and plugins as we wanted. You can find more details about Appium 2.0 here.

Highlights of Appium

  • When Espresso or XCUI upgrades the API contract, Appium under the hood will make necessary changes and the test will remain unchanged and work as before.
  • supports Cross platform testing, i.e., write one test that runs across many platforms.
  • allows users to write tests in WebDriver compatible languages – Java, Python, C#, Ruby, JS, etc.
  • Does not require application to be recompiled as it uses standard automation APIs across all platforms.
  • A Black box testing tool which also supports Gray box testing to some extent with Espresso’s driver backdoor capability.
  • Can switch between Espresso driver and UIAutomator2 driver for Android in a single session. (For example: Creating a session with Espresso Driver and then we can move to UIAutomator2 to perform actions outside of application under test.)
View the code on Gist.
  • The latest Webdriver W3C Actions API is designed in such a way that any complex gestures can be designed and executed on any platform, e.g., Android, iOS. Below is an example of a swipe gesture that runs on Android and iOS platforms.
View the code on Gist.
View the code on Gist.
  • Appium has a locator strategy specific to Espresso, e.g., Data Matcher strategy, and another for XCUI, e.g., NSPredicates and ClassChain
View the code on Gist.

What is Espresso

Espresso is an Android test framework developed by Google for UI testing. Espresso automatically synchronizes test actions with the user interface of the mobile app and ensures that activity is started well before the actual test run.

Highlights of Espresso

  • Feedback cycle is fast as it doesn’t require server communication. 
  • Allows users to create custom view matchers and is based on Hamcrest matchers.
  • Espresso Framework can be categorized between black box and white box testing, commonly called as gray box testing framework.
  • Accessibility testing is possible in Native Espresso.
  • Requires the entire code base to run the test.
  • Locator strategy is Id from R file.
  • Applitools Ultrafast Grid can be used to perform visual testing.
  • For testing webviews, Espresso internally uses WebDriver APIs to control the behaviour of a webview.
View the code on Gist.

What is XCUITest

The XCUITest framework from Apple helps users write UI tests straight inside the Xcode with the separate UI testing target in the app.

XCUITest uses accessibility identifiers to interact with the main iOS app. XCUITests can be written in Swift or Objective-C. 

There isn’t a reliable framework out there which easily supports testing on Apple TV devices. XCUITest is the only way to verify tvOS apps. SinceXcode 7, Apple has shipped XCTest prebuilt into its development kit. 

Highlights of XCUITest

  • Runs in a separate process from our main iOS app and it doesn’t access an application’s internal methods.
  • XCUIElement class in XCUITest provides gestures such as tap, press, swipe, pinch and rotate.
View the code on Gist.
  • Offers several inbuilt assertions e.g., XCTKVOExpectation, XCTNSNotificationExpectation, XCTDarwinNotificationExpectation, XCTNSPredicateExpectation, etc.
View the code on Gist.

Conclusion

Appium, Espresso and XCUI can each fill different needs for UI testing. The way to choose between them is to consider the requirements of your project. If your scope is limited just to one platform and you want comprehensive and embedded UI testing, XCUI or Espresso are great fits. For cross-platform testing across iOS, Android, and Hybrid then Appium is your best choice. 

The post Appium vs Espresso vs XCUITest – Understanding how Appium Compares to Espresso & XCUITest appeared first on Automated Visual Testing | Applitools.

]]>
Getting Started with Appium 2.0 Beta https://applitools.com/blog/appium-2-0-beta/ Tue, 09 Feb 2021 23:47:06 +0000 https://applitools.com/?p=26748 Appium team has released 2.0.0-beta.10 recently with the official Appium image plugin and some minor bug fixes and improvements over its earlier beta versions.

The post Getting Started with Appium 2.0 Beta appeared first on Automated Visual Testing | Applitools.

]]>

Appium released its first major version almost 7 years ago. Since then, Appium has rolled out a lot of new features and its automation backend architecture has evolved quite a lot. 

Appium 2.0, the next major release, has been in talks for a couple of years now, as Jonathan Lipps and the team have been brainstorming and implementing new features. 

Installing Appium 2.0 Server

Appium team has released 2.0.0-beta.10 recently with the official Appium image plugin and some minor bug fixes and improvements over its earlier beta versions. Appium 2.0 beta versions can be installed using the below command:

npm install -g appium@next 

Appium server can take up several optional arguments. In addition to the server arguments, Appium 2.0 introduces new arguments:

  • -ah to specify a directory to install Appium drivers
appium server -ah /path/to/install/drivers driver install uiautomator2
  • -ka or –keep-alive-timeout to specify the number of seconds the Appium server should apply as both the keep-alive timeout and the connection timeout for all requests. Defaults to 600 seconds.

appium server -ka 800

Decoupled Drivers

Appium drivers (UIAutomator2 driver, XCUITest driver, Espresso Driver, etc) are tightly coupled with Appium Server but from Appium 2.0 these drivers are separated from Appium Server and can be installed separately based on users’ needs. Creating custom drivers for any new platform or special use cases are going to be easy from Appium 2.0. 

For example, in the future, we might have an Appium Wear driver to automate WearOS Apps or an Appium KaiOS driver to automate smart feature apps in kaiOS.

To list all the available drivers in appium, enter the following command:

appium driver list
✔ Listing available drivers
- uiautomator2 [not installed]
- xcuitest [not installed]
- youiengine [not installed]
- windows [not installed]
- mac [not installed]
- mac2 [not installed]
- espresso [not installed]
- tizen [not installed]
- flutter [not installed]
- safari [not installed]
- gecko [not installed]

To install a driver for say uiautomator2 driver, Appium now has subcommands to install, update, etc

appium driver install uiautomator2
Attempting to find and install driver 'uiautomator2'
✔ Installing 'uiautomator2' using NPM install spec 
'appium-uiautomator2-driver'
Driver uiautomator2@1.61.2 successfully installed
- automationName: UiAutomator2
- platformNames: ["Android"]

To view the list of installed appium drivers, type the following command:

appium driver list --installed
✔ Listing installed drivers
- uiautomator2@1.61.2 [installed (NPM)]

There are many other options offered by the Drivers CLI to install drivers from a specific source, update all the installed drivers, etc. This simplifies the overall installation process and users have the flexibility to choose to upgrade drivers without updating the server itself.

Plugins

Appium plugins will be here to help with the various use cases that require a change to Appium’s default behavior. These changes provide users an opportunity to build new plugins in the future, for example,  Jonathan Lipps is currently working on a driver for Roku smart TV!

The Appium team continues to maintain some plugins which can be found here

Plugins help add arbitrary functionality before or after actual Appium commands. Also, the plugin can modify the Appium Server itself to introduce new commands and distribute them. For example, the current “image” plugin from Appium helps find an element by an image and also helps in image comparison too. 

To list all available Appium Plugins:

appium plugin list
✔ Listing available plugins
- images [not installed]

To install an Appium plugin, use this command and replace “images” with the name of the plugin you’d like to install:

appium plugin install images

To activate a plugin when starting the Appium server, use the following command (replace “images” with the name of the plugin you’d like to activate):

appium server -ka 800 --plugins=images -pa /wd/hub
[Appium] Welcome to Appium v2.0.0-beta.10
[Appium] Non-default server args:
[Appium]   plugins: {
[Appium]     0: images
[Appium]   }
[Appium]   basePath: /wd/hub
[Appium]   keepAliveTimeout: 800
[Appium]   tmpDir: 
/var/folders/f5/fwh8w_ms6q377gn_fb2bmjp40000gp/T
[Appium] Appium REST http interface listener started on 
0.0.0.0:4723
[Appium] Available drivers:
[Appium]   - uiautomator2@1.61.2 (automationName 
'UiAutomator2')
[Appium]   - xcuitest@3.36.0 (automationName 'XCUITest')
[Appium] Available plugins:
[Appium]   - images@1.1.2 (ACTIVE)

No code changes are required at this time in the client script to execute using the latest Appium server.

Other Breaking Changes

The minimum node version required for the Appium server to run is node 12.

Summary

A lot of new plugins are expected to come soon. The ability to easily create new drivers and plugins in Appium 2.0 will help solve many interesting use cases and problems that were hard to solve before. Watch this space as we share more details related to the same as it happens. 

Credits to Jonathan Lipps, Mykola Mokhnach, kazucocoa, and other contributors for their wonderful contributions to the Appium community.  

Srinivasan Sekar – https://www.linkedin.com/in/srinivasan-sekar/

Sai Krishna – https://www.linkedin.com/in/sai-krishna-3755407b/

The post Getting Started with Appium 2.0 Beta appeared first on Automated Visual Testing | Applitools.

]]>