Cake O'Clock

Project:

https://www.codecademy.com/paths/web-development/tracks/test-driven-development-javascript/modules/why-test/projects/cake-clock

This projects includes two things that I don’t think they covered. WebDrivers (maybe through handlebars, but that’s different). And the assert. has not been covered, yet this project involves both of these.

I have a question about browser.url(’/) . Why doesn’t it include the website address (‘www.example.com’)

You’re doing testing on a site being served from within the learning environment. It’s using express to handle the routes, so ‘/’ is being resolved to that local site.

You can dig into the other files that you don’t need to modify for the lesson to see how it’s working if you’d like. Open up the folder, you’ll see a folder named routes, then an index.js file. Here’s a snippet of the code in there that is serving the GET ‘/’ route:

router.get('/', async (req, res) => {
  const order = await Order.findOne({});

  res.render('index', { order });
});
1 Like

So many questions here. So this jsdom… have we learned this yet? There also no explanation. I searched the web and foudn it explained this way:

const jsdom = require('jsdom');
const {JSDOM} = jsdom;
const dom = new JSDOM(`<!DOCTYPE html>`);
const document = dom.window.document;

but that’s not how the code we have has it. I also put a few console.logs to see what its doing… and I’m still not getting it.

const {jsdom} = require('jsdom');

const parseTextFromHTML = (htmlAsString, selector) => {

  console.log(htmlAsString)

  const selectedElement = jsdom(htmlAsString).querySelector(selector);

  if (selectedElement !== null) {

    console.log(selectedElement)

    return selectedElement.textContent;

  } else {

    throw new Error(`No element with selector ${selector} found in HTML string`);

  }

};

.
.
.
// Add the 'labels the pick up hour' test here

    it('The field in the order ticket must be labeled “Pick up time:”', ()=>{

      const label = "pick up time:"

      browser.url('/')

      var element = browser.getText('#pickUp')

      console.log(element)

      assert.include(element, label)

    })

and this is the test results:


 npm test

> cake-bar-js@0.0.0 test /home/ccuser/workspace/why-test-project-2
> bin/wdio-test

<body>
    <div class="banner">
    <h1>CAKE BAR</h1>
  </div>

  <div class="body-container">
    <div class="menu">
      <form id="cake-form" action="/place-order" method="post">
        <div class="form-container">
          <div class="form-row">
            <h2>Enter your name</h2>
          </div>

          <div class="form-row">
            <div class="name-flex">
              <div class="name-col-1">
                <input type="text" id="name" name="name" value="">
              </div>
            </div>
          </div>

          <div class="form-row">
            <h2>Pick a cake type</h2>
          </div>

          <div class="form-row">
            <div class="input-col">
              <label for="plain">
                <input type="radio" id="plain" name="cakeType" value="Plain">Plain<br>
              </label>
            </div>
            <div class="input-col">
              <label for="whole-wheat">
                <input type="radio" id="whole-wheat" name="cakeType" value="Whole Wheat">Whole Wheat<br>
              </label>
            </div>
          </div>

          <div class="form-row">
            <h2>Add fillings</h2>
          </div>

          <div class="form-row">
            <div class="input-col">
              <label for="strawberries">
                <input type="checkbox" id="strawberries" name="fillings" value="Strawberries">Strawberries<br>
              </label>
              <label for="blueberries">
                <input type="checkbox" id="blueberries" name="fillings" value="Blueberries">Blueberries<br>
              </label>
              <label for="banana">
                <input type="checkbox" id="banana" name="fillings" value="Banana">Banana<br>
              </label>
              <label for="apple">
                <input type="checkbox" id="apple" name="fillings" value="Apple">Apple<br>
              </label>
            </div>
            <div class="input-col">
              <label for="macadamia-nuts">
                <input type="checkbox" id="macadamia-nuts" name="fillings" value="Macadamia Nuts">Macadamia Nuts<br>
              </label>
              <label for="sprinkles">
                <input type="checkbox" id="sprinkles" name="fillings" value="Sprinkles">Sprinkles<br>
              </label>
              <label for="chocolate-chips">
                <input type="checkbox" id="chocolate-chips" name="fillings" value="Chocolate Chips">Chocolate chips<br>
              </label>
              <label for="bacon">
                <input type="checkbox" id="bacon" name="fillings" value="Bacon">Bacon<br>
              </label>
            </div>
          </div>

          <div class="form-row">
            <div class="input-col">
              <h2>Choose a size</h2>
            </div>
            <div class="input-col">
              <h2>Set a pick up</h2>
            </div>
          </div>

          <div class="form-row select-row">
            <div class="select-col">
              <div class="styled-select">
                <select id="select-stack" name="size">
                  <option id="single" value="1">Single Stack</option>
                  <option id="double" value="2">Double Stack</option>
                  <option id="triple" value="3">Triple Stack</option>
                  <option id="quadruple" value="4">Quadruple Stack</option>
                  <option id="quintuple" value="5">Quintuple Stack</option>
                  <option id="sextuple" value="6">Sextuple Stack</option>
                  <option id="septuple" value="7">Septuple Stack</option>
                  <option id="octuple" value="8">Octuple Stack</option>
                  <option id="nonuple" value="9">Nonuple Stack</option>
                  <option id="decuple" value="10">Decuple Stack</option>
                  <option id="centuple" value="100">Centuple Stack</option>
                </select>
              </div>
            </div>
            <div class="select-col">
              <div class="styled-select">
                <select id="select-pickUp" name="pickUp">
                  <option id="8:00" value="8:00">8:00</option>
                  <!-- Fix the value below -->
                  <option id="9:00" value="9:00">9:00</option>
                  <option id="10:00" value="10:00">10:00</option>
                  <option id="11:00" value="11:00">11:00</option>
                  <option id="12:00" value="12:00">12:00</option>
                  <!-- Remove the line below-->
              
                </select>
              </div>
            </div>
          </div>

          <div class="form-row place-order-div">
            <input class="button" id="submit-order" type="submit" value="Place order">
          </div>
        </div>
      </form>

      <form action="/clear-order" method="post">
        <div class="form-container">
          <div class="form-row place-order-div">
            <input class="button" id="clear-order" type="submit" value="Clear">
          </div>
        </div>
      </form>
    </div>

    <div class="order">
      <h2 id="deliver-to">deliver to: <span></span></h2>
      <h2 id="cake-type">cake: <span></span></h2>
      <h2 id="fillings">fillings: <span></span></h2>
      <h2 id="size">pancake count: <span></span></h2>
      <!-- Fix the header below -->
      <h2 id="pickUp">pick up time: <span></span></h2>
    </div>
  </div>
  
