jasmine / jasmine-browser-runner

Serve and run your Jasmine specs in a browser
49 stars 23 forks source link

Can Jasmine-browser-runner specs interact with a webapp? #26

Closed BawdyInkSlinger closed 1 year ago

BawdyInkSlinger commented 1 year ago

I'm sure this title is confusing so let me explain my use case:

My product only has a frontend--a single page app. I already use jasmine for the unit tests. But for the integration/end to end tests, I use testcafe. The problem is, testcafe is very slow so I'm looking for alternatives. Since my product is 100% frontend, I don't need to serve my pages. I think that gives me an opportunity that doesn't normally exist.

In theory (I think?), I should be able to render my product in the same HTML page as the test runner. Then, my specs could interact with my product and assert on the HTML. I'm assuming if I could figure out how to do that, the tests would run much faster than they do with testcafe.

If this is sound reasoning (please tell me if it's not), here's my question: how do I use a custom html test runner? I'd need to merge my product's html with the test runner html, so they both exist on the same page.

sgravrock commented 1 year ago

It depends on where your HTML is rendered.

If it's rendered client-side by the code that you're testing, then this is a well-trod path. The idea is to set up a hidden DOM node in a beforeEach and then tell the code under test to operate inside of that:

// Untested, but should show the basic idea
beforeEach(function() {
    let root = document.getElementById('content-root');
    if (root) {
        root.innerHTML = ''; // clear out results of previous test
    } else {
        root = document.createElement('div');
        root.id = 'content-root';
        root.style.display = 'none'; // so we don't pay for layout calculation
        document.body.appendChild(root);
    }
});

it('should do something', function() {
    myApp.renderIn(document.getElementById('content-root'));
    // ... the rest of the test
});

That assumes that your application can be told to work inside of a specific DOM subtree and not affect elements elsewhere in the page. If it can't do that, you might need to stick with an end to end testing framework.

If your HTML is server-rendered, I don't currently have a good solution. That's not an unreasonable thing to want. But in practice people who go down that road usually end up needing the capabilities of a full end to end testing framework, running into conflicts between their code and Jasmine's HTML, or both.

BawdyInkSlinger commented 1 year ago

That assumes that your application can be told to work inside of a specific DOM subtree and not affect elements elsewhere in the page.

I think it probably can. I'll try it and see.

If your HTML is server-rendered, I don't currently have a good solution.

It's 100% client rendered.

Do you think using JSDOM with jasmine-node might be an easier path to go down than jasmine-browser-runner with an embedded app? I can try both, but I haven't put much time into either, so your opinion may save me considerable time.

sgravrock commented 1 year ago

JSDOM is going to be easier if your code needs the whole page to itself. Otherwise I'd expect either approach to take about the same effort.