From 2b92842263d4bd1f83a12c167c7fe18fe5a2775b Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Tue, 14 Aug 2018 20:22:20 +0200 Subject: [PATCH] openidu-test-e2e: filter test added --- .../test/e2e/OpenViduEventManager.java | 55 +++++ .../test/e2e/OpenViduTestAppE2eTest.java | 205 +++++++++++++++--- 2 files changed, 235 insertions(+), 25 deletions(-) diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduEventManager.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduEventManager.java index 00b5e928..b81ad645 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduEventManager.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduEventManager.java @@ -39,6 +39,9 @@ import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + /** * Manager event class for BrowserUser. Collects, cleans and stores events from * openvidu-testapp @@ -214,6 +217,58 @@ public class OpenViduEventManager { return hasMediaStream; } + public Map getAverageRgbFromVideo(WebElement videoElement) { + String script = "var callback = arguments[arguments.length - 1];" + + "var video = document.getElementById('" + videoElement.getAttribute("id") + "');" + + "var canvas = document.createElement('canvas');" + + "canvas.height = video.videoHeight;" + + "canvas.width = video.videoWidth;" + + "var context = canvas.getContext('2d');" + + "context.drawImage(video, 0, 0, canvas.width, canvas.height);" + + "var imgEl = document.createElement('img');" + + "imgEl.src = canvas.toDataURL();" + + "var blockSize = 5;" + + "var defaultRGB = { r: 0, g: 0, b: 0 };" + + "context.drawImage(video, 0, 0, 220, 150);" + + "var dataURL = canvas.toDataURL();" + + "imgEl.onload = function () {" + + "let i = -4;" + + "var rgb = { r: 0, g: 0, b: 0 };" + + "let count = 0;" + + "if (!context) {" + + " return defaultRGB;" + + "}" + + + "var height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;" + + "var width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;" + + "let data;" + + "context.drawImage(imgEl, 0, 0);" + + + "try {" + + "data = context.getImageData(0, 0, width, height);" + + "} catch (e) {" + + "return defaultRGB;" + + "}" + + + "length = data.data.length;" + + "while ((i += blockSize * 4) < length) {" + + "++count;" + + "rgb.r += data.data[i];" + + "rgb.g += data.data[i + 1];" + + "rgb.b += data.data[i + 2];" + + "}" + + + "rgb.r = ~~(rgb.r / count);" + + "rgb.g = ~~(rgb.g / count);" + + "rgb.b = ~~(rgb.b / count);" + + + "console.warn(rgb);" + + "callback(rgb);" + + "};"; + Object averageRgb = ((JavascriptExecutor) driver).executeAsyncScript(script); + return (Map)averageRgb; + } + public String getDimensionOfViewport() { String dimension = (String) ((JavascriptExecutor) driver) .executeScript("return (JSON.stringify({width: window.innerWidth, height: window.innerHeight}))"); diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java index e901751f..cd41941f 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java @@ -26,6 +26,7 @@ import java.io.File; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; @@ -551,10 +552,10 @@ public class OpenViduTestAppE2eTest { setupBrowser("chrome"); - log.info("Signal message"); + log.info("Subscribe Unsubscribe"); user.getDriver().findElement(By.id("one2one-btn")).click(); - user.getDriver().findElements(By.className("publish-checkbox")).get(0).click(); + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .publish-checkbox")).click(); List joinButtons = user.getDriver().findElements(By.className("join-btn")); for (WebElement el : joinButtons) { @@ -571,15 +572,15 @@ public class OpenViduTestAppE2eTest { true, true)); // Global unsubscribe-subscribe + WebElement subscriberVideo = user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 video")); + WebElement subBtn = user.getDriver().findElement(By.cssSelector(("#openvidu-instance-0 .sub-btn"))); + subBtn.click(); - user.getDriver().findElements(By.className(("sub-btn"))).get(0).click(); + user.getWaiter() + .until(ExpectedConditions.not(ExpectedConditions.attributeToBeNotEmpty(subscriberVideo, "srcObject"))); + Assert.assertFalse(user.getEventManager().hasMediaStream(subscriberVideo)); - user.getWaiter().until(ExpectedConditions.not(ExpectedConditions - .attributeToBeNotEmpty(user.getDriver().findElements(By.tagName("video")).get(0), "srcObject"))); - Assert.assertFalse( - user.getEventManager().hasMediaStream(user.getDriver().findElements(By.tagName("video")).get(0))); - - user.getDriver().findElements(By.className(("sub-btn"))).get(0).click(); + subBtn.click(); user.getEventManager().waitUntilEventReaches("streamPlaying", 3); Assert.assertEquals(user.getDriver().findElements(By.tagName("video")).size(), 2); @@ -587,24 +588,24 @@ public class OpenViduTestAppE2eTest { true, true)); // Video unsubscribe - - Iterable firstVideo = Arrays.asList(user.getDriver().findElements(By.tagName("video")).get(0)); - user.getDriver().findElements(By.className(("sub-video-btn"))).get(0).click(); + subscriberVideo = user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 video")); + Iterable firstVideo = Arrays.asList(subscriberVideo); + user.getDriver().findElement(By.cssSelector(("#openvidu-instance-0 .sub-video-btn"))).click(); Thread.sleep(1000); Assert.assertTrue(user.getEventManager().assertMediaTracks(firstVideo, true, false)); // Audio unsubscribe - user.getDriver().findElements(By.className(("sub-audio-btn"))).get(0).click(); + user.getDriver().findElement(By.cssSelector(("#openvidu-instance-0 .sub-audio-btn"))).click(); Thread.sleep(1000); Assert.assertTrue(user.getEventManager().assertMediaTracks(firstVideo, false, false)); // Video and audio subscribe - user.getDriver().findElements(By.className(("sub-video-btn"))).get(0).click(); + user.getDriver().findElement(By.cssSelector(("#openvidu-instance-0 .sub-video-btn"))).click(); Thread.sleep(1000); Assert.assertTrue(user.getEventManager().assertMediaTracks(firstVideo, false, true)); - user.getDriver().findElements(By.className(("sub-audio-btn"))).get(0).click(); + user.getDriver().findElement(By.cssSelector(("#openvidu-instance-0 .sub-audio-btn"))).click(); Thread.sleep(1000); Assert.assertTrue(user.getEventManager().assertMediaTracks(firstVideo, true, true)); @@ -721,7 +722,7 @@ public class OpenViduTestAppE2eTest { } latch2.countDown(); }); - user.getDriver().findElements(By.className("change-publisher-btn")).get(0).click(); + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .change-publisher-btn")).click(); user.getEventManager().waitUntilEventReaches("streamDestroyed", 2); user.getEventManager().waitUntilEventReaches("accessAllowed", 2); user.getEventManager().waitUntilEventReaches("streamCreated", 4); @@ -753,7 +754,7 @@ public class OpenViduTestAppE2eTest { } latch3.countDown(); }); - user.getDriver().findElements(By.className("change-publisher-btn")).get(0).click(); + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .change-publisher-btn")).click(); user.getEventManager().waitUntilEventReaches("streamDestroyed", 4); user.getEventManager().waitUntilEventReaches("accessAllowed", 3); user.getEventManager().waitUntilEventReaches("streamCreated", 6); @@ -780,7 +781,7 @@ public class OpenViduTestAppE2eTest { @Test @DisplayName("Stream property changed event") - void streamPropertyChangedEvent() throws Exception { + void streamPropertyChangedEventTest() throws Exception { Queue threadAssertions = new ConcurrentLinkedQueue(); @@ -811,7 +812,7 @@ public class OpenViduTestAppE2eTest { threadAssertions.add(((String) event.get("eventContent")).contains("videoActive [false]")); latch1.countDown(); }); - user.getDriver().findElements(By.className("pub-video-btn")).get(0).click(); + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .pub-video-btn")).click(); user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 2); if (!latch1.await(5000, TimeUnit.MILLISECONDS)) { @@ -832,7 +833,7 @@ public class OpenViduTestAppE2eTest { threadAssertions.add(((String) event.get("eventContent")).contains("audioActive [false]")); latch2.countDown(); }); - user.getDriver().findElements(By.className("pub-audio-btn")).get(0).click(); + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .pub-audio-btn")).click(); user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 4); if (!latch2.await(5000, TimeUnit.MILLISECONDS)) { @@ -902,12 +903,13 @@ public class OpenViduTestAppE2eTest { Assert.assertTrue(user.getEventManager().assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true, true)); - WebElement recordBtn = user.getDriver().findElements(By.className("publisher-rec-btn")).get(0); + WebElement recordBtn = user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .publisher-rec-btn")); recordBtn.click(); Thread.sleep(2000); - WebElement pauseRecordBtn = user.getDriver().findElements(By.className("publisher-rec-pause-btn")).get(0); + WebElement pauseRecordBtn = user.getDriver() + .findElement(By.cssSelector("#openvidu-instance-0 .publisher-rec-pause-btn")); pauseRecordBtn.click(); Thread.sleep(2000); @@ -920,10 +922,10 @@ public class OpenViduTestAppE2eTest { user.getWaiter().until(ExpectedConditions.elementToBeClickable(By.cssSelector("#recorder-preview video"))); - user.getWaiter().until(waitForVideoDuration( - user.getDriver().findElements(By.cssSelector("#recorder-preview video")).get(0), 4)); + user.getWaiter().until( + waitForVideoDuration(user.getDriver().findElement(By.cssSelector("#recorder-preview video")), 4)); - user.getDriver().findElements(By.id("close-record-btn")).get(0).click(); + user.getDriver().findElement(By.id("close-record-btn")).click(); user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.cssSelector("#recorder-preview video"), 0)); @@ -1205,6 +1207,146 @@ public class OpenViduTestAppE2eTest { gracefullyLeaveParticipants(2); } + @Test + @DisplayName("Video filter test") + void videoFilterTest() throws Exception { + + setupBrowser("chrome"); + + log.info("Video filter test"); + + // Configure publisher + user.getDriver().findElement(By.id("add-user-btn")).click(); + user.getDriver().findElements(By.cssSelector("#openvidu-instance-0 .subscribe-checkbox")).get(0).click(); + user.getDriver().findElements(By.cssSelector("#openvidu-instance-0 .send-audio-checkbox")).get(0).click(); + user.getDriver().findElement(By.id("session-settings-btn-0")).click(); + Thread.sleep(1000); + user.getDriver().findElement(By.id("add-allowed-filter-btn")).click(); + user.getDriver().findElement(By.id("save-btn")).click(); + Thread.sleep(1000); + + // Configure subscriber + user.getDriver().findElement(By.id("add-user-btn")).click(); + user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .publish-checkbox")).click(); + + List joinButtons = user.getDriver().findElements(By.className("join-btn")); + for (WebElement el : joinButtons) { + el.sendKeys(Keys.ENTER); + } + + user.getEventManager().waitUntilEventReaches("connectionCreated", 4); + user.getEventManager().waitUntilEventReaches("accessAllowed", 1); + user.getEventManager().waitUntilEventReaches("streamCreated", 2); + user.getEventManager().waitUntilEventReaches("streamPlaying", 2); + + try { + System.out.println(getBase64Screenshot(user)); + } catch (Exception e) { + e.printStackTrace(); + } + + Assert.assertEquals(user.getDriver().findElements(By.tagName("video")).size(), 2); + Assert.assertTrue(user.getEventManager().assertMediaTracks(user.getDriver().findElements(By.tagName("video")), + false, true)); + + WebElement subscriberVideo = user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 video")); + + // Analyze Chrome fake video stream without gray filter (GREEN color) + Map rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo); + System.out.println(rgb.toString()); + Assert.assertTrue(checkVideoAverageRgbGreen(rgb)); + + // Try to apply none allowed filter + user.getDriver().findElement(By.cssSelector(".filter-btn")).click(); + WebElement filterTypeInput = user.getDriver().findElement(By.id("filter-type-field")); + filterTypeInput.clear(); + filterTypeInput.sendKeys("NotAllowedFilter"); + user.getDriver().findElement(By.id("apply-filter-btn")).click(); + user.getWaiter().until(ExpectedConditions.attributeContains(By.id("filter-response-text-area"), "value", + "Error [You don't have permissions to apply a filter]")); + + // Try to execute method over not applied filter + user.getDriver().findElement(By.id("exec-filter-btn")).click(); + user.getWaiter().until(ExpectedConditions.attributeContains(By.id("filter-response-text-area"), "value", + "has no filter applied in session")); + + // Apply allowed video filter + filterTypeInput.clear(); + filterTypeInput.sendKeys("GStreamerFilter"); + WebElement filterOptionsInput = user.getDriver().findElement(By.id("filter-options-field")); + filterOptionsInput.clear(); + filterOptionsInput.sendKeys("{\"command\": \"videobalance saturation=0.0\"}"); + user.getDriver().findElement(By.id("apply-filter-btn")).click(); + user.getWaiter().until( + ExpectedConditions.attributeContains(By.id("filter-response-text-area"), "value", "Filter applied")); + + // Try to apply another filter + user.getDriver().findElement(By.id("apply-filter-btn")).click(); + user.getWaiter().until(ExpectedConditions.attributeContains(By.id("filter-response-text-area"), "value", + "already has a filter applied in session")); + + // Analyze Chrome fake video stream with gray filter (GRAY color) + user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 2); + Thread.sleep(500); + rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo); + System.out.println(rgb.toString()); + Assert.assertTrue(checkVideoAverageRgbGray(rgb)); + + // Execute filter method + WebElement filterMethodInput = user.getDriver().findElement(By.id("filter-method-field")); + filterMethodInput.clear(); + filterMethodInput.sendKeys("setElementProperty"); + WebElement filterParamsInput = user.getDriver().findElement(By.id("filter-params-field")); + filterParamsInput.clear(); + filterParamsInput.sendKeys("{\"propertyName\":\"saturation\",\"propertyValue\":\"1.0\"}"); + user.getDriver().findElement(By.id("exec-filter-btn")).click(); + user.getWaiter().until(ExpectedConditions.attributeContains(By.id("filter-response-text-area"), "value", + "Filter method executed")); + + // Analyze Chrome fake video stream without gray filter (GREEN color) + user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 4); + Thread.sleep(500); + rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo); + System.out.println(rgb.toString()); + Assert.assertTrue(checkVideoAverageRgbGreen(rgb)); + + user.getDriver().findElement(By.id("close-dialog-btn")).click(); + Thread.sleep(500); + + // Publisher leaves and connects with active filter + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .leave-btn")).click(); + user.getEventManager().waitUntilEventReaches("streamDestroyed", 2); + user.getEventManager().waitUntilEventReaches("connectionDestroyed", 1); + user.getEventManager().waitUntilEventReaches("sessionDisconnected", 1); + user.getDriver().findElement(By.id("publisher-settings-btn-0")).click(); + Thread.sleep(500); + user.getDriver().findElement(By.id("save-btn")).click(); + Thread.sleep(500); + + user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .join-btn")).click(); + user.getEventManager().waitUntilEventReaches("connectionCreated", 7); + user.getEventManager().waitUntilEventReaches("accessAllowed", 2); + user.getEventManager().waitUntilEventReaches("streamCreated", 4); + user.getEventManager().waitUntilEventReaches("streamPlaying", 4); + + // Analyze Chrome fake video stream with gray filter (GRAY color) + subscriberVideo = user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 video")); + rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo); + System.out.println(rgb.toString()); + Assert.assertTrue(checkVideoAverageRgbGray(rgb)); + + // Remove filter + user.getDriver().findElement(By.cssSelector(".filter-btn")).click(); + Thread.sleep(500); + user.getDriver().findElement(By.id("remove-filter-btn")).click(); + user.getWaiter().until( + ExpectedConditions.attributeContains(By.id("filter-response-text-area"), "value", "Filter removed")); + user.getEventManager().waitUntilEventReaches("streamPropertyChanged", 6); + + user.getDriver().findElement(By.id("close-dialog-btn")).click(); + gracefullyLeaveParticipants(2); + } + private void listEmptyRecordings() { // List existing recordings (empty) user.getDriver().findElement(By.id("list-recording-btn")).click(); @@ -1222,6 +1364,19 @@ public class OpenViduTestAppE2eTest { }; } + private boolean checkVideoAverageRgbGreen(Map rgb) { + // GREEN color: {r < 15, g > 130, b <15} + return (rgb.get("r") < 15) && (rgb.get("g") > 130) && (rgb.get("b") < 15); + } + + private boolean checkVideoAverageRgbGray(Map rgb) { + // GRAY color: {r < 50, g < 50, b < 50} and the absolute difference between them + // not greater than 2 + return (rgb.get("r") < 50) && (rgb.get("g") < 50) && (rgb.get("b") < 50) + && (Math.abs(rgb.get("r") - rgb.get("g")) <= 2) && (Math.abs(rgb.get("r") - rgb.get("b")) <= 2) + && (Math.abs(rgb.get("b") - rgb.get("g")) <= 2); + } + private void gracefullyLeaveParticipants(int numberOfParticipants) throws Exception { int accumulatedConnectionDestroyed = 0; for (int j = 1; j <= numberOfParticipants; j++) {