Can you close all open windows in capybara? - ruby

So when I run my tests individually, they work great. However, when I run my feature (multiple tests) my code is failing.
This is because when capybara exists, not all of my windows are closing and therefore my selenium drivers don't know which window to use.
Basically, what is happening is that my test is opening multiple windows. This is happening because my tests are clicking links which open new windows and checking the content in the new windows. Even though I am saying page.quit at the end of each test, this function isn't closing all open windows (closes active window but not the original window). When the 2nd test runs, it uses the originally create window, but when it goes to open the new pop up, it uses the wrong window.
How can I ensure that a new browser is being used during each test and all windows from the previous test are closed.
I am currently using page.reset! and page.quit.
Not sure, but can I say session.quit to close all open browser windows?

This code works:
page.execute_script "window.close();"
I just execute this while in the window I want to close.

I use this code piece to access popups and close them after. It should not be much difference
within_window(page.driver.browser.window_handles.last) do
click buttons and stuff...
...
page.driver.browser.close #closes popup
end
Hope it helps

page.driver.browser.window_handles.each do |handle|
page.driver.browser.switch_to.window(handle)
page.execute_script "window.close()"
end
Did the charm for me. Combination of #Jason and #Justin's answers.
Thanks!

Try the following:
page.driver.browser.window_handles.each do |handle|
page.driver.browser.switch_to.window(handle)
page.quit
end
(I think it will work, but I have not had a chance to test it.)

Try this:
tab_id = page.driver.find_window("http://google.com.au")
page.driver.browser.switch_to.window(tab_id)
page.driver.quit
This worked for me.

In order to have all assertions in spec file, I passed control to new page (window), after executing assertions I closed new page and passed control to original page as bellow:
after(:each) do
expect(#static_page.has_logo?).to eq(true) # assertion in new page
page.execute_script('window.close()') # close new page
switch_to_window(windows.first) # return control to first page
end

Adding this here because this page comes up within the first few Google results for "capybara close all windows".
We had some mysterious feature spec failures that we tracked down to a few that opened app links in second tabs -- since the tabs were just left open, every so often they'd fire a failing AJAX request and the current test would bomb out with a completely unrelated error. The way we fixed that was to add a hook that made sure to close all but the current window after every feature spec:
Rspec.configure do |config|
config.after(type: :feature) do
# Make sure all browser windows except one are closed
windows.reject(&:current?).each(&:close)
end
end
This worked like a charm for us, using Capybara's headless_chrome driver.

Add this to your feature tests, it'll reset the session cookies and start the test on a blank page:
# Window washing - use a clean window before every example
before(:example) do
page.reset!
end

Related

Selenium WebDriver in Ruby: Preventing the test from closing the browser window at end

I appear to be having the exact opposite problem many other people have - in that my Selenium tests in Ruby will close the browser window at test end, no matter what the end result is. Pass or fail, it will always close the browser. I would like to stop this.
Context:
Previously I coded tests in Java using IntelliJ IDEA. Browser windows for Selenium tests in this case would NOT close at all period unless you used driver.quit(). This is actually quite useful as it means that the browser window would stay open if the test failed - which meant I could look at where it stopped in the browser and help figure out why it failed. This was also useful for test writing as it meant that I could essentially pick up where I left off to write the next block instead of having to keep a parallel tab going in another browser by hand to get the next set of selectors in the given screen.
I've found in Ruby using RubyMine that the browser will close when the test ends in any capacity. This is a bit of a problem. While technically I could take a screencap on failure, it'd mean that I'd have a harder time retracing why it failed (back button on browser, typing in fields to work out if a quirk in our UI caused it, etc). And of course, screencaps take up hard drive space. ;)
I've tried the detach=true (and True) command switch for Chrome and that has not worked.
Setup:
IDE: RubyMine
Gems: selenium-webdriver
Browser: Chrome, using ChromeDriver. (In Ruby this just involves using WebDriver)
OS: OSX
Not headless, using no other frameworks/testing environments. It is quite literally a few lines of setup and then hitting the run button in RubyMine in a bog-standard .rb.
Summary:
I haven't been able to find any existing questions here or in other places online for Ruby specifically for keeping a Selenium test in RubyMine from closing the window on test end. "Test end" in this case refers to success (reaching the end of the .rb) or failure (Tracebacks, in this case). I would prefer that the window would stay open until it'd hit a driver.quit line. Is there any way I can set this up?
Thank you very much. I hope this isn't redundant. I also hope this will help other testers in the future :)
You can use the :desired_capabilities to set this flag:
caps = Selenium::WebDriver::Remote::Capabilities.chrome("goog:chromeOptions" => {detach: true})
driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps
Note that old examples will be using "chromeOptions", but for newer Chrome versions, it will need to be "goog:chromeOptions".
#JustinKo has posted an answer here
Chrome detach option is no longer working
You can pass Chrome Options using the following format:
browser = Watir::Browser.new(
:chrome,
'goog:chromeOptions' => {detach: true}
)
The answer from #Justin Ko worked for me. However at the time of posting I am getting a warning telling me to use
capabilities: caps
instead of
desired_capabilities: caps
as it is now currently deprecated at the time of posting.
I do not have enough reputation to be able to comment so I am posting this as an answer.

Close window through Capybara

I am trying to launch the browser for the capybara automation. The browser is auto populating a "Error window" (non-browser window).
I need to "close/click ok" on the window to open the browser. I tried to handle this popup with the "AutoIT" executable file. When i run the AutoIT file manually, the executable file handles it successfully.
I am not able to execute through the capybara script. The code is as below
ses = Capybara::Session.new(:selenium)
IO.popen('c:\ruby\handler.exe') #- Tried this step to execute AutoIT .exe file before visit url step.
No luck here. The popup appears only when referencing with the object.
ses.execute_script "window.close()" #- Tried this step to close the window with the ses object. no luck in this too.
ses.visit "https://google.com"
Is there a way to close the window programmatically?
It seems that you should be able to register a custom selenium driver using the Chrome browser and specify the command-line option to disable all extensions, with the following driver registry code:
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome,
:switches => %w[--disable-extensions])
end
ses = Capybara::Session.new(:selenium)
...
I put this together using information here and the list of available command line options here (I did not test this myself though).
There are a few approaches to a popup error like that:
1) The easiest one is to do your approach - execute an autoit script before calling capybara to visit the site that results in the error popping up. You should ensure that the autoit script you are executing waits for the window to appear before trying to close it (see: https://www.autoitscript.com/autoit3/docs/functions/WinWait.htm for reference).
2) You could execute another ruby script/thread (keep in mind threading in ruby is a bit complicated) that would execute the autoit script in the background (in a loop) and wait for a succesfull response.
3) You could try to disable whatever is causing the error to pop up in your browser.
I will be able to provide some code following approaches 1 and 2 in a few hours if you will still have problems solving the issue.
The error Failed to load Extension. Loading of unpacked extensions are disabled by administrator. indicates that your system was set-up to disable extensions with Chrome. So even if you manage to close it, you probably won't be able to automate Chrome with Selenium since it needs to start Chrome with the driver as an extension.
Your best chance to make it work is probably to disable the restriction or to add the extension to the white list.
Here is a link about this issue:
https://bugs.chromium.org/p/chromedriver/issues/detail?id=639

