⚡ 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.