Angular unit test stuck on GitHub Action CI

Viewed 1866

I'm trying to setup a CI pipeline on an default Angular project with GitHub Actions. I can run unit test locally successfully, but run into issues with GitHub Actions. What do I need to change to get it running successfully?

name: Node.js CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [10.x, 12.x, 14.x]

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test

Here is the log output for this step

> ng test

Compiling @angular/core/testing : es2015 as esm2015
Compiling @angular/platform-browser/testing : es2015 as esm2015
Compiling @angular/compiler/testing : es2015 as esm2015
Compiling @angular/platform-browser-dynamic/testing : es2015 as esm2015
Compiling @angular/common/testing : es2015 as esm2015
Compiling @angular/router/testing : es2015 as esm2015
- Generating browser application bundles...
17 12 2020 20:14:02.566:WARN [karma]: No captured browser, open http://localhost:9876/
17 12 2020 20:14:02.708:INFO [karma-server]: Karma v5.1.1 server started at http://localhost:9876/
17 12 2020 20:14:02.709:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
17 12 2020 20:14:02.713:INFO [launcher]: Starting browser Chrome
āœ” Browser application bundle generation complete.
- Generating browser application bundles...
āœ” Browser application bundle generation complete.
17 12 2020 20:14:07.847:WARN [karma]: No captured browser, open http://localhost:9876/
17 12 2020 20:14:08.707:ERROR [launcher]: Cannot start Chrome
    [2646:2646:1217/201408.612463:ERROR:browser_main_loop.cc(1434)] Unable to open X display.

17 12 2020 20:14:08.707:ERROR [launcher]: Chrome stdout: 
17 12 2020 20:14:08.707:ERROR [launcher]: Chrome stderr: [2646:2646:1217/201408.612463:ERROR:browser_main_loop.cc(1434)] Unable to open X display.

17 12 2020 20:14:08.712:INFO [launcher]: Trying to start Chrome again (1/2).
17 12 2020 20:14:08.860:ERROR [launcher]: Cannot start Chrome
    [2682:2682:1217/201408.854964:ERROR:browser_main_loop.cc(1434)] Unable to open X display.

17 12 2020 20:14:08.861:ERROR [launcher]: Chrome stdout: 
17 12 2020 20:14:08.861:ERROR [launcher]: Chrome stderr: [2682:2682:1217/201408.854964:ERROR:browser_main_loop.cc(1434)] Unable to open X display.

17 12 2020 20:14:08.863:INFO [launcher]: Trying to start Chrome again (2/2).
17 12 2020 20:14:09.006:ERROR [launcher]: Cannot start Chrome
    [2711:2711:1217/201409.000191:ERROR:browser_main_loop.cc(1434)] Unable to open X display.

17 12 2020 20:14:09.006:ERROR [launcher]: Chrome stdout: 
17 12 2020 20:14:09.007:ERROR [launcher]: Chrome stderr: [2711:2711:1217/201409.000191:ERROR:browser_main_loop.cc(1434)] Unable to open X display.

17 12 2020 20:14:09.008:ERROR [launcher]: Chrome failed 2 times (cannot start). Giving up.
2 Answers

If you don't want to change your package.json, karma.conf, or install Puppeteer (whatever-that-is) as suggested in the other answer, you can just modify your GitHub actions config to pass the --watch=false and --browsers=ChromeHeadless flags to the underlying script.

jobs:
  build:
    steps:
    - run: npm test -- --watch=false --browsers=ChromeHeadless

That first "floating" -- is important ... it tells NPM to pass any subsequent arguments to the script that it's calling rather than trying to evaluate them against npm. So if npm test calls ng test, the above will actually call ng test --watch=false --browsers=ChromeHeadless.

--watch=false will fix the "the run never ends" problem, which is caused by ng test watching for file changes to trigger test reruns.

--browsers=ChromeHeadless will fix the fact that GitHub Actions can't run the full Chrome browsers on a system that has no display (hence the "Unable to open X display" in the error output.) So instead of running full Chrome, it'll run a special headless version which simulates the display portions.

you need to install puppeteer and so some extra configuration

npm install puppeteer --save-dev

in karma.conf.js under restartOnFileChange: true, add

customLaunchers: {
  ChromeHeadlessCustom: {
    base: 'ChromeHeadless',
    flags: ['--no-sandbox', '--disable-gpu']
  }
}

in package.json update test script to be "test": "ng test --watch=false --browsers=ChromeHeadlessCustom",

Related