Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling browser.mock in a docker container fails with ECONNREFUSED #104

Closed
johnson-tyl opened this issue Jun 9, 2021 · 20 comments
Closed

Comments

@johnson-tyl
Copy link

Originally logged here: webdriverio/webdriverio#6997


If you run a test that needs browser.mock inside docker container, it fails on node-fetch ClientRequest with ECONNREFUSED error.

Exception:

FetchError: Failed to fetch browser webSocket URL from http://localhost:39857/json/version: request to http://localhost:39857/json/version failed, reason: connect ECONNREFUSED 127.0.0.1:39857
    at ClientRequest.<anonymous> (C:\Users\user\workspace\node.js\tyl-e2e-reviews\node_modules\node-fetch\lib\index.js:1461:11)
    at Socket.socketErrorListener (_http_client.js:426:9)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at Browser.runCommandWithHooks (C:\Users\user\workspace\node.js\tyl-e2e-reviews\node_modules\@wdio\sync\build\wrapCommand.js:100:24)
    at Browser.wrapCommandFn (C:\Users\user\workspace\node.js\tyl-e2e-reviews\node_modules\@wdio\sync\build\wrapCommand.js:67:44)
    at LoginPage.setPassword (C:\Users\user\workspace\node.js\tyl-e2e-reviews\tests\pages\app\application\login.page.js:36:29)

NOTE: The port seen above is not same every time, so cant expose it either.

Environment (please complete the following information):

  • WebdriverIO version: 7.6.1
  • Mode: WDIO Testrunner
  • If WDIO Testrunner, running sync/async: sync
  • Node.js version: [e.g. 8.11.2] v12.18.3
  • NPM version: [e.g. 5.8.0] v6.14.11
  • Browser name and version: Chrome 91
  • Platform name and version: Docker - image: standalone-chrome-debug
  • Additional wdio packages used (if applicable): wdio-docker-service

Config of WebdriverIO

exports.config = {
    runner: 'local',
    hostname: 'localhost',
    path: '/wd/hub',
    outputDir: './logs',

    capabilities: [
	{
		"maxInstances": 5,
		"browserName": "chrome",
		"goog:chromeOptions": {
			"args": [
				"--start-maximized"
			],
			"prefs": {
				"credentials_enable_service": false,
				"profile": {
					"password_manager_enabled": false
				}
			}
		}
	}],
	services:
        [
            [wdioScreenshot],
            'shared-store',
            'docker'
        ],
    dockerOptions: {
        image: 'selenium/standalone-chrome-debug',
        healthCheck: {
            url: 'http://localhost:4444',
            maxRetries: 3,
            inspectInterval: 1000,
            startDelay: 2000
        },
        options: {
            p: ['4444:4444', '5900:5900'],
            shmSize: '2g'
        }
    },
    dockerLogs: 'logs',
}

Describe the bug
I am running my existing local tests inside the docker container using the wdio-docker-service and the tests that were running successfully locally dont run inside the container, where it encounters the browser.mock() call, its throwing the error mentioned above.

To Reproduce
Steps to reproduce the behavior:

  1. Setup a project with latest WebdriverIO and wdio-docker-service
  2. Write a test that uses browser.mock()
  3. Setup the tests to run inside the container using the instructions from here
  4. Run the tests

Expected behavior
The test should pass when running inside the container.

Log
Nothing in logs, see the exception above.

@stsvilik
Copy link
Collaborator

@johnson-tyl If all you need is to expose an extra port from the docker container (and you can somehow "fix" it to be the same all the time), then all you need to do is expose it via dockerOptions.options.p (just like in example you have, just add one more to an array).

@johnson-tyl
Copy link
Author

This port is random, if I knew what it was I would have exposed it.

Do you know of any way to fix this port before running?

@stsvilik
Copy link
Collaborator

Not sure how to fix it, but there is a way to expose a range of ports in Docker, which you could try. Isn't there a range for these ports?

@johnson-tyl
Copy link
Author

I managed to fix the debugger port and expose it in docker but now it throws socket hang up error.

