Watir-webdriver keeps opening multiple browsers - cucumber

Hello StackOverflow members,
I've been searching the site (and the rest of the web) for an answer to this question, but all my search queries returned the awesome features of Watir... I seem to be one of the few people running into this particular problem. I hope someone out there has an easy answer for me :)
I'm working on website test automation. The current test set is written with Cucumber/Ruby/Selenium-Webdriver/Capybara. I'm personally interested in switching to Watir-Webdriver in combination with Cucumber and Ruby, but I'm struggling with the following:
Every time I run my cucumber test, Watir opens not one, but TWO browser screens. It seems to want to initiate a blank screen (which just goes to the site I configurated as default), plus another browser screen in which the actual test steps are executed.
Keep in mind, I'm rather new to this and I'm having this trouble when simply following a beginners tutorial. Nothing fancy as of yet.
In my 'Support/env.rb' file, I have the following:
require "cucumber"
require 'watir-webdriver'
app_host = ENV['apphost']
Before do
#browser = Watir::Browser.start app_host, :firefox
end
Before do |scenario|
#scenario_tag = scenario.source_tag_names
#browser.cookies.clear
end
at_exit do
#browser.close
end
The first bit in my steps file (GoogleSearch.rb -- yes it's that basic):
require_relative "../support/env"
Given(/^that I have gone to the Google page$/) do
#browser.goto 'http://www.google.com'
end
Now, when I run this test, I expect just ONE browser to be initiated. But instead, the automation initiates TWO browser screens. One just stays in the background doing nothing, the other contains the test steps.
Again, I've searched for a while now (which I'm usually pretty good at), but I haven't found the answer to my problem anywhere. The only way I got it to work, is to start with a step in my steps file, initiating a browser (instead of doing this in the env.rb file). But I don't want to start each test with opening a browser..
Any help would be very much appreciated. If any more information from me is required, I'll update as soon as I can.
Thanks in advance!

The problem is that env.rb is being loaded twice:
It is automatically included when running the cucumber command
It is being included a second time in GoogleSearch.rb when calling the line require_relative "../support/env".
As a result, each of the hooks is registered twice. In other words, Cucumber is seeing the hooks to run before each scenario as:
Before do
#browser = Watir::Browser.start app_host, :firefox
end
Before do |scenario|
#scenario_tag = scenario.source_tag_names
#browser.cookies.clear
end
Before do
#browser = Watir::Browser.start app_host, :firefox
end
Before do |scenario|
#scenario_tag = scenario.source_tag_names
#browser.cookies.clear
end
As you can see, Watir::Browser.start is called twice resulting in the two browsers. The first one is not used since the second call uses the same variable.
To solve the problem, simply remove the require_relative "../support/env" line.
Note that this will only address the issue with opening two browsers for each scenario. You will notice that you will still get a new browser for each scenario and that only the last browser gets closed. If you only want one browser for all scenarios, you should look at the global hooks.

Related

Detect that automated Chrome page has been closed

I have written code to automate entries into a survey using Excel VBA with selenium controlling chrome.
If the user closes the driven chrome window then currently I get a vba error when the next element can't be found.
I want to write some code to detect the chrome window is no longer present and then close down the vba code smoothly.
My idea was to try to find the tab title and execute the closure code if it did not exist - meaning I got the chrome not available error. The code below seems to work but there is a 13 second wait whilst it looks for the page title. Shortening any of the 4 Timeouts available in selenium basic does not seem to change this wait.
My questions are:
Is there a better way to check if the driven chrome window has closed?
Is there a way to shorten the period of time before the error is thrown?
On Error Resume Next
tabTitle = ch.Title
If Not tabTitle Then
Debug.Print "Closed"
End If
On Error GoTo 0
Many thanks
The only way I know of is to catch UnreachableBrowserException. I am not sure what Selenium version you are using, but in Java, you would surround your code in a try/catch
try {
// do your Excel thing here
} catch (UnreachableBrowserException e) {
// execute your alternate plan
}
The problem is that this could happen at any time, anywhere. You can simply put this everywhere on the code. If this is part of a fully-automated solution, why not simply run your script in headless mode. This will prevent the root cause of the problem which is a user unexpectedly closing the browser.

