Why won't CasperJS accept a redirect request after clicking on a link? - phantomjs

I'm having more Casper troubles, this time I've told Casper to click on a href that will redirect it to a page that will redirect it to the twitter app auth page:
var casper = require('casper').create({
verbose: false,
logLevel: 'debug',
waitTimeout: 10000
});
phantom.cookiesEnabled = true;
casper.start('http://foo.bar', function afterstart() {
if (this.exists('#back-to-top')) {
this.echo('BOOYA! foo.bar is loaded', 'INFO');
} else {
this.echo('Page didnt load, something went all screwy.', 'ERROR');
}
});
casper.then(function signin() {
this.click('a[href="/sys/login"]' );
});
casper.then(function tellsignin() {
if (this.exists('#not-logged-in ')) {
this.echo("I clicked on twitter login button, so now the twitter login page is loaded.", 'INFO');
} else {
this.echo('Twitter login link didnt work, something went wacky');
};
});
When I run it, the console error output is this, plus some other stuff that isn't important:
Test file: testingtest.js
BOOYA! foo.bar is loaded
Twitter login link didnt work, something went wacky
I've tried looking up explanations, and found this group thread, but it unfortunately doesn't provide any answers for my problem.
Does anyone know any possible reasons why Casper isn't redirecting?

I've resolved the issue thanks to all of your help and support, lol! What happened is that the tellsignin function was being executed before the browser had time to be redirected to the twitter app auth page, so I just added a this.waitForText('Authorize foo-bar app to use your account?') to the signin function.

Related

Google OAuth2 SignIn method fires at page load

I have used the official button for Google SignIn:
SignIn Page:
<div class="g-signin2" data-onsuccess="AuthenticateGoogleUser"></div>
function AuthenticateGoogleUser(googleUser){
.....
capture the user info and redirect to Home page
.....
}
When configuring for the credentials, I have set the redirection URL to the signin page.
This is how the Signout happens for the app:
function SignOutGoogleUser() {
if (gapi != null && gapi != undefined &&
gapi.auth2 != null && gapi.auth2 != undefined) {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
auth2.disconnect();
....Redirect to Home page...
});
}
}
The methods work fine. If I signout, will be redirected to home page.
But, when I manually browse the SignIn page after signout, the AuthenticateGoogleUser method is triggered and I am auto signed into the app (with google account).
The AuthenticateGoogleUser method should be only triggered on the button click. Is that right.
But here it is being triggered on load of SignIn page. Is that expected. Can this be stopped.
I'm using MVC C# as backend.
Without seeing all of your code, I am working on the assumption that you have not placed the function in a document ready wrapper and made sure to only kick it off on a button click or other event from which you would like to have it fire. As it stands now, it will fire on that page load.
$(document).ready(function(){
$("btnLogin").click(function(){
AuthenticateGoogleUser(googleUser);
});
});

How do I check if a user likes my page via facebook JS SDK nowadays?

I've been trying very hard to solve this issue for the last days, but I really can't get through. I've found this question many times on this forum, but none of the solutions presented here solved my problem because they have been posted some years ago and Facebook is updating the way to solve a given issue very often. My facebook javascript SDK to check if a user likes my page is as follows:
$(document).ready( function () {
try {
FB.init({
appId : '{my_app_id',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
version: 'v5.0'
});
} catch (e) {
alert(e.message);
}
try {
FB.getLoginStatus(function(response) {
if (response['status'] == 'connected') {
try {
FB.api(
"/{my_page_id}/likes", {access_token: 'my_app_token'},
function (response) {
alert(response.error.message);
if (response && !response.error) {
//code to check likes
}
}
);
} catch (e) {alert(e.message);}
}
});
} catch (e) {
alert(e.message);
}
});
The FB.init works and also the FB.getLoginStatus, where response['status'] is really 'connected'. But my FB.api does not work. The alert(response.error.message); line returns the following error: "(#10) This endpoint requires the 'manage_pages' permission or the 'Page Public Content Access' feature. Refer to https://developers.facebook.com/docs/apps/review/login-permissions#manage-pages and https://developers.facebook.com/docs/apps/review/feature#reference-PAGES_ACCESS for details.". I've been checking the manuals from Facebook for developers, but they are very incomplete, at least the ones in Portuguese (I am Brasilian). I'm really sick of trying to get this working by myself, so I'm looking for a help from the users of this forum.
Thanks in advance.
The /page-id/likes endpoint returns likes of a Page (for example, other Pages liked by the Page), NOT users who like your Page. And for getting that data, you need to own the Page, and you need to authorize with the manage_pages permission.
There is no way to get a list of Users who like your Page, the only reliable way to check if a specific User likes a Page is by authorizing that User with the user_likes permission. After that, you can use the /me/likes endpoint to get liked Pages. Although, you would need to get the permission reviewed by Facebook, and you would need a very good reason to use the permission.
Additional Info: How to check if someone is liked my fanpage from my website?

