Drum Machine Tests fail even though it is working

Tell us what’s happening:

Hi, all! My Drum Machine project is almost done and all tests are passing except these two:

  • Test 5: When I click on a .drum-pad element, the audio clip contained in <audio> element should be triggered.
  • Test 7: When a .drum-pad is triggered, a string describing the associated audio clip is displayed as the inner text of the #display element (each string must be unique).

However, my project does working just fine at least from user’s perspective. It plays a sound when specific keyboard keys is pressed and it displays the name of the sound on the screen. I’m not quite sure what is causing these two tests to fail.

Could you take a look at my code and see what’s missing? Thanks.

Your code so far

HTML


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
</head>
<body>

    <div id="drum-machine">
      <div id='display'></div>
      <span id='q' class="drum-pad"><audio id='Q' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3'></audio>Q</span>
      <span id='w' class="drum-pad"><audio id='W' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3'></audio>W</span>
      <span id='e' class="drum-pad"><audio id='E' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3'></audio>E</span>
      <span id='a' class="drum-pad"><audio id='A' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3'></audio>A</span>
      <span id='s' class="drum-pad"><audio id='S' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3'></audio>S</span>
      <span id='d' class="drum-pad"><audio id='D' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3'></audio>D</span>
      <span id='z' class="drum-pad"><audio id='Z' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3'></audio>Z</span>
      <span id='x' class="drum-pad"><audio id='X' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3'></audio>X</span>
      <span id='c' class="drum-pad"><audio id='C' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3'></audio>C</span>
    </div>
  
    <script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
</body>

JavaScript (jQuery)

// Highlight the key when a keyboard key is pressed
$(document).keypress(function(e) {
  var colors = String.fromCharCode(e.which);
  $('#'+ colors + '').addClass('yellow');
});

// Remove the highlighted key when a keyboard key is released
$(document).keyup(function() {
  $('.drum-pad').removeClass('yellow')
});

// play a sound if selected keys - Q,W,E,A,S,D,Z,X,C - are clicked
// Also, display the name of the sound when selected keys are clicked
$(document).keydown(function(event){
    if (event.keyCode == 81) { 
       $('#Q').get(0).play();
       $('#display').html('Heater 1')
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 87) { 
       $('#W').get(0).play();
       $('#display').html('Heater 2');
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 69) { 
       $('#E').get(0).play();
       $('#display').html('Heater 3');
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 65) { 
       $('#A').get(0).play();
       $('#display').html('Heater 4');
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 83) { 
       $('#S').get(0).play();
       $('#display').html('Clap');
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 68) { 
       $('#D').get(0).play();
       $('#display').html('Open HH');
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 90) { 
       $('#Z').get(0).play();
       $('#display').html("Kick n' Hat");
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 88) { 
       $('#X').get(0).play();
       $('#display').html('Kick');
    }
});

$(document).keydown(function(event){
    if (event.keyCode == 67) { 
       $('#C').get(0).play();
       $('#display').html('Closed HH');
    }
});

CSS

.yellow { 
  background-color: #ffc400;
}

#display {
  margin-bottom: 100px;
  border-style: solid;
  font-size: 24px;
  text-align: center;
  padding: 12px;
  font-weight: bold;
  font-family: sans-serif;
}

