openvidu-test-e2e: add e2e test for individual recordings abruptly stopped

v2
pabloFuente 2025-11-13 20:38:03 +01:00
parent 46050c40b4
commit 216d0e399f
5 changed files with 388 additions and 24 deletions

View File

@ -17,22 +17,41 @@
package io.openvidu.test.browsers;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCdp;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.RemoteWebDriver;
public class ChromeUser extends BrowserUser {
private Long chromeDriverPid;
public ChromeUser(String userName, int timeOfWaitInSeconds, boolean headless) {
this(userName, timeOfWaitInSeconds, generateDefaultScreenChromeOptions(), headless);
}
@ -92,7 +111,9 @@ public class ChromeUser extends BrowserUser {
}
} else {
log.info("Using local web driver");
this.driver = new ChromeDriver(options);
ChromeDriver chromeDriver = new ChromeDriver(options);
this.driver = chromeDriver;
this.chromeDriverPid = getChromeDriverPid(chromeDriver);
}
this.driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(timeOfWaitInSeconds));
@ -135,4 +156,184 @@ public class ChromeUser extends BrowserUser {
return options;
}
/**
* Simulates an abrupt Chrome crash by forcefully killing the browser process.
* Works for both local and remote WebDriver instances.
*
* @throws IOException if process killing fails
*/
public void simulateCrash() throws IOException {
String REMOTE_URL = System.getProperty("REMOTE_URL_CHROME");
if (REMOTE_URL != null) {
// Remote WebDriver: Use Chrome DevTools Protocol to crash the browser
simulateRemoteCrash();
} else {
// Local WebDriver: Kill the Chrome process directly
simulateLocalCrash();
}
log.info("Simulated Chrome crash for user {}", this.clientData);
}
/**
* Simulates crash for local Chrome instance by killing the process
*/
private void simulateLocalCrash() throws IOException {
ProcessHandle.of(chromeDriverPid).ifPresent(ph -> {
// Kill all descendant processes (the actual Chrome browser processes)
ph.descendants().forEach(child -> child.destroyForcibly());
});
}
/**
* Simulates crash for remote Chrome instance using CDP
*/
private void simulateRemoteCrash() {
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
try {
Map<String, Object> params = Collections.emptyMap();
HasCdp cdp = (driver instanceof HasCdp)
? (HasCdp) driver
: (HasCdp) new Augmenter().augment(driver);
cdp.executeCdpCommand("Browser.crash", params);
} catch (Exception ignored) {
// Expected if browser crashes while executing the command
}
}, executor);
try {
cf.get(2, TimeUnit.SECONDS);
log.info("Browser crash command executed (response received)");
} catch (TimeoutException te) {
log.info("Browser crash command sent (no response as expected)");
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
log.warn("Interrupted while sending crash command", ie);
} catch (ExecutionException ee) {
log.info("Browser crashed (execution failure)", ee.getCause());
}
} catch (Exception e) {
log.warn(
"CDP crash command failed, attempting alternative method by directly killing \"selenium/standalone-chrome\" docker container",
e);
try {
Runtime.getRuntime().exec(new String[] { "sh", "-c",
"docker ps | grep selenium/standalone-chrome | awk '{print $1}' | xargs -I {} docker kill {}" });
} catch (IOException ex) {
log.error("Failed to kill remote Chrome process", ex);
}
} finally {
executor.shutdownNow();
}
}
/**
* Extracts Chrome driver process PID from ChromeDriver
*/
private Long getChromeDriverPid(ChromeDriver driver) {
try {
Capabilities caps = driver.getCapabilities();
Object debuggerAddress = caps.getCapability("goog:chromeOptions");
if (debuggerAddress instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> options = (Map<String, Object>) debuggerAddress;
Object addr = options.get("debuggerAddress");
if (addr != null) {
// Parse port from debugger address (e.g., "localhost:12345")
String[] parts = addr.toString().split(":");
if (parts.length == 2) {
int port = Integer.parseInt(parts[1]);
return findPidByPort(port);
}
}
}
// Fallback: Find Chrome process by command line
return findChromePidByCommandLine();
} catch (Exception e) {
log.warn("Failed to get Chrome PID from driver", e);
return null;
}
}
/**
* Finds Chrome PID by the port it's listening on
*/
private Long findPidByPort(int port) {
try {
String os = System.getProperty("os.name").toLowerCase();
Process process;
if (os.contains("win")) {
process = Runtime.getRuntime().exec(new String[] { "netstat", "-ano" });
} else {
process = Runtime.getRuntime().exec(new String[] { "sh", "-c", "lsof -ti:" + port + " | head -n 1" });
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
if (os.contains("win")) {
while ((line = reader.readLine()) != null) {
if (line.contains(":" + port + " ")) {
String[] parts = line.trim().split("\\s+");
return Long.parseLong(parts[parts.length - 1]);
}
}
} else {
line = reader.readLine();
if (line != null && !line.isEmpty()) {
return Long.parseLong(line.trim());
}
}
} catch (Exception e) {
log.warn("Failed to find PID by port", e);
}
return null;
}
/**
* Finds Chrome PID by searching for chrome process
*/
private Long findChromePidByCommandLine() {
try {
String os = System.getProperty("os.name").toLowerCase();
Process process;
if (os.contains("win")) {
process = Runtime.getRuntime()
.exec(new String[] { "sh", "-c",
"wmic process where \"name='chrome.exe'\" get ProcessId,CommandLine" });
} else if (os.contains("mac")) {
process = Runtime.getRuntime().exec(new String[] { "sh", "-c",
"ps aux | grep -i chrome | grep -v grep | awk '{print $2}' | head -n 1" });
} else {
process = Runtime.getRuntime().exec(new String[] { "sh", "-c",
"pgrep -f chrome | head -n 1" });
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
if (os.contains("win")) {
reader.readLine(); // Skip header
line = reader.readLine();
if (line != null) {
String[] parts = line.trim().split("\\s+");
return Long.parseLong(parts[parts.length - 1]);
}
} else {
line = reader.readLine();
if (line != null && !line.isEmpty()) {
return Long.parseLong(line.trim());
}
}
} catch (Exception e) {
log.warn("Failed to find Chrome PID by command line", e);
}
return null;
}
}

View File

@ -47,7 +47,7 @@ public class RecordingUtils {
private boolean recordedFileFine(File file, Recording recording,
Function<Map<String, Long>, Boolean> colorCheckFunction) throws IOException {
this.checkMultimediaFile(file, recording.hasAudio(), recording.hasVideo(), recording.getDuration(),
recording.getResolution(), recording.getFrameRate(), "aac", "h264", true);
recording.getResolution(), recording.getFrameRate(), "aac", "h264", true, 2);
boolean isFine = false;
Picture frame;
@ -115,7 +115,8 @@ public class RecordingUtils {
}
public void checkIndividualRecording(String recPath, Recording recording, int numberOfVideoFiles,
String audioDecoder, String videoDecoder, boolean checkAudio) throws IOException {
String audioDecoder, String videoDecoder, boolean checkAudio, long durationToleranceInSeconds)
throws IOException {
// Should be only 2 files: zip and metadata
File folder = new File(recPath);
@ -179,7 +180,8 @@ public class RecordingUtils {
log.info("Duration of {} according to sync metadata json file: {} s", webmFile.getName(),
durationInSeconds);
this.checkMultimediaFile(webmFile, recording.hasAudio(), recording.hasVideo(), durationInSeconds,
recording.getResolution(), recording.getFrameRate(), audioDecoder, videoDecoder, checkAudio);
recording.getResolution(), recording.getFrameRate(), audioDecoder, videoDecoder, checkAudio,
durationToleranceInSeconds);
webmFile.delete();
}
@ -190,7 +192,9 @@ public class RecordingUtils {
}
public void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration, String resolution,
Integer frameRate, String audioDecoder, String videoDecoder, boolean checkAudio) throws IOException {
Integer frameRate, String audioDecoder, String videoDecoder, boolean checkAudio,
long durationToleranceInSeconds)
throws IOException {
// Check tracks, duration, resolution, framerate and decoders
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file.getAbsolutePath());
@ -225,11 +229,11 @@ public class RecordingUtils {
df.setRoundingMode(RoundingMode.UP);
log.info("Duration of {} according to ffmpeg: {} s", file.getName(), metadata.getDuration());
log.info("Duration of {} according to 'duration' property: {} s", file.getName(), duration);
log.info("Difference in s duration: {}", Math.abs(metadata.getDuration() - duration));
final double difference = 10;
Assertions.assertTrue(Math.abs((metadata.getDuration() - duration)) < difference,
log.info("Difference in s duration: {}", Math.abs(duration - metadata.getDuration()));
Assertions.assertTrue(Math.abs((duration - metadata.getDuration())) < durationToleranceInSeconds,
"Difference between recording entity duration (" + duration + ") and real video duration ("
+ metadata.getDuration() + ") is greater than " + difference + " in file " + file.getName());
+ metadata.getDuration() + ") is greater than " + durationToleranceInSeconds + " in file "
+ file.getName());
}
public boolean thumbnailIsFine(File file, Function<Map<String, Long>, Boolean> colorCheckFunction) {

View File

@ -45,7 +45,7 @@ public class MediaNodeDockerUtils {
DockerClient dockerClient = getDockerClient();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(containerId).withAttachStdout(true)
.withAttachStderr(true)
.withCmd("bash", "-c", "docker stop kms && sleep " + (millisStop / 1000) + " && docker start kms")
.withCmd("bash", "-c", "docker kill kms && sleep " + (millisStop / 1000) + " && docker start kms")
.exec();
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(new ResultCallback.Adapter<>() {
});

View File

@ -58,12 +58,14 @@ import io.openvidu.java.client.OpenViduRole;
import io.openvidu.java.client.Recording;
import io.openvidu.java.client.RecordingProperties;
import io.openvidu.java.client.Session;
import io.openvidu.test.browsers.ChromeUser;
import io.openvidu.test.browsers.utils.CustomHttpClient;
import io.openvidu.test.browsers.utils.RecordingUtils;
import io.openvidu.test.browsers.utils.Unzipper;
import io.openvidu.test.browsers.utils.layout.CustomLayoutHandler;
import io.openvidu.test.browsers.utils.webhook.CustomWebhook;
import io.openvidu.test.e2e.utils.TestUtils;
import io.openvidu.test.e2e.annotations.OnlyKurento;
public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
@ -649,10 +651,13 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
}
}
long accumulatedTimesWhenSartingRecordings = 0;
// Start the recording of the sessions
restClient.rest(HttpMethod.POST, "/openvidu/api/recordings/start",
"{'session':'" + sessionName + "','outputMode':'INDIVIDUAL'}", HttpURLConnection.HTTP_OK);
user.getEventManager().waitUntilEventReaches("recordingStarted", 3);
Thread.sleep(1000);
// Get connectionId and streamId for one of the users configured to NOT be
@ -671,20 +676,39 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
}
}
long timeBeforeOp = System.currentTimeMillis();
// Generate 3 total recordings of 1 second length for the stream of the user
// configured to NOT be recorded
restClient.rest(HttpMethod.PATCH, "/openvidu/api/sessions/" + sessionName + "/connection/" + connectionId2,
"{'record':true}", HttpURLConnection.HTTP_OK);
user.getEventManager().waitUntilEventReaches("connectionPropertyChanged", 1);
accumulatedTimesWhenSartingRecordings += System.currentTimeMillis() - timeBeforeOp;
Thread.sleep(1000);
timeBeforeOp = System.currentTimeMillis();
restClient.rest(HttpMethod.PATCH, "/openvidu/api/sessions/" + sessionName + "/connection/" + connectionId2,
"{'record':false}", HttpURLConnection.HTTP_OK);
restClient.rest(HttpMethod.PATCH, "/openvidu/api/sessions/" + sessionName + "/connection/" + connectionId2,
"{'record':true}", HttpURLConnection.HTTP_OK);
user.getEventManager().waitUntilEventReaches("connectionPropertyChanged", 3);
accumulatedTimesWhenSartingRecordings += System.currentTimeMillis() - timeBeforeOp;
Thread.sleep(1000);
timeBeforeOp = System.currentTimeMillis();
restClient.rest(HttpMethod.PATCH, "/openvidu/api/sessions/" + sessionName + "/connection/" + connectionId2,
"{'record':false}", HttpURLConnection.HTTP_OK);
restClient.rest(HttpMethod.PATCH, "/openvidu/api/sessions/" + sessionName + "/connection/" + connectionId2,
"{'record':true}", HttpURLConnection.HTTP_OK);
user.getEventManager().waitUntilEventReaches("connectionPropertyChanged", 5);
accumulatedTimesWhenSartingRecordings += System.currentTimeMillis() - timeBeforeOp;
Thread.sleep(1000);
restClient.rest(HttpMethod.POST, "/openvidu/api/recordings/stop/" + sessionName, HttpURLConnection.HTTP_OK);
@ -695,7 +719,7 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
String recPath = "/opt/openvidu/recordings/" + sessionName + "/";
Recording recording = new OpenVidu(OpenViduTestAppE2eTest.OPENVIDU_URL, OpenViduTestAppE2eTest.OPENVIDU_SECRET)
.getRecording(sessionName);
this.recordingUtils.checkIndividualRecording(recPath, recording, 4, "opus", "vp8", true);
this.recordingUtils.checkIndividualRecording(recPath, recording, 4, "opus", "vp8", true, 5);
// Analyze INDIVIDUAL recording metadata
new Unzipper().unzipFile(recPath, recording.getName() + ".zip");
@ -718,8 +742,9 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assertions.assertEquals(connectionId1, file.get("connectionId").getAsString(),
"Wrong connectionId file metadata property");
long msDuration = file.get("endTimeOffset").getAsLong() - file.get("startTimeOffset").getAsLong();
Assertions.assertTrue((msDuration - 4000) < 1000,
"Wrong recording duration of individual file. Difference: " + (msDuration - 4000));
long differenceInDuration = msDuration - 4000 - accumulatedTimesWhenSartingRecordings;
Assertions.assertTrue(differenceInDuration < 750,
"Wrong recording duration of individual file. Difference: " + differenceInDuration);
count1++;
} else if (fileStreamId.equals(streamId2)) {
// Dynamically recorded user
@ -753,6 +778,137 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assertions.assertTrue(regexNames.isEmpty(), "Some expected file name didn't existed: " + regexNames.toString());
}
@Test
@DisplayName("Individual record with abrupt user disconnection")
void individualRecordWithAbruptUserDisconnectionTest() throws Exception {
isRecordingTest = true;
log.info("Individual record with abrupt user disconnection");
CustomHttpClient restClient = new CustomHttpClient(OpenViduTestAppE2eTest.OPENVIDU_URL, "OPENVIDUAPP",
OpenViduTestAppE2eTest.OPENVIDU_SECRET);
JsonObject config = restClient.rest(HttpMethod.GET, "/openvidu/api/config", HttpURLConnection.HTTP_OK);
String defaultOpenViduWebhookEndpoint = null;
Integer defaultOpenViduRecordingAutostopTimeout = null;
if (config.has("OPENVIDU_WEBHOOK_ENDPOINT")) {
defaultOpenViduWebhookEndpoint = config.get("OPENVIDU_WEBHOOK_ENDPOINT").getAsString();
}
if (config.has("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT")) {
defaultOpenViduRecordingAutostopTimeout = config.get("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT").getAsInt();
}
CountDownLatch initLatch = new CountDownLatch(1);
io.openvidu.test.browsers.utils.webhook.CustomWebhook.main(new String[0], initLatch);
try {
if (!initLatch.await(30, TimeUnit.SECONDS)) {
Assertions.fail("Timeout waiting for webhook springboot app to start");
CustomWebhook.shutDown();
return;
}
Map<String, Object> newConfig = Map.of("OPENVIDU_PRO_NETWORK_QUALITY", false,
"OPENVIDU_PRO_SPEECH_TO_TEXT", "disabled", "OPENVIDU_WEBHOOK", true,
"OPENVIDU_WEBHOOK_ENDPOINT", "http://127.0.0.1:7777/webhook",
"OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT", 0);
restartOpenViduServer(newConfig);
OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome");
final String sessionName = "AbruptStopOfIndividualRecording";
final String recordingName = "ABRUPT_STOP_OF_INDIVIDUAL_RECORDING";
user.getDriver().findElement(By.id("add-user-btn")).click();
user.getDriver().findElement(By.id("session-name-input-0")).clear();
user.getDriver().findElement(By.id("session-name-input-0")).sendKeys(sessionName);
user.getDriver().findElement(By.className("join-btn")).click();
user.getEventManager().waitUntilEventReaches("connectionCreated", 1);
user.getEventManager().waitUntilEventReaches("accessAllowed", 1);
user.getEventManager().waitUntilEventReaches("streamCreated", 1);
user.getEventManager().waitUntilEventReaches("streamPlaying", 1);
int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
Assertions.assertEquals(1, numberOfVideos, "Expected 1 video but found " + numberOfVideos);
Assertions.assertTrue(
user.getBrowserUser().assertMediaTracks(user.getDriver().findElements(By.tagName("video")), true,
true),
"Video was expected to have audio and video tracks");
user.getDriver().findElement(By.id("session-api-btn-0")).click();
Thread.sleep(1000);
user.getDriver().findElement(By.id("rec-properties-btn")).click();
Thread.sleep(500);
// Set recording name
user.getDriver().findElement(By.id("recording-name-field")).sendKeys(recordingName);
// Set OutputMode to INDIVIDUAL
user.getDriver().findElement(By.id("rec-outputmode-select")).click();
Thread.sleep(500);
user.getDriver().findElement(By.id("option-INDIVIDUAL")).click();
Thread.sleep(500);
user.getDriver().findElement(By.id("start-recording-btn")).click();
user.getWaiter().until(ExpectedConditions.attributeToBe(By.id("api-response-text-area"), "value",
"Recording started [" + sessionName + "]"));
user.getEventManager().waitUntilEventReaches("recordingStarted", 1);
Thread.sleep(3000);
CustomWebhook.clean();
((ChromeUser) user.getBrowserUser()).simulateCrash();
JsonObject event = CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 20);
Assertions.assertEquals("networkDisconnect", event.get("reason").getAsString(),
"Wrong reason for webrtcConnectionDestroyed event");
event = CustomWebhook.waitForEvent("participantLeft", 1);
Assertions.assertEquals("networkDisconnect", event.get("reason").getAsString(),
"Wrong reason for participantLeft event");
event = CustomWebhook.waitForEvent("recordingStatusChanged", 1);
Assertions.assertEquals("lastParticipantLeft", event.get("reason").getAsString(),
"Wrong reason for recordingStatusChanged event");
Assertions.assertEquals("stopped", event.get("status").getAsString(),
"Wrong status in recordingStatusChanged event");
event = CustomWebhook.waitForEvent("sessionDestroyed", 1);
Assertions.assertEquals("lastParticipantLeft", event.get("reason").getAsString(),
"Wrong reason for sessionDestroyed event");
event = CustomWebhook.waitForEvent("recordingStatusChanged", 1);
Assertions.assertEquals("lastParticipantLeft", event.get("reason").getAsString(),
"Wrong reason for recordingStatusChanged event");
Assertions.assertEquals("ready", event.get("status").getAsString(),
"Wrong status in recordingStatusChanged event");
// Check that the INDIVIDUAL recording has been properly saved and is healthy
// even after Chrome crash
String recPath = "/opt/openvidu/recordings/" + sessionName + "/";
Recording recording = new OpenVidu(OpenViduTestAppE2eTest.OPENVIDU_URL,
OpenViduTestAppE2eTest.OPENVIDU_SECRET)
.getRecording(sessionName);
this.recordingUtils.checkIndividualRecording(recPath, recording, 1, "opus", "vp8", true, 15);
} finally {
Map<String, Object> oldConfig = new HashMap<>();
oldConfig.put("OPENVIDU_WEBHOOK", false);
if (defaultOpenViduWebhookEndpoint != null) {
oldConfig.put("OPENVIDU_WEBHOOK_ENDPOINT", defaultOpenViduWebhookEndpoint);
}
if (defaultOpenViduRecordingAutostopTimeout != null) {
oldConfig.put("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT", defaultOpenViduRecordingAutostopTimeout);
}
restartOpenViduServer(oldConfig);
CustomWebhook.shutDown();
}
}
@Test
@DisplayName("REST API PRO test")
void restApiProTest() throws Exception {
@ -1143,6 +1299,7 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
}
@Test
@OnlyKurento
@DisplayName("Network quality test")
void networkQualityTest() throws Exception {
@ -1290,7 +1447,8 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
filterOptionsInput = user.getDriver().findElement(By.id("filter-options-field"));
filterOptionsInput.clear();
filterOptionsInput.sendKeys("{\"url\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Solid_red.svg/1024px-Solid_red.svg.png\"}");
filterOptionsInput.sendKeys(
"{\"url\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Solid_red.svg/1024px-Solid_red.svg.png\"}");
user.getDriver().findElement(By.id("apply-filter-btn")).click();
user.getWaiter().until(
ExpectedConditions.attributeContains(By.id("operation-response-text-area"), "value", "Filter applied"));
@ -1326,7 +1484,8 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
// Blue
filterParamsInput.clear();
filterParamsInput.sendKeys("{\"url\": \"https://png.pngtree.com/thumb_back/fw800/background/20210207/pngtree-blue-pure-color-simple-background-image_557085.jpg\"}");
filterParamsInput.sendKeys(
"{\"url\": \"https://png.pngtree.com/thumb_back/fw800/background/20210207/pngtree-blue-pure-color-simple-background-image_557085.jpg\"}");
user.getDriver().findElement(By.id("exec-filter-btn")).click();
user.getWaiter().until(ExpectedConditions.attributeContains(By.id("operation-response-text-area"), "value",
"Filter method executed"));

View File

@ -1646,7 +1646,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
String recPath = recordingsPath + sessionName + "/";
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(sessionName);
this.recordingUtils.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
this.recordingUtils.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true, 2);
// Try to get the stopped recording
user.getDriver().findElement(By.id("get-recording-btn")).click();
@ -1853,17 +1853,17 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
String recPath = recordingsPath + SESSION_NAME + "/";
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME);
this.recordingUtils.checkMultimediaFile(new File(recPath + recording.getName() + ".mp4"), false, true,
recording.getDuration(), recording.getResolution(), recording.getFrameRate(), null, "h264", true);
recording.getDuration(), recording.getResolution(), recording.getFrameRate(), null, "h264", true, 2);
// Check video-only INDIVIDUAL recording
recPath = recordingsPath + SESSION_NAME + "~1/";
recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "~1");
this.recordingUtils.checkIndividualRecording(recPath, recording, 3, "opus", "vp8", true);
this.recordingUtils.checkIndividualRecording(recPath, recording, 3, "opus", "vp8", true, 2);
// Check audio-only INDIVIDUAL recording
recPath = recordingsPath + SESSION_NAME + "~2/";
recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "~2");
this.recordingUtils.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
this.recordingUtils.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true, 2);
user.getDriver().findElement(By.id("close-dialog-btn")).click();
Thread.sleep(500);
@ -1945,7 +1945,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
// Check audio-only COMPOSED recording
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME);
this.recordingUtils.checkMultimediaFile(new File(recordingFilePath), true, false, recording.getDuration(), null,
null, "opus", null, true);
null, "opus", null, true, 2);
user.getDriver().findElement(By.id("close-dialog-btn")).click();
Thread.sleep(500);
@ -2970,7 +2970,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assertions.assertFalse(OV.fetch(), "OpenVidu.fetch() should return false");
this.recordingUtils.checkIndividualRecording("/opt/openvidu/recordings/" + customSessionId + "/", recording, 2,
"opus", "vp8", false);
"opus", "vp8", false, 2);
// Not recorded session
try {
@ -3991,7 +3991,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assertions.assertTrue(rec.getSize() > 0, "Recording size is 0");
this.recordingUtils.checkIndividualRecording("/opt/openvidu/recordings/TestSession/", rec, 1, "opus", "vp8",
true);
true, 10);
user.getDriver().findElement(By.id("remove-all-users-btn")).click();
user.getEventManager().clearAllCurrentEvents();
@ -4075,7 +4075,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
Assertions.assertTrue(rec.getSize() > 0, "Recording size is 0");
this.recordingUtils.checkIndividualRecording("/opt/openvidu/recordings/TestSession/", rec, 1, "opus", "vp8",
true);
true, 10);
OV.fetch();
sessions = OV.getActiveSessions();
@ -4569,7 +4569,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
CustomWebhook.waitForEvent("recordingStatusChanged", 10); // Ready
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(recId);
this.recordingUtils.checkIndividualRecording(recPath + recId + "/", recording, 1, "opus", "vp8", true);
this.recordingUtils.checkIndividualRecording(recPath + recId + "/", recording, 1, "opus", "vp8", true, 2);
// Test IPCAM individual recording (IPCAM video only, recording audio and video)