Skip to content

Commit 5703953

Browse files
authored
Open sourcing Firebase In-App Messaging's Display SDK (#90)
[Firebase In-App Messaging](https://firebase.google.com/docs/in-app-messaging/) helps you engage users who are actively using your app by sending them targeted and contextual messages that nudge them to complete key in-app actions - like beating a game level, buying an item, or subscribing to content. The FIAM Display SDK gives you more control over your in-app messages you send, allowing you to customize typeface, colors, transitions, corner radii, and more.
1 parent e29a6e0 commit 5703953

File tree

128 files changed

+7979
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+7979
-2
lines changed

fiamui-app/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# FIAMUI-App SDK
2+
This module contains a test-app for Firebase In-App Messaging's Display SDK
3+
(see the firebase-inappmessaging-display module).
4+
5+
[Firebase In-App Messaging](https://firebase.google.com/docs/in-app-messaging/) helps you engage
6+
users who are actively using your app by sending them targeted and contextual messages that nudge
7+
them to complete key in-app actions - like beating a game level, buying an item, or subscribing to
8+
content.
9+
10+
The FIAM Display SDK gives you more control over your in-app messages you send, allowing you to
11+
customize typeface, colors, transitions, corner radii, and more.
12+
13+
## Running Tests
14+
Unit tests:
15+
`../gradlew :fiamui-app:test`
16+
17+
Integration tests, requiring a running and connected device (emulator or real):
18+
`../gradlew :fiamui-app:connectedAndroidTest`
19+
20+
The best way to test is via the fiamui-app in this repo - you can run the test, or use
21+
Firebase Test Lab to run a series of UI tests. See fiamui-app/scripts for more details

fiamui-app/fiamui-app.gradle

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
apply plugin: "com.android.application"
16+
17+
android {
18+
compileSdkVersion 27
19+
20+
defaultConfig {
21+
applicationId "com.example.firebase.fiamui"
22+
minSdkVersion 16
23+
targetSdkVersion 27
24+
versionCode 1
25+
versionName "1.0"
26+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
27+
multiDexEnabled true
28+
}
29+
30+
buildTypes {
31+
release {
32+
minifyEnabled false
33+
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
34+
}
35+
}
36+
37+
testOptions {
38+
animationsDisabled = true
39+
}
40+
41+
lintOptions {
42+
warning 'InvalidPackage'
43+
warning 'GradleCompatible'
44+
}
45+
46+
// TODO: Would be nice if we could test on 1_7
47+
compileOptions {
48+
sourceCompatibility JavaVersion.VERSION_1_8
49+
targetCompatibility JavaVersion.VERSION_1_8
50+
}
51+
}
52+
53+
dependencies {
54+
implementation project(path: ":firebase-inappmessaging-display")
55+
implementation "com.google.firebase:firebase-measurement-connector:17.0.1"
56+
implementation('com.google.firebase:firebase-inappmessaging:17.0.3') {
57+
exclude group: 'com.google.firebase', module: 'firebase-common'
58+
}
59+
implementation('com.google.firebase:firebase-analytics:16.0.4') {
60+
exclude group: 'com.google.firebase', module: 'firebase-common'
61+
}
62+
63+
implementation "com.android.installreferrer:installreferrer:1.0"
64+
implementation "com.android.support:design:27.1.1"
65+
implementation "com.android.support:appcompat-v7:27.1.1"
66+
67+
// The following dependencies are not required to use the FIAM UI library.
68+
// They are used to make some aspects of the demo app implementation simpler for
69+
// demonstrative purposes, and you may find them useful in your own apps; YMMV.
70+
implementation 'me.priyesh:chroma:1.0.2'
71+
implementation "com.jakewharton:butterknife:8.8.1"
72+
implementation "com.jakewharton:butterknife-compiler:8.8.1"
73+
annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"
74+
75+
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
76+
androidTestImplementation 'com.android.support.test:rules:1.0.2'
77+
}

fiamui-app/proguard-rules.pro

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in /usr/local/google/home/ashwinraghav/Android/Sdk/tools/proguard/proguard-android.txt
4+
# You can edit the include path and order by changing the proguardFiles
5+
# directive in build.gradle.
6+
#
7+
# For more details, see
8+
# http://developer.android.com/guide/developing/tools/proguard.html
9+
10+
# Add any project specific keep options here:
11+
12+
# If your project uses WebView with JS, uncomment the following
13+
# and specify the fully qualified class name to the JavaScript interface
14+
# class:
15+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16+
# public *;
17+
#}
18+
19+
# Uncomment this to preserve the line number information for
20+
# debugging stack traces.
21+
#-keepattributes SourceFile,LineNumberTable
22+
23+
# If you keep the line number information, uncomment this to
24+
# hide the original source file name.
25+
#-renamesourcefileattribute SourceFile
26+
27+
-keep class **$$ViewInjector { *; }
28+
-keep class **$$ViewBinder { *; }

fiamui-app/scripts/run-test-lab.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
#
3+
# Copyright 2018 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# First, you need to create a project, and bucket to use for the FTL runs.
18+
19+
#############################################################################################
20+
## Note, running this will incur any FTL-related charges. ##
21+
## We do require manual setting of the script arguments to ensure you've read this notice. ##
22+
#############################################################################################
23+
24+
PROJECT_ID={{add your project id here}}
25+
BUCKET_NAME={{add your bucket name here}}
26+
27+
# Assemble the app
28+
./gradlew :fiamui-app:assembleDebug :fiamui-app:assembleDebugAndroidTest
29+
30+
# Choose the project
31+
gcloud config set project $PROJECT_ID
32+
33+
# Show the storage bucket
34+
echo "Tests launching!"
35+
36+
# Run the tests on the following devices
37+
# * Pixel 2, API 27 - good for testing the ideal case
38+
# * OnePlus, API 22 - popular problematic phone model
39+
# * Nexus 7, API 19 - small tablet screen, outdated API
40+
# * Galaxy S7E, API 23 - popular high-end phone model, samsung exposure
41+
# * Low Res Phone, API 23 - capture very low-res cases
42+
# * Moto X, API 19 - popular old phone model, low API
43+
gcloud firebase test android run \
44+
--type instrumentation \
45+
--results-bucket=$BUCKET_NAME \
46+
--app fiamui-app/build/outputs/apk/debug/fiamui-app-debug.apk \
47+
--test fiamui-app/build/outputs/apk/androidTest/debug/fiamui-app-debug-androidTest.apk \
48+
--device model=Pixel2,version=27,locale=en,orientation=portrait \
49+
--device model=Pixel2,version=27,locale=en,orientation=landscape \
50+
--device model=A0001,version=22,locale=en,orientation=portrait \
51+
--device model=A0001,version=22,locale=en,orientation=landscape \
52+
--device model=Nexus7,version=19,locale=en,orientation=portrait \
53+
--device model=Nexus7,version=19,locale=en,orientation=landscape \
54+
--device model=hero2lte,version=23,locale=en,orientation=portrait \
55+
--device model=hero2lte,version=23,locale=en,orientation=landscape \
56+
--device model=NexusLowRes,version=23,locale=en,orientation=portrait \
57+
--device model=NexusLowRes,version=23,locale=en,orientation=landscape \
58+
--device model=victara,version=19,locale=en,orientation=portrait \
59+
--device model=victara,version=19,locale=en,orientation=landscape
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.example.firebase.fiamui">
4+
5+
<application>
6+
<uses-library android:name="android.test.runner"/>
7+
</application>
8+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
9+
<uses-permission android:name="android.permission.INTERNET"/>
10+
</manifest>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.example.firebase.fiamui;
16+
17+
import static android.support.test.espresso.Espresso.onView;
18+
import static android.support.test.espresso.action.ViewActions.click;
19+
import static android.support.test.espresso.action.ViewActions.scrollTo;
20+
import static android.support.test.espresso.action.ViewActions.swipeLeft;
21+
import static android.support.test.espresso.assertion.ViewAssertions.matches;
22+
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
23+
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
24+
import static android.support.test.espresso.matcher.ViewMatchers.withId;
25+
import static android.support.test.espresso.matcher.ViewMatchers.withText;
26+
import static com.example.firebase.fiamui.TestConstants.*;
27+
import static org.hamcrest.CoreMatchers.is;
28+
import static org.hamcrest.CoreMatchers.not;
29+
30+
import android.support.annotation.IdRes;
31+
import android.support.annotation.NonNull;
32+
import android.support.test.espresso.Root;
33+
import android.support.test.espresso.ViewInteraction;
34+
import android.support.test.filters.MediumTest;
35+
import android.support.test.rule.ActivityTestRule;
36+
import android.support.test.runner.AndroidJUnit4;
37+
import org.hamcrest.Matcher;
38+
import org.junit.After;
39+
import org.junit.Before;
40+
import org.junit.Rule;
41+
import org.junit.Test;
42+
import org.junit.rules.TestName;
43+
import org.junit.runner.RunWith;
44+
45+
@MediumTest
46+
@RunWith(AndroidJUnit4.class)
47+
public class BannerTest {
48+
49+
@Rule
50+
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
51+
52+
@Rule public TestName name = new TestName();
53+
54+
private Matcher<Root> rootMatcher;
55+
56+
@Before
57+
public void setUp() {
58+
rootMatcher = withDecorView(not(is(mActivityRule.getActivity().getWindow().getDecorView())));
59+
}
60+
61+
@After
62+
public void tearDown() {
63+
ScreenShotter.takeScreenshot(name.getMethodName());
64+
close();
65+
}
66+
67+
@Test
68+
public void testBanner() {
69+
open();
70+
71+
getView(R.id.banner_root).check(matches(isDisplayed()));
72+
getView(R.id.banner_title).check(matches(withText(TITLE_TEXT_NORMAL)));
73+
getView(R.id.banner_body).check(matches(withText(BODY_TEXT_NORMAL)));
74+
}
75+
76+
private void open() {
77+
onView(withId(R.id.banner_fiam)).perform(scrollTo()).perform(click());
78+
onView(withId(R.id.start)).perform(scrollTo()).perform(click());
79+
}
80+
81+
private void close() {
82+
getView(R.id.banner_content_root).perform(swipeLeft());
83+
84+
// Need to sleep for a second to give the swipe animation time to finish so
85+
// the banner does not interfere with the next test.
86+
try {
87+
Thread.sleep(1000);
88+
} catch (InterruptedException e) {
89+
e.printStackTrace();
90+
}
91+
}
92+
93+
@NonNull
94+
private ViewInteraction getView(@IdRes int id) {
95+
return onView(withId(id)).inRoot(rootMatcher);
96+
}
97+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.example.firebase.fiamui;
16+
17+
import static android.support.test.espresso.Espresso.onView;
18+
import static android.support.test.espresso.action.ViewActions.click;
19+
import static android.support.test.espresso.action.ViewActions.scrollTo;
20+
import static android.support.test.espresso.assertion.ViewAssertions.matches;
21+
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
22+
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
23+
import static android.support.test.espresso.matcher.ViewMatchers.withId;
24+
import static org.hamcrest.CoreMatchers.is;
25+
import static org.hamcrest.CoreMatchers.not;
26+
27+
import android.support.annotation.IdRes;
28+
import android.support.annotation.NonNull;
29+
import android.support.test.espresso.Root;
30+
import android.support.test.espresso.ViewInteraction;
31+
import android.support.test.filters.MediumTest;
32+
import android.support.test.rule.ActivityTestRule;
33+
import android.support.test.runner.AndroidJUnit4;
34+
import org.hamcrest.Matcher;
35+
import org.junit.After;
36+
import org.junit.Before;
37+
import org.junit.Rule;
38+
import org.junit.Test;
39+
import org.junit.rules.TestName;
40+
import org.junit.runner.RunWith;
41+
42+
@MediumTest
43+
@RunWith(AndroidJUnit4.class)
44+
public class ImageTest {
45+
46+
@Rule
47+
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
48+
49+
@Rule public TestName name = new TestName();
50+
51+
private Matcher<Root> rootMatcher;
52+
53+
@Before
54+
public void setUp() {
55+
rootMatcher = withDecorView(not(is(mActivityRule.getActivity().getWindow().getDecorView())));
56+
}
57+
58+
@After
59+
public void tearDown() {
60+
ScreenShotter.takeScreenshot(name.getMethodName());
61+
close();
62+
}
63+
64+
@Test
65+
public void testImage() {
66+
open();
67+
68+
getView(R.id.image_root).check(matches(isDisplayed()));
69+
}
70+
71+
@NonNull
72+
private ViewInteraction getView(@IdRes int id) {
73+
return onView(withId(id)).inRoot(rootMatcher);
74+
}
75+
76+
private void open() {
77+
onView(withId(R.id.image_fiam)).perform(scrollTo()).perform(click());
78+
onView(withId(R.id.start)).perform(scrollTo()).perform(click());
79+
}
80+
81+
private void close() {
82+
getView(R.id.collapse_button).perform(click());
83+
}
84+
}

0 commit comments

Comments
 (0)