Driver-based Appium architecture for testing on Android
For testing on Android devices, Perfecto supports the driver-based Appium architecture introduced in Appium 1.10. This architecture is fully aligned with local Appium testing. This change applies to native, web, and hybrid app testing.
On this page:
Benefits
The driver-based Appium architecture comes with the following benefits:
-
Full compatibility with Appium standard
-
Bug fixes and enhancements
-
Support of Android deep links
Deep links are URLs that take users directly to specific content in your app. For example:
getDriver().get("theapp://login/darlene/testing123");
When a clicked link or programmatic request invokes a web URI intent, the Android system tries each of the following actions, in sequential order, until the request succeeds:
-
Open the user's preferred app that can handle the URI, if one is designated.
-
Open the only available app that can handle the URI.
-
Allow the user to select an app from a dialog.
-
-
Unique Perfecto features, such as sensor injection, to complement the Appium feature set
Supported Android devices
The driver-based architecture works with any Android device that supports the UIAutomator2 (v1.25.0) automation framework.
Prerequisites
The driver-based architecture requires the following:
-
XPATH 1.0. Regular expression matching with the
matches()
function is not supported. -
Appium client 6.1.0 or later.
Enable the driver-based Appium architecture
During the transition phase from pre-driver-based Appium architecture (prior to Appium 1.10) to driver-based architecture, you need to select the driver-based architecture explicitly on a per-script basis using the following designated capabilities. These capabilities control the architecture used for either native only, native and web, native and hybrid, or native, web, and hybrid.
If the new architecture is already the default, you can omit these capabilities.
capabilities.setCapability("enableAppiumBehavior", true);
capabilities.setCapability("useAppiumForWeb", true);
capabilities.setCapability("browserName", "Chrome");
New capabilities for hybrid
capabilities.setCapability("enableAppiumBehavior", true);
capabilities.setCapability("useAppiumForHybrid", true);
Quantum capabilities
When working with a Quantum project, use the following capabilities.
Quantum | New capability for native
<parameter name="perfecto.capabilities.enableAppiumBehavior" value="true" />
Quantum | New capabilities for web
<parameter name="perfecto.capabilities.enableAppiumBehavior" value="true" />
<parameter name="perfecto.capabilities.useAppiumForWeb" value="true" />
<parameter name="perfecto.capabilities.browserName" value="Chrome" />
<parameter name="perfecto.capabilities.enableAppiumBehavior" value="true"></parameter>
<parameter name="perfecto.capabilities.useAppiumForHybrid" value="true" />
Alternatively, use the following syntax.
<parameter name="perfecto.additional.capabilities" value="{'enableAppiumBehavior':true, 'useAppiumForWeb':true, 'useAppiumForHybrid':true}" />
Migrate existing Perfecto hybrid scripts to the driver-based architecture
-
If your app uses WebViews, when creating the WebView object, set the
setWebContentsDebuggingEnabled
property totrue
. To learn more, see Android remote debugging. -
Change the value of the
automationName
capability fromPerfectoMobile
to its default value,Appium
. Alternatively, becauseAppium
is the default value, you can remove this capability. -
Cancel the instrumentation (there is no need to instrument the tested app). Then fix object locators, if needed, because the tree seen by the script is slightly different.
-
Add the following capabilities with a value of
true
(as described above):-
useAppiumForHybrid
-
enableAppiumBehavior
-
-
Review and adjust the switch-to-WebView logic in your code: The driver can now return the list with several WebView contexts, and the best practice is switching to the last context in this list (provided that the tested WebView is currently in the front).
Work with multipe WebViews in Android hybrid apps
Sometimes, Android hybrid apps have more than one WebView (for example, one for app content and one for ads). By default, Appium might only show one WebView context—often not the one you want.
To work with multiple WebViews:
-
Navigate to the screen with multiple WebViews and wait for them to load.
CopyWebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(hybridScreen)).click();
wait.until(ExpectedConditions.presenceOfElementLocated(webview)); -
Define a helper method to find and switch from the
NATIVE_APP
context to the WebView context.Copyprivate String getWebContext(AppiumDriver driver) {
for (String context : driver.getContextHandles()) {
if (!context.equals("NATIVE_APP")) return context;
}
return null;
} -
Call the helper method to get the WebView context and then switch to it.
Copydriver.context(getWebContext(driver));
-
Use the
getWindowHandles()
metho to access mutiple WebViews.Even within one WebView context, Appium sees multiple WebViews as separate windows via Chromedriver.
Copyfor (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle);
String content = driver.findElement(By.tagName("body")).getText();
System.out.println(content);
} -
Validate each WebView's content, such as body text, title, or URL, to confirm you are in the correct one.
Following is a complete code sample.
// 1. Wait for WebViews to Load
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(hybridScreen)).click();
wait.until(ExpectedConditions.presenceOfElementLocated(webview));
// 2. Switch to the WebView Context
private String getWebContext(AppiumDriver driver) {
for (String context : driver.getContextHandles()) {
if (!context.equals("NATIVE_APP")) return context; // Return the first non-native context (WebView)
}
return null;
}
driver.context(getWebContext(driver)); // Switch to WebView
// 3. Use getWindowHandles() to Access Multiple WebViews
// After switching to WebView context, switch between multiple WebViews
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle); // Switch between different WebViews
String content = driver.findElement(By.tagName("body")).getText(); // Extract content from the body tag
System.out.println(content); // Print content for validation or interaction
}
// 4. Validate Content
// Here, you can perform checks on the WebView’s content
// For example, check if the title matches
String pageTitle = driver.getTitle();
System.out.println("WebView Title: " + pageTitle);