I am trying to test a click event in app.spec.js using Jasmine with the code below and am getting an error that says the following. Any suggestions? I’m not sure how to refer to the element.
I have tried different methods to refer to the DOM. Do I need to create a mock of document? I am pretty new to creating these type of tests.
Error
When the +1 Player 1 button is pressed > should call incrementPlayerOneScore
TypeError: Cannot read properties of null (reading 'click')
TypeError: Cannot read properties of null (reading 'click')
at UserContext.<anonymous> (file:///C:/Users/charl/Documents/WebDev/PingPongScorekeeper/spec/app.spec.js:9:56)
at <Jasmine>
app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="app.css">
<title>Ping Pong Scorekeeper</title>
</head>
<body>
<h1>Ping Pong Scorekeeper</h1>
<div>
<span id="playerOneScore">0</span> to <span id="playerTwoScore">0</span>
</div>
<div>
<p>Use the buttons below to keep score.</p>
</div>
<div>
<label for="winningPointsSelect">Playing To:</label>
<select name="winningPoints" id="winningPointsSelect">
<option value="">--Please choose an option--</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
</div>
<div>
<button id="playerOnePointButton">+1 to Player 1</button>
<button id="playerTwoPointButton">+1 to Player 2</button>
<button id="resetButton">Reset</button>
</div>
<script type="text/javascript" src="src/pingPongGame.js"></script>
<script type="text/javascript" src="src/app.js"></script>
</body>
</html>
specRunner.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Jasmine Spec Runner v3.10.1</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-3.10.1/jasmine_favicon.png">
<link rel="stylesheet" href="lib/jasmine-3.10.1/jasmine.css">
<!-- include source files here... -->
<script src="src/app.js"></script>
<script src="src/pingPongGame.js"></script>
<script src="lib/jasmine-3.10.1/jasmine.js"></script>
<script src="lib/jasmine-3.10.1/jasmine-html.js"></script>
<script src="lib/jasmine-3.10.1/boot0.js"></script>
<!-- optional: include a file here that configures the Jasmine env -->
<script src="lib/jasmine-3.10.1/boot1.js"></script>
<!-- include spec files here... -->
<script src="spec/app.spec.js"></script>
<script src="spec/pingPongGame.spec.js"></script>
</head>
<body>
</body>
</html>
app.js
const newPingPongGame = new PingPongGame(10);
const resetButton = document.querySelector('#resetButton');
resetButton.addEventListener('click', function () {
newPingPongGame.isGameWon();
});
pingPongGame.js
class PingPongGame {
constructor(newWinningPoints) {
this._playerOneScore = 0;
this._playerTwoScore = 0;
this._isGameWon = false;
this._winningPoints = newWinningPoints;
}
get playerOneScore() {
return this._playerOneScore;
}
set playerOneScore(newPlayerOneScore) {
this._playerOneScore = newPlayerOneScore;
}
get playerTwoScore() {
return this._playerTwoScore;
}
set playerTwoScore(newPlayerTwoScore) {
this._playerTwoScore = newPlayerTwoScore;
}
get winningPoints() {
return this._winningPoints;
}
set winningPoints(newWinningPoints) {
this._winningPoints = newWinningPoints;
}
get isGameWon() {
return this._isGameWon;
}
set isGameWon(newIsGameWon) {
this._isGameWon = newIsGameWon;
}
incrementPlayerOneScore() {
this._playerOneScore++;
}
incrementPlayerTwoScore() {
this._playerTwoScore++;
}
resetGame() {
this._playerOneScore = 0;
this._playerTwoScore = 0;
this._winningPoints = 10;
this._isGameWon = false;
}
isGameWon() {
if (this._playerOneScore == this._winningPoints || this._playerTwoScore == this._winningPoints) {
this._isGameWon = true;
} else {
this._isGameWon = false;
}
return this._isGameWon;
}
}
app.spec.js
describe("When the +1 Player 1 button is pressed", function () {
it("should trigger a click event", function () {
document.querySelector("#playerOnePointButton").click();
expect("click").toHaveBeenTriggeredOn("#playerOnePointButton");
});
it("should call incrementPlayerOneScore", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerOneScore = 1;
document.querySelector("#playerOnePointButton").click();
let result = newPingPongGame._playerOneScore;
expect(result).toBe(2);
});
});
pingPongGame.spec.js
describe("When the pingPongGame constructor is called", function () {
it("should create a ping pong game with given arguments.", function () {
let newPingPongGame = new PingPongGame(10);
expect(newPingPongGame._winningPoints).toBe(10);
});
it("should set the value of playerOneScore to zero.", function () {
let newPingPongGame = new PingPongGame(10);
expect(newPingPongGame._playerOneScore).toBe(0);
});
it("should set the value of playerTwoScore to zero.", function () {
let newPingPongGame = new PingPongGame(10);
expect(newPingPongGame._playerTwoScore).toBe(0);
});
});
describe("When the getter method for playerOneScore is called", function () {
it("should return the value of playerOneScore.", function () {
let newPingPongGame = new PingPongGame(10);
let testValue = newPingPongGame._playerOneScore;
expect(testValue).toBe(0);
});
})
describe("When the setter method for playerOneScore is called", function () {
it("should set the value of playerOneScore.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerOneScore = 1;
expect(newPingPongGame._playerOneScore).toBe(1);
});
});
describe("When the getter method for playerTwoScore is called", function () {
it("should return the value of playerTwoScore.", function () {
let newPingPongGame = new PingPongGame(10);
let testValue = newPingPongGame._playerTwoScore;
expect(testValue).toBe(0);
});
})
describe("When the setter method for playerTwoScore is called", function () {
it("should set the value of playerTwoScore.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerTwoScore = 1;
expect(newPingPongGame._playerTwoScore).toBe(1);
});
});
describe("When the getter method for winningPoints is called", function () {
it("should return the value of winningPoints.", function () {
let newPingPongGame = new PingPongGame(11);
let testValue = newPingPongGame._winningPoints;
expect(testValue).toBe(11);
});
})
describe("When the setter method for winningPoints is called", function () {
it("should set the value of winningPoints.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._winningPoints = 5;
expect(newPingPongGame._winningPoints).toBe(5);
});
});
describe("When incrementPlayerOneScore is called", function () {
it("should increment playerOneScore by one.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame.incrementPlayerOneScore();
expect(newPingPongGame.playerOneScore).toBe(1);
});
});
describe("When incrementPlayerTwoScore is called", function () {
it("should increment playerTwoScore by one.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame.incrementPlayerTwoScore();
expect(newPingPongGame.playerTwoScore).toBe(1);
});
});
describe("When resetGame is called", function () {
it("should set the value of playerOneScore to zero.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame.incrementPlayerOneScore();
newPingPongGame.resetGame();
expect(newPingPongGame.playerOneScore).toBe(0);
});
it("should set the value of playerTwoScore to zero.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame.incrementPlayerTwoScore();
newPingPongGame.resetGame();
expect(newPingPongGame.playerTwoScore).toBe(0);
});
it("should create set winning points to ten.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._winningPoints = 12;
newPingPongGame.resetGame();
expect(newPingPongGame._winningPoints).toBe(10);
});
it("should set isGameWon to false", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._isGameWon = true;
newPingPongGame.resetGame();
expect(newPingPongGame._isGameWon).toBe(false);
});
});
describe("When isGameWon is called", function () {
it("should return true if the game is won by player one.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerOneScore = 10;
let isGameWon = newPingPongGame.isGameWon();
expect(isGameWon).toBe(true);
});
it("should return true if the game is won by player two.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerTwoScore = 10;
let isGameWon = newPingPongGame.isGameWon();
expect(isGameWon).toBe(true);
});
it("should return false if the game is not won by player one.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerOneScore = 8;
let isGameWon = newPingPongGame.isGameWon();
expect(isGameWon).toBe(false);
});
it("should return false if the game is not won by player two.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerTwoScore = 8;
let isGameWon = newPingPongGame.isGameWon();
expect(isGameWon).toBe(false);
});
it("should set the isGameWon value to true if the game is won.", function () {
let newPingPongGame = new PingPongGame(10);
newPingPongGame._playerOneScore = 10;
newPingPongGame.isGameWon();
let isGameWon = newPingPongGame._isGameWon;
expect(isGameWon).toBe(true);
});
});