Repository: capricorn86/happy-dom
Pull request #296 (2021-10-05 15:25:03)

#294@patch: Throws exception if referenceNode is not child of parent …
…node or if referenceNode is not sent.


Patch:
diff --git a/packages/happy-dom/src/nodes/node/Node.ts b/packages/happy-dom/src/nodes/node/Node.ts
index 480ac856..5635a711 100644
--- a/packages/happy-dom/src/nodes/node/Node.ts
+++ b/packages/happy-dom/src/nodes/node/Node.ts
@@ -336,7 +336,7 @@ export default class Node extends EventTarget implements INode {
 	 * @param [referenceNode] Node to insert before.
 	 * @returns Inserted node.
 	 */
-	public insertBefore(newNode: INode, referenceNode?: INode | null): INode {
+	public insertBefore(newNode: INode, referenceNode: INode | null): INode {
 		// If the type is DocumentFragment, then the child nodes of if it should be moved instead of the actual node.
 		// See: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment
 		if (newNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
@@ -351,8 +351,20 @@ export default class Node extends EventTarget implements INode {
 			return newNode;
 		}
 
-		let index = referenceNode ? this.childNodes.indexOf(referenceNode) : 0;
-		index = index === -1 ? 0 : index;
+		if (referenceNode === undefined) {
+			throw new DOMException(
+				"Failed to execute 'insertBefore' on 'Node': 2 arguments required, but only 1 present.",
+				'TypeError'
+			);
+		}
+
+		const index = referenceNode ? this.childNodes.indexOf(referenceNode) : 0;
+
+		if (index === -1) {
+			throw new DOMException(
+				"Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
+			);
+		}
 
 		if (newNode.parentNode) {
 			const index = newNode.parentNode.childNodes.indexOf(newNode);


Test patch:
diff --git a/packages/happy-dom/test/nodes/node/Node.test.ts b/packages/happy-dom/test/nodes/node/Node.test.ts
index bd412ddc..3b9ccb5f 100644
--- a/packages/happy-dom/test/nodes/node/Node.test.ts
+++ b/packages/happy-dom/test/nodes/node/Node.test.ts
@@ -428,7 +428,7 @@ describe('Node', () => {
 			);
 		});
 
-		it('Inserts a Node after all children if no reference given.', () => {
+		it('Inserts a Node after all children if reference node is "null".', () => {
 			const child1 = document.createElement('span');
 			const child2 = document.createElement('span');
 			const newNode = document.createElement('span');
@@ -447,6 +447,30 @@ describe('Node', () => {
 
 			expect(newNode.isConnected).toBe(true);
 		});
+
+		it('Throws an exception if reference node is node sent.', () => {
+			const child1 = document.createElement('span');
+			const child2 = document.createElement('span');
+			const newNode = document.createElement('span');
+			const parent = document.createElement('div');
+
+			parent.appendChild(child1);
+			parent.appendChild(child2);
+
+			expect(() => parent.insertBefore(newNode)).toThrow(
+				"Failed to execute 'insertBefore' on 'Node': 2 arguments required, but only 1 present."
+			);
+		});
+
+		it('Throws an exception if reference node is not child of parent node.', () => {
+			const referenceNode = document.createElement('span');
+			const newNode = document.createElement('span');
+			const parent = document.createElement('div');
+
+			expect(() => parent.insertBefore(newNode, referenceNode)).toThrow(
+				"Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
+			);
+		});
 	});
 
 	describe('replaceChild()', () => {