Loading chrome with extension using watir-webdriver gives Timeout error - watir

I have HTML Tidy extension installed in chrome.
When I do:
b = Watir::Browser.new :chrome
The Chrome browser opens up but without extension.
So I used following:
b = Watir::Browser.new (:chrome, :switches => %w[--load-extension=
"C:\Users\.....\AppData\Local\Google\Chrome\UserData\Default\Extensions\gljdonhfjnfdklljmfaabfpjlonflfnm"])
This opens the Chrome browser with an extension
But after few seconds it gives me error:
[0402/141412:ERROR:proxy_launcher.cc(551)] Failed to wait for testing
channel presence. test\automation\proxy_launcher.cc(477): error: Value
of: automation_proxy_.get()
Actual: false Expected: true Timeout::Error: Timeout::Error
I did a search and it looks like a chromedriver bug.
I am using Chromedriver version : 26.0.1383.0
Has anyone come across this issue? Can some one please suggest a work around if one is available?

The Ruby library Nokogiri can check for well formed markup. Then you are not dependant on browser things. You can capture the html from Watir-Webdriver. Or you can capture it from net/http.
require "net/http"
require "uri"
require "nokogiri"
uri = URI.parse("http://www.google.com")
response = Net::HTTP.get_response(uri)
puts parse_body(response.body)
def parse_body(response)
begin
return Nokogiri::XML(response) { |config| config.strict }
rescue Nokogiri::XML::SyntaxError => e
return "caught exception: #{e}"
end
end

Related

How can I know if browser is Chrome vs Firefox from web extension popup JavaScript?

I am using the chrome namespace for both Chrome and Firefox, but would like to know which browser is running the web extension.
Links to extension resources have different schemes in Chrome and Firefox.
const isFirefox = chrome.runtime.getURL('').startsWith('moz-extension://');
const isChrome = chrome.runtime.getURL('').startsWith('chrome-extension://');
Check chrome.app which is absent in Firefox:
const isFirefox = !chrome.app;
Check for browser which is absent in Chrome:
const isFirefox = window.browser && browser.runtime;
(the additional check is to avoid false positives on pages that have an element with id="browser" that creates a named property on window object for this element)
Use the asynchronous browser.runtime.getBrowserInfo.
P.S. navigator.userAgent may be changed during debugging in devtools when switching to device mode or via about:config option in Firefox so it's an unreliable source.
This is what I do in my own extensions to check for Firefox (FF) vs Chrome:
const FF = typeof browser !== 'undefined';
Update: (1)
Here is an explanation .....
I am using the chrome namespace for both Chrome and Firefox, but would
like to know which browser is running the web extension.
AFA I understand, the question relates to extension code and not content code. I use above code in background script in "firefox-webextensions" or "google-chrome-extension" background script.
From then on then code would be:
if (FF) {...}
else { .... }
Once established, content script has no bearing on it.
In case of a developer who somehow decides to use id="browser" then a further step could be added which returns a boolean true|false e.g.
const FF = typeof browser !== 'undefined' && !!browser.runtime;
Worth nothing that the following returns an object or undefined and not a boolean
const isFirefox = window.browser && browser.runtime;
While it works fine in if() conditionals, it wont work in other situations where a boolean would be required (e.g. switch)
(1) Note: Marking down answers, discourages people from spending time and effort in answering questions in future.

Watir & Nokogiri not loading content in frame

Using watir & nokogiri to parse the content I can find in my bank account. The line browser.div(:id => 'main_layout_v2_1_cell_1:0').wait_until_present tells watir to wait until the div that is loaded by js appears. (I disabled javascript in Chrome to check if the content is loaded by javascript, and indeed it is.)
Nonetheless when Nokogiri puts browser.html it shows all the content except the section loaded by js.
require 'rubygems'
require 'watir'
require 'watir-webdriver'
require "watir-webdriver/wait"
require 'nokogiri'
browser = Watir::Browser.new
browser.goto 'https://particulares.gruposantander.es/SUPFPA_ENS/BtoChannelDriver.ssobto?dse_operationName=NavLoginSupernet&dse_parentContextName=&dse_processorState=initial&dse_nextEventName=start'
#Login
browser.select_list(:name => 'tipoDocumento').select 'NIF'
browser.text_field(:name => 'numeroDocumento').set 'xxx'
browser.text_field(:name => 'password').set 'xxx'
browser.button(:value => 'Entrar').click
#Select account
browser.link(:title => 'Cuentas').when_present.click
browser.div(:id => 'main_layout_v2_1_cell_1:0').wait_until_present
#Parse what you see, Noko
page = Nokogiri::HTML.parse(browser.html)
puts page
Things I've tried:
If I'm parsing the whole HTML through Nokogiri is because first I have tried to get those links I want to click finding by ID, title, text. None of them worked because as Nokogiri shows in the output, that part of code is not present.
Extending the timeout and rescueing the error to give the browser more time to make sure the code is there.
Code here:
begin
Timeout::timeout(40) do
#Parse what you see, Noko
page = Nokogiri::HTML.parse(browser.html)
puts page
end
puts 'done'
rescue Timeout::Error => e
puts 'not done :/'
end
Wait_until a div present in the content loaded by js is present > browser.wait_until{browser.div(:id => 'main_layout_v2_1_cell_1:0').exist?} > Timeout error.
Notes: the content I'm trying to get is wrapped in a body tag with this structure <body scroll="auto" bgcolor="F4F6F7" onload="main.onload();">
The code parsed by Nokogiri only outputs the content that is not loaded by js. How to load that content too?
The html method only does not include the contents of frames and iframes. As a result, if the desired content is within a frame, you need to explicitly tell Watir to return the frame HTML.
Assuming there is only 1 iframe on the page, you would do:
page = Nokogiri::HTML.parse(browser.iframe.html)

