Selenium Grid error on GitLab CI: Error forwarding the new session Empty pool of VM for setup Capabilities
Asked Answered
V

2

9

Since documentation on GitLab CI configuration and Selenium is generally poor, I'm asking for help.

Configuration as by interest point:

gitlab.ci.yml:

image: node:7

variables:
  HUB_PORT_4444_TCP_ADDR: "selenium__hub"
  HUB_PORT_4444_TCP_PORT: "4444"

services:
  - selenium/hub:latest
  - selenium/node-phantomjs:latest

stages:
  - test

test:
  stage: test
  before_script:
    - apt-get update
    - apt-get install -y default-jdk default-jre
    - npm install -s -g @angular/[email protected]
    - npm install -s
    - node ./node_modules/protractor/bin/webdriver-manager update
  script:
    - ./node_modules/.bin/protractor protractor.ci.conf.js

protractor.ci.conf.js:

/*global jasmine */
const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {
  allScriptsTimeout: 11000,
  specs: [
    './e2e/**/*.e2e-spec.ts'
  ],
  capabilities: {
    'browserName': 'phantomjs',
    'phantomjs.binary.path': './node_modules/phantomjs-prebuilt/bin/phantomjs'
  },
  directConnect: false,
  baseUrl: 'http://localhost:4200/',
  framework: 'jasmine',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    print: function() {}
  },
  beforeLaunch: function() {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },
  onPrepare: function() {
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
  },
  seleniumAddress: 'http://selenium__hub:4444/wd/hub'
};

With the above configuration, GitLab fails with:

$ ./node_modules/.bin/protractor protractor.ci.conf.js
(node:3702) DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
[09:53:27] I/launcher - Running 1 instances of WebDriver
[09:53:27] I/hosted - Using the selenium server at http://selenium__hub:4444/wd/hub
[09:53:28] E/launcher - Error forwarding the new session Empty pool of VM for setup Capabilities [{phantomjs.binary.path=./node_modules/phantomjs-prebuilt/bin/phantomjs, count=1, browserName=phantomjs}]
[09:53:28] E/launcher - WebDriverError: Error forwarding the new session Empty pool of VM for setup Capabilities [{phantomjs.binary.path=./node_modules/phantomjs-prebuilt/bin/phantomjs, count=1, browserName=phantomjs}]
    at Object.checkLegacyResponse (/builds/netaachen/operator-app/node_modules/selenium-webdriver/lib/error.js:505:15)
    at parseHttpResponse (/builds/netaachen/operator-app/node_modules/selenium-webdriver/lib/http.js:509:13)
    at doSend.then.response (/builds/netaachen/operator-app/node_modules/selenium-webdriver/lib/http.js:440:13)
    at process._tickCallback (internal/process/next_tick.js:109:7)
From: Task: WebDriver.createSession()
    at Function.createSession (/builds/netaachen/operator-app/node_modules/selenium-webdriver/lib/webdriver.js:777:24)
    at createDriver (/builds/netaachen/operator-app/node_modules/selenium-webdriver/index.js:167:33)
    at Builder.build (/builds/netaachen/operator-app/node_modules/selenium-webdriver/index.js:632:14)
    at Hosted.getNewDriver (/builds/netaachen/operator-app/node_modules/protractor/lib/driverProviders/driverProvider.ts:60:29)
    at Runner.createBrowser (/builds/netaachen/operator-app/node_modules/protractor/lib/runner.ts:225:39)
    at q.then.then (/builds/netaachen/operator-app/node_modules/protractor/lib/runner.ts:391:27)
    at _fulfilled (/builds/netaachen/operator-app/node_modules/protractor/node_modules/q/q.js:834:54)
    at self.promiseDispatch.done (/builds/netaachen/operator-app/node_modules/protractor/node_modules/q/q.js:863:30)
    at Promise.promise.promiseDispatch (/builds/netaachen/operator-app/node_modules/protractor/node_modules/q/q.js:796:13)
    at /builds/netaachen/operator-app/node_modules/protractor/node_modules/q/q.js:556:49
[09:53:28] E/launcher - Process exited with error code 199
ERROR: Build failed: exit code 1
Vocalise answered 30/5, 2017 at 12:3 Comment(4)
Cool, what is your question? :PTorrie
Sorry for not posing the question as obviously and leaving it to the title. I've included the failure stack now.Vocalise
should base_url port be the same as the hub port? also, this might be useful to you github.com/angular/protractor/issues/1226Immortalize
@nivesnine, it changed the result to protractor - Could not find Angular on page http://selenium__standalone-chrome:4444/ : retries looking for angular exceeded. The problem does not relate to the page not having angular since e2e tests pass locally with the local protactor configuration (baseUrl set to localhost:4200).Vocalise
V
2

