SuperUberDuper
SuperUberDuper

Reputation: 9633

How to get karma to clear the dom after each test?

The component I'm testing does some changes to the dom in an it() test, however it remains there in the next it() test, and this breaks my test. Is there a way to reset the DOM each it() test?

Upvotes: 5

Views: 7446

Answers (3)

Jan Esser
Jan Esser

Reputation: 111

For none JQuery users:

afterEach(function () {
    document.body.innerHTML = '';
});

Above removes all the <script> tags which are added by default, but that does not matter, because they have alreay been executed once (and Karma does never refresh the browser, at least not till all tests finish).

Hence you can also use beforeEach(...) (but I like to think of it as a dining table, you don't clean up before you start, you clean up after yourself).


I wrote a little DomCleaner that keeps track of events boud during your tests and cleans the body on cleanup (requireJS but you can change the code to your needs):

define(function () {
    'use strict';

    var installed = false,
        documentAddListener,
        documentListeners,
        windowAddListener,
        windowListeners;
    return {
        install: function () {
            if (installed) {
                throw new Error('Trying to install document cleaner, but its already installed!');
            }
            installed = true;
            documentAddListener = document.addEventListener;
            windowAddListener = window.addEventListener;
            spyOn(document, 'addEventListener');
            spyOn(window, 'addEventListener');
            documentListeners = [];
            windowListeners = [];
            document.addEventListener.and.callFake(function () {
                documentListeners.push(arguments);
                documentAddListener.apply(null, arguments);
            });
            window.addEventListener.and.callFake(function () {
                documentListeners.push(arguments);
                windowAddListener.apply(null, arguments);
            });
        },
        cleanup: function () {
            if (!installed) {
                throw new Error('Trying to cleanup document, but cleaner is not installed!');
            }
            installed = false;
            documentListeners.forEach(function (listener) {
                document.removeEventListener.apply(null, listener);
            });
            windowListeners.forEach(function (listener) {
                window.removeEventListener.apply(null, listener);
            });
            documentListeners = [];
            windowListeners = [];
            document.body.innerHTML = '';
        },
    };
});

use it like this (in your first describe):

beforeEach(function () {
   domCleaner.install();
});
afterEach(function () {
   domCleaner.cleanup();
});

Upvotes: 11

SuperUberDuper
SuperUberDuper

Reputation: 9633

I had to do this manually in each test method.

Just use DOM operations that remove stuff from the html using javascript.

stuff like

document.body.innerHTML = '';

Upvotes: 0

Marcos Savoury
Marcos Savoury

Reputation: 317

If using Jasmine - Use the beforeEach function to run a command before each test. In that function, you can clear the DOM. An example using jQuery:

describe("A test suite", function() {
    beforeEach(function () {
        $('body').empty();
    });                                                                                                                                                                                                                                   
});

Upvotes: 4

Related Questions