I'm using CasperJS 1.0.2 under PhantomJS 1.8.1 on Windows 8.
Trying to write a test for a web site. The site is heavily reliant on JS and the coding principals are quite unusual, which may be creating some problems but I'm not sure.
Here is the code I'm using to test login and search function:
var url = 'http://www.testsite.com/';
var casper = require('casper').create();
casper.start();
casper.start(url, function() {
this.echo('Page: ' + this.getTitle());
this.capture('start.png');
if (this.exists('input#TxtUserName')) {
this.sendKeys('input#TxtUserName', 'testlogin');
this.sendKeys('input#TxtPassword', 'testpass');
this.click('input#BtnLogin');
this.capture('loggedin.png');
}
});
casper.then(function() {
this.capture('beforesearch.png');
this.sendKeys("input#txtSearch", '1002');
this.click("input#cmdSubmit");
this.echo('Searching');
this.capture('aftersearch.png');
});
casper.run();
When I run this code, every page on the screen capture is the same with the exception that the login information is filled in on login.png. At no point does it actually login (using my real login credentials) after the click event. The search results also don't show after that click is fired.
Any clue what could be causing this?
Here is my waitFor code after submitting the search:
casper.waitForText("Part:", function() {
this.capture('searchresults.png');
});
You should use casper.waitFor to make sure the next page has been loaded. Otherwise phantom will take the screenshot before the form submit has been answered.
Related
I need to run my custom protocol twice but it doesn't work the second time, I got this error ( Not allowed to launch 'cutomProtocol' because user gesture is required. ) I tried to find a solution but I did not find any!
Same problem with chrome, firefox and edge.
I need to see this popup twice
window.location.href = 'my-protocol://${base64}';
and
customProtocolVerify(
`my-protocol://${base64}`,
() => {
// successCb: Callback function which gets called when custom protocol is found.
console.log('My protocol found and opened the file successfully..');
},
() => {
// failCb: Callback function which gets called when custom protocol not found.
console.log('My protocol not found.');
}
);
I tried with these two and didn't work
Clarification
I have a custom protocol.
My scenario:
check if it's installed successfully (I'm using customProtocolVerify method) and that method makes the launch if the protocol is found
run some APIs
launch the protocol again
My problem:
Step 3 doesn't work, I have the error on the console that says " Not allowed to launch... " and of course I can't see my popup to open my protocol.
I'm asking for help to make step 3 work
The only way to bypass this "bug" is to ask the user twice (or in a loop) by showing a OK alert or some sort of user confirm box.
My solution:
OpenLinkInExternalApp(Link);
alerty.alert('', { title: '', okLabel: 'Open Link' }, function () {
OpenLinkInExternalApp(Link);
});
The above code will open the external app, then a OK alert will pop up, after clicking OK, I call the same code again. Do this in a loop if needed.
TIP:
We guide our users to use split screen at this stage. This is where users can dock your web-app on the left and the external app on the right as an example.
Alert Box:
We user Alerty.js https://github.com/undead25/alerty#readme
I'm new to Cordova, any help would be appreciated.
I created a new Cordova Project in VS2015 and added the Cordova SMS plugin to my project (https://www.npmjs.com/package/cordova-sms-plugin).
I added this code to /www/scripts/index.js function onDeviceReady (as per documentiation for plugin):
function onDeviceReady() {
// Handle the Cordova pause and resume events
document.addEventListener( 'pause', onPause.bind( this ), false );
document.addEventListener( 'resume', onResume.bind( this ), false );
var numberString = "aoeuaeu";
var bypassAppChooser = true;
//CONFIGURATION
var options = {
replaceLineBreaks: false,
android: {
intent: 'INTENT' // send SMS with the native android SMS messaging
}
};
var successSMS = function () { alert('Message sent successfully'); };
var errorSMS = function (e) { alert('Message Failed:' + e); };
sms.send("0811231234", "Testing123", options, successSMS, errorSMS);
I debug the project using Debug, Android, Ripple - Nexus (Galaxy) selected options. When I place a breakpoint on the sms.send line of code and I add a watch for 'sms.send', I can see the object exists.
When I single step, this line in sms.js seems to be the last line that executes:
// fire
exec(
success,
failure,
'Sms',
'send', [phone, message, androidIntent, replaceLineBreaks]
);
I then get the following error message in Ripple:
'Sms.send We seem to be missing some stuff :( What is kinda cool though you can fill in the textarea to pass a json object to the callback you want to execute).'
I can see that all of the objects in that line is defined (success, failure, phone, message, androidIntent, replaceLineBreaks). When I 'step into' this line, it continues to execute code in ripple.js, but it becomes hard to follow for a person, since there are no line breaks in this file.
What am I doing wrong? I've read through all the documentation I can find & searched stackoverflow questions and can't seem to find any solutions to the problem.
I've uploaded this entire project (zipped), which can be downloaded at:
https://drive.google.com/file/d/0BwWgTMh-JLbfNHV0MlE5Yk5IZ3M/view?usp=sharing
Thanks in advance
Thank you Cordova team at Microsoft for helping me with an answer:
"Ripple has the ability to emulate some but not all plugins. SMS is not one of the plugins that it can fully emulate. However, in the message that pops up, you do have the ability to hit the Success or Fail buttons which will report back to the app that it was successful or not in sending the SMS. While that doesn’t actually send a message, it does let you test your app to see how it behaves for different results.
I tried the bit of sample code you included in the first email. In Ripple, I was able to change the alert by hitting the different buttons.
Trying other deployment methods, in both the VS Android Emulator and the Google Emulator they showed failure alert messages that they don’t support SMS messages. I then launched it on an Android phone device and it said it was successful.
So I believe your options are mainly using Ripple to fake sending of messages or using a device for testing."
forexample I can go to msn.com and open developer tools and write this code document.querySelector('.news a').click() and it will open news.
Now I want a program to do this automatically for me. write a javascript code that do this for me
actully this was just a simple example I don't want a program to open news in msn actully I want to submit something automaticaly.
1)how can I do this (I know if want to make this app for desktop I should use something like appjs)? 2)Is there any way that it doesn't open browser and submit that?
update:
I tested casperjs(as mentioned in comments) and I tried to login to my outlook then capture it.
here is my code:
var casper = require('casper').create();
casper.start("https://outlook.com", function(response) {
this.page.evaluate(function(a,b) {
// login
document.querySelector('#i0116').value = a;
document.querySelector('#i0118').value = b;
document.querySelector('#idSIButton9').click();
},'**********#outlook.com','**********');
}).then( function(){
this.capture('outlook.png');
this.echo(this.getTitle());
}).run();
from this and this stackoverflow questions
I tried casperjs --ssl-protocol=tlsv1 test.js and casperjs --ssl-protocol=any test.js and .wait(4000, function(){this.capture('outlook.png')} but all of them loged sign in and the below picture
as you see the sign in form is filled but it couldn't enter it.
In the developer tools I entered
document.querySelector('#i0116').value = a;
document.querySelector('#i0118').value = b;
document.querySelector('#idSIButton9').click();
and it worked but here it doesn't work.
I have a node.js application that runs on the Sails.js MVC Framework. The application supports connections from multiple clients using socket.io in real-time. It supports different roles. For example, you can login as a standard user or as a moderator.
For testing, I use mocha-casperjs (and chai and other stuff that is not important for my question) and run the tests from grunt using grunt mocha_phantomjs. The tests are specified in the Gruntfile.js file in the root folder of my project. They are specified like this:
Gruntfile.js:
mocha_casperjs: {
files: {
src: [
'test/single-client.js',
'test/multi-client.js',
]
}
}
Here is a test case I want to verify: Once the Moderator clicks on a specific button, a div.container should appear on both the Moderator's view as well as the standard user's view.
Now, testing the single-client aspect works well. Here is a basic scenario:
test/single-client.js:
describe('Clicking on a Button as a Moderator', function() {
it('results in div.container to appear on the Moderators view', function() {
casper
.start('http://localhost:1337')
.logInAsMod() //Note: This is pseudocode for submitting a login form
.thenClick('button')
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
})
}
which results in:
Clicking on a Button as a Moderator
✓ results in div.container to appear on the Moderator's view
However, I'm struggling in testing the multi-client aspect of this test case: The div.container should not only appear on the Moderator's view, but also on the standard user's view. From what I understand, the casper.run() method, which starts the tests defined earlier in the source code, will be called by the mocha-phantomjs module. So something like this won't work:
test/multi-client.js:
describe('Clicking on a Button as a Moderator', function() {
it('results in div.container to appear on the Moderators view and on the standard users view', function() {
casper
.start('http://localhost:1337')
.logInAsMod() //Note: This is pseudocode for submitting a login form
.thenClick('button')
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
casper
.logInAsUser() //Note: This is pseudocode for submitting a login form
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
})
}
The problem with the code above is that the casper.run() call only creates one instance of casperjs. It would be really great if I could write something like this:
var casperMod = require('casper').create();
var casperUser = require('casper').create();
casperMod
.start('http://localhost:1337')
.logInAsMod() //Note: This is pseudocode for submitting a login form
casperUser
.start('http://localhost:1337')
.logInAsUser() //Note: This is pseudocode for submitting a login form
casperMod
.thenClick('button')
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
casperUser
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
So I would have two instances of casperjs that I can write the routines for. However, this results in Error: Cannot find module 'casper' because the mocha-casperjs framework does not support the inclusion of another casperjs instance.
Permanently logging out and in again is not an option, because I want to test the real-time aspect of the application.
Does anyone have a suggestion in how to achieve multiple instances of casperjs when using mocha-casperjs?
You will have problems with this in any framework as you need two sets of cookies, basically two browsers running. Even if you did create two casper instances, you're still in one phantomjs process that shares the cookies.
What can do is create a new WebPage instance and swap that out on the current casper instance, plus swap the cookies:
casper
.start('http://localhost:1337')
.logInAsMod()
.thenClick('button')
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
.then(function() {
var userPage = require('webpage').create(),
modCookies = phantom.cookies
phantom.clearCookies()
casper
.logInAsUser()
.then(function() {
('div.container').should.be.inDOM.and.visible;
})
})
My site was probably hacked. I am finding script.js from bigcatsolutions.com in my page. It triggers a popup of an affiliate program. The script isn't on the page by default and I want to know how can I find where it was injected. The script sometimes injects other ad sites.
In chrome I see this:
The injected script code:
function addEvent(obj, eventName, func) {
if (obj.attachEvent) {
obj.attachEvent("on" + eventName, func);
} else if (obj.addEventListener) {
obj.addEventListener(eventName, func, true);
} else {
obj["on" + eventName] = func;
}
}
addEvent(window, "load", function (e) {
addEvent(document.body, "click", function (e) {
if (document.cookie.indexOf("booknow") == -1) {
params = 'width=800';
params += ', height=600';
params += ', top=50, left=50,scrollbars=yes';
var w = window.open("http://booknowhalong.com/discount-news", 'window', params).blur();
document.cookie = "booknow";
window.focus();
}
});
})
My site is moved from my hosting company to Amazon EC2 Windows 2013 Server and still have the issues, so it means that the code still resides on the server somewhere. My site was build using ASP.ENT / C#.
Things I did:
tried to search the original aspx and aspx.cs code files
Have you checked the IIS logs to see if they are hitting a specific page and injecting it there?
Do you load any data from a database? You could check in the tables and see if anything out of the ordinary appears there.
It is unlikely that the .aspx pages have actually been physically modified and even more unlikely that the DLL have been as .aspx.cs files are compiled in to your BIN folder as DLL's. The more likely scenario is that you have an unsecure page that a malicious site is injecting its script into. The other possible attack vector is that you have had malicious code via SQL injection and are loading it each time.
After deep searching and I missed it in the first run, I found that the script was injected into the ASP.NET masterpage.
I ran a search to search for a specific string in all the files and that's how I found it. It seems that the server itself was breached and the hacker put the code into several websites.
So for those of you who have this type of problem, I recommend running a text search and try to find the URL that is tights to the running script.
Hope that helps and thanks for your time.