FetchError: Failed to fetch browser webSocket URL from http://localhost:9222/json/version: request to http://localhost:9222/json/version failed, reason: socket hang up
    at ClientRequest.<anonymous> (C:\Users\user\workspace\node.js\app\node_modules\node-fetch\lib\index.js:1461:11)
    at Socket.socketOnEnd (_http_client.js:453:9)
    at endReadableNT (_stream_readable.js:1220:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at Browser.runCommandWithHooks (C:\Users\user\workspace\node.js\app\node_modules\@wdio\sync\build\wrapCommand.js:100:24)
    at Browser.wrapCommandFn (C:\Users\user\workspace\node.js\app\node_modules\@wdio\sync\build\wrapCommand.js:67:44)

Any idea how to fix this, I am not running it headless, will that make any difference?

@stsvilik
Copy link
Collaborator

Help me understand where this call is initiated. Is Chrome (in remote debug mode) running inside a container or outside on your machine?

@johnson-tyl
Copy link
Author

johnson-tyl commented Jun 14, 2021

This is my test setup:

  • Uses wdio-docker-service
  • Uses devtools implicitly through browser.mock() call, so devtools it not a service in wdio config
  • Running inside docker on chrome

Docker options:

dockerOptions: {
        image: 'selenium/standalone-chrome-debug',
        healthCheck: {
            url: 'http://localhost:4444',
            maxRetries: 3,
            inspectInterval: 1000,
            startDelay: 2000
        },
        options: {
            expose: [ 9222 ],
            p: ['4444:4444', '5900:5900', '0.0.0.0:9222:9222'],
            shmSize: '2g'
        }

Capablities:

capabilities: [
	{
		"maxInstances": 5,
		"browserName": "chrome",
		"goog:chromeOptions": {
			"args": [
				"--remote-debugging-address=0.0.0.0",
				"--remote-debugging-port=9222",
				"--start-maximized"
			],
			"prefs": {
				"credentials_enable_service": false,
				"profile": {
					"password_manager_enabled": false
				}
			}
		},
		"cjson:metadata": {
			"browser": {
				"name": "chrome",
				"version": "latest"
			},
			"platform": {
				"name": "windows",
				"version": "10.0.19042"
			}
		}
	}
]

Services:

services:
        [
            [wdioScreenshot],
            [rerunService, {rerunDataDir: './report/rerun'}],
            'shared-store',
            'docker'
        ]

Let me know if you need anything else please.

@stsvilik
Copy link
Collaborator

stsvilik commented Jun 14, 2021

Could you try to remove expose option and just use p with 9222:9222?

@johnson-tyl
Copy link
Author

Could you try to remove expose option and just use p with 9222:9222?

Have done that too, same result I am afraid.

@johnson-tyl
Copy link
Author

you mean also remove 0.0.0.0 from p?

@stsvilik
Copy link
Collaborator

Yep

@johnson-tyl
Copy link
Author

Yep

tried that too, same error, any other ideas?

@stsvilik
Copy link
Collaborator

Hard to say because I'm still fuzzy about which side attempts to make a connection. If test running on your machine is trying to connect to debug port inside a container, then localhost should resolve fine since that port is exposed. If it's the code inside container which attempts to access port outside via localhost, then it will not work since to a Docker that name points to itself.

@johnson-tyl
Copy link
Author

Since devtools run inside the chrome browser (inside container), its possible the call might be from the inside of the container. Someone had a similar problem using wdio-docker-service and devtools as service, #78 not sure if their problem was resolved.

@stsvilik
Copy link
Collaborator

Maybe this will help if you can change the host to which it attempts to connect. https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach

@johnson-tyl
Copy link
Author

Thanks @stsvilik, I tried changing the remote-debugging-address to "host.docker.internal" but getting the same error.

"goog:chromeOptions": {
			"args": [
				"--remote-debugging-address=host.docker.internal",
				"--remote-debugging-port=9222",
				"--start-maximized"
			],
			"prefs": {
				"credentials_enable_service": false,
				"profile": {
					"password_manager_enabled": false
				}
			}
		},

Tried the 2nd option of adding network: 'host' to dockerOptions but that's throwing error starting docker, looks like its only supported in Docker on Linux (I am on Windows):

dockerOptions: {
    image: 'selenium/standalone-chrome-debug',
    healthCheck: {
        url: 'http://localhost:4444',
        maxRetries: 3,
        inspectInterval: 1000,
        startDelay: 2000
    },
    options: {
        p: ['4444:4444', '5900:5900', '0.0.0.0:9222:9222'],
        network: 'host',
        shmSize: '2g'
    }
}

Anything more you can recommend please? I am not a regular Docker user, so not very good at troubleshooting these issues, so any help is appreciated.

@johnson-tyl
Copy link
Author

Looks like I found the solution to the problem, the only way it exposes the port outside of container is when you run it headless, this is completely odd.

Tried it after reading it a few different places on Stackoverflow, last one being:
https://stackoverflow.com/questions/48319240/chrome-fails-to-serve-from-debugging-port-inside-docker-container

@stsvilik
Copy link
Collaborator

I would add host to the Docker with IP of host machine and use that host name with remote debugging address.

@johnson-tyl
Copy link
Author

If I add IP address of host, it will fail when one of my colleagues run it, as they wont have the same IP address as my machine?

@CristobalBautista
Copy link

@johnson-tyl Hi, I'm trying to run the browser.mock() command in a docker container as well, but I'm getting the same error you got.
Did you manage to make it work?
I'm already running it in --headless and set the --remote-debugging-port=9222, but same error.

@gianlucamangiapelo
Copy link

Hy @johnson-tyl I'm trying to fix this issue also on my side.
Can you share with us your configurations that allows to use .mock() with no issue?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants