Node.JS testing DOM with Mocha? - node.js

I'm trying to do some simple view testing in my Node.JS app using the Mocha testing framework...
For example, I want to test that the <ol> on the page has n <li> children, given the number of records I setup in my test.
I tried using Apricot to do this, and while I got it to work, when it fails the error messages are fantastically unhelpful... also, it doesn't always work.
What I'd love is a simple way to test the response body for HTML elements, so I can determine if they match the data they should be displaying.
Here's my test in it's current state: https://gist.github.com/2330685
Anyone know how I can do this?

Posting the comment as answer as well.
For DOM manipulation or element finding, I am suggesting the great library cheerio, which can load the html as string and then use jQuery-like selectors. Also it seems to be really lightweight. I replaced the JSDOM with request + cheerio combination.

Related

JSDom's querySelectorAll function not retrieving elements inside of <div>

jsdom version 15.1.1 jest version 24.9.0 node.js version 10.16.0
I am trying to get information from an offline html page by using
var summaryInfo = document.querySelectorAll(".className");
Array.prototype.slice.call(summaryInfo).forEach(n => ... }
In this case there should return 6 arrays of info, but I only get 2
The same exact code works fine in a normal browser, but when I use jsdom with jest it has this problem
I put in a log to see what was being passed through and found with the 2 that work the outermost tag is an <li> and everything inside is just as it should be, but with the other elements the outermost tag is a <div> interestingly nothing shows up inside.
I also checked the html document I am drawing from to make sure that those <div> elements are indeed not empty and they aren't.
Any help that you can provide would be much appreciated!
Thank you in advance.
It turns out that the HTML page had a structure where some <li> tags did not have surrounding <ul> containers. While this worked in browsers like Chrome and Firefox, that was more because the browsers were designed to correct problems like that. Intrinsically my problem is with the HTML page I am trying to use and I can't correct that.

How can I use Express to render dynamic files?

I'm looking to use Express to render raw strings as HTML, with the ability to reference static files in a specified directory (CSS, images, and other resources).
I've done a lot of research, but I haven't seen anything that approaches what I'm trying to do. For example, I thought perhaps writing a custom templating engine that only pretended to load a file would cut it, but that doesn't seem to do the trick.
What's the best way to approach this?
There are many ways to do it.
It can done in any other templating engine as well but here i am guiding you to implement same using EJS(Embedded Javascript).
Use Express Generator to create an ExpressJS app with EJS templating Engine.
command :
express --ejs AppName
For more information about express Generator refer to doc here
Now EJS has tags such as :
1. <% code %> - Code that is evaulated without "echo" it is not printed out.
2. <%= code %> - Code that is evaluated and printed out and escaped!
3. <%- Code %> - Code that is evaluated printed out and not escaped!
So in your case you can use 3rd the third tag that i have mentioned above.
Render EJS views in the usual way from your route config:
res.render('index.ejs', {
// data you want to pass ..
});
Code sample
Some time ago i was playing around with EJS, i developed a very small blogApp for practice.
You can look into this view, line number 33, for more practical way of implementing same.

Showing Markdown-encoded blog posts with Node and Express

Hello,
I have been trying to learn Node with Express for about a week now. So far I got the basics of how to build MVC on top of it, and using JavaScript proved easier and cleaner than I would have ever gotten with another server language (except Python, maybe). But let's get into one of my first problems and one of a few I couldn't solve myself.
I'm using the Jade templating engine and I love it. I love how simple it is to input Markdown into the template. You just say :markdown and it's there!
But then I got into a problem. It's all easy to parse and print Markdown, however how am I supposed to display a blog post, for example, that's been stored as Markdown text in the database, on screen? I tried:
each entry in posts
h1 #{entry.title}
:markdown
#{entry.text}
div#post-footer
#{entry.date}
But the # gets parsed as a Markdown header, not a Jade directive. How do I make it so I can display Markdown properly?
var md = require('marked');
res.render('template', {md: md, markdownContent: markdownContent};
then inside the template use
div!= md(markdownContent);

Reusing Yesod widgets in AJAX results

I'm writing a very simple Yesod message list that uses AJAX to add new list items without reloading the page (both in the case of other users modifying the database, or the client themselves adding an item). This means I have to encode the HTML structure of the message items in both the Halmet template (when the page loads initially) and the Julius template (for when the dynamic addition happens). They look something like this:
In homepage.hamlet:
$if not $ null messages
<ul id=#{listId}>
$forall Entity mid message <- messages
<li id=#{toPathPiece mid}>
<p>#{showMarkdown $ messageText message}
<abbr .timeago title=#{showUTCTime $ messagePosted message}>
And in homepage.julius:
function(message) {
$('##{rawJS listId}').prepend(
$('<li>')
.attr('id', message.id)
.append('<p>' + message.text + '</p>')
.append($('<abbr class=timeago />')
.attr('title', message.posted).timeago())
.slideDown('slow')
);
}
I'd love to be able to unify these two representations somehow. Am I out of luck, or could I somehow abuse widgets into both generating an HTML response, and filling in code in a JavaScript file?
Note: Of course, I understand that the templates would have to work very differently, since the AJAX call is getting its values from a JS object, not from the server. It's a long shot, but I thought I'd see if anyone's thought about this before.
I think it's something of a AJAX best-practice to pick one place to do your template rendering, either on the server or client. Yesod is (currently) oriented toward doing the rendering on the server.
This can still work with AJAX replacement of contents, though. Instead of getting a JSON response from the POST, you should get a text/html response that contains the result of rendering the template on the server with the values that would have been returned via JSON and then replacing the innerHTML of the DOM node that's being updated.
If you want to support both JSON and HTML responses (to support 3rd party applications via API or something) you would have to make the format of the response be a function of the request; either appending ".json" or ".html" to the URL or including a HTTP header that lists the specific document type required by the client.
It would be nice if Yesod provided a 'jwhamlet' template or something that would render the HTML via javascript in order to support client rendering, but I'm not aware of one. That's not to say there isn't one I'm not aware of, though, so keep an eye open for other answers.
If you wanted to make such a thing, you might try tweaking the hamlet quasi-quote code so that instead of expanding the quasi-quotes to an html-generating function, it expanded them to a JSON-generating function and a pre-rendered chunk of text that's a template in mustache-style such that the JSON returned by the function would provide the correct context for the template to be rendered the way you want.

How to use Ember.js {{action}} in Handlebars.js templates on top of Jade

I'm using Ember.js and Handlebars.js for a project I'm working on at the moment. Server-side is Node.js + express and I make use of the Jade templating engine.
Now, whenever I want to tie actions to DOM elements, I use the {{action}} attribute of Ember.js. Currently, this is how my code looks in Jade:
script(type='text/x-handlebars', data-template-name='frontpage')
div.logo(''='{{action goToFrontpage}}')
The above does work, however, the ''='{{action goToFrontpage}}' part seems somewhat hackish.
Is there any other way of doing this? Perhaps a best-practice when combining Ember.js, Handlebars.js, and Jade?
Sometimes it's better to just use html in Jade.
<div {{action GoToFrontpage}} class="logo"></div>
An other example I see a lot is the strong tag.
.stuff
| This is an
strong important
| message.
You can write this
.stuff This is an <strong>important</strong> message.
I find the second a lot more readable and concise.

Resources