Перейти к основному содержимому

Как обновлять браузеры в больших проектах

Проблема

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

Пересняв тысячи скриншотов, разработчик создает пулл-реквест, который ему надо влить в главную ветку проекта. И влитие такого пулл-реквеста становится крайне сложной задачей из-за постоянно возникающих мерж-конфликтов. Так как разработка не стоит на месте, и какие-то команды в это время меняют тесты: переснимают эталонные скриншоты, чтобы учесть внедрение новой функциональности, или удаляют неактуальные тесты, и, соответственно, их скриншоты. А значит, пулл-реквест с большим количеством измененных файлов будет быстро устаревать и требовать постоянного ребейза относительно главной ветки проекта. При чем этот ребейз требует целого ряда действий: нужно не только обновить кодовую базу, но и заново запустить соответствующие тесты, чтобы переснять скриншоты. Так как простым выбором «правильной» стороны мерж-конфликта между скриншотами здесь не обойтись. Оба скриншота при мерж-конфликте будут неправильными: один — устаревшим, а другой — не соответствующим новой версии браузера.

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

Есть 3 варианта решения данной проблемы.

Решение 1: testplane.browser().version()

Testplane позволяет переопределить версию браузера для конкретного теста или набора тестов с помощью специального хелпера testplane.browser().version().

Например:

// Переопределяем версию браузера chrome-desktop на 70.3 для всего набора тестов
testplane.browser("chrome-desktop").version("70.3");
describe("suite", function () {
it("test 1", function () {
// ...
});

// Переопределяем версию браузера chrome-desktop на 70.1 для конкретного теста
testplane.browser("chrome-desktop").version("70.1");
it("test 2", function () {
// ...
});
});

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

Решение 2: Browser Version Changer

Можно воспользоваться плагином hermione-browser-version-changer, который позволяет определять версию браузера для конкретного теста на основе специального словаря (store) и предикатов для всех доступных в проекте версий браузеров.

Пример использования плагина:

module.exports = {
plugins: {
"hermione-browser-version-changer": {
enabled: true,
initStore: async () => {
// Подготавливаем словарь с произвольными признаками для разметки
return {
"title-test1": "tag1",
"title-test2": "tag1",
"title-test3": "tag2",
};
},
browsers: {
"chrome-desktop": {
// Ключ "70.1" – версия браузера, значение – предикат
// Если функция вернет истинное значение, для браузера установится данная версия
70.1: (test, version, store) => {
// test – текущий тест
// version – предлагаемая версия "70.1"
// store – словарь, который был подготовлен в методе initStore

// Установить версию браузера 70.1, если тест относится к "tag1"
return store[test.title] === "tag1";
},
80: (test, version, store) => {
return store[test.title] === "tag2";
},
},
},
},

// другие плагины testplane...
},

// другие настройки testplane...
};

Приведенный пример — очень условный и, вполне возможно, что в вашем проекте вам даже не понадобится использовать store, а хватит проверки соответствия теста заданному паттерну регулярного выражения.