Can I automate Chrome request blocking using Selenium-webdriver for Ruby? - ruby

I am a QA automation analyst responsible for testing a multi-platform online banking application. For our automation testing we use RubyMine suite with Gherkin/Cucumber, Ruby-scripted steps and Selenium-webdriver, Watir and page-object gems/libraries.
I have a number of scripts that I cannot automate completely without manual intervention, and these include blocking certain network calls through Telerik Fiddler to produce warning pages or error messages, etc. The future of our automation would be to do this through RubyMine instead of Fiddler for network blocking. I know there is a way to do this in Chrome using Inspect Element and the Network menu using enable request blocking. However, I cannot figure out a way to force Chrome through Ruby/Selenium to block a given request. The only way is do manually do it myself, and therefore I can't actually automate these as wanted.
So, my question -- is this a possibility to automate request-blocking with Selenium-webdriver? And, if so, where should I begin to look for help with this?
Thanks.

To block URLs from loading with Selenium with the DevTool API:
def send_cmd(driver, cmd, params={})
bridge = driver.send(:bridge)
resource = "session/#{bridge.session_id}/chromium/send_command_and_get_result"
response = bridge.http.call(:post, resource, {'cmd':cmd, 'params': params})
raise response[:value] if response[:status]
return response[:value]
end
send_cmd(driver, "Network.setBlockedURLs", {'urls': ["*"]})
send_cmd(driver, "Network.enable")

It's not very well documented, but you can also implement request blocking by passing the host-resolver-rules option to chrome and mapping the domain to localhost or an invalid IP. Something like this should work for you:
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--host-resolver-rules=MAP www.google-analytics.com 127.0.0.1')
driver = Selenium::WebDriver.for :chrome, options: options

For those wanting to know, python version is just:
driver.execute_cdp_cmd('Network.setBlockedURLs', {"urls": ["www.baidu.com"]})
driver.execute_cdp_cmd('Network.enable', {})

Try https://github.com/lightbody/browsermob-proxy
I dont know if it can satisfy your requirement as I am no way a network expert, I do use browsermob-proxy extensively to capture network request along with selenium and there is a method to blacklist certain request
https://browsermob-proxy-py.readthedocs.io/en/stable/client.html#browsermobproxy.Client.blacklist
How to disable loading external urls on seleniumlibrary/robotframework

Related

Selenium profile is getting detected by Google?

