I want to delete a particular cookie using Capybara within Cucumber test and don't want to use Webkit / Poltergeist - capybara

I have tried a couple of ways like using browser.manage.delete_cookie and also setting cookie to empty by doing something like this : page.driver.browser.manage.set_cookie("#{'cookie_name'}:") but none of them helped.
This is my Step Defn file
Given('I am on Learn Page') do
page.driver.browser.manage.window.resize_to(1800,990)
#tried this to click on the radio button from chrome settings to disable all cookies, but failed
visit "chrome://settings/cookies"
find('.//*[#id="label"]/text()').click
#find('#radioCollapse').click
#failed with this too
visit "https://mylearnwebsite.com/"
browser = Capybara.current_session.driver.browser
browser.manage.delete_cookie 'my_cookie'
#and with this as well
page.driver.browser.manage.set_cookie("{'my_cookie'}:")
end
All of them either says, unable to locate element or Selenium::WebDriver::Error::NoSuchElementError
I am a newbie to Capybara and trying to automate a couple of web application features using the same.It would be a great help if anyone from the group suggest how to proceed here.

You need to be on a page where the cookie would be valid in order to interact with the cookies (WebDriver spec limitation). Assuming that https://mylearnwebsite.com/ is the site where the cookie is valid and you're using the selenium driver then
visit "https://mylearnwebsite.com/"
page.driver.browser.manage.delete_cookie 'my_cookie' # this is driver specific
page.refresh # to reload the page without the cookie
...
would delete the cookie. Since you haven't shown what you're actually checking after removing the cookie it's hard to guess what behavior you're looking to actually test, so the code above is just calling refresh to see the page state without the cookie.
Noe: From a general system/feature testing purpose it's usually not valuable to manually interact with cookies, you're generally better off just testing the user behaviors which have a side-effect of modifying cookies.

Related

How to access cookies (Capybara/Selenium Chrome Webdriver)

