Stuart Brown
Stuart Brown

Reputation: 987

Using Chai to test value of HTML element

I'm learning Mocha and Chai and am trying to write a test to check the value of the H1 tag on a page. I have the test below which attempts to do this in three of ways:

const expect  = require('chai').expect;
const assert = require('chai').assert;
const request = require('request');
const chaiHttp = require('chai-http');
const app = require('../../app');
const chai = require('chai');
chai.use(require('chai-dom'));
chai.use(chaiHttp);

//first attempt
describe('Story Homepage', function(){
  it('Should have an H1 of My Home Page', function(){
  chai.request(app)
  .get('/', function (){
     expect(document.querySelector('h1')).should.have.text('My Home Page');
     });
  })
});

//second attempt
describe('Story Page Tests', function () {
it('Homepage H1 is My Home Page', function(done) { 
    chai.request(app)
    .get('/', function(done){
      expect(document.querySelector('h1').should.have.text('My Home Page'));
      done(); 
    })
  });
});


//third attempt
describe('Story Page Tests', function () {
  it('Homepage H1 is My Home Page', function(done) { 
      chai.request(app)
      .get('/')
      .end(function(err, res) {
        expect(document.querySelector('h1').should.have.text('My Home Page'));
      done();                               
    });
  });
});

I've attempted to use the chai-dom extension in the way described here https://github.com/nathanboktae/chai-dom#texttext to do this. However: The first test passes but should not pass (the on the page is not the same as asserted by the test)

The second of the tests reports an error Error: Timeout of 15000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. but I think that I am using done correctly above.

The third test reports an error Uncaught ReferenceError: document is not defined which seems logical but I'm not really sure how to resolve it.

Does anyone offer advice on how to do this correctly?

Upvotes: 3

Views: 13046

Answers (3)

Kevin Danikowski
Kevin Danikowski

Reputation: 5196

I used node-html-parser and would recommend you do the same: https://www.npmjs.com/package/node-html-parser

Here is my code:

import {parse} from 'node-html-parser';
import {expect} from 'chai';
import {describe, it, before} from 'mocha';
import request from 'supertest';

describe('Page Tests', async function () {
  let page = null;

  before(async function(){
    const response = await request(server).get(workingTestUrl);

    page = parse(response.text);
  })

  it('Should give a person page at test url', async function () {
    const obituarySection = page.querySelector('#main-obituary');

    expect(obituarySection).to.exist;
  }); 
});

Upvotes: -1

Vladyn
Vladyn

Reputation: 583

Hello @Stuart I'm working on something similar and I had almost the same issue. From what I've tried so far I found the JS-DOM in combination with chai-dom for quite useful. So having a simple html constructor for creating an element like this:

function HtmlElement(el) {
  this.element = (el instanceof HTMLElement) ? el : document.createElement(el);
}

HtmlElement.create = function create(el) {
  return new HtmlElement(el);
};

HtmlElement.prototype.addId = function addId(id) {
  this.element.id = id || '';
  return this;
};

...and further in the tests:

describe("Checks element methods presence on the prototype", function(){
    it('should have addClass method', function () {
    const ul = (new HtmlElement('ul').addId('some'));
    console.log(ul.element);
    ul.element.should.equal(`<ul id="some"></ul>`);
  });
});

should pass.

Upvotes: 1

Nathan Black
Nathan Black

Reputation: 440

Your 3rd attempt is written correctly from an asynchronous mocha test perspective, but you have a fundamental issue in that you are running your tests in Node.js as I can tell, and you are writing an assertion code as if it were in the browser.

If you are doing an HTTP request from node and getting back an HTML response, there is no browser in the picture at all, which means no DOM API and no document object thus your document is not defined error.

If you want to do unit testing in the browser. There are many, many ways to do this, but try a simple tutorial like this to get started.

Upvotes: 2

Related Questions