E2E test Protractor issue: redirect to another page in the same window - protractor

The website I need to test requires login. However, you have to stay in the same window to keep your login information, which means if you close the window of this page, you need to login again. This gives me the problem: when I am using protractor to test the websites, it seems like each time I use browser.get(url). It will turn off the browser and open another one for the test, then I lost my login information. So I can't test the pages I want to test. Can anybody give me some suggestions, I have not figured it out for one days. Crazy!
describe('Sample List page test', function(){
beforeEach(function(){
browser.driver.get('http://localhost:8600/#/login');
browser.driver.sleep(2000);
browser.driver.findElement(by.id('google-login')).click();
});
it('should list all the items in samples',function(){
browser.get("#/osctr/sample");
expect(browser.getTitle()).toBe("Sample");
}
});
});
In the above codes, I can't get information in the sample page because I used brower.get(url), it will open a new page which I will lose my login information.

When you do browser.driver.get(), it would open a new windown. That's how selenium-webdriver works. There was an issue opened longtime back to attach webdriver instance to an existing browser window which is now marked as NotFeasible.
If you want to keep the browser session intact, you can do browser.driver.get() in before() method instead of beforeEach() and have multiple tests that work on the same browser instance and quit the browser in after method.

Related

Facebook Javascript API "This authorization code has been used" on quick screen refresh (F5 or COMMAND+R)

I'm using the Facebook Javascript API for login in conjunction with the official Facebook PHP SDK on my server to execute the two following lines of code:
$helper = $fb->getJavaScriptHelper();
$accessToken = $helper->getAccessToken();
With the token, I'm further able to execute this code which gets the necessary details I need on the server:
$fb->setDefaultAccessToken($accessToken);
$response = $fb->get('/me?locale=en_US&fields=name,first_name,last_name,email,gender');
If I refresh the webpage I'm working with and let it fully load everything works correctly and I'm able to print to screen all of the details I get back in $response.
The problem I'm having, however, is that if I quickly refresh the screen (either by hitting F5 on Windows machines or COMMAND+R on Macs) before the Facebook javascript code executes I get the following thrown error from the Facebook API:
"This authorization code has been used"
How do I avoid this? Do I wrap the Facebook code on the client side in a jQuery document ready function? I hesitate to do that because I've been told that the Facebook Javascript code is good to go as a stand-alone script that is intelligent enough to know when the document is loaded.
I'm about ready to throw in the towel and just code a manual login process that totally bypasses the Facebook Javascript API. Thanks for your help.
Put the access code into a $_session['access_token'] and then redirect to another page to get the data.
Login Page
Callback Page (save into the session variable)
Working Page (work with the session variable)
See more: https://benmarshall.me/facebook-php-sdk/#example-login

Having trouble AFTER form submission with zombie.js

I have the following setup on my site:
You enter credentials on a login page and that takes you to a second page (which normally produces no screen output) which validates the user and redirects them to the appropriate homepage.
My step definitions consist of three steps:
Load up initial login page.
Enter credentials and submit.
Verify (by checking page title) that I made it in the homepage.
My first step passes with flying colors.
My second step claims to pass.
My third step fails.
Upon review, I found that it's because the second step, while officially it didn't fail, didn't do what it was supposed to do. Zombie got stuck on the validation page. At first I thought it was just missing the redirect, but it seems that it doesn't execute ANYTHING on the validation page. I even commented out the entire page and simply put an output of "Hello" at the top of the page. If my browser.html(); can be believed, it doesn't even see that. I know I make it to the second page because I have
console.log("\n" + browser.location.href);
which shows me the URL of the second page.
I then have
console.log(browser.html());
which is empty.
I even have a:
browser.wait(10000,callback);
beforehand to give it some processing time but to no avail.
Some information that might be relevant:
This is a ColdFusion site. I know zombie's handling the concept of CF since it's loading the login page initially, although there's not much actual CF processing going on there.
There's DB access happening. If zombie is accessing like a regular browser, it shouldn't make a difference, but it's there. Although even when I comment everything out, it still doesn't work, so I doubt that's actually relevant.
This is my script portion for the login step. Please advise if I'm approaching this the wrong way.
this.When(/^I input my credentials$/, function(callback) {
browser.fill("login", "myusername").fill("password", "mypassword");
browser.document.forms[0].submit();
// Put in here to account for redirect time it will take to get past validation page to actual home page
browser.wait(10000,callback);
callback();
});
If you need any other information, please let me know. I would appreciate any help whatsoever in being able to make this work!
I am not sure I fully understand your problem, but it looks like this may be an issue with the way you are handling asynchronous calls. At any rate, you should not need to browser.wait for something like this at all. Try something like the following:
this.When(/^I input my credentials$/, function(callback) {
browser
.fill("login", "myusername")
.fill("password", "mypassword")
.pressButton("#selectorForYourButton", function (err) {
// Check for errors or any other behaviour this test is actually about
callback();
});
});
First, the pressButton method is preferable because it gets closer to testing actual browser interaction. But more importantly, callback() is only executed after all the events fired off by pressing the button have been resolved.

