Use behat with zombieJS to click on an element gives a DriverException - behat

I am using behat with a zombie driver to test my application. Now I am trying to click on an element (a td), to fire an ajax request. But when clicking this element I receive the error:
Error while processing event 'click' (Behat\Mink\Exception\DriverException
The code I use is from this thread
Nowhere on the internet I can find someone with the same error message, so I have no clue how to solve this.
The HTML I want to click on looks like this:
<td value="2" onclick="switchStatus(this.id); updateScores();; return false;" id="37_12_2">2</td>
These javascript functions do an ajax call to the server and do nothing with the saved result (no success method).
The test function I use looks like this:
/**
* #Given /^I click td "([^"]*)"$/
*/
public function iClickTd($id)
{
$locator = "#$id";
$element = $this->getSession()->getPage()->find('css', $locator);
if (null === $element) {
throw new \InvalidArgumentException(sprintf('Could not evaluate CSS selector: "%s"', $locator));
}
$element->click();
$this->getSession()->wait(1000);
}
And in the test I have:
And I click td "37_12_2"
The behat.yml:
default:
suites:
default:
contexts:
- FeatureContext:
- http://localhost/
extensions:
Behat\MinkExtension\ServiceContainer\MinkExtension:
base_url: http://localhost/
sessions:
default:
goutte: ~
javascript:
zombie:
node_modules_path: '/usr/lib/node_modules/'
Used versions:
"phpunit/phpunit": "4.5.*",
"phpspec/phpspec": "~2.1",
"behat/behat": "~3.0",
"behat/mink": "~1.6",
"behat/mink-extension": "~2.0",
"behat/mink-goutte-driver": "*",
"behat/mink-zombie-driver": "~1.2"
npm v1.4.28
php 5.6
Does anyone know what goes wrong, and how I can make this function work?

The actual problem was a wrong ajax request. Using a real webbroser the ajax call went right, but using zombieJS this call went to a wrong url.
When someone else has the same exception, you can view your real problem by changing the following part in the ZombieDriver.php:
From:
$out = $this->server->evalJS($js);
if (!empty($out)) {
throw new DriverException(sprintf("Error while processing event '%s'", $event));
}
To:
$out = $this->server->evalJS($js);
if (!empty($out)) {
echo $out;
throw new DriverException(sprintf("Error while processing event '%s'", $event));
}
$out contains the actual error message of an ajax call.

Related

Error -32 EPIPE broken pipe

I am doing a post request with ajax that should return a partialview but I always get following error in log:
Connection id "0HL6PHMI6GKUP" communication error.
Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -32 EPIPE broken pipe
When looking at the debug log, I see that it is loading the partialview data but than I get the error.
I can't find anything on the net about the -32 EPIPE error, could someone help me explain what this error means?
Ajax call
$( "#PostForm" ).submit(function( event ) {
//Ajax call
$.ajax({
type: 'POST',
url: "/url/path/CreateBox",
data: {
"id": $("#RackId").val(),
"Name": $("#Name").val()
},
success: function(result){
$("#modal").html(result);
}
});
});
Controller
[HttpPost]
public async Task<IActionResult> CreateBox(int id, string Name)
{
//Get the info of the given ID
Rack rack = await this._rackAccess.GetByIdAsync(id);
if (rack == null)
{
return NotFound();
}
Box box = new Box();
box.Rack = rack;
if (!string.IsNullOrEmpty(Name))
{
box.Name = Name;
var result = await this._boxAccess.InsertAsync(box);
//Returns a list of boxes
return PartialView("Boxes", await this._boxAccess.ToRackListAsync(rack.ID));
}else{
//Returns form again
return PartialView("CreateBox", box);
}
}
Version
Aspnet core: 1.1.0
"Microsoft.AspNetCore.Server.Kestrel": "1.1.0"
"Microsoft.AspNetCore.Hosting": "1.1.0",
Solution can be found on github were I posted the problem aswell:
https://github.com/aspnet/KestrelHttpServer/issues/1978
Answer of halter73 on github:
The "communication error" usually comes in ECONNRESET, EPIPE, and ECANCELED varieties. Which one you get usually just depends on which platform you're running on, but all three generally mean the same thing: that the client closed the connection ungracefully.
I have a theory why this is happening. I think that the page might be getting reloaded mid-xhr causing the xhr to get aborted. This can be fixed by returning false from your jQuery submit callback.
I took all your dependencies and your jQuery snippet and demonstrated how this page reload can cause an EPIPE on linux and an ECANCELED on Windows in a sample repro at https://github.com/halter73/EPIPE. It uses csproj instead of project.json because I don't have an old CLI that supports project.json easily available.
Maybe due to long time processing on server-side,
communication pipe was broken by overtime mechanism.
Wish this is helpful.

Ember-auth signin test fails with json

I am having some issues with testing my signin/signout and related features of my app. The app works, but the test fail.
For testing, I use a QUnit with testem (I also tried teaspoon)
test "after signin, should redirect user back to previous page", ->
visit '/library'
fillIn '.signin-email', 'example#example.com'
fillIn '.signin-password', 'examplepass'
click '.signin-btn'
andThen ->
equal(testing().path(), 'library', "Should redirect back to library (was #{testing().path()})")
After running the test, I get a failure:
(screenshot here )
Authentication: visiting restricted page as non authenticated user: after signin, should redirect user back to previous page (2, 0, 2)Rerun544 ms
{user_id: 2, auth_token: wVveiyDLuXBXu69pQ2XQwg}
Source:
at Test.QUnitAdapter.Test.Adapter.extend.exception (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50149:5)
at superWrapper [as exception] (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:13374:16)
at Object.onerror (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50009:22)
at onerror (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20453:16)
at EventTarget.trigger (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20286:22)
at null.<anonymous> (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20439:14)
at EventTarget.trigger (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20286:22)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20588:17
Should redirect back to library (was signin)
Expected:
"library"
Result:
"signin"
Diff:
"library" "signin"
Source:
at http://localhost:7357/public/assets/spec/javascripts/integration/authentication_pages_spec.js.js:22:14
at andThen (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50258:20)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49817:21
at isolate (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49989:14)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49972:12
at invokeCallback (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20463:19)
at null.<anonymous> (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20513:11)
Also, auth.coffee:
App.Auth = Em.Auth.extend
request: 'jquery'
response: 'json'
strategy: 'token'
session: 'cookie'
modules: [
'emberData',
'authRedirectable',
'actionRedirectable'
]
signInEndPoint: '/signin'
signOutEndPoint: '/signout'
tokenKey: 'auth_token'
tokenIdKey: 'user_id'
tokenLocation: 'param'
emberData:
userModel: 'user' # create user model on login
authRedirectable:
route: 'signin'
actionRedirectable:
signInRoute: 'library'
# signInSmart: true
# signInBlacklist: ['signin']
signOutRoute: 'index'
I am unable to find the source of the error, so maybe it is something to do with ember-auth. Any ideas would be very appreciated.
Update 1 [Jan 4th]:
I've written an additional test, which passes only halfway. The test is simpler than the previous in that it does not check a redirect, but only checks that the user name appears in the UI after signin.
test "after signin, TEST", ->
visit '/library'
fillIn '.signin-email', 'user#example.com'
fillIn '.signin-password', 'foobargaz'
click '.signin-btn'
andThen ->
ok exists('.menu-signout'), "signout button exists"
The assertions passes, but I get an additional error reporting the returned JSON as seen in this screenshot. The screenshot basically shows:
[Fail] {user_id: 2, auth_token: wVveiyDLuXBXu69pQ2XQwg}
[Pass] signout button exists
Additionally, I've also run the tests by mocking the ajax requests with mockjax, but with the same failure.
Third, I should note that I had to patch "ember-auth-request-jquery.js" to make it work with ember testing as suggested here
I'm pretty sure you're failing to wait on the first visit to happen, so here's how I read it (I'm no CS person)
You're telling Ember to go to library
Before being sure it's finished navigating you're trying to fill in 2 fields and click a button (all of which probably doesn't exist)
then you check to see if it's library, but while waiting after you thought you clicked, really the page finishes rendering the login page from the visit
Here's what js2coffe says it'd kind of look like (my main point is the then after the visit).
test "after signin, should redirect user back to previous page", ->
visit("/library").then ->
fillIn ".signin-email", "example#example.com"
fillIn ".signin-password", "examplepass"
click(".signin-btn").then ->
equal testing().path(), "library", "Should redirect back to library (was " + (testing().path()) + ")"
Update 1/4: Documentation changed on me
Now we move to educated guess time. Looking through the Ember-auth code it might not be creating any timers/promises that Ember is aware of, in affect Ember thinks it's finished the signin process immediately. So the click promise is resolved immediately and you run your test immediately (andThen waits on the global testing promise to resolve). To test the theory you can do some terrible timeout and see if it does indeed redirect after some time
test "after signin, should redirect user back to previous page", ->
visit "/library"
fillIn ".signin-email", "example#example.com"
fillIn ".signin-password", "examplepass"
click ".signin-btn"
stop()
Ember.run.later this, (->
start()
equal testing().path(), "library", "Should redirect back to library (was " + (testing().path()) + ")"
), 5000
It turns out my coffeescript was not the best in the world.
The module function in QUnit should NOT compile to:
module('Authentication: visiting restricted page as non authenticated user', function() {
return setup(function() {
return Em.run(App, App.advanceReadiness);
});
});
but to:
module('Authentication: visiting restricted page as non authenticated user', {
setup: function() {
Ember.run(App, App.advanceReadiness);
},
// This is also new
teardown: function() {
App.reset();
}
});
Additionally, in my spec_helper.coffee file I had something like this:
QUnit.testStart(function() {
// FIXME: this below made it fail every time
// Ember.run(function() {
// return App.reset();
// });
Ember.testing = true;
});
QUnit.testDone(function() {
Ember.testing = false;
});
QUnit.done(function() {
return Ember.run(function() {
return App.reset();
});
});
which seems to have caused some issues, so I just deleted it and the tests now pass.

dojo.io.iframe.send does not send a request on second time onwards in dojo 1.8

Example code snippet
this._deferred = dojo.io.iframe.send({
url: "/Some/Servie",
method: "post",
handleAs: 'html',
content: {},
load: function(response, ioArgs){
//DO successfull callback
},
error: function(response, ioArgs){
// DO Failer callback
}
});
Steps
click submit button send a request and successfully got a response
click submit button again...request never send...
Appreciate any help
I can't talk for 1.8, but I am using dojo 1.6 and had a very similar issue that I resolved with the following method:
dojo.io.iframe._currentDfd = null; //insert this line
dojo.io.iframe.send
({...
*verified in Chrome Version 25.0.1364.152 m
Source: http://mail.dojotoolkit.org/pipermail/dojo-interest/2012-May/066109.html
dojo.io.frame.send will only send one request at a time, so if it thinks that the first request is still processing (whether it actually is or not), it won't work on the second call. The trick is to call cancel() on the returned deferred result if one exists, like so:
if (this._deferred) {
this._deferred.cancel();
}
this._deferred = dojo.io.iframe.send({
....
that will cancel the first request and allow the second request to send properly.
For dojo 1.8, dojo.io.iframe is deprecated. dojo.request.iframe is used instead.
And the solution from #Sorry-Im-a-N00b still works:
iframe._currentDfd = null;
iframe.get(url, {
data: sendData,
});

Fetching current loggedin user using spring security

I have a problem in getting the logged in user in my spring-extjs application.I am using spring security 2.0.4.Here are the details of what i have tried.
Controller class:
#RequestMapping(value="/StaffingApplication/index.action", method = RequestMethod.GET)
public String printUser(ModelMap model) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName(); //get logged in username
System.out.println(name);
model.addAttribute("username", name);
return "index.jsp";
}
login.js file
var login = new Ext.FormPanel({
labelWidth:80,
url:'j_spring_security_check',
frame:true,
title:'Please Login',
defaultType:'textfield',
width:300,
height:130,
monitorValid:true,
// Specific attributes for the text fields for username / password.
// The "name" attribute defines the name of variables sent to the server.
items:[{
fieldLabel:'Username',
name:'j_username',
allowBlank:false
},{
fieldLabel:'Password',
name:'j_password',
inputType:'password',
allowBlank:false
}],
// All the magic happens after the user clicks the button
buttons:[{
text:'Login',
formBind: true,
// Function that fires when user clicks the button
handler:function(){
login.getForm().submit({
method:'POST',
// Functions that fire (success or failure) when the server responds.
// The server would actually respond with valid JSON,
// something like: response.write "{ success: true}" or
// response.write "{ success: false, errors: { reason: 'Login failed. Try again.' }}"
// depending on the logic contained within your server script.
// If a success occurs, the user is notified with an alert messagebox,
// and when they click "OK", they are redirected to whatever page
// you define as redirect.
success:function(){
Ext.Msg.alert('Status', 'Login Successful!', function(btn, text){
if (btn == 'ok'){
window.location = 'index.action';
}
});
},
// Failure function, see comment above re: success and failure.
// You can see here, if login fails, it throws a messagebox
// at the user telling him / her as much.
failure:function(form, action){
if(action.failureType == 'server'){
obj = Ext.util.JSON.decode(action.response.responseText);
Ext.Msg.alert('Login Failed!', obj.errors.reason);
}else{
Ext.Msg.alert('Warning!', 'Authentication server is unreachable : ' + action.response.responseText);
//window.location='loginFailure.html'+action.response.responseText;
}
login.getForm().reset();
}
});
}
}]
});
On my jsp page I access it like this.
<div id="header" class="header">Options Staffing Application
<div style="" id="user-status">
<a href='<c:url value="j_spring_security_logout"/>'>Logout</a>
<h3>Username : ${username}</h3>
</div>
</div>
But I just get a blank in place of username.
When I try to print it in the controller I get the value printed,but doesn't seem to be displayed on the jsp page.Went throgh other threads but did not help.Any help would be appreciated
Thanks for the time
Sachin
You don't need to put the username into an object model because you can access it from a jsp just like the way you do in the controller class:
<h3>Username <%=SecurityContextHolder.getContext().getAuthentication().getName(); =></h3>
Or even better:
<h3>Username <sec:authentication property="name" /></h3>
But i'm not sure if you can use that taglib in Spring Security 2

Why doesn't dojo.io.script.get() execute the provided error function when receiving a 404?

I am trying to use the following to do a cross-domain get:
dojo.io.script.get({
url: myUrl,
callbackParamName: "callback",
preventCache: true,
load: dojo.hitch( this, loadFunction ),
error: dojo.hitch( this, function() {
console.log('Error!!!');
})
});
The load function runs fine, however, when the server returns a 404, the error function does not run. Can anyone tell me why?
EDIT
After some investigation, I found that a timeout and handler could be implemented in the following way:
dojo.io.script.get({
url: myUrl,
callbackParamName: "callback",
timeout: 2000
}).then(function(data){
console.log(data);
}, function(error){
alert(error);
});
This uses functionality provided by the dojo.Deferred object.
When accessing server with script tags (that what dojo.io.script.get does), status code and headers are not available.
You may try some other ways to detect a problem, like using a timeout and analyzing a content of a script. The latter is problematic for JSONP calls (like in your example).
I realize this is old but I thought I'd share a solution in case others, like I had, come across this thread.
dojo.io.script is essentially adding a <script/> to your html page. So you can try this:
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', myUrl);
script.onerror = function() {
debugger
}
script.onload = function() {
debugger
}
document.getElementsByTagName('body')[0].appendChild(script);
That way if the script fails to load the onerror event is called.
*This may not work in every instance but is a good start