#javascript tag not working for cucumber test cases using capybara driver

I am getting this error when using #javascript tag for scenario :
Unable to load URL: http://testdomain.mentorstring.com:3000/login because of error loading http://testdomain.mentorstring.com:3000/login: Unknown error (Capybara::Webkit::InvalidResponseError).
when i am running the same without javascript tag i get no error and the test passes.
It is likely an error on the page. Check your browser console when loading the page. Also, see more details here: Capybara webkit invalid response error, how to debug?
This answer also provides a way to debug it: https://stackoverflow.com/a/12194920/769971
Try using following capybara configurations in your env.rb file
Capybara.configure do |config|
config.run_server = true
config.server_port = 3000
config.javascript_driver = :webkit
config.default_wait_time = 30
config.always_include_port = true
config.default_host = 'your_app_url'
config.app_host = 'http://your_app_url'
end

How can I ignore tests when under a particular browser?

My suite of cucumbers gets run on both Firefox and Chrome. Some of them require a browser resize, which is horrible to deal with in Chrome. Since the behaviors that need the resize don't require cross browser testing, I'd like some way to ignore them when the detected browser is Chrome. Is there a way to do this? Perhaps with hooks or in the steps? I'm currently doing the resizing in Before and After hooks.
I don't know which web-driver you are using, but for watir-webdriver you can do the following:
You can determine which browser it is in the steps that you want to skip using the code in the below URL.
http://watirwebdriver.com/determining-which-browser/
Once you determine that it is chrome you can just skip that particular step.
In your test helper, you can add those methods :
def use_chrome_driver
Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.current_driver = :selenium_chrome
end
def setup
Capybara.current_driver = :selenium
end
All your tests will use the selenium default webdriver, then when you need to use Chrome, just call the method use_chrome_driver at the beginning of your test like that :
def test_login_with_chrome
use_chrome_driver
...
end
You may also add into your helper your firefox driver with the correct browser size you need, and make it the default selenium browser.

Capybara use Internet Explorer as browser rather than Firefox

Hi is it possible to tell Capybara to use IE instead of always defaulting to Firefox?
I have to write some automated tests but the business only supports Internet Explorer so I need the tests to be run on this browser.
Thanks.
As marc_s suggested in the comments, you could try making IE the default browser on your test machine.
I also see some google hits about using Capybara with Selenium (remote control).
If you're interested, check the Selenium docs for how to specify the browser.
Edit It seems the tutorial I posted before was Rack-only. Not sure, but maybe this will work instead:
http://www.johng.co.uk/2010/10/13/run_capybara_and_cucumber_features_in_internet_explorer_on_remote_windows/
Capybara.app_host = "http://192.168.1.37:3000"
Capybara.default_driver = :selenium
Capybara.register_driver :selenium do |app|
Capybara::Driver::Selenium.new(app,
:browser => :remote,
:url => "http://192.168.1.127:4444/wd/hub",
:desired_capabilities => :internet_explorer)
end
It still requires Selenium.
Edit 2:
If you get this error:
Capybara::TimeoutError: failed to resynchronize, ajax request timed out
Then try adding this code to features/step_definitions/mydefiniation.rb:
Before do
page.driver.options[:resynchronize] = false
end
See this question about that specific problem: Using Capybara for AJAX integration tests
Use ->
ignore_mode = opts.delete(:introduce_flakiness_by_ignoring_security_domains) != false
Goto -> External Libraries- selenium-webdriver - lib - selenium - webdriver - ie - bridge.rb
Update module IE -> def initialize
It contains -
ignore_mode = opts.delete(:introduce_flakiness_by_ignoring_security_domains)
just add != false so that it becomes ->
ignore_mode = opts.delete(:introduce_flakiness_by_ignoring_security_domains) != false

Resources