How to redirect to an external url with Selenium, and come back?

I am working in perl with Selenium RC, server version 2.19.0-b09 and I cannot figure out whether it is even possible to redirect to an external URL and come back to my application. I am trying to test Facebook OAuth in my application, which means I have to go to Facebook and come back to my app.
use Test::WWW::Selenium::Catalyst 'MyApp', -selenium_args => 'injectProxyMode -trustAllSSLCertificates -debug -log /home/me/browserlog.txt -firefoxProfileTemplate /home/me/.mozilla/firefox/SeleniumUser.default/';
my $selenium = Test::WWW::Selenium::Catalyst->start({
browser => '*chrome',
});
The reason I think this is possible at all is because a custom Firefox profile and the -injectProxyMode, *chrome browser and -trustAllSSLCertificates options enable me to post to and see all the redirects in my debug log, but my Remote Control window always disappears after the redirects. I can see the PROXY URL to which Facebook is trying to send me back, e.g., a URL on my own base domain. But it looks like there is no window for it to return to. In multiWindow mode I am left with my application in a Firefox window. In singleWindow mode my tests just end and all the windows close.
I have tried both -singleWindow and -multiWindow mode. I have gotten the list of windows after I make my post to https://www.facebook.com:443/login.php... and before all the redirects. I see a single window that is never available to select_window, and it always disappears on the second iteration if I run get_all_window_names in in a while loop: a window with a name like "_e_0RWG".
So, how could I conceivably do what I am trying to accomplish with Selenium? It seems so near and yet so far.

Facebook Login throws "Permission denied"

