Run Angular Protractor tests via Azure Hosted Agent Chromedriver

Viewed 577

My team is trying to improve the reliability of our E2E tests in our Azure DevOps pipelines as it relates to chrome updates. Currently we set the needed chrome driver version as a parameter in our yaml pipeline and then use that variable during our webdriver-manager update step

parameters:
    chromeDriverVersion: 83.0.4103.39
...
script: './node_modules/protractor/bin/webdriver-manager update --versions.chrome=${{parameters.chromeDriverVersion}} 

This works fine, except we have to update the version every time Chrome is updated on the Azure Hosted Agent. While looking at the Agent Capabilities I noticed that "CHROMEWEBDRIVER" is available via an ENV variable. So this got me thinking, shouldn't we just be able to use the installed Chrome driver which is presumably kept in sync with the installed version of Chrome? I know that there is a "chromeDriver" param in the protractor config that according to the Protractor docs takes the path to an installed Chrome driver. I've added it to my protractor config like so:

chromeDriver: process.env.CHROMEWEBDRIVER ? process.env.CHROMEWEBDRIVER : null,

This seems to "work" in the sense that it tries to start the webdriver, but it fails with:

E/launcher - Process exited with error code 199

Not particularly helpful and it seems to be a common error code that I can see lots of other people having issues with but not in this context.

I have also tried getting the version of the installed Chrome driver using:

$(CHROMEWEBDRIVER --version)

And then using that version number to just install the correct version via my scripting step listed above, but this did not work because the version is not just the version number but also includes other info (ex: HeadlessChrome/83.0.4103.61). Additionally I tried several permutations on the CHROMEWEBDRIVER variable, adding a leading '.', adding a trailing '.exe', etc and all of these result in the error "Could not find chromedriver at ...", which leads me to believe my protractor config approach is at least getting the right path, since it gets past this step and then fails.

TL;DR

Trying to make cloud based e2e tests more robust, but when using the chrome driver installed on the azure agent via protractor config it errors out with code 199.

Full protractor config

exports.config = {
  SELENIUM_PROMISE_MANAGER: false,
  useAllAngular2AppRoots: true,
  allScriptsTimeout: 31000,
  specs: [
    '../src/features/**/*.feature'
  ],
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: {
        '--headless',
        '--disable-gpu',
        '--window-size=1400,740',
        '--no-sandbox'
      }
    }
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'custom',
  frameworkPath: require.resolve("protractor-cucumber-framework"),
  cucumberOpts: {
    strict: true,
    format: ["json:./e2e/reports/json/cucumber_report.json"],
    require: ["../src/features/**/*.ts", "../src/support/*.ts"],
  },
  chromeDriver: process.env.CHROMEWEBDRIVER ? process.env.CHROMEWEBDRIVER : null,
};
3 Answers

The issue is that CHROMEWEBDRIVER environment variable contains a path to directory (take a look at sources), but chromeDriver expects a file path.

So you should do it like this (for linux)

chromeDriver: process.env.CHROMEWEBDRIVER ? require('path').join(process.env.CHROMEWEBDRIVER, 'chromedriver') : null,

or, if you want cross-platform compatibility (windows/linux) you can introduce a variable

const chromeDriverFileName = process.env.OS === 'Windows_NT' ? 'chromedriver.exe' : 'chromedriver';
...
chromeDriver: process.env.CHROMEWEBDRIVER ? require('path').join(process.env.CHROMEWEBDRIVER, chromeDriverFileName) : null,

Just configured it for my project, seems to work fine.

Try removing the chromeDriver attribute from your protractor.conf.js and then running this command before you start your tests:

npx webdriver-manager update

This is what ive been using to keep the chrome driver that protractor uses updated. npx is an npm utility that basically allows you to update a dependency (protractor) of a dependecy (webdriver-manager)

I've finally managed to run the Protractor tests with the Chrome version that is currently installed on the hosted agent by using a Powershell script. Maybe this might help you or other readers to achieve the same.

It first gets the version of the Chrome that is installed on the agent and uses this version to download & install the Webdriver.

It looks like you are using Angular. In this case it is important to note that in the final step, to run the e2e script you have to pass in an argument --webdriver-update=false otherwise it will update the Webdriver again to the newest version, which could be different from the version installed on the agent.

Here is the code, you can use it in a Powershell task:

$ver = ((Get-Item "C:\Program Files\Google\Chrome\Application\chrome.exe").VersionInfo).ProductVersion
echo "Chrome version: "
echo $ver
npx webdriver-manager update --versions.chrome $ver
npx ng e2e --webdriver-update=false

P.S. This only works on Windows based agents

P.S.S. I didn't need to specify the chromeDriver in the protractor config, it automatically takes the webdriver that is installed with the webdriver-manager

Related