In JavaScript, an array is an ordered list of values you access by position (users[0]), and an object is a set of named properties you access by key (user.email). Test code uses both constantly: arrays for lists of test data, objects for a single record or config. Working with a list of records, like users returned by an API? See Array of Objects in JavaScript.

What is an Array?

An array is a data structure used to store multiple values in a single variable.

In automation projects, arrays are commonly used to handle collections of test data, such as usernames, URLs, or expected values. They help reduce duplicate code and make test scripts clean and readable.

Where and Why Used in a Project

In real-time automation, arrays are used when we have fixed-size test data that needs to be iterated using loops.

Real-time Example

In our login automation, I used an array to store multiple invalid passwords and looped through them to validate error messages in a single test.


Advertisement

How to Declare an Array

An array in JavaScript/TypeScript is declared using square brackets ([]) or the Array constructor.

Square brackets are preferred because they are simpler and more readable.

Arrays store multiple related values in one variable.

In automation projects, arrays are frequently used to:

  • Store multiple locators

  • Handle test data

  • Loop through multiple test scenarios

TypeScript also allows type-safe arrays, which help avoid runtime errors.

Playwright JavaScript

const urls = ["https://qa.site.com", "https://stage.site.com"];

Playwright TypeScript

const urls: string[] = ["https://qa.site.com", "https://stage.site.com"];

Quick Summary

Arrays:

  • Store multiple values in one variable.

  • Are declared using [] or Array().

  • Use [] as the most common approach.

  • Are very useful for test data and looping in Playwright tests.


Finding the Length of an Array

In JavaScript, we find the length of an array using the .length property, which returns the total number of elements.

It is a property, not a method, so we don't use parentheses.

In Playwright automation, .length is commonly used to:

  • Validate the number of elements on a page.

  • Control loops for test execution.

  • Assert test data count.

This helps write dynamic, reliable tests instead of hard-coded values.

const menuItems = await page.$$(".menu-item");

if (menuItems.length > 0) {
  console.log("Menu items are loaded");
}

Better in Playwright tests: page.$$() reads the page once — if the menu is still loading, length is 0. To assert a count, use a locator with a web-first assertion that waits: await expect(page.locator('.menu-item')).toHaveCount(5);. Keep .length for arrays you already have, such as test data.


map vs forEach

  • forEach executes a function on each array element without returning a new array.

  • map executes a function and returns a new array with transformed values.

forEach

Iterates over array elements and performs an action for each.

Used when you want to perform actions and don't need a return value.

map

Iterates over array elements and returns a new array.

Useful when you want to transform data (e.g., for assertions).

Real-life Example

  • forEach → checking each item in a shopping list.

  • map → creating a new list of prices after applying a discount.

Real-time Testing Example

  • forEach → performing login with multiple usernames stored in an array.

  • map → modifying an array of test URLs to add query parameters before use.


What is an Object?

An object in JavaScript is a collection of key-value pairs used to store data in a structured format using keys (properties) and values.

const obj = {
  key1: value1,
  key2: value2,
  key3: value3
};

In automation, objects let you:

  • Pass structured data to functions or page objects.

  • Dynamically access or update values during tests.

This makes tests cleaner, more readable, and more maintainable.

Real-time Example

In my Playwright project, I stored multiple user credentials as objects for use across login tests.


How to Create an Object

In JavaScript, objects can be created in two main ways.

Using {}.

Preferred because it is simpler, cleaner, and more readable.

Object Constructor

Using new Object().

Objects store related data as key-value pairs for easy access.

In Playwright, objects are commonly used for:

  • Test data

  • Configuration

  • Passing objects to functions

  • Passing objects to page objects

  • Supporting modular code

  • Using them in loops to perform actions on different objects


Array vs Object

An array stores data as an ordered list of elements, while an object stores data as key-value pairs.

Arrays are used for lists; objects are used for structured data.

Feature Array Object
Data storage Ordered elements Key-value pairs
Indexing Numeric indexes Keys (strings or symbols)
Best for Lists of values Structured/related data

