openvidu-test-e2e added

pull/20/head
pabloFuente 2017-06-30 19:13:50 +02:00
parent fd0e868257
commit 24c5f3d161
9 changed files with 469 additions and 2 deletions

View File

@ -58,8 +58,8 @@ session.generateToken(tokenOptions, function (token) {
#### **Session**
| Method | Returns | Parameters | Description |
| -------------- | ------- | --------------------------------------------- | ----------- |
| getSessionId() | String | `callback(sessionId:string):Function` | The callback receives as parameter the unique identifier of the Session. You will need to return this parameter to the client side to pass it during the connection process to the session |
| generateToken() | String | _`TokenOptions:tokenOptions`_<br>`callback(token:string):Function` | The callback receives as parameter the new created token. The value returned is required in the client side just as the sessionId in order to connect to a session |
| getSessionId() | | `callback(sessionId:string):Function` | The callback receives as parameter the unique identifier of the Session. You will need to return this parameter to the client side to pass it during the connection process to the session |
| generateToken() | | _`TokenOptions:tokenOptions`_<br>`callback(token:string):Function` | The callback receives as parameter the new created token. The value returned is required in the client side just as the sessionId in order to connect to a session |
#### **OpenViduRole**
| Enum | Description |

52
openvidu-test-e2e/pom.xml Normal file
View File

@ -0,0 +1,52 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.openvidu</groupId>
<artifactId>testapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>openvidu-test-e2e</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>example.openvidu.testapp.cucumbertest.TestRunner</start-class>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-core -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-core</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,28 @@
Feature: Connecting To Session
IN ORDER TO complete a bidirectional communication
AS a regular user
I WANT TO check the WebRTC connections between two peers
Scenario Outline: Users connect to the same session
Given Chrome users <chromeUsers> and Firefox users <firefoxUsers> go to "http://localhost:5000" page with <secondsOfWait> seconds
And users fill "participantId" input
And users fill "sessionId" input with session name <session>
When users click on "commit" button
Then users should see title <session> in element with id "session-header"
And "1" video element/s should be shown in element with id "publisher"
And "1" video element/s in "publisher" should be playing media
And users should see other users nicknames in paragraph element
And all video elements should be shown in element with id "subscriber"
And all video elements in "subscriber" should be playing media
And <firefoxUsers> leave session
And <firefoxUsers> see "Join a video session" text in "h1" element
And <chromeUsers> div "subscriber" should have <chromeUsers> videos
And close all browsers
Examples:
| chromeUsers | firefoxUsers | session | secondsOfWait |
| ['User1'] | ['User2'] | Session1 | 7 |
| ['User1', 'User3'] | ['User2'] | Session2 | 7 |
| ['User1'] | ['User2', 'User3'] | Session3 | 7 |
| ['User1', 'User3'] | ['User2', 'User4'] | Session4 | 7 |
| ['User1', 'User3', 'User5'] | ['User2', 'User4', 'User6'] | Session4 | 7 |

View File

@ -0,0 +1,53 @@
package io.openvidu.test.e2e.cucumbertest;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
public class BrowserUser {
protected WebDriver driver;
protected WebDriverWait waiter;
protected String userName;
private int timeOfWait;
public BrowserUser(String userName, int timeOfWait) {
this.userName = userName;
this.timeOfWait = timeOfWait;
}
public WebDriver getDriver() {
return this.driver;
}
public WebDriverWait getWaiter() {
return this.waiter;
}
public String getUserName() {
return this.userName;
}
public Object runJavascript(String script, Object... args) {
return ((JavascriptExecutor)this.driver).executeScript(script, args);
}
public void navigateTo(String url){
this.driver.get(url);
String scriptAppend = "var s = document.createElement('script'); " + "s.type = 'text/javascript';"
+ "s.innerHTML = arguments[0];" + "document.body.appendChild(s);";
String scriptContent = "window['MY_FUNC']= function(videoOwner) { "
+ "var elem = document.createElement('div');" + "elem.id = videoOwner + '-video-is-playing';"
+ "document.body.appendChild(elem); "
+ "document.getElementById(videoOwner + '-video-is-playing').innerHTML = (videoOwner + ' VIDEO PLAYING')"
+ "}";
this.runJavascript(scriptAppend, scriptContent);
}
protected void configWaiterAndScript() {
this.waiter = new WebDriverWait(this.driver, this.timeOfWait);
}
}

View File

@ -0,0 +1,28 @@
package io.openvidu.test.e2e.cucumbertest;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class ChromeUser extends BrowserUser {
public ChromeUser(String userName, int timeOfWait) {
super(userName, timeOfWait);
System.setProperty("webdriver.chrome.driver", "/home/pablo/Downloads/chromedriver");
ChromeOptions options = new ChromeOptions();
// This flag avoids to grant the user media
options.addArguments("--use-fake-ui-for-media-stream");
// This flag fakes user media with synthetic video (green with spinner
// and timer)
options.addArguments("--use-fake-device-for-media-stream");
this.driver = new ChromeDriver(options);
this.driver.manage().timeouts().setScriptTimeout(3, TimeUnit.SECONDS);
this.configWaiterAndScript();
}
}

View File

@ -0,0 +1,27 @@
package io.openvidu.test.e2e.cucumbertest;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.remote.DesiredCapabilities;
public class FirefoxUser extends BrowserUser {
public FirefoxUser(String userName, int timeOfWait) {
super(userName, timeOfWait);
DesiredCapabilities capabilities = new DesiredCapabilities();
FirefoxProfile profile = new FirefoxProfile();
// This flag avoids granting the access to the camera
profile.setPreference("media.navigator.permission.disabled", true);
// This flag force to use fake user media (synthetic video of multiple
// color)
profile.setPreference("media.navigator.streams.fake", true);
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
this.driver = new FirefoxDriver(capabilities);
this.configWaiterAndScript();
}
}

View File

@ -0,0 +1,12 @@
package io.openvidu.test.e2e.cucumbertest;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/main/features"
,glue={"io/openvidu/test/e2e/stepdefinition"}
)
public class TestRunner { }

View File

@ -0,0 +1,229 @@
package io.openvidu.test.e2e.stepdefinition;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import io.openvidu.test.e2e.cucumbertest.BrowserUser;
import io.openvidu.test.e2e.cucumbertest.ChromeUser;
import io.openvidu.test.e2e.cucumbertest.FirefoxUser;
public class StepsConnectingToSession {
public final int numDrivers = 2;
public Map<String, BrowserUser> browserUsers = new ConcurrentHashMap<>();
@Given("^Chrome users (.+) and Firefox users (.+) go to \"([^\"]*)\" page with (.+) seconds$")
public void chrome_users_and_firefox_users_go_to_something_page_with_seconds(String chromeusers,
String firefoxusers, String strArg1, String secondsOfWait) throws Throwable {
// List of Chrome users
List<String> chromeNames = fromArrayStringifyToList(chromeusers);
// List of Firefox users
List<String> firefoxNames = fromArrayStringifyToList(firefoxusers);
for (String name : chromeNames) {
browserUsers.put(name, new ChromeUser(name, Integer.parseInt(secondsOfWait)));
}
for (String name : firefoxNames) {
browserUsers.put(name, new FirefoxUser(name, Integer.parseInt(secondsOfWait)));
}
for (BrowserUser user : this.browserUsers.values()) {
user.navigateTo(strArg1);
}
}
@When("^users click on \"([^\"]*)\" button$")
public void users_click_on_something_button(String strArg1) throws Throwable {
for (BrowserUser user : browserUsers.values()) {
user.getDriver().findElement(By.name(strArg1)).click();
}
}
@Then("^users should see title (.+) in element with id \"([^\"]*)\"$")
public void users_should_see_title_in_element_with_id_something(String session, String strArg1) throws Throwable {
for (BrowserUser user : browserUsers.values()) {
Assert.assertTrue(user.getWaiter().until(ExpectedConditions
.textToBePresentInElement(user.getDriver().findElement(By.id(strArg1)), session)));
}
}
@And("^users fill \"([^\"]*)\" input$")
public void users_fill_something_input(String strArg1) throws Throwable {
for (Entry<String, BrowserUser> entry : this.browserUsers.entrySet()) {
WebElement nicknameInput = entry.getValue().getDriver().findElement(By.id(strArg1));
nicknameInput.clear();
nicknameInput.sendKeys(entry.getKey());
}
}
@And("^users fill \"([^\"]*)\" input with session name (.+)$")
public void users_fill_something_input_with_session_name(String session, String strArg1) throws Throwable {
for (BrowserUser user : this.browserUsers.values()) {
WebElement sessionInput = user.getDriver().findElement(By.id(session));
sessionInput.clear();
sessionInput.sendKeys(strArg1);
}
}
@And("^\"([^\"]*)\" video element/s should be shown in element with id \"([^\"]*)\"$")
public void something_video_elements_should_be_shown_in_element_with_id_something(String strArg1, String strArg2)
throws Throwable {
for (BrowserUser user : this.browserUsers.values()) {
new Thread(() -> {
By byXpath = By.xpath("//div[(@id='" + strArg2 + "')]/video");
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(byXpath, Integer.parseInt(strArg1)));
}).run();
}
}
@And("^\"([^\"]*)\" video element/s in \"([^\"]*)\" should be playing media$")
public void something_video_elements_in_something_should_be_playing_media(String strArg1, String strArg2)
throws Throwable {
By byXpath = By.xpath("//div[(@id='" + strArg2 + "')]/video");
for (BrowserUser user : this.browserUsers.values()) {
new Thread(() -> {
List<WebElement> videos = user.getDriver().findElements(byXpath);
int numOfVideosPlaying = 0;
for (int i = 0; i < videos.size(); i++) {
if (this.checkVideoPlaying(user, videos.get(i), strArg2)) {
numOfVideosPlaying++;
}
}
Assert.assertEquals(numOfVideosPlaying, Integer.parseInt(strArg1));
}).run();
}
}
@And("^all video elements should be shown in element with id \"([^\"]*)\"$")
public void all_video_elements_should_be_shown_in_element_with_id_something(String strArg1) throws Throwable {
for (BrowserUser user : this.browserUsers.values()) {
new Thread(() -> {
By byXpath = By.xpath("//div[(@id='" + strArg1 + "')]/video");
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(byXpath, this.browserUsers.size() - 1));
}).run();
}
}
@And("^all video elements in \"([^\"]*)\" should be playing media$")
public void all_video_elements_in_something_should_be_playing_media(String strArg1) throws Throwable {
By byXpath = By.xpath("//div[(@id='" + strArg1 + "')]/video");
for (BrowserUser user : this.browserUsers.values()) {
new Thread(() -> {
List<WebElement> videos = user.getDriver().findElements(byXpath);
int numOfVideosPlaying = 0;
for (int i = 0; i < videos.size(); i++) {
if (this.checkVideoPlaying(user, videos.get(i), strArg1)) {
numOfVideosPlaying++;
}
}
Assert.assertEquals(numOfVideosPlaying, this.browserUsers.size() - 1);
}).run();
}
}
@Then("^users should see other users nicknames in paragraph element$")
public void users_should_see_other_users_nicknames_in_paragraph_element() throws Throwable {
for (BrowserUser user : this.browserUsers.values()) {
new Thread(() -> {
for (Entry<String, BrowserUser> entry : this.browserUsers.entrySet()) {
if (entry.getValue().getUserName() != user.getUserName()) {
By byXpath = By.xpath("//div[(@id='subscriber')]/p[@id='data-" + entry.getKey() + "']");
user.getWaiter().until(ExpectedConditions.textToBePresentInElementLocated(byXpath, entry.getKey()));
}
}
}).run();
}
}
@And("^(.+) leave session$")
public void leave_session(String firefoxusers) throws Throwable {
List<String> firefoxUsers = this.fromArrayStringifyToList(firefoxusers);
for (String user : firefoxUsers) {
new Thread(() -> {
this.browserUsers.get(user).getDriver().findElement(By.id("buttonLeaveSession")).click();
}).run();
}
}
@And("^(.+) see \"([^\"]*)\" text in \"([^\"]*)\" element$")
public void see_something_text_in_something_element(String firefoxusers, String strArg1, String strArg2)
throws Throwable {
List<String> firefoxUsers = this.fromArrayStringifyToList(firefoxusers);
for (String user : firefoxUsers) {
Assert.assertEquals((this.browserUsers.get(user).getDriver().findElement(By.tagName(strArg2)).getText()),
strArg1);
}
}
@And("^(.+) div \"([^\"]*)\" should have (.+) videos$")
public void div_something_should_have_videos(String usersInRoom, String strArg1, String usersInRoom2)
throws Throwable {
for (BrowserUser user : this.browserUsers.values()) {
new Thread(() -> {
List<String> users = this.fromArrayStringifyToList(usersInRoom);
if (users.contains(user.getUserName())) {
for (String u : users) {
if (!u.equals(user.getUserName())) {
By byXpath = By
.xpath("//div[(@id='" + strArg1 + "')]/video[@id='native-video-" + u + "_webcam']");
user.getWaiter().until(ExpectedConditions.presenceOfElementLocated(byXpath));
}
}
}
}).run();
}
}
@And("^close all browsers$")
public void close_all_browsers() throws Throwable {
for (BrowserUser user : this.browserUsers.values()) {
user.getDriver().quit();
}
}
private List<String> fromArrayStringifyToList(String arrayStringify) {
String[] tokens = arrayStringify.substring(2, arrayStringify.length() - 2).split("'(\\s)*,(\\s)*'");
return Arrays.asList(tokens);
}
private boolean checkVideoPlaying(BrowserUser user, WebElement videoElement, String containerId) {
// Video element should be in 'readyState'='HAVE_ENOUGH_DATA'
//user.getWaiter().until(ExpectedConditions.attributeToBe(videoElement, "readyState", "4"));
// Video should have a valid 'src' value
user.getWaiter().until(ExpectedConditions.attributeToBeNotEmpty(videoElement, "src"));
// Video should have a srcObject (type MediaStream) with the
// attribute 'active' to true
Boolean activeSrcObject = (Boolean) user.runJavascript("return document.getElementById('" + containerId
+ "').getElementsByTagName('video')[0].srcObject.active");
Assert.assertTrue(activeSrcObject);
// Video should trigger 'playing' event
user.runJavascript("document.getElementById('" + videoElement.getAttribute("id")
+ "').addEventListener('playing', window.MY_FUNC('" + containerId + "'))");
user.getWaiter()
.until(ExpectedConditions.textToBePresentInElement(
user.getDriver().findElement(By.id(containerId + "-video-is-playing")),
containerId + " VIDEO PLAYING"));
user.runJavascript(
"document.body.removeChild(document.getElementById('" + containerId + "-video-is-playing'))");
return true;
}
}

View File

@ -0,0 +1,38 @@
package example.openvidu.testapp;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}