I need to detect the CSS display value after a click event has been executed. I am sure it is user error, but I cannot get Jasmine.js to report if an elements visibility has been changed after the click.
Here is the codepen link: http://codepen.io/nicholasabrams/pen/dPYoJr
Here is the code itself: (this is obviously not the actual case that it is being used in however it is a very simplified version that recreates the issue I am having currently)
$('#button1').on('click', function(){
$(this).append('<button id="#button2">!!!!!</button>');
});
Here is the test itself:
describe("button#1 click test", function(){
beforeEach(function(){
$('#button1').click();
});
it("Should inject a new button with #button2 as the id", function(){
expect($('#button2')).toBeVisible();
});
});
At first - in your pen you should add external script for jasmine-jquery. Next, button in a button, it's illegal according to W3C Phrasing content, but there must be no interactive content descendant. Jasmine is just fine, try to append to parent:
$('#button1').on('click', function(){
$(this).parent().append('<button id="#button2">!!!!!</button>');
});
Working pen http://codepen.io/anon/pen/zxvGja?editors=101
Related
I am trying out the arrival.js library to detect when an element is injected into the body or is somehow available in the DOM. This is the code I am trying in JS:
setTimeout(function() {
$("body").append("<p class = 'foo'>Yep</p>");
}, 5000);
$(function() {
$(document).arrive(".foo", function() {
alert("hell Yeah");
});
});
Problem is, the element does get appended to the body after 5 seconds, but the alert never comes up. Any idea how to make it work as expected?
This is the fiddle.
Remove arrive.min.js in resource and use this cdn link
https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js
fiddle
I'm having a problem with a jasmine test together with a knockout-template:
The html is similar to this:
<body>
<my-widget params="value: $data></my-widget>
</body>
the widget has a click-binding:
<div class="my-widget">
<a id="#clickme" data-bind="click: doSomething">Click me</a>
</div>
the widget-javascript is like this:
ko.components.register('my-widget', {
viewModel : function(params) {
this.doSomething = function() {
// doing something
};
},
template: {
require: 'text!../../templates/my-widget.html'
}
});
All of this works perfectly in production, but in Jasmine/Jquery, triggering a click on $('#clickme') does not execute the doSomething.
The following is an excerpt from my jasmine test (It's been greatly simplified but should contain the essentials):
beforeEach(function (done) {
require(['specHelpers', 'knockout'],
function (specHelpers, knockout) {
specHelpers.loadFixtureIntoPage("page.html", "myPage"); // template and id to use
expect($('#myPage')).toExist();
done();
});
});
it("WILL NOT TRIGGER MY CLICK", function (done) {
ko.applyBindings(myPage.pageViewModel, $('#myPage'))[0]);
setTimeout(function() {
$('#clickme').click();
// doSomething is not called :(
done();
}, 300);
});
When console.logging the #clickme element I can see that it is present.
It seems that the click binding in the widget does not get applied properly. However, when I run the test in bdd and it's over and failed - I can manually click this element and doSomething does get called.
What am I doing wrong? As I said, running the actual application works perfectly. It just seems that jasmine cannot handle the click bindings properly - I don't have this problem with the regular click events that are set in the document.ready
You really shouldn't be testing button clicks like that - you can be more certain if you just call the function doSomething() directly. Same way that you don't test any internals of JQuery yourself.
If you really really want to test events on a fixture, have you tried just
$("#clickme").trigger('click');
Also, double check that fixture is inserted into DOM in when you debug the test (say via browser)
So I am making a website for radio streams and was told I should use Jquery and AJAX to load the HTML files into a div on button click so that I wouldn't have to make the user load a completely new HTML page for each radio stream. But I am a bit lost since I am new to this language and I am not entirely sure what I am doing wrong.
Currently I have a index.html page that loads each individual div and loads all the available radio stations in an iframe linking to an HTML file. In this HTML file there are around 40 buttons that each have to link to their own radio stream. On a button press I want said stream to load into the 'radio player' div for a smooth transition.
After trying to google the problem I was told to do this with the following JavaScript code:
$(function(){
$(".538").click(function(){
$("#div3").load("/includes/about-info.html");
});
});
Since each button is also showing its own image file, I tried to add class="538 to each image source so the JavaScript knows what is targeted. Unfortunately it doesn't seem to work at all and I have no clue what to do. I tried to do this in a separate index.js file which unfortunately didn't work, so I tried to use the JavaScript code in the HTML file itself, and this didn't seem to do the trick either.
TL/DR: trying to load HTML code in a div when an image button is clicked.
Is there perhaps a tutorial for this available? I tried to search the web but couldn't find anything at all. If anyone is able to help me out with this problem I'd love you forever.
I think what's happening is that you're working with dynamic elements. More importantly you should never use numbers to start off either a class name or id.
Unless you post a bit more code it's hard to figure out exactly what you're wanting to do.
If you work with dynamic html the click event won't work, because well you need do dynamically bind the event listener.
For that you can use
$('#dynamicElement').on('click', function() {
$(this).find('#elementYouWantToLoadInto').load('/includes/about-info.html');
});
The above code works if the element is nested in the button. If it's an external element then use.
$('#dynamicElement').on('click',function() {
$('#elementYouWantToLoadInto').load('/includes/abount-info.html');
});
You mentioned that this language is a bit new to you; If you're open to a bit of refactoring:
Your main page should have 2 sections:
<div id='myButtons'>
<input type='radio' data-url='/includes/about-info.html' />
<...>
</div>
<div id='myContent'></div>
<script>
$(function() { //jquery syntax - waits for the page to load before running
$('#myButtons').on('click', 'input', function() { // jquery: any click from an input inside of myButtons will be caught)
var button = $(this),
url = button.data('url'),
content = $('#myContent');
content.load(url);
});
</script>
Jquery: http://api.jquery.com/
you can try this
$('#myButtons').on('click', 'input', function() {
$.get("about-info.html", function(data) {
$("#div3").html(data);
});
});
or
$(document).ready(function(){
$(function(){
$(".radio538").click(function(){
$("#div3").load("/includes/about-info.html");
});
});
})
$(document).ready(function(){
$('#radio1').on('click',function(){
#('#loadradiohere').load('/includes/about-info.html');
});
});
Try that code in your .js file. I am still working for a similar project man.
The typeahead display gets stuck to the body when using append to body in combination with routing.
typeahead-append-to-body="true"
I used the Angular seed project and one of the simple Typeahead examples and replicated the problem: http://plnkr.co/WSNIRKLqOCLqO87jp3an
Load page
Select 'view2'
Select 'view1'
Type alpha character 'a' into the input
Observe the typeahead display attached to the body
Select view2
Observe display is still attached to the body
Problem happens in all the browsers I tried.
I see the click bindings to the document fire but the dismissClickHandler is not called if the page is has been routed to before. Meaning it works fine the first time, but when you go back to a page that you have been to before it never firs the dismissClickHandler.
https://github.com/angular-ui/bootstrap/blob/master/src/typeahead/typeahead.js
// Keep reference to click handler to unbind it.
var dismissClickHandler = function (evt) {
if (element[0] !== evt.target) {
resetMatches();
scope.$digest();
}
};
$document.bind('click', dismissClickHandler);
originalScope.$on('$destroy', function(){
$document.unbind('click', dismissClickHandler);
});
var $popup = $compile(popUpEl)(scope);
if ( appendToBody ) {
$document.find('body').append($popup);
} else {
element.after($popup);
}
Any thoughts?
Please note that this is fixed using the latest versions of Angular (1.4.7) and Angular UI Bootstrap (0.14.3) - at the time of this writing. As such, I've closed https://github.com/angular-ui/bootstrap/issues/2551.
I believe this is a bug of the angular-bootstrap to not call $popup.remove() when its scope has been destroyed.
The reason it seems to work fine at the first time is because when you navigate to view 2, the template has't been ready in a cache yet, so it take sometime to load, and that allow the dismissClickHandler() to get executed and hide a popup.
But just hidding the popup is not enough. It should be removed from the DOM.
In your plunker, if you navigate back and forth between views a few times, then inspect the DOM, you will see a lot of dangling ui elements are still there but hidden in the document.body.
runTarm put me on the right track. This is my (quite dirty) fix, I remove the typeahead from the DOM on destroy of the scope:
originalScope.$on('$destroy', function(){
$document.find('[id^=typeahead]').remove();
$document.unbind('click', dismissClickHandler);
});
I submitted a bug: https://github.com/angular-ui/bootstrap/issues/2551
Okay basically I have a post:
<div class=post>
<div class=content></div>
<div class=content-meta></div>
</div>
thats the prototype of it to help explain
so what I want to do is use some JS to basically delete or hide the div 'content-meta'
Using JQuery I have:
$('.content-meta').remove();
however when I am using CasperJS I am a little puzzled as how I should implement this code.
I am looking to manipulate a post prior to screen capturing it (the screencapture part works fine)
Heres the code (URL's OMITTED) I have been testing with, It picks up the class just fine, but I have no idea where/how to execute the Jquery to remove the detected element prior to screen capture:
casper.start('http://pageurl.com/XYZ', function() {
if (this.exists('.content-meta')) {
this.echo('found .content-meta', 'INFO');
} else {
this.echo('.content-meta not found', 'ERROR');
}
this.captureSelector('resultingcapture.png', '.post');
});
casper.run();
TL;DR How do you execute JS/Jquery from within a CasperJS function?
For execute javascript code from CasperJS, You have to use evaluate() method
The evaluate() method as a gate between the CasperJS environment and the one of the page you have opened; everytime you pass a closure to evaluate(), you're entering the page and execute code as if you were using the browser console.
Your code should be something like this:
var casper = require('casper').create();
casper.start('http://pageurl.com/XYZ', function() {
if (this.exists('.content-meta')) {
this.echo('found .content-meta', 'INFO');
//evaluates an expression in the current page DOM context.
this.evaluate(function(){
//delete div 'content-meta'
$('.content-meta').remove();
});
this.then(function(){
this.captureSelector('resultingcapture.png', '.post');
});
} else {
this.echo('.content-meta not found', 'ERROR');
}
});
casper.run();
Note: This code is going to run only if the webcontext includes jQuery, otherwise you have to remove the div using just javascript.