watir - is it able to use watir-webdriver and selenium-webdriver in the same time?

I'm new to automation, sorry if the title is not appropiate.
I have Ruby, Devkit, gem json, cucumber, capybara, selenium-webdriver, rspec installed following the guide http://www.swtestacademy.com/ruby-cucumber-and-capybara-on-windows/
However I cannot locate an element using a full xpath (checked and verified with xpath plugin and developer tool), my action is:
page.find(:xpath, "my_xpath").send_keys(yyy)
and I got:
Unable to find visible xpath
I also tried:
page.findElement(By.xpath("my_xpath")).send_keys("ori_pw")
and I got:
uninitialized constant By (NameError)
And I would like to try using watir, I have installed gem watir, watir-webdriver.
and added require 'watir' into my env.rb
then I try:
page.input(:name => "xxx").set(yyy)
But I get: undefined method `input' for # (NoMethodError)
May I have some suggestions please?
Thanks.
=============================================Edit#1
My env.rb now looks like this:
require 'rubygems'
require 'capybara'
require 'capybara/dsl'
require 'rspec'
require "selenium-webdriver"
require 'watir'
require 'cucumber'
Selenium::WebDriver::Firefox::Binary.path='C:\Program Files\Mozilla Firefox\firefox.exe'
Capybara.run_server = false
#Set default driver as Selenium
Capybara.default_driver = :selenium
#Set default selector as css
Capybara.default_selector = :cs
#Syncronization related settings
module Helpers
def without_resynchronize
    page.driver.options[:resynchronize] = false
    yield
    page.driver.options[:resynchronize] = true
end
end
World(Capybara::DSL, Helpers)
How can I disable capybara and set watir properly?
Sorry that I have no technical background...
Thomas, Yes the element is visible,
HTML screenshot
Actually I will be setting value to these 3 password fields.
The xpath I'm trying is:
/html/body[#class='modal-open']/app-root/div[#id='wrapper']/app-navigation/user-change-password/div[#id='myModal']/div[#class='modal-dialog modal-lg']/div[#class='modal-content']/div[#class='modal-body']/form[#class='ng-pristine ng-invalid ng-touched']/fieldset[#class='form-horizontal']/div[#class='form-group'][1]/div[#class='col-sm-7']/input[1]
(at the end I use avoid using class as I see the class name different sometimes)
Thanks.
=============================================Edit#2
The problem now shift to chromedriver.
Double clicking it able to show
Starting ChromeDriver 2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f) on port 9515
Only local connections are allowed.
But enter chromedriver on cmd will show Chromedriver.exe has stopped working.
The reason it's not working for you is due to an unfortunate bug in geckodriver/firefox - which is probably also going to affect watir - whereby it assumes any element with a hidden attribute is actually non-visible (if the display style is set to anything other than default it actually overrides the hidden attribute but not as far as selenium is concerned). This is affecting you because of the hidden attribute on the element div#myModal which makes selenium think the entire modal is non-visible - https://github.com/mozilla/geckodriver/issues/864. If you swap to testing with Chrome instead the issue will go away.
Additionally using XPaths as specific as you show is a terrible idea and will lead to highly fragile tests. If you swap to Chrome (Capybara.default_driver = :selenium_chrome) you'd be much better off just doing something like
page.fill_in('Original Password', with: 'blah')
or
page.find('input[name="originalPassword"]`).set('blah')
One final point, the :resynchronize option went away a long time ago, you might want to find a more up to date guide to follow

Load Steps into Console?

