org.jitsi.meet.test.SharedVideoTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jitsi.meet.test.SharedVideoTest.java

Source

/*
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jitsi.meet.test;

import junit.framework.*;
import org.jitsi.meet.test.util.*;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;

/**
 * Tests shared video functionality.
 * @author Damian Minkov
 */
public class SharedVideoTest extends TestCase {
    /**
     * Links to youtube videos and their titles, used for loading and testing.
     */
    private static String V1_LINK = "https://www.youtube.com/watch?v=xNXN7CZk8X0";
    private static String V1_TITLE = "[FOSDEM 2014] Jitsi Videobridge and WebRTC";
    private static String V2_LINK = "https://youtu.be/x-YGw3bgB_s";
    private static String V2_TITLE = "Jitsi Videobridge and WebRTC";

    /**
     * Assign to variable c the shared video container.
     * Used to obtain the player.
     */
    private static String JS_GET_SHARED_VIDEO_CONTAINER = "var c = APP.UI.getLargeVideo().containers['sharedvideo']; ";

    private static String currentVideoTitle;

    /**
     * Constructs test.
     * @param name method name.
     */
    public SharedVideoTest(String name) {
        super(name);
    }

    /**
     * Orders tests.
     * @return the suite with order tests.
     */
    public static junit.framework.Test suite() {
        TestSuite suite = new TestSuite();

        suite.addTest(new SharedVideoTest("startSharingVideo"));
        suite.addTest(new SharedVideoTest("checkRunning"));
        suite.addTest(new SharedVideoTest("checkTitles"));
        suite.addTest(new SharedVideoTest("pauseTest"));
        suite.addTest(new SharedVideoTest("playTest"));
        suite.addTest(new SharedVideoTest("seekTest"));
        suite.addTest(new SharedVideoTest("volumeTest"));
        suite.addTest(new SharedVideoTest("muteTest"));
        suite.addTest(new SharedVideoTest("switchVideoTest"));
        suite.addTest(new SharedVideoTest("backToSharedVideoTest"));
        suite.addTest(new SharedVideoTest("stopSharingTest"));
        suite.addTest(new SharedVideoTest("startSharingDifferentVideo"));
        suite.addTest(new SharedVideoTest("checkRunning"));
        suite.addTest(new SharedVideoTest("checkTitles"));
        suite.addTest(new SharedVideoTest("stopSharingTest"));
        suite.addTest(new SharedVideoTest("startSharingDifferentVideo"));
        suite.addTest(new SharedVideoTest("checkRunning"));
        suite.addTest(new SharedVideoTest("checkTitles"));
        suite.addTest(new SharedVideoTest("videoOwnerLeavesTest"));
        suite.addTest(new SharedVideoTest("shareVideoBeforeOthersJoin"));
        suite.addTest(new SharedVideoTest("checkRunning"));
        suite.addTest(new SharedVideoTest("checkTitles"));
        suite.addTest(new SharedVideoTest("sharePausedVideoBeforeOthersJoin"));
        suite.addTest(new SharedVideoTest("checkTitles"));
        suite.addTest(new SharedVideoTest("stopSharingTest"));

        return suite;
    }

    /**
     * Starts a shared video and checks whether it is visible and is playing.
     */
    public void startSharingVideo() {
        System.err.println("Start startSharingVideo.");

        startSharingVideoByUrlAndTitle(V1_LINK, V1_TITLE, true);
    }

