blueimp / wdio

Docker setup for WebdriverIO with automatic screenshots, image diffing and screen recording support for containerized versions of Chrome and Firefox on Linux, mobile versions of Chrome and Firefox on Android as well as Safari on iOS, Safari on macOS and Edge on Windows.
https://hub.docker.com/r/blueimp/wdio
MIT License
296 stars 51 forks source link

Problem with WDIO v4 #11

Closed GRme-zz closed 4 years ago

GRme-zz commented 4 years ago

I want to use your blueimp/wdio solution to execute WDIO tests in an own project, because I like this solution and it is really easy to use, also in combination with Jenkins. So, I’ve tried to make it useful for my project, but I have an issue with it and hope you can help me or can give me some recommendations :)))

So, what did I do:

Now the problem is that it is not running with my own docker image based on the updated Dockerfile. The difference between your project https://github.com/blueimp/wdio and my project is the WDIO version. You are using WDIO v5 and we are still using WDIO v4. Maybe that could be the reason.

When I try to start a simple test (via docker-compose run --rm wdio chrome.js --spec=test/google.js), that only opens the google page, then it’s really fine while using your docker image (with WDIO v5) in docker-compose.yml. But when I’m using my docker image (with WDIO v4) then I get this error:

grme:web-client-uat GRme$ docker-compose run --rm wdio chrome.js --spec=test/google.js
Starting web-client-uat_chromedriver_1 ... done
Starting web-client-uat_geckodriver_1  ... done
Waiting for host: chromedriver:4444 ... ok
Waiting for host: geckodriver:4444  ... ok
ERROR: connect ECONNREFUSED 127.0.0.1:4444
chrome
    at new RuntimeError (/usr/lib/wdio/node_modules/webdriverio/build/lib/utils/ErrorHandler.js:143:12)
    at Request._callback (/usr/lib/wdio/node_modules/webdriverio/build/lib/utils/RequestHandler.js:342:43)
    at self.callback (/usr/lib/wdio/node_modules/request/request.js:185:22)
    at Request.emit (events.js:198:13)
    at Request.EventEmitter.emit (domain.js:448:20)
    at Request.onRequestError (/usr/lib/wdio/node_modules/request/request.js:881:8)
    at ClientRequest.emit (events.js:203:15)
    at ClientRequest.EventEmitter.emit (domain.js:448:20)
    at Socket.socketErrorListener (_http_client.js:392:9)
    at Socket.emit (events.js:198:13)

The big problem is that we are not able to switch to WDIO v5 in a fast way because therefore we have to do a refactoring that will take a lot of time and I’m the only testautomation guy at the moment ;) So, I try to make it runnable also with WDIO v4.

This is my Dockerfile:

FROM alpine:3.10
RUN echo '@edgetesting http://dl-cdn.alpinelinux.org/alpine/edge/testing' \
  >> /etc/apk/repositories