Cucumber test with Selenium and Ruby in Jenkins server fails but passes in local machine

I have some cucumber tests made using the gem 'cucumber-rails'.
This tests use another gem called 'page-objects' (from cheezy) and in my tests I use Selenium and Chrome-driver.
To make the tests run in the Jenkins server (that has no X) I use the gem 'headless' and I've configured the server to use Xfvb (my local machine runs Elementary OS Freya 0.3.2 and the server runs Ubuntu 15.10).
When I run these tests in my local machine (also using headless), they all pass flawlessly every time. The same happens when I run the tests in Jenkins' server from the Terminal.
But when I run them on Jenkins CI, some fail (the error is "didn't find an element" - when the element is there).
Both tests fail because it cannot find an element (the element exists and when it fails I print the screen just to check what's happening. The page print show that it is on the right page and displays the element).
The strange thing is that they both fail at the second step (the first one is going to the login page and authenticate, which it does correctly). Also, there's another test that runs first that always passes (the tests have pretty much the same structure).
Both tests run over the same server (the webpage they access is the same and the data is the same).
I have looked at this over and over and I can't find any explanation. I know the problem is not very detailed, so if there's anything missing that might be important, just tell me and I'll update the post.
If you happen to know any reason why the tests might fail on a 'Xless' server, I would greatly appreciate it!
Thanks a lot for the help!
Edit:
The failures are both "element not found" and the element is present.
I've also made the Jenkins user part of the sudoers.
Any ideas?
Thanks a lot
The only way to solve these issues is to debug the error received. To debug, we can add screenshots at different places in the scenario to identify the cause of the failure. If this is failing as page not completely loaded, then to solve this issue, is to increase the default wait time to open the particular page or to locate an element. Once the page loads or element is located, set the default time to its original value.
Example:
1. You can add screen shot in you scenario:
Scenario: Click on Sign In Link
Given Joe opens "www.yahoo.com" page
When Joe takes screenshot with file name "ScreenShot1"
When Joe clicks "Sign In" link
The second line "When Joe takes screenshot with file name "ScreenShot1" can be used to take the screen shot
And(/^(\S*) takes screenshot with file name "([^"]*)"$/) do |user, file_name|
takes_screenshot_with_file_name(file_name, "ScreenShot")
end
def takes_screenshot_with_file_name(file_name, message)
page.save_screenshot("../../target/#{file_name}.png", :full => true)
end
Default wait time can be increased in below mentioned way:
The second line "And Joe waits for "Sign In" link" can be used to increase the default wait time
Scenario: Click on Sign In Link
Given Joe opens "www.yahoo.com" page
And Joe waits for "Sign In" link
When Joe clicks "Sign In" link
And(/^Joe waits for "([^"]*)" link$/) do |linkName|
Capybara.default_wait_time = 120
page.should have_content(linkName)
Capybara.default_wait_time = DEFAULT_WAIT_TIME
end
Things you can try:
Reduce the test to the very basics: Instead of running it all, just that concrete page and try to find that element. Check if that works. It probably won't...but you can pinpoint better the problem.
Add some waits in the code (sleep <number of seconds>), to see if your code is trying to find something "too fast". This happens time to time.
Instead of using headless, try to use something else and run it in a browser (with some gems like capybara you can switch between headless, firefox or chrome).
Can you find some sort of JS logs, to see if there are any errors?
Do Jenkins and your environment have exactly the same gem versions?
Another thing you can do to debug it is use something like byebug and set a breakpoint just before it fails. You can then use the interactive console to inspect the page, and run different commands to try to find the element. You would have to do this while in jenkins, but as a last resort...
Ok, so I found out the problem and the solution.
The problem was that the elements were still not loaded when performing their lookup. The solution was to use PageObject.wait_until to wait for them.
I realized that this was the problem after noticing the errors were sometimes these ones: Stale Element Reference
But there's a question that remains, still: why does this only happen in Jenkins CI? (whoever finds the solution will earn the bounty :) )

