Problem, Solution, Implementation & Showcase
We need to run browser UI tests with codeception. However these test are features requiring browser extensions. At this time there is no clear documentation for enabling said extensions on codeception with selenium.
In summary, we need for the codeception to install browse extenion(s) when it initializes browsers.
The Solution
In order to install a chrome extension we need to get it’s source code from the Chrome store, and load it through a yaml configuration file in codeception.
Similarly for firefox, we just need to extract the extension (xpi). However, the geckodriver does not accept arguments like chrome above for loading an extension. Also loading a firefox_profile does not currently work [source_here]. As such we’ll need to build a codeception module, and load the extension there.
The Implementation
You can find a solid template installing extension in codeception at our repo rdok/installing-browser-extension-in-codeception This repo also contains installation scripts which will autodownload all required files for our tests: selenium-server-standalone.jar, chromedriver, geckodriver, as well as the two extensions we install. When executing the composer install
command.
If you already know setting up codeception and environements, feel free to skip the rest of the blog and just check the above repository.
Following are descriptions of what I believe to be the major difficulties when instructing codeception to install browser extensions.
Install chrome extension
Download the extension you are interested in. Here’s the way we do it on repo.
adBlockerFile="./tests/_data/adBlock"
adBlockerId=gighmmpiobklfepjocnamgkkbiglidom
mkdir -p $adBlockerFile
wget "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$adBlockerId%26uc" -O "$adBlockerId.zip"
unzip -d $adBlockerFile "$adBlockerId.zip"
rm -f $adBlockerId.zip
Instruct codeception to add arguments to load the extension directory when initializing the chrome driver.
modules:
enabled:
- \Helper\ChromeHelper
config:
\Helper\ChromeHelper:
browser: 'chrome'
url: 'http://www.detectadblock.com/'
capabilities:
chromeOptions:
args:
- 'load-extension=tests/_data/adBlock'
\Helper\Chrome
is a custom codeception module extending the WebDriver module. It is a workaround for an issue with firefox to open a new tab, rather a new window.
Install Firefox Extension
Download the extension you are interested in. Here’s the way we do it in our repo.
wget "https://addons.mozilla.org/firefox/downloads/latest/adblock-plus/addon-1865-latest.xpi" -O "adblocker.xpi"
Instruct codeception to load our own custom FirefoxHelper.
modules:
enabled:
- \Helper\FirefoxHelper
config:
\Helper\FirefoxHelper:
browser: 'firefox'
url: 'http://www.detectadblock.com/'
Currently loading a firefox profile, does not work in codeception. This issue seems to be have been persisted from 2016 Firefox Profile Not Working Properly for Selenium Webdriver #2690
As such, we override the codeception’s initialization of the WebDriver command with our own custom FirefoxHelper:
public function _initialize()
{
parent::_initialize();
$profile = new FirefoxProfile();
$profile->addExtension('tests/_data/adblock-plus.xpi');
$capabilities = DesiredCapabilities::firefox();
$capabilities->setCapability(FirefoxDriver::PROFILE, $profile);
$this->capabilities = $capabilities;
}
Conclusion
- The browser installation scripts are quite handy, as every time we execute the
composer install
command it will upgrade the browser extension. Thus we do not need to manually redownload them in the log term future. - I might setup a docker in the future. This should make the development independent. As it is now, the repo can test drived only by Linux OS Desktops.
Finally, here’s the overall steps you’ll need to take for setting up the repo in your Linux Desktop
git clone https://github.com/rdok/installing-browser-extension-in-codeception
cd installing-browser-extension-in-codeception
composer install
java -jar selenium-server-standalone*
./vendor/bin/codecept run --env chrome
./vendor/bin/codecept run --env firefox