⚡ JavaScript: Who Changes the DOM

JavaScript: Who Changes the DOM: JavaScript is the electrical and automation system of the building: it is the power that makes the page LIVE afterward, makes something happen wh

JavaScript is the electrical and automation system of the building: it is the power that makes the page LIVE afterward, makes something happen when a button is pressed, and produces new BugCards when data arrives from the server. Why is JS the layer that concerns a tester most? Because it is what changes the DOM — an element is absent for a moment, then appears when a fetch completes; this is why you need to "wait for the element" and why `sleep` is the wrong answer. Java analogy: the DOM is built synchronously on the main thread, but a fetch returns asynchronously — like trying to read a CompletableFuture's result without waiting for it. In QA context: the root of locate-timing problems is JS asynchrony; the right reflex is not to sleep a fixed time but to conditionally wait for the element's presence/visibility.

🧱 D1. DOM Manipulation: createElement, appendChild, innerHTML

JS changing the DOM is like a CONSTRUCTION WORKER adding a room to a building AFTERWARD: `document.createElement('li')` prepares a new "brick" but it is NOT attached anywhere yet — it only sits in a JS variable; `appendChild` REALLY adds this brick to the wall (the DOM tree). So why is `createElement`+`appendChild` sometimes preferred over `element.innerHTML = htmlString`? Because `innerHTML` COMPLETELY destroys and rebuilds the existing subtree from scratch — event listeners and DOM references bound to it become SILENTLY invalid (a sneaky bug source). Java analogy: like the difference between creating a nesne with `new Foo()` (createElement) and adding it to a collection with `list.add(foo)` (appendChild) — existing and being a PART of the system are different steps. In QA context: if `createElement` was called but `appendChild` has not run yet, trying to locate that element ALWAYS fails — this is the foundation of the timing lesson in D3.

Step by Step: The Gap Between `createElement` and `appendChild`

`document.createElement('li')`

A NEW node is created in memory, but this node is NOT attached anywhere — it is not part of the DOM tree.

If you tried to locate it at this moment...

`document.querySelector('li')` can NEVER find this new node — it only sits in a JS VARIABLE, not in the tree.

`parent.appendChild(newLi)`

The node is now REALLY added to the DOM tree — until this line ran, the node "existed but was invisible".

Now it can be located

AFTER `appendChild` runs, a `querySelector`/Playwright locator can find this element.

`innerHTML` carries a different risk

`innerHTML = htmlString` COMPLETELY destroys and rebuilds the existing subtree — old event listeners and locator references become SILENTLY invalid.