span {
  font-weight: bold;
  font-family: sans-serif;
  text-decoration: none;
  background-color: #EEEEEE;
  color: #333333;
  padding: 20px;
  margin: 100px 5px 0px 0px;
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36.

Challenge: Build a Drum Machine

Link to the challenge:

Hey there,

great work so far! :clap:

You can have a look at the tests and how they work:

Because debugging is a very valuable skill to learn, try to understand the tests on your own and let us know if you need some help.

1 Like

I did read the error messages and unfortunately I have no clue why it is failing. According to the Test 5 error message, it says:

The <audio> element with id=“Q” on does not play when the Q .drum-pad is clicked*

The problem is it does play the audio when “Q” key is clicked. The audio element has an id “Q” on it and I have connected the audio to the corresponding “.drum-pad” keys. Otherwise, test 6 would have failed too.

Next is this one from Test 7:

Each time a drum pad is triggered, a unique string should be displayed in the element with the id “display”

This one has left me scratching on my head. It definitely displays the name of the sound on the display element when the drum pad is triggered. All the strings are unique as well. So I’m completely lost on this one.

The only thing I understand is I have structured my code in a way that FCC tests is unable to read the code and so it is probably treating as if it hasn’t existed in the first place.

P.S: I have looked at the test code you posted earlier and it appears it is trying to detect for certain keywords: “.drum-pad” and “.clip” . It did detected these two words for test 3 and 4, but for some reason it cannot do the same for test 6. Again, I have no idea why it is not passing.

Great work so far!

As you can see, a lot of tests work with audioElements,
defined as

const audioElements = document.querySelectorAll('.drum-pad .clip');

So we are searching for all elements that have a class = "drum-pad clip".

Your elements look like this:

<span id='q' class="drum-pad">
  <audio id='Q' class='clip' src='...'></audio>
  Q
</span>

So the test code can’t find them, because the classes drum-pad and clip live in two different HTML elements.


There are also some tests that work with drumPads defined like this:

const drumPads = document.querySelectorAll('.drum-pad');

My idea is to step into each test from top to bottom and have a look what it uses (e.g. drumPads or audioElements) and fix it.

1 Like

All right. So the problem might be how I’ve structured HTML codes and the way I placed the class and id names. I’m already exhausted from troubleshooting tests for hours so I’ll do it on the next day when I’m well rested.

Appreciated your help so far, miku!

Ok, I came back to do the challenge again after one week break and oh boy this is getting me to nowhere! Test 5 is one thing, but it’s Test 7 that is testing my patient. :tired_face:

I’ve reread the tests, changed the codes for HTML and jQuery and still I have the same problem. I’ve also read almost all the forums related to Drum Machine and it seems that many people were having similar problem. They all claim their app is working fine but the tests is failing. Because the majority of the app is created in React, I cannot find anything that is useful in my case.

Can someone kindly point me the mistakes and possibly provide hints?

CodePen: https://codepen.io/mohammedasker/pen/RwoMKEx?editors=0010

HTML


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
</head>
<body>

    <div id="drum-machine">
      <div id='display'>Drum Machine</div>
      <span class="drum-pad clip" id='heater-1'>Q<audio id='Q' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3'></audio></span>
      <span class="drum-pad clip" id='heater-2' >W<audio id='W' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3'></audio></span>
      <span class="drum-pad clip" id='heater-3'>E<audio id='E' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3'></audio></span>
      <span class="drum-pad clip" id='heater-4'>A<audio id='A' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3'></audio></span>
      <span class="drum-pad clip" id='clap'>S<audio id='S' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3'></audio></span>
      <span class="drum-pad clip" id='open-hh'>D<audio id='D' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3'></audio></span>
      <span class="drum-pad clip" id='kick-n-hat'>Z<audio id='Z' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3'></audio></span>
      <span class="drum-pad clip" id='kick'>X<audio id='X' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3'></audio></span>
      <span class="drum-pad clip" id='closed-hh'>C<audio id='C' class='clip' src='https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3'></audio></span>
    </div>
  
    <script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
</body>

JavaScript (jQuery)


$(document).keydown(function(event){
    if (event.which == 81 || event.which == 113) { 
      event.preventDefault();
       $('#Q').get(0).play();
       $('#display').text('Heater 1')
       $('#heater-1').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#heater-1").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
    if (event.which == 87 || event.which == 119) { 
      event.preventDefault();
       $('#W').get(0).play();
       $('#display').text('Heater 2');
      $('#heater-2').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#heater-2").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
    if (event.which == 69 || event.which == 101) { 
      event.preventDefault();
       $('#E').get(0).play();
       $('#display').text('Heater 3');
      $('#heater-3').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#heater-3").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
    if (event.which == 65 || event.which == 97) { 
      event.preventDefault();
       $('#A').get(0).play();
       $('#display').text('Heater 4');
      $('#heater-4').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#heater-4").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
  event.preventDefault();
    if (event.which == 83 || event.which == 115) { 
       $('#S').get(0).play();
       $('#display').text('Clap');
      $('#clap').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#clap").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
  event.preventDefault();
    if (event.which == 68 || event.which == 100) { 
       $('#D').get(0).play();
       $('#display').text('Open HH');
      $('#open-hh').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#open-hh").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
  event.preventDefault();
    if (event.which == 90 || event.which == 122) { 
       $('#Z').get(0).play();
       $('#display').text("Kick n' Hat");
      $('#kick-n-hat').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#kick-n-hat").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
  event.preventDefault();
    if (event.which == 88 || event.which == 120) { 
       $('#X').get(0).play();
       $('#display').text('Kick');
      $('#kick').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#kick").css('background', '');
    }, 150);
    }
});

$(document).keydown(function(event){
  event.preventDefault();
    if (event.which == 67 || event.which == 99) { 
       $('#C').get(0).play();
       $('#display').text('Closed HH');
      $('#closed-hh').css('background-color', '#ffc400')
      setTimeout(function(){
      $("#closed-hh").css('background', '');
    }, 150);
    }
});
  1. When I click on a .drum-pad element, the audio clip contained in its child <audio> element should be triggered

Your handlers are for keys only , not for mouseclicks

For handling multiple buttons events with query/js your best bet is event delegation or with js, well explained

Think test #7 is failing for the same reason

1 Like

Your handlers are for keys only , not for mouseclicks

Will you mind elaborating on this part? I’m using keydown to play the sound when clicked a keyboard and no sounds will play via mouse. Did you mean that my handlers will check for mouseclicks?

To make sure we are on the same page: Your current app is listening(=expecting) keydown events on document (you click with mouse, a key can be pressed , and you are using keyboard event .keydown())
i think that you should set handler/handlers for mouse event click too , say mouseup on buttons (which are <span></span> in your code), so that when you click on them they’d start playing sounds and show descriprion on display, because user story says #5 when i click…, and #4 when i press, which is working now.
If you’ll try to add click event to document , remember about event bubbling

Hope this makes sense

keyboard events jquery
mouse events jquery

1 Like

OK, I’m happy to report that my app has passed all the tests!

The reason why the tests was failing is because the app plays the sound when the keyboard is pressed but not when the mouse is clicked. Since the test is also looking for events when the mouse is clicked and it wasn’t able to do so, therefore the tests has failed.

So the solution is to replace the span elements with button to make them clickable and then I have to make sure the sound is playing when the keyboard AND mouse is clicked.

My code ended up being huge and messy but since it’s working that’s the most important thing. Thank you @Annestezia and @miku86 for your help. I really appreciate it.

1 Like

Hey Mohammed,
happy that you managed to find a solution on your own. :clap:

1 Like