Accessing Object Properties

Object properties in JavaScript can be accessed using:

  • Dot notation (object.key)

  • Bracket notation (object["key"])

Dot Notation

Easy and readable.

Used when the property name is known and fixed.

Bracket Notation

Useful when property names are dynamic or stored in variables.

In Playwright, this is used to:

  • Access usernames and passwords stored in objects for login tests.

  • Fetch configuration values for dynamic environment handling.

  • Update values before performing actions on UI elements.


Destructuring

Destructuring in JavaScript allows you to extract values from arrays or objects into individual variables using a clean, readable syntax.

const { username, password } = user;    // object destructuring

const [qaUrl, stageUrl] = urls;         // array destructuring

In automation, destructuring lets you:

  • Access multiple properties of an object (e.g., login credentials) in one line.

  • Extract multiple values from arrays (e.g., URLs or test data).

In my Playwright project, I destructured the username and password from a user object for login tests.


Looping Through Object Properties

You can loop through object properties using:

  • for...in

  • Object.keys()

  • Object.values()

  • Object.entries()

for...in Loop

Loops over all enumerable keys of an object.

Object.keys() with forEach

Loops over all keys.

Object.keys(user).forEach(key => console.log(key, user[key]));

Object.values() with forEach

Loops over all values.

Object.values(user).forEach(value => console.log(value));

Object.entries() with forEach

Loops over key-value pairs.

Object.entries(user).forEach(([key, value]) => console.log(key, value));

In my Playwright project, I used Object.entries() to loop through test data dynamically, accessing both keys and values.


Try It: Array and Object Traps Seen in Test Code

Save as arrays.mjs and run node arrays.mjs. We ran it on Node 22:

// 1. sort() compares as strings by default
const timings = [120, 9, 45, 1000];
console.log('sort()            :', [...timings].sort());
console.log('sort((a,b)=>a-b)  :', [...timings].sort((a, b) => a - b));

// 2. map returns a new array; forEach returns undefined
const names = ['asha', 'ravi'];
console.log('map     →', names.map(n => n.toUpperCase()), '| forEach →', names.forEach(n => n.toUpperCase()));

// 3. Spread is a SHALLOW copy — nested test data is still shared
const baseUser = { name: 'qa_user', address: { city: 'Pune' } };
const copy = { ...baseUser };
copy.name = 'qa_user_2';
copy.address.city = 'Chennai';                    // changes baseUser too!
console.log('after shallow copy:', baseUser.name, '/', baseUser.address.city);
const deep = structuredClone(baseUser);
deep.address.city = 'Delhi';
console.log('after deep copy   :', baseUser.address.city);

// 4. filter / find / some / every on test results
const results = [
  { test: 'login', status: 'passed', ms: 900 },
  { test: 'search', status: 'failed', ms: 1500 },
  { test: 'cart', status: 'passed', ms: 4200 },
];
console.log('failed tests:', results.filter(r => r.status === 'failed').map(r => r.test));
console.log('first slow test:', results.find(r => r.ms > 3000)?.test);
console.log('any failure?', results.some(r => r.status === 'failed'), '| all under 5s?', results.every(r => r.ms < 5000));
const byStatus = results.reduce((acc, r) => ({ ...acc, [r.status]: (acc[r.status] ?? 0) + 1 }), {});
console.log('count by status:', byStatus);

// 5. new Array(3) creates empty slots, not [3]
console.log('new Array(3):', new Array(3), '| Array.of(3):', Array.of(3));

Output:

