namespace XFESystem.Browser.Tests;
public sealed class DomPrototypeMutationTests
{
[Fact]
public void ElementPrototypeInterceptorsObserveActualMutationAndTheBorrowedReceiver()
{
var page = new BrowserService();
try
{
page.Navigate("about:Start");
string result = page.ExecuteJavaScript("""
const first=document.createElement('div'),second=document.createElement('div'),child=document.createElement('span');
document.body.append(first,second);let observed=0;
const original=Element.prototype.appendChild;
Element.prototype.appendChild=function(node){observed++;return original.call(this,node)};
first.appendChild(child);Node.prototype.appendChild.call(second,child);
[observed,child.parentNode===second,Object.hasOwn(first,'appendChild'),typeof original].join(',')
""");
Assert.Equal("1,true,false,function", result);
}
finally { page.Release(); }
}
[Fact]
public void BorrowedInsertionReplacementAndRemovalUseTheActualParentAndReturnTheOriginalNode()
{
var page = new BrowserService();
try
{
page.Navigate("about:Start");
Assert.Equal("true,true,true,true", page.ExecuteJavaScript("""
const parent=document.createElement('div'),a=document.createElement('i'),b=document.createElement('b'),c=document.createElement('u');
parent.append(a);const inserted=Node.prototype.insertBefore.call(parent,b,a);
const replaced=Node.prototype.replaceChild.call(parent,c,a);
const removed=Node.prototype.removeChild.call(parent,b);
[inserted===b,replaced===a,removed===b,parent.firstChild===c].join(',')
"""));
Assert.Equal("true", page.ExecuteJavaScript("let rejected=false;try{Node.prototype.appendChild.call({},c)}catch{rejected=true}rejected"));
}
finally { page.Release(); }
}
}
namespace XFESystem.Browser.Tests;
public sealed class DomPrototypeMutationTests
{
[Fact]
public void ElementPrototypeInterceptorsObserveActualMutationAndTheBorrowedReceiver()
{
var page = new BrowserService();
try
{
page.Navigate("about:Start");
string result = page.ExecuteJavaScript("""
const first=document.createElement('div'),second=document.createElement('div'),child=document.createElement('span');
document.body.append(first,second);let observed=0;
const original=Element.prototype.appendChild;
Element.prototype.appendChild=function(node){observed++;return original.call(this,node)};
first.appendChild(child);Node.prototype.appendChild.call(second,child);
[observed,child.parentNode===second,Object.hasOwn(first,'appendChild'),typeof original].join(',')
""");
Assert.Equal("1,true,false,function", result);
}
finally { page.Release(); }
}
[Fact]
public void BorrowedInsertionReplacementAndRemovalUseTheActualParentAndReturnTheOriginalNode()
{
var page = new BrowserService();
try
{
page.Navigate("about:Start");
Assert.Equal("true,true,true,true", page.ExecuteJavaScript("""
const parent=document.createElement('div'),a=document.createElement('i'),b=document.createElement('b'),c=document.createElement('u');
parent.append(a);const inserted=Node.prototype.insertBefore.call(parent,b,a);
const replaced=Node.prototype.replaceChild.call(parent,c,a);
const removed=Node.prototype.removeChild.call(parent,b);
[inserted===b,replaced===a,removed===b,parent.firstChild===c].join(',')
"""));
Assert.Equal("true", page.ExecuteJavaScript("let rejected=false;try{Node.prototype.appendChild.call({},c)}catch{rejected=true}rejected"));
}
finally { page.Release(); }
}
}