    /**
     * Start shared video.
     * @param url
     * @param title
     * @param checkSecondParticipantState whether second participant state
     *                                    needs to be checked
     */
    private void startSharingVideoByUrlAndTitle(String url, String title, boolean checkSecondParticipantState) {
        WebDriver owner = ConferenceFixture.getOwner();
        MeetUIUtils.clickOnToolbarButton(owner, "toolbar_button_sharedvideo");

        TestUtils.waitForElementByXPath(owner, "//input[@name='sharedVideoUrl']", 5);

        //owner.findElement(
        //    By.xpath("//input[@name='sharedVideoUrl']")).sendKeys(url);
        // sendKeys is not working for FF, seems the input has size of 20
        // and only 21 chars goes in, the size is not visible in
        // web-development console
        MeetUIUtils.setAttribute(owner, owner.findElement(By.xpath("//input[@name='sharedVideoUrl']")), "value",
                url);

        currentVideoTitle = title;

        owner.findElement(By.name("jqi_state0_buttonspandatai18ndialogShareSharespan")).click();

        WebDriverWait wait = new WebDriverWait(owner, 30);
        wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("sharedVideoIFrame")));
        // make sure we are in meet, not in the frame
        owner.switchTo().defaultContent();

        assertEquals("Video not displayed:", true, owner.findElement(By.id("sharedVideoIFrame")).isDisplayed());

        if (checkSecondParticipantState) {
            // Now let's check the second participant state
            WebDriver secondParticipant = ConferenceFixture.getSecondParticipant();
            // make sure we are in meet, not in the frame
            secondParticipant.switchTo().defaultContent();

            assertEquals("Video not displayed:", true,
                    secondParticipant.findElement(By.id("sharedVideoIFrame")).isDisplayed());
        }
    }

    /**
     * Waits for player to be defined and checks its state.
     * @param participant
     * @param state
     */
    private void checkPlayerLoadedAndInState(WebDriver participant, String state) {
        TestUtils.waitForBoolean(participant, JS_GET_SHARED_VIDEO_CONTAINER + "return (c && c.player "
                + "&& c.player.getPlayerState() === " + state + ");", 15);
    }

    /**
     * Checks for title on both sides, compare with current video playing title.
     */
    public void checkTitles() {
        System.err.println("Start checkTitles.");

        String ownerVideoTitle = TestUtils.executeScriptAndReturnString(ConferenceFixture.getOwner(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getVideoData().title;");
        assertEquals("Different title found on owner", currentVideoTitle, ownerVideoTitle);

        String secondVideoTitle = TestUtils.executeScriptAndReturnString(ConferenceFixture.getSecondParticipant(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getVideoData().title;");
        assertEquals("Different title found on second participant", currentVideoTitle, secondVideoTitle);
    }

    /**
     * Checks that both players are playing.
     */
    public void checkRunning() {
        System.err.println("Start checkRunning.");

        checkPlayerLoadedAndInState(ConferenceFixture.getOwner(), "YT.PlayerState.PLAYING");
        checkPlayerLoadedAndInState(ConferenceFixture.getSecondParticipant(), "YT.PlayerState.PLAYING");
    }

    /**
     * Pause player and check whether its paused on both sides.
     */
    public void pauseTest() {
        System.err.println("Start pauseTest.");

        ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "c.player.pauseVideo();");

        checkPlayerLoadedAndInState(ConferenceFixture.getOwner(), "YT.PlayerState.PAUSED");
        checkPlayerLoadedAndInState(ConferenceFixture.getSecondParticipant(), "YT.PlayerState.PAUSED");
    }

    /**
     * Play player and check whether its playing on both sides.
     */
    public void playTest() {
        System.err.println("Start playTest.");

        ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "c.player.playVideo();");

        checkPlayerLoadedAndInState(ConferenceFixture.getOwner(), "YT.PlayerState.PLAYING");
        checkPlayerLoadedAndInState(ConferenceFixture.getSecondParticipant(), "YT.PlayerState.PLAYING");
    }

    /**
     * Fast-forward player and check whether its playing on both sides and its
     * positions are no more than 10 secs. away.
     */
    public void seekTest() {
        System.err.println("Start seekTest.");

        ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "c.player.seekTo(86);");

        // let's wait for the fast forward
        TestUtils.waitForBoolean(ConferenceFixture.getOwner(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return (c.player.getPlayerState() === YT.PlayerState.PLAYING"
                        + " && c.player.getCurrentTime() > 86);",
                10);
        TestUtils.waitForBoolean(ConferenceFixture.getSecondParticipant(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return (c.player.getPlayerState() === YT.PlayerState.PLAYING"
                        + " && c.player.getCurrentTime() > 86);",
                10);

        Object ownerTimeObj = ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getCurrentTime();");

        Object secondTimeObj = ((JavascriptExecutor) ConferenceFixture.getSecondParticipant())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getCurrentTime();");

        double ownerTime = 0;
        if (ownerTimeObj instanceof Double)
            ownerTime = (Double) ownerTimeObj;
        else if (ownerTimeObj instanceof Long)
            ownerTime = (Long) ownerTimeObj;

        double secondTime = 0;
        if (secondTimeObj instanceof Double)
            secondTime = (Double) secondTimeObj;
        else if (secondTimeObj instanceof Long)
            secondTime = (Long) secondTimeObj;

        // let's check that time difference is less than 10 seconds
        assertTrue("Players time differ owner:" + ownerTime + " second:" + secondTime,
                (Math.abs(ownerTime - secondTime) < 10));
    }

    /**
     * Changes the current volume and checks for the change on the other side
     */
    public void volumeTest() {
        System.err.println("Start volumeTest.");

        Long ownerVolume = (Long) ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getVolume();");

        long volumeToSet = ownerVolume - 20;

        ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.setVolume(" + volumeToSet + ");");
        // now check for volume on both sides
        TestUtils.waitForBoolean(ConferenceFixture.getOwner(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return (c.player.getPlayerState() === YT.PlayerState.PLAYING"
                        + " && c.player.getVolume() == " + volumeToSet + ");",
                10);
        TestUtils.waitForBoolean(ConferenceFixture.getSecondParticipant(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return (c.player.getPlayerState() === YT.PlayerState.PLAYING"
                        + " && c.player.getVolume() == " + volumeToSet + ");",
                10);
    }

    /**
     * Mutes the current volume and checks for the change on the other side
     */
    public void muteTest() {
        System.err.println("Start muteTest.");

        ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.mute();");
        // now check for volume on both sides
        TestUtils.waitForBoolean(ConferenceFixture.getOwner(), JS_GET_SHARED_VIDEO_CONTAINER
                + "return (c.player.getPlayerState() === YT.PlayerState.PLAYING" + " && c.player.isMuted());", 10);
        TestUtils.waitForBoolean(ConferenceFixture.getSecondParticipant(),
                JS_GET_SHARED_VIDEO_CONTAINER + "return (c.player.getPlayerState() === YT.PlayerState.PLAYING"
                        + " && (c.player.isMuted() || c.player.getVolume() == 0));",
                10);
    }

    /**
     * Switches video to another participant.
     */
    public void switchVideoTest() {
        System.err.println("Start clickOnRemoteVideoAndTest.");

        new SwitchVideoTest("participantClickOnRemoteVideoAndTest").participantClickOnRemoteVideoAndTest();
    }

    /**
     * Clicks back to shared video and checks is video is visible.
     */
    public void backToSharedVideoTest() {
        System.err.println("Start backToSharedVideoTest.");

        ConferenceFixture.getSecondParticipant().findElement(By.id("sharedVideoContainer")).click();
        TestUtils.waitMillis(1000);

        assertEquals("Video not displayed:", true,
                ConferenceFixture.getSecondParticipant().findElement(By.id("sharedVideoIFrame")).isDisplayed());
    }

    /**
     * Tries to stop shared video and cancels, check its still displayed on
     * both sides.
     * Stops shared video and checks on both sides its not played.
     */
    public void stopSharingTest() {
        System.err.println("Start stopSharingTest.");

        WebDriver owner = ConferenceFixture.getOwner();
        MeetUIUtils.clickOnToolbarButton(owner, "toolbar_button_sharedvideo");

        TestUtils.waitForElementByXPath(owner,
                "//button[@name=" + "'jqi_state0_buttonspandatai18ndialogCancelCancelspan']", 5);

        // let's cancel
        owner.findElement(By.name("jqi_state0_buttonspandatai18ndialogCancelCancelspan")).click();

        // video should be visible on both sides
        WebDriver secondParticipant = ConferenceFixture.getSecondParticipant();
        assertEquals("Video not displayed:", true, owner.findElement(By.id("sharedVideoIFrame")).isDisplayed());
        assertEquals("Video not displayed:", true,
                secondParticipant.findElement(By.id("sharedVideoIFrame")).isDisplayed());

        MeetUIUtils.clickOnToolbarButton(owner, "toolbar_button_sharedvideo");

        // now lets stop sharing
        TestUtils.waitForElementByXPath(owner,
                "//button[@name=" + "'jqi_state0_buttonspandatai18ndialogRemoveRemovespan']", 5);
        owner.findElement(By.name("jqi_state0_buttonspandatai18ndialogRemoveRemovespan")).click();

        try {
            TestUtils.waitForNotDisplayedElementByID(owner, "sharedVideoIFrame", 5);
        } catch (StaleElementReferenceException ex) {
            // if the element is detached in a process of checking its display
            // status, means its not visible anymore
        }
        try {
            TestUtils.waitForNotDisplayedElementByID(secondParticipant, "sharedVideoIFrame", 5);
        } catch (StaleElementReferenceException ex) {
            // if the element is detached in a process of checking its display
            // status, means its not visible anymore
        }
    }

    /**
     * Starts sharing another video.
     */
    public void startSharingDifferentVideo() {
        System.err.println("Start startSharingDifferentVideo.");

        startSharingVideoByUrlAndTitle(V2_LINK, V2_TITLE, true);
    }

    /**
     * The owner leaves and we need to check that shared video is removed
     * on second participant.
     */
    public void videoOwnerLeavesTest() {
        System.err.println("Start videoOwnerLeavesTest.");

        ConferenceFixture.close(ConferenceFixture.getOwner());

        TestUtils.waitForNotDisplayedElementByID(ConferenceFixture.getSecondParticipant(), "sharedVideoIFrame", 5);
    }

    /**
     * Start shared video before second participant joins.
     * This tests
     */
    public void shareVideoBeforeOthersJoin() {
        System.err.println("Start shareVideoBeforeOthersJoin.");

        shareVideoBeforeOthersJoin(false);
    }

    /**
     * Shares the video when only owner is in room, and if needed pause.
     * @param pause whether to pause before starting others
     */
    private void shareVideoBeforeOthersJoin(boolean pause) {
        ConferenceFixture.closeAllParticipants();

        TestUtils.waitMillis(1000);

        WebDriver owner = ConferenceFixture.getOwner();

        MeetUtils.waitForParticipantToJoinMUC(owner, 10);
        TestUtils.waitForDisplayedElementByID(owner, "toolbar_button_sharedvideo", 10);

        // just wait a little after button is displayed
        // sometimes the button is reported as
        // Element is not clickable at point (566, -10)
        TestUtils.waitMillis(1000);

        startSharingVideoByUrlAndTitle(V2_LINK, V2_TITLE, false);
        checkPlayerLoadedAndInState(owner, "YT.PlayerState.PLAYING");

        String stateToCheck = "YT.PlayerState.PLAYING";
        if (pause) {
            stateToCheck = "YT.PlayerState.PAUSED";
            ((JavascriptExecutor) ConferenceFixture.getOwner())
                    .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "c.player.seekTo(15);");
            ((JavascriptExecutor) ConferenceFixture.getOwner())
                    .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "c.player.pauseVideo();");
        }

        ConferenceFixture.waitForSecondParticipantToConnect();
        MeetUtils.waitForIceConnected(owner);
        MeetUtils.waitForSendReceiveData(owner);

        // Now let's check the second participant state
        WebDriver secondParticipant = ConferenceFixture.getSecondParticipant();
        // make sure we are in meet, not in the frame
        secondParticipant.switchTo().defaultContent();

        checkPlayerLoadedAndInState(secondParticipant, stateToCheck);

        assertEquals("Video not displayed:", true,
                secondParticipant.findElement(By.id("sharedVideoIFrame")).isDisplayed());
    }

    public void sharePausedVideoBeforeOthersJoin() {
        System.err.println("Start sharePausedVideoBeforeOthersJoin.");

        shareVideoBeforeOthersJoin(true);

        checkPlayerLoadedAndInState(ConferenceFixture.getOwner(), "YT.PlayerState.PAUSED");
        checkPlayerLoadedAndInState(ConferenceFixture.getSecondParticipant(), "YT.PlayerState.PAUSED");

        Object ownerTimeObj = ((JavascriptExecutor) ConferenceFixture.getOwner())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getCurrentTime();");

        Object secondTimeObj = ((JavascriptExecutor) ConferenceFixture.getSecondParticipant())
                .executeScript(JS_GET_SHARED_VIDEO_CONTAINER + "return c.player.getCurrentTime();");

        double ownerTime = 0;
        if (ownerTimeObj instanceof Double)
            ownerTime = (Double) ownerTimeObj;
        else if (ownerTimeObj instanceof Long)
            ownerTime = (Long) ownerTimeObj;

        double secondTime = 0;
        if (secondTimeObj instanceof Double)
            secondTime = (Double) secondTimeObj;
        else if (secondTimeObj instanceof Long)
            secondTime = (Long) secondTimeObj;

        // let's check that time difference is less than 10 seconds
        assertTrue("Players time differ owner:" + ownerTime + " second:" + secondTime,
                (Math.abs(ownerTime - secondTime) < 10));
    }
}