Настройка системы WEB — тестирования на основе headless chromium-browser, chromedriver, nightwatch и node.js на Ubuntu

    image

    Предисловие


    Привет, Хабр! Данная задача возникла у меня с проблемой, которая заключалась в создании робота для авторизации в Instagram, который бы делал за меня лайки. Всю задачу не напишу, напишу только часть реализации в виде настройки необходимого инструментария на удаленном сервере.

    WEB — тестирование — это объемная и неоднозначная сфера, которая может заключаться в решении задач не только в плане тестирования WEB — приложений, но и, к примеру, в плане построения парсеров, роботов IoT и ботов работы с социальными сетями и все это используя только JavaScript!

    Возможно, что вам не нравится словосочетание «тестирование», возможно, отчасти, из-за того, что это словосочетание заключает в себе более интересные вещи, которые, к примеру, позволят нам написать бота, способного авторизироваться в Instagram, Facebook и совершать там ряд действий от нашего лица и в одно и то же время нудно заниматься наблюдением, как выполняется наш фронтенд, но тестирование имеет смысл и уже стандартизировано сообществом W3C и продолжает развиваться.

    Описание задачи в двух словах


    Какую задачу мы ставим, чтобы решить при помощи тестирования? Всего-то нужно, чтобы какая-то программа открывала браузер и там автоматически кликала ссылки, вбивала тексты и показывала, что получится или возвращала параметр результата, который нам нужен. И все это нужно сделать на Linux — дистрибутиве Ubuntu 16.04, у которого нет GUI, т.е. у нас только консоль и запустить привычный браузер, как на полноценном компьютере не получится.

    Что нужно для решения тестирования без GUI?


    Все, что нужно для современного, «монопольного» тестирования на JavaScript:

    1. Headless Chromium Browser v 59 (chromium-browser) — безголовый браузер в консоли;
    2. Node.js (nodejs) — сервер JavaScript;
    3. WebDriver (chromedriver) — драйвер для обработки тестов на JavaScript и работы с chromium-browser посредством Node.js;
    4. Nightwatch.js (nightwatch) — известная библиотека для написания и запуска автотестов посредством Node.js от LinkedIn.

    Установка на сервер


    Напишем шаги для последовательной установки всех компонентов для тестирования.

    image

    1). Установка cromium-browser. Перед установкой chromium-browser надо будет установить все необходимые для него зависимости, поэтому надо будет выполнить ряд действий.
    Устанавливаем зависимости:

    sudo apt-get -f install

    Если у нас были первые попытки установки, но помещали отсутствие зависимостей, то будет хорошо, если удалить загруженные файлы в /var/cache/apt/archives запуском команды:

    sudo rm /var/cache/apt/archives/chromium*

    Теперь устанавливаем сам cromium-browser:

    sudo apt-get install chromium-browser

    image

    2). Установка nodejs. Как установить Node.js и все методы установки подробно описано тут.

    Один из самых простых методов установки:
    Есть вероятность, что данным методом установится старая стабильная версия v4.2.6 из репозитория Ubuntu, под которым этот пример тестирования не проверен. Для стабильной работы оптимально, если установить версию 7 или выше методом PPA или NVM

    sudo apt-get update
    sudo apt-get install nodejs

    Также потребуется и менеджер пакетов, посредством которого надо будет установить chromedriver и nightwatch :

    sudo apt-get install npm

    Они нужны будут нам обработать тесты на JavaScript из Node.js.

    image

    3). Установка chromedriver. Этот драйвер выполняет роль WebDriver’а, предоставляющего API, к примеру, чтобы иметь возможность кликать на ссылки и вбивать тексты в текстовые поля и формы, для этого мы и будем использовать Chromedriver. Для установки chromedriver выполняем команду:

    npm install chromedriver

    image

    4). Установка nightwatch. Nightwatch.js — это библиотека для написания и запуска автотестов на JavaScript:

    npm install nightwatch

    Схема работы тестирования


    Коротко вся схема выглядит таким образом, что тесты на Nightwatch.js отправляют запросы на Chromedriver, а Chromedriver обращается к Chrome Browser для исполнения тестов(заполнение полей форм и нажатие на ссылки):

    image

    Настройка и запуск первого теста


    Конфигурационный файл Nightwatch.js умолчанию находится в папке node_modules/nightwatch/bin и настройки берутся по умолчанию оттуда и для того, чтобы задать наши пользовательские настройки для Nightwatch.js нужно создать файл nightwatch.json в корне проекта и прописать туда всё необходимое, чтобы Chromedriver использовался напрямую (без Selenium и других сторонних вещей) и Chromium запускался в «headless» режиме:

    {
      "src_folders": ["tests"], // путь к папке с тестами
      "output_folder": "reports",
      "custom_commands_path": "",
      "custom_assertions_path": "",
      "page_objects_path": "",
      "globals_path": "globals.js", // путь к файлу, в котором задаётся глобальный контекст для всех тестов
    
      "selenium": {
        "start_process": false // отменяем запуск Селениума, т.к. будем обращаться к Chromedriver напрямую
      },
    
      "test_settings": {
        "default": {
          "selenium_port": 9515, // номер порта Chromedriver по умолчанию ("selenium_" в имени поля — это пережиток прошлого)
          "selenium_host": "localhost",
          "default_path_prefix" : "",
    
          "desiredCapabilities": {
            "browserName": "chrome",
            "chromeOptions" : {
              "args" : ["--no-sandbox", "--headless", "--disable-gpu"], // специальные флаги для работы Хрома в headless-режиме
              "binary" : "/usr/bin/chromium-browser" // путь к исполняемому файлу Хрома
            },
            "acceptSslCerts": true
          }
        }
      }
    }
    

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

    const chromedriver = require('chromedriver');
    
    module.exports = {
      before: function(done) {
        chromedriver.start();
    
        done();
      },
    
      after: function(done) {
        chromedriver.stop();
    
        done();
      }
    };
    

    Теперь необходимо написать любой тест для проверки работоспособности системы тестирования. К примеру, нужно открыть google.com, поискать что-нибудь и проверить результаты поиска. Конечно, Nightwatch.js API предоставляет ещё кучу всяких методов для всевозможных проверок, но для начала нам хватит:

    module.exports = {
      'Test google.com': function(browser) {
        const firstResultSelector = '#rso cite._Rm';
    
        browser
          .url('http://google.com', () => {
            console.log('Loading google.com...');
          })
          .waitForElementVisible('#lst-ib', 5000)
          .execute(function() {
            document.getElementById('lst-ib').value = 'Блог WebSofter!';
          })
          .submitForm('form')
          .waitForElementVisible(firstResultSelector, 5000)
          .getText(firstResultSelector, result => {
            browser.assert.equal(result.value, 'blog.websofter.ru/');
          })
          .end();
          
      }
    };
    

    Запускаем через консоль по команде:

    nightwatch --test google.js


    Замечание. Во первых, если Node.js установлен через nvm, то надо активировать сессию через команду:

    nvm ~/.profile

    во вторых, для запуска теста необходимо создать в корне проекта package.json с данными проекта, а в виде запускаемого фала надо указать google.js через команду:

    npm init

    Далее уже выполняем команду запуска нашего теста:

    nightwatch --test google.js

    Результатом выше изложенного кода в файлах будет результат в консоли:

    image

    Т.е., мы заходим на главную сайта Google, вбиваем в поиск словосочетание «Блог WebSofter!» и в итоге сравнивается адрес нашего блога на наличие в определенных тегах на странице результата поиска.

    Скачать рабочий пример из этой статьи можно по ссылке.

    Заключение


    Первоначально Nightwatch.js был ориентирован на работу с Selenium. Но сегодня она умеет работать с chromedriver напрямую и необходимость в Selenium тем более в PhantomJS отпадает, хотя есть возможность с ними интегрировать.

    Осторожно! Безголовый режим Chrome доступен на Mac и Linux в v59. Поддержка Windows входит в Chrome v60. Чтобы проверить, какая версия Chrome у вас есть, откройте

    chrome://version

    Безголовый Chrome поставляется в версии Chrome 59. Это способ запуска браузера Chrome в безголовой среде, т.е. в консоли без GUI. Подобным образом работал PhantomJS. Chrome привносит в командную строку все современные функции веб-платформы, предоставляемые Chromium и движком Blink.

    Почему это полезно?

    Безголовый браузер — отличный инструмент для автоматического тестирования и серверных сред, где вам не нужна видимая оболочка пользовательского интерфейса. Например, вы можете выполнить некоторые тесты на реальной веб-странице, создать PDF-файл или просто проверить, как браузер отображает URL-адрес. Дополнительно можно узнать по ссылке

    Ссылки по теме


    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 10
    • 0

      Спасибо за статью!


      Скрытый текст
      Устанавливаем зависимости:
      sudo apt-get -f install

      Боюсь, вы только что случайно бутылку колы.

      • 0

        Мне кажется, что, наверняка, для этого уже есть Docker образ на хабе :)

        • 0
          Или использовать сервисы такие как: testoid.ru или ghostinspector.com
          • 0
            Да, использование:
            docker run -p 5900:5900 --rm -e SCREEN_WIDTH=1280 -e SCREEN_HEIGHT=1000 --net=host selenium/standalone-chrome-debug

            сильно упрощает настройку и работу
          • +11

            Конечно, Nightwatch в целом неплох, но имеет свои недостатки: устаревший синтаксис с callback-цепочками вместо Promises и async/await, и требования наличия webdriver-а к браузеру — как тестировать на смартфоне или смарт-ТВ? Если Вы занимаетесь функциональным тестированием web-сфере и следите за развитием технологий, рекоммендую ознакомиться с этой статьей, и в частности, присмотреться к решениям от TestCafe — тоже на Node.js, но поудобнее и решающий вопрос с любыми девайсами. Можно вообще SauseLabs прикрутить, чтобы тестировать на всевозможных устройствах скопом.

            • 0
              Да, TestCafe выглядит не плохим. Но! Присмотритесь по-внимательнее:

              «TestCafe uses a URL-rewriting proxy which allows it to work without the WebDriver. This proxy injects the driver script that emulates user actions into the tested page.». © FAQ I have heard that TestCafe does not use Selenium. How does it operate?

              Меня, если честно, очень коробит, когда тест.программа лезет в тестируемый объект. Да, бывают случаи, когда без модификации тест.объекта нет возможности проверить ту или иную функциональность, но когда есть зачем это надо делать? Я к тому что Selenium-based решения сейчас более выигрышные!
              • +2

                Безусловно, у всех решений свои плюсы и минусы. В принципе, в современном web-е код модифицируется и так немало раз — babel для async/await и генераторов, bundle-ирование в webpack-е, polyfills и так далее — так что в принципе в еще одном преобразовании особо ничего страшного нет.
                Сам hammerhead выглядит довольно надежным — мне удалось найти, как выйти из песочницы, но маловероятно, что в обычном web-приложении такое бывает. Зато пользователи SmartTV и прочих необычных браузеров счастливы :)

                • +2
                  В принципе, в современном web-е код модифицируется и так немало раз — babel для async/await и генераторов, bundle-ирование в webpack-е, polyfills и так далее — так что в принципе в еще одном преобразовании особо ничего страшного нет.

                  Не спорю! Но. Все эти преобразования дают итоговый продукт. Вот именно итоговый продукт и есть тест. объект, который желательно не трогать и проверять таким какой он есть. Иначе может получиться ситуация, что у разработчика одна ситуация, а пользователя совсем другая. Я сейчас про конечного продукта, т.е. по принципу черного ящика, а не серо или бело ящичные виды тестирования
              • +1
                Спасибо большое! Как раз искал что то в этом духе)
              • 0
                Исследовал множество инструментов для тестирования на nodejs и выбрал nightwatchjs. Много лет применял nightwatchjs в работе в разных компаниях, но на текущий день его сложно рекомендовать новым людям из-за отсутствия поддержки async/await из коробки, которые помогают писать тест как «синхронный» код, делая тесты лаконичнее в синтаксисе и проще для восприятия и понимания.

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

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.