</body>
HTMLSelectElement {}

                  8:00
                  
                  9:00
                  10:00
                  11:00
                  12:00
                  
              
                
PICK UP TIME:
------------------------------------------------------------------
[phantomjs #0-0] Session ID: 21fc7a80-25f2-11eb-bb61-7514d45a1055
[phantomjs #0-0] Spec: /home/ccuser/workspace/why-test-project-2/test/features/user-visits-index-test.js
[phantomjs #0-0] Running: phantomjs
[phantomjs #0-0]
[phantomjs #0-0] User visits index
[phantomjs #0-0]
[phantomjs #0-0] to post an order
[phantomjs #0-0]   ✓ starts with a blank order
[phantomjs #0-0]   ✓ does not provide options outside of working hours
[phantomjs #0-0]   ✓ dispays hours in xx:00 format
[phantomjs #0-0]   1) The field in the order ticket must be labeled “Pick up time:”
[phantomjs #0-0]   ✓ accepts the customer name
[phantomjs #0-0]   ✓ accepts the cake type
[phantomjs #0-0]   ✓ accepts multiple fillings

[phantomjs #0-0]   ✓ accepts the stack size
[phantomjs #0-0]
[phantomjs #0-0] to clear an order
[phantomjs #0-0]   ✓ deletes the selected options
[phantomjs #0-0]
[phantomjs #0-0]
[phantomjs #0-0] 8 passing (5s)
[phantomjs #0-0] 1 failing
[phantomjs #0-0]
[phantomjs #0-0] 1) to post an order The field in the order ticket must be labeled “Pick up time:”:
[phantomjs #0-0] expected 'PICK UP TIME:' to include 'pick up time:'
[phantomjs #0-0] AssertionError: expected 'PICK UP TIME:' to include 'pick up time:'
[phantomjs #0-0]     at Context.it (/home/ccuser/workspace/why-test-project-2/test/features/user-visits-index-test.js:63:14)
[phantomjs #0-0]

npm ERR! Test failed.  See above for more details.


What is jsdom doing? Why is console.log(selectedElement) logs as HTMLSelectElement {} ? Why does this apparant HTMLSelectElement {} empty object have a .textContent attribute/key?

So passing browser.getHTML('body') into parseTextFromHTML( browser.getHTML('body', '#pickUp') returns a lowercase version of:

var element = browser.getText('#pickUp')

which returns the CAPITALS version (actual representation of the text) . So I stuck with my method of checking and changed the criteria to:

const label = "PICK UP TIME:"

Would still love to know what jsdom does and why it’s important. Why my way might not be the best, or if it’s ok.

It looks like you’re on the Web Development track, so you’ll cover jsdom a bit more in the Learn Server Testing with TDD part of that track. Not sure if they changed the order in the new paths.

There’s a lot more hidden properties of the object. You can get a glimpse of it by using the built-in util module in Node.

const util = require('util');  //put at the top

//use this for your log instead
console.log(util.inspect(selectedElement, {showHidden: true, depth: 2}));

Now you’ll see a lot more than what appears to be an empty object.

1 Like

So yeah… this project is BEFORE when you learn everything… I would recommend copy and paste the hints but pay attention to it. Don’t spend too much time on it.