Skip to content
This repository has been archived by the owner on Sep 21, 2021. It is now read-only.

Commit

Permalink
Add feature to start or stop video recording using cookie (#1085)
Browse files Browse the repository at this point in the history
* Add feature to start or stop video recording using cookie

Per #490, video recording can be started, if disabled, or stopped, if enabled, by sending cookie named 'zaleniumVideo'. This is beneficial when multiple tests run in the same session.

Additionally to assist with identifying tests in the dashboard, a cookie named 'zaleniumTestName' can be passed in to set the test name. This name will appear in the dashboard. If name already exists, a count will be appended to the name.

* Making the test more complete

* Add feature to start or stop video recording using cookie

Per #490, video recording can be started, if disabled, or stopped, if enabled, by sending cookie named 'zaleniumVideo'. This is beneficial when multiple tests run in the same session.

Additionally to assist with identifying tests in the dashboard, a cookie named 'zaleniumTestName' can be passed in to set the test name. This name will appear in the dashboard. If name already exists, a count will be appended to the name.

* Adding TestNG groups

Co-authored-by: Chanatan Charnkijtawarush <C.Charnkijtawarush@allegiantair.com>
Co-authored-by: Diego Molina <diemol@gmail.com>
  • Loading branch information
3 people committed Mar 24, 2020
1 parent c33b808 commit 3b8d180
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 23 deletions.
4 changes: 2 additions & 2 deletions charts/zalenium/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ hub:

## The tag for the image
## ref: https://hub.docker.com/r/dosel/zalenium/tags
tag: "3"
tag: "latest"

## Specify a imagePullPolicy
## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
Expand Down Expand Up @@ -250,4 +250,4 @@ nodeSelector:
hostAliases: []
# - ip: "127.0.0.1"
# hostnames:
# - "cosbench.local"
# - "cosbench.local"
36 changes: 36 additions & 0 deletions docs/_posts/2000-01-08-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,42 @@ Thanks [adrichem](https://github.com/adrichem) for implementing this feature! Mo

</details>

#### Change video recording status while in session
<details>
<summary>Click for details.</summary>

<div class="container m-2 p-2">
It is possible to enable or disable video recording while the test is running regardless of what is setup when the session starts.
This is done by sending a cookie with the name <code>zaleniumVideo</code> with a value of <code>true</code> (to enable recording)
or false (to disable recording). Disabling recording while it is originally enable will result in a new video file. This can be useful
when you have multiple tests in one session and want to split up each test in its own file. This feature is only available with elgalu/selenium.
Here is an example in Java:

{% highlight java %}
Cookie cookie = new Cookie("zaleniumVideo", "true");
webDriver.manage().addCookie(cookie);
{% endhighlight %}

</div>

</details>

#### Change test file name while in session
<details>
<summary>Click for details.</summary>

<div class="container m-2 p-2">
A video file name can be changed in session by sending a cookie with the name <code>zaleniumTestName</code> with any value.
This can be useful when coupling with <code>zaleniumVideo</code> to give each split video a custom name. Here is an example in Java:

{% highlight java %}
Cookie cookie = new Cookie("zaleniumTestName", "anyName");
webDriver.manage().addCookie(cookie);
{% endhighlight %}

</div>

</details>

***

Expand Down
12 changes: 6 additions & 6 deletions run_integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ else
if [ "${INTEGRATION_TO_TEST}" = sauceLabs ]; then
if [ -n "${SAUCE_USERNAME}" ]; then
env "PATH=$PATH" mvn clean
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -DintegrationToTest=${INTEGRATION_TO_TEST}
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dgroups=normal -DintegrationToTest=${INTEGRATION_TO_TEST}
# Check for generated videos
ls -la ${VIDEOS_FOLDER}/saucelabs*.mp4 || (echo "No Sauce Labs videos were downloaded." && exit 2)
ls -la ${VIDEOS_FOLDER}/zalenium*.mp4 || (echo "No Zalenium videos were generated." && exit 2)
Expand All @@ -24,7 +24,7 @@ else
if [ "${INTEGRATION_TO_TEST}" = browserStack ]; then
if [ -n "${BROWSER_STACK_USER}" ]; then
env "PATH=$PATH" mvn clean
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -DintegrationToTest=${INTEGRATION_TO_TEST}
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dgroups=normal -DintegrationToTest=${INTEGRATION_TO_TEST}
# Check for generated videos
ls -la ${VIDEOS_FOLDER}/browserstack*.mp4 || (echo "No BrowserStack videos were downloaded." && exit 2)
ls -la ${VIDEOS_FOLDER}/zalenium*.mp4 || (echo "No Zalenium videos were generated." && exit 2)
Expand All @@ -33,7 +33,7 @@ else
if [ "${INTEGRATION_TO_TEST}" = testingBot ]; then
if [ -n "${TESTINGBOT_KEY}" ]; then
env "PATH=$PATH" mvn clean
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -DintegrationToTest=${INTEGRATION_TO_TEST}
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dgroups=normal -DintegrationToTest=${INTEGRATION_TO_TEST}
# Check for generated videos
ls -la ${VIDEOS_FOLDER}/testingbot*.mp4 || (echo "No TestingBot videos were downloaded." && exit 2)
ls -la ${VIDEOS_FOLDER}/zalenium*.mp4 || (echo "No Zalenium videos were generated." && exit 2)
Expand All @@ -42,7 +42,7 @@ else
if [ "${INTEGRATION_TO_TEST}" = crossBrowserTesting ]; then
if [ -n "${CBT_USERNAME}" ]; then
env "PATH=$PATH" mvn clean
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -DintegrationToTest=${INTEGRATION_TO_TEST}
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dgroups=normal -DintegrationToTest=${INTEGRATION_TO_TEST}
# Check for generated videos
ls -la ${VIDEOS_FOLDER}/crossbrowsertesting*.mp4 || (echo "No CBT videos were downloaded." && exit 2)
ls -la ${VIDEOS_FOLDER}/zalenium*.mp4 || (echo "No Zalenium videos were generated." && exit 2)
Expand All @@ -51,7 +51,7 @@ else
if [ "${INTEGRATION_TO_TEST}" = lambdaTest ]; then
if [ -n "${LT_USERNAME}" ]; then
env "PATH=$PATH" mvn clean
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -DintegrationToTest=${INTEGRATION_TO_TEST}
mvn clean verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dgroups=normal -DintegrationToTest=${INTEGRATION_TO_TEST}
# Check for generated videos
ls -la ${VIDEOS_FOLDER}/lambdatest*.mp4 || (echo "No LambdaTest videos were downloaded." && exit 2)
ls -la ${VIDEOS_FOLDER}/zalenium*.mp4 || (echo "No Zalenium videos were generated." && exit 2)
Expand All @@ -64,7 +64,7 @@ else
mkdir -p "${VIDEOS_FOLDER}"
chmod +x target/zalenium_in_docker_compose.sh
target/zalenium_in_docker_compose.sh start
mvn verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dskip.failsafe.setup=true -DintegrationToTest=sauceLabs
mvn verify -Pintegration-test -DthreadCountProperty=2 -Dskip.surefire.tests=true -Dskip.failsafe.setup=true -Dgroups=normal -DintegrationToTest=sauceLabs
# Check for generated videos
ls -la ${VIDEOS_FOLDER}/saucelabs*.mp4 || (echo "No Sauce Labs videos were downloaded." && exit 2)
ls -la ${VIDEOS_FOLDER}/zalenium*.mp4 || (echo "No Zalenium videos were generated." && exit 2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class TestInformation {
private String platform;
private String platformVersion;
private String fileName;
private int fileCount = 0;
private String fileExtension;
private String videoUrl;
private List<String> logUrls;
Expand Down Expand Up @@ -113,6 +114,10 @@ public String getFileName() {
return fileName;
}

public int getFileCount() {
return fileCount;
}

public List<String> getLogUrls() {
return logUrls;
}
Expand Down Expand Up @@ -244,6 +249,12 @@ public String getBrowserAndPlatform() {
public JsonObject getMetadata() { return this.metadata;}
public void setMetadata(JsonObject metadata) { this.metadata = metadata;}

public void setTestName(String name) { this.testName = name;}

public void setFileCount(int fileCount) {
this.fileCount = fileCount;
}

public boolean equals(Object obj) {
if (obj == null) return false;
if (obj == this) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public class DockerSeleniumRemoteProxy extends DefaultRemoteProxy {
private long cleanupStartedTime = 0;
private AtomicBoolean timedOut = new AtomicBoolean(false);
private long timeRegistered = System.currentTimeMillis();
private boolean stopRecordingByCookie = false;

public DockerSeleniumRemoteProxy(RegistrationRequest request, GridRegistry registry) {
super(request, registry);
Expand Down Expand Up @@ -326,6 +327,27 @@ public void beforeCommand(TestSession session, HttpServletRequest request, HttpS
processContainerAction(DockerSeleniumContainerAction.SEND_NOTIFICATION, messageCommand,
getContainerId());
}
if ("zaleniumVideo".equalsIgnoreCase(cookieName)) {
boolean recordVideo = Boolean.parseBoolean(cookie.get("value").getAsString());
if (recordVideo && !isVideoRecordingEnabled()) {
setVideoRecordingEnabledSession(true);
testInformation.setVideoRecorded(true);
stopRecordingByCookie = false;
videoRecording(DockerSeleniumContainerAction.START_RECORDING);
} else if (!recordVideo && isVideoRecordingEnabled()){
stopRecordingByCookie = true;
videoRecording(DockerSeleniumContainerAction.STOP_RECORDING);
setVideoRecordingEnabledSession(false);
testInformation.setVideoRecorded(false);
}
}
if ("zaleniumTestName".equalsIgnoreCase(cookieName)) {
String newTestName = cookie.get("value").getAsString();
if (!newTestName.isEmpty()) {
testName = newTestName;
testInformation.setTestName(testName);
}
}
else if(CommonProxyUtilities.metadataCookieName.equalsIgnoreCase(cookieName)) {
JsonParser jsonParser = new JsonParser();
JsonObject metadata = jsonParser.parse(cookie.get("value").getAsString()).getAsJsonObject();
Expand Down Expand Up @@ -634,6 +656,9 @@ void processContainerAction(final DockerSeleniumContainerAction action, final St
if (keepVideoAndLogs()) {
if (DockerSeleniumContainerAction.STOP_RECORDING == action) {
copyVideos(containerId);
if (stopRecordingByCookie) {
DashboardCollection.updateDashboard(testInformation);
}
}
if (DockerSeleniumContainerAction.TRANSFER_LOGS == action) {
copyLogs(containerId);
Expand All @@ -660,9 +685,18 @@ void copyVideos(final String containerId) {
if (!Files.exists(videoFile.getParent())) {
Files.createDirectories(videoFile.getParent());
}

//For multiple recording in one session, add '_{count}' to the test name
if (Files.exists(videoFile)) {
testInformation.setTestName(testName + "_" + testInformation.getFileCount());
testInformation.buildVideoFileName();
videoFile = Paths.get(String.format("%s/%s", testInformation.getVideoFolderPath(),
testInformation.getFileName()));
}
Files.copy(entry.get(), videoFile, StandardCopyOption.REPLACE_EXISTING);
CommonProxyUtilities.setFilePermissions(videoFile);
videoWasCopied = true;
testInformation.setFileCount(testInformation.getFileCount() + 1);
LOGGER.debug("Video file copied to: {}/{}", testInformation.getVideoFolderPath(), testInformation.getFileName());
}
} catch (IOException e) {
Expand Down Expand Up @@ -765,22 +799,25 @@ private void unsetCleaningMarker() {
private void cleanupNode(boolean willShutdown) {
// This basically means that the node is cleaning up and will receive a new request soon
// willShutdown == true => there won't be a next session
this.setCleaningMarker(!willShutdown);
if (!isCleaningUp()) {
this.setCleaningMarker(!willShutdown);

try {
if (testInformation != null) {
processContainerAction(DockerSeleniumContainerAction.SEND_NOTIFICATION,
try {
if (testInformation != null) {
processContainerAction(DockerSeleniumContainerAction.SEND_NOTIFICATION,
testInformation.getTestStatus().getTestNotificationMessage(), getContainerId());
}
videoRecording(DockerSeleniumContainerAction.STOP_RECORDING);
processContainerAction(DockerSeleniumContainerAction.TRANSFER_LOGS, getContainerId());
processContainerAction(DockerSeleniumContainerAction.CLEANUP_CONTAINER, getContainerId());
}
videoRecording(DockerSeleniumContainerAction.STOP_RECORDING);
processContainerAction(DockerSeleniumContainerAction.TRANSFER_LOGS, getContainerId());
processContainerAction(DockerSeleniumContainerAction.CLEANUP_CONTAINER,
getContainerId());

if (testInformation != null && keepVideoAndLogs()) {
DashboardCollection.updateDashboard(testInformation);
if (testInformation != null && keepVideoAndLogs()) {
DashboardCollection.updateDashboard(testInformation);
}
} finally {
this.unsetCleaningMarker();
}
} finally {
this.unsetCleaningMarker();
}
}

Expand Down
54 changes: 51 additions & 3 deletions src/test/java/de/zalando/ep/zalenium/it/ParallelIT.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.zalando.ep.zalenium.it;

import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.net.NetworkUtils;
Expand All @@ -17,7 +19,9 @@
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;

Expand Down Expand Up @@ -148,7 +152,8 @@ private WebDriver getWebDriver() {
return webDriver.get();
}

@Test(dataProvider = "browsersAndPlatformsForLivePreview")
@SuppressWarnings("groupsTestNG")
@Test(dataProvider = "browsersAndPlatformsForLivePreview", groups = "normal")
public void checkIframeLinksForLivePreviewWithMachineIp(DesiredCapabilities desiredCapabilities) {

NetworkUtils networkUtils = new NetworkUtils();
Expand All @@ -165,8 +170,8 @@ public void checkIframeLinksForLivePreviewWithMachineIp(DesiredCapabilities desi
assertThat(pageSource, containsString("view_only=false"));
}


@Test(dataProvider = "browsersAndPlatforms")
@SuppressWarnings("groupsTestNG")
@Test(dataProvider = "browsersAndPlatforms", groups = "normal")
public void loadGooglePageAndCheckTitle(DesiredCapabilities desiredCapabilities) {

// Go to the homepage
Expand All @@ -187,4 +192,47 @@ public void loadTheInternetPageAndCheckTitle(DesiredCapabilities desiredCapabili
assertThat(getWebDriver().getTitle(), containsString("Internet"));
}

@SuppressWarnings("groupsTestNG")
@Test(dataProvider = "browsersAndPlatformsForLivePreview", groups = {"minikube"})
public void splitVideoRecordingOfOneSessionIntoMultipleFiles(DesiredCapabilities desiredCapabilities) {

// Go to first page
getWebDriver().manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
getWebDriver().get("https://the-internet.herokuapp.com/");

// Set test name
String testName = desiredCapabilities.getBrowserName() + "_splitVideoTest";
Cookie nameCookie = new Cookie("zaleniumTestName", testName);
getWebDriver().manage().addCookie(nameCookie);

// Stop the video
Cookie stopCookie = new Cookie("zaleniumVideo", "false");
getWebDriver().manage().addCookie(stopCookie);

// Start the video
Cookie startCookie = new Cookie("zaleniumVideo", "true");
getWebDriver().manage().addCookie(startCookie);

getWebDriver().get("https://www.google.com");

// Stop the video
getWebDriver().manage().addCookie(stopCookie);

// Start the video
getWebDriver().manage().addCookie(startCookie);

getWebDriver().get("https://www.apple.com");

// Stop the video
getWebDriver().manage().addCookie(stopCookie);

// Go to the dashboard
getWebDriver().get(String.format("http://%s:%s/dashboard", ZALENIUM_HOST, ZALENIUM_PORT));

assertThat(getWebDriver().findElements(By.xpath("//small[text()='" + testName + "']")).size(), is(1));
assertThat(getWebDriver().findElements(By.xpath("//small[text()='" + testName + "_1']")).size(), is(1));
assertThat(getWebDriver().findElements(By.xpath("//small[text()='" + testName + "_2']")).size(), is(1));

}

}
Loading

0 comments on commit 3b8d180

Please sign in to comment.