Adding tests to video player code

I did that and received an error:

But you did not say I was going to receive an error.

https://jsfiddle.net/av4z8ojx/

TypeError: expect(…).tohaveClass is not a function

Was I supposed to get that error?

or did I do something wrong?

 it("when one playButton is initialized", function() {

        // given
        manageCover.init({
          container: ".play2",
          playButton: ".playb"
        });

        document.body.classList.remove("initial-fade");

        // when
        const playButton = document.querySelector(".playb");
        simulateClick(playButton);

        // then
        expect(document.body).tohaveClass("initial-fade");
      });

      it("when all playButtons are initialized", function() {

        // given
        manageCover.init({
          container: ".container",
          playButton: ".cover"
        });

        document.body.classList.remove("initial-fade");

        // when
        const playButton = document.querySelector(".playb");
        simulateClick(playButton);

        // then
        expect(document.body).tohaveClass("initial-fade");
      });

My apologies - that was a typing error on my part. The casing is important, so it needs to be toHaveClass instead of tohaveClass. I’ll update the previous post now.

1 Like

I fixed it here: https://jsfiddle.net/zdLmvo2a/

What do I do next?

That would be this:

After that I’ll have something else for when the classList is expected to be false

These would be changed to what?

expect(container.classList.contains("hide")).toBe(false);
expect(container.classList.contains("hide")).toBe(false);
expect(document.body.classList.contains("initial-fade")).toBe(false);

They will be changed to the same type of thing using toHaveClass, but the not matcher is used before it to reverse things.

What else gets done to these?

expect(document.body).toHaveClass("hide");

expect(document.body).toHaveClass("initial-fade");

This gets added somewhere? .not.toBe

What else gets done to those lines?

but the not matcher is used before it to reverse things.

I don’t understand what that means.

Maybe I am looking at the wrong section of code, I am not sure.

Does this not get changed:

expect(container.classList.contains("hide")).toBe(false);

to this:

expect(document.body).toHaveClass("hide");

But to something else?

Does the order in which the line is written get moved around?

You just add .not to the expectation to change it from expecting true to expecting false.

The following is expected to be true:

expect(something).toBe(true);

And the following is expected to be false:

expect(something).not.toBe(true);

In the same manner, the following is expected to be true:

expect(document.body).toHaveClass("hide");

and the following is expected to be false:

expect(document.body).not.toHaveClass("hide");
1 Like

I did that here: https://jsfiddle.net/hp0bxaqf/

What am I ready to do next?

Am I able to start work on the next test?

This was as far as I was able to get.

it("with a single coverSelector", function() {

  // given
  manageCover.addCoverHandler({
    coverSelector: ".playb"
  });

});

Not quite yet. Continuing to work our way up through the tests, we have the no-parameters test that still uses toThrow(), which can be much easier to understand when we use toThrowError() instead.

It’s going to be similar to the “needs a coverSelector parameter” test, but is instead about needing a container parameter.

I did that here: https://jsfiddle.net/q5x8034p/

   it("with no parameters", function() {
      const fnCall = () => manageCover.init();
      expect(fnCall).toThrowError();
    });

Two things need to occur there that haven’t been done. Right now the test doesn’t tell us which error is expected to be thrown. You can have the test show you the error that’s thrown by giving toThrowError() a function parameter of /foo/ or something similar. That way you can then use the error message that’s shown to you to replace foo, with suitable text from the error instead.

The second thing that should occur from a test that expects an error, is to tell us what it needs to avoid that error. In this case it needs a function parameter similar to the other test that expects an error, but you really need to rename the test so that it tells us what function parameter it needs.

This is what I did: https://jsfiddle.net/9gexrd4w/

    it("needs a function parameter of container", function() {
      const fnCall = () => manageCover.init();
      expect(fnCall).toThrowError(/foo/);
    });

Where I then get this error:

Expected function to throw an exception with a message matching /foo/, but it threw an exception with message ‘Cannot read properties of undefined (reading ‘container’)’.

What do I do next?

You replace /foo/ with what we as the programmer need to know from the error message, which is:
/Cannot read properties of undefined/

1 Like

I did that here: https://jsfiddle.net/7prova1w/1/

    it("needs a function parameter of container", function() {
      const fnCall = () => manageCover.init();
      expect(fnCall).toThrowError(/Cannot read properties of undefined/);
    });

What am I up to next?

We now seem to be in a pretty good state to move on to the addCoverHandler test. First we look at the addCoverHandler test called “needs a coverSelector parameter”. The next test after that should be called “with a coverSelector parameter” where we give the addEventHandler a coverSelector string as it’s parameter.

Your previous instructions at post #205

Said this:

The next test will be called “with a single coverSelector”. Your previous attempt that that is quite wrong, so we’ll take it one line at a time.

In that “with a single coverSelector” test, define a coverSelector variable for the element with the playb classname.

That is what I did here: https://jsfiddle.net/uc5sb1em/

With the updated it " " from your new instructions.

it("with a coverSelector parameter", function() {

      // given
      manageCover.addCoverHandler({
        coverSelector: ".playb"
      });
      
     // const coverSelector = document.querySelector(".playb");

    });

Where I get this error:

SyntaxError: Failed to execute ‘querySelector’ on ‘Document’: ‘[object Object]’ is not a valid selector.

Which means I am needing this line I think, but it is not written the right way:

const coverSelector = document.querySelector(".playb");

That error is correct for your parameter is an object, not a selector. It needs to be a selector that you use for the function parameter.

What am I supposed to do next?

What are the next instructions?

Were you having me do something?

Am I supposed to wait for other instructions?

You seem to have some confusion about selectors, so I need to ask you about what you understand is a selector, more specifically, a cover selector.

I don’t understand:

Is this wrong?

     manageCover.addCoverHandler({
        coverSelector: ".playb"
      });

I was doing this:

In that “with a single coverSelector” test, define a coverSelector variable for the element with the playb classname.

or, I thought I was supposed to do that.

the variable: coverSelector:

the element: ".playb"

Is that not what I was supposed to do?

I seem to be confused about what part of the instructions I am currently working on.

Is this good or not good?

     manageCover.addCoverHandler({
        coverSelector: ".playb"
      });

Does that need to be fixed or no?

Yes that is wrong. The addCoverHandler function is being given an object as the argument to the function.

That is not a defined variable. What coverSelector is there, is a property of the object.

That is not an element. That is a string which is used as a selector. That selector would target a cover element, so it’s called a cover selector.

Are you able to better understand the instruction being given to you now?

Remember the recent post where I clearly pointed out the significant difference between property and parameter?

More accurately, that instruction should be to give addEventHandler a coverSelector string as its argument. For when you call functions they are called using arguments, and when you define functions, they are defined using parameters.