I am adding Facebook login to my existing asp.net application. I have added a Facebook login button to my login screen. Now, I click Facebook's login button and in IE 9 it throws client-side exception in all.js on Line 22: if(a.params)b.fbCallID=a.id;
Even after that exception I see the Facebook login screen and can log in, and in the main browser window I get the auth.login event, so I can live with that.
But, if I am already logged in to Facebook, I come to the page and click Facebook login button, I briefly see the empty popup window, then I get teh same client-side exception, and then I get no event in the main browser window, so I don't know if the user logged in so I can't redirect them to another page.
I tried the channelUrl trick but it didn't help.
Any suggestions what's going on?
I found this hack that fixed the issue for me; add this line right after you call FB.init():
// Hack to fix http://bugs.developers.facebook.net/show_bug.cgi?id=20168 for IE7/8/9
FB.UIServer.setLoadedNode = function (a, b) {
FB.UIServer._loadedNodes[a.id] = b;
};
The reason it is happening (from the websites and documents I have read, and believe me, I've read a LOT) is that IE refuses cross-site javascript, and it sees the all.js as crossing the sandbox border. A good discussion can be found here.
Some people say that adding the channel.html file works, but we have tried all flavors of that, and have not had any success. (Remember that the http or https must match the page sending the request.)
Microsoft makes reference to this same issue and their advice is to add the site to trusted sites (that doesn't help). Old advice (from last year) is to add CP="HONK" as your compact privacy policy, but I think that bug was fixed, and it was cookie-related.
What seems to be happening to us is that the login actually continues, and the callback gets called properly, but the main thread that should complete outside of the login call stops executing (because of the error). So, any functions outside the login fail to execute after the login call.
If anyone has a way to get IE to not throw the exception or to create a workaround for this issue, I am desperate to have it. Any info needed I will be happy to provide, but a sample is here:
enter code here
code before login here...
FB.login(function(response){
callback stuff here... This part fires.
});
main thread stuff here... This fails because of permission denied error.

FB.getLoginStatus not calling its callback

The title really says it all. Under some (undetermined) conditions FB.getLoginStatus() just stops working and won't invoke the callback I gave it. The only interesting clues I've found are
FB.Auth._loadState is stuck on "loading" -- whatever is supposed to make it click over to "loaded" isn't happening
slight delays like putting in alert() calls tend to make it start working
Any hints at all about even how to investigate this welcome.
This usually happens for me when I am running the page under a different domain from what has been registered in Facebook. Typically this is when I am developing locally.
If you are running locally, you'll have to set up a local web server and then modify your hosts file to point the the registered domain to 127.0.0.1 in order to test on your local machine. Don forget to remove that line from the hosts file when you want to test it on the server.
According to:
https://developers.facebook.com/bugs/240058389381072
You cannot put your application under sandbox mode, or else it won't work. Go into your app settings, advanced, and switch it. This stumped me for a couple hours until I happened upon the bug report.
I had similar problem with FB API. It turned out, that my Facebook App was misconfigured. Please make sure that this is not the case for you. My problem was that my "Site URL" param in FB application was pointing to https, but I was using http protocol for development. Any call against FB api after FB.init was not calling my callback functions. So the first thing to do should be to double check App config.
Now, if some reason you depend on FB api but you wish to have a fallback option in case it;s inoperative - workaround with timer should be ok for you. Just set up a timer and disable it if FB Api gives you proper response. If not - fallback to some custom function which will perform some additional logic.
function callFbApi() {
var timeoutHandler = setTimeout(function() { requestFailed(); }, 1000);
function requestFailed() {
// When this happens, it means that FB API was unresponsive
doSomeFallbackWork();
alert('hey, FB API does not work!');
}
FB.getLoginStatus(function(response) {
clearTimeout(timeoutHandler); // This will clear the timeout in case of proper FB call
doSomeUsualWorkAfterFbReplies();
return false;
}, true);
}
If your application is in sandbox mode, Facebook acts as if your application is invisible to anyone who is not listed as an application developer. If you're not logged in, then it would stand to reason that your app is now invisible.
The callback will only fire if you're initializing with a visible application. Otherwise the following response is returned:
<span>Application Error: There was a problem getting data for the application you requested. The application may not be valid, or there may be a temporary glitch. Please try again later. </span>
For more info please see my comment on this bug ticket:
https://developers.facebook.com/bugs/240058389381072
Maybe you are using the asynchronous call. The same thing happened when I called FB.init with window.fbAsyncInit. All I did was delay the FB.getLoginStatus with a setTimeout function
window.setTimeout(checkLogStatus, 1000);
function checkLogStatus(){
alert("check");
// fetch the status on load
FB.getLoginStatus(handleSessionResponse);
}
It seemed to work after that
On the new version of the Developer app, you have to make sure to have put the correct URL you are using to access the application in the Website field under the
Select how your app integrates with Facebook
section.
Make sure the protocol is HTTPS and not HTTP.
I had a similar problem. The site worked every time when I was opening the browser, but fails when I tried to reload.
The cause was the missing "www" on the site name on Facebook configurations. Note that putting "www" (like www.yoursite.com) works on both situations (yoursite.com or www.yoursite.com).
As others have posted, you must be accessing your site at the same URL that facebook expects. For example if facebook has a callback "example.com" but you're browser has "www.example.com", that can cause this problem.
In addition, if third-party cookies are not allowed by your browser, you may also see this problem. Or you may see the callback erroneously reporting the user is not connected.
Just posting a situation I had were calling FB.getLoginStatus got absolutely no response.
My application is designed to run in a tab, and I only entered the Page Tab URLs on the app admin page, and not the App On Facebook (i.e. Canvas) URLs. The tab loads perfectly, but any calls to the FB JS SDK provoke no response.
In Facebook App Settings, go to Client OAuth Settings, look at Valid OAuth redirect URIs
Make sure you have listed all URIs which are the domains from which Facebook SDK is being invoked. For example:
I develop at localhost:5000 and deploy to Heroku. Notice the format: http://domain.name/