Внедрение поддержки video recording в Selenium Grid на Windows

В продолжение данной темы,

посмотрим, как заставить Selenium Grid записывать видео не только на Linux, но и Windows OS. Оригинал.

После небольшого исследования я пришел к выводу, что для организации кросс-платформенного решения лучше все же взять ffmpeg, вместо avconv. Ввиду отсутствия отличий в плане ключевых функций, изменения конснутся по сути только нескольких IO опций.

final String display = SystemUtils.IS_OS_LINUX ? System.getenv("DISPLAY") : "desktop";
final String recorder = SystemUtils.IS_OS_LINUX ? "x11grab" : "gdigrab";
final String[] commandsSequence = new String[]{
		RECORDING_TOOL, "-y",
		"-video_size", info.getResolution(),
		"-f", recorder,
		"-i", display,
		"-an",
		"-vcodec", "libx264",
		"-crf", String.valueOf(info.getQuality()),
		"-r", String.valueOf(info.getFrameRate()),
		outputPath
};

Вместо x11grab будет использоваться gdigrab, который поставляется вместе с Windows. Ну а в качестве input мы должны сообщить тулу, что намеряны записывать desktop.

Стоит также отметить, что в случае наличия видео записи с указанным именем, ffmpeg будет ожидать подтверждения пользователя о перезаписи. Т.к. мы запускаем процесс в non-interactive mode, для избежания потенциальных проблем следует указать флаг -y.

Следующий challenge касатется остановки видео записи. Ввиду того, что ffmpeg требует корретного закрытия для осуществления финализации видео потока, мы не можем просто так прибить процесс командой taskkill. Такой же трюк с INT сигналом, как и в Linux, не поддерживается из коробки в Windows. Посему, для решения данной задачи был использован сторонний тул, написанный на плюсах, который умеет делать ровно то же самое, что и линуксовый аналог. От нас лишь требуется получить ffmpeg PID, и передать его данному тулу.

public static void stopVideoRecording() {
	final String output = SystemUtils.IS_OS_LINUX ?
			runCommand("pkill", "-INT", RECORDING_TOOL) :
			runCommand(Optional.ofNullable(SEND_CTRL_C_TOOL_PATH).orElse(SEND_CTRL_C_TOOL_NAME), getPidOf(RECORDING_TOOL));
	LOGGER.info("Stop recording output log: " + output);
}

Следует отметить, что сам тул - весьма экзотический. И найти его на просторах всемирной паутины оказалось не так уж и просто. Посему, во избежание дополнительных сложностей с поиском, он был помещен в ресурсы проекта. Но использовать его напрямую из jar файла мы не сможем. Для этого нам предвариательно понадобится его извлечь, скажем, в OS-specific tmp folder. И сделать это желательно уже при старте самого грида.

public static void main(String[] args) throws Exception {
	if (SystemUtils.IS_OS_WINDOWS)
		exportResourceToTmpDir(SEND_CTRL_C_TOOL_NAME).ifPresent(path -> SEND_CTRL_C_TOOL_PATH = path);
	GridLauncher.main(args);
}

Там самым, мы определили новую точку входа в приложение, что следует обязательно указать maven-assembly-plugin’у.

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <mainClass>com.blogspot.notes.automation.qa.grid.core.CustomGridLauncher</mainClass>
            </manifest>
        </archive>
    </configuration>

Вот собственно и все. Стоит разве что только отметить, что раз уж мы поменяли avconv на ffmpeg, следует позаботиться и об обновлении docker-selenium исходников.

#=====
# VNC, ffmpeg
#=====
RUN apt-get update -qqy \
  && DEBIAN_FRONTEND=noninteractive apt-get -qqy install software-properties-common python-software-properties \
  && DEBIAN_FRONTEND=noninteractive add-apt-repository ppa:djcj/hybrid \
  && apt-get -qqy install \
    x11vnc \
    ffmpeg \
  && rm -rf /var/lib/apt/lists/* \
  && mkdir -p ~/.vnc \
  && x11vnc -storepasswd secret ~/.vnc/passwd

Ввиду того, что ffmpeg отсутствует в официальных Ubuntu-репозиториях, необходимо вначале указать его точное месторасположение, подключив ppa:djcj/hybrid, перед непосредственной установкой.

На этом все. Исходники, как обычно, на GitHub. Не забываем об установке ffmpeg и помещении оного в system path, а также - ставить лайки, если пост вам оказался полезным. :wink:

4 лайка