Is it possible to load the step definitions I have defined into the calabash-android console?
I would like to be able to use them when navigating the app within the console.
Thanks
No from the console you can not run a single step definition.
But you can start execution of a test at a specific line appending parameter to the call to start your test
:<linenumber>
This will start execution of your feature file from that specific line and it will run from there to the end of the file.
So while it is not what you are looking for at least it is something.
Did you try step('<step_name>') method?
To be honest I'm not sure if this will work. I know it's working insinde Ruby methods and step definitions - I wanted to post a comment but I can't with 28 points of reputation ;)
You can also try making ruby methods with code from within the step definition:
Then /^I do something$/ do
some code
goes here
end
def do_something
some code
goes here
# same code as in step definition
end
or just use step method:
def do_something
step('I do something')
end
and then call it in a calabash console (I prefer using binding.pry inside some script rather than calling "pure" calabash-console - it makes me sure that I will have all needed methods included).

PHP-FPM fastcgi_finish_request() not working as expected

I read #Dmitri 's original example of how to use fastcgi_finish_request() question and tried to follow the example in the answer in my Kohana 3.1 setup in index.php:
echo Request::factory()
->execute()
->send_headers()
->body();
Right after that, I added:
fastcgi_finish_request();
sleep(5);
Initially, I thought it worked. But then I realised in only worked for every other request. Example:
Navigate to localhost (works, no pause)
Click link to localhost/controller (pause 5 seconds)
Click another link to localhost/controller (works again, no pause)
And it continues on like that. Am I missing something? Like maybe a setting in php5-fpm config file?
Running PHP 5.3.5-1ubuntu7.2 with Suhosin-Patch, Nginx
Call session_write_close() before you call fastcgi_finish_request() to resolve this issue:
session_write_close();
fastcgi_finish_request();
sleep(5);
Next to the server-response itself (which you can control with the fastcgi_finish_request function and rest assured it works that way), there can be other resources that is blocking the (next) script from starting right ahead.
This can be file-lockings (popular for session) and other stuff. As you have not shared much code and we do not see your Kohana configuration you should take a look which components you use and which resources they acquire.
Is it because your web server only handles one php instance at a time and it is still exciting the previous script?

Method for Debugging Userscripts in Chrome

I've attempted to make some modifications to a userscript to enable it to work under Chrome, but when I drag it into Chrome's window in order to install it, a dialog pops up and says 'Invalid Script Header'.
I've tried to use the Developer Tools, and built-in Javascript Console, to debug any errors occurring, but nothing appears to list any information.
Console.app does not list anything meaningful, except for the same error message I already know.
[0x0-0x2d02d].com.google.Chrome: [346:1547:16686819618022:ERROR:extension_error_reporter.cc(55)] Extension error: Invalid script header.
How can I reasonably debug this error message and figure out what about the header is incorrect?
I'm using Chrome 15.0.861.0 on the dev channel, under OS 10.7 Lion.
I finally stumbled across the answer to this question, amusingly via a Chromium Bug Report.
As it turns out, the answer to my question was in the (significantly brief) Userscript Documentation for Chrome page.
With Greasemonkey-style #include rules, it is not possible for Chrome to know for certain the domains a script will run on (because google.* can also run on google.evil.com). Because of this, Chrome just tells users that these scripts will run on all domains, which is sometimes scarier than necessary. With #match, Chrome will tell users the correct set of domains a user script will run on.
As it turns out, I had been using #match http://*musicbrainz.org in an attempt to match www.musicbrainz.org as well as musicbrainz.org, but per the quoted text, that doesn't save you from accidentally matching evilmusicbrainz.org. So, my solution was to use two lines:
#match http://*.musicbrainz.org
#match http://musicbrainz.org
Type:
debugger;
Somewhere in the code, and the Web Inspector will pop up in that location. I have answered similar question here Chrome debugger inject javascript
I figured out while I got the same error message ( INVALID SCRIPT HEADER ) that it accoured cause of a typo between the // ==UserScript== Header info.
wronge line
// #run-at document.end
corrected line
// #run-at document-end

Resources