Why this matters on the job
Every Cypress test you will ever write is plain JavaScript running in Node.js and in the browser. In interviews at Indian service companies (TCS, Infosys, Wipro, Cognizant) and product companies alike, the first Cypress round almost always starts with JavaScript basics: "What is the difference between let and const?", "What does an arrow function return?", "Why can't you use async/await with Cypress commands?". Testers who switch from manual testing or from Selenium-Java often struggle not with Cypress itself but with JavaScript syntax. This lesson gives you exactly the JavaScript a tester needs — no more, no less — and sets up a clean Node.js workspace that you will reuse for the whole course.
On a real project you will receive a repository, run npm install, and be expected to add tests the same day. If you understand package.json, npm scripts, modules and array helpers, you will be productive from day one.
Concepts
The JavaScript a tester actually uses
| Feature | Example | Where you will use it in Cypress |
|---|---|---|
const / let | const url = '/inventory.html' | Test data, selectors, configuration values |
| Arrow functions | (a, b) => a - b | Every describe, it, .then() callback |
| Template literals | `Logged in as ${name}` | Dynamic selectors and URLs |
| Destructuring | const { status, body } = res | Reading API responses and fixtures |
| Spread | { ...user, zip: '' } | Building negative test data from a base object |
map / filter / reduce | prices.reduce((s, p) => s + p, 0) | Verifying sorting, totals, list contents |
| Modules | module.exports / export default | Page objects, helpers, config files |
| Promises / async-await | await fetch(url) | Node scripts and setupNodeEvents tasks — not inside Cypress command chains |
Node.js, npm and package.json
Node.js is the JavaScript runtime that runs Cypress, its config file and its plugins. npm installs packages listed in package.json into node_modules. Two sections matter most: devDependencies (tools like Cypress, reporters, Faker) and scripts (shortcuts such as npm run cy:run that your CI pipeline will call). Always commit package-lock.json so every teammate and the CI server install identical versions.
Tip: Use an LTS version of Node (20 or 22). Cypress 14 and later do not support Node versions older than 18, and CI images default to LTS, so matching it locally avoids "works on my machine" surprises.
Hands-on Lab: Set up Node.js and practise tester-grade JavaScript
- Install Node.js LTS. On macOS/Linux use nvm; on Windows use the installer from nodejs.org or nvm-windows. Then verify:
# macOS / Linux with nvm nvm install 22 nvm use 22 # verify (any OS) node -v # v22.x.x npm -v # 10.x.x - Create the course workspace that you will grow into a Cypress framework:
Open the folder in VS Code. Install the extensions ESLint and Prettier.mkdir cypress-qaji && cd cypress-qaji npm init -y git init echo "node_modules/" > .gitignore - Create
basics.jswith the code below. Every line is a pattern you will reuse in Cypress tests.
Run it with// basics.js — run with: node basics.js const users = [ { username: 'standard_user', locked: false }, { username: 'locked_out_user', locked: true }, { username: 'problem_user', locked: false }, ]; // 1. Arrow function + template literal const greet = (name) => `Logging in as ${name}`; console.log(greet(users[0].username)); // 2. Destructuring const { username, locked } = users[1]; console.log(username, 'locked?', locked); // 3. filter + map: which users can log in? const activeUsers = users.filter((u) => !u.locked).map((u) => u.username); console.log('Active:', activeUsers); // 4. reduce: cart total (what a checkout test verifies) const prices = [29.99, 9.99, 15.99, 49.99]; const total = prices.reduce((sum, p) => sum + p, 0); console.log('Cart total:', total.toFixed(2)); // 5. Sorting a COPY so the original stays untouched const sortedAsc = [...prices].sort((a, b) => a - b); console.log('Sorted:', sortedAsc, 'Original:', prices); // 6. Spread to derive negative test data from a valid object const buyer = { firstName: 'Asha', lastName: 'Rao', zip: '411001' }; const buyerWithoutZip = { ...buyer, zip: '' }; console.log(buyerWithoutZip); // 7. Promise + async/await (fine in Node scripts, NOT inside Cypress chains) const fakeApi = (ms) => new Promise((resolve) => setTimeout(() => resolve({ status: 200 }), ms)); (async () => { const res = await fakeApi(300); console.log('API status:', res.status); })();node basics.js. Expected output:Logging in as standard_user locked_out_user locked? true Active: [ 'standard_user', 'problem_user' ] Cart total: 105.96 Sorted: [ 9.99, 15.99, 29.99, 49.99 ] Original: [ 29.99, 9.99, 15.99, 49.99 ] { firstName: 'Asha', lastName: 'Rao', zip: '' } API status: 200 - Practise modules. Create
utils.jsand import it fromapp.js(CommonJS — the same stylecypress.config.jsuses):// utils.js const toNumber = (priceText) => Number(priceText.replace('$', '')); const isSortedAsc = (arr) => arr.every((v, i) => i === 0 || arr[i - 1] <= v); module.exports = { toNumber, isSortedAsc };// app.js — run with: node app.js const { toNumber, isSortedAsc } = require('./utils'); const uiPrices = ['$7.99', '$9.99', '$15.99', '$29.99']; const numbers = uiPrices.map(toNumber); console.log(numbers, 'sorted?', isSortedAsc(numbers)); // [ 7.99, 9.99, 15.99, 29.99 ] sorted? true - Call a real API from Node (Node 18+ has
fetchbuilt in). Save asfetch-demo.mjs— the.mjsextension enables ES modules and top-levelawait:// fetch-demo.mjs — run with: node fetch-demo.mjs const res = await fetch('https://jsonplaceholder.typicode.com/users/1'); const user = await res.json(); console.log(res.status, user.name, user.email); // Expected: 200 Leanne Graham Sincere@april.biz - Add npm scripts so commands are discoverable by anyone who clones the repo:
Opennpm pkg set scripts.basics="node basics.js" npm pkg set scripts.api="node fetch-demo.mjs" npm run basics npm run apipackage.jsonand confirm ascriptsblock now exists. Commit:git add . && git commit -m "chore: node workspace".
Why Cypress commands are not promises
Cypress commands such as cy.get() do not run immediately. They are queued and executed later, one after another, with automatic retries. That is why you never write const el = await cy.get('#id'). To use a value produced by Cypress, you chain .then() or use an alias. You will practise this in Lesson 3, but remember the rule now: plain JavaScript runs instantly, Cypress commands run later in a queue.
// WRONG — text is undefined because the command has not run yet
// const text = cy.get('.title').invoke('text');
// RIGHT — work with the yielded value inside .then()
cy.get('.title').invoke('text').then((text) => {
expect(text).to.equal('Products');
});
Common mistakes
- Using
var— it is function-scoped and leaks across blocks. Default toconst; useletonly when you reassign. - Calling
.sort()on the original array — it mutates it. Copy first with[...arr].sort(). - Sorting numbers without a comparator:
[10, 9, 100].sort()gives[10, 100, 9]because the default sort compares strings. - Mixing
requireandimportin the same file, or usingimportin a.jsfile run directly by Node without"type": "module". - Deleting
package-lock.jsonto "fix" install errors — it changes versions silently for the whole team.
Real-world assignment
Your lead shares this list of product prices scraped from a UI: ['$49.99', '$7.99', '$15.99', '$29.99', '$9.99', '$15.99']. Write price-check.js that (1) converts them to numbers, (2) prints the total rounded to 2 decimals, (3) prints the cheapest and most expensive item using Math.min/Math.max with spread, (4) prints how many duplicates exist using a Set, and (5) exits with code 1 (process.exit(1)) if the list is not sorted ascending. Add it as npm run price-check and push the repo to GitHub.
Key takeaways
- Cypress = JavaScript on Node.js; know
const/let, arrow functions, template literals, destructuring, spread and array helpers. - Use Node LTS, commit
package-lock.json, and expose every command through npm scripts. async/awaitis for Node scripts and plugin tasks; Cypress commands are queued and use.then().- Always copy before sorting and pass a numeric comparator.