import '../../src/index'; import { expect } from 'chai'; describe('Mutation observer tests', () => { function observerHelper() { const records: MutationRecord[] = []; const observer = new MutationObserver((rs) => { records.push(...rs); }); return { records, observer }; } it('new attribute', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); observer.observe(root, { attributes: true, attributeOldValue: true }); root.setAttribute('a', '1'); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('attributes'); expect(records[0].attributeName).to.eq('a'); }); it('attribute change', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); root.setAttribute('a', '1'); observer.observe(root, { attributes: true, attributeOldValue: true }); root.setAttribute('a', '2'); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('attributes'); expect(records[0].attributeName).to.eq('a'); expect(records[0].oldValue).to.eq('1'); }); it('attribute remove', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); root.setAttribute('a', '1'); observer.observe(root, { attributes: true, attributeOldValue: true }); root.removeAttribute('a'); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('attributes'); expect(records[0].attributeName).to.eq('a'); expect(records[0].oldValue).to.eq('1'); }); it('text change', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createTextNode('1'); root.appendChild(node); observer.observe(node, { characterData: true, characterDataOldValue: true }); node.data = '2'; await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('characterData'); expect(records[0].oldValue).to.eq('1'); }); it('text node add', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); observer.observe(root, { childList: true }); const node = root.ownerDocument!.createTextNode('1'); root.appendChild(node); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('childList'); expect(records[0].addedNodes).to.have.length(1); expect(records[0].addedNodes[0]).to.eq(node); }); it('element node add', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); observer.observe(root, { childList: true }); const node = root.ownerDocument!.createElement('div'); root.appendChild(node); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('childList'); expect(records[0].addedNodes).to.have.length(1); expect(records[0].addedNodes[0]).to.eq(node); }); it('attribute node add', async () => { // todo: don't know if it is the correct way to report Attr addition const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); observer.observe(root, { childList: true }); const node = root.ownerDocument!.createAttribute('div'); root.appendChild(node); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('childList'); expect(records[0].addedNodes).to.have.length(1); expect(records[0].addedNodes[0]).to.eq(node); }); it('element node remove', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createElement('div'); root.appendChild(node); observer.observe(root, { childList: true }); root.removeChild(node); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('childList'); expect(records[0].removedNodes).to.have.length(1); expect(records[0].removedNodes[0]).to.eq(node); }); it('element node insertBefore', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createElement('div'); root.appendChild(node); observer.observe(root, { childList: true }); const node2 = root.ownerDocument!.createElement('span'); root.insertBefore(node2, node); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('childList'); expect(records[0].addedNodes).to.have.length(1); expect(records[0].addedNodes[0]).to.eq(node2); }); it('element node replace', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createElement('div'); root.appendChild(node); observer.observe(root, { childList: true }); const node2 = root.ownerDocument!.createElement('span'); root.replaceChild(node2, node); await Promise.resolve(); expect(records).to.have.length(2); expect(records[0].type).to.eq('childList'); expect(records[0].addedNodes).to.have.length(1); expect(records[0].addedNodes[0]).to.eq(node2); expect(records[1].type).to.eq('childList'); expect(records[1].removedNodes).to.have.length(1); expect(records[1].removedNodes[0]).to.eq(node); }); it('nested attribute change', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createElement('div'); root.appendChild(node); node.setAttribute('a', '1'); observer.observe(root, { attributes: true, attributeOldValue: true, subtree: true }); node.setAttribute('a', '2'); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('attributes'); expect(records[0].target).to.eq(node); expect(records[0].attributeName).to.eq('a'); expect(records[0].oldValue).to.eq('1'); }); it('subtree text change', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createTextNode('1'); root.appendChild(node); observer.observe(root, { characterData: true, characterDataOldValue: true, subtree: true }); node.data = '2'; await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('characterData'); expect(records[0].oldValue).to.eq('1'); }); it('subtree element node add', async () => { const root = new DOMParser().parseFromString('', 'text/xml').documentElement; const { records, observer } = observerHelper(); const node = root.ownerDocument!.createElement('div'); root.appendChild(node); observer.observe(root, { childList: true, subtree: true }); const node2 = root.ownerDocument!.createElement('span'); node.appendChild(node2); await Promise.resolve(); expect(records).to.have.length(1); expect(records[0].type).to.eq('childList'); expect(records[0].addedNodes).to.have.length(1); expect(records[0].addedNodes[0]).to.eq(node2); }); });