Strange redirecting with koala gem - ruby

I'm using ruby, sinatra, and the koala gem to create an app for facebook.
When I redirect to /auth/facebook It does what is needed, however it first redirects to a page with this rectangle, then goes to the auth dialog. I think this is very ugly for the end user. How can I remove this strange redirection?
Code:
#This function defines a get and post route with the same parameters.
def get_or_post(path, opts={}, &block)
get(path, opts, &block)
post(path, opts, &block)
end
get "/auth/facebook/?" do
redirect authenticator.url_for_oauth_code(:permissions => FACEBOOK_SCOPE)
end
get_or_post '/auth/facebook/callback/?' do
session[:access_token] = authenticator.get_access_token(params[:code])
update_user()
redirect '/'
end

I guess you are doing the redirect inside of the canvas iframe? That of course would try to display the auth dialog inside of that iframe, and the auth dialog does not want to be displayed in any kind of (i)frame.
So instead of redirecting (where you can not specify a target), use JavaScript to “redirect” – have your script put out a small HTML document, that basically just contains one line of JavaScript, that uses
top.location.href = '{auth dialog URL goes here}';
to load a new URL in the top frame of the current browser window.

Related

Follow post form redirects using Ruby Mechanize

We're trying to follow post forms that initialize redirects before showing their content using ruby Mechanize/Nokogiri. One example would be the search form on
http://www.chewtonrose.co.uk/
... if you hit the "search" button on your browser, you get taken to
http://www.chewtonrose.co.uk/AdvancedSearch/tabid/4280/Default.aspx?view=tn
how could we set up Mechanize to return that second url?
is Mechanize even the right tool?
Yes, mechanize is good. I checked in this case you will need to submit WITH the button.
agent = Mechanize.new
page = agent.get(<url>)
form = #get form
button = #get button
page2 = agent.submit(form, button)
page2.uri # will show your 2nd url

Ruby on Rails - run Ruby File.open only when link is clicked

