Quality Assurance and Testing with Chai - Run Functional Tests Using a Headless Browser

i’m trying to finish the course of " Quality Assurance and Testing with Chai " however at the last two chalenges of " Run Functional Tests Using a Headless Browser " it seems there’s a glitch a bug or my code is somehow wrong , i am getting the error " AssertionError [ERR_ASSERTION]: No open window with an HTML document ",
i’ve even tried copying the answer from git a hint page and still didn’t pass .

any idea what should i do ?

Your project link(s)

solution: boilerplate-mochachai - Replit

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0

Challenge: Quality Assurance and Testing with Chai - Run Functional Tests Using a Headless Browser

Link to the challenge:

1 Like

There’s an issue with replit and zombie working (or not) together.
You can run the headless browser tests locally by changing your Browser.site url to http://localhost:3000/ (or whichever PORT you’re running the app on).

1 Like

i tried

that also didn’t work .
i’ve never tried cloning an FCC boilerplate before , i’ve tried publishing the app with my solution with github pages " cause the test ask for live URL " but that also wasn’t a good idea . also tried codesandbox.io it seems that i have the same error

1 Like

Try removing the parentheses from done in this return statement:

suiteSetup(function(done) {
    return browser.visit('/', done());
  });

…and keep the local Browser.site address.

1 Like

This all boils down to issues with getting the async stuff right with done. My guess is any solutions that work by setting the Browser.site to localhost actually work by minimizing the time needed to visit the site to “fast enough” to avoid async problems.

The first issue is you are calling done() instead of passing done to browser.visit():

suiteSetup(function(done) {
  return browser.visit('/', done());
});

When you use done() you are calling done(). You need to give done as the callback to browser.visit():

suiteSetup(function(done) {
  return browser.visit('/', done);
});

see here, first example, so that browser.visit() can call done when the visit is complete.

Next, you have to get your suiteSetup() hook outside your suite instead of inside your suite.

Finally, your test() cases need to have a done(). Currently yours looks like

    test('Submit the surname "Colombo" in the HTML form', function(done) {
    ...
    });

but they need a done() call to signal the end of the test:

    test('Submit the surname "Colombo" in the HTML form', function(done) {
    ...
      done();
    });

Additionally, I’m not sure what function, if any, your after() function has in relation to passing the tests. Its removal does not affect the tests in any way I could find.

Implementing these changes allowed your code to pass the tests without setting the site to localhost as is often suggested.

1 Like

thank you so much , that was the problem , in earlier chalenges i had to change this so i can pass the test , first time it wasn’t working without the parenthathese

1 Like

Then at the root level of the 'Functional Tests with Zombie.js' suite, instantiate a new instance of the Browser object with the following code:

const browser = new Browser();

And use the suiteSetup hook to direct the browser to the / route with the following code:

suiteSetup(function(done) {
 return browser.visit('/', done);
});

Unless I’m misunderstanding something, the instructions above imply that you should put the suiteSetup hook inside the test suite?

If I change my Browser.site url to my repl live url, the tests fail every single time, whether I put the above hook inside or outside my test suite.

Here’s my repl: boilerplate-mochachai - Replit

I think I’ve made the changes you suggest but it’s failing the headless browser tests. If I change Browser.site to local url, and put the hook back inside the suite, it works just fine.

Can you see what’s wrong with my code?

As an aside, adding the ‘after’ code restarts the repl after it (always!) crashes when running functional tests. It allows challenges to pass on FCC, which otherwise timeout.

1 Like

i was trying to do what you said , but i couldn’t do it , when one test is fixed the other fails .
in earlier challenges i had to make the code look this way so i can pass or the tests doesn’t timeout , it doesn’t sound logical to change earlier tests cod in the last challenge.

1 Like

Fork and update of your repl. All tests pass and fCC’s tests pass although I had to comment the after() and start the server and immediately run the fCC tests. The timing never linked up between the tests and my server with after().

You need a done() in the browser.pressButton() callback to signal that it is finished and a done() in the test() to signal that it is finished.

1 Like

Not sure what you mean since I was only adding changes to your headless tests in the second part of the functional tests. I just posted a full working example in another reply, so feel free to look there.

1 Like

there should be two done() in the tests ? one in the browser.pressButton and one after it ?

also i didn’t mean to offend you in anyway , i just have too many questions about this , i realy don’t understand how everything is connected .