UFT - Object Identification not working on Run Time

I have written a code for Web page. The process requires me to click on a weblink which opens up a new window, then perform some operations on the browser window. Then I close the new browser. This is repeated multiple times in the code. All the elements on all the browser windows are normally identifiable using the object spy. However, intermittently during run time when a new browser window opens up the elements on the page are not getting recognized (hence it throws errors). When i go into the debug mode and try using the object spy the maximum identification i can capture is Browser(<>).Page(<>). Nothing in the page is getting recognized.
Now if i close this browser and reopen it and check again, the elements on the page are getting captured by the object spy and i can continue with my script execution. Sometimes I have to close and reopen multiple times for it to work.
Is there any way to handle this scenario. check for object identifications on the run time maybe. Dunno if it this is any relevant but i am not making use of the OR in my project.
Thanks in advance.
This sounds like a bug in UFT and you should contact HP's support.
A workaround if you know where the problem is probable to appear is to add Browser("<name>").RefreshWebSupport. This is an undocumented feature of UFT that sometimes helps in cases like this.

Problem with Pop-up Windows using Selenium

I'm new to the testing world, so my question might seem a lil' bit too naive and stupid. At risk of looking/sounding stupid, my question is this:
I've been trying to test the contents in a pop-up window on my company's web app. I've figured out how to detect the pop-up window for now, but i can't get selenium to 'click' on the link inside of that pop-up window. there are multiple pop-ups in this web app so it's really difficult for a newbie like to create a test case.
I tried the click, clickAndWait, mouseDown and mouseKey as an option but it is still not working. can somebody guide me through this?
TIA,
Angela
When the popup appears you will need to move the context of the script over to the window.
You can do this by using the selectWindow | window_ID_from_the_link and then do the clicking.
If that doesn't work you may need to use the openWindow command to create the popup and then start testing against that.
Use getConfirmation/getassert/getprompt according to the type of the pop up you use .....By default they will be clicked with ok option by the server and you have to consume the message from the pop up for the other selenium commands to work correctly.............
The above suggestion is given from my experience in working with selenium RC used with perl..........
Perhaps you can try the FireFox Plugin. You can click through your application and record your steps. After recording the steps you can easily save it as some sort of file or unittest.
I'm not sure about the command you should use for the popups, maybe the firefox plugin will help in this manner (it will create your commands).
If you created the popup with a div tag, U can use following code to stop the selenium server until the popup opens.
int second = 0;
while(!selenium.IsElementPresent(mylink))
{
if(second >= 5)
break;
Thread.Sleep(1000);
second++;
}
After a popup opens, Now you can click on any link inside the popup.You have to use the below code.
selenium.click("id=popup_link"); (popup_link is the id of the link present on the popup)
Good Luck.
Not sure if this is what you are looking for, but if you want to click on something specific that Selenium is not able to handle - like browser pop-ups or other pop-ups, you can use Sikuli Script. Sikuli does an image comparison and clicks on the same - this is very powerful.
Here is the link: http://www.sikuli.org/

Resources