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

Chrome Remote Interface not working with Selenium/ChromeDriver #265

Closed
furkhan324 opened this issue Sep 14, 2017 · 3 comments
Closed

Chrome Remote Interface not working with Selenium/ChromeDriver #265

furkhan324 opened this issue Sep 14, 2017 · 3 comments

Comments

@furkhan324
Copy link

Hey there. I am having some trouble using Chrome Remote Interface on top of Chromedriver. I use Chromedriver to start chrome, find the remote-debugging-port and then connect Chrome Remote Interface to this port. Although the connection is successful, subsequent commands do not (i.e client.Page.navigate()) produce any effect. I understand Chrome can be started with chrome-launcher but I would like to use chromedriver to simulate certain workflows

Here is a test script to reproduce the issue(Given chromedriver is installed):

//test.js
var webdriver = require("selenium-webdriver");
var chrome = require("selenium-webdriver/chrome");
var cdp = require("chrome-remote-interface");

async function test(){
  var options = new chrome.Options();

 options.addArguments(["--detach=true"]);

  //START DRIVER
  var driver = new webdriver.Builder().
  withCapabilities(options.toCapabilities()).build();

  //FIND REMOTE DEBUGGING PORT
  await driver.get("chrome://version");
  let element = await driver.findElement(webdriver.By.id('command_line'));
  let text = await element.getText();
  console.log('Chrome command line flags:');
  console.log(text);

  var splitStr=text.split(" ");
  let port = 0;
  splitStr.filter(function(word,index){
    if(word.match(/--remote-debugging-port=*/)){
      console.log(word);
      port = Number(word.split('=')[1]);

    }else{
    }
  });

  console.log(typeof port)
  console.log('Port:');
  console.log(port);

  //START CHROME REMOTE INTERFACE
  cdp({
    port:port
  }, function(chrome){
    console.log(chrome);
    chrome.Page.enable();
    chrome.Page.navigate({'url': 'https://yahoo.com'}) //NOT WORKING
  }).on('error', function (e) {
    console.error('Cannot connect to Chrome', e);
  });

}

test();

SELENIUM_BROWSER=chrome node test.js

This script works when Chrome is started via chrome-launcher, so my guess is starting Chrome via chromedriver may have options enabled that impede Chrome Remote interface to work on top of it.

| Operating system | MacOS Sierra 10.12.15
| Node.js | 8.0.0
| Chrome/Chromium/... | 58.0.3029.110
| chrome-remote-interface | 0.24.5

Is Chrome running in a container? NO

@cyrus-and
Copy link
Owner

cyrus-and commented Sep 14, 2017

The problem is that the current (and only) tab chrome://version/ is already being inspected by Selenium/ChromeDriver so by default chrome-remote-interface pick the only other available target ("Chrome Automation Extension" in my case) thus loading https://yahoo.com in that context.

Try this:

const {target} = await cdp.New({port});

//START CHROME REMOTE INTERFACE
cdp({
    port, target
}, function (chrome) {
    chrome.Page.enable();
    chrome.Page.navigate({'url': 'https://yahoo.com'});
}).on('error', function (e) {
    console.error('Cannot connect to Chrome', e);
});

@furkhan324
Copy link
Author

furkhan324 commented Sep 14, 2017

Hey thanks for the clarification. My intended use case is to capture the DevTools Timeline through a workflow driven by Selenium so I would like the target tab to be the same as the one being driven by Selenium.

I would want to do something like this:

...
var TRACE_CATEGORIES = ["-*", "devtools.timeline", "disabled-by-default-devtools.timeline", "disabled-by-default-devtools.timeline.frame", "toplevel", "blink.console", "disabled-by-default-devtools.timeline.stack", "disabled-by-default-devtools.screenshot", "disabled-by-default-v8.cpu_profile", "disabled-by-default-v8.cpu_profiler", "disabled-by-default-v8.cpu_profiler.hires"];

cdp.Tracing.tracingComplete(function () {
    var file = 'profile-' + Date.now() + '.devtools.trace';
    fs.writeFileSync(file, JSON.stringify(rawEvents, null, 2));
    console.log('Trace file: ' + file);
    console.log('You can open the trace file in DevTools Timeline panel. (Turn on experiment: Timeline tracing based JS profiler)\n')
});

//Start Trace
cdb.Tracing.start({
    "categories":   TRACE_CATEGORIES.join(','),
    "options":      "sampling-frequency=10000"  
});

//Use driver to go through login workflow
await driver.get('https://<login page>.com');
await driver.findElement(webdriver.By.id('password')).sendKeys('***');
await driver.findElement(webdriver.By.id('username')).sendKeys('***');
await driver.findElement(webdriver.By.id('sign_in')).submit();
await driver.get("http://<some-other-website>.com");
//End Trace
await cdp.Tracing.end();

Can chrome-remote-interface target the same tab being used by Webdriver? Is this possible? If not, can chrome-remote-interface be used to do the following/similar workflow(field inputs/form submissions/page navigations) (say using cdp.DOM...?).

Thanks

@cyrus-and
Copy link
Owner

cyrus-and commented Sep 14, 2017

Can chrome-remote-interface target the same tab being used by Webdriver? Is this possible?

I don't think so.

You can do basically everything by using Runtime.evaluate to inject some JavaScript code in the page. For example:

Runtime.evaluate({
    expression: `document.getElementById('password').value = '***';
                 document.getElementById('username').value = '***';
                 document.getElementById('sign_in').submit();`
});

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

No branches or pull requests

2 participants