Basically I'm trying out Selenium webdriver (using FireFox) and right now I am trying to sign up to a Google account.
However, the strange thing is that whenever I run Selenium and let it use the (empty I assume?) Selenium FireFox profile Google seems to detect it and block me (asking for phone vertification).
This is even the case when I load up the selenium profile and manually sign up.
When I sign up manually (and don't use the selenium profile) I can sign up just fine.
Is the Selenium FireFox profile some how special which enables the servers to detect it?
EDIT: I'm trying to startup selenium with my default FF profile (however it keeps starting up in an empty profile) - here's the code:
OpenQA.Selenium.Proxy proxySetting = new OpenQA.Selenium.Proxy();
proxySetting.HttpProxy = proxy;
proxySetting.FtpProxy = proxy;
proxySetting.SslProxy = proxy;
FirefoxProfile profile = new FirefoxProfile("default");
profile.SetProxyPreferences(proxySetting);
profile.SetPreference("browser.privatebrowsing.autostart", true);
_driver = new FirefoxDriver(profile);
EDIT:
I managed to open the default firefox profile but now it doesn't use my proxy settings. How can I use the normal profile and still customize the profile proxies?
This post talks about an HtmlDriver tag being added to the HTML in the FirefoxDriver which would be a dead giveaway
Google is a strong supporter of Open Source, and even Selenium itself, however I don't think Google would particularly condone a Selenium script creating a bunch of spam accounts that probably would never be used, and just take space.
That being said, I believe that it would be possible potentially.
The only way that Google would be able to know you are using Selenium, is based on the Request Headers. It's possible either the User-Agent has something to do with Selenium, or one of the other Headers.
My solution would be to use something like Fiddler to listen to the requests that Firefox is sending, and then edit your Selenium scripts to account for, and change those requests so Google does not know that you are using Selenium.
This most likely goes against their terms of use, so exercise caution, and use this answer for educational purposes only.
Is there a chance, if you were using the complete path to your firefox profile directory? (e.g. C:\Users\???\AppData\Roaming\Mozilla\Firefox\Profiles\your_profile.default)

Will selenium record firebug and tamper data manipulations?

I am writing an automated test script. So far, Selenium has helped me. Now,I have a test case where I should tamper the request and add a parameter and then submit the request. I did it manually by using tamperdata.
I want to automate this test case now. The problem is, selenium is not recording my actions of adding a parameter and then submitting the request. I understand selenium is a record-playback kind of tool. can some one confirm me if it cannot record tamper data or am doing wrong?
If it cannot, how do you people automate these kind of test cases.
Selenium really is not designed for such a type of work. If a regular user can't make a tampered request (without Firebug etc.), then Selenium usually can't, too. Anyway, you can have FireBug: How do I run Firebug within Selenium WebDriver (Selenium 2)?. Controlling it, that's where the problems come - and I don't think it's worth the research.
One way to do this could be HttpUrlConnection in Java, making and sending the request in Java ... see those SO questions: How to send HTTP request in java?, Using java.net.URLConnection to fire and handle HTTP requests

why send_keys can't work after right click in chrome and ie, but firefox is fine?

i want to copy a image in the page with right click and alt+y,and follow code is work well in the firefox,but chrome and ie. so i can't get the image from the clipboard.
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto('www.baidu.com')
b.img(:src=>"http://www.baidu.com/img/baidu_sylogo1.gif").right_click
b.send_keys ("{alt}y")
and follow code can work well
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto('www.baidu.com')
b.send_keys :tab
this can work well
When you do b.send_keys ("{alt}y"), you are just typing the letters {, a, l, etc.
Try this instead:
b.send_keys([:alt, 'y'])
Watir and Watir-Webdriver use different inputs for send_keys - see here.
Note: I did not test your full script with this. To be honest, I cannot figure out how to manually copy the image to clipboard using alt+y.
It would help to know why you want to save the image. Would a screen shot work? If it will, try this:
b.driver.save_screenshot "#{Time.now.to_i}.png"
Based on one of the previous comments, its sounds like you ultimately just need a way to save the image. I assume copying it to clipboard is not actually important.
So you do all your navigation in Watir-Webdriver and then switch to one of the other Ruby gems (ex Open-URI or Net-Http) to download the image.
The following is an example using Open-URI:
require 'watir-webdriver'
require "open-uri"
save_file = 'C:\Documents and Settings\Setup\Desktop\image.png'
b = Watir::Browser.new :chrome
b.goto('www.baidu.com')
image_location = b.img.src
File.open(save_file, 'wb') do |fo|
fo.write open(image_location).read
end
Do not waste any time trying to automate validation such as a Captcha (Completely Automated Public Turing Test To Tell Computers and Humans Apart) or other authentication system designed to thwart automation. Yes it can be done but it is effectively engaging in an arms race or tilting at windmills. More importantly it brings no value to your employer.
The right way to automate around a captcha or verification code is to configure the test environment such that the code is predictable. Many captcha tools, or verification tools, have the ability to operate in 'test' mode where they have a set response. You'd never configure a production environment that way, but you can easily (and ought to) configure a test environment that way.
Talk to the folks who setup and control the test environment. They just need some logic that knows it's a test env and then uses the proper api call for the captcha or authorization tool (like the google authorizer, or the widgets that spit out numbers every 5 minutes) to put it in test mode so it uses a predictable validation response.
Here is an example of what I am talking about: http://captcha.biz/doc/aspnet/api/captcha-configuration-reference.html#BotDetect.Configuration.ITestModeConfiguration
If you are using something that does not support this, then you can either configure the system to skip the captcha entirely, OR you can configure it to point some test stub that you create (instead of the real captcha system). This will be a small bit of code that you or your developers create that uses the same api as a real captcha, but always expects the same answer. In that case everything behaves exactly like it was talking to a real captcha service, but the little stub code it is talking to always sends the same image with the same 'answer' e.g. 'testing'
This sort of thing is normal for test environments, where all sorts of third party stuff is either disabled, or put into a test mode, or connected to a test sandbox (e.g. captcha's, advertising, website analytics, tracking pixels, credit card authorization services, etc)

Can Watir interact with Firefox Extensions?

I know that with watir-WebDriver, I can make use of RubyBindings to have the browser load specific profiles or Firefox add-ons when I create a new browser instance. However, can I use Watir to actually use the add-on(s) I open?
The reason I ask is that I am trying to implement a web scraper to navigate to websites and record HTTP interactions. However, since Tamper Data already does the HTTP request/response logging I require, I'd rather use its functionality instead of having to redo it myself.
If this is not possible, I'm wondering if anyone knows a unit tester that will allow me to:
Open a Firefox browser & load Tamper Data
Navigate to specified pages
Click a button on Tamper Data's UI
You can't interact with extensions using bare watir/webdriver as far as i know, need to find a workaround ... Try something like rautomation - https://github.com/jarmo/RAutomation or autoit - http://www.autoitscript.com/site/
This works for me to launch firebug:
Win 7 & XP:
require 'watir-webdriver'
default = Watir::WebDriver::Firefox::Profile.new
If you are admin on your machine it will be the following... otherwise search and provide path:
default.add_extension("/Users/Administrator/AppData/Roaming/Mozilla/Firefox/Profiles/krqve9uc.firebug/extensions/firebug#software.joehewitt.com.xpi")
b = Watir::Browser.new(:firefox, :profile => default)

Run script directly in 2 various browsers

I have created Ruby test script that use Selenium RC to test my web app directly in 2 browsers(IE, Firefox). My script runs - first on IE then continue on Firefox and then should be continued and finished in already opened IE browser. My problem is: I can't continue(reconnect) to run my script in already opened IE browser. I use:
#browser = RSpecSeleniumHelper.connect_browser("URL")
but it opens with new session (it needs to keep previous session).
Is there a particular reason you need to switch between browsers half way through?
I have no idea how you'd fix the problem, but it seems like it would be best solved by running the tests in one browser at a time.
I'm also unsure why you need to switch back and forth in your browsers.
Regardless, I'm doing something similar, but instead I use a different library. I'm using the "Selenium" gem. (gem install selenium) and here's what I would do in your situation.
#ie_driver = Selenium::SeleniumDriver.new(rc_host, port, "*iexplore", url, 1000)
#ie_driver.start
#ie_driver.whatever //Test code
#ff_driver = Selenium::SeleniumDriver.new(rc_host, port, "*firefox", url, 1000)
#ff_driver.start
#ff_driver.whatever //Test code
#ff_driver.stop
#ie_driver.whatever //Continue test code with IE
#ie_driver.stop
In summary, while I'm not really familiar with your selenium library, typically I would create 2 instances of the R/C driver, that way I won't have to interrupt the session.

Resources