GitLab CI 上的 Selenium Grid 错误:转发新会话时出错 用于设置功能的 VM 空池

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

由于关于 GitLab CI 配置和 Selenium 的文档通常很差,我正在寻求帮助。

按兴趣点配置:

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/cli@1.0.6
    - 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'
};

使用上述配置,GitLab 失败并显示:

$ ./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

我从未使用过 Gitlab CI 但有 Selenium 经验。所以让我首先描述一些重要的考虑因素:

  1. 您收到的错误意味着中心中没有请求的浏览器。这可能是因为 PhantomJS 没有成功注册。
  2. 您无需安装 Java 或 Selenium 服务器即可使用 PhantomJS。它是一个独立的二进制文件,实现了 Selenium 协议。因此,为了与 PhantomJS 一起工作 - 只需使用 PhantomJS 启动容器。例如,我会使用这个:selenoid/phantomjs:2.1.1(构建文件是 here)——它只运行 phantomjs --webdriver=4444。 PhantomJS 默认侦听端口 8910 但由于上面的命令我们仍然可以使用 4444.
  3. 我认为您也不需要使用 webdriver-manager 这是一个 Java 脚本工具来下载 Selenium 服务器或 webdriver 二进制文件。这不需要使用 PhantomJS。
  4. 不确定为什么要添加 HUB_PORT_4444_TCP_ADDR 等环境变量。所以我会把它们全部删除。

话虽如此,让我们尝试修改您的文件。

gitlab-ci.yml 变为:

image: node:7

services:
  - selenoid/phantomjs:2.1.1

stages:
  - test

test:
  stage: test
  before_script:
    - npm install -s -g @angular/cli@1.0.6
    - npm install -s
  script:
    - ./node_modules/.bin/protractor protractor.ci.conf.js

protractor.ci.conf.js 变为(仅在 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'
};

不确定什么是 baseUrl - 似乎是 Protractor 的东西,所以我认为不需要更改。有问题请多多提问

关键是在 GitLab CI 上使用 Xvfb。这会旋转显示屏,因此 --headless Chrome 可以 运行 规格。

我将更多信息和代码块打包到 How to run AngularJS end-to-end tests on GitLab CI 的博客 post 中。