1 Like

Now the tests initially pass but then the repl continuously crashes and restarts with error messages in the console. I pasted in your code exactly.


Also, I have no understanding why more than one done() is required in each of those tests.

It seems that the FCC instructions for this are incorrect then?

1 Like

Yes. Both. browser.pressButton() and test() are asynchronous here since they are waiting on the browser to execute code that causes data transfer over the internet (theoretically), so they both have to be signalled that the code has executed, so both need a done(). Although, it seems the browser.pressButton() is usually fast enough to avoid async problems.

1 Like

I have the same behavior, but the project is to test your testing and the requirements want tests that pass and the correct assertions and mention nothing about behavior afterwards. Admittedly, it used to bother me that the server crashed or otherwise misbehaved, but as this behavior exists on most of the projects and assignments that use the assertion analyzer code and I stopped worrying about it.

I have a feeling this is all mocha’s fault (or my fault for missing some teardown thing) but I’ve not looked for it recently since I use jest for front-end tests and mocha for back-end without these issues.

1 Like

sollution does not work for me , please assist here is my code below …
Also when i move the setup above i the previous excercises test fails
please help for the life of me i cant figure out what im doing wrong

all tests pass i.e i can assert the name , surname and count but the first test “All tests should passs” keeps failing thank you for assistance…
the error i get is …
23 passing (62ms)
2 failing

  1. Functional Tests with Zombie.js
    “Famous Italian Explorers” form
    Submit the surname “Colombo” in the HTML form:
    AssertionError [ERR_ASSERTION]: No open window with an HTML document
const chai = require('chai');
const assert = chai.assert;

const server = require('../server');

const chaiHttp = require('chai-http');
chai.use(chaiHttp);

suite('Functional Tests', function () {
  this.timeout(5000);
  suite('Integration tests with chai-http', function () {
    // #1
    test('Test GET /hello with no name', function (done) {
      chai
        .request(server)
        .get('/hello')
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.text, 'hello Guest');
          done();
        });
    });
    // #2
    test('Test GET /hello with your name', function (done) {
      chai
        .request(server)
        .get('/hello?name=xy_z')
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.text, 'hello xy_z');
          done();
        });
    });
    // #3
    test('Send {surname: "Colombo"}', function (done) {
      chai
        .request(server)
        .put('/travellers')
        .send({
          surname: "Colombo", 
        })
        .end(function (err, res) {
          assert.equal(res.status, 200)
          assert.equal(res.type, 'application/json')
          assert.equal(res.body.name, 'Cristoforo')
          assert.equal(res.body.surname, 'Colombo')
          done();
        });
    });
    // #4
    test('Send {surname: "da Verrazzano"}', function (done) {
      chai
        .request(server)
        .put('/travellers')
        .send({
          "surname": "da Verrazzano"
        })
        .end((err, res)=> {
          assert.equal(res.status, 200)
          assert.equal(res.type, 'application/json')
          assert.equal(res.body.name, 'Giovanni')
          assert.equal(res.body.surname, 'da Verrazzano')
          done();
        })
    });
  });
});

const Browser = require('zombie');
Browser.site = 'http://localhost:3000/'; // Your URL here
const browser = new Browser();
// suiteSetup(function(done) {
//   return browser.visit('/', done);
// });

suite('Functional Tests with Zombie.js', function () {
  this.timeout(5000);

  // suiteSetup(function(done) {
  //   return browser.visit('/', done);
  // });

  suite('Headless browser', function () {
    test('should have a working "site" property', function() {

      suiteSetup(function(done) {
        return browser.visit('/', done);
      });
      console.log('wow')
      assert.isNotNull(browser.site);
    });
  });

  suite('"Famous Italian Explorers" form', function () {
    
    // #5 'Submit the surname "Colombo" in the HTML form'
    test('Submit the surname "Colombo" in the HTML form', function (done) {
      browser.fill('surname', "Colombo").then(() => {
        browser.pressButton('submit', () => {
          browser.assert.success();
          browser.assert.text('span#name', 'Cristoforo');
          browser.assert.text('span#surname', "Colombo");
          browser.assert.elements('span#dates', 1);
          done();
        });
      });
      done();
    });
    // #6
    test('Submit the surname "Vespucci" in the HTML form', function (done) {
      assert.fail();

      done();
    });
  });
});

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.