In my code i am opening a browser as follow :-
Capybara.current_driver = :selenium
include Capybara::DSL
describe 'Auro' do
specify "OMX Manual Order" do
visit 'https://omx.ordermotion.com/en/console.asp'
end
How can i close this browser?
Have Tried following ,but no luck:-
Capybara.current_session.driver.reset!
page.execute_script "window.close();"
If you're only using selenium, then the following should work:
page.driver.quit
However, if you ever want to switch between different webdrivers, then you might want to add a condition or two. This is what I use:
page.driver.quit unless (Capybara.current_driver == :webkit || Capybara.current_driver == :sauce)
:webkit refers to the headless capybara-webkit and :sauce refers to Sauce Labs, but you can use that code for whichever webdrivers you want to use.
Hope that helps!
Try some of these
page.driver.browser.close
or
window = page.current_window
window.close
Keep in mind that if you have no other windows to switch to, an error will be raised
Try giving this a shot:
page.execute_script "window.close();"
Related
Like the title says capybara is having trouble finding double_click:
undefined method `double_click' for #<Capybara::Node::Element:...>
Click works just fine as do most other methods. I'm using capybara 2.1.0, poltergeist 1.6.0 and phantomjs 1.9.7. Any ideas?
For posterity here's the solution:
I set javascript_driver:
Capybara.javascript_driver = :poltergeist
but not default_driver:
Capybara.default_driver = :poltergeist
Are you sure you have a valid Capybara element that can be clicked on?
page.find('#lst-ib').double_click
The above works on Google.com
For double click event, the below approach might help you solve your problem.
I know its bit late but for people who might face similar issue in their automation work
On latest ruby capybara and selenium version use
element = page.find(:xpath,"//a[contains(text(), locator)]")
page.driver.browser.action.double_click(element.native).perform
for Old version pls use the below code:
element = page.find(:xpath,"//a[contains(text(), locator)]")
page.driver.browser.mouse.double_click(element.native)
Find the element with either xpath or css.
Use page.driver.browser.mouse.double_click(element.native) to perform the action
I'm using Capybara and Poltergeist and cannot for the life of me get all my tests to consistently pass. I have this one issue in particular with a date selector. It should be really simple - user clicks on input, out puts a selection of months (first image). A month is then clicked, and then a day selection appears (second image), on which a day of the month is selected.
Now, my code looks as follows:
all(:css, 'input.from_date').last.click
expect(page).to have_css(".datepicker-months")
within(:css, '.datepicker-months') { find('.month', :text => 'Jun', match: :first).click }
expect(page).not_to have_css(".datepicker-months")
expect(page).to have_css(".datepicker-days")
within(:css, '.datepicker-days') { find('.day', :text => work[:start_date].stamp('31').to_i.to_s, match: :first).click } #.to_i.to_s used to remove leading zeros
page.assert_no_selector('.datepicker-days')
Sometimes it passes, but most of the time it says:
expected to find css ".datepicker-days" but there were no matches
or
expected not to find css ".datepicker-months", found 1 match: "« 2015 » JanFebMarAprMayJunJulAugSepOctNovDec"
If I try and debug this by calling binding.pry, I can run the commands step by step in the console and it works perfectly. My timeout is set to more than enough (i think). Any ideas why this test fails intermittently?
My config:
Capybara.javascript_driver = :poltergeist
Capybara.default_wait_time = 60
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
timeout: 60,
js_errors: false,
phantomjs_logger: File.open("log/phantomjs.log", "a")})
end
UPDATE:
When adding sleep(0.5) after every step in the process, it passes each and every time. This is bad practice and I'm supposed to be able to write tests without doing this. :/
Whenever I run into these inconsistencies, I try to find other things to assert against so that you don't have to count on sleep.
If there are any sort of animations that start/stop, you can try to assert against those.
You can also try to be more specific in your current expectation, since it seems like you had no trouble clicking on the object you found
expect(page).not_to have_css('.datepicker-months .month', :text => 'Jun')
If any of that gets you any farther let us know.
[7] pry(#<RSpec::Core::ExampleGroup::Nested_1>)> page.execute_script "window.close()"
Selenium::WebDriver::Error::NoSuchWindowError: Script execution failed. Script: window.close();
The window could not be found
[8] pry(#<RSpec::Core::ExampleGroup::Nested_1>)> page.driver.browser.window_handles
=> ["f1-2"]
I had a browser open with two tabs, the above command does close one but the last tab never closes. It is open but when I try to run page.execute_script "window.close()" it gives the above error.
page.driver.browser.window_handles.each do |handle|
page.driver.browser.switch_to.window(handle)
page.execute_script "window.close()"
end
The above code was working for me sometime back but doesnt work anymore. It gives the same error.
UPDATE:
When I use,
page.driver.browser.window_handles.each do |handle|
page.driver.browser.switch_to.window(handle)
page.driver.browser.close
end
it gives the following error Selenium::WebDriver::Error::UnknownError: 'auto_id' does not refer to an open tab
Two ways you can do it
In line with your technique using JS. You would first need to switch back to your first browser window (window_handle) and then perform "window.close()". (Not Preferred) (Not sure why its not working now for you, did you upgrade server version or different browser?)
Simply use #driver.quit (Preferred)
Update
Just write this once. This will close all windows.
after(:each) do
#driver.quit
end
If you want to close only one browser tab/window/popup, switch to that window_handle and then perform
#driver.close();
page.driver.browser.close closes current tab towards the end and the last (second) tab closes itself after each example.
in case if you are using cucumber, you can the use the BEFORE/AFTER hooks .please refer similar question on stackoverflow
for some more on cucumber,please refer this Cucumber Hooks
Perhaps this isn't actually the issue I'm experiencing, but it seems that when I "click_link" a link with target="_blank", the session keeps the focus on the current window.
So I either want to be able to switch to the new window, or to ignore the _blank attribute - essentially, I just want it to actually go to the page indicated by the link so I can make sure it's the right page.
I use the webkit and selenium drivers.
I submitted my findings thus far below. A more thorough answer is much appreciated.
Also, this only works with selenium - the equivalent for the webkit driver (or pointing out where I could discover it myself) would be much appreciated.
Capybara >= 2.3 includes the new window management API. It can be used like:
new_window = window_opened_by { click_link 'Something' }
within_window new_window do
# code
end
This solution only works for the Selenium driver
All open windows are stores in Selenium's
response.driver.browser.window_handles
Which seems to be an array. The last item is always the window that was most recently opened, meaning you can do the following to switch to it.
Within a block:
new_window=page.driver.browser.window_handles.last
page.within_window new_window do
#code
end
Simply refocus for current session:
session.driver.browser.switch_to.window(page.driver.browser.window_handles.last)
Referenced on the capybara issues page: https://github.com/jnicklas/capybara/issues/173
More details on Selenium's window switching capabilities: http://qastuffs.blogspot.com/2010/10/testing-pop-up-windows-using-selenium.html
This is now working with Poltergeist. Although window_handles is still not implemented (you need a window name, i.e. via a JavaScript popup):
within_window 'other_window' do
current_url.should match /example.com/
end
Edit: Per comment below, Poltergeist now implements window_handles since version 1.4.0.
Capybara provides some methods to ease finding and switching windows:
facebook_window = window_opened_by do
click_button 'Like'
end
within_window facebook_window do
find('#login_email').set('a#example.com')
find('#login_password').set('qwerty')
click_button 'Submit'
end
More details here: Capybara documentation
I know this is old post, but for what its worth in capybara 2.4.4
within_window(switch_to_window(windows.last)) do
# in my case assert redirected url from a prior click action
expect(current_url).to eq(redirect['url'])
end
Seems like it is not possible with capybara-webkit right now: https://github.com/thoughtbot/capybara-webkit/issues/271
:-(
At the same time https://github.com/thoughtbot/capybara-webkit/issues/129 claims it is possible to switch windows with within_window.
Also https://github.com/thoughtbot/capybara-webkit/issues/47 suggests that page.driver.browser.switch_to().window(page.driver.browser.window_handles.last) works. Ah well, on to code reading.
The code at https://github.com/thoughtbot/capybara-webkit/blob/master/lib/capybara/webkit/browser.rb at least has some references that suggest that the API that works for webdriver / firefox is also working for webkit.
Now within_window implemented for capybara-webkit http://github.com/thoughtbot/capybara-webkit/pull/314 and here you can see how to use it http://github.com/mhoran/capybara-webkit-demo
As of May 2014 the following code works on capybara-webkit
within_window(page.driver.browser.window_handles.last) do
expect(current_url).to eq('http://www.example.com/')
end
To explicitly change window, you use switch_to_window
def terms_of_use
terms_window = window_opened_by do
click_link(#terms_link)
end
switch_to_window(terms_window)
end
An after that method browser will work in the new page, instead of wrap everything in a within_window block
This works for me in capybara-webkit:
within_window(windows.last) do
# code here
end
(I'm using capybara 2.4.1 and capybara-webkit 1.3.0)
You can pass a name, url or title of the window also
(But now its dipricated)
let(:product) { create :product }
it 'tests' do
visit products_path
click_link(product.id)
within_window(product_path(product)) do
expect(page).to have_content(product.title)
end
end
You can pass a labda or a proc also
within_window(->{ page.title == 'Page title' }) do
click_button 'Submit'
end
wish it stretches the method usage to more clearly understaing
I had this issue when opening links in an gmail window: I fixed it like this:
Given /^(?:|I )click the "([^"]*)" link in email message$/ do |field|
# var alllinks = document.getElementsByTagName("a");
# for (alllinksi=0; alllinksi<alllinks.length; alllinksi++) {
# alllinks[alllinksi].removeAttribute("target");
# }
page.execute_script('var alllinks = document.getElementsByTagName("a"); for (alllinksi=0; alllinksi<alllinks.length; alllinksi++) { alllinks[alllinksi].removeAttribute("target"); }')
within(:css, "div.msg") do
click_link link_text
end
end
The best idea is to update capybara to the latests version (2.4.1) and just use
windows.last
because page.driver.browser.window_handles is deprecated.
The main implementation (window_opened_by) raises an error for me:
*** Capybara::WindowError Exception: block passed to #window_opened_by opened 0 windows instead of 1
So, I resolve it by this solution:
new_window = open_new_window
within_window new_window do
visit(click_link 'Something')
end
page.driver.browser.window_handles
# => ["CDwindow-F7EF6D3C12B68D6B6A3DFC69C2790718", "CDwindow-9A026DEC65C3C031AF7D2BA12F28ADC7"]
I personally like the following approach since it works correctly regardless of JS being enabled or not.
My Spec:
it "shows as expected" do
visit my_path
# ...test my non-JS stuff in the current tab
switch_to_new_tab
# ...test my non-JS stuff in the new tab
# ...keep switching to new tabs as much as necessary
end
# OR
it "shows as expected", js: true do
visit my_path
# ...test my non-JS stuff in the current tab
# ...also test my JS stuff in the current tab
switch_to_new_tab
# ...test my non-JS stuff in the new tab
# ...also test my JS stuff in the new tab
# ...keep switching to new tabs as much as necessary
end
Test helpers:
def switch_to_new_tab
current_browser = page.driver.browser
if js_enabled?
current_browser.switch_to.window(current_browser.window_handles.last)
else
visit current_browser.last_request.fullpath
end
end
def js_enabled?
Capybara.current_driver == Capybara.javascript_driver
end
I've tried several examples found online, but with no luck. I am looking to confirm the confirm message of a delete link. The last attempt was the code below, but that resulted in an Capybara::NotSupportedByDriverError error.
def confirm_dialog
page.evaluate_script('window.confirm = function() { return true; }')
end
Adding an answer for those hitting this in 2016 and beyond. You can now use Capybara directly to accept a confirmation box. You do this by wrapping the code that causes the confirmation box to appear in the accept_confirm function.
accept_confirm do
click_link 'Destroy'
end
First of all switch to using Selenium as the driver by putting an #javascript tag in front of your scenario.
The following code in your cucumber step will then confirm the dialogue:
page.driver.browser.switch_to.alert.accept
# or
page.driver.browser.switch_to.alert.dismiss
# or
page.driver.browser.switch_to.alert.text
As #NobbZ said, this question has been asked and answered before here: How to test a confirm dialog with Cucumber?.
More selenium documentation available here too: http://code.google.com/p/selenium/wiki/RubyBindings#JavaScript_dialogs
for capybara-webkit:
page.driver.browser.accept_js_confirms
page.driver.browser.reject_js_confirms
which is still working, but the documentation says also:
page.driver.accept_js_confirms!
page.driver.accept_js_confirms!
See https://github.com/thoughtbot/capybara-webkit , search "accept_js_confirms"
I've had timing issues with browser dialogs in a CI environment so I'm polling for a dialog before accepting it:
def accept_browser_dialog
wait = Selenium::WebDriver::Wait.new(:timeout => 30)
wait.until {
begin
page.driver.browser.switch_to.alert
true
rescue Selenium::WebDriver::Error::NoAlertPresentError
false
end
}
page.driver.browser.switch_to.alert.accept
end
I had to use a sleep in the webkit test since it would fail everynow and then otherwise.
Here is what I came up with after reading everyones posts:
if page.driver.class == Capybara::Selenium::Driver
page.driver.browser.switch_to.alert.accept
elsif page.driver.class == Capybara::Webkit::Driver
sleep 1 # prevent test from failing by waiting for popup
page.driver.browser.accept_js_confirms
else
raise "Unsupported driver"
end
try to add :js => true to your test.
RSpec’s metadata feature can be used to switch to a different driver.
Use :js => true to switch to the javascript driver, or provide a
:driver option to switch to one specific driver. For example:
it 'will use the default js driver' :js => true do
...
end
In Capybara its very simple to accept the model window. Even we can do the same in selenium but its little tough for people who are not aware about selenium.
page.accept_modal #This will accept the modal window
page.dismiss_modal #This will Reject/Dismiss the modal window
I would guess that you have to add selenium to your gem-file and configure it and capybara that capybara uses selenium as the driver.
I think also that How to test a confirm dialog with Cucumber? is very similar to your question, especially the accepted answer.