testcafe - CAS authentication

New to TestCafe. Got some simple example tests working easily. However, I wasn't able to find any examples of features that would seem to allow me to log in to my application via a CAS authentication page.
This code works to find the login button on the login page and click it.
fixture`VRT`
.page `http://myapp.com/login/`;
test('Find Login button', async t => {
const input = Selector('input.btn');
await t.click(input);
});
And this would work to type in the username and password on the login page:
test('Login using CAS', async t => {
await t
.expect("#username").exists
.typeText('#username', 'myuser')
.typeText('#password', '***')
.click('#submit');
});
But the problem is that there seems to be no way to continue from one test to another. So I can't go from the first test that opens the login page, to the next test that enters the credentials. It seems like, for TestCafe, every test has to specify its own page.
If I try to go to the CAS login page directly, by specifying it as the fixture "page", TestCafe fails to open the page, I think because the URL is extremely long.
Thanks for any suggestions.
Update:
So, using roles got me a bit further (thanks) but had to get through one more CAS page with an input button to click before getting to the page I wanted to test. Was able to add in another click to the role login:
import { Role } from 'testcafe';
import { Selector } from 'testcafe';
const finalLoginBtn = Selector('input.btn');
const myUserRole = Role('http://example.com/login', async t => {
await t
.click('input.btn')
.typeText('#username', 'my-username')
.typeText('#password', '*****')
.click('#submit')
.click(finalLoginBtn);
}, { preserveUrl: true });
fixture`VRT`
test("My User Page", async t => {
await t.navigateTo(`http://example.com`)
await t.useRole(myUserRole);
});
The TestCafe 'User Roles' functionality should suit your requirements. Please, refer to the following topic in the TestCafe documentation for details: https://devexpress.github.io/testcafe/documentation/test-api/authentication/user-roles.html

How to perfectly isolate and clear environments between each test?

I'm trying to connect to SoundCloud using CasperJS. What is interesting is once you signed in and rerun the login feature later, the previous login is still active. Before going any further, here is the code:
casper.thenOpen('https://soundcloud.com/', function() {
casper.click('.header__login');
popup = /soundcloud\.com\/connect/;
casper.waitForPopup(popup, function() {
casper.withPopup(popup, function() {
selectors = {
'#username': username,
'#password': password
};
casper.fillSelectors('form.log-in', selectors, false);
casper.click('#authorize');
});
});
});
If you run this code at least twice, you should see the following error appears:
CasperError: Cannot dispatch mousedown event on nonexistent selector: .header__login
If you analyse the logs you will see that the second time, you were redirected to https://soundcloud.com/stream meaning that you were already logged in.
I did some research to clear environments between each test but it seems that the following lines don't solve the problem.
phantom.clearCookies()
casper.clear()
localStorage.clear()
sessionStorage.clear()
Technically, I'm really interested about understanding what is happening here. Maybe SoundCloud built a system to also store some variables server-side. In this case, I would have to log out before login. But my question is how can I perfectly isolate and clear everything between each test? Does someone know how to make the environment unsigned between each test?
To clear server-side session cache, calling: phantom.clearCookies(); did the trick for me. This cleared my session between test files.
Example here:
casper.test.begin("Test", {
test: function(test) {
casper.start(
"http://example.com",
function() {
... //Some testing here
}
);
casper.run(function() {
test.done();
});
},
tearDown: function(test) {
phantom.clearCookies();
}
});
If you're still having issues, check the way you are executing your tests.
Where did you call casper.clear() ?
I think you have to call it immediately after you have opened a page like:
casper.start('http://www.google.fr/', function() {
this.clear(); // javascript execution in this page has been stopped
//rest of code
});
From the doc: Clears the current page execution environment context. Useful to avoid having previously loaded DOM contents being still active.

Facebook JS SDK FB.Login function

In my website, I have a button for "facebook connect", which when clicked on, triggers the following code:
<script type="text/javascript">
$(document).ready(function(){
console.log(<?=(isLoggedIn()+0)?>);
$("#fbconnect").click( function(){
FB.login(function(response) {
alert(JSON.stringify(response.authResponse));
if (response.authResponse) {
window.location = window.location;
alert('Welcome! Fetching your information.... ');
} else {
alert('User cancelled login or did not fully authorize.');
}
}, {scope: 'email,user_likes'});
} );
});
</script>
The button works well: it shows the facebook login dialog, and then alerts the appropriate message. However, when I refresh the page, the user is still logged out both server-side and client-side. Do I need to handle the access token and cookies myself or does the javascript SDK take care of that? If the latter, then why doesn't this code work?
Thank you.
UPDATE 1:
It works perfectly on localhost with Firefox, and on the server with all browsers. So the problem exists only for chrome and on localhost. Is there some chrome security setting that prevents cookies from being saved for localhost?