The key is to use Xvfb on GitLab CI. That spins up the display so --headless Chrome can run the specs.

I wrapped more info and chunks of code into the blog post of How to run AngularJS end-to-end tests on GitLab CI.

Vocalise answered 13/12, 2017 at 22:19 Comment(0)
P
1

I have neved used Gitlab CI but have Selenium experience. So let me first describe some important considerations:

  1. An error you receive means that there's no requested browser in the hub. This is probably because PhantomJS did not manage to register.
  2. You don't need to install neither Java nor Selenium server to work with PhantomJS. It is a standalone binary implementing itself Selenium protocol. So in order to work with PhantomJS - just start container with PhantomJS. For example I would use this one: selenoid/phantomjs:2.1.1 (build file is here) - it just runs phantomjs --webdriver=4444. PhantomJS by default listens on port 8910 but because of command above we can still use 4444.
  3. I think you also don't need to use webdriver-manager which is a Javascript tool to download Selenium server or webdriver binaries. This is not needed to work with PhantomJS.
  4. Not sure why environment variables like HUB_PORT_4444_TCP_ADDR were added. So I would remove them all.

Having said that let's try to modify your files.

gitlab-ci.yml becomes:

image: node:7

services:
  - selenoid/phantomjs:2.1.1

stages:
  - test

test:
  stage: test
  before_script:
    - npm install -s -g @angular/[email protected]
    - npm install -s
  script:
    - ./node_modules/.bin/protractor protractor.ci.conf.js

protractor.ci.conf.js becomes (only changed container name in seleniumAddress):

/*global jasmine */
const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {
  allScriptsTimeout: 11000,
  specs: [
    './e2e/**/*.e2e-spec.ts'
  ],
  capabilities: {
    'browserName': 'phantomjs',
    'phantomjs.binary.path': './node_modules/phantomjs-prebuilt/bin/phantomjs'
  },
  directConnect: false,
  baseUrl: 'http://localhost:4200/',
  framework: 'jasmine',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    print: function() {}
  },
  beforeLaunch: function() {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },
  onPrepare: function() {
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
  },
  seleniumAddress: 'http://selenoid__phantomjs:4444/wd/hub'
};

Not sure what is baseUrl - seems to be some Protractor stuff, so I think don't need to change. Please ask more questions if any.

Plainclothesman answered 9/6, 2017 at 15:33 Comment(7)
The above configuration is flawed due to following reasons: a) browsers.json is missing for selenoid as documented at github.com/aerokube/selenoid b) aerokube/selenoid:2.1.1 does not exist, the highest tag currently is 1.3.2. When fixed to 1.3.2, selenoid will fail to launch with 2017-06-20T09:21:56.661951157Z 2017/06/20 09:21:56 /usr/bin/selenoid: browsers config: read error: open /etc/selenoid/browsers.json: no such file or directory.Vocalise
My error - needs to be selenoid/phantomjs:2.1.1, updated. You don't need Selenoid itself - just start container with Phantomjs.Plainclothesman
Thanks for the update. I've tried that, runs the specs but fails with Failed: waiting for page to load for 10000ms, so clearly failing to load the page from localhost:4200 :(Vocalise
Since Protractor 5 doesn't support PhantomJS any more, I also tried downgrading Protractor to 4.0.14, but unfortunately without luck, it still times out. Looks like baseUrl is really the key problem here.Vocalise
I think this is because localhost in container and localhost:4200 are two different things. You application under test starts somewhere outside Docker container and PhantomJS goes to localhost inside container - this is why it fails. So I think the solution is to reference baseUrl like http://build__container:4200, where build__container - is either some predefined alias for container where tests are run or host machine IP address if tests are run there.Plainclothesman
GitLab has a convention that in the circumstances converts service to selenoid__phantomjs as you quite rightly denoted in your example, but it is not worknig. http://selenoid__phantomjs:4200 times out as well as http://selenoid__phantomjs:4444.Vocalise
Your tests start another server listening on port 4200 somewhere outside this container - this is why it does not work. You need to find how to access the tests container - not the PhantomJS one.Plainclothesman

© 2022 - 2024 — McMap. All rights reserved.