RUN apk --no-cache add \
    nodejs \
    npm \
    ffmpeg \
    android-tools@edgetesting \
    nano \
    git \
    curl \
    wget \
    bzip2 \
    xvfb \
    vim \
    xterm \
  && npm install -g \
    npm@latest \
  && rm -rf \
    /tmp/* \
    /root/.npm
WORKDIR /usr/lib/wdio
COPY package.json ./
RUN npm install \
  && npm audit fix \
  && rm -rf \
    /tmp/* \
    /root/.npm
ENV NODE_PATH=/usr/lib/wdio/node_modules
ENV PATH=$PATH:/usr/lib/wdio/node_modules/.bin
COPY bin/wait-for-hosts.sh /usr/local/bin/wait-for-hosts
RUN chmod 777 /usr/local/bin/wait-for-hosts
RUN chmod 777 -Rf ${NODE_PATH}
RUN adduser -D -u 1000 wdio
USER wdio
WORKDIR /opt
ENTRYPOINT ["wait-for-hosts", "--", "wdio"]

This is my package.json (with WDIO v4):

{
  "name": "webdriverio",
  "version": "1.3.0",
  "description": "Automated Testing (End2End, Rest API)",
  "main": "index.js",
  "dependencies": {
    "asserts": "4.0.2",
    "dotenv": "8.1.0",
    "fetch": "1.1.0",
    "html2json": "1.0.2",
    "json-query": "2.2.2",
    "json-to-html-form": "1.7.0",
    "mochawesome-report-generator": "3.1.5",
    "moment": "2.24.0",
    "promise": "8.0.3",
    "replace-in-file": "4.1.3",
    "request": "2.88.0",
    "request-promise": "4.2.4",
    "swagger-walk": "github:paulvollmer/swagger-walk",
    "wdio-screen-commands": "2.10.0",
    "webdriverio": "4.14.4"
  },
  "devDependencies": {
    "chai": "4.2.0",
    "chromedriver": "latest",
    "config": "3.2.2",
    "eslint": "6.4.0",
    "eslint-config-google": "0.14.0",
    "find": "0.3.0",
    "frisby": "2.1.2",
    "fs-extra": "8.1.0",
    "geckodriver": "latest",
    "hippie-swagger": "3.2.0",
    "jest": "24.9.0",
    "jest-html-reporter": "2.6.2",
    "jest-junit": "8.0.0",
    "jshint": "2.10.2",
    "mocha": "6.2.1",
    "mochawesome": "4.1.0",
    "scripty": "1.9.1",
    "selenium-server-standalone-jar": "3.141.59",
    "selenium-standalone": "6.16.0",
    "supertest": "4.0.2",
    "wdio-allure-reporter": "0.8.3",
    "wdio-chromedriver-service": "5.0.2",
    "wdio-firefox-profile-service": "0.1.3",
    "wdio-junit-reporter": "0.4.4",
    "wdio-mocha-framework": "0.6.4",
    "wdio-mochawesome-reporter": "2.0.1",
    "wdio-sauce-service": "0.4.14",
    "wdio-selenium-standalone-service": "0.0.12",
    "wdio-spec-reporter": "0.1.5",
    "winston": "3.2.1",
    "xunit-viewer": "5.1.11",
    "yargs": "14.0.0"
  },
  "prettier": {
    "arrowParens": "always",
    "bracketSpacing": true,
    "singleQuote": true,
    "trailingComma": "all",
    "printWidth": 100
  },
  "scripts": {
    "prepare-on-unix": "chmod -Rf 777 ./scripts/ && chmod -Rf 777 ./scripts-win/ && dos2unix ./scripts/* && unix2dos ./scripts-win/*",
    "clear-screenshots": "scripty",
    "test": "scripty",
    "npm-test": "scripty",
    "clear-test": "scripty",
    "clear-npm-test": "scripty",
    "postResults": "scripty",
    "test-postResults": "scripty",
    "clear-test-postResults": "scripty",
    "generateMochawesome": "scripty",
    "npm-install-and-run-all-rest-tests": "scripty",
    "npm-install-and-run-rest-tests": "scripty",
    "run-all-rest-tests": "scripty",
    "run-rest-tests": "scripty",
    "analyze-report-for-exit-code": "scripty"
  },
  "author": "Martin"
}

This is my chrome.js (WDIO config file):

'use strict';

exports.config = Object.assign({}, require('./hooks'), {
  hostname: 'chromedriver',
  path: '/',
  capabilities: [
    {
      // Set maxInstances to 1 if screen recordings are enabled:
      // maxInstances: 1,
      browserName: 'chrome',
      'goog:chromeOptions': {
        // Disable headless mode if screen recordings are enabled:
        args: ['--headless', '--window-size=1440,900']
      }
    }
  ],
  logLevel: 'error',
  reporters: ['spec'],
  framework: 'mocha',
  mochaOpts: {
    timeout: 60000
  },
  specs: ['test/**/*.js'],
  maximizeWindow: true,
  screenshots: {
    saveOnFail: true
  },
  videos: {
    enabled: false,
    resolution: '1440x900',
    startDelay: 500,
    stopDelay: 500
  },
  assetsDir: '/home/webdriver/assets/',
  mailhog: {
    host: 'mailhog'
  }
});