sort()            : [ 1000, 120, 45, 9 ]
sort((a,b)=>a-b)  : [ 9, 45, 120, 1000 ]
map     → [ 'ASHA', 'RAVI' ] | forEach → undefined
after shallow copy: qa_user / Chennai
after deep copy   : Chennai
failed tests: [ 'search' ]
first slow test: cart
any failure? true | all under 5s? true
count by status: { passed: 2, failed: 1 }
new Array(3): [ <3 empty items> ] | Array.of(3): [ 3 ]
  • sort() without a comparator sorts numbers as text — 1000 came before 9. Asserting that response times or prices are sorted with a plain sort() gives wrong expectations.
  • Spread ({ ...obj }) is a shallow copy. Changing the copy's nested address.city changed the original too — a classic cause of tests that pass alone and fail when run together, because one test modified shared test data. structuredClone() makes a real deep copy (the "after deep copy" line shows the original kept its value from before).
  • filter, find, some, every and reduce turn a results array into exactly the check you need, without manual loops.

Coming from Java? Java arrays have a fixed size and one type, while JavaScript arrays grow and can mix types; list.stream().filter(...) in Java is the equivalent of array.filter(...). Step through the Java version of array and object handling in the Java Code Visualizer to see how the two languages differ. Related: Loops & Conditions.

From Real Projects

My automation background is Java with Selenium and TestNG. JavaScript comes up more and more for testers because tools like Playwright and Cypress are built on it — and most concepts on this page have a direct Java equivalent. Learning it alongside Java makes switching between frameworks much easier. Spread creates a shallow copy — nested test data is still shared.


📚 Official documentation: MDN: JavaScript Guide · dev.java: Learn Java (Oracle)

JavaScript Array Methods Cheat Sheet

MethodWhat it doesChanges the original?
push(x) / pop()Add / remove at the endYes
unshift(x) / shift()Add / remove at the startYes
splice(i, n)Remove or insert items at a positionYes
slice(a, b)Copy part of the arrayNo
includes(x) / indexOf(x)Is it there? / where is it?No
find(fn) / findIndex(fn)First item (or index) that matchesNo
filter(fn)All items that matchNo
map(fn)Transform every item into a new arrayNo
reduce(fn, start)Combine items into one value (sum, count)No
some(fn) / every(fn)Does any / every item match?No
sort(fn)Sort the itemsYes (use toSorted() for a copy)
join(sep)Turn the array into a stringNo
const prices = [499, 1299, 299];
const total = prices.reduce((sum, p) => sum + p, 0);   // 2097
const sorted = [...prices].sort((a, b) => a - b);       // [299, 499, 1299], original untouched
const allPositive = prices.every(p => p > 0);           // true

Trap: sort() with no compare function sorts as text, so [10, 9, 1].sort() gives [1, 10, 9]. Always pass (a, b) => a - b for numbers.

FAQs

What is an array in JavaScript?

A data structure that stores multiple values in a single variable; in automation, it's used for collections of test data like usernames, URLs, or expected values.

How do you declare an array?

Using square brackets ([]) (preferred for readability) or the Array() constructor.

TypeScript also supports type-safe arrays like string[].

How do you find the length of an array?

With the .length property (not a method), which returns the total number of elements.

What is the difference between map and forEach?

  • forEach performs an action on each element and returns nothing.

  • map transforms each element and returns a new array.

What is an object in JavaScript?

A collection of key-value pairs used to store structured data via properties (keys) and values.

How do you access object properties?

Using:

  • Dot notation (object.key) for known property names.

  • Bracket notation (object["key"]) for dynamic ones.

What is destructuring?

A syntax to extract values from arrays or objects into individual variables in one line, commonly used for test data and credentials.

How do you loop through an object's properties?

Using:

  • for...in

  • Object.keys()

  • Object.values()

  • Object.entries() combined with forEach

What is the difference between an array and an object in JavaScript?

An array stores an ordered list accessed by numeric index; an object stores named properties accessed by key. Use an array for many items of the same kind and an object for one item with several fields.

How do you check if a value is an array in JavaScript?

Use Array.isArray(value). typeof returns "object" for arrays, so it can't tell them apart from plain objects.

Does sort() change the original array in JavaScript?

Yes, sort() sorts in place and returns the same array. To keep the original, sort a copy with [...arr].sort() or use arr.toSorted() in modern browsers and Node.js 20+.