mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e now works on openvidu-testapp
parent
f2d521bd69
commit
835050db6c
|
@ -1,12 +0,0 @@
|
|||
[](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
[](http://openvidu.io/docs/home/)
|
||||
[](https://groups.google.com/forum/#!forum/openvidu)
|
||||
|
||||
[![][OpenViduLogo]](http://openvidu.io)
|
||||
|
||||
openvidu-test-e2e
|
||||
===
|
||||
|
||||
end2end tests for OpenVidu. Implemented with [Cucumber](https://cucumber.io/) framework, ready to work with [openvidu-insecure-js](https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-insecure-js), [openvidu-insecure-angular](https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-insecure-angular), [openvidu-js-java](https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-js-java), [openvidu-js-node](https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-js-node), [openvidu-mvc-java](https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-mvc-java), [openvidu-mvc-node](https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-mvc-node).
|
||||
|
||||
[OpenViduLogo]: https://secure.gravatar.com/avatar/5daba1d43042f2e4e85849733c8e5702?s=120
|
|
@ -1,7 +1,7 @@
|
|||
<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>
|
||||
|
||||
|
||||
<parent>
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-parent</artifactId>
|
||||
|
@ -9,47 +9,142 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>openvidu-test-e2e</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>OpenVidu Test e2e</name>
|
||||
<description>e2e tests for OpenVidu Tutorials</description>
|
||||
<url>http://maven.apache.org</url>
|
||||
<description>End2End tests for OpenVidu TestApp</description>
|
||||
<url>http://openvidu.io</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<organization>
|
||||
<name>OpenVidu</name>
|
||||
<url>http://openvidu.io</url>
|
||||
</organization>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/OpenVidu/openvidu.git</url>
|
||||
<connection>scm:git:https://github.com/OpenVidu/openvidu.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/OpenVidu/openvidu.git</developerConnection>
|
||||
<tag>develop</tag>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>openvidu.io</id>
|
||||
<name>-openvidu.io Community</name>
|
||||
<organization>openvidu.io</organization>
|
||||
<organizationUrl>http://openvidu.io</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<start-class>example.openvidu.testapp.cucumbertest.TestRunner</start-class>
|
||||
<!-- Java 8 -->
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
|
||||
<!-- Encoding -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<!-- Test dependencies version -->
|
||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<selenium-jupiter.version>1.1.2</selenium-jupiter.version>
|
||||
<slf4j.version>1.7.25</slf4j.version>
|
||||
|
||||
<!-- Plugins versions -->
|
||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||
<jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.bonigarcia</groupId>
|
||||
<artifactId>selenium-jupiter</artifactId>
|
||||
<version>${selenium-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
</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>
|
||||
<artifactId>selenium-chrome-driver</artifactId>
|
||||
<version>3.4.0</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>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-firefox-driver</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-api</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-remote-driver</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>21.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xml-apis</groupId>
|
||||
<artifactId>xml-apis</artifactId>
|
||||
<version>1.4.01</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
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 "main-video"
|
||||
And "1" video element/s in "main-video" should be playing media
|
||||
And users should see other users nicknames
|
||||
And all video elements should be shown in element with id "video-container"
|
||||
And all video elements in "video-container" should be playing media
|
||||
And <firefoxUsers> leave session
|
||||
And <firefoxUsers> see "Join a video session" text in "h1" element
|
||||
And <chromeUsers> div "video-container" 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 | 10 |
|
|
@ -0,0 +1,156 @@
|
|||
package io.openvidu.test.e2e;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.openqa.selenium.JavascriptExecutor;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
public class OpenViduEventManager {
|
||||
|
||||
private static class RunnableCallback implements Runnable {
|
||||
|
||||
private final Consumer<JSONObject> callback;
|
||||
private JSONObject eventResult;
|
||||
|
||||
public RunnableCallback(Consumer<JSONObject> callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setEventResult(JSONObject json) {
|
||||
this.eventResult = json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
callback.accept(this.eventResult);
|
||||
}
|
||||
}
|
||||
|
||||
private Thread pollingThread;
|
||||
private ExecutorService execService = Executors.newCachedThreadPool();
|
||||
private final int LATCH_TIMEOUT = 10000;
|
||||
private WebDriver driver;
|
||||
private WebDriverWait waiter;
|
||||
private Queue<JSONObject> eventQueue;
|
||||
private Map<String, RunnableCallback> eventCallbacks;
|
||||
private Map<String, AtomicInteger> eventNumbers;
|
||||
private Map<String, CountDownLatch> eventCountdowns;
|
||||
private AtomicBoolean isInterrupted = new AtomicBoolean(false);
|
||||
|
||||
public OpenViduEventManager(WebDriver driver, WebDriverWait waiter) {
|
||||
this.driver = driver;
|
||||
this.waiter = waiter;
|
||||
this.eventQueue = new ConcurrentLinkedQueue<JSONObject>();
|
||||
this.eventCallbacks = new ConcurrentHashMap<>();
|
||||
this.eventNumbers = new ConcurrentHashMap<>();
|
||||
this.eventCountdowns = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public void startPolling() {
|
||||
|
||||
this.pollingThread = new Thread(() -> {
|
||||
while (!this.isInterrupted.get()) {
|
||||
this.getEventsFromBrowser();
|
||||
this.emitEvents();
|
||||
}
|
||||
});
|
||||
this.pollingThread.start();
|
||||
}
|
||||
|
||||
public void stopPolling() {
|
||||
this.eventCallbacks.clear();
|
||||
this.eventCountdowns.clear();
|
||||
this.eventNumbers.clear();
|
||||
this.isInterrupted.set(true);
|
||||
this.pollingThread.interrupt();
|
||||
}
|
||||
|
||||
public void on(String eventName, Consumer<JSONObject> callback) {
|
||||
this.eventCallbacks.put(eventName, new RunnableCallback(callback));
|
||||
}
|
||||
|
||||
public void waitUntilNumberOfEvent(String eventName, int eventNumber) {
|
||||
CountDownLatch eventSignal = new CountDownLatch(eventNumber);
|
||||
this.setCountDown(eventName, eventSignal);
|
||||
try {
|
||||
if (!eventSignal.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
throw(new TimeoutException());
|
||||
}
|
||||
} catch (InterruptedException | TimeoutException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private AtomicInteger getNumEvents(String eventName) {
|
||||
return this.eventNumbers.computeIfAbsent(eventName, k -> new AtomicInteger(0));
|
||||
}
|
||||
|
||||
private void setCountDown(String eventName, CountDownLatch cd) {
|
||||
this.eventCountdowns.put(eventName, cd);
|
||||
for(int i=0; i< getNumEvents(eventName).get(); i++){
|
||||
cd.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
private void emitEvents() {
|
||||
while (!this.eventQueue.isEmpty()) {
|
||||
JSONObject event = this.eventQueue.poll();
|
||||
|
||||
System.out.println(event.get("event") + ": " + event);
|
||||
|
||||
RunnableCallback callback = this.eventCallbacks.get(event.get("event"));
|
||||
if (callback != null) {
|
||||
callback.setEventResult(event);
|
||||
execService.submit(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getEventsFromBrowser() {
|
||||
String rawEvents = this.getAndClearEventsInBrowser();
|
||||
|
||||
if (rawEvents == null || rawEvents.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] events = rawEvents.replaceFirst("^<br>", "").split("<br>");
|
||||
JSONParser parser = new JSONParser();
|
||||
for (String e : events) {
|
||||
try {
|
||||
JSONObject event = (JSONObject) parser.parse(e);
|
||||
String eventName = (String) event.get("event");
|
||||
|
||||
this.eventQueue.add(event);
|
||||
getNumEvents(eventName).incrementAndGet();
|
||||
|
||||
if (this.eventCountdowns.get(eventName) != null) {
|
||||
this.eventCountdowns.get(eventName).countDown();
|
||||
}
|
||||
} catch (ParseException exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getAndClearEventsInBrowser() {
|
||||
String events = (String) ((JavascriptExecutor) driver)
|
||||
.executeScript("var e = window.myEvents; window.myEvents = ''; return e;");
|
||||
return events;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package io.openvidu.test.e2e;
|
||||
/*
|
||||
* (C) Copyright 2017-2019 OpenVideo (http://openvidu.io/)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
import static java.lang.invoke.MethodHandles.lookup;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.openqa.selenium.By;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import io.github.bonigarcia.SeleniumExtension;
|
||||
import io.openvidu.test.e2e.browser.ChromeUser;
|
||||
import io.openvidu.test.e2e.browser.FirefoxUser;
|
||||
|
||||
|
||||
/**
|
||||
* E2E test for openvidu-testapp.
|
||||
*
|
||||
* @author Pablo Fuente (pablo.fuente@urjc.es)
|
||||
* @since 1.1.1
|
||||
*/
|
||||
@Tag("e2e")
|
||||
@DisplayName("E2E tests for OpenVidu TestApp")
|
||||
@ExtendWith(SeleniumExtension.class)
|
||||
@RunWith(JUnitPlatform.class)
|
||||
public class OpenViduTestAppE2eTest {
|
||||
|
||||
final Logger log = getLogger(lookup().lookupClass());
|
||||
|
||||
final String DEFAULT_SESSION_NAME = "TestSession";
|
||||
|
||||
String testAppUrl = "http://localhost:4200/"; // default value (local)
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("One2One [Video + Audio] session")
|
||||
void oneToOneVideoAudioSession() throws InterruptedException {
|
||||
|
||||
FirefoxUser user = new FirefoxUser("TestUser", 10);
|
||||
user.getEventManager().startPolling();
|
||||
|
||||
log.debug("Navigate to openvidu-testapp and click on 1:1 scenario");
|
||||
|
||||
user.getDriver().get(testAppUrl);
|
||||
user.getDriver().findElement(By.id("auto-join-checkbox")).click();
|
||||
user.getDriver().findElement(By.id("one2one-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("videoPlaying", 4);
|
||||
|
||||
user.getDriver().findElement(By.id("remove-user-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("streamDestroyed", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("sessionDisconnected", 1);
|
||||
|
||||
user.getDriver().findElement(By.id("remove-user-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("sessionDisconnected", 2);
|
||||
|
||||
user.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("One2Many [Video + Audio] session")
|
||||
void oneToManyVideoAudioSession() throws InterruptedException {
|
||||
|
||||
ChromeUser user = new ChromeUser("TestUser", 10);
|
||||
user.getEventManager().startPolling();
|
||||
|
||||
log.debug("Navigate to openvidu-testapp and click on 1:N scenario");
|
||||
|
||||
user.getDriver().get(testAppUrl);
|
||||
user.getDriver().findElement(By.id("auto-join-checkbox")).click();
|
||||
user.getDriver().findElement(By.id("one2many-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("videoPlaying", 4);
|
||||
|
||||
user.getDriver().findElements(By.className(("leave-btn"))).get(0).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("streamDestroyed", 3);
|
||||
|
||||
user.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Unique user remote subscription [Video + Audio]")
|
||||
void oneRemoteSubscription() throws InterruptedException {
|
||||
|
||||
ChromeUser user = new ChromeUser("TestUser", 10);
|
||||
user.getEventManager().startPolling();
|
||||
|
||||
log.debug("Navigate to openvidu-testapp and join one user with remote subscription");
|
||||
|
||||
user.getDriver().get(testAppUrl);
|
||||
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||
user.getDriver().findElement(By.className("subscribe-remote-check")).click();
|
||||
user.getDriver().findElement(By.id("join-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("connectionCreated", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("accessAllowed", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("videoElementCreated", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("remoteVideoPlaying", 1);
|
||||
|
||||
user.getDriver().findElement(By.className(("leave-btn"))).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("sessionDisconnected", 1);
|
||||
|
||||
user.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Unique user remote subscription [ScreenShare + Audio]")
|
||||
void oneRemoteSubscriptionScreen() throws InterruptedException {
|
||||
|
||||
ChromeUser user = new ChromeUser("TestUser", 10);
|
||||
user.getEventManager().startPolling();
|
||||
|
||||
log.debug("Navigate to openvidu-testapp and join one user with remote subscription");
|
||||
|
||||
user.getDriver().get(testAppUrl);
|
||||
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||
user.getDriver().findElement(By.className("screen-radio")).click();
|
||||
user.getDriver().findElement(By.className("subscribe-remote-check")).click();
|
||||
user.getDriver().findElement(By.id("join-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("connectionCreated", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("accessAllowed", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("videoElementCreated", 1);
|
||||
user.getEventManager().waitUntilNumberOfEvent("remoteVideoPlaying", 1);
|
||||
|
||||
user.getDriver().findElement(By.className(("leave-btn"))).click();
|
||||
|
||||
user.getEventManager().waitUntilNumberOfEvent("sessionDisconnected", 1);
|
||||
|
||||
user.dispose();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package io.openvidu.test.e2e.browser;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import io.openvidu.test.e2e.OpenViduEventManager;
|
||||
|
||||
public class BrowserUser {
|
||||
|
||||
protected WebDriver driver;
|
||||
protected WebDriverWait waiter;
|
||||
protected String clientData;
|
||||
protected int timeOfWait;
|
||||
protected OpenViduEventManager eventManager;
|
||||
|
||||
public BrowserUser(String clientData, int timeOfWait) {
|
||||
this.clientData = clientData;
|
||||
this.timeOfWait = timeOfWait;
|
||||
}
|
||||
|
||||
public WebDriver getDriver() {
|
||||
return this.driver;
|
||||
}
|
||||
|
||||
public WebDriverWait getWaiter() {
|
||||
return this.waiter;
|
||||
}
|
||||
|
||||
public OpenViduEventManager getEventManager() {
|
||||
return this.eventManager;
|
||||
}
|
||||
|
||||
public String getClientData() {
|
||||
return this.clientData;
|
||||
}
|
||||
|
||||
protected void newWaiter(int timeOfWait) {
|
||||
this.waiter = new WebDriverWait(this.driver, timeOfWait);
|
||||
}
|
||||
|
||||
protected void configureDriver() {
|
||||
this.waiter = new WebDriverWait(this.driver, this.timeOfWait);
|
||||
this.driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
|
||||
this.eventManager = new OpenViduEventManager(this.driver, this.waiter);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.eventManager.stopPolling();
|
||||
this.driver.quit();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package io.openvidu.test.e2e.browser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
public class ChromeUser extends BrowserUser {
|
||||
|
||||
public ChromeUser(String userName, int timeOfWait) {
|
||||
super(userName, timeOfWait);
|
||||
|
||||
System.setProperty("webdriver.chrome.driver", "/home/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
|
||||
options.addArguments("--use-fake-device-for-media-stream");
|
||||
// This flag selects the entire screen as video source when screen sharing
|
||||
options.addArguments("--auto-select-desktop-capture-source=Entire screen");
|
||||
|
||||
try {
|
||||
// Add Screen Sharing extension
|
||||
options.addExtensions(new ClassPathResource("ScreenCapturing.crx").getFile());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.driver = new ChromeDriver(options);
|
||||
this.driver.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS);
|
||||
|
||||
this.configureDriver();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
package io.openvidu.test.e2e.cucumbertest;
|
||||
package io.openvidu.test.e2e.browser;
|
||||
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxProfile;
|
||||
import org.openqa.selenium.remote.CapabilityType;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
|
||||
public class FirefoxUser extends BrowserUser {
|
||||
|
||||
public FirefoxUser(String userName, int timeOfWait) {
|
||||
super(userName, timeOfWait);
|
||||
|
||||
System.setProperty("webdriver.gecko.driver", "/home/geckodriver");
|
||||
|
||||
DesiredCapabilities capabilities = new DesiredCapabilities();
|
||||
capabilities.setCapability("acceptInsecureCerts", true);
|
||||
|
@ -21,9 +22,10 @@ public class FirefoxUser extends BrowserUser {
|
|||
profile.setPreference("media.navigator.streams.fake", true);
|
||||
|
||||
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
|
||||
this.driver = new FirefoxDriver(capabilities);
|
||||
|
||||
this.configWaiterAndScript();
|
||||
this.driver = new FirefoxDriver(capabilities);
|
||||
|
||||
this.configureDriver();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
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 { }
|
|
@ -1,216 +0,0 @@
|
|||
package io.openvidu.test.e2e.stepdefinition;
|
||||
|
||||
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(() -> {
|
||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.cssSelector("#" + strArg2 + " video"), 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 {
|
||||
for (BrowserUser user : this.browserUsers.values()) {
|
||||
new Thread(() -> {
|
||||
List<WebElement> videos = user.getDriver().findElements(By.cssSelector("#" + strArg2 + " video"));
|
||||
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(() -> {
|
||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.cssSelector("#" + strArg1 + " video"), this.browserUsers.size()));
|
||||
}).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 {
|
||||
for (BrowserUser user : this.browserUsers.values()) {
|
||||
new Thread(() -> {
|
||||
List<WebElement> videos = user.getDriver().findElements(By.cssSelector("#" + strArg1 + " video"));
|
||||
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());
|
||||
}).run();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("^users should see other users nicknames$")
|
||||
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()) {
|
||||
user.getWaiter().until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector("#data-" + entry.getKey() + " p"), 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) {
|
||||
user.getWaiter().until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#" + strArg1 + " video#" + "native-video-" + u + "_webcam")));
|
||||
}
|
||||
}
|
||||
}).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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package example.openvidu.testapp;
|
||||
package io.openvidu.test.e2e.tes;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
org.slf4j.simpleLogger.defaultLogLevel=DEBUG
|
||||
org.slf4j.simpleLogger.logFile=System.out
|
||||
org.slf4j.simpleLogger.showDateTime=true
|
||||
org.slf4j.simpleLogger.dateTimeFormat=[yyyy-MM-dd HH:mm:ss:SSS]
|
||||
org.slf4j.simpleLogger.showThreadName=true
|
||||
org.slf4j.simpleLogger.showLogName=true
|
||||
org.slf4j.simpleLogger.showShortLogName=true
|
|
@ -0,0 +1,20 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDUTCCAjmgAwIBAgIJAOQFplq7ejUaMA0GCSqGSIb3DQEBCwUAMD8xFjAUBgNV
|
||||
BAMMDXd3dy5teWRvbS5jb20xGDAWBgNVBAoMD015IENvbXBhbnkgTFRELjELMAkG
|
||||
A1UEBhMCVVMwHhcNMTcxMDAzMTIxMTU5WhcNMjcxMDAxMTIxMTU5WjA/MRYwFAYD
|
||||
VQQDDA13d3cubXlkb20uY29tMRgwFgYDVQQKDA9NeSBDb21wYW55IExURC4xCzAJ
|
||||
BgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6ymIS6N0
|
||||
RDQD/hAFUzPZkY4dKOfiRLATTa1EZsssTdPE8FiAYVua+jW5Zm3LFFQ5BMIeJjCZ
|
||||
jbJFSMSEjC9aNPsqTGc6zeHaBfrJnTxY7nBOv9dAHrhDHs8nuwGwTY3kYUu+r5kd
|
||||
VEZHht5RRw0wE1PUrXhBKWnziuXnpbx5XWOgk9afn6pf4IfzSlDM7Mgk8ZtEmajy
|
||||
2TB1okTd7h+pHhGOwKGSGrjY0cCLZwq3B06R4/wuLejJYTm3/QB5dPJnEzZxsXE+
|
||||
QXmAP3a4uEsUzyYBK0gW10Xj/EM33VLqepXYAe0T6F8PCqSjeumxhCla520L5Fvl
|
||||
oBLJ4r2h7XspLwIDAQABo1AwTjAdBgNVHQ4EFgQU3OjBfIpR6o3ALB9JCfq11RYy
|
||||
AZwwHwYDVR0jBBgwFoAU3OjBfIpR6o3ALB9JCfq11RYyAZwwDAYDVR0TBAUwAwEB
|
||||
/zANBgkqhkiG9w0BAQsFAAOCAQEAV43AXlj01X3FM6XbdENObBZuHM18ioF/Kw1R
|
||||
LFXM/ANrNrYRYSHSXuw9N3/WHS68vb5FLnOAkY/oWNBtdPcLOrgcn+Prp2HMAJOj
|
||||
4eSWEzbT3JGIoPMbxGEGFUalrHU43MzeQbrjCML83BjuLZDe1Nx5r4DJqRcETHyr
|
||||
SV3spwS2gvhw51cOIVKrYfeB+WYuDd1BPeWgWcQaQgMK9HyMX2XiydwpZAUSHCpq
|
||||
UrvDU/QHQ5s0hqCmmj2iSTLiP4rwFCsTWTSrYdugntgWlN1RlZInoP4D/NUH2xiY
|
||||
LhIzviKmNeIqlkLGd1GyC2FQy49SW2SlmAqqq33etjt8b288Yg==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDrKYhLo3RENAP+
|
||||
EAVTM9mRjh0o5+JEsBNNrURmyyxN08TwWIBhW5r6NblmbcsUVDkEwh4mMJmNskVI
|
||||
xISML1o0+ypMZzrN4doF+smdPFjucE6/10AeuEMezye7AbBNjeRhS76vmR1URkeG
|
||||
3lFHDTATU9SteEEpafOK5eelvHldY6CT1p+fql/gh/NKUMzsyCTxm0SZqPLZMHWi
|
||||
RN3uH6keEY7AoZIauNjRwItnCrcHTpHj/C4t6MlhObf9AHl08mcTNnGxcT5BeYA/
|
||||
dri4SxTPJgErSBbXReP8QzfdUup6ldgB7RPoXw8KpKN66bGEKVrnbQvkW+WgEsni
|
||||
vaHteykvAgMBAAECggEBAJvGrl+Ujk8jucVRrYVZInWWE2Dmgm+Hx7G75kTFr7p6
|
||||
Xsnrhld3zCiU8BSXBGCaDg9F25zmssE3Z0f1zevi7jmMa4+jDkQVqUwuveFneW2x
|
||||
faj9GJ+A5g2Bokrxqm0lYjTFbTJ7Ff+ecoE3wdV0OfWDoa2rrFaXtdm7xAB44lhm
|
||||
goYQKwabyRNHxq20lF0zHfnkSfiTJACtmU/uaQw9PL1XhIDhLLSECPWbUdtyGice
|
||||
swV7P56SSsH1Z7Xrpvwbo8YSNl1MkopNTgX1xqNTAA4TBG3MGvsAGbtQ/0euL782
|
||||
MEjgVzsEj+KDdLklTTwir8o9+Od7G7XPqoJeM1+Iw1ECgYEA9eHlZuCmbvAj7GB4
|
||||
n6Wh8UgB1TLfSbOUr7Ip5wQvEoE4J9TyjTMuhJZvYuKBoQzeKOKFWAoQcw1hazza
|
||||
/Kk3XftMW81os3nd0Ayt5bJsaHpC71kDPA/y39ih9tyZQxY19QNLOVL3p3UIh3ol
|
||||
cMJX3knPEztcZgkH5TjyfW9cYVkCgYEA9Na2AUUX3NMRCnXkpHRgD4hN3imyGXKW
|
||||
nQ7M0c6YK8sw6YcUUthPcLWv1FjyOqTCO+rWHgGJp1G9IQqLfGJrw80c6GxK0tuQ
|
||||
Y1NRjpVfL9k/TiEqahhVseY0OTiMRmwC6Hp03z1xGwNrQKkA7eddMIRqU2p5QWV6
|
||||
MEE586mSxccCgYEAsFPdBRfZgvknad4M4sAPEE7JMbEXu2zTFeQ4dHjloOmV8cqe
|
||||
Xm/zzhVrr4gr2ei2cK9xXJ9rCHbyA8tSZ5qaIAWUzsjRatPcI9TT6EM5xvrWgXpd
|
||||
/Xaaf7iE/dlY92k4LIq+KU+8VhRxl2Ya73APP1PC8lHBg1K6nMFn9Fgl8ZECgYAK
|
||||
+8bWb78OTPmqunczWXUlvTuhB8XRlm5jRVKy5s20yTy8fS7QOJv3tm7Y29SiBNoh
|
||||
zfslBXSjaOtPHCX9wnyLIBx34MPKiccEbaxu9Qx8HQbV/m7kq4rMnEMjfgHs9tN6
|
||||
kmPD0AHO8GxTTkGYapSnpIkQjOo7oM3GdGahI65N6QKBgQC5yz4v7TG0T1AdXkVN
|
||||
A1tol8iAq5+9PJrEsoUXATorsMZhE7kyZ4CfS0YHThKWEAUZJnXD4CxXrpWAdzyU
|
||||
tc2b+AJ5XWfjzuWGZ74LAQB1QnRZlDeGvf9CfU2yDaZKZCahBQENTf44UjfWV3Zd
|
||||
Krj3S50vAzOyTVOOMbWz/+E48w==
|
||||
-----END PRIVATE KEY-----
|
|
@ -13,6 +13,7 @@ import { OpenviduInstanceComponent } from './components/openvidu-instance/openvi
|
|||
import { ExtensionDialogComponent } from './components/openvidu-instance/extension-dialog.component';
|
||||
import { OpenviduRestService } from './services/openvidu-rest.service';
|
||||
import { OpenviduParamsService } from './services/openvidu-params.service';
|
||||
import { TestFeedService } from './services/test-feed.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -32,7 +33,8 @@ import { OpenviduParamsService } from './services/openvidu-params.service';
|
|||
],
|
||||
providers: [
|
||||
OpenviduRestService,
|
||||
OpenviduParamsService
|
||||
OpenviduParamsService,
|
||||
TestFeedService
|
||||
],
|
||||
entryComponents: [ ExtensionDialogComponent ],
|
||||
bootstrap: [AppComponent]
|
||||
|
|
|
@ -89,7 +89,7 @@ md-radio-button {
|
|||
color: #4d4d4d;
|
||||
}
|
||||
|
||||
.event-list {
|
||||
.event-list-div {
|
||||
display: inline-block;
|
||||
width: 125px;
|
||||
height: 183.5px;
|
||||
|
@ -108,9 +108,9 @@ md-chip {
|
|||
}
|
||||
|
||||
.scroll-custom::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
background-color: #F5F5F5;
|
||||
/*-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);*/
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.scroll-custom::-webkit-scrollbar {
|
||||
|
|
|
@ -44,10 +44,10 @@
|
|||
<div fxFlex="40">
|
||||
<md-radio-group [(ngModel)]="optionsVideo" [disabled]="session || disableRadioButtons" [ngModelOptions]="{standalone: true}">
|
||||
<div>
|
||||
<md-radio-button value="video" [checked]="checkRadioVideo && optionsVideo==='video'">Video</md-radio-button>
|
||||
<md-radio-button class="video-radio" value="video" [checked]="checkRadioVideo && optionsVideo==='video'">Video</md-radio-button>
|
||||
</div>
|
||||
<div>
|
||||
<md-radio-button value="screen" [checked]="checkRadioScreen && optionsVideo==='screen'">Screen</md-radio-button>
|
||||
<md-radio-button class="screen-radio" value="screen" [checked]="checkRadioScreen && optionsVideo==='screen'">Screen</md-radio-button>
|
||||
</div>
|
||||
</md-radio-group>
|
||||
<md-checkbox class="subscribe-remote-check" name="subscribeToRemote" (change)="subscribeToRemote = !subscribeToRemote" [disabled]="(!sendAudio && !sendVideo) || !publishTo || session"
|
||||
|
@ -68,27 +68,24 @@
|
|||
<div class="session-card-inner">
|
||||
<div class="session-title">{{sessionName}}</div>
|
||||
<div class="session-actions">
|
||||
<button *ngIf="publishTo && sendVideo" (click)="toggleVideo()"><md-icon aria-label="Mute video button">{{videoIcon}}</md-icon></button>
|
||||
<button *ngIf="publishTo && sendAudio" (click)="toggleAudio()"><md-icon aria-label="Mute audio button">{{audioIcon}}</md-icon></button>
|
||||
<button (click)="leaveSession()"><md-icon aria-label="Leave button">clear</md-icon></button>
|
||||
<button class="video-btn" *ngIf="publishTo && sendVideo" (click)="toggleVideo()"><md-icon aria-label="Mute video button">{{videoIcon}}</md-icon></button>
|
||||
<button class="audio-btn" *ngIf="publishTo && sendAudio" (click)="toggleAudio()"><md-icon aria-label="Mute audio button">{{audioIcon}}</md-icon></button>
|
||||
<button class="leave-btn" (click)="leaveSession()"><md-icon aria-label="Leave button">clear</md-icon></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="session.connection" fxLayout>
|
||||
<div fxFlex="135px" class="video-container">
|
||||
|
||||
<div class="event-list scroll-custom">
|
||||
<md-accordion>
|
||||
<md-expansion-panel *ngFor="let event of events">
|
||||
<md-expansion-panel-header [collapsedHeight]="'20px'" [expandedHeight]="'20px'">
|
||||
<div class="event-list-div scroll-custom">
|
||||
<md-accordion [attr.id]="'events-' + session.connection.connectionId" class="event-list">
|
||||
<md-expansion-panel *ngFor="let event of events" class="event-item">
|
||||
<md-expansion-panel-header [attr.id]="event.name + '-' + session.connection.connectionId" [collapsedHeight]="'20px'" [expandedHeight]="'20px'" class="event-name">
|
||||
{{event.name}}
|
||||
</md-expansion-panel-header>
|
||||
{{event.content}}
|
||||
<div class="event-content">{{event.content}}</div>
|
||||
</md-expansion-panel>
|
||||
</md-accordion>
|
||||
<!--<md-chip-list class="mat-chip-list-stacked" aria-orientation="vertical">
|
||||
<md-chip *ngFor="let event of events">{{event}}</md-chip>
|
||||
</md-chip-list>-->
|
||||
</div>
|
||||
</div>
|
||||
<div [attr.id]="'remote-vid-' + session.connection.connectionId" fxFlex="270px" class="video-container">
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
import { OpenVidu, Session, Subscriber, Publisher, Stream } from 'openvidu-browser';
|
||||
import { MdDialog, MdDialogRef } from '@angular/material';
|
||||
import { ExtensionDialogComponent } from './extension-dialog.component';
|
||||
import { TestFeedService } from '../../services/test-feed.service';
|
||||
|
||||
declare var $: any;
|
||||
|
||||
|
@ -83,7 +84,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
openviduError: any;
|
||||
|
||||
constructor(private changeDetector: ChangeDetectorRef, public extensionDialog: MdDialog) {
|
||||
constructor(private changeDetector: ChangeDetectorRef, public extensionDialog: MdDialog, public testFeedService: TestFeedService) {
|
||||
this.generateSessionInfo();
|
||||
}
|
||||
|
||||
|
@ -296,6 +297,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
private updateEventList(event: string, content: string) {
|
||||
this.events.push({ name: event, content: content });
|
||||
this.testFeedService.pushNewEvent(this.sessionName, this.session.connection.connectionId, event, content);
|
||||
}
|
||||
|
||||
toggleSubscribeTo(): void {
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<div class="top-div">
|
||||
<div class="controls-div">
|
||||
<button id="add-user-btn" md-raised-button color="primary" (click)="addUser()">ADD USER</button>
|
||||
<button id="remove-user-btn" md-raised-button color="primary" (click)="users.pop()" [disabled]="!users.length">REMOVE USER</button>
|
||||
<button id="remove-user-btn" md-raised-button color="primary" (click)="users = []" [disabled]="!users.length">REMOVE ALL</button>
|
||||
<button id="remove-user-btn" md-raised-button color="primary" (click)="removeUser()" [disabled]="!users.length">REMOVE USER</button>
|
||||
<button id="remove-all-users-btn" md-raised-button color="primary" (click)="removeAllUsers()" [disabled]="!users.length">REMOVE ALL</button>
|
||||
</div>
|
||||
<div class="scenario-div">
|
||||
<md-checkbox class="auto-join-check" [(ngModel)]="autoJoin" name="autoJoin">Auto join</md-checkbox>
|
||||
<button id="remove-user-btn" md-raised-button color="primary" (click)="loadScenario(2,0,0)">1:1</button>
|
||||
<button id="remove-user-btn" md-raised-button color="primary" (click)="loadScenario(0,1,numberSubs)">1:{{numberSubs}}</button>
|
||||
<md-checkbox id="auto-join-checkbox" class="auto-join-check" [(ngModel)]="autoJoin" name="autoJoin">Auto join</md-checkbox>
|
||||
<button id="one2one-btn" md-raised-button color="primary" (click)="loadScenario(2,0,0)">1:1</button>
|
||||
<button id="one2many-btn" md-raised-button color="primary" (click)="loadScenario(0,1,numberSubs)">1:{{numberSubs}}</button>
|
||||
<md-form-field>
|
||||
<input mdInput [(ngModel)]="numberSubs">
|
||||
</md-form-field>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { OpenviduParamsService } from '../../services/openvidu-params.service';
|
||||
import { TestFeedService } from '../../services/test-feed.service';
|
||||
import { SessionConf } from '../openvidu-instance/openvidu-instance.component';
|
||||
|
||||
@Component({
|
||||
|
@ -14,6 +15,7 @@ export class TestSessionsComponent implements OnInit, OnDestroy {
|
|||
openviduSecret: string;
|
||||
|
||||
paramsSubscription: Subscription;
|
||||
eventsInfoSubscription: Subscription;
|
||||
|
||||
// OpenViduInstance collection
|
||||
users: SessionConf[] = [];
|
||||
|
@ -21,7 +23,7 @@ export class TestSessionsComponent implements OnInit, OnDestroy {
|
|||
numberSubs = 3;
|
||||
autoJoin = false;
|
||||
|
||||
constructor(private openviduParamsService: OpenviduParamsService) { }
|
||||
constructor(private openviduParamsService: OpenviduParamsService, private testFeedService: TestFeedService) { }
|
||||
|
||||
ngOnInit() {
|
||||
const openviduParams = this.openviduParamsService.getParams();
|
||||
|
@ -33,6 +35,11 @@ export class TestSessionsComponent implements OnInit, OnDestroy {
|
|||
this.openviduUrl = params.openviduUrl;
|
||||
this.openviduSecret = params.openviduSecret;
|
||||
});
|
||||
|
||||
this.eventsInfoSubscription = this.testFeedService.newLastEvent$.subscribe(
|
||||
newEvent => {
|
||||
(window as any).myEvents += ('<br>' + JSON.stringify(newEvent));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
@ -49,6 +56,14 @@ export class TestSessionsComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
private removeUser(): void {
|
||||
this.users.pop();
|
||||
}
|
||||
|
||||
private removeAllUsers(): void {
|
||||
this.users = [];
|
||||
}
|
||||
|
||||
private loadSubsPubs(n: number): void {
|
||||
for (let i = 0; i < n; i++) {
|
||||
this.users.push({
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { TestFeedService } from './test-feed.service';
|
||||
|
||||
describe('TestFeedService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [TestFeedService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([TestFeedService], (service: TestFeedService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs/Subject';
|
||||
|
||||
@Injectable()
|
||||
export class TestFeedService {
|
||||
|
||||
lastEvent;
|
||||
newLastEvent$ = new Subject<any>();
|
||||
|
||||
constructor() { }
|
||||
|
||||
getLastEvent() {
|
||||
return this.lastEvent;
|
||||
}
|
||||
|
||||
pushNewEvent(session: string, connection: string, event: string, eventContent: string) {
|
||||
this.lastEvent = ({ session: session, connection: connection, event: event, eventContent: eventContent });
|
||||
this.newLastEvent$.next(this.lastEvent);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,6 +14,10 @@
|
|||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
window.myEvents = '';
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
Loading…
Reference in New Issue