And finally this is my docker-compose.yml:

version: '3.7'
services:
  chromedriver:
    image: blueimp/chromedriver
    init: true
    tmpfs: /tmp
    environment:
      - DISABLE_X11=false
      - ENABLE_VNC=true
      - EXPOSE_X11=true
    volumes:
      - ./assets:/home/webdriver/assets:ro
    ports:
      - 127.0.0.1:5900:5900
  geckodriver:
    image: blueimp/geckodriver
    init: true
    tmpfs: /tmp
    shm_size: 2g
    environment:
      - DISABLE_X11=false
      - ENABLE_VNC=true
      - EXPOSE_X11=true
    volumes:
      - ./assets:/home/webdriver/assets:ro
    ports:
      - 127.0.0.1:5901:5900
  wdio:
    #image: blueimp/wdio:latest
    image: myimage:latest
    init: true
    #read_only: true
    tmpfs:
      - /tmp
      - /home/wdio/.android
    environment:
      - WAIT_FOR_HOSTS=
          chromedriver:4444
          geckodriver:4444
      - WINDOWS_HOST
      - ANDROID_SERIAL
      - PLATFORM_VERSION
      - DEVICE_NAME
      - ORIENTATION
      - MACOS_ASSETS_DIR=$PWD/assets/
      - WINDOWS_ASSETS_DIR
    volumes:
      - .:/opt
      #- ./reports:/opt/reports
    depends_on:
      - chromedriver
      - geckodriver

Maybe you have some recommendations or tips for me what I can do to make it runnable for me.

It would be very, very cool and you would make me really happy :))) I hope I will get an answer from you.

GRme-zz commented 4 years ago

When I replace all the WDIO v4 packages in package.json with WDIO v5 packages then the simple test is running. So, it is really because of the WDIO version. Is there any chance to make it runnable with WDIO v4?

blueimp commented 4 years ago

Hi @GRme , unfortunately this project has never been tested with wdio@v4; the first version already used wdio@v5.

However the bug might simply be due to the config not properly setting the address of the selenium server. The following line from your error output shows that wdio tries to connect to localhost, but the chromedriver is running on a different host (chromedriver):

ERROR: connect ECONNREFUSED 127.0.0.1:4444

So if you can find out what the difference is between setting the selenium server address in wdio v4/v5, you might be able to fix this problem.

GRme-zz commented 4 years ago

Hey @blueimp,

thanks for your answer. Normally the hostname is relevant to set the driver server. and the driver server is chromedriver in that case, doesn't matter if WDIO v4 or v5 is used. But maybe I have to migrate to WDIO v5, even though it will be a great effort ;)

blueimp commented 4 years ago

Sorry, I think I didn't explain properly what I meant with the difference between the wdio versions.

From your error log of wdio, we can see the following line:

ERROR: connect ECONNREFUSED 127.0.0.1:4444

wdio tries to connect to the selenium server (chromedriver in our case) on the address 127.0.0.1:4444, which would be in the same container. However the selenium server is running in a separate container and only available at the address chromedriver:4444.

This leads to my assumption that there might be a difference in how the different wdio versions configure the selenium server address.

Looking at the v4 WebdriverIO documentation, the config for the selenium host is indeed different from the one for version 5 (see current (v5) WebdriverIO documentation).

The config property for the selenium server address in WebdriverIO:

So to fix the connection issue, you'll have to set the following:

host: 'chromedriver'
GRme-zz commented 4 years ago

hey @blueimp, thanks a lot. now I'm a step further.