In my application I have a link_to that I use for voting purposes. This link_to does different things if user_signed_in? or not.
When user IS signed in, they can vote, otherwise a modal opens for them to sign up or login.
What I want to achieve is to count how many users has clicked on voting buttons but didn't vote because of sign up.
I was thinking to do a easy ruby operation and add 1 and date for each click.
Here is my link:
= link_to_unless has_voted?(#image.id, 1), (image_tag 'vote/thumb-up.png'),user_signed_in?? vote_image_path : File.open("public/count.txt", "a+") { |file| file.puts ([1, Date.today]).join }, data: {target: user_signed_in?? "" : "#login-modal", toggle: user_signed_in? ? "" : 'modal'}, remote: true
Everything works fine when user is signed in, but when I want to run:
File.open("public/count.txt", "a+") { |file| file.puts ([1]).join }
is when things goes wrong.
This adds the number, but instead of adding number to count.txt file only when link_to is clicked, it also adds 1 for each visit/refresh.
How can I make File.open("public/count.txt", "a+") { |file| file.puts ([1]).join } only run when link_to is clicked and not on each visit/refresh.
I have been thinking to make a route and add the function there and redirect back, but then I can't open sign up modal and at same time I do not want to refresh the page and send user back and forward.
Seems to me like it would be a good fit for server-generated JavaScript responses.
To summarize the concept:
create a link which triggers an AJAX request to the server (using link_to with remote: true)
let the server decide whether to count the vote or increase the voted-but-not-logged-in-counter and show the modal. Based on this it will generate the corresponding JavaScript which will be executed on the client
the client receives a JavaScript response and executes it
It is your decision whether the modal functionality is already loaded from the start and the server just returns showLoginModal(); or whether the server response contains the whole JavaScript to create the modal.

Ruby Watir -- Trying to loop through links in cnn.com and click each one of them

I have created this method to loop through the links in a certain div in the web site. My porpose of the method Is to collect the links insert them in an array then click each one of them.
require 'watir-webdriver'
require 'watir-webdriver/wait'
site = Watir::Browser.new :chrome
url = "http://www.cnn.com/"
site.goto url
box = Array.new
container = site.div(class: "column zn__column--idx-1")
wanted_links = container.links
box << wanted_links
wanted_links.each do |link|
link.click
site.goto url
site.div(id: "nav__plain-header").wait_until_present
end
site.close
So far it seems like I am only able to click on the first link then I get an error message stating this:
unable to locate element, using {:element=>#<Selenium::WebDriver::Element:0x634e0a5400fdfade id="0.06177683611003881-3">} (Watir::Exception::UnknownObjectException)
I am very new to ruby. I appreciate any help. Thank you.
The problem is that once you navigate to another page, all of the element references (ie those in wanted_links) become stale. Even if you return to the same page, Watir/Selenium does not know it is the same page and does not know where the stored elements are.
If you are going to navigate away, you need to collect all of the data you need first. In this case, you just need the href values.
# Collect the href of each link
wanted_links = container.links.map(&:href)
# You have each page URL, so you can navigate directly without returning to the homepage
wanted_links.each do |link|
site.goto url
end
In the event that the links do not directly navigate to a page (eg they execute JavaScript when clicked), you will need to collect enough data to re-locate the elements later. What you use as the locator will depend on what is known to be static/unique. As an example, I will assume that the link text is a good locator.
# Collect the text of each link
wanted_links = container.links.map(&:text)
# Iterate through the links
wanted_links.each do |link_text|
container = site.div(class: "column zn__column--idx-1")
container.link(text: link_text).click
site.back
end

links opening in new window - Cheezy page-object ruby gem with selenium

I'm new to page-object and selenium, but so far it's all been going ok. The last elements I'm testing for this page are social media links.
To check that the links are correct i usually click them and then use selenium's driver.current_url to check that the url of the window is what we'd expect for that link, but these social media buttons are opening links in a new window (this is just to their static facebook page rather than a login etc) which causes the test to fail
is there a way of either:
1-forcing the link to open in the current window, or
2-extracting the target url from the link_element?
this is what the tests look like atm:
def test_facebook_button
assert #testpage.facebook_icon?, 'Facebook button not found'
#testpage.facebook_icon_link
sleep 5
assert #browser.current_url == '<facebookurlforsite>', 'Facebook link does not open expected URL'
end
if not i'm guessing i'd just use the actual selenium methods as some sort of exception to manually grab the properties of the link, i'd rather not some elements be in the page model and some out in the test itself but i can see how it's probably necessary
If you are just checking that the link navigates to the right URL, checking the link's href attribute will be the quickest. The PageObject::Elements::Link elements have an href method for this.
Assuming that facebook_icon_link is your link defined by an accessor method, you would call:
facebook_icon_link_element.href
In other words, the assertion could be written as:
assert facebook_icon_link_element.href == '<facebookurlforsite>'

instantiating a page object in Ruby with Selenium and Cucumber

I'm trying to automatize a browser to navigate a website and click on different pages. To do this I have two classes AllPages and SearchPage which inherits from AllPages.
The first thing I do is instantiate AllPages, go to the website and click a link which leads me to a Searchpage, at which point I try to instantiate SearchPage using these lines of code
AllPages:
def return_search_page browser
#browser = browser
end
Steps:
#newpage = AllPages.new #browser
#searchpage = #newpage.return_search_page #newpage
#searchpage.find_searchbox
the error i get trying to run this is:
"undefined method `find_searchbox' for #< AllPages:0x00000002632cf0> (NoMethodError)"
My method find_searchbox which is located in SearchPage is this
def find_searchbox
#browser.find_element(:class, "searchbox")
end
I'm guessing i'm freaking up the instantiation of the object #searchpage, since that's in a scenario that comes after opening the browser and navigating to the website.
Any help will be appreciated
def return_search_page browser
SearchPage.new browser
end
#newpage = AllPages.new #browser
#searchpage = #newpage.return_search_page #browser
#searchpage.find_searchbox
And if you are setting #browser in your initialize, you wouldn't need to pass it in as a parameter to #return_seearch_page

Resources