I am using Konacha to test a BackboneJS application in my Ruby on Rails application. I have read about every tutorial on the web and it shows how easy it is to set up and get working. Unfortunately, I am not having this level of success. Here is what I have:
app/assets/javascripts/app_specific/itapp/models/post.js
Itapp.Models.Post = Backbone.Model.extend({
isFirstPost: function() {
return (this.get('id') === Itapp.bootstrap.posts[0].get('id'));
},
});
spec/javascripts/app_specific/itapp/models/post_spec.js
//= require spec_helper
var expect = chai.expect;
describe("Posts", function() {
it("should have a first post", function() {
//just trying anything to get some kind of valid error/issue
//I could put anything here and it wouldn't matter, just FYI
expect(typeof this.isFirstPost).to.equal('function');
});
});
spec/javascripts/spec_helper.js file:
// Require the appropriate asset-pipeline files:
//= require application
//Any other testing specific code here...
//Custom matchers, etc....
Konacha.mochaOptions.ignoreLeaks = true
beforeEach(function() {
return window.page = $("#konacha");
});
// set the Mocha test interface
// see http://mochajs.org/#interfaces
mocha.ui('bdd');
//
// ignore the following globals during leak detection
mocha.globals(['YUI']);
//
// or, ignore all leaks
mocha.ignoreLeaks();
//
// set slow test timeout in ms
mocha.timeout(5);
//
// Show stack trace on failing assertion.
chai.config.includeStack = true;
I do have a config/initializers/konacha.rb file:
Konacha.configure do |config|
config.spec_dir = "spec/javascripts"
config.spec_matcher = /_spec\.|_test\./
config.stylesheets = %w(application)
config.driver = :selenium
end if defined?(Konacha)
The error I am getting:
Error: Failed to load app_specific/itapp/collections/posts_spec.js.
Perhaps it failed to compile? Check the rake output for errors.
Checking the rake output:
ActionView::Template::Error: couldn't find file 'application' which I am requiring in my spec_helper.js
So for some reason even though in my spec_helper I am trying to load the BackboneJS application for the testing environment it is not able to find it.
Any thoughts/ideas that I should try to get this communicating/working?
--Mike Riley
I figured this out. The problem was that it was not finding the file under app/assets/javascripts/ correctly. I needed to do this at the top of the spec/javascripts/app_specific/itapp/models/post_spec.js file:
//= require app_specific/itapp/models/post
Once I did that it was able to find the associated code that I am testing against. I will need to work a bit more to clean up the path in a spec_helper.js file, but I am no longer blocked on this.
Related
I'm using angularjs-rails gem.
I've created angular_app folder in assets, and have angular_app/controllers/phoneListController.js.coffee, and angular_app/modules/phoneCatApp.js.coffee (*yeah you're right I'm doing angular's phone tutorial ). So angular_app/controllers/phoneListController.js.coffee has:
phonecatApp.controller 'PhoneListController', ($scope) ->
$scope.phones = [
{ 'name': 'Nexus S'
'snippet': 'Fast just got faster with Nexus S.'
}
{
'name': 'Motorola XOOMâ„¢ with Wi-Fi'
'snippet': 'The Next, Next Generation tablet.'
}
{
'name': 'MOTOROLA XOOMâ„¢'
'snippet': 'The Next, Next Generation tablet.'
}
]
return
angular_app/modules/phoneCatApp.js.coffee has:
phonecatApp = angular.module('phonecatApp', [])
Every thing works fine if I use vanila js in angular_app/modules/phoneCatApp.js.coffee using `phonecatApp = angular.module('phonecatApp', [])`` (with backsticks).
So problem is that coffee covers all in anonymous function with ().call.this. What should I do to make it work in coffee?
The problem, as you've stated, is the
(function() { ... }).call(this)
that the coffeescript compiler generates. To make phonecatApp a global simply do
this.phonecatApp = phonecatApp
in your angular_app/modules/phoneCatApp.js.coffee file after the angular.module() call.
However, MUCH better is to use:
angular.module('phonecatApp').controller( ... )
to define your controllers. This version gets angular to provide the module singleton on which to define the controller.
So I am trying to make a game in Dart and I decided to check out this asset_pack package. I tried to test the example code (below) but asset.imported prints null..why is this?
I did create /web/test/foo.txt in my project folder and put a little bit of text in it but still I get null printed.
main() {
// Construct a new AssetManager.
AssetManager assets = new AssetManager();
// Register the 'test' pack. No url is needed so the empty string suffices.
AssetPack testPack = assets.registerPack('test', '');
// Register asset 'foo' and load it's contents from 'foo.txt'.
// The asset type is 'text' and there are no arguments for the loader
// or importer.
Future<Asset> futureAsset = testPack.loadAndRegisterAsset('foo', 'foo.txt',
'text', {}, {})
futureAsset.then((asset) {
// Print the contents of foo.txt.
print(asset.imported);
});
}
I think your file has to be in the web/ folder or you have to load test/foo.txt. If you run the example you should see an error that the file was not found in the developer console. This code seems to work:
Future<Asset> futureAsset = testPack.loadAndRegisterAsset('foo', 'text',
'test/foo.txt', {}, {})
I have a web page that opens a div when you click a button. This div allows you to drag a file from your desktop onto its area; the file then gets uploaded to the server. I'm working with the Ruby implementation of Selenium.
By using the JavaScript debugger in Firefox, I can see that an event called "drop" is being passed to some JavaScript code "handleFileDrop(event)". I presume that if I were to create a mock event and fire it somehow that I could trigger this code.
If found an interesting article that seemed to point me in a promising direction, but I'm still short of figuring it all out. I am able to pass JavaScript to the page using Selenium's get_eval method. Calling methods using this.browserbot is getting me the elements I need.
So:
How do I build the file object that
needs to be part of the mock drop
event?
How do I fire the drop event
such that it gets picked up as if I
had dropped a file in the div?
I post an RSpec test that simulate files drag and drop using Selenium webdriver.
It use jQuery to make and trigger a fake 'drop' event.
This code simulate drag and drop of a single file. For sake of simplicity I've stripped code that allow multiple files dropping. Tell me if you need it.
describe "when user drop files", :js => true do
before do
page.execute_script("seleniumUpload = window.$('<input/>').attr({id: 'seleniumUpload', type:'file'}).appendTo('body');")
attach_file('seleniumUpload', Rails.root + 'spec/support/pdffile/pdfTest.pdf')
# Trigger the drop event
page.execute_script("e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : seleniumUpload.get(0).files } }; $('#fileDropArea').trigger(e);")
end
it "should ..." do
should have_content '...'
end
P.S.: remember to replace #fileDropArea with ID of your drop area.
P.P.S: don't use evaluate_script in place of execute_script, otherwise selenium get stuck evaluating complex jQuery objects!
UPDATE:
I've write a method you can reuse and do the stuff written above.
def drop_files files, drop_area_id
js_script = "fileList = Array();"
files.count.times do |i|
# Generate a fake input selector
page.execute_script("if ($('#seleniumUpload#{i}').length == 0) { seleniumUpload#{i} = window.$('<input/>').attr({id: 'seleniumUpload#{i}', type:'file'}).appendTo('body'); }")
# Attach file to the fake input selector through Capybara
attach_file("seleniumUpload#{i}", files[i])
# Build up the fake js event
js_script = "#{js_script} fileList.push(seleniumUpload#{i}.get(0).files[0]);"
end
# Trigger the fake drop event
page.execute_script("#{js_script} e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : fileList } }; $('##{drop_area_id}').trigger(e);")
end
Usage:
describe "when user drop files", :js => true do
before do
files = [ Rails.root + 'spec/support/pdffile/pdfTest1.pdf',
Rails.root + 'spec/support/pdffile/pdfTest2.pdf',
Rails.root + 'spec/support/pdffile/pdfTest3.pdf' ]
drop_files files, 'fileDropArea'
end
it "should ..." do
should have_content '...'
end
end
As #Shmoopy asked for it, here's a C# translation of the code provided by #micred
private void DropImage(string dropBoxId, string filePath)
{
var javascriptDriver = this.Driver as IJavaScriptExecutor;
var inputId = dropBoxId + "FileUpload";
// append input to HTML to add file path
javascriptDriver.ExecuteScript(inputId + " = window.$('<input id=\"" + inputId + "\"/>').attr({type:'file'}).appendTo('body');");
this.Driver.FindElement(By.Id(inputId)).SendKeys(filePath);
// fire mock event pointing to inserted file path
javascriptDriver.ExecuteScript("e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : " + inputId + ".get(0).files } }; $('#" + dropBoxId + "').trigger(e);");
}
You can use Blueduck Sda (http://sda.blueducktesting.com)
Is an OSS that has implemented ALL selenium functions (It works with selenium RC) but it allows you to automate Windows actions. So you can test web, and interact with the OS.
So you can make your test, and then, just tell the mouse to click on the element and drop it where you want!
Nice testing!
Note: you should also add
e.originalEvent.dataTransfer.types = [ 'Files' ];
It seems quite hard to get the AngularJS/Karma end-to-end testing environment working with a Rails backend.
I have Karma installed and running with the following config file:
basePath = '../';
files = [
ANGULAR_SCENARIO,
ANGULAR_SCENARIO_ADAPTER,
'test/e2e/**/*.js'
];
autoWatch = false;
browsers = ['Chrome'];
// singleRun = true;
proxies = {
'/': 'http://local.mywebsite.com:3000/'
};
urlRoot = 'e2e';
junitReporter = {
outputFile: 'test_out/e2e.xml',
suite: 'e2e'
};
Where http://local.mywebsite.com:3000/ is my rails application.
I try a very simple test:
it('should redirect to /', function() {
expect(browser().location().url()).toBe("/");
});
But I am stuck with the following error:
http://localhost:9876/base/test/e2e/scenarios.js:8:5
TypeError: Object [object Object] has no method 'resumeBootstrap'
at HTMLIFrameElement.<anonymous> (http://localhost:9876/adapter/lib/angular-scenario.js:26285:27)
at HTMLIFrameElement.jQuery.event.dispatch (http://localhost:9876/adapter/lib/angular-scenario.js:3064:9)
at HTMLIFrameElement.elemData.handle.eventHandle (http://localhost:9876/adapter/lib/angular-scenario.js:2682:28)
at k (http://connect.facebook.net/en_US/all.js:48:745)
Where scenarios.js comes from https://github.com/angular/angular-seed.
Any idea how to make it work?
Try
it('should redirect to /', function() {
browser().navigateTo("/");
expect(browser().window().path()).toBe("/");
});
I would get the most up-to-date version of angular scenario runner. You can find the unstable version at
http://code.angularjs.org/1.1.4/angular-scenario.js
and the stable version at
http://code.angularjs.org/1.0.6/angular-scenario.js
Then, be sure to update your karma configuration to use the newest scenario runner
files = [
'path/to/angular-scenario.js',
ANGULAR_SCENARIO_ADAPTER,
'test/e2e/**/*.js'
];
Hopefully that helps.
The solution above is correct. This link covers the problem: https://github.com/karma-runner/karma/issues/470
I hit the same issue while running the excellent examples on: http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-testacular.html
That's a great resource if you're getting started, but you will need to update from testacular to karma and update angularjs to 1.0.6
I am using Symfony 1.2 and I have some issues switching context.
This code was working fine:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('account', 'prod', false);
$context = sfContext::createInstance($configuration, 'account-prod');
$userToLogin = PcUserPeer::retrieveByEmailAddress("myemail#example.com");
Auth::login($context->getUser(), $userToLogin, false, false);
echo "all done.";
At some point requirements changed and I needed to use the 'public' application before the 'account' one.
Then I changed to:
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
// {{{ new code:
$configuration = ProjectConfiguration::getApplicationConfiguration('public', 'prod', false);
sfContext::createInstance($configuration);
// some code using the public app...
// }}}
$configuration = ProjectConfiguration::getApplicationConfiguration('account', 'prod', false);
$context = sfContext::createInstance($configuration, 'account-prod');
// {{{ new code:
sfContext::switchTo('account-prod');
// }}}
$userToLogin = PcUserPeer::retrieveByEmailAddress("myemail#example.com");
CustomAuth::login($context->getUser(), $userToLogin, false, false);
echo "all done.";
Basically I added a switchTo call.
After the change, the code got broken and the error message is this:
PHP Fatal error: Call to a member function prepare() on a non-object in /var/www/html/myproj/symfony/storage/sfPDOSessionStorage.class.php on line 109
Thanks for your help,
Dan
Symfony is trying to load the session storage object. I suppose there is a problem with your new environment's configuration.
Check
/apps/public/config/factories.yml
Look for "storage" and try to find out how is it different from the other app's configuration.
Hard to know without a backtrace/more info what is triggering the error. It looks like you are using sessions stored in a database, and that a query related to that is failing.
Try setting the third argument to getApplicationConfiguration to true (which will turn debug on) and see if you get more output.
At a guess, it looks like the account app is using PDO session storage, and is failing to connect to the database or something?