Видеозапись выполнения тестов Selenium
Есть ли смысл создавать видеозапись процесса тестирования? Вопрос спорный, но думаю, что каждый из вас хоть раз сталкивался с нестабильно работающими тестами, когда один и тот же тест через раз завершается неудачей без видимых причин. В такой ситуации иногда практически невозможно разобраться в чем конкретно заключалась ошибка.
Записывать выполнение тестов полностью или только особо критические моменты — это решение зависит от Ваших предпочтений и свободного дискового пространства :). Главное, что такая возможность есть и она реализуется относительно несложно.
Для видеозаписи нам понадобится Monte Media Library Screen Recorder. К сожалению, этой библиотеки нет в Maven репозитории, поэтому необходимый нам MonteScreenRecorder.jar нужно скачать на официальном сайте. На момент написания статьи последняя версия рекордера была 0.7.7. Теперь загруженный jar файл можно добавить в Build Path проекта или, если Вы используете Maven, выполнить следующие шаги:
1. Установить библиотеку в локальный репозиторий, из командной строки:
mvn install:install-file -Dfile=MonteScreenRecorder.jar -DgroupId=org.monte
-DartifactId=monte-screen-recorder -Dversion=0.7.7 -Dpackaging=jar
-Dfile=абсолютный или относительный путь к файлу
2. Добавить зависимость в pom.xml
org.monte
monte-screen-recorder
0.7.7
Сперва создадим собственный класс, который будет вызывать Monte ScreenRecorder и выполнять все необходимые настройки видеозаписи:
import static org.monte.media.FormatKeys.*;
import static org.monte.media.VideoFormatKeys.*;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import org.monte.media.Format;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.math.Rational;
import org.monte.screenrecorder.ScreenRecorder;
public class VideoRecorder {
private ScreenRecorder screenRecorder;
public void startRecording() {
try {
GraphicsConfiguration gc = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
this.screenRecorder = new ScreenRecorder(gc, new Format(
MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI),
new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey,
ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
CompressorNameKey,
ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, DepthKey,
24, FrameRateKey, Rational.valueOf(15), QualityKey,
1.0f, KeyFrameIntervalKey, 15 * 60), new Format(
MediaTypeKey, MediaType.VIDEO, EncodingKey,
"black", FrameRateKey, Rational.valueOf(30)), null);
this.screenRecorder.start();
} catch (Exception e) {
System.out.println(e);
}
}
public void stopRecording() {
try {
this.screenRecorder.stop();
} catch (Exception e) {
System.out.println(e);
}
}
}
Обратите внимание, все действия в методах заключены в блок try … catch для того, чтобы случайно возникшие ошибки видеозаписи не повлияли на дальнейшее выполнение тестов. По умолчанию, ScreenRecorder делает запись всего экрана и сохраняет файл в соответствующую видео директорию ОС ( Windows — Libraries\Videos, Mac — Movies и т.д.) со стандартным именем, например, «ScreenRecording 2013-11-08 at 18.09.00.avi».
Сделаем наш класс немного интереснее, добавив такую функциональность, как задание имени и директории сохранения файла, а также указание области экрана для записи.
import static org.monte.media.FormatKeys.*;
import static org.monte.media.VideoFormatKeys.*;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.monte.media.Format;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.math.Rational;
import org.monte.screenrecorder.ScreenRecorder;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
public class VideoRecorder {
private final String RECORD_DIRECTORY = "D:\\Projects\\temp\\";
private ScreenRecorder screenRecorder;
public void startRecording(WebDriver driver) {
try {
GraphicsConfiguration gc = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
File dir = new File(RECORD_DIRECTORY);
// записываем только область окна драйвера
// для уменьшения размера видео файла
Point point = driver.manage().window().getPosition();
Dimension dimension = driver.manage().window().getSize();
Rectangle rectangle = new Rectangle(point.x, point.y,
dimension.width, dimension.height);
this.screenRecorder = new ScreenRecorder(gc, rectangle,
new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey,
MIME_AVI),
new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey,
ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
CompressorNameKey,
ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, DepthKey,
24, FrameRateKey, Rational.valueOf(15), QualityKey,
1.0f, KeyFrameIntervalKey, 15 * 60), new Format(
MediaTypeKey, MediaType.VIDEO, EncodingKey,
"black", FrameRateKey, Rational.valueOf(30)), null,
dir);
this.screenRecorder.start();
} catch (Exception e) {
System.out.println(e);
}
}
public void stopRecording(String recordName) {
try {
this.screenRecorder.stop();
// переименовываем созданный .avi файл,
if (recordName != null) {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH.mm.ss");
File newFileName = new File(String.format("%s%s %s.avi",
RECORD_DIRECTORY, recordName,
dateFormat.format(new Date())));
this.screenRecorder.getCreatedMovieFiles().get(0)
.renameTo(newFileName);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
Пример использования класса VideoRecorder в тесте:
public class RecordedTest {
private WebDriver driver;
@Before
public void setUpDriver() {
driver = new FirefoxDriver();
}
@Test
public void testRecordFirefox() throws Exception {
driver.get("http://www.google.com.ua");
// начинаем запись
VideoRecorder recorder = new VideoRecorder();
recorder.startRecording(driver);
try {
// критическая секция
WebElement element = driver.findElement(By.name("q"));
element.sendKeys("Cheese!");
element.submit();
} finally {
// останавливаем запись
recorder.stopRecording("Google send Cheese");
}
}
@After
public void closeDriver() {
driver.quit();
}
}
И снова использование блока try … catch, в этом случае его finally секции, для того, чтобы корректно завершить процесс видеозаписи даже в случае возникновения ошибок при выполнении теста.
Так как запись активности осуществляется непосредственно на экране, то такой способ не может быть использован при параллельном запуске тестов, а также с RemoteWebDriver или Grid.