I've been able to find loads and loads of examples that claim that page.driver.cookies should work but there is no such method on Selenium::WebDriver::Chrome::Driver (which is what page.driver is).
I've been trying to dig around with pry to find anything that responds to cookies, cookie_jar, set_cookie or clear_cookies but there seems to be nothing. Not on page, page.driver or page.driver.browser.
I also don't quite get the sentiment that reading cookies isn't a thing in testing (the RackTest driver exposes #cookie_jar but Rack::Test::Methods only forwards set_cookie and clear_cookies). Why shouldn't I test a middleware that sets a cookie under certain conditions?
The reason you shouldn't be testing cookies directly, is because feature/system tests are the wrong place for that. Those types of tests are designed to test things from a users perspective, and users don't actually see cookies they just see the behaviors cookies enable. Therefore, in Capybara tests, you should just be testing the behaviors enabled by cookies not that the actual cookies are set. The setting/clearing of cookies is really something that should be tested for in controller or request tests.
If you still insist on accessing cookies directly then they are accessible using JS via evaluate_script or via selenium driver specific methods page.driver.browser.manage.all_cookies, etc. - although any time you're calling page.driver.xxx you're probably doing something you shouldn't be.
Just from reading this documentation, have you tried something like this:
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome
begin
driver.get 'https://www.example.com'
# Adds the cookie into current browser context
driver.manage.add_cookie(name: "key", value: "value")
ensure
driver.quit
end

how to keep browser open (using existing session) for each scenario in capybara selenium

I am new to write integration tests in rails. Let's say i have below scenarios,
Admin logs in.
Creates a new user.
Assign new role to user.
So currently for every scenario , it opens a new browser window (or may be resetting the session).
As for login we are using 3rd party oauth it takes huge amount of time for login.
So i do not want to login for each scenario. Once after login it should execute scenarios one by one without asking for login again and again. But i am not sure how to achieve the same using rspec and selenium.
Any help would be greatly appreciated .
Capybara.current_session.instance_variable_set(:#touched, false)
Executing the above after each scenario maintains the session.
Selenium shouldn't be opening a new browser window for each scenario (unless you're specifically closing the tab in an after block), but it should reset it to about:blank. As for the rest of your request, it would be completely bypassing the intention of feature/integration tests where each test should be completely isolated from the other tests. What you should be doing, if you don't want to manually login for each test, is using the test mode of whatever auth library you're using to allow you to shortcut the login.
For instance, if using OmniAuth - see https://github.com/omniauth/omniauth/wiki/Integration-Testing

Capybara: testing when cookies, localStorage, and sessionStorage are disabled

Need help finding a way to write a test for cases where all or some of the following are disabled in the requesting browser:
cookies
localStorage
sessionStorage
I have looked at capybara-webkit and poltergeist (PhantomJS) but neither seems to allow for this functionality.
As far as disabling cookies in phantomjs via poltergeist in your test suite:
poltergeist-1.5.1/lib/capybara/poltergeist/browser.rb line 243
contains a handy method that you can use like this:
page.driver.browser.cookies_enabled= false
Then you can visit a page that checks for cookies, and confirm your app's approach to asking for cookies from the user is working. I was able to turn cookies back on later in the test as well, and confirm the recovery part of my app's workflow. No re-start necessary.
page.driver.browser.cookies_enabled= true

How to write Spock tests that share the browser sessions

I was trying to automate some functional tests using Spock (Grails app) and I'm not able to figure out how to automate the following:
I need to be able to login to one Web app and click on a link (from the web app) and open a new browser window and be logged in to the second app (because they share the user credentials - they use SSO). All the functionalities I need to test are on the second web app and there is NO direct login to that app.
I was wondering if there is a way to use the current browser session (and share the cookie) between web apps.
I would appreciate any ideas.
Answer found
I have managed to find the answers to my query. As mentioned in my comments below, I used withNewWindow() method as follows:
withNewWindow({ AnchorForNewPage.click()}){
assert at(NewPage)
do something
and something else
}
Make sure that actions you perform on the second page are all within this closure, otherwise the tests will fail.
Let me quote The Book of Geb:
The geb.spock.GebSpec class will clear the cookies in the cleanup()
method unless the spec is #Stepwise, in which case they are cleared in
cleanupSpec() (meaning that all feature methods in a stepwise spec
share the same browser state).
Not sure will it do for SSO and session sharing between two web-apps, but you may give it a try. Just keep the test steps requiring shared session as fixture methods in single Specification class.

Test stay signed in with Rspec

I'm a bit stumped on how (and where) to write some rspec tests for the "stay signed in" functionality you see all over, including on the google login.
The examples I found on the web weren't much help. Specifically I want to test these two scenarios.
1
a) user signs in with valid credentials without having clicked "stay
signed in"
b) user closes the browser, re-opens it and requests a protect page.
The user should not see the protected page.
The user should see the page asking them to signed in.
2
a) user signs in with valid credentials and having clicked "stay
signed in"
b) user closes the browser, re-opens it and requests a protected page.
The user should not see the page asking them to sign in.
The user should be taken to the protected page.
My first attempt at solving the problem involved simulating a browser close by deleting the user_id I stored in the session (since it gets deleted on browser close). However, these tests failed because I was working in the request spec folder and have no access there to the session variables. My earlier related question: session available in some rspec files and not others. how come?
What is the best way to do these test with rspec?
I think you should try standard rails method for integration tests - open_session.
Personally I never did that and can't give you tested code.
See multiple sessions example on rails guides.
There are two problems here, that I think belong into different tests:
User cannot access protected page when not logged in. That's a controller test.
User gets logged in automatically even after the session has been destroyed, so long the "remember" me flag was set in the cookie.
For #1, you can try something like:
describe UsersController do
context "when not logged in" do
context "GET users/edit" do
it "redirects to login" do
get :edit, :id => 123
response.should redirect_to login_path
end
end
end
end
You can make a more general test case that asserts all actions which aren't explicitly listed, so that you don't have test gaps if the access code later becomes more permissive by accident. But that's a more subtle point.
For #2 you can write a request spec that sets the "remember me flag", then logs out, then logs in again and checks that you get to the page you expected. Drive all this from the browser by filling out credentials, checking the remember me box, clicking buttons.
The question is: Why? Why do you want to test this? Are you using a home-grown login system? Highly discouraged, unless you're a top-notch security expert. If you're not using a home-grown system, but instead Devise which comes tested, then don't re-test the library functionality. Just only test your application code, such as access rights to certain pages, which is covered by #1. You can also take a look at the tests that come with Devise how they test for this condition.
Hope this helps.
Update To clarify the request spec for #2. As mentioned in the other answer by #cutalion (who deserves the credit for the right answer), the mechanism for verifying that login can persist across session closing is built into the ActionDispatch IntegrationTest framework with open_session.
See Rails docs IntegrationTest API which includes examples. A blog post expanding on the use of a custom DSL.
This still seems to be a recurring problem in 2018. Some basic documentation is clearly missing. I finally found a solution: "Show me the cookies" gem.
Switching the Capybara driver clears the session, so one possibility would be changing the driver in the middle of a test to simulate browser close/open. But getting an alternative driver (for example selenium, or selenium_chrome) to work is not trivial, and besides this method would probably delete all cookies.
Also this simple command resets the session: Capybara.reset_sessions! But the problem again is that it not only destroys the session cookie but also permanent cookies. So it's useless for testing "Remember me" functionality.
I finally settled on Show me the cookies gem. It was very simple to install and implement. I just followed the provided directions for rspec. The command expire_cookies provides a satisfying simulation of quitting and opening a browser.

Resources