javascript Karma Chrome Headless 不适用于 Jenkins

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50526682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:09:21  来源:igfitidea点击:

Karma Chrome Headless not working on Jenkins

javascriptdockerjenkinskarma-runner

提问by STEEL

When I run the below setup with Docker locally on my mac everything works fine.

当我在 Mac 本地使用 Docker 运行以下设置时,一切正常。

But same setup does not work on Jenkins running on Ubuntu 16.04

但是相同的设置不适用于在 Ubuntu 16.04 上运行的 Jenkins

ChromiumHeadless have not captured in 60000 ms, killing.

ChromiumHeadless 在 60000 ms 内没有捕获,杀死。

Following error log is from Jenkins console:

以下错误日志来自Jenkins 控制台:

25 05 2018 06:35:09.076:INFO [karma]: Karma v2.0.2 server started at http://0.0.0.0:9222/
25 05 2018 06:35:09.079:INFO [launcher]: Launching browser Chromium_no_sandbox with unlimited concurrency
25 05 2018 06:35:09.090:INFO [launcher]: Starting browser ChromiumHeadless
25 05 2018 06:36:09.128:WARN [launcher]: ChromiumHeadless have not captured in 60000 ms, killing.
25 05 2018 06:36:09.139:INFO [launcher]: Trying to start ChromiumHeadless again (1/2).
25 05 2018 06:37:09.140:WARN [launcher]: ChromiumHeadless have not captured in 60000 ms, killing.
25 05 2018 06:37:09.147:INFO [launcher]: Trying to start ChromiumHeadless again (2/2).

Package.json... "testProd": "./node_modules/karma/bin/karma start karma.conf-prod.js --single-run",

包.json... "testProd": "./node_modules/karma/bin/karma start karma.conf-prod.js --single-run",

Dockerfile

文件

FROM zenika/alpine-node:latest
LABEL name="product-web"

# Update apk repositories
RUN echo "http://dl-2.alpinelinux.org/alpine/edge/main" > /etc/apk/repositories
RUN echo "http://dl-2.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
RUN echo "http://dl-2.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories

