Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.

Commit 557166b

Browse files
author
Sharath Ganesh Pai
committed
Setup UIAutomator Tests and enable it in CI.
1 parent ecabc88 commit 557166b

14 files changed

Lines changed: 1417 additions & 26 deletions

File tree

Jenkinsfile

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ def matrix = [
1111
'target': 'i686-linux-android',
1212
'test': true,
1313
],
14-
'cliqz-alpha':[
14+
/*'cliqz-alpha':[
1515
'bundleid': 'com.cliqz.browser.alpha',
1616
'target': 'arm-linux-androideabi',
1717
'test': false,
18-
],
18+
],*/
1919
'ghostery-alpha':[
2020
'bundleid': 'com.ghostery.android.alpha',
2121
'target': 'arm-linux-androideabi',
@@ -35,14 +35,14 @@ def build(Map m){
3535
def apk = ""
3636
def testsFolder = "cliqz-mobile-tests"
3737
setupTestInstance(
38-
test,
39-
"ami-6c24fc11",
40-
"1",
41-
"t2.medium",
42-
"android_ci_genymotion",
43-
"sg-5bbf173f",
44-
"subnet-341ff61f",
45-
"us-east-1"
38+
test, // Boolean value for Running Tests
39+
"ami-6c24fc11", // Amazon AWS AMI ID
40+
"1", // Count, Number of Instances
41+
"t2.medium", // Instance Size
42+
"android_ci_genymotion", // RSA Key
43+
"sg-5bbf173f", // Secutiry Group ID of AWS
44+
"subnet-341ff61f", // Subnet ID for the instance
45+
"us-east-1" // AWS Region
4646
) {
4747
try {
4848
stage('Checkout') {
@@ -55,10 +55,14 @@ def build(Map m){
5555
image.pull()
5656
image.inside {
5757
stage('Build Cliqz React Native') {
58-
cliqz.buildCliqzReactNative("cliqz")
58+
cliqz.buildCliqzReactNative("cliqz") // Pass the Folder Name for the React Native SRC
5959
}
6060
stage("Build APK: ${flavorname}") {
61-
apk = cliqz.buildBrowser("${androidtarget}", "${flavorname}", "ci")
61+
apk = cliqz.buildBrowser(
62+
"${androidtarget}", // Target for the build
63+
"${flavorname}", // Name of the Flavor
64+
"ci" // Type of the Build (CI, Nightly or Release)
65+
)
6266
archiveArtifacts allowEmptyArchive: true, artifacts: "build/${apk}"
6367
}
6468
}
@@ -78,12 +82,22 @@ def build(Map m){
7882
"FLAVOR=${flavorname}",
7983
"appPackage=${bundleid}"
8084
]) {
81-
stage('Genymotion ADB Connect') {
82-
genymotion.connectGenyInstance('da5f91e6-e1ca-4aac-94ea-352b6769228b')
85+
stage('Set Genymotion Resolution and Connect') {
86+
genymotion.genySetPhoneResolution('da5f91e6-e1ca-4aac-94ea-352b6769228b') // Pass the Credentials ID for the AWS API Key
87+
genymotion.connectGenyInstance('da5f91e6-e1ca-4aac-94ea-352b6769228b') // Pass the Credentials ID for the AWS API Key
88+
}
89+
stage("Run UIA2 Tests & Upload Results: ${flavorname}"){
90+
timeout(10){
91+
cliqz.runUITests("${flavorname}") // Pass the Flavor Name for running the UIAutomator Tests
92+
}
8393
}
84-
stage("Run Tests & Upload Results: ${flavorname}") {
94+
stage("Run Appium Tests & Upload Results: ${flavorname}") {
8595
timeout(60) {
86-
cliqz.runAppiumTests("${testsFolder}", "${flavorname}", "${apk}")
96+
cliqz.runAppiumTests(
97+
"${testsFolder}", // Path to the Folder where the Tests are cloned.
98+
"${flavorname}", // Flavor Name for running the UIAutomator Tests
99+
"${apk}" // Path to the APK used for testing.
100+
)
87101
}
88102
}
89103
}
@@ -95,7 +109,7 @@ def build(Map m){
95109
error 'Something Failed ! Check Logs above.'
96110
} finally {
97111
stage('Clean Up') {
98-
utils.cleanUp("${testsFolder}")
112+
utils.cleanUp("${testsFolder}") // Path to the Folder where the Tests are cloned. This will delete the Tests Folder.
99113
}
100114
}
101115
}

Jenkinsfile.docker

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ node('us-east-1 && ubuntu && docker && !gpu') {
1010
}
1111

1212
def baseImageName = "browser-f/android:${dockerTag}"
13-
13+
1414
stage('Build Create Docker Image') {
1515
docker.withRegistry('https://141047255820.dkr.ecr.us-east-1.amazonaws.com'){
1616
def baseImage = docker.build(baseImageName, '--build-arg USER=`whoami` --build-arg UID=`id -u` --build-arg GID=`id -g` .')

mozconfigs/jenkins.mozconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# Build Firefox for Android:
22
# Add MOZILLA_OFFICIAL flag to proguard the artifacts
3-
MOZILLA_OFFICIAL=1
3+
# MOZILLA_OFFICIAL=1
44

55
# Android Targets: 'i686-linux-android' or 'arm-linux-androideabi'
66
ac_add_options --enable-application=mobile/android
77
ac_add_options --target=$ANDROID_TARGET
88

99
# With the following Android SDK:
1010
ac_add_options --with-android-sdk=$ANDROID_HOME
11+
ac_add_options --with-android-min-sdk=21
1112

1213
# Allow artifact builds:
1314
ac_add_options --enable-artifact-builds

mozilla-release/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ buildscript {
5252
url repository
5353
}
5454
}
55+
google()
5556
}
5657

5758
ext.kotlin_version = '1.2.41'

mozilla-release/mobile/android/app/build.gradle

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ android {
4747
ndk {
4848
abiFilters mozconfig.substs.ANDROID_CPU_ARCH.toString()
4949
}
50+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
51+
// testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
52+
// Used by Robolectric based tests; see TestRunner.
5053
/* Cliqz end */
5154
applicationId mozconfig.substs.ANDROID_PACKAGE_NAME
52-
testApplicationId 'org.mozilla.roboexample.test'
53-
testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
54-
// Used by Robolectric based tests; see TestRunner.
5555
buildConfigField 'String', 'BUILD_DIR', "\"${project.buildDir}\""
5656
multiDexEnabled true
5757
vectorDrawables.useSupportLibrary = true
@@ -214,7 +214,11 @@ android {
214214
}
215215

216216
androidTest {
217-
java {
217+
/* Cliqz Start :: Cliqz Android Tests */
218+
java {
219+
srcDir "${topsrcdir}/mobile/android/tests/cliqz/java"
220+
}
221+
/*java {
218222
srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/src"
219223
// Bug 1229149 tracks pushing this into a :services Gradle project.
220224
srcDir "${topsrcdir}/mobile/android/services/src/androidTest/java"
@@ -226,6 +230,7 @@ android {
226230
assets {
227231
srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/assets"
228232
}
233+
/o Cliqz End */
229234
}
230235
}
231236

@@ -289,7 +294,9 @@ dependencies {
289294
implementation project(path: ':thirdparty')
290295

291296
testImplementation 'junit:junit:4.12'
297+
/* Cliqz Start o/
292298
testImplementation 'org.robolectric:robolectric:3.8'
299+
/o Cliqz End */
293300
testImplementation 'org.simpleframework:simple-http:6.0.1'
294301
testImplementation 'org.mockito:mockito-core:1.10.19'
295302

@@ -299,6 +306,9 @@ dependencies {
299306
/*Cliqz Start*/
300307
//Library for control center donut - chart
301308
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.2'
309+
//UIAutomator2 Dependencies
310+
implementation 'com.android.support.test:testing-support-lib:0.1'
311+
implementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
302312
/*Cliqz End*/
303313

304314
}
@@ -608,3 +618,21 @@ if (mozconfig.substs.MOZ_JAVA_CODE_COVERAGE) {
608618
}
609619
}
610620
}
621+
/* Cliqz Start */
622+
// Grant permissions to disable Animations.
623+
task grantAnimationPermissions(type: Exec, dependsOn: 'installWithGeckoBinariesDebug') {
624+
group = 'Verification tasks'
625+
description = 'Grant permissions for testing.'
626+
def appPackage = mozconfig.substs.ANDROID_PACKAGE_NAME
627+
def androidHome = mozconfig.substs.ANDROID_SDK_ROOT
628+
commandLine "$androidHome/platform-tools/adb shell pm grant $appPackage android.permission.SET_ANIMATION_SCALE".split(" ")
629+
}
630+
631+
afterEvaluate {
632+
tasks.each { task ->
633+
if (task.name.contains('connectedWithGeckoBinariesDebugAndroidTest')) {
634+
task.dependsOn grantAnimationPermissions
635+
}
636+
}
637+
}
638+
/* Cliqz End */

mozilla-release/mobile/android/app/src/androidTest/AndroidManifest.xml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Cliqz Start -->
23
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
package="org.mozilla.roboexample.test"
4+
package="com.cliqz.mobile.test"
45
android:sharedUserId="${MOZ_ANDROID_SHARED_ID}"
56
android:versionCode="1"
67
android:versionName="1.0" >
8+
<!-- NOTE: Replaced package name. package="org.mozilla.roboexample.test" Cliqz End -->
79

810
<uses-sdk android:minSdkVersion="${MOZ_ANDROID_MIN_SDK_VERSION}"
911
android:targetSdkVersion="${ANDROID_TARGET_SDK}"/>
1012
<!-- TODO: re-instate maxSdkVersion. -->
1113

1214
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
13-
1415
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
1516
<uses-permission android:name="android.permission.WAKE_LOCK" />
1617

1718
<instrumentation
1819
android:name="org.mozilla.gecko.FennecInstrumentationTestRunner"
1920
android:targetPackage="${ANDROID_PACKAGE_NAME}" />
2021

22+
<!-- Cliqz Start -+>
23+
<application
24+
android:label="@string/app_name"> -->
2125
<application
22-
android:label="@string/app_name">
26+
android:label="Instrumentation Test">
27+
<!-- Cliqz End -->
2328

2429
<uses-library android:name="android.test.runner" />
2530

mozilla-release/mobile/android/base/AndroidManifest.xml.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#ifdef MOZ_ANDROID_SHARED_ID
1111
android:sharedUserId="@MOZ_ANDROID_SHARED_ID@"
1212
#endif
13+
<uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
1314
<! - Cliqz End -->
1415
<uses-sdk android:minSdkVersion="@MOZ_ANDROID_MIN_SDK_VERSION@"
1516
#ifdef MOZ_ANDROID_MAX_SDK_VERSION

mozilla-release/mobile/android/base/FennecManifest_permissions.xml.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
<uses-feature android:name="android.hardware.nfc" android:required="false"/>
4646
#endif
4747

48+
#ifndef MOZILLA_OFFICIAL
49+
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
50+
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
51+
#endif
52+
4853
#ifdef MOZ_WEBRTC
4954
<uses-feature android:name="android.hardware.audio.low_latency" android:required="false"/>
5055
<uses-feature android:name="android.hardware.camera.any" android:required="false"/>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.cliqz.mobile.test;
2+
3+
import android.util.Log;
4+
5+
import org.junit.Ignore;
6+
import org.junit.internal.AssumptionViolatedException;
7+
import org.junit.internal.runners.model.EachTestNotifier;
8+
import org.junit.runner.Description;
9+
import org.junit.runner.notification.RunNotifier;
10+
import org.junit.runner.notification.StoppedByUserException;
11+
import org.junit.runners.BlockJUnit4ClassRunner;
12+
import org.junit.runners.model.FrameworkMethod;
13+
import org.junit.runners.model.InitializationError;
14+
import org.junit.runners.model.Statement;
15+
16+
/**
17+
* Copyright © Cliqz 2019
18+
*/
19+
public class CliqzRunner extends BlockJUnit4ClassRunner {
20+
21+
private static final int RETRY_COUNT = 2;
22+
23+
public CliqzRunner(Class<?> clazz) throws InitializationError {
24+
super(clazz);
25+
}
26+
27+
@Override
28+
public void run(final RunNotifier notifier) {
29+
final EachTestNotifier testNotifier = new EachTestNotifier(notifier, getDescription());
30+
Statement statement = classBlock(notifier);
31+
try {
32+
statement.evaluate();
33+
} catch (AssumptionViolatedException ave) {
34+
testNotifier.fireTestIgnored();
35+
} catch (StoppedByUserException sbue) {
36+
throw sbue;
37+
} catch (Throwable t) {
38+
Log.w("AUTOBOTS", "Retry class: " + getDescription().getDisplayName());
39+
retry(testNotifier, statement, t, getDescription());
40+
}
41+
}
42+
43+
@Override
44+
protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
45+
final Description description = describeChild(method);
46+
if (method.getAnnotation(Ignore.class) != null) {
47+
notifier.fireTestIgnored(description);
48+
} else {
49+
runTest(methodBlock(method), description, notifier);
50+
}
51+
}
52+
53+
private void runTest(Statement statement, Description description, RunNotifier notifier) {
54+
final EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
55+
eachNotifier.fireTestStarted();
56+
try {
57+
statement.evaluate();
58+
} catch (AssumptionViolatedException e) {
59+
eachNotifier.addFailedAssumption(e);
60+
} catch (Throwable e) {
61+
Log.w("AUTOBOTS", "Retry test: " + description.getDisplayName());
62+
retry(eachNotifier, statement, e, description);
63+
} finally {
64+
eachNotifier.fireTestFinished();
65+
}
66+
}
67+
68+
private void retry(EachTestNotifier notifier, Statement statement, Throwable currentThrowable, Description info) {
69+
int failedAttempts = 0;
70+
Throwable caughtThrowable = currentThrowable;
71+
while (RETRY_COUNT > failedAttempts) {
72+
try {
73+
notifier.fireTestIgnored();
74+
notifier.fireTestStarted();
75+
Log.w("AUTOBOTS", "Retry attempt " + (failedAttempts + 1) + " for " + info.getDisplayName());
76+
statement.evaluate();
77+
notifier.fireTestFinished();
78+
return;
79+
} catch (Throwable t) {
80+
failedAttempts++;
81+
caughtThrowable = t;
82+
}
83+
}
84+
Log.e("AUTOBOTS", caughtThrowable.getMessage());
85+
notifier.addFailure(caughtThrowable);
86+
}
87+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.cliqz.mobile.test.driver;
2+
3+
import android.support.test.uiautomator.UiObject2;
4+
import android.util.Log;
5+
6+
/**
7+
* Copyright © Cliqz 2019
8+
*/
9+
public class ElementData {
10+
11+
private UiObject2 element;
12+
private boolean exists;
13+
private boolean checked;
14+
private boolean enabled;
15+
private boolean focused;
16+
private boolean selected;
17+
private String text;
18+
private String description;
19+
20+
21+
public ElementData(UiObject2 elem) {
22+
element = elem;
23+
try {
24+
exists = element.getResourceName()!=null;
25+
text = element.getText();
26+
description = element.getContentDescription();
27+
checked = element.isChecked();
28+
enabled = element.isEnabled();
29+
focused = element.isFocused();
30+
selected = element.isSelected();
31+
} catch (Exception e) {
32+
Log.w("AUTOBOTS", e.toString());
33+
}
34+
}
35+
36+
public boolean hasChanged() {
37+
ElementData tempData = new ElementData(element);
38+
return this != tempData;
39+
}
40+
41+
}

0 commit comments

Comments
 (0)