Skip to content

Commit

Permalink
[rb] UNSTABLE, Adding driver#send_devtools_command for sending comman…
Browse files Browse the repository at this point in the history
…ds to Chrome DevTools debugger.

For some reason specs for headless mode are not passing.

Refer:
bayandin/chromedriver@9d18be0
  • Loading branch information
pulkitsharma07 committed Feb 13, 2018
1 parent 2300e36 commit 1142e0b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
7 changes: 6 additions & 1 deletion rb/lib/selenium/webdriver/chrome/bridge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ module Bridge

COMMANDS = {
get_network_conditions: [:get, '/session/:session_id/chromium/network_conditions'.freeze],
set_network_conditions: [:post, '/session/:session_id/chromium/network_conditions'.freeze]
set_network_conditions: [:post, '/session/:session_id/chromium/network_conditions'.freeze],
send_devtools_command: [:post, '/session/:session_id/chromium/send_command'.freeze]
}.freeze

def commands(command)
Expand All @@ -37,6 +38,10 @@ def network_conditions=(conditions)
execute :set_network_conditions, {}, {network_conditions: conditions}
end

def send_devtools_command(command, params)
execute :send_devtools_command, {}, {cmd: command, params: params}
end

end # Bridge
end # Chrome
end # WebDriver
Expand Down
1 change: 1 addition & 0 deletions rb/lib/selenium/webdriver/chrome/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module Chrome

class Driver < WebDriver::Driver
include DriverExtensions::HasNetworkConditions
include DriverExtensions::CommunicatesToDevTools
include DriverExtensions::HasTouchScreen
include DriverExtensions::HasWebStorage
include DriverExtensions::TakesScreenshot
Expand Down
1 change: 1 addition & 0 deletions rb/lib/selenium/webdriver/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
require 'selenium/webdriver/common/driver_extensions/has_network_connection'
require 'selenium/webdriver/common/driver_extensions/uploads_files'
require 'selenium/webdriver/common/driver_extensions/has_addons'
require 'selenium/webdriver/common/driver_extensions/communicates_to_dev_tools'
require 'selenium/webdriver/common/interactions/interactions'
require 'selenium/webdriver/common/interactions/input_device'
require 'selenium/webdriver/common/interactions/interaction'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

module Selenium
module WebDriver
module DriverExtensions
module CommunicatesToDevTools

#
# Send commands to the Chrome DevTools Debugger.
# Refer: https://chromedevtools.github.io/devtools-protocol/
#
# @example
# driver.send_devtools_command('Page.navigate', {url: 'http://www.google.com'})
#
# @param [String] command The command to send to DevTools.
# @param [Hash] parameters The paramters of the respective command.
#

def send_devtools_command(command, parameters)
@bridge.send_devtools_command(command, parameters)
end

#
# Chrome's headless mode has Downloads disabled by default.
# Use this method to enable it and set a download directory
#
# @example
# driver.download_path='/some/dir/which/exists/'
#
# @param [String] path The path to set as the download directory
#

def download_path=(path)
@bridge.send_devtools_command('Page.setDownloadBehavior', behavior: 'allow', downloadPath: path)
end

end # CommunicatesToDevTools
end # DriverExtensions
end # WebDriver
end # Selenium
51 changes: 51 additions & 0 deletions rb/spec/integration/selenium/webdriver/chrome/driver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,57 @@ module Chrome
'upload_throughput' => 789
)
end

context "DevTools communication" do
it 'can send commands to DevTools' do
driver.send_devtools_command('Page.navigate', url: url_for('blank.html'))
expect(driver.title).to eq('blank')
driver.send_devtools_command('Page.navigate', url: url_for('colorPage.html'))
expect(driver.title).to eq('Color Page')
end

describe('#set_download_path') do
let(:download_path) { Dir.mktmpdir }
let(:file_to_download) { "blank.html" }
let(:final_path_to_downloaded_file) { download_path + "/" + file_to_download }
let(:page_to_download_from) do
'data:text/html,'\
'<!DOCTYPE html>'\
'<div>'\
'<a download="" href="' + url_for(file_to_download) + '">Go!</a>'\
'</div>'\
'</html>'
end

before(:each) do
File.delete(final_path_to_downloaded_file) if File.exist?(final_path_to_downloaded_file)
end

it 'can download files in headless mode' do
options = Selenium::WebDriver::Chrome::Options.new
options.headless!
local_driver = WebDriver::Driver.for(:chrome, options: options)
local_driver.download_path = download_path
local_driver.get(page_to_download_from)

local_driver.find_element(css: 'a').click

sleep 3

This comment has been minimized.

Copy link
@luke-hill

luke-hill Feb 14, 2018

Optimisation, wait for this file not to have a uuid temporary suffix. Will shave a couple of seconds off runtime. (In both areas)

This comment has been minimized.

Copy link
@pulkitsharma07

pulkitsharma07 Feb 14, 2018

Author Owner

Will do.

sidenote: can you download files on your system ? Using chrome headless and the chromium/send_command to enable downloads. That will help me in tracking down the issue.

This comment has been minimized.

Copy link
@luke-hill

luke-hill Feb 14, 2018

I've managed to get headless tests working using one of the elemental tips I've been improving.

See https://github.com/tourdedave/elemental-selenium-tips - However this doesn't use the inbuilt headless ones you're modifying.

I can have a play on friday and try debug the issue if you'd like.

This comment has been minimized.

Copy link
@pulkitsharma07

pulkitsharma07 Feb 14, 2018

Author Owner

Just to confirm, You were able to download files in headless tests on chrome ?
Can you share the test case?

This https://github.com/tourdedave/elemental-selenium-tips/blob/master/72-headless-chrome/ruby/example.rb seems to be only opening an URL and taking a screenshot.

This comment has been minimized.

Copy link
@dreyks

dreyks Jun 10, 2018

I've been trying to make this work, gathered bits of information all over the internet and ended up with pretty much the same: sending Page.setDownloadBehavior

But unfortunately this still doesn't work for headless chrome

This comment has been minimized.

Copy link
@dreyks

dreyks Jun 10, 2018

UPDATE: ok so it does work when navigating to file url directly but doesn't work if I use click

This comment has been minimized.

Copy link
@pulkitsharma07

pulkitsharma07 Jun 10, 2018

Author Owner

@dreyks: The last time I checked this, I was able to get specs to pass with Chrome 65 (chromedriver 2.36), including download in headless chrome.
What Chrome/chromedriver versions are you using ?

This comment has been minimized.

Copy link
@dreyks

dreyks Jun 10, 2018

@pulkitsharma07, figured this out: it does not work with links with target="_blank"

right now the upstream selenium has changed this spec so that it only tests that it does not crash

This comment has been minimized.

Copy link
@dreyks

dreyks Jun 10, 2018

i have chromedriver 2.39 @ chrome 67

local_driver.quit
expect(File).to exist(final_path_to_downloaded_file)
end

it 'can download files in non-headless mode' do
driver.download_path = download_path
driver.get(page_to_download_from)

driver.find_element(css: 'a').click

sleep 3
expect(File).to exist(final_path_to_downloaded_file)
end
end
end
end
end # Chrome
end # WebDriver
Expand Down

2 comments on commit 1142e0b

@luke-hill
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dreyks - If after the updated chrome releases your specific use case is not fixed. Could you maybe look into raising a separate specific issue, for the specific case with _blank.

Even if it's a non-issue. It would provide some much needed compartmentalisation

@dreyks
Copy link

@dreyks dreyks commented on 1142e0b Jun 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do. thank you for your time

Please sign in to comment.