# Install chromium
RUN apk -U --no-cache \
    --allow-untrusted add \
    zlib-dev \
    chromium \
    xvfb \
    wait4ports \
    xorg-server \
    dbus \
    ttf-freefont \
    mesa-dri-swrast \
    grep \
    udev \
    && apk del --purge --force linux-headers binutils-gold gnupg zlib-dev libc-utils \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/* \
    /usr/lib/node_modules/npm/man \
    /usr/lib/node_modules/npm/doc \
    /usr/lib/node_modules/npm/html \
    /usr/lib/node_modules/npm/scripts

WORKDIR /home/dev/code
COPY . .

#RUN rm -rf node_modules && npm cache clear --force

ENV CHROME_BIN=/usr/bin/chromium-browser
ENV CHROME_PATH=/usr/lib/chromium/

RUN npm install
RUN npm run testProd && npm run buildProd

karma.conf-prod.js

karma.conf-prod.js

const path = require('path');
module.exports = function(config) {
    config.set({
        basePath: '',
        browsers: ['ChromeHeadlessNoSandbox'],
    customLaunchers: {
        ChromeHeadlessNoSandbox: {
            base: 'ChromeHeadless',
            flags: [
                '--no-sandbox',
                '--user-data-dir=/tmp/chrome-test-profile',
                '--disable-web-security'
            ]
        }
    },
        frameworks: ['mocha', 'chai'],
        captureConsole: true,
        files: [
            'node_modules/babel-polyfill/dist/polyfill.js',
            'test/root.js'
        ],
        preprocessors: {
            'src/index.js': ['webpack', 'sourcemap'],
            'test/root.js': ['webpack']
        },
        webpack: {
            devtool: 'inline-source-map',
            module: {
                loaders: [
                    {
                        test: /\.js$/,
                        loader: 'babel-loader',
                        exclude: path.resolve(__dirname, 'node_modules'),
                        query: {
                            plugins: ['transform-decorators-legacy', 'transform-regenerator'],
                            presets: ['env', 'stage-1', 'react']
                        }
                    },
                    {
                        test: /\.json$/,
                        loader: 'json-loader',
                    },
                ]
            },
            externals: {
                'react/addons': true,
                'react/lib/ExecutionEnvironment': true,
                'react/lib/ReactContext': true
            }
        },
        webpackServer: {
            noInfo: true
        },
        reporters: ['spec'],
        port: 9222,
        logLevel: config.LOG_INFO
    });
};

I even tried with logLevel: config.LOG_DEBUGbut did not show anything missing or unusual.

我什至尝试过,logLevel: config.LOG_DEBUG但没有显示任何遗漏或异常。

采纳答案by STEEL

The issue was with the jenkin's xbmcdisplay driver .

问题出在 jenkin 的xbmc显示驱动程序上。

I fixed it by switching to Travic-CI

我通过切换到 Travic-CI 修复了它

before_install: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - sleep 3

回答by Kiran Shahi

Based on issue Karma 1.6 breaks Headless support for Chromecreated on github, it is related to the slower machine and happens, because it took > 60 seconds before test bundle was parsed and executed by Chrome and therefore test run was started and communicated back to Karma server. Reasons why it may take long vary.

基于问题 Karma 1.6 打破了对在github 上创建的 Chrome 的无头支持,这与较慢的机器有关并且发生了,因为在 Chrome 解析和执行测试包之前花费了 > 60 秒,因此测试运行开始并返回给 Karma服务器。可能需要很长时间的原因各不相同。

There are 2 ways to handle timeout:

有两种处理超时的方法:

Investigate why your test bundle loads >60 seconds and make sure it loads faster.

调查为什么你的测试包加载超过 60 秒并确保它加载得更快。

  1. Increase browserNoActivityTimeoutto highter value, so test bundle has enough time to load.
  2. This particular appearance of timeout does not seem to be a Karma issue, but rather problem in the project or misconfiguration.
  1. browserNoActivityTimeout增加到更高的值,以便测试包有足够的时间来加载。
  2. 超时的这种特殊外观似乎不是 Karma 问题,而是项目中的问题或配置错误。

Based on the Derek'scomment

基于德里克的评论

There was a connection that was disconnecting too soon.

有一个连接断开过快。

He found that in /static/karma.js, when the socket was created, there was a timeout value that is hardcoded to 2 seconds (see below). He just added another 0 to make it 20 seconds and the connection stayed open long enough for the server to respond to the initial request. karma/client/main.js

他发现在 /static/karma.js 中,当创建套接字时,有一个硬编码为 2 秒的超时值(见下文)。他只是添加了另一个 0 使其为 20 秒,并且连接保持打开足够长的时间以使服务器响应初始请求。业力/客户端/main.js

Lines 14 to 20 in e79463b

e79463b 中的第 14 至 20 行

var socket = io(location.host, { 
   reconnectionDelay: 500, 
   reconnectionDelayMax: Infinity, 
   timeout: 2000, 
   path: KARMA_PROXY_PATH + KARMA_URL_ROOT.substr(1) + 'socket.io', 
   'sync disconnect on unload': true 
 }) 

The next problem he faced was that Karma thought there was no activity even though there was traffic going back and forth on the socket. To fix that he just added browserNoActivityTimeout: 60000 to the Karma configuration.

他面临的下一个问题是 Karma 认为即使套接字上有流量来回也没有活动。为了解决这个问题,他刚刚在 Karma 配置中添加了 browserNoActivityTimeout: 60000。

You need to change the timeout configuration more then that is in the configuration file.

您需要更改配置文件中的超时配置。

回答by drordk

had the same issue "ChromHeadless have not captured in 60000 ms" (failing after 3 attempts), on Jenkinsrunning on RHEL 7.5. Tried several configurations, and eventually adding the --proxy-bypass-list, and --proxy-servermade it work.

在运行RHEL 7.5 的Jenkins上遇到了同样的问题“ ChromHeadless 没有在 60000 毫秒内捕获”(3 次尝试后失败)。尝试了几种配置,最终添加了--proxy-bypass-list,并且--proxy-server使它工作。

minimal working configuration

最低工作配置

 browsers: ['HeadlessChrome'],
    customLaunchers:{
      HeadlessChrome:{
        base: 'ChromeHeadless',
        flags: [
          '--no-sandbox',
          '--proxy-bypass-list=*',
          '--proxy-server=\'http://<my org proxy server>:8080\''
       ]
      }
    },

Below you can see a few more options in the config like the one I used. We have two browser configuration, Chrome for day to day dev work where we do want to see the browser open, and a headless chrome for CI/CD tests when building our solution on a Jenkins server.

在下面,您可以在配置中看到更多选项,就像我使用的那样。我们有两个浏览器配置,Chrome 用于我们希望看到浏览器打开的日常开发工作,以及在 Jenkins 服务器上构建我们的解决方案时用于 CI/CD 测试的无头 chrome。

Command line to run it in Jenkins:

在 Jenkins 中运行它的命令行:

npm run test -- -cc -sr --browser HeadlessChrome

In package.jsonwe added a couple of lines to the scriptssection:

package.json 中,我们在脚本部分添加了几行:

 "test": "ng test",
    "test-dev": "ng test --browser Chrome",

karma.conf.js

业力配置文件

 browsers: ['Chrome', 'HeadlessChrome'],
    customLaunchers:{
      HeadlessChrome:{
        base: 'ChromeHeadless',
        flags: [
          '--no-sandbox',
       //   '--remote-debugging-port=9222',
       //   '--enable-logging',
       //   '--user-data-dir=./karma-chrome',
       //   '--v=1',
       //   '--disable-background-timer-throttling',
       //   '--disable-renderer-backgrounding',
          '--proxy-bypass-list=*',
          '--proxy-server=\'http://<my org proxy server>:8080\''
       ]
      }
    },

After the above steps it worked from a shell on the Jenkins machine. However it failed when running as a Jenkins job with Cannot start ChromeHeadless Trying to start ChromeHeadless again (1/2).printed to the console.

在上述步骤之后,它在 Jenkins 机器上的 shell 中工作。但是,在作为 Jenkins 作业运行时失败,无法启动 ChromeHeadless 尝试再次启动 ChromeHeadless (1/2)。打印到控制台。

I compared the env variables, and after a few trial and errors found that XDG_DATA_DIRSenvironment variable exists when logged in a bash shell (where headless chrome tests succeeds), and this variable was not defined in the failing Jenkins job env. So adding it (copied from the shell env | grep XDG_DATA_DIRS) finally solved it. I guess I should check what is the minimal configuration/dirs I should put there, and what is the root cause, but its working now :-)

我比较了 env 变量,经过几次试验和错误后发现XDG_DATA_DIRS环境变量在登录 bash shell(无头 chrome 测试成功的地方)时存在,并且这个变量没有在失败的 Jenkins 作业环境中定义。所以添加它(从shell env | grep XDG_DATA_DIRS 复制)终于解决了它。我想我应该检查我应该放在那里的最小配置/目录是什么,根本原因是什么,但它现在可以工作了:-)

Added the below to the jenkins job just before running the test

在运行测试之前将以下内容添加到 jenkins 作业中

export XDG_DATA_DIRS=/users/<jenkins user e.g. jk1003>/.local/share/flatpak/exports/share/:/var/lib/flatpak/exports/share/:/usr/local/share/:/usr/share/

Another possible solution

另一种可能的解决方案

A friend told me that he solved such an issue long ago using Xvfb

一个朋友告诉我他很早就用Xvfb解决了这个问题

回答by LeOn - Han Li

For me I have to add the chrome local ip/port explicitly to NO_PROXYso that Karmacould capture the browser.

对我来说,我必须显式添加 chrome 本地 ip/端口,NO_PROXY以便Karma可以捕获浏览器。

In the karma.conf.js:

karma.conf.js

process.env.NO_PROXY = 'localhost, 0.0.0.0/4201, 0.0.0.0/9876';
process.env.no_proxy = 'localhost, 0.0.0.0/4201, 0.0.0.0/9876';

Note, even I export it in our jenkinsfile, it does not work, Have to be in the js process.

注意,即使我导出到我们的jenkinsfile.

回答by Ankit Saxena

For me, below worked, seems version and conf issue:

对我来说,下面的工作,似乎版本和 conf 问题:

In package.jsonI am using:

package.json我使用:

"karma": "1.3.0",
"karma-chrome-launcher": "2.2.0"

In karma confadd this:

karma conf 中添加:

    browsers: ['ChromeHeadlessNoSandbox'],
    customLaunchers: {
        ChromeHeadlessNoSandbox: {
            base: 'ChromeHeadless',
            flags: ['--no-sandbox']
        }
    }

It shall work.

它会起作用。