Skip to content

Commit a69445d

Browse files
authored
Enable android integration test on android emulator (#376)
1 parent b43e145 commit a69445d

File tree

24 files changed

+816
-91
lines changed

24 files changed

+816
-91
lines changed

.github/workflows/integration_tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,10 @@ jobs:
351351
if: matrix.target_platform == 'Desktop' && !cancelled()
352352
run: |
353353
python scripts/gha/desktop_tester.py --testapp_dir ta
354-
- name: Run iOS integration tests on Simulator locally
355-
if: contains(env.mobileTestOn, 'simulator') && matrix.target_platform == 'iOS' && !cancelled()
354+
- name: Run iOS integration tests on iOS Simulator / Android Emulator locally
355+
if: contains(env.mobileTestOn, 'simulator') && startsWith(matrix.os, 'macos') && matrix.target_platform != 'Desktop' && !cancelled()
356356
run: |
357-
python scripts/gha/test_simulator.py --testapp_dir ta
357+
python scripts/gha/test_simulator.py --testapp_dir ta --ci
358358
# Workaround for https://github.com/GoogleCloudPlatform/github-actions/issues/100
359359
# Must be run after the Python setup action
360360
- name: Set CLOUDSDK_PYTHON (Windows)

scripts/gha/integration_testing/gameloop/gameloopUITests/gameloopUITests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class GameLoopLauncherUITests: XCTestCase {
8585
return timeoutSecs
8686
} else {
8787
// Default 5 minutes
88-
return TimeInterval(60 * 3)
88+
return TimeInterval(60 * 5)
8989
}
9090
}
9191

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apply plugin: 'com.android.application'
2+
apply plugin: 'kotlin-android'
3+
4+
android {
5+
compileSdkVersion rootProject.compileSdk
6+
buildToolsVersion rootProject.buildTools
7+
8+
defaultConfig {
9+
applicationId "com.google.firebase.gameloop"
10+
minSdkVersion rootProject.minSdk
11+
targetSdkVersion rootProject.targetSdk
12+
versionCode 1
13+
versionName "1.0"
14+
15+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16+
}
17+
18+
buildTypes {
19+
release {
20+
minifyEnabled false
21+
}
22+
}
23+
}
24+
25+
dependencies {
26+
implementation fileTree(dir: "libs", include: ["*.jar"])
27+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
28+
implementation 'androidx.core:core-ktx:1.1.0'
29+
implementation 'androidx.appcompat:appcompat:1.1.0'
30+
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
31+
32+
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
33+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
34+
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
35+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.google.firebase.gameloop">
5+
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator"/>
6+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.google.firebase.gameloop
2+
3+
import androidx.test.ext.junit.rules.ActivityScenarioRule
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import androidx.test.filters.SdkSuppress
6+
import androidx.test.platform.app.InstrumentationRegistry
7+
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
8+
import androidx.test.uiautomator.By
9+
import androidx.test.uiautomator.UiDevice
10+
import androidx.test.uiautomator.Until
11+
import junit.framework.Assert.assertNotNull
12+
import org.junit.Before
13+
import org.junit.Rule
14+
import org.junit.Test
15+
import org.junit.runner.RunWith
16+
17+
@RunWith(AndroidJUnit4::class)
18+
@SdkSuppress(minSdkVersion = 18)
19+
class GameLoopUITest {
20+
21+
companion object {
22+
const val GAMELOOP_TIMEOUT = 7 * 60 * 1000L
23+
}
24+
25+
private lateinit var device: UiDevice
26+
27+
@get:Rule
28+
var activityRule: ActivityScenarioRule<MainActivity>
29+
= ActivityScenarioRule(MainActivity::class.java)
30+
31+
@Before
32+
fun initDevice() {
33+
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
34+
}
35+
36+
@Test
37+
fun testLaunchGameLoop() {
38+
val element = device.wait(
39+
Until.findObject(By.text(getInstrumentation().targetContext.getString(R.string.test_complete))),
40+
GAMELOOP_TIMEOUT)
41+
assertNotNull(element)
42+
}
43+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.google.firebase.gameloop">
4+
5+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
6+
7+
<application
8+
android:allowBackup="true"
9+
android:icon="@mipmap/ic_launcher"
10+
android:label="@string/app_name"
11+
android:supportsRtl="true"
12+
android:theme="@style/AppTheme">
13+
14+
<activity android:name=".MainActivity">
15+
<intent-filter>
16+
<action android:name="android.intent.action.MAIN" />
17+
18+
<category android:name="android.intent.category.LAUNCHER" />
19+
</intent-filter>
20+
</activity>
21+
22+
<provider
23+
android:authorities="com.google.firebase.gameloop.fileprovider"
24+
android:name="androidx.core.content.FileProvider"
25+
android:exported="false"
26+
android:grantUriPermissions="true">
27+
<meta-data
28+
android:name="android.support.FILE_PROVIDER_PATHS"
29+
android:resource="@xml/file_paths"/>
30+
</provider>
31+
</application>
32+
33+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.google.firebase.gameloop
2+
3+
import android.content.Intent
4+
import android.content.pm.ResolveInfo
5+
import android.net.Uri
6+
import android.os.Bundle
7+
import android.util.Log
8+
import android.widget.TextView
9+
import androidx.appcompat.app.AppCompatActivity
10+
import androidx.core.content.FileProvider
11+
import java.io.File
12+
13+
14+
class MainActivity : AppCompatActivity(R.layout.activity_main) {
15+
companion object {
16+
const val GAMELOOP_INTENT = "com.google.intent.action.TEST_LOOP"
17+
const val TEST_LOOP_REQUEST_CODE = 1
18+
}
19+
20+
private lateinit var testingTV: TextView
21+
override fun onCreate(savedInstanceState: Bundle?) {
22+
super.onCreate(savedInstanceState)
23+
testingTV = findViewById(R.id.test)
24+
launchGame()
25+
}
26+
27+
private fun launchGame() {
28+
val intent = Intent(GAMELOOP_INTENT, null)
29+
intent.addCategory(Intent.CATEGORY_DEFAULT)
30+
intent.type = "application/javascript"
31+
val pkgAppsList: List<ResolveInfo> = packageManager.queryIntentActivities(intent, 0)
32+
val gamePackageName = pkgAppsList[0].activityInfo.packageName
33+
34+
val dir = File(getExternalFilesDir(null), gamePackageName)
35+
if (!dir.exists()) dir.mkdirs()
36+
val filename = "Results1.json"
37+
val file = File(dir, filename)
38+
file.createNewFile()
39+
Log.d("TAG", "Test Result Path :" + file)
40+
val fileUri: Uri = FileProvider.getUriForFile(this, "com.google.firebase.gameloop.fileprovider", file)
41+
42+
intent.setPackage(gamePackageName)
43+
.setDataAndType(fileUri, "application/javascript").flags = Intent.FLAG_GRANT_WRITE_URI_PERMISSION
44+
45+
startActivityForResult(intent, TEST_LOOP_REQUEST_CODE)
46+
}
47+
48+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
49+
super.onActivityResult(requestCode, resultCode, data)
50+
when (requestCode) {
51+
TEST_LOOP_REQUEST_CODE -> testingTV.text = getString(R.string.test_complete)
52+
}
53+
}
54+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
tools:context=".MainActivity">
8+
<TextView
9+
android:layout_width="wrap_content"
10+
android:layout_height="wrap_content"
11+
android:text="@string/testing"
12+
android:id="@+id/test"
13+
app:layout_constraintBottom_toBottomOf="parent"
14+
app:layout_constraintLeft_toLeftOf="parent"
15+
app:layout_constraintRight_toRightOf="parent"
16+
app:layout_constraintTop_toTopOf="parent" />
17+
18+
</androidx.constraintlayout.widget.ConstraintLayout>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<color name="colorPrimary">#6200EE</color>
4+
<color name="colorPrimaryDark">#3700B3</color>
5+
<color name="colorAccent">#03DAC5</color>
6+
</resources>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<resources>
2+
<string name="app_name">gameloop</string>
3+
<string name="testing">Testing</string>
4+
<string name="test_complete">Game Loop Complete</string>
5+
</resources>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<resources>
2+
<!-- Base application theme. -->
3+
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
4+
<!-- Customize your theme here. -->
5+
<item name="colorPrimary">@color/colorPrimary</item>
6+
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
7+
<item name="colorAccent">@color/colorAccent</item>
8+
</style>
9+
10+
</resources>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<paths>
3+
<external-path
4+
name="files"
5+
path="/"/>
6+
</paths>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2+
buildscript {
3+
ext.kotlin_version = "1.3.72"
4+
repositories {
5+
google()
6+
jcenter()
7+
}
8+
dependencies {
9+
classpath "com.android.tools.build:gradle:4.0.1"
10+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11+
12+
// NOTE: Do not place your application dependencies here; they belong
13+
// in the individual module build.gradle files
14+
}
15+
}
16+
17+
allprojects {
18+
repositories {
19+
google()
20+
jcenter()
21+
}
22+
}
23+
24+
ext {
25+
compileSdk = 28
26+
buildTools = '28.0.3'
27+
minSdk = 16
28+
targetSdk = 28
29+
}
30+
31+
task clean(type: Delete) {
32+
delete rootProject.buildDir
33+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Project-wide Gradle settings.
2+
# IDE (e.g. Android Studio) users:
3+
# Gradle settings configured through the IDE *will override*
4+
# any settings specified in this file.
5+
# For more details on how to configure your build environment visit
6+
# http://www.gradle.org/docs/current/userguide/build_environment.html
7+
# Specifies the JVM arguments used for the daemon process.
8+
# The setting is particularly useful for tweaking memory settings.
9+
org.gradle.jvmargs=-Xmx2048m
10+
# When configured, Gradle will run in incubating parallel mode.
11+
# This option should only be used with decoupled projects. More details, visit
12+
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13+
# org.gradle.parallel=true
14+
# AndroidX package structure to make it clearer which packages are bundled with the
15+
# Android operating system, and which are packaged with your app"s APK
16+
# https://developer.android.com/topic/libraries/support-library/androidx-rn
17+
android.useAndroidX=true
18+
# Automatically convert third-party libraries to use AndroidX
19+
android.enableJetifier=true
20+
# Kotlin code style for this project: "official" or "obsolete":
21+
kotlin.code.style=official
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Sat Apr 03 15:11:30 PDT 2021
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
zipStoreBase=GRADLE_USER_HOME
5+
zipStorePath=wrapper/dists
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

0 commit comments

Comments
 (0)