Bug 1357633 - part2 : add tests.
Based on bug1357639, add new test tasks.
MozReview-Commit-ID: 9k8ZkF00MwG
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/robocop/robocop_media_playback_js.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<audio id="testAudio" src="audio.ogg" loop></audio>
+<script type="application/javascript" src="robocop_head.js"></script>
+<script type="text/javascript">
+var audio = document.getElementById("testAudio");
+
+let test = {
+ play_audio : function() {
+ audio.play();
+ },
+
+ pause_audio : function() {
+ audio.pause();
+ },
+
+ adjust_audio_volume : function(volume) {
+ audio.volume = volume;
+ },
+
+ adjust_audio_muted : function(muted) {
+ audio.muted = muted;
+ },
+
+ finish_test: function() {
+ java.disconnect();
+ },
+};
+
+var java = new JavaBridge(test);
+
+</script>
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/MediaPlaybackTest.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/MediaPlaybackTest.java
@@ -6,31 +6,33 @@ package org.mozilla.gecko.tests;
import org.mozilla.gecko.Actions;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.media.AudioFocusAgent;
import org.mozilla.gecko.media.AudioFocusAgent.State;
import org.mozilla.gecko.media.MediaControlService;
+import org.mozilla.gecko.tests.helpers.JavascriptBridge;
import android.content.Intent;
import android.content.Context;
import android.app.Notification;
import android.app.NotificationManager;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.service.notification.StatusBarNotification;
import com.robotium.solo.Condition;
abstract class MediaPlaybackTest extends BaseTest {
private Context mContext;
private int mPrevIcon = 0;
+ private JavascriptBridge mJs;
private static final int UI_CHANGED_WAIT_MS = 6000;
protected final void info(String msg) {
mAsserter.dumpLog(msg);
}
protected final Context getContext() {
@@ -294,9 +296,35 @@ abstract class MediaPlaybackTest extends
mAsserter.ok(isAvailableToCheckNotification(),
"Checking the android version for media control testing",
"The API to check system notification is only available after version 23.");
}
protected final boolean isAvailableToCheckNotification() {
return Build.VERSION.SDK_INT >= 23;
}
+
+ /**
+ * Can communicte with JS bey getJS(), but caller should create and destroy
+ * JSBridge manually.
+ */
+ protected JavascriptBridge getJS() {
+ mAsserter.ok(mJs != null,
+ "JSBridege existence check",
+ "Should connect JSBridge before using JS!");
+ return mJs;
+ }
+
+ protected void createJSBridge() {
+ mAsserter.ok(mJs == null,
+ "JSBridege existence check",
+ "Should not recreate the JSBridge!");
+ mJs = new JavascriptBridge(this, mActions, mAsserter);
+ }
+
+ protected void destroyJSBridge() {
+ mAsserter.ok(mJs != null,
+ "JSBridege existence check",
+ "Should create JSBridge before destroy it!");
+ mJs.disconnect();
+ mJs = null;
+ }
}
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/StringHelper.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/StringHelper.java
@@ -80,16 +80,17 @@ public class StringHelper {
public final String ROBOCOP_OFFLINE_STORAGE_URL = "/robocop/robocop_offline_storage.html";
public final String ROBOCOP_PICTURE_LINK_URL = "/robocop/robocop_picture_link.html";
public final String ROBOCOP_SEARCH_URL = "/robocop/robocop_search.html";
public final String ROBOCOP_TEXT_PAGE_URL = "/robocop/robocop_text_page.html";
public final String ROBOCOP_ADOBE_FLASH_URL = "/robocop/robocop_adobe_flash.html";
public final String ROBOCOP_INPUT_URL = "/robocop/robocop_input.html";
public final String ROBOCOP_READER_MODE_BASIC_ARTICLE = "/robocop/reader_mode_pages/basic_article.html";
public final String ROBOCOP_LINK_TO_SLOW_LOADING = "/robocop/robocop_link_to_slow_loading.html";
+ public final String ROBOCOP_MEDIA_PLAYBACK_JS_URL = "/robocop/robocop_media_playback_js.html";
public final String ROBOCOP_MEDIA_PLAYBACK_LOOP_URL = "/robocop/robocop_media_playback_loop.html";
private final String ROBOCOP_JS_HARNESS_URL = "/robocop/robocop_javascript.html";
// Robocop page images
public final String ROBOCOP_PICTURE_URL = "/robocop/Firefox.jpg";
// Robocop page titles
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/helpers/JavascriptBridge.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/helpers/JavascriptBridge.java
@@ -100,16 +100,27 @@ public final class JavascriptBridge {
// If JavaBridge has been loaded
private boolean mJavaBridgeLoaded;
/* package */ static void init(final UITestContext context) {
sActions = context.getActions();
sAsserter = context.getAsserter();
}
+ public JavascriptBridge(final Object target, final Actions action, final Assert asserter) {
+ sActions = action;
+ sAsserter = asserter;
+ mTarget = target;
+ mMethods = target.getClass().getMethods();
+ mExpecter = sActions.expectGlobalEvent(Actions.EventType.GECKO, EVENT_TYPE);
+ // The JS here is unrelated to a test harness, so we
+ // have our message parser end on assertion failure.
+ mLogParser = new JavascriptMessageParser(sAsserter, true);
+ }
+
public JavascriptBridge(final Object target) {
mTarget = target;
mMethods = target.getClass().getMethods();
mExpecter = sActions.expectGlobalEvent(Actions.EventType.GECKO, EVENT_TYPE);
// The JS here is unrelated to a test harness, so we
// have our message parser end on assertion failure.
mLogParser = new JavascriptMessageParser(sAsserter, true);
}
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAudioFocus.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAudioFocus.java
@@ -18,16 +18,19 @@ public class testAudioFocus extends Medi
info("- run test : testBasicAbility -");
testBasicAbility();
info("- run test : testAudioFocusChanged -");
testAudioFocusChanged();
info("- run test : testSwitchTab -");
testSwitchTab();
+
+ info("- run test : testAdjustMediaVolumeOrMuted -");
+ testAdjustMediaVolumeOrMuted();
}
private void testBasicAbility() {
info("- check audio focus in the beginning -");
mAsserter.is(getAudioFocusAgent().getAudioFocusState(),
State.LOST_FOCUS,
"Should not own audio focus.");
@@ -135,9 +138,63 @@ public class testAudioFocus extends Medi
addTab(BLANK_URL);
info("- should still own the audio focus -");
checkAudioFocusStateAfterChanged(true);
info("- close tab -");
closeAllTabs();
}
+
+ /**
+ * Audio focus should only be requested when media is audible.
+ */
+ private void testAdjustMediaVolumeOrMuted() {
+ info("- create JSBridge -");
+ createJSBridge();
+
+ info("- load URL -");
+ final String MEDIA_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_MEDIA_PLAYBACK_JS_URL);
+ loadUrlAndWait(MEDIA_URL);
+
+ info("- play media -");
+ getJS().syncCall("play_audio");
+
+ info("- wait until media starts playing -");
+ final Tab tab = Tabs.getInstance().getSelectedTab();
+ waitUntilTabMediaStarted(tab);
+
+ info("- wait tab becomes audible -");
+ checkTabAudioPlayingState(tab, true /* audible */);
+ checkAudioFocusStateAfterChanged(true);
+
+ info("- change media's volume to 0.0 -");
+ getJS().syncCall("adjust_audio_volume", 0.0);
+ checkTabAudioPlayingState(tab, false /* non-audible */);
+ checkAudioFocusStateAfterChanged(false);
+
+ info("- change media's volume to 1.0 -");
+ getJS().syncCall("adjust_audio_volume", 1.0);
+ checkTabAudioPlayingState(tab, true /* audible */);
+ checkAudioFocusStateAfterChanged(true);
+
+ info("- mute media -");
+ getJS().syncCall("adjust_audio_muted", true);
+ checkTabAudioPlayingState(tab, false /* non-audible */);
+ checkAudioFocusStateAfterChanged(false);
+
+ info("- unmute media -");
+ getJS().syncCall("adjust_audio_muted", false);
+ checkTabAudioPlayingState(tab, true /* audible */);
+ checkAudioFocusStateAfterChanged(true);
+
+ info("- pause media -");
+ getJS().syncCall("pause_audio");
+ checkTabAudioPlayingState(tab, false /* non-audible */);
+ checkAudioFocusStateAfterChanged(false);
+
+ info("- close tab -");
+ closeAllTabs();
+
+ info("- destroy JSBridge -");
+ destroyJSBridge();
+ }
}
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMediaControl.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMediaControl.java
@@ -27,16 +27,22 @@ public class testMediaControl extends Me
info("- run test : testAudioFocusChanged -");
testAudioFocusChanged();
info("- run test : testSwitchTab -");
testSwitchTab();
info("- run test : testCloseTab -");
testCloseTab();
+
+ info("- run test : testResumeMediaFromPage -");
+ testResumeMediaFromPage();
+
+ info("- run test : testAdjustMediaVolumeOrMuted -");
+ testAdjustMediaVolumeOrMuted();
}
private void testBasicBehaviors() {
info("- load URL -");
final String MEDIA_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_MEDIA_PLAYBACK_LOOP_URL);
loadUrlAndWait(MEDIA_URL);
info("- wait until media starts playing -");
@@ -154,9 +160,94 @@ public class testMediaControl extends Me
info("- media control should disappear -");
waitUntilNotificationUIChanged();
checkIfMediaNotificationBeCleared();
info("- close tab -");
closeAllTabs();
}
+
+ /**
+ * Media control and audio focus should be changed as well when user resume
+ * media from page, instead of from media control.
+ */
+ private void testResumeMediaFromPage() {
+ info("- create JSBridge -");
+ createJSBridge();
+
+ info("- load URL -");
+ final String MEDIA_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_MEDIA_PLAYBACK_JS_URL);
+ loadUrlAndWait(MEDIA_URL);
+
+ info("- play media -");
+ getJS().syncCall("play_audio");
+
+ info("- wait until media starts playing -");
+ final Tab tab = Tabs.getInstance().getSelectedTab();
+ waitUntilTabMediaStarted(tab);
+ checkIfMediaPlayingSuccess(true /* playing */);
+
+ info("- simulate media control pause -");
+ notifyMediaControlService(MediaControlService.ACTION_PAUSE);
+ checkIfMediaPlayingSuccess(false /* paused */);
+
+ info("- resume media from page -");
+ getJS().syncCall("play_audio");
+ checkIfMediaPlayingSuccess(true /* playing */);
+
+ info("- pause media from page -");
+ getJS().syncCall("pause_audio");
+ checkIfMediaPlayingSuccess(false /* paused */, true /* clear notification */);
+
+ info("- close tab -");
+ closeAllTabs();
+
+ info("- destroy JSBridge -");
+ destroyJSBridge();
+ }
+
+ /**
+ * Media control should always be displayed even the media becomes non-audible.
+ */
+ private void testAdjustMediaVolumeOrMuted() {
+ info("- create JSBridge -");
+ createJSBridge();
+
+ info("- load URL -");
+ final String MEDIA_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_MEDIA_PLAYBACK_JS_URL);
+ loadUrlAndWait(MEDIA_URL);
+
+ info("- play media -");
+ getJS().syncCall("play_audio");
+
+ info("- wait until media starts playing -");
+ final Tab tab = Tabs.getInstance().getSelectedTab();
+ waitUntilTabMediaStarted(tab);
+ checkIfMediaPlayingSuccess(true /* playing */);
+
+ info("- change media's volume to 0.0 -");
+ getJS().syncCall("adjust_audio_volume", 0.0);
+ checkMediaNotificationStates(tab, true);
+
+ info("- change media's volume to 1.0 -");
+ getJS().syncCall("adjust_audio_volume", 1.0);
+ checkMediaNotificationStates(tab, true);
+
+ info("- mute media -");
+ getJS().syncCall("adjust_audio_muted", true);
+ checkMediaNotificationStates(tab, true);
+
+ info("- unmute media -");
+ getJS().syncCall("adjust_audio_muted", false);
+ checkMediaNotificationStates(tab, true);
+
+ info("- pause media -");
+ getJS().syncCall("pause_audio");
+ checkIfMediaPlayingSuccess(false /* paused */, true /* clear notification */);
+
+ info("- close tab -");
+ closeAllTabs();
+
+ info("- destroy JSBridge -");
+ destroyJSBridge();
+ }
}