{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/testing-using-jest-and-puppeteer-javascript/",
    "result": {"data":{"site":{"siteMetadata":{"title":"CrewCode Solutions"}},"markdownRemark":{"id":"e0ea46b7-1202-5ffc-88c2-6e2236f40254","excerpt":"In this article i will explain you about testing using jest and puppeteer which you can either do in your nodejs application Kinds of testing Unit Test…","html":"<p>In this article i will explain you about testing using jest and puppeteer which you can either do in your nodejs application</p>\n<p><strong><em>Kinds of testing</em></strong></p>\n<ul>\n<li>\n<p>Unit Test</p>\n</li>\n<li>\n<p>Integration Test</p>\n</li>\n<li>\n<p>End-to-End Testing</p>\n</li>\n</ul>\n<p>We will be looking on to the above testing with an example step by step using jest and puppeteer in this article</p>\n<p><strong><em>Testing tools we needed for testing</em></strong></p>\n<ul>\n<li>\n<p>Test Runner: Execute your tests, summarize results eg Mocha, Jest</p>\n</li>\n<li>\n<p>Assetion Library: Define testing logic, conditions eg Chai, Jest</p>\n</li>\n<li>\n<p>Headless Browser: Simulates browser interaction, automated testing eg Puppeteer we will be using automated testing for end to end testing</p>\n</li>\n</ul>\n<h4>Step1: Setup a node.js project</h4>\n<ul>\n<li>\n<p>We will be setting up a node.js project and we will be adding <strong><em>index.html file</em></strong> and <strong><em>app.js file</em></strong> and <strong><em>styles.css</em></strong> and <strong><em>util.js</em></strong> to our root path</p>\n</li>\n<li>\n<p>This command will help you in initializing your nodejs project</p>\n</li>\n</ul>\n<pre><code class=\"language-js\">npm init\n</code></pre>\n<ul>\n<li>Add below code to your app.js file</li>\n</ul>\n<pre><code class=\"language-js\">const { checkAndGenerate, createElement } = require(\"./util\");\n\nconst initApp = () => {\n  // Initializes the app, registers the button click listener\n  const newUserButton = document.querySelector(\"#btnAddUser\");\n  newUserButton.addEventListener(\"click\", addUser);\n};\n\nconst addUser = () => {\n  // Fetches the user input, creates a new HTML element based on it\n  // and appends the element to the DOM\n  const newUserNameInput = document.querySelector(\"input#name\");\n  const newUserAgeInput = document.querySelector(\"input#age\");\n\n  const outputText = checkAndGenerate(\n    newUserNameInput.value,\n    newUserAgeInput.value\n  );\n\n  if (!outputText) {\n    return;\n  }\n\n  const userList = document.querySelector(\".user-list\");\n\n  const element = createElement(\"li\", outputText, \"user-item\");\n  userList.appendChild(element);\n};\n\n// Start the app!\ninitApp();\n</code></pre>\n<ul>\n<li>Add below code to your util.js file</li>\n</ul>\n<pre><code class=\"language-js\">const generateText = (name, age) => {\n  // Returns output text\n  return `${name} (${age} years old)`;\n};\n\nexports.createElement = (type, text, className) => {\n  // Creates a new HTML element and returns it\n  const newElement = document.createElement(type);\n  newElement.classList.add(className);\n  newElement.textContent = text;\n  return newElement;\n};\n\nconst validateInput = (text, notEmpty, isNumber) => {\n  // Validate user input with two pre-defined rules\n  if (!text) {\n    return false;\n  }\n  if (notEmpty &#x26;&#x26; text.trim().length === 0) {\n    return false;\n  }\n  if (isNumber &#x26;&#x26; +text === NaN) {\n    return false;\n  }\n  return true;\n};\n\nexports.checkAndGenerate = (name, age) => {\n  if (!validateInput(name, true, false) || !validateInput(age, false, true)) {\n    return false;\n  }\n  return generateText(name, age);\n};\n\nexports.generateText = generateText;\nexports.validateInput = validateInput;\n</code></pre>\n<ul>\n<li>Add below code to your styles.css file</li>\n</ul>\n<pre><code class=\"language-css\">body {\n  font-family: sans-serif;\n}\n\n.control-panel {\n  width: 25rem;\n}\n\n.input-container {\n  margin: 1rem;\n}\n\n.input-container label,\n.input-container input {\n  display: block;\n  width: 100%;\n}\n\n.input-container input {\n  font: inherit;\n}\n\n.button {\n  font: inherit;\n  background: #521751;\n  color: white;\n  border: 1px solid #521751;\n  padding: 0.5rem 1rem;\n  border-radius: 3px;\n  margin: 0 1rem;\n}\n\n.user-list {\n  display: flex;\n  flex-direction: column;\n  list-style: none;\n  margin: 1rem;\n  padding: 0;\n}\n\n.user-item {\n  margin-bottom: 1rem;\n  padding: 1rem;\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);\n  width: 20rem;\n}\n</code></pre>\n<p>Add below code to your index.html file</p>\n<pre><code class=\"language-html\">&#x3C;!DOCTYPE html>\n&#x3C;html lang=\"en\">\n  &#x3C;head>\n    &#x3C;meta charset=\"UTF-8\" />\n    &#x3C;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    &#x3C;meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n    &#x3C;link rel=\"stylesheet\" href=\"styles.css\" />\n    &#x3C;title>JS Testing&#x3C;/title>\n  &#x3C;/head>\n\n  &#x3C;body>\n    &#x3C;section class=\"control-panel\">\n      &#x3C;div class=\"input-container\">\n        &#x3C;label for=\"name\">Name&#x3C;/label>\n        &#x3C;input type=\"text\" id=\"name\" />\n      &#x3C;/div>\n      &#x3C;div class=\"input-container\">\n        &#x3C;label for=\"age\">Age&#x3C;/label>\n        &#x3C;input type=\"number\" id=\"age\" />\n      &#x3C;/div>\n      &#x3C;button id=\"btnAddUser\" class=\"button\">Add User&#x3C;/button>\n    &#x3C;/section>\n    &#x3C;hr />\n    &#x3C;section class=\"user-output\">\n      &#x3C;ul class=\"user-list\">&#x3C;/ul>\n    &#x3C;/section>\n    &#x3C;script src=\"dist/main.js\">&#x3C;/script>\n  &#x3C;/body>\n&#x3C;/html>\n</code></pre>\n<h4>Step2: Install webpack and webpack dev server</h4>\n<ul>\n<li>Use below command to install webpack and modify your package.json file to serve your application with webpack</li>\n</ul>\n<pre><code class=\"language-js\">//run this command where you have created your project\nnpm install --save-dev webpack webpack-cli\n</code></pre>\n<pre><code class=\"language-js\">//modify the package.json file and add these script\n\"scripts\": {\n    \"start\": \"webpack app.js --mode development --watch\",\n    \"test\": \"echo \\\"Error: no test specified\\\" &#x26;&#x26; exit 1\"\n  },\n</code></pre>\n<ul>\n<li>Use below command to install jest</li>\n</ul>\n<pre><code class=\"language-js\">npm install --save-dev jest\n</code></pre>\n<h4>Step 3: Writing and Running Unit Test</h4>\n<ul>\n<li>\n<p>Create a separate file same as file which you are testing for example iam gonna test a function inside util.js file then i will create a file with the name <strong><em>util.test.js</em></strong></p>\n</li>\n<li>\n<p>We will be testing generatedText function inside util.js file</p>\n</li>\n</ul>\n<p>Inside util.test.js file update the following code</p>\n<pre><code class=\"language-js\">const { generateText } = require(\"./util\");\ntest(\"should output name and age\", () => {\n  const text = generateText(\"Abc\", 29);\n  expect(text).toBe(\"Abc (29 years old)\");\n});\n</code></pre>\n<ul>\n<li>\n<p>In above code we are testing generateText function and we have given the name of test to be \"should output name and age\"\nand we are calling the function inside test function and expecting the result to be \"Max (29 years old)\"</p>\n</li>\n<li>\n<p>Modify the package.json file and add the script for jest testing</p>\n</li>\n</ul>\n<pre><code class=\"language-js\">//modify the package.json file and add these script\n\"scripts\": {\n    \"start\": \"webpack app.js --mode development --watch\",\n    \"test\": \"jest --watch\"\n  },\n</code></pre>\n<ul>\n<li>Run the command and it will start the test and it will keep running and look for the change and test accordingly</li>\n</ul>\n<pre><code class=\"language-js\">npm run test\n</code></pre>\n<h4>Step 4: Writing and Running Integration Test</h4>\n<ul>\n<li>In our integration testing we are considering unit test as well now we have a function named checkAndGenerate inside util.js file which is calling validateinput and generateText function which were part of our unit test</li>\n</ul>\n<p>Add the below code to your util.test.js file and run command <strong><em>npm run test</em></strong> to test using jest</p>\n<pre><code class=\"language-js\">const { generateText } = require(\"./util\");\ntest(\"should output name and age\", () => {\n  const text = generateText(\"Abc\", 29);\n  expect(text).toBe(\"Abc (29 years old)\");\n});\n\ntest(\"should generate a valid text output\", () => {\n  const text = checkAndGenerate(\"Abc\", 29);\n  expect(text).toBe(\"Abc (29 years old)\");\n});\n</code></pre>\n<h4>Step 5: Writing and running end to end test or user interface test using puppeteer</h4>\n<ul>\n<li>Install puppeteer using below command</li>\n</ul>\n<pre><code class=\"language-js\">npm install --save-dev puppeteer\n</code></pre>\n<p>Once done just add another test case inside util.test.js file</p>\n<pre><code class=\"language-js\">const puppeteer = require(\"puppeteer\");\nconst { generateText, checkAndGenerate } = require(\"./util\");\n\ntest(\"should output name and age\", () => {\n  const text = generateText(\"Abc\", 29);\n  expect(text).toBe(\"Abc (29 years old)\");\n});\n\ntest(\"should generate a valid text output\", () => {\n  const text = checkAndGenerate(\"Abc\", 29);\n  expect(text).toBe(\"Abc (29 years old)\");\n});\n\ntest(\"should create an element with text and correct class\", async () => {\n  const browser = await puppeteer.launch({\n    headless: true,\n  });\n  const page = await browser.newPage();\n  await page.goto(\"file path for your index.html file\");\n  await page.click(\"input#name\");\n  await page.type(\"input#name\", \"Anna\");\n  await page.click(\"input#age\");\n  await page.type(\"input#age\", \"28\");\n  await page.click(\"#btnAddUser\");\n  const finalText = await page.$eval(\".user-item\", (el) => el.textContent);\n  expect(finalText).toBe(\"Def (28 years old)\");\n}, 10000);\n</code></pre>\n<ul>\n<li>In the above test case we are creating a browser using this code</li>\n</ul>\n<pre><code class=\"language-js\">const browser = await puppeteer.launch({\n  headless: true,\n});\n</code></pre>\n<ul>\n<li>Once browser is created we are navigating to the page that has to be displayed in the browser created by puppeteer</li>\n</ul>\n<pre><code class=\"language-js\">const page = await browser.newPage();\nawait page.goto(\"file path for your index.html file\");\n</code></pre>\n<ul>\n<li>Once page is rendered we are clicking on the input text and filling up those input text and finally click on submit button</li>\n</ul>\n<pre><code class=\"language-js\">await page.goto(\"file path for your index.html file\");\nawait page.click(\"input#name\");\nawait page.type(\"input#name\", \"Anna\");\nawait page.click(\"input#age\");\nawait page.type(\"input#age\", \"28\");\nawait page.click(\"#btnAddUser\");\n</code></pre>\n<ul>\n<li>Once we have inputed and click on submit button we are fetching the final result and testing against our expected value</li>\n</ul>\n<pre><code class=\"language-js\">const finalText = await page.$eval(\".user-item\", (el) => el.textContent);\nexpect(finalText).toBe(\"Def (28 years old)\");\n</code></pre>","fields":{"slug":"/testing-using-jest-and-puppeteer-javascript/"},"frontmatter":{"title":"Testing using jest and puppeteer in nodejs","date":"June 01, 2023","description":"In this article i will explain you how you can test your functionality using jest and add automated testing using puppeteer","bannerimage":"https://crew-code-images.s3.us-east-1.amazonaws.com/blog_images/puppetter.jpeg"}},"previous":{"fields":{"slug":"/serverless-rest-api-using-python-and-awslambda/"},"frontmatter":{"title":"Serverless Rest API using python and AWS Lambda","date":"May 30, 2023","bannerimage":"https://crew-code-images.s3.us-east-1.amazonaws.com/blog_images/serverless.jpeg"}},"next":{"fields":{"slug":"/web-component-javascript/"},"frontmatter":{"title":"Creating web component in javascript","date":"June 11, 2023","bannerimage":"https://crew-code-images.s3.us-east-1.amazonaws.com/blog_images/web-component.jpeg"}}},"pageContext":{"id":"e0ea46b7-1202-5ffc-88c2-6e2236f40254","previousPostId":"0470c4dc-cb45-5794-a6fb-e5d124e324a3","nextPostId":"d4aefb01-f69c-5a6f-a0de-824fe424b563"}},
    "staticQueryHashes": ["3860684146"]}