Управление браузером через php
Attempts to determine the capabilities of the user's browser, by looking up the browser's information in the browscap.ini file.
Parameters
You can bypass this parameter with a null value.
If set to true , this function will return an array instead of an object .
Return Values
Returns false when no information can be retrieved, such as when the browscap configuration setting in php.ini has not been set.
Examples
echo $_SERVER [ 'HTTP_USER_AGENT' ] . "\n\n" ;
?php$browser = get_browser ( null , true );
print_r ( $browser );
?>
The above example will output something similar to:
Notes
Note:
In order for this to work, your browscap configuration setting in php.ini must point to the correct location of the browscap.ini file on your system.
browscap.ini is not bundled with PHP, but you may find an up-to-date » php_browscap.ini file here.
While browscap.ini contains information on many browsers, it relies on user updates to keep the database current. The format of the file is fairly self-explanatory.
User Contributed Notes 17 notes
This function is too slow for todays needs.
Since browser detection can be tricky and very slow, I compared a few packages.
Here are the results:
User Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Sinergi Package
---------------
Chrome 63.0.3239.84 on Windows 10.0
Took 0.0022480487823486 seconds.
---------------
WhichBrowser Package
---------------
Chrome 63 on Windows 10
Took 0.021045207977295 seconds.
---------------
Piwik Package
---------------
Chrome 63.0 on Windows 10
Took 0.079447031021118 seconds.
---------------
get_browser Package
---------------
Chrome 63.0 on Windows 10
Took 0.09611701965332 seconds.
---------------
User Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Sinergi Package
---------------
Firefox 57.0 on Windows 10.0
Took 0.0023159980773926 seconds.
---------------
WhichBrowser Package
---------------
Firefox 57.0 on Windows 10
Took 0.019663095474243 seconds.
---------------
Piwik Package
---------------
Firefox 57.0 on Windows 10
Took 0.079678058624268 seconds.
---------------
get_browser Package
---------------
Firefox 57.0 on Windows 10
Took 0.02236008644104 seconds.
---------------
If you ONLY need a very fast and simple function to detect the browser name (update to May 2016):
function get_browser_name ( $user_agent )
if ( strpos ( $user_agent , 'Opera' ) || strpos ( $user_agent , 'OPR/' )) return 'Opera' ;
elseif ( strpos ( $user_agent , 'Edge' )) return 'Edge' ;
elseif ( strpos ( $user_agent , 'Chrome' )) return 'Chrome' ;
elseif ( strpos ( $user_agent , 'Safari' )) return 'Safari' ;
elseif ( strpos ( $user_agent , 'Firefox' )) return 'Firefox' ;
elseif ( strpos ( $user_agent , 'MSIE' ) || strpos ( $user_agent , 'Trident/7' )) return 'Internet Explorer' ;
?>
This function also resolves the trouble with Edge (that contains in the user agent the string "Safari" and "Chrome"), with Chrome (contains the string "Safari") and IE11 (that do not contains 'MSIE' like all other IE versions).
Note that "strpos" is the fastest function to check a string (far better than "preg_match") and Opera + Edge + Chrome + Safari + Firefox + Internet Explorer are the most used browsers today (over 97%).
To my surprise I found that none of the get_browser alternatives output the correct name / version combination that I was looking for using Opera or Chrome. They either give the wrong name eg Safari when in fact it should be Chrome and if the ua string includes a version number as with the latest versions of Chrome and Opera the wrong number is reported. So I took bits and pieces from the various examples and combined them and added a check for version.
function getBrowser ()
<
$u_agent = $_SERVER [ 'HTTP_USER_AGENT' ];
$bname = 'Unknown' ;
$platform = 'Unknown' ;
$version = "" ;
//First get the platform?
if ( preg_match ( '/linux/i' , $u_agent )) $platform = 'linux' ;
>
elseif ( preg_match ( '/macintosh|mac os x/i' , $u_agent )) $platform = 'mac' ;
>
elseif ( preg_match ( '/windows|win32/i' , $u_agent )) $platform = 'windows' ;
>
// Next get the name of the useragent yes seperately and for good reason
if( preg_match ( '/MSIE/i' , $u_agent ) && ! preg_match ( '/Opera/i' , $u_agent ))
<
$bname = 'Internet Explorer' ;
$ub = "MSIE" ;
>
elseif( preg_match ( '/Firefox/i' , $u_agent ))
<
$bname = 'Mozilla Firefox' ;
$ub = "Firefox" ;
>
elseif( preg_match ( '/Chrome/i' , $u_agent ))
<
$bname = 'Google Chrome' ;
$ub = "Chrome" ;
>
elseif( preg_match ( '/Safari/i' , $u_agent ))
<
$bname = 'Apple Safari' ;
$ub = "Safari" ;
>
elseif( preg_match ( '/Opera/i' , $u_agent ))
<
$bname = 'Opera' ;
$ub = "Opera" ;
>
elseif( preg_match ( '/Netscape/i' , $u_agent ))
<
$bname = 'Netscape' ;
$ub = "Netscape" ;
>
// see how many we have
$i = count ( $matches [ 'browser' ]);
if ( $i != 1 ) //we will have two since we are not using 'other' argument yet
//see if version is before or after the name
if ( strripos ( $u_agent , "Version" ) < strripos ( $u_agent , $ub ))$version = $matches [ 'version' ][ 0 ];
>
else $version = $matches [ 'version' ][ 1 ];
>
>
else $version = $matches [ 'version' ][ 0 ];
>
// check if we have a number
if ( $version == null || $version == "" )
return array(
'userAgent' => $u_agent ,
'name' => $bname ,
'version' => $version ,
'platform' => $platform ,
'pattern' => $pattern
);
>
// now try it
$ua = getBrowser ();
$yourbrowser = "Your browser: " . $ua [ 'name' ] . " " . $ua [ 'version' ] . " on " . $ua [ 'platform' ] . " reports:
" . $ua [ 'userAgent' ];
print_r ( $yourbrowser );
?>
Follow up to Francesco R's post from 2016.
His function works for most human traffic; added a few lines to cover the most common bot traffic. Also fixed issue with function failing to detect strings at position 0 due to strpos behavior.
// Function written and tested December, 2018
function get_browser_name ( $user_agent )
// Make case insensitive.
$t = strtolower ( $user_agent );
// If the string *starts* with the string, strpos returns 0 (i.e., FALSE). Do a ghetto hack and start with a space.
// "[strpos()] may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE."
// http://php.net/manual/en/function.strpos.php
$t = " " . $t ;
// Humans / Regular Users
if ( strpos ( $t , 'opera' ) || strpos ( $t , 'opr/' ) ) return 'Opera' ;
elseif ( strpos ( $t , 'edge' ) ) return 'Edge' ;
elseif ( strpos ( $t , 'chrome' ) ) return 'Chrome' ;
elseif ( strpos ( $t , 'safari' ) ) return 'Safari' ;
elseif ( strpos ( $t , 'firefox' ) ) return 'Firefox' ;
elseif ( strpos ( $t , 'msie' ) || strpos ( $t , 'trident/7' )) return 'Internet Explorer' ;
// Search Engines
elseif ( strpos ( $t , 'google' ) ) return '[Bot] Googlebot' ;
elseif ( strpos ( $t , 'bing' ) ) return '[Bot] Bingbot' ;
elseif ( strpos ( $t , 'slurp' ) ) return '[Bot] Yahoo! Slurp' ;
elseif ( strpos ( $t , 'duckduckgo' ) ) return '[Bot] DuckDuckBot' ;
elseif ( strpos ( $t , 'baidu' ) ) return '[Bot] Baidu' ;
elseif ( strpos ( $t , 'yandex' ) ) return '[Bot] Yandex' ;
elseif ( strpos ( $t , 'sogou' ) ) return '[Bot] Sogou' ;
elseif ( strpos ( $t , 'exabot' ) ) return '[Bot] Exabot' ;
elseif ( strpos ( $t , 'msn' ) ) return '[Bot] MSN' ;
// Common Tools and Bots
elseif ( strpos ( $t , 'mj12bot' ) ) return '[Bot] Majestic' ;
elseif ( strpos ( $t , 'ahrefs' ) ) return '[Bot] Ahrefs' ;
elseif ( strpos ( $t , 'semrush' ) ) return '[Bot] SEMRush' ;
elseif ( strpos ( $t , 'rogerbot' ) || strpos ( $t , 'dotbot' ) ) return '[Bot] Moz or OpenSiteExplorer' ;
elseif ( strpos ( $t , 'frog' ) || strpos ( $t , 'screaming' )) return '[Bot] Screaming Frog' ;
// Miscellaneous
elseif ( strpos ( $t , 'facebook' ) ) return '[Bot] Facebook' ;
elseif ( strpos ( $t , 'pinterest' ) ) return '[Bot] Pinterest' ;
Всем привет! Сегодня я расскажу вам о том, как с помощью PHP можно работать с Selenium.
Чаще всего это бывает необходимо, когда перед вами стоит задача написать автотесты для web интерфейса или свой парсер/краулер.
«Selenium — это инструмент для автоматизации действий веб-браузера.
В большинстве случаев используется для тестирования Web-приложений, но этим не
ограничивается. В частности, реализация Selenium WebDriver для браузера phantomjs
часто используется как веб-граббер.»
Мы рассмотрим следующие нюансы:
- Использование Behat/Mink для соединения с Selenium
- Запуск Selenium в docker, и удаленный доступ по VNC
- Расширим функционал Behat с помощью Extension Feature
1. Готовим Behat и Mink
Behat это php фреймворк, который изначально был создан для поведенческого тестирования (BDD). Он является официальной PHP реализацией более известного продукта Cucumber, который часто используется в других языках программирования.
Сам по себе работать с Selenium он не умеет и предназначен больше для написания функциональных тестов без использования браузера.
Устанавливается как обычный пакет:
Чтобы научить behat работать с браузером, нам понадобится его расширение Mink, а также бридж для работы с конкретным вендором (в нашем случае это Selenium). Полный список вендоров вы сможете найти на страничке Mink. С учетом версий, ваш composer.json должен выглядеть примерно так:
После установки у вас появится vendor/bin/behat файл, ответственный за запуск тестов. Если vendor/bin/behat --version показало вам установленную версию, то с высокой долей вероятности установка прошла успешно :)
Завершающей фазой является конфигурация
Файлы сценариев или (*.feature файлы) — yml файлы, написанные на псевдо-языке Gherkin, содержат, по сути, набор пошаговых инструкций, которые выполнит ваш браузер в ходе исполнения конкретного сьюта. Подробнее о синтаксисе вы можете узнать, перейдя по ссылке выше.
Каждая такая «инструкция» в свою очередь матчится на методы класса «контекста» с помощью регулярных выражений, указанных в аннотациях класса. Behat\MinkExtension\Context\MinkContext
Имена самих методов роли не играют, хотя хорошим тоном будет придерживаться аналогичного аннотациям именования в CamelCase.
Если вам не хватает доступных по умолчанию конструкций Gherkin, вы можете расширить функционал в классах наследниках MinkContext правильно указав аннотации. Эту роль и выполняют «контекстные» классы.
2. Установка и настройка окружения
Те из вас, кто уже работал с Selenium знают, что после старта теста, на машине запустится браузер и пройдет шаги, указанные в .feature файле.
Запуск Selenium в Docker немного сложнее. Во-первых вам понадобятся Иксы в контейнере, во-вторых – вам захочется увидеть, что же происходит внутри контейнера.
Ребята из Selenium уже обо всём позаботились и собирать свой контейнер вам не придется. Контейнер со Standalone сервером на борту будет сразу доступен по 5900 порту, куда можно постучаться с любого VNC клиента (например с этого). Внутри контейнера вас встретит приветливый интерфейс Fluxbox с предустановленным Chrome. В моем случае это выглядит так:
Чтобы прийти к успеху, вы можете запустить докер контейнер, согласно инструкции на сайте:
Важный момент, без шаред волюма /dev/shm хрому не хватит памяти и он не сможет запуститься, поэтому не забываем его указать.
В моем случае используется docker-compose, и YAML файл будет выглядеть следующим образом:
Я хочу, чтобы мои тесты заходили на Facebook через VPN, включенный на хост-машине, поэтому важно указать network_mode.
Чтобы запустить контейнер, используя compose, выполним следующую команду:
Теперь пробуем подсоединиться по VNC на localhost:5900 и открыть браузер внутри контейнера. Если вам это удалось и вы видите что-то похожее на скриншот выше — вы прошли этот уровень.
3. От теории к практике. Автоматизируем
В примере, приведенном ниже, я буду доставать всех пользователей Facebook по переданным фамилии и имени. Сценарий будет выглядеть следующим образом:
И соответственно Context класс (констуктор и нэймспейсы опущены)
В методе SearchExntesion::load пробрасывается Сервис SearchController, отвечающий непосредственно за объявление параметров и их прием/обработку.
Если всё объявлено правильно, то список доступных команд behat дополнится новым аргументом --search-by-fullname:
Получив входные данные внутри SearchController, они могут быть переданы в Context классы напрямую, либо сохранены в базе данных и т.д В примере выше я для этого использую Registry паттерн. Подход вполне рабочий, но если вы знаете, как это сделать по-другому, пожалуйста, расскажите в комментариях.
Привет, Хабр! Меня зовут Виталий Котов, я работаю в Badoo, в отделе QA. Большую часть времени занимаюсь автоматизацией тестирования. Недавно я столкнулся с задачей максимально быстро развернуть Selenium-тесты для одного из наших проектов. Условие было простое: код должен лежать в отдельном репозитории и не использовать наработки предыдущих автотестов. Ах, да, и нужно было обойтись без CI. При этом тесты должны были запускаться сразу после изменения кода проекта. Отчёт должен был приходить на почту.
Собственно, опытом такого развёртывания я и решил поделиться. Получился своего рода гайд «Как запустить тесты за пару часов».
Условия задачи
Прежде всего стоит декомпозировать задачу на несколько подзадач. Получается, что наша миссия, если мы возьмемся за её исполнение, заключается в следующем:
- нужен отдельный репозиторий;
- в нём должны лежать тесты;
- в нём должен лежать некий механизм, который будет запускать тесты по изменению кода проекта;
- отчёт должен быть читаемым, удобным и приходить на почту указанным людям.
В Badoo первые Selenium-тесты были написаны на PHP на основе фреймворка PHPUnit. Сервер Badoo по большей части написан на PHP и к моменту, когда появилась автоматизация, было решено не плодить технологии.
Для работы с Selenium тогда был выбран фреймворк от Facebook, но в какой-то момент мы так увлеклись добавлением туда своего функционала, что наша версия перестала быть совместимой с их.
Поскольку задача была срочная, я решил не экспериментировать с технологиями. Разве что выбрал фреймворк Facebook последней версии — интересно было, что там новенького.
Я скачал composer, с помощью которого собирать такой проект мне показалось удобнее:
Файл composer.json выглядел тогда так:
Класс MyTestCase
Первое, что требовалось сделать, — это написать свой TestCase-класс:
В нём появились функции setUp и tearDown, которые создавали и убивали Selenium-сессию, и функция onNotSuccessfulTest, которая обрабатывала данные упавшего теста:
В setUp всё довольно просто: мы создаём сессию, указав URL Selenium-фермы и желаемые capabilities. На этом этапе меня интересовал только браузер, на котором мы собирались гонять тесты.
C tearDown всё несколько хитрее.
Суть вот в чем. Для упавшего теста tearDown выполняется до того, как выполнится onNotSuccessfulTest. Следовательно, если мы хотим закрывать сессию в tearDown, все необходимые данные из неё стоит получить заблаговременно: текущая локация, скриншот и HTML-слепок, значения cookie и прочее. Все эти данные потребуются нам для формирования красивого и понятного отчёта.
Собирать данные, соответственно, следует только для упавших тестов, помня о том, что tearDown будет вызываться для всех тестов, включая успешно прошедшие, skipped и incomplete.
Сделать это можно как-то так:
Класс ArtifactsHelper, как нетрудно догадаться из названия, помогает собирать артефакты. Но о нём чуть позже. :)
А пока вернёмся к tearDown. В нём мы уже собрали все необходимые данные для упавшего теста, так что можно спокойно закрывать сессию.
Далее следует onNotSuccessfulTest, где нам понадобится ReflectionClass. Выглядит он так:
Класс ArtifactsHelper
Класс довольно простой, так что расскажу о нём очень коротко. Он создаёт файлы, которые называются как упавший тест плюс таймстемп, и помещает их в соответствующую папочку. После прогона всех тестов файлы добавляются в итоговый email с отчётом и удаляются. Выглядит это дело примерно так:
В конструкторе мы создаём нужную директорию, если её нет, и привязываем driver к локальному полю, чтобы было удобнее им пользоваться.
Методы takeLocalScreenshot и takeLocalSource создают файлы со скриншотом (.jpg) и HTML-слепком (.html). Они будут называться именем теста, только мы заменим часть символов на другие, чтобы название файла не смущало файловую систему.
Тесты
Тесты у нас будут наследоваться от MyTestCase. Приводить примеры не буду — всё стандартно. Через $this->driver мы работаем с Selenium, а все assert’ы и прочее выполняем через $this.
Стоит сказать несколько слов про передачу параметров для запуска тестов. PHPUnit не даст при запуске теста из консоли добавить какой-то незнакомый ему параметр. А это было бы очень удобно, например, чтобы иметь возможность задавать желаемый браузер для тестов.
Я решил эту проблему следующим образом: создал папочку bin/ в корне проекта, куда положил исполняемый файл с названием phpunit следующего содержания:
А в классе MyCommand, соответственно, прописал желаемые параметры:
Теперь, если запускать тесты от нашего phpunit-файла, можно задавать параметры, которые будут передаваться в тесты в массив $GLOBALS['argv']. Дальше его можно парсить и как-то обрабатывать.
Запуск по изменению кода проекта
Итак, теперь у нас есть всё для того, чтобы начать запускать тесты по триггеру. К сожалению, репозитория с кодом проекта у нас нет, так что узнать, когда были совершены изменения в нём, не представляется возможным. Без помощи разработчиков тут не обойтись.
Мы договорились, что в тестовом окружении у приложения будет специальный адрес, по которому можно будет увидеть хеш последнего коммита (по сути, версия сайта).
Дальше всё просто: по cron запускаем специальный скриптик раз в пару минут. При первом запуске он идёт при помощи Curl по этому адресу и получает текущую версию сайта. Далее он создаёт в специальной директории файлик version.file, куда пишет эту версию. В следующий раз он получает версию и с сайта, и из файлика; если они отличаются, записывает новую версию в файл и запускает тесты, Если нет — не делает ничего.
В итоге всё выглядит примерно так:
Отправка письма с отчётом
К сожалению, в PHPUnit из класса TestCase невозможно определить, последний ли тест прошёл в сьюте или нет. Конечно, там есть метод tearDownAfterClass, но он выполняется после завершения тестов в одном классе. Если в сьюте указаны, например, два класса с тестами, tearDownAfterClass исполнится дважды.
Мне же нужно было где-то прописать логику, которая будет отправлять письмо гарантированно после прохождения всех тестов. И, конечно, делать это только один раз. Как вы уже догадались, я написал очередной хелпер. :)
Класс Mailer
Этот класс хранит в себе информацию о прошедших тестах: тексты ошибок, пути до файла со скриншотом и HTML-слепком. Он сделан по принципу Singleton, инстанцируется единожды при первом вызове. И не уничтожается принудительно. Понимаете, к чему я веду? :)
Всё верно, логику отправки письма я добавил в деструктор. Когда процесс прогона тестов завершается, приходит сборщик мусора и уничтожает мой класс. Следовательно, деструктор срабатывает в самый последний момент.
В зависимости от того, прошли тесты успешно или нет, меняется заголовок письма. Если версия сайта менялась в течение прогона, тесты запускаются повторно.
Автопул тестов
Ну и напоследок немного удобства. Так как вся эта система будет жить где-то на удалённом сервере, было бы удобно, если бы она сама умела делать git pull, чтобы случайно не забыть подмёржить важные изменения в тестах.
Для этого создаём исполняемый файлик следующего содержания:
Скрипт исполнит команду git pull, и, если что-то пойдёт не так и ему это не удастся, напишет письмо ответственному сотруднику.
Дальше добавляем скрипт в cron, запуская раз в пару минут, — и дело в шляпе.
Итоги
Итоги обычно подводят с оглядкой на изначальную задачу. Вот что у нас получается:
- появился отдельный репозиторий;
- там при помощи сomposer мы собрали проект: скачали PHPUnit и фреймворк Facebook;
- написали свой TestCase-класс, который умеет генерить удобные отчёты;
- написали тесты, которые можно запускать в разных браузерах и с разными параметрами;
- создали механизм, который будет запускать эти тесты при изменении версии тестируемого проекта;
- позаботились об отправке письма с отчётом и скриншотами;
- добавили скрипт, который автоматически всё это дело обновляет до нужной версии.
Такая вот история. Спасибо за внимание! Буду рад услышать ваши истории, пишите в комментариях. :)
php-webdriver – Selenium WebDriver bindings for PHP
Php-webdriver library is PHP language binding for Selenium WebDriver, which allows you to control web browsers from PHP.
This library is compatible with Selenium server version 2.x, 3.x and 4.x.
The library supports JsonWireProtocol and also implements experimental support of W3C WebDriver. The W3C WebDriver support is not yet full-featured, however it should allow to control Firefox via Geckodriver and new versions of Chrome and Chromedriver with just a slight limitations.
Installation is possible using Composer.
If you don't already use Composer, you can download the composer.phar binary:
Then install the library:
Upgrade from version
Starting from version 1.8.0, the project has been renamed from facebook/php-webdriver to php-webdriver/webdriver .
In order to receive the new version and future updates, you need to rename it in your composer.json:
and run composer update .
1. Start server (aka. remote end)
To control a browser, you need to start a remote end (server), which will listen to the commands sent from this library and will execute them in the respective browser.
This could be Selenium standalone server, but for local development, you can send them directly to so-called "browser driver" like Chromedriver or Geckodriver.
📙 Below you will find a simple example. Make sure to read our wiki for more information on Chrome/Chromedriver.
Install the latest Chrome and Chromedriver. Make sure to have a compatible version of Chromedriver and Chrome!
Run chromedriver binary, you can pass port argument, so that it listens on port 4444:
📙 Below you will find a simple example. Make sure to read our wiki for more information on Firefox/Geckodriver.
Install the latest Firefox and Geckodriver. Make sure to have a compatible version of Geckodriver and Firefox!
Run geckodriver binary (it start to listen on port 4444 by default):
c) Selenium standalone server
Selenium server can be useful when you need to execute multiple tests at once, when you run tests in several different browsers (like on your CI server), or when you need to distribute tests amongst several machines in grid mode (where one Selenium server acts as a hub, and others connect to it as nodes).
Selenium server then act like a proxy and takes care of distributing commands to the respective nodes.
The latest version can be found on the Selenium download page.
Selenium server could also be started inside Docker container - see docker-selenium project.
2. Create a Browser Session
When creating a browser session, be sure to pass the url of your running server.
Now you can start browser of your choice:
3. Customize Desired Capabilities
Desired capabilities define properties of the browser you are about to start.
They can be customized:
Capabilities can also be used to 📙 configure a proxy server which the browser should use.
To configure browser-specific capabilities, you may use 📙 ChromeOptions or 📙 FirefoxOptions.
4. Control your browser
See example.php for full example scenario. Visit our GitHub wiki for 📙 php-webdriver command reference and further examples.
NOTE: Above snippets are not intended to be a working example by simply copy-pasting. See example.php for a working example.
For latest changes see CHANGELOG.md file.
Some basic usage example is provided in example.php file.
How-tos are provided right here in 📙 our GitHub wiki.
You may also want to check out the Selenium project docs and wiki.
Testing framework integration
To take advantage of automatized testing you may want to integrate php-webdriver to your testing framework. There are some projects already providing this:
-
uses php-webdriver and integrates with PHPUnit using PantherTestCase is another project using php-webdriver, could be used for testing via DuskTestCase integrates php-webdriver directly to PHPUnit, and provides parallelization testing framework provides BDD-layer on top of php-webdriver in its WebDriver module
- You can also check out this blogpost + demo project, describing simple PHPUnit integration
We have a great community willing to help you!
❓ Do you have a question, idea or some general feedback? Visit our Discussions page. (Alternatively, you can look for many answered questions also on StackOverflow).
🐛 Something isn't working, and you want to report a bug? Submit it here as a new issue.
📙 Looking for a how-to or reference documentation? See our wiki.
We love to have your help to make php-webdriver better. See CONTRIBUTING.md for more information about contributing and developing php-webdriver.
Php-webdriver is community project - if you want to join the effort with maintaining and developing this library, the best is to look on issues marked with "help wanted" label. Let us know in the issue comments if you want to contribute and if you want any guidance, and we will be delighted to help you to prepare your pull request.
About
PHP client for Selenium/WebDriver protocol. Previously facebook/php-webdriver
Информации по автоматизации тестирования через браузер в русскоязычном сегменте интернета не так много как хотелось бы, поэтому я решил внести свою небольшую лепту, благо как раз понадобилось решить практическую задачу на эту тему. В этой небольшой статье мы рассмотрим простую задачу — как сделать полный скриншот вебстраницы, предварительно выполнив с ней некоторые действия, например, раскрыв свернутые блоки.
Из инструментария нам понадобится:
Уже скачали SeleniumHQ сервер? SeleniumHQ сервер это java-приложение, поэтому чтобы он запустился вам нужна Java (установите при необходимости). Скачанный файл будет называться типа “selenium-server-standalone-3.13.0.jar”. Он не требует установки, этот файл это и есть сама программа. Чтобы запустить SeleniumHQ сервер выполните команду:
Путь, конечно же, может отличаться, в зависимости от того в какой папке у вас будет размещаться selenium-server-standalone-3.13.0.jar.
Если вы пользуетесь Safari 10+, то достаточно выбрать в меню Develop > Allow Remote Automation. Также проверьте наличие драйвера, путь к исполняемому файлу “/usr/bin/safaridriver”. Если у вас другой браузер — скачайте и установите соответствующий драйвер.
Теперь нужно заполучить Facebook WebDriver. Для этого выполните в папке будущего проекта команду:
да, у вас должен быть установлен Composer.
Можно проверить, работает ли наша конфигурация, набрав какой-нибудь простой код:
В принципе, ничего сложного. Единственное, из-за чего работа с Facebook WebDriver может показаться сложной, это обилие доступных к использованию классов и методов, в таком ассортименте, что не знаешь куда смотреть. Благо, есть документация. Но самым лучшим путем к изучению будет поставить перед собой реальную задачу и решать ее, параллельно подбирая нужные методы и находя возможности. Так, для примера рассмотрим более сложную задачу. Мне понадобилось сделать скриншот веб-страницы, предварительно развернув на ней скрытые блоки текста:
Чтобы блок текста раскрылся, нужно щелкнуть по нему мышкой. Это мы и будем эмулировать с помощью WebDriver и Selenium.
Пример мы рассмотрели далеко не самый сложный, но и здесь мне пришлось поэкспериментировать, пока я не пришел к выводу, что перед использованием click() надо сделать sendKeys(). Также обратите внимание, если findElement() не находит элемента по условию поиска, она генерирует исключение, поэтому очень желательно помещать findElement() в блок try-catch. В следующей статье рассмотрим задачу посерьезнее.
Читайте также: