Мар 192016
 

Интернет реклама УБС

Видеозапись выполнения тестов 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.

Мар 192016
 

WebDriver и SSL Untrusted certificate

При тестировании веб-приложений, использующих защищенное https соединение, Вы можете столкнуться с ошибками сертификатов при работе с некоторыми веб-драйверами, в частности, с InternetExplorerDriver. Если существует какая-либо проблема с сертификатом, Вы увидите оповещение «Это соединение является недоверенным». Как и в случае с диалоговыми окнами, при появлении такого сообщения работа веб-драйвера с элементами страницы полностью блокируется и продолжать тестирование ресурса дальше просто невозможно.

FirefoxDriver и ChromeDriver

На сегодняшний день FirefoxDriver и ChromeDriver (selenium 2.37.1) автоматически принимают все сертификаты по-умолчанию и не выводят оповещений, поэтому никаких дополнительных настроек при работе с ними не требуется. Однако такое поведение для FirefoxDriver уже отмечено как @Deprecated и возможно в скором времени предупреждения сертификатов безопасности будут обрабатываться иначе.

// Accept untrusted SSL certificates.
@Deprecated
public static final boolean ACCEPT_UNTRUSTED_CERTIFICATES = true;

В любом случае, приведу примеры того как управлять автоматическим приемом сертификатов, возможно, Вам это пригодится для более ранних версий драйвера или наоборот понадобится это отключить.

1. Для FirefoxDriver:

DesiredCapabilities capability = DesiredCapabilities.firefox();
capability.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
driver = new FirefoxDriver(capability);

или

FirefoxProfile profile = new FirefoxProfile();
profile.setAcceptUntrustedCertificates(true);
driver = new FirefoxDriver(profile);

2. Для ChromeDriver:

ChromeOptions options = new ChromeOptions();
options.addArguments("--ignore-certificate-errors");
driver = new ChromeDriver(options);

В текущей реализации chromedriver.exe опция «—ignore-certificate-errors» передается браузеру по-умолчанию во время инициализации. Для того, чтобы эту функцию отключить можно выполнить следующее (для chromedriver.exe версии не ниже 2.7):

ChromeOptions options = new ChromeOptions();
options.setExperimentalOptions("excludeSwitches",
        Arrays.asList("ignore-certificate-errors"));
driver = new ChromeDriver(options);

Использование ExperimentalOptions является временным решением, потому как в скором времени должна выйти полноценная поддержка excludeSwitches в ChromeOptions.

Internet Explorer

В случае с Internet Explorer вариант с установкой DesiredCapabilities ACCEPT_SSL_CERTS для тестирования не работает. Для IE нельзя временно поменять расширенные параметры, они задаются навсегда. Изменять их приходится вручную еще до начала тестирования. Но я настоятельно рекомендую не понижать настройки безопасности в IE. После смены настроек, факт их изменения обычно забывается и в результате остается машина с неверно сконфигурированным SSL/TSL в IE.

Для того, чтобы продолжить тестирование в IE после вывода такого предупреждения, нам нужно просто кликнуть по ссылке Continue to this website (not recommended), ее id = «overridelink». Но проблема в том, что после появления этого окна работа InternetExplorerDriver частично заблокирована и мы не можем выполнить обычный click() на элементе. Поэтому для нажатия на ссылку можно использовать javascript:

driver.get("javascript:document.getElementById('overridelink').click();");
Мар 192016
 

Установка DKIM в ISPmanager ( Debian, Ubuntu )

Добрый день.

Появилась такая проблема — письма отправленные сервера попадают в спам. По большей части проблема была в некорректной SPF и PTR записях (сделанных не мной). Но я решил дополнить еще и DKIM записью.

Вот краткая заметка, как я это делал.

/usr/local/ispmgr/sbin/pkgctl -D cache
killall -9 ispmgr

1. Заходим в панель управления сервером и переходи на вкладку «Возможности», устанавливаем «OpenDKIM — фильтр DKIM». Если не получается через панель, устанавливаем вручную:
Debian/Ubuntu:

# sudo apt-get install opendkim

Для Debian/Ubuntu необходимо установить дополнительный пакет:

# sudo apt-get install opendkim-tools

Centos/RH:

# yum install opendkim

2. Генерируем этот самый DKIM ключ и сертификат:
Debian/Ubuntu:

# cd /etc/exim4/ssl/
# /usr/bin/opendkim-genkey -D /etc/exim4/ssl -d domain.com -s dkim -r

Centos/RH:

# cd /etc/exim/ssl
# opendkim-genkey -D /etc/exim/ssl -d domain.com -s dkim -r

где domain.com — это ваш домен.

3. Перезагрузим exim:

# sudo /etc/init.d/exim4 restart/

4. Заходим опять в панель управления сервером, на вкладке «Почтовые домены» выбираем нужный домен и жмем кнопку «Изменить» и ставим галочку «Включить DKIM».

Теперь радуемся, что наши письма подписаны и с меньшей вероятностью попадут в спам листы популярных почтовых служб.

Фев 082015
 

Дополнительный ip для интерфейса (ifconfig alias)

Добавляем несколько ip адресов в разный Unix системах.

FreeBSD

Установка адреса алиас через интерфейс:
ifconfig fxp0 alias 192.168.111.110
Удалить существующий алиас с интерфейса:
ifconfig fxp0 -alias 192.168.111.110
Установка алиаса при загрузки системы (rc.conf)
ifconfig_em0_alias0="inet 192.168.111.110"

Debian/Ubuntu

Прописываем алиас на интерфейс (eth0 — оригинальный, eth0:0, eth0:1 — дополнителные)
ifconfig eth0:0 192.168.111.110 up
Установка алиаса при загрузке системы (/etc/network/interfaces)

auto eth0:0
iface eth0:0 inet static
name Ethernet alias LAN card
address 192.168.1.11
netmask 255.255.255.0
broadcast 192.168.1.255
network 192.168.1.0

auto eth0:1
iface eth0:1 inet static
name Ethernet alias LAN card
address 192.168.10.11
netmask 255.255.255.0
broadcast 192.168.10.255
network 192.168.10.0
Удалить существующий алиас с интерфейса:
ifconfig eth0:0 down
Авг 192014
 

Потратил на чтение документации достаточно времени, заставляя Samba работать с символическими ссылками. Предлагаю Вам свое решение.

Открываем конфигурационный файл:

sudo nano /etc/samba/smb.conf

В начале секции [global] пишем.

unix extensions = no
wide links = yes
follow symlinks = yes

Не забываем перезагрузить демон:

service smbd restart
/etc/init.d/samba restart

Данное решение очень удобно если Вам надо работать с файлами в разных частях системы.
Не забывайте про безопасность, она очень важна в системе.