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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[馃悰 Bug]: chromedriver service is not killed #10795

Closed
gravityvi opened this issue Jun 22, 2022 · 12 comments 路 Fixed by #10796
Closed

[馃悰 Bug]: chromedriver service is not killed #10795

gravityvi opened this issue Jun 22, 2022 · 12 comments 路 Fixed by #10796

Comments

@gravityvi
Copy link
Contributor

What happened?

Even after calling driver.quit. Not able to start chrome driver on the same port. Server is not getting killed and the port is not released.

How can we reproduce the issue?

const webdriver = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const BROWSER_NAME = webdriver.Browser.CHROME;

async function getDriver() {
  let service = new chrome.ServiceBuilder(require('chromedriver').path).setPort(9515);

  service.setStdio(['pipe', process.stdout, process.stderr]);

  return new webdriver.Builder()
    .setChromeService(service)
    .forBrowser(BROWSER_NAME)
    .build();
}

async function runTestWithCaps() {
  for (i = 0; i <= 5; i++) {
    try {
      driver = await getDriver();
      await driver.get("http://www.google.com");
      await driver.quit();
    } catch(err) {
      console.log(err);
    }
  }
}

runTestWithCaps();

Relevant log output

tarting ChromeDriver 102.0.5005.61 (0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.


Starting ChromeDriver 102.0.5005.61 (0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
[1655906636.622][SEVERE]: bind() failed: Address already in use (48)
IPv4 port not available. Exiting...


Starting ChromeDriver 102.0.5005.61 (0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
[1655906639.852][SEVERE]: bind() failed: Address already in use (48)
IPv4 port not available. Exiting...


Starting ChromeDriver 102.0.5005.61 (0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
[1655906642.727][SEVERE]: bind() failed: Address already in use (48)
IPv4 port not available. Exiting...

Starting ChromeDriver 102.0.5005.61 (0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
[1655906647.038][SEVERE]: bind() failed: Address already in use (48)
IPv4 port not available. Exiting...

Starting ChromeDriver 102.0.5005.61 (0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819}) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
[1655906651.742][SEVERE]: bind() failed: Address already in use (48)

Operating System

macOS Monterey

Selenium version

4.2.2

What are the browser(s) and version(s) where you see this issue?

chrome 102

What are the browser driver(s) and version(s) where you see this issue?

chromedriver 102

Are you using Selenium Grid?

No response

@github-actions
Copy link

@gravityvi, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

@praveendvd
Copy link
Contributor

@diemol i think the issue is with : https://github.com/SeleniumHQ/selenium/blob/trunk/javascript/node/selenium-webdriver/remote/index.js#L196

We are not starting new server if a server is already existing , we just creates a new session in the existing server. So if we call quit , the server gets killed and so the error mentioned in #10499 is thrown

The ideal fix seems to be to start new server or add additional flag whether to start new server or not.

fix in #10499 will not kill the server.

@praveendvd
Copy link
Contributor

@diemol i was thinking if we could add a method like spawnNewService(true)

  return new webdriver.Builder()
  .forBrowser(BROWSER_NAME)
  .withCapabilities(webdriver.Capabilities.chrome())
  .setChromeOptions(options)
  .spawnNewService(true)
  .build();

and add it as condition in remote.js start method

start(opt_timeoutMs) {
   if (this.address_ && !this.spawnNewService_) {
     return this.address_
   }

   const timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS
   const self = this

   let resolveCommand
   this.command_ = new Promise((resolve) => (resolveCommand = resolve))

   this.address_ = new Promise((resolveAddress, rejectAddress) => {
     resolveAddress(

But i am not sure how to pass the options from node_modules/selenium-webdriver/index.js to node_modules/selenium-webdriver/remote/index.js

@diemol
Copy link
Member

diemol commented Jun 28, 2022

The default behavior should be to span a new service for each session, and this should be transparent for the user.

@praveendvd
Copy link
Contributor

praveendvd commented Jun 28, 2022

@diemol so should we remove this

 if (this.address_ ) {
     return this.address_
   }

@diemol
Copy link
Member

diemol commented Jun 28, 2022

I am not very familiar with the code details, so better please coordinate with @gravityvi who is already sending a PR.

@gravityvi
Copy link
Contributor Author

@praveendvd the issue is only happening with chrome service and I think it's due to this line:

function getDefaultService() {
if (!defaultService) {
defaultService = new ServiceBuilder().build()
}
return defaultService
}
It returns defaultService if it has been already created once.

@praveendvd
Copy link
Contributor

@gravityvi perfect your current PR and this additional change will fix both the issues , just verified . @diemol

@praveendvd
Copy link
Contributor

i was trying like this and it was saying path not found so i ignored going to getdefaultservice: 馃槃

  static createSession(caps, opt_serviceExecutor) {
    let onQuit
    let executor
    if (opt_serviceExecutor instanceof http.Executor) {
      executor = opt_serviceExecutor
      configureExecutor(executor, this.VENDOR_COMMAND_PREFIX)
    } else {
      let service =  new ServiceBuilder().build()
      executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX)
      onQuit = ()=>service.kill()
    }

changing chrome to :

/**
 * Returns the default ChromeDriver service. If such a service has not been
 * configured, one will be constructed using the default configuration for
 * a ChromeDriver executable found on the system PATH.
 * @return {!remote.DriverService} The default ChromeDriver service.
 */
function getDefaultService() {
   return new ServiceBuilder().build()
}

and


  /**
   * Creates a new session with the WebDriver server.
   *
   * @param {(Capabilities|Options)=} opt_config The configuration options.
   * @param {(remote.DriverService|http.Executor)=} opt_serviceExecutor Either
   *     a  DriverService to use for the remote end, or a preconfigured executor
   *     for an externally managed endpoint. If neither is provided, the
   *     {@linkplain ##getDefaultService default service} will be used by
   *     default.
   * @return {!Driver} A new driver instance.
   */
  static createSession(caps, opt_serviceExecutor) {
    let onQuit
    let executor
    if (opt_serviceExecutor instanceof http.Executor) {
      executor = opt_serviceExecutor
      configureExecutor(executor, this.VENDOR_COMMAND_PREFIX)
    } else {
      let service =  new ServiceBuilder().build()
      executor = createExecutor(service.start(), this.VENDOR_COMMAND_PREFIX)
      onQuit = ()=>service.kill()
    }

    // W3C spec requires noProxy value to be an array of strings, but Chromium
    // expects a single host as a string.
    let proxy = caps.get(Capability.PROXY)
    if (proxy && Array.isArray(proxy.noProxy)) {
      proxy.noProxy = proxy.noProxy[0]
      if (!proxy.noProxy) {
        proxy.noProxy = undefined
      }
    }

    return /** @type {!Driver} */ (super.createSession(executor, caps, onQuit))
  }

Fixes both the issues

@praveendvd
Copy link
Contributor

@gravityvi i think you have to do the same changes for all chromium based browsers not just chrome .

@gravityvi
Copy link
Contributor Author

@praveendvd yes will do that

@github-actions
Copy link

github-actions bot commented Aug 4, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants