add legacy tests, optimize empty types

This commit is contained in:
Karl Seguin
2025-11-14 15:55:02 +08:00
parent 1164da5e7a
commit 7ab88e9a71
104 changed files with 5461 additions and 27 deletions

View File

@@ -112,6 +112,33 @@ pub fn build(b: *Build) !void {
test_step.dependOn(&run_tests.step);
}
{
// ZIGDOM
// browser
const exe = b.addExecutable(.{
.name = "legacy_test",
.use_llvm = true,
.root_module = b.createModule(.{
.root_source_file = b.path("src/main_legacy_test.zig"),
.target = target,
.optimize = optimize,
.sanitize_c = enable_csan,
.sanitize_thread = enable_tsan,
.imports = &.{
.{.name = "lightpanda", .module = lightpanda_module},
},
}),
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("legacy_test", "Run the app");
run_step.dependOn(&run_cmd.step);
}
{
// wpt
const exe = b.addExecutable(.{

View File

@@ -615,6 +615,8 @@ pub fn mapZigInstanceToJs(self: *Context, js_obj_: ?v8.Object, value: anytype) !
}
const isolate = self.isolate;
const JsApi = bridge.Struct(ptr.child).JsApi;
// Sometimes we're creating a new v8.Object, like when
// we're returning a value from a function. In those cases
// we have to get the object template, and we can get an object
@@ -626,19 +628,26 @@ pub fn mapZigInstanceToJs(self: *Context, js_obj_: ?v8.Object, value: anytype) !
const template = self.templates[resolved.class_id];
break :blk template.getInstanceTemplate().initInstance(v8_context);
};
const JsApi = bridge.Struct(ptr.child).JsApi;
// The TAO contains the pointer to our Zig instance as
// well as any meta data we'll need to use it later.
// See the TaggedAnyOpaque struct for more details.
const tao = try arena.create(TaggedAnyOpaque);
tao.* = .{
.value = resolved.ptr,
.prototype_chain = resolved.prototype_chain.ptr,
.prototype_len = @intCast(resolved.prototype_chain.len),
.subtype = if (@hasDecl(JsApi.Meta, "subtype")) JsApi.Meta.subype else .node,
};
js_obj.setInternalField(0, v8.External.init(isolate, tao));
if (!@hasDecl(JsApi.Meta, "empty_with_no_proto")) {
// The TAO contains the pointer to our Zig instance as
// well as any meta data we'll need to use it later.
// See the TaggedAnyOpaque struct for more details.
const tao = try arena.create(TaggedAnyOpaque);
tao.* = .{
.value = resolved.ptr,
.prototype_chain = resolved.prototype_chain.ptr,
.prototype_len = @intCast(resolved.prototype_chain.len),
.subtype = if (@hasDecl(JsApi.Meta, "subtype")) JsApi.Meta.subype else .node,
};
js_obj.setInternalField(0, v8.External.init(isolate, tao));
} else {
// If the struct is empty, we don't need to do all
// the TOA stuff and setting the internal data.
// When we try to map this from JS->Zig, in
// typeTaggedAnyOpaque, we'll also know there that
// the type is empty and can create an empty instance.
}
const js_persistent = PersistentObject.init(isolate, js_obj);
gop.value_ptr.* = js_persistent;
@@ -1504,6 +1513,15 @@ pub fn typeTaggedAnyOpaque(comptime R: type, js_obj: v8.Object) !R {
}
const T = ti.pointer.child;
const JsApi = bridge.Struct(T).JsApi;
if (@hasDecl(JsApi.Meta, "empty_with_no_proto")) {
// Empty structs aren't stored as TOAs and there's no data
// stored in the JSObject's IntenrnalField. Why bother when
// we can just return an empty struct here?
return @constCast(@as(*const T, &.{}));
}
// if it isn't an empty struct, then the v8.Object should have an
// InternalFieldCount > 0, since our toa pointer should be embedded
// at index 0 of the internal field count.
@@ -1511,7 +1529,7 @@ pub fn typeTaggedAnyOpaque(comptime R: type, js_obj: v8.Object) !R {
return error.InvalidArgument;
}
const type_name = @typeName(bridge.Struct(T).JsApi);
const type_name = @typeName(JsApi);
if (@hasField(bridge.JsApiLookup, type_name) == false) {
@compileError("unknown Zig type: " ++ @typeName(R));
}

View File

@@ -314,7 +314,9 @@ fn generateConstructor(comptime JsApi: type, isolate: v8.Isolate) v8.FunctionTem
};
const template = v8.FunctionTemplate.initCallback(isolate, callback);
template.getInstanceTemplate().setInternalFieldCount(1);
if (!@hasDecl(JsApi.Meta, "empty_with_no_proto")) {
template.getInstanceTemplate().setInternalFieldCount(1);
}
const class_name = v8.String.initUtf8(isolate, if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi));
template.setClassName(class_name);
return template;

View File

@@ -1,13 +1,13 @@
<!DOCTYPE html>
<script src="testing.js"></script>
<!-- <script id=basic>
<script id=basic>
{
const parser = new DOMParser();
testing.expectEqual('object', typeof parser);
testing.expectEqual('function', typeof parser.parseFromString);
}
</script> -->
</script>
<script id=parseSimpleHTML>
{
@@ -23,7 +23,7 @@
}
</script>
<!-- <script id=parseWithAttributes>
<script id=parseWithAttributes>
{
const parser = new DOMParser();
const doc = parser.parseFromString('<div id="test" class="foo">Content</div>', 'text/html');
@@ -118,4 +118,3 @@
});
}
</script>
-->

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<script src="testing.js"></script>
<script id=intl>
var te = new TextEncoder();
testing.expectEqual('utf-8', te.encoding);
testing.expectEqual([226, 130, 172], Array.from(te.encode('€')));
// this will crash if ICU isn't properly configured / ininitialized
testing.expectEqual("[object Intl.DateTimeFormat]", new Intl.DateTimeFormat().toString());
</script>

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<script src="testing.js"></script>
<script id=crypto>
const a = crypto.randomUUID();
const b = crypto.randomUUID();
testing.expectEqual(36, a.length);
testing.expectEqual(36, b.length);
testing.expectEqual(false, a == b)
testing.expectError('Error: QuotaExceededError', () => {
crypto.getRandomValues(new BigUint64Array(8193));
});
let r1 = new Int32Array(5)
let r2 = crypto.getRandomValues(r1)
testing.expectEqual(5, new Set(r1).size);
testing.expectEqual(5, new Set(r2).size);
testing.expectEqual(true, r1.every((v, i) => v === r2[i]));
var r3 = new Uint8Array(16);
let r4 = crypto.getRandomValues(r3);
r4[6] = 10;
testing.expectEqual(10, r4[6]);
testing.expectEqual(10, r3[6]);
</script>

View File

@@ -0,0 +1,6 @@
<!DOCTYPE html>
<script src="testing.js"></script>
<script id=support>
testing.expectEqual(true, CSS.supports('display: flex'));
testing.expectEqual(true, CSS.supports('text-decoration-style', 'blink'));
</script>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=css_rule_list>
let list = new CSSRuleList();
testing.expectEqual(true, list instanceof CSSRuleList);
testing.expectEqual(0, list.length);
testing.expectEqual(null, list.item(0));
</script>

View File

@@ -0,0 +1,102 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=css_style_declaration>
let style = document.createElement('div').style;
style.cssText = 'color: red; font-size: 12px; margin: 5px !important;';
testing.expectEqual(3, style.length);
testing.expectEqua;('red', style.getPropertyValue('color'));
testing.expectEqua;('12px', style.getPropertyValue('font-size'));
testing.expectEqua;('', style.getPropertyValue('unknown-property'));
testing.expectEqual('important', style.getPropertyPriority('margin'));
testing.expectEqual('', style.getPropertyPriority('color'));
testing.expectEqual('', style.getPropertyPriority('unknown-property'));
testing.expectEqual('color', style.item(0));
testing.expectEqual('font-size', style.item(1));
testing.expectEqual('margin', style.item(2));
testing.expectEqual('', style.item(3));
style.setProperty('background-color', 'blue');
testing.expectEqual('blue', style.getPropertyValue('background-color'));
testing.expectEqual(4, style.length);
style.setProperty('color', 'green');
testing.expectEqual('green', style.color);
testing.expectEqual('green', style.getPropertyValue('color'));
testing.expectEqual(4, style.length);
style.setProperty('padding', '10px', 'important');
testing.expectEqual('10px', style.getPropertyValue('padding'));
testing.expectEqual('important', style.getPropertyPriority('padding'));
style.setProperty('border', '1px solid black', 'IMPORTANT');
testing.expectEqual('important', style.getPropertyPriority('border'));
</script>
<script id=removeProperty>
testing.expectEqual('green', style.removeProperty('color'));
testing.expectEqual('', style.getPropertyValue('color'));
testing.expectEqual(5, style.length)
testing.expectEqual('', style.removeProperty('unknown-property'));
</script>
<script id=includes>
testing.expectEqual(false, style.cssText.includes('font-size: 10px;'));
testing.expectEqual(true, style.cssText.includes('font-size: 12px;'));
testing.expectEqual(true, style.cssText.includes('margin: 5px !important;'));
testing.expectEqual(true, style.cssText.includes('padding: 10px !important;'));
testing.expectEqual(true, style.cssText.includes('border: 1px solid black !important;'));
</script>
<script id=special_char">
style.cssText = 'color: purple; text-align: center;';
testing.expectEqual(2, style.length);
testing.expectEqual('purple', style.getPropertyValue('color'));
testing.expectEqual('center', style.getPropertyValue('text-align'));
testing.expectEqual('', style.getPropertyValue('font-size'));
style.setProperty('cont', 'Hello; world!');
testing.expectEqual('Hello; world!', style.getPropertyValue('cont'));
style.cssText = 'content: "Hello; world!"; background-image: url("test.png");';
testing.expectEqual('"Hello; world!"', style.getPropertyValue('content'));
testing.expectEqual('url("test.png")', style.getPropertyValue('background-image'));
</script>
<script id=cssFloat">
testing.expectEqual('', style.cssFloat);
style.cssFloat = 'left';
testing.expectEqual('left', style.cssFloat);
testing.expectEqual('left', style.getPropertyValue('float'));
style.cssFloat = 'right';
testing.expectEqual('right', style.cssFloat);
testing.expectEqual('right', style.getPropertyValue('float'));
style.cssFloat = null;
testing.expectEqual('', style.cssFloat);
testing.expectEqual('', style.getPropertyValue('float'));
</script>
<script id=misc>
style.setProperty('display', '');
testing.expectEqual('', style.getPropertyValue('display'));
style.cssText = ' color : purple ; margin : 10px ; ';
testing.expectEqual('purple', style.getPropertyValue('color'));
testing.expectEqual('10px', style.getPropertyValue('margin'));
style.setProperty('border-bottom-left-radius', '5px');
testing.expectEqual('5px', style.getPropertyValue('border-bottom-left-radius'));
testing.expectEqual('visible', style.visibility);
testing.expectEqual('visible', style.getPropertyValue('visibility'));
testing.expectEqual('10px', style.margin);
style.margin = 'auto';
testing.expectEqual('auto', style.margin);
</script>

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=css_stylesheet>
let css = new CSSStyleSheet()
testing.expectEqual(true, css instanceof CSSStyleSheet);
testing.expectEqual(0, css.cssRules.length);
testing.expectEqual(null, css.ownerRule);
let index1 = css.insertRule('body { color: red; }', 0);
testing.expectEqual(0, index1);
testing.expectEqual(1, css.cssRules.length);
let replaced = false;
css.replace('body{}').then(() => replaced = true);
testing.eventually(() => testing.expectEqual(true, replaced));
</script>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=animation>
let a1 = document.createElement('div').animate(null, null);
testing.expectEqual('finished', a1.playState);
let cb = [];
a1.ready.then(() => { cb.push('ready') });
a1.finished.then((x) => {
cb.push('finished');
cb.push(x == a1);
});
testing.eventually(() => testing.expectEqual(['finished', true], cb));
</script>

View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<a id="link" href="foo" class="ok">OK</a>
<script id=attribute>
let a = document.createAttributeNS('foo', 'bar');
testing.expectEqual('foo', a.namespaceURI);
testing.expectEqual(null, a.prefix);
testing.expectEqual('bar', a.localName);
testing.expectEqual('bar', a.name);
testing.expectEqual('', a.value);
// TODO: libdom has a bug here: the created attr has no parent, it
// causes a panic w/ libdom when setting the value.
//.{ "a.value = 'nok'", "nok" },
testing.expectEqual(null, a.ownerElement);
let b = document.getElementById('link').getAttributeNode('class');
testing.expectEqual('class', b.name);
testing.expectEqual('ok', b.value);
b.value = 'nok';
testing.expectEqual('nok', b.value)
b.value = null;
testing.expectEqual('null', b.value);
b.value = 'ok';
testing.expectEqual('ok', b.value);
testing.expectEqual('link', b.ownerElement.id);
</script>

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<a id="link" href="foo" class="ok">OK</a>
<script id=character_data>
let link = document.getElementById('link');
let cdata = link.firstChild;
testing.expectEqual('OK', cdata.data);
cdata.data = 'OK modified';
testing.expectEqual('OK modified', cdata.data);
cdata.data = 'OK';
testing.expectEqual(2, cdata.length);
testing.expectEqual(true, cdata.nextElementSibling === null);
// create a next element
let next = document.createElement('a');
testing.expectEqual(true, link.appendChild(next, cdata) !== undefined);
testing.expectEqual(true, cdata.nextElementSibling.localName === 'a');
testing.expectEqual(true, cdata.previousElementSibling === null);
// create a prev element
let prev = document.createElement('div');
testing.expectEqual(true, link.insertBefore(prev, cdata) !== undefined);
testing.expectEqual('div', cdata.previousElementSibling.localName);
cdata.appendData(' modified');
testing.expectEqual('OK modified', cdata.data);
cdata.deleteData('OK'.length, ' modified'.length);
testing.expectEqual('OK', cdata.data)
cdata.insertData('OK'.length-1, 'modified');
testing.expectEqual('OmodifiedK', cdata.data);
cdata.replaceData('OK'.length-1, 'modified'.length, 'replaced');
testing.expectEqual('OreplacedK', cdata.data);
testing.expectEqual('replaced', cdata.substringData('OK'.length-1, 'replaced'.length));
testing.expectEqual('', cdata.substringData('OK'.length-1, 0));
testing.expectEqual('replaced', cdata.substringData('OK'.length-1, 'replaced'.length));
testing.expectEqual('', cdata.substringData('OK'.length-1, 0));
</script>

View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=comment>
let comment = new Comment('foo');
testing.expectEqual('foo', comment.data);
let empty = new Comment()
testing.expectEqual('', empty.data);
</script>

View File

@@ -0,0 +1,190 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id="content">
<a id="a1" href="foo" class="ok">OK</a>
<p id="p1" class="ok empty">
<span id="s1"></span>
</p>
<p id="p2"> And</p>
</div>
<script id=document>
testing.expectEqual('Document', document.__proto__.__proto__.constructor.name);
testing.expectEqual('Node', document.__proto__.__proto__.__proto__.constructor.name);
testing.expectEqual('EventTarget', document.__proto__.__proto__.__proto__.__proto__.constructor.name);
let newdoc = new Document();
testing.expectEqual(null, newdoc.documentElement);
testing.expectEqual(0, newdoc.children.length);
testing.expectEqual(0, newdoc.getElementsByTagName('*').length);
testing.expectEqual(null, newdoc.getElementsByTagName('*').item(0));
testing.expectEqual(true, newdoc.inputEncoding === document.inputEncoding);
testing.expectEqual(true, newdoc.documentURI === document.documentURI);
testing.expectEqual(true, newdoc.URL === document.URL);
testing.expectEqual(true, newdoc.compatMode === document.compatMode);
testing.expectEqual(true, newdoc.characterSet === document.characterSet);
testing.expectEqual(true, newdoc.charset === document.charset);
testing.expectEqual(true, newdoc.contentType === document.contentType);
testing.expectEqual('HTML', document.documentElement.tagName);
testing.expectEqual('UTF-8', document.characterSet);
testing.expectEqual('UTF-8', document.charset);
testing.expectEqual('UTF-8', document.inputEncoding);
testing.expectEqual('CSS1Compat', document.compatMode);
testing.expectEqual('text/html', document.contentType);
testing.expectEqual('http://localhost:9582/src/tests/dom/document.html', document.documentURI);
testing.expectEqual('http://localhost:9582/src/tests/dom/document.html', document.URL);
testing.expectEqual(document.body, document.activeElement);
$('#a1').focus();
testing.expectEqual($('#a1'), document.activeElement);
testing.expectEqual(0, document.styleSheets.length);
</script>
<script id=getElementById>
let divById = document.getElementById('content');
testing.expectEqual('HTMLDivElement', divById.constructor.name);
testing.expectEqual('div', divById.localName);
</script>
<script id=getElementsByTagName>
let byTagName = document.getElementsByTagName('p');
testing.expectEqual(2, byTagName.length)
testing.expectEqual('p1', byTagName.item(0).id);
testing.expectEqual('p2', byTagName.item(1).id);
let byTagNameAll = document.getElementsByTagName('*');
// If you add a script block (or change the HTML in any other way on this
// page), this test will break. Adjust it accordingly.
testing.expectEqual(21, byTagNameAll.length);
testing.expectEqual('html', byTagNameAll.item(0).localName);
testing.expectEqual('SCRIPT', byTagNameAll.item(11).tagName);
testing.expectEqual('s1', byTagNameAll.namedItem('s1').id);
</script>
<script id=getElementByClassName>
let ok = document.getElementsByClassName('ok');
testing.expectEqual(2, ok.length);
let empty = document.getElementsByClassName('empty');
testing.expectEqual(1, empty.length);
let emptyok = document.getElementsByClassName('empty ok');
testing.expectEqual(1, emptyok.length);
</script>
<script id=createXYZ>
var v = document.createDocumentFragment();
testing.expectEqual('#document-fragment', v.nodeName);
v = document.createTextNode('foo');
testing.expectEqual('#text', v.nodeName);
v = document.createCDATASection('foo');
testing.expectEqual('#cdata-section', v.nodeName);
v = document.createAttribute('foo');
testing.expectEqual('foo', v.nodeName);
v = document.createComment('foo');
testing.expectEqual('#comment', v.nodeName);
v.cloneNode(); // doesn't crash, (I guess that's the point??)
let pi = document.createProcessingInstruction('foo', 'bar')
testing.expectEqual('foo', pi.target);
pi.cloneNode(); // doesn't crash (I guess that's the point??)
</script>
<script id=importNode>
let nimp = document.getElementById('content');
var v = document.importNode(nimp);
testing.expectEqual('DIV', v.nodeName);
</script>
<script id=children>
testing.expectEqual(1, document.children.length);
testing.expectEqual('HTML', document.children.item(0).nodeName);
testing.expectEqual('HTML', document.firstElementChild.nodeName);
testing.expectEqual('HTML', document.lastElementChild.nodeName);
testing.expectEqual(1, document.childElementCount);
let nd = new Document();
testing.expectEqual(0, nd.children.length);
testing.expectEqual(null, nd.children.item(0));
testing.expectEqual(null, nd.firstElementChild);
testing.expectEqual(null, nd.lastElementChild);
testing.expectEqual(0, nd.childElementCount);
</script>
<script id=createElement>
let emptydoc = document.createElement('html');
emptydoc.prepend(document.createElement('html'));
let emptydoc2 = document.createElement('html');
emptydoc2.append(document.createElement('html'));
// Not sure what the above are testing, I just copied and pasted them.
// Maybe that something doesn't crash?
// Adding this so that the test runner doesn't complain;
testing.skip();
</script>
<script id=querySelector>
testing.expectEqual(null, document.querySelector(''));
testing.expectEqual('HTML', document.querySelector('*').nodeName);
testing.expectEqual('content', document.querySelector('#content').id);
testing.expectEqual('p1', document.querySelector('#p1').id);
testing.expectEqual('a1', document.querySelector('.ok').id);
testing.expectEqual('p1', document.querySelector('a ~ p').id);
testing.expectEqual('HTML', document.querySelector(':root').nodeName);
testing.expectEqual(2, document.querySelectorAll('p').length);
testing.expectEqual([''],
Array.from(document.querySelectorAll('#content > p#p1'))
.map(row => row.querySelector('span').textContent)
);
testing.expectEqual(0, document.querySelectorAll('.\\:popover-open').length);
testing.expectEqual(0, document.querySelectorAll('.foo\\:bar').length);
</script>
<script id=adoptNode>
// this test breaks the doc structure, keep it at the end
let nadop = document.getElementById('content')
var v = document.adoptNode(nadop);
testing.expectEqual('DIV', v.nodeName);
</script>
<script id=adoptedStyleSheets>
const acss = document.adoptedStyleSheets;
testing.expectEqual(0, acss.length);
acss.push(new CSSStyleSheet());
testing.expectEqual(1, acss.length);
</script>
<script id=createEvent>
const event = document.createEvent("Event");
testing.expectEqual(true, event instanceof Event);
testing.expectEqual("", event.type);
const customEvent = document.createEvent("CustomEvent");
customEvent.initCustomEvent("hey", false, false);
testing.expectEqual(true, customEvent instanceof CustomEvent);
testing.expectEqual(true, customEvent instanceof Event);
testing.withError(
(err) => {
// TODO: Check the error type.
},
() => document.createEvent("InvalidType"),
);
</script>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<body></body>
<script id=documentFragement>
testing.expectEqual('DocumentFragment', new DocumentFragment().constructor.name);
const dc1 = new DocumentFragment();
testing.expectEqual(true, dc1.isEqualNode(dc1))
const dc2 = new DocumentFragment();
testing.expectEqual(true, dc1.isEqualNode(dc2))
let f = document.createDocumentFragment();
let d = document.createElement('div');
testing.expectEqual(0, d.childElementCount);
d.id = 'x';
testing.expectEqual(null, $('#x'));
f.append(d);
testing.expectEqual(1, f.childElementCount)
testing.expectEqual('x', f.children[0].id);
testing.expectEqual(null, $('#x'));
document.getElementsByTagName('body')[0].append(f.cloneNode(true));
testing.expectEqual(true, $('#x') != null);
testing.expectEqual(null, document.querySelector('.hello'));
testing.expectEqual(0, document.querySelectorAll('.hello').length);
testing.expectEqual('x', document.querySelector('#x').id);
testing.expectEqual(['x'], Array.from(document.querySelectorAll('#x')).map((n) => n.id));
</script>

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=documentType>
let dt1 = document.implementation.createDocumentType('qname1', 'pid1', 'sys1');
let dt2 = document.implementation.createDocumentType('qname2', 'pid2', 'sys2');
let dt3 = document.implementation.createDocumentType('qname1', 'pid1', 'sys1');
testing.expectEqual(true, dt1.isEqualNode(dt1));
testing.expectEqual(true, dt1.isEqualNode(dt3));
testing.expectEqual(false, dt1.isEqualNode(dt2));
testing.expectEqual(false, dt2.isEqualNode(dt3));
testing.expectEqual(false, dt1.isEqualNode(document));
testing.expectEqual(false, document.isEqualNode(dt1));
</script>

View File

@@ -0,0 +1,7 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=domParser>
const dp = new DOMParser();;
const parsed = dp.parseFromString('<div>abc</div>', 'text/html');
testing.expectEqual('[object HTMLDocument]', parsed.toString());
</script>

View File

@@ -0,0 +1,341 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id="content" dir="ltr">
<a id="link" href="foo" class="ok">OK</a>
<p id="para-empty" class="ok empty">
<span id="para-empty-child"></span>
</p>
<p id="para"> And</p>
<!--comment-->
</div>
<script id=element>
let content = document.getElementById('content');
testing.expectEqual('http://www.w3.org/1999/xhtml', content.namespaceURI);
testing.expectEqual(null, content.prefix);
testing.expectEqual('div', content.localName);
testing.expectEqual('DIV', content.tagName);
testing.expectEqual('content', content.id);
testing.expectEqual('ltr', content.dir);
content.id = 'foo';
testing.expectEqual('foo', content.id);
content.id = 'content';
testing.expectEqual('', content.className);
let p1 = document.getElementById('para-empty');
testing.expectEqual('ok empty', p1.className);
testing.expectEqual('', p1.dir);
p1.className = 'foo bar baz';
testing.expectEqual('foo bar baz', p1.className);
p1.className = 'ok empty';
testing.expectEqual(2, p1.classList.length);
</script>
<script id=closest>
const el2 = document.createElement('div');
el2.id = 'closest';
el2.className = 'ok';
testing.expectEqual(el2, el2.closest('#closest'));
testing.expectEqual(el2, el2.closest('.ok'));
testing.expectEqual(null, el2.closest('#9000'));
testing.expectEqual(null, el2.closest('.notok'));
const sp = document.createElement('span');
el2.appendChild(sp);
testing.expectEqual(el2, sp.closest('#closest'));
testing.expectEqual(null, sp.closest('#9000'));
</script>
<script id=attributes>
testing.expectEqual(true, content.hasAttributes());
testing.expectEqual(2, content.attributes.length);
testing.expectEqual(['id', 'dir'], content.getAttributeNames());
testing.expectEqual('content', content.getAttribute('id'));
testing.expectEqual('content', content.attributes['id'].value);
let x = '';
for (const attr of content.attributes) {
x += attr.name + '=' + attr.value + ',';
}
testing.expectEqual('id=content,dir=ltr,', x);
testing.expectEqual(false, content.hasAttribute('foo'));
testing.expectEqual(null, content.getAttribute('foo'));
content.setAttribute('foo', 'bar');
testing.expectEqual(true, content.hasAttribute('foo'));
testing.expectEqual('bar', content.getAttribute('foo'));
testing.expectEqual(['id', 'dir', 'foo'], content.getAttributeNames());
testing.expectError('Error: InvalidCharacterError', () => {
content.setAttribute('.foo', 'invalid')
});
content.setAttribute('foo', 'baz');
testing.expectEqual(true, content.hasAttribute('foo'));
testing.expectEqual('baz', content.getAttribute('foo'));
content.removeAttribute('foo');
testing.expectEqual(false, content.hasAttribute('foo'));
testing.expectEqual(null, content.getAttribute('foo'));
let b = document.getElementById('content');
testing.expectEqual(true, b.toggleAttribute('foo'));
testing.expectEqual(true, b.hasAttribute('foo'));
testing.expectEqual('', b.getAttribute('foo'));
testing.expectEqual(false, b.toggleAttribute('foo'));
testing.expectEqual(false, b.hasAttribute('foo'));
testing.expectEqual(false, document.createElement('a').hasAttributes());
const div2 = document.createElement('div');
div2.innerHTML = '<p id=1 .lit$id=9>a</p>';
testing.expectEqual('<p id="1" .lit$id="9">a</p>', div2.innerHTML);
testing.expectEqual(['id', '.lit$id'], div2.childNodes[0].getAttributeNames());
</script>
<script id=children>
testing.expectEqual(3, content.children.length);
testing.expectEqual('A', content.firstElementChild.nodeName);
testing.expectEqual('P', content.lastElementChild.nodeName);
testing.expectEqual(3, content.childElementCount);
</script>
<script id=sibling>
content.prepend(document.createTextNode('foo'));
content.append(document.createTextNode('bar'));
let d = document.getElementById('para');
testing.expectEqual('P', d.previousElementSibling.nodeName);
testing.expectEqual(null, d.nextElementSibling);
</script>
<script id=querySelector>
testing.expectEqual(null, content.querySelector('foo'));
testing.expectEqual(null, content.querySelector('#foo'));
testing.expectEqual('link', content.querySelector('#link').id);
testing.expectEqual('para', content.querySelector('#para').id);
testing.expectEqual('link', content.querySelector('*').id);
testing.expectEqual(null, content.querySelector(''));
testing.expectEqual('link', content.querySelector('*').id);
testing.expectEqual(null, content.querySelector('#content'));
testing.expectEqual('para', content.querySelector('#para').id);
testing.expectEqual('link', content.querySelector('.ok').id);
testing.expectEqual('para-empty', content.querySelector('a ~ p').id);
testing.expectEqual(0, content.querySelectorAll('foo').length);
testing.expectEqual(0, content.querySelectorAll('#foo').length);
testing.expectEqual(1, content.querySelectorAll('#link').length);
testing.expectEqual('link', content.querySelectorAll('#link').item(0).id);
testing.expectEqual(1, content.querySelectorAll('#para').length);
testing.expectEqual('para', content.querySelectorAll('#para').item(0).id);
testing.expectEqual(4, content.querySelectorAll('*').length);
testing.expectEqual(2, content.querySelectorAll('p').length);
testing.expectEqual('link', content.querySelectorAll('.ok').item(0).id);
</script>
<script id=createdAttributes>
let ff = document.createAttribute('foo');
content.setAttributeNode(ff);
testing.expectEqual('foo', content.getAttributeNode('foo').name);
testing.expectEqual('foo', content.removeAttributeNode(ff).name);
testing.expectEqual(null, content.getAttributeNode('bar'));
</script>
<script id=innerHTML>
testing.expectEqual(' And', document.getElementById('para').innerHTML);
testing.expectEqual('<span id="para-empty-child"></span>', $('#para-empty').innerHTML.trim());
let h = $('#para-empty');
const prev = h.innerHTML;
h.innerHTML = '<p id="hello">hello world</p>';
testing.expectEqual('<p id="hello">hello world</p>', h.innerHTML);
testing.expectEqual('P', h.firstChild.nodeName);
testing.expectEqual('hello', h.firstChild.id);
testing.expectEqual('hello world', h.firstChild.textContent);
h.innerHTML = prev;
testing.expectEqual('<span id="para-empty-child"></span>', $('#para-empty').innerHTML.trim());
testing.expectEqual('<p id="para"> And</p>', $('#para').outerHTML);
</script>
<script id=dimensions>
const para = document.getElementById('para');
testing.expectEqual(5, para.clientWidth);
testing.expectEqual(5, para.clientHeight);
let r1 = document.getElementById('para').getBoundingClientRect();
testing.expectEqual(0, r1.x);
testing.expectEqual(0, r1.y);
testing.expectEqual(5, r1.width);
testing.expectEqual(5, r1.height);
let r2 = document.getElementById('content').getBoundingClientRect();
testing.expectEqual(5, r2.x);
testing.expectEqual(0, r2.y);
testing.expectEqual(5, r2.width);
testing.expectEqual(5, r2.height);
let r3 = document.getElementById('para').getBoundingClientRect();
testing.expectEqual(0, r3.x);
testing.expectEqual(0, r3.y);
testing.expectEqual(5, r3.width);
testing.expectEqual(5, r3.height);
testing.expectEqual(10, para.clientWidth);
testing.expectEqual(5, para.clientHeight);
let r4 = document.createElement('div').getBoundingClientRect();
testing.expectEqual(0, r4.x);
testing.expectEqual(0, r4.y);
testing.expectEqual(0, r4.width);
testing.expectEqual(0, r4.height);
</script>
<script id=matches>
const el = document.createElement('div');
el.id = 'matches';
el.className = 'ok';
testing.expectEqual(true, el.matches('#matches'));
testing.expectEqual(true, el.matches('.ok'));
testing.expectEqual(false, el.matches('#9000'));
testing.expectEqual(false, el.matches('.notok'));
</script>
<script id=scroll>
const el3 = document.createElement('div');
el3.scrollIntoViewIfNeeded();
el3.scrollIntoViewIfNeeded(false);
// doesn't throw is good enough
testing.skip();
</script>
<script id=before>
const before_container = document.createElement('div');
document.append(before_container);
const b1 = document.createElement('div');
before_container.append(b1);
const b1_a = document.createElement('p');
b1.before(b1_a, 'over 9000');
testing.expectEqual('<p></p>over 9000<div></div>', before_container.innerHTML);
</script>
<script id=after>
const after_container = document.createElement('div');
document.append(after_container);
const a1 = document.createElement('div');
after_container.append(a1);
const a1_a = document.createElement('p');
a1.after('over 9000', a1_a);
testing.expectEqual('<div></div>over 9000<p></p>', after_container.innerHTML);
</script>
<script id=getElementsByTagName>
var div1 = document.createElement('div');
div1.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
testing.expectEqual(1, div1.getElementsByTagName('a').length);
</script>
<script id=outerHTML>
let fc = document.createElement('div')
fc.innerHTML = '<script><\/script>';
testing.expectEqual('<div><script><\/script></div>', fc.outerHTML);
fc = document.createElement('div')
fc.innerHTML = '<script><\/script><p>hello</p>';
testing.expectEqual('<div><script><\/script><p>hello</p></div>', fc.outerHTML);
</script>
<script id=remove>
const rm = document.createElement('div');
testing.expectEqual([], rm.getAttributeNames());
rm.id = 'to-remove';
document.getElementsByTagName('body')[0].appendChild(rm);
$('#to-remove').remove();
testing.expectEqual(null, $('#to-remove'));
</script>
<script id=elementDir>
const divElement = document.createElement("div");
// Always initialized with empty string if `dir` attribute not provided.
testing.expectEqual("", divElement.dir);
divElement.dir = "ltr";
testing.expectEqual("ltr", divElement.dir);
divElement.dir = "rtl";
testing.expectEqual("rtl", divElement.dir);
divElement.dir = "auto";
testing.expectEqual("auto", divElement.dir);
</script>
<script id=linkRel>
const linkElement = document.createElement("link");
// A newly created link element must have it's rel set to empty string.
testing.expectEqual("", linkElement.rel);
linkElement.rel = "stylesheet";
testing.expectEqual("stylesheet", linkElement.rel);
</script>
<!-- This structure will get mutated by insertAdjacentHTML test -->
<div id="insert-adjacent-html-outer-wrapper">
<div id="insert-adjacent-html-inner-wrapper">
<span></span>
<p>content</p>
</div>
</div>
<script id=insertAdjacentHTML>
// Insert "beforeend".
const wrapper = $("#insert-adjacent-html-inner-wrapper");
wrapper.insertAdjacentHTML("beforeend", "<h1>title</h1>");
let newElement = wrapper.lastElementChild;
testing.expectEqual("H1", newElement.tagName);
testing.expectEqual("title", newElement.innerText);
// Insert "beforebegin".
wrapper.insertAdjacentHTML("beforebegin", "<h2>small title</h2>");
newElement = wrapper.previousElementSibling;
testing.expectEqual("H2", newElement.tagName);
testing.expectEqual("small title", newElement.innerText);
// Insert "afterend".
wrapper.insertAdjacentHTML("afterend", "<div id=\"afterend\">after end</div>");
newElement = wrapper.nextElementSibling;
testing.expectEqual("DIV", newElement.tagName);
testing.expectEqual("after end", newElement.innerText);
testing.expectEqual("afterend", newElement.id);
// Insert "afterbegin".
wrapper.insertAdjacentHTML("afterbegin", "<div class=\"afterbegin\">after begin</div><yy></yy>");
newElement = wrapper.firstElementChild;
testing.expectEqual("DIV", newElement.tagName);
testing.expectEqual("after begin", newElement.innerText);
testing.expectEqual("afterbegin", newElement.className);
</script>
<script id=nonBreakingSpace>
// Test non-breaking space encoding (critical for React hydration)
const div = document.createElement('div');
div.innerHTML = 'hello\xa0world';
testing.expectEqual('hello\xa0world', div.textContent);
testing.expectEqual('hello&nbsp;world', div.innerHTML);
// Test that outerHTML also encodes non-breaking spaces correctly
const p = document.createElement('p');
p.textContent = 'XAnge\xa0Privacy';
testing.expectEqual('<p>XAnge&nbsp;Privacy</p>', p.outerHTML);
</script>

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id="content"><p id=para></p></div>
<script id=eventTarget>
testing.expectEqual('[object EventTarget]', new EventTarget().toString());
let content = $('#content');
let para = $('#para');
var nb = 0;
var evt;
var phase;
var cur;
function reset() {
nb = 0;
evt = undefined;
phase = undefined;
cur = undefined;
}
function cbk(event) {
evt = event;
phase = event.eventPhase;
cur = event.currentTarget;
nb++;
}
content.addEventListener('basic', cbk);
content.dispatchEvent(new Event('basic'));
testing.expectEqual(1, nb);
testing.expectEqual(true, evt instanceof Event);
testing.expectEqual('basic', evt.type);
testing.expectEqual(2, phase);
testing.expectEqual('content', cur.getAttribute('id'));
reset();
para.dispatchEvent(new Event('basic'))
// handler is not called, no capture, not the targeno bubbling
testing.expectEqual(0, nb);
testing.expectEqual(undefined, evt);
reset();
content.addEventListener('basic', cbk);
content.dispatchEvent(new Event('basic'))
testing.expectEqual(1, nb);
reset();
content.addEventListener('basic', cbk, true);
content.dispatchEvent(new Event('basic'));
testing.expectEqual(2, nb);
reset()
content.removeEventListener('basic', cbk);
content.dispatchEvent(new Event('basic'));
testing.expectEqual(1, nb);
reset();
content.removeEventListener('basic', cbk, {capture: true});
content.dispatchEvent(new Event('basic'));
testing.expectEqual(0, nb);
reset();
content.addEventListener('capture', cbk, true);
content.dispatchEvent(new Event('capture'));
testing.expectEqual(1, nb);
testing.expectEqual(true, evt instanceof Event);
testing.expectEqual('capture', evt.type);
testing.expectEqual(2, phase);
testing.expectEqual('content', cur.getAttribute('id'));
reset();
para.dispatchEvent(new Event('capture'));
testing.expectEqual(1, nb);
testing.expectEqual(true, evt instanceof Event);
testing.expectEqual('capture', evt.type);
testing.expectEqual(1, phase);
testing.expectEqual('content', cur.getAttribute('id'));
reset();
content.addEventListener('bubbles', cbk);
content.dispatchEvent(new Event('bubbles', {bubbles: true}));
testing.expectEqual(1, nb);
testing.expectEqual(true, evt instanceof Event);
testing.expectEqual('bubbles', evt.type);
testing.expectEqual(2, phase);
testing.expectEqual('content', cur.getAttribute('id'));
reset();
para.dispatchEvent(new Event('bubbles', {bubbles: true}));
testing.expectEqual(1, nb);
testing.expectEqual(true, evt instanceof Event);
testing.expectEqual('bubbles', evt.type);
testing.expectEqual(3, phase);
testing.expectEqual('content', cur.getAttribute('id'));
const obj1 = {
calls: 0,
handleEvent: function() { this.calls += 1 }
};
content.addEventListener('he', obj1);
content.dispatchEvent(new Event('he'));
testing.expectEqual(1, obj1.calls);
content.removeEventListener('he', obj1);
content.dispatchEvent(new Event('he'));
testing.expectEqual(1, obj1.calls);
// doesn't crash on null receiver
content.addEventListener('he2', null);
content.dispatchEvent(new Event('he2'));
</script>

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id="content">
<a id="link" href="foo" class="ok">OK</a>
</div>
<script id=exceptions>
let content = $('#content');
let link = $('#link');
testing.withError((err) => {
const msg = "Failed to execute 'appendChild' on 'Node': The new child element contains the parent.";
testing.expectEqual(3, err.code);
testing.expectEqual(msg, err.message);
testing.expectEqual('HierarchyRequestError: ' + msg, err.toString());
testing.expectEqual(true, err instanceof DOMException);
testing.expectEqual(true, err instanceof Error);
}, () => link.appendChild(content));
</script>
<script id=constructor>
let exc0 = new DOMException();
testing.expectEqual('Error', exc0.name);
testing.expectEqual(0, exc0.code);
testing.expectEqual('', exc0.message);
testing.expectEqual('Error', exc0.toString());
let exc1 = new DOMException('Sandwich malfunction');
testing.expectEqual('Error', exc1.name);
testing.expectEqual(0, exc1.code);
testing.expectEqual('Sandwich malfunction', exc1.message);
testing.expectEqual('Error: Sandwich malfunction', exc1.toString());
let exc2 = new DOMException('Caterpillar turned into a butterfly', 'NoModificationAllowedError');
testing.expectEqual('NoModificationAllowedError', exc2.name);
testing.expectEqual(7, exc2.code);
testing.expectEqual('Caterpillar turned into a butterfly', exc2.message);
testing.expectEqual('NoModificationAllowedError: Caterpillar turned into a butterfly', exc2.toString());
</script>

View File

@@ -0,0 +1,67 @@
<!DOCTYPE html>
<body>
<div id="content">
<a id="link" href="foo" class="ok">OK</a>
<p id="para-empty" class="ok empty">
<span id="para-empty-child"></span>
</p>
<p id="para"> And</p>
<!--comment-->
</div>
</body>
<script src="../testing.js"></script>
<script id=caseInsensitve>
const Ptags = document.getElementsByTagName('P');
testing.expectEqual(2, Ptags.length);
testing.expectEqual('p', Ptags.item(0).localName);
testing.expectEqual('p', Ptags.item(1).localName);
</script>
<script id=all>
let allTags = document.getElementsByTagName('*');
testing.expectEqual(13, allTags.length);
testing.expectEqual('html', allTags.item(0).localName);
testing.expectEqual('html', allTags.item(0).localName);
testing.expectEqual('head', allTags.item(1).localName);
testing.expectEqual('html', allTags.item(0).localName);
testing.expectEqual('body', allTags.item(2).localName);
testing.expectEqual('div', allTags.item(3).localName);
testing.expectEqual('p', allTags.item(7).localName);
testing.expectEqual('span', allTags.namedItem('para-empty-child').localName);
// array like
testing.expectEqual('html', allTags[0].localName);
testing.expectEqual('p', allTags[7].localName);
testing.expectEqual(undefined, allTags[14]);
testing.expectEqual('span', allTags['para-empty-child'].localName);
testing.expectEqual(undefined, allTags['foo']);
</script>
<script id=element>
let content = $('#content');
testing.expectEqual(4, content.getElementsByTagName('*').length);
testing.expectEqual(2, content.getElementsByTagName('p').length);
testing.expectEqual(0, content.getElementsByTagName('div').length);
testing.expectEqual(1, document.children.length);
testing.expectEqual(3, content.children.length);
</script>
<script id=liveness>
const ptags = document.getElementsByTagName('p');
testing.expectEqual(2, ptags.length);
testing.expectEqual(' And', ptags.item(1).textContent);
let p = document.createElement('p');
p.textContent = 'OK live';
// hasn't been added, still 2
testing.expectEqual(2, ptags.length);
testing.expectEqual(true, content.appendChild(p) != undefined);
testing.expectEqual(3, ptags.length);
testing.expectEqual('OK live', ptags.item(2).textContent);
testing.expectEqual(true, content.insertBefore(p, $('#para-empty')) != undefined);
testing.expectEqual('OK live', ptags.item(0).textContent);
</script>

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=implementation>
let impl = document.implementation;
testing.expectEqual("[object HTMLDocument]", impl.createHTMLDocument().toString());;
const doc = impl.createHTMLDocument('foo');
testing.expectEqual("[object HTMLDocument]", doc.toString());
testing.expectEqual("foo", doc.title);
testing.expectEqual("[object HTMLBodyElement]", doc.body.toString());
testing.expectEqual("[object Document]", impl.createDocument(null, 'foo').toString());
testing.expectEqual("[object DocumentType]", impl.createDocumentType('foo', 'bar', 'baz').toString());
testing.expectEqual(true, impl.hasFeature());
</script>

View File

@@ -0,0 +1,163 @@
<!DOCTYPE html>
<body></body>
<script src="../testing.js"></script>
<script id=intersectionObserver>
{
// never attached
let count = 0;
const div = document.createElement('div');
new IntersectionObserver((entries) => {
count += 1;
}).observe(div);
testing.eventually(() => {
testing.expectEqual(0, count);
});
}
{
// not connected, but has parent
let count = 0;
const div1 = document.createElement('div');
const div2 = document.createElement('div');
new IntersectionObserver((entries) => {
console.log(entries[0]);
count += 1;
}).observe(div1);
div2.appendChild(div1);
testing.eventually(() => {
testing.expectEqual(1, count);
});
}
</script>
<script id=reobserve>
{
let count = 0;
let observer = new IntersectionObserver(entries => {
count += entries.length;
});
const div1 = document.createElement('div');
document.body.appendChild(div1);
// cannot fire synchronously, must be on the next tick
testing.expectEqual(0, count);
observer.observe(div1);
testing.expectEqual(0, count);
observer.observe(div1);
observer.observe(div1);
testing.expectEqual(0, count);
testing.eventually(() => {
testing.expectEqual(1, count);
});
}
</script>
<script id=unobserve>
{
let count = 0;
let observer = new IntersectionObserver(entries => {
count += entries.length;
});
const div1 = document.createElement('div');
document.body.appendChild(div1);
testing.expectEqual(0, count);
observer.observe(div1);
testing.expectEqual(0, count);
observer.observe(div1);
observer.observe(div1);
testing.expectEqual(0, count);
observer.unobserve(div1);
testing.eventually(() => {
testing.expectEqual(0, count);
});
}
</script>
<script id=disconnect>
{
let count = 0;
let observer = new IntersectionObserver(entries => {
count += entries.length;
});
const div1 = document.createElement('div');
document.body.appendChild(div1);
// cannot fire synchronously, must be on the next tick
testing.expectEqual(0, count);
observer.observe(div1);
testing.expectEqual(0, count);
observer.observe(div1);
observer.observe(div1);
testing.expectEqual(0, count);
observer.disconnect();
testing.eventually(() => {
testing.expectEqual(0, count);
});
}
</script>
<script id=entry>
{
let entry = null;
let observer = new IntersectionObserver(entries => {
entry = entries[0];
});
let div1 = document.createElement('div');
document.body.appendChild(div1);
new IntersectionObserver(entries => { entry = entries[0]; }).observe(div1);
testing.eventually(() => {
testing.expectEqual(0, entry.boundingClientRect.x);
testing.expectEqual(1, entry.intersectionRatio);
testing.expectEqual(0, entry.intersectionRect.x);
testing.expectEqual(0, entry.intersectionRect.y);
testing.expectEqual(5, entry.intersectionRect.width);
testing.expectEqual(5, entry.intersectionRect.height);
testing.expectEqual(true, entry.isIntersecting);
testing.expectEqual(0, entry.rootBounds.x);
testing.expectEqual(0, entry.rootBounds.y);
testing.expectEqual(5, entry.rootBounds.width);
testing.expectEqual(5, entry.rootBounds.height);
testing.expectEqual('[object HTMLDivElement]', entry.target.toString());
});
}
</script>
<script id=timing>
{
const capture = [];
const observer = new IntersectionObserver(() => {
capture.push('callback');
});
const div = document.createElement('div');
capture.push('pre-append');
document.body.appendChild(div);
capture.push('post-append');
capture.push('pre-observe');
observer.observe(div);
capture.push('post-observe');
testing.eventually(() => {
testing.expectEqual([
'pre-append',
'post-append',
'pre-observe',
'post-observe',
'callback',
], capture)
});
}
</script>

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=messageChannel>
const mc1 = new MessageChannel();
testing.expectEqual(mc1.port1, mc1.port1);
testing.expectEqual(mc1.port2, mc1.port2);
testing.expectEqual(true, mc1.port1 != mc1.port2);
mc1.port1.postMessage('msg1');
let message = null;
let target = null;
let currentTarget = null;
mc1.port2.onmessage = (e) => {
message = e.data;
target = e.target;
currentTarget = e.currentTarget;
};
// as soon as onmessage is called, queued messages are delivered
testing.expectEqual('msg1', message);
testing.expectEqual(mc1.port2, target);
testing.expectEqual(mc1.port2, currentTarget);
mc1.port1.postMessage('msg2');
testing.expectEqual('msg2', message);
testing.expectEqual(mc1.port2, target);
testing.expectEqual(mc1.port2, currentTarget);
message = null;
mc1.port1.close();
mc1.port1.postMessage('msg3');
testing.expectEqual(null, message);
const mc2 = new MessageChannel();
mc2.port2.postMessage('msg1');
mc2.port1.postMessage('msg2');
let message1 = null;
mc2.port1.addEventListener('message', (e) => {
message1 = e.data;
});
let message2 = null;
mc2.port2.addEventListener('message', (e) => {
message2 = e.data;
});
testing.expectEqual(null, message1);
testing.expectEqual(null, message2);
mc2.port2.start();
testing.expectEqual(null, message1);
testing.expectEqual('msg2', message2);
message2 = null;
mc2.port1.start();
testing.expectEqual('msg1', message1);
testing.expectEqual(null, message2);
</script>

View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<div></div>
<div id=d1><p id=p1> And</p></div>
<div id=d2><p id=p2> And</p></div>
<div id=d3><p id=p3> And</p></div>
<script src="../testing.js"></script>
<script id=mutationObserver>
// doesn't crash, yay.
new MutationObserver(() => {}).observe(document, { childList: true });
var nb = 0;
var mrs;
let cb_this1;
let mu1 = new MutationObserver(function(mu) {
mrs = mu;
nb++;
cb_this1 = this;
});
mu1.observe(document.firstElementChild, { attributes: true, attributeOldValue: true });
document.firstElementChild.setAttribute("foo", "bar");
document.firstElementChild.firstChild.setAttribute("foo", "bar");
testing.eventually(() => {
testing.expectEqual(1, nb);
testing.expectEqual(cb_this1, mu1);
testing.expectEqual('attributes', mrs[0].type);
testing.expectEqual(document.firstElementChild, mrs[0].target);
testing.expectEqual('bar', mrs[0].target.getAttribute('foo'));
testing.expectEqual('foo', mrs[0].attributeName);
testing.expectEqual(null, mrs[0].oldValue);
});
var nb2 = 0;
var mrs2;
var node1 = $('#p1').firstChild;
let mu2 = new MutationObserver((mu) => {
mrs2 = mu;
nb2++;
cb_this2 = this;
})
mu2.observe(node1, { characterData: true, characterDataOldValue: true });
node1.data = "foo";
testing.eventually(() => {
testing.expectEqual(1, nb2);
testing.expectEqual(window, cb_this2);
testing.expectEqual('characterData', mrs2[0].type);
testing.expectEqual(node1, mrs2[0].target);
testing.expectEqual('foo', mrs2[0].target.data);
testing.expectEqual(' And', mrs2[0].oldValue);
});
</script>
<script id=callback>
// tests that mutation observers that have a callback which trigger the
// mutation observer don't crash.
// https://github.com/lightpanda-io/browser/issues/550
var node2 = $("#p2");
new MutationObserver(() => {
node2.innerText = 'a';
}).observe($('#d2'), { subtree:true, childList:true });
node2.innerText = "2";
testing.eventually(() => testing.expectEqual('a', node2.innerText));
var node3 = $("#p3");
var attrWatch = 0;
new MutationObserver(() => {
attrWatch++;
}).observe($('#d3'), { attributeFilter: ["name"], subtree: true });
node3.setAttribute("id", "1");
testing.expectEqual(0, attrWatch);
node3.setAttribute('name', 'other');
testing.eventually(() => testing.expectEqual(1, attrWatch));
</script>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<div id="content"></div>
<script src="../testing.js"></script>
<script id=namedNodeMap>
let a = document.getElementById('content').attributes;
testing.expectEqual(1, a.length);
testing.expectEqual('[object Attr]', a.item(0).toString());
testing.expectEqual(null, a.item(1));
testing.expectEqual('[object Attr]', a.getNamedItem('id').toString());
testing.expectEqual(null, a.getNamedItem('foo'));
testing.expectEqual('[object Attr]', a.setNamedItem(a.getNamedItem('id')).toString());
testing.expectEqual('id', a['id'].name);
testing.expectEqual('content', a['id'].value);
testing.expectEqual(undefined, a['other']);
a[0].value = 'abc123';
testing.expectEqual('abc123', a[0].value);
</script>

View File

@@ -0,0 +1,266 @@
<!DOCTYPE html>
<body><div id="content">
<a id="link" href="foo" class="ok">OK</a>
<p id="para-empty" class="ok empty">
<span id="para-empty-child"></span>
</p>
<p id="para"> And</p>
<!--comment-->
</div>
<div id="rootNodeComposed"></div>
</body>
<script src="../testing.js"></script>
<script>
function trimAndReplace(str) {
str = str.replace(/(\r\n|\n|\r)/gm,'');
str = str.replace(/\s+/g, ' ');
str = str.trim();
return str;
}
let content = $('#content');
let link = $('#link');
let first_child = content.firstChild.nextSibling; // nextSibling because of line return \n
</script>
<script id=compareDocumentPosition>
testing.expectEqual(10, document.body.compareDocumentPosition(document.firstChild));
testing.expectEqual(10, $('#para-empty').compareDocumentPosition(content));
testing.expectEqual(20, content.compareDocumentPosition($('#para-empty')));
testing.expectEqual(0, link.compareDocumentPosition(link));
testing.expectEqual(2, $('#para-empty').compareDocumentPosition(link));
testing.expectEqual(4, link.compareDocumentPosition($('#para-empty')));
</script>
<script id=proto>
testing.expectEqual('HTMLDocument', content.getRootNode().__proto__.constructor.name);
</script>
<script id=getRootNodeComposed>
const testContainer = $('#rootNodeComposed');
const shadowHost = document.createElement('div');
testContainer.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
const shadowChild = document.createElement('span');
shadowRoot.appendChild(shadowChild);
testing.expectEqual('ShadowRoot', shadowChild.getRootNode().__proto__.constructor.name);
testing.expectEqual('ShadowRoot', shadowChild.getRootNode({ composed: false }).__proto__.constructor.name);
testing.expectEqual('HTMLDocument', shadowChild.getRootNode({ composed: true }).__proto__.constructor.name);
testing.expectEqual('HTMLDocument', shadowHost.getRootNode().__proto__.constructor.name);
const disconnected = document.createElement('div');
const disconnectedChild = document.createElement('span');
disconnected.appendChild(disconnectedChild);
testing.expectEqual('HTMLDivElement', disconnectedChild.getRootNode().__proto__.constructor.name);
testing.expectEqual('HTMLDivElement', disconnectedChild.getRootNode({ composed: true }).__proto__.constructor.name);
</script>
<script id=firstChild>
let body_first_child = document.body.firstChild;
testing.expectEqual('div', body_first_child.localName);
testing.expectEqual('HTMLDivElement', body_first_child.__proto__.constructor.name);
testing.expectEqual(null, $('#para-empty').firstChild.firstChild);
</script>
<script id=lastChild>
let last_child = content.lastChild.previousSibling; // previousSibling because of line return \n
testing.expectEqual('Comment', last_child.__proto__.constructor.name);
</script>
<script id=nextSibling>
let next_sibling = link.nextSibling.nextSibling;
testing.expectEqual('p', next_sibling.localName);
testing.expectEqual('HTMLParagraphElement', next_sibling.__proto__.constructor.name);
testing.expectEqual(null, $('#para-empty-child').nextSibling.nextSibling);
</script>
<script id=previousSibling>
let prev_sibling = $('#para-empty').previousSibling.previousSibling;
testing.expectEqual('a', prev_sibling.localName);
testing.expectEqual('HTMLAnchorElement', prev_sibling.__proto__.constructor.name);
testing.expectEqual(null, content.previousSibling);
</script>
<script id=parentElement>
let parent = $('#para').parentElement;
testing.expectEqual('div', parent.localName);
testing.expectEqual('HTMLDivElement', parent.__proto__.constructor.name)
let h = content.parentElement.parentElement;
testing.expectEqual(null, h.parentElement);
testing.expectEqual('HTMLDocument', h.parentNode.__proto__.constructor.name);
</script>
<script id=nodeName>
testing.expectEqual('A', first_child.nodeName);
testing.expectEqual('#text', link.firstChild.nodeName);
testing.expectEqual('#comment', last_child.nodeName);
testing.expectEqual('#document', document.nodeName);
</script>
<script id=nodeType>
testing.expectEqual(1, first_child.nodeType)
testing.expectEqual(3, link.firstChild.nodeType)
testing.expectEqual(8, last_child.nodeType)
testing.expectEqual(9, document.nodeType)
</script>
<script id=ownerDocument>
let owner = content.ownerDocument;
testing.expectEqual('HTMLDocument', owner.__proto__.constructor.name);
testing.expectEqual(null, document.ownerDocument)
let owner2 = document.createElement('div').ownerDocument;
testing.expectEqual('HTMLDocument', owner2.__proto__.constructor.name);
</script>
<script id=isConnected>
testing.expectEqual(true, content.isConnected);
testing.expectEqual(true, document.isConnected);
const connDiv = document.createElement('div');
testing.expectEqual(false, connDiv.isConnected);
const connParentDiv = document.createElement('div');
connParentDiv.appendChild(connDiv);
testing.expectEqual(false, connDiv.isConnected);
content.appendChild(connParentDiv);
testing.expectEqual(true, connDiv.isConnected);
</script>
<script id=nodeValue>
testing.expectEqual('comment', last_child.nodeValue);
testing.expectEqual(null, link.nodeValue);
let text = link.firstChild;
testing.expectEqual('OK', text.nodeValue);
text.nodeValue = 'OK modified';
testing.expectEqual('OK modified', text.nodeValue);
</script>
<script id=textContent>
testing.expectEqual('OK modified', text.textContent);
testing.expectEqual('OK modified And', trimAndReplace(content.textContent));
text.textContent = 'OK';
testing.expectEqual('OK', text.textContent);
testing.expectEqual('', trimAndReplace($('#para-empty').textContent));
$('#para-empty').textContent = 'OK';
testing.expectEqual('#text', $('#para-empty').firstChild.nodeName);
</script>
<script id=appendChild>
let append = document.createElement('h1');
testing.expectEqual('[object HTMLHeadingElement]', content.appendChild(append).toString());
testing.expectEqual('HTMLHeadingElement', content.lastChild.__proto__.constructor.name);
testing.expectEqual('[object HTMLAnchorElement]', content.appendChild(link).toString());
</script>
<script id=cloneNode>
let clone = link.cloneNode();
testing.expectEqual('[object HTMLAnchorElement]', clone.toString());
testing.expectEqual(null, clone.parentNode);
testing.expectEqual(null, clone.firstChild);
let clone_deep = link.cloneNode(true);
testing.expectEqual('#text', clone_deep.firstChild.nodeName);
</script>
<script id=contains>
testing.expectEqual(true, link.contains(text));
testing.expectEqual(false, text.contains(link));
</script>
<script id=hasChildNodes>
testing.expectEqual(true, link.hasChildNodes());
testing.expectEqual(false, text.hasChildNodes());
</script>
<script id=childNodesLength>
testing.expectEqual(1, link.childNodes.length);
testing.expectEqual(0, text.childNodes.length);
</script>
<script id=insertBefore>
let insertBefore = document.createElement('a');
testing.expectEqual(true, link.insertBefore(insertBefore, text) !== undefined);
testing.expectEqual('a', link.firstChild.localName);
let insertBefore2 = document.createElement('b');
testing.expectEqual('b', link.insertBefore(insertBefore2, null).localName);
testing.expectEqual('b', link.childNodes[link.childNodes.length - 1].localName);
</script>
<script id=isDefaultNamespace>
// TODO: does not seems to work
// link.isDefaultNamespace('')", "true" },
testing.expectEqual(false, link.isDefaultNamespace('false'));
</script>
<script id=isEqualNode>
let equal1 = document.createElement('a');
let equal2 = document.createElement('a');
equal1.textContent = 'is equal';
equal2.textContent = 'is equal';
// TODO: does not seems to work
// testing.expectEqual(true, equal1.isEqualNode(equal2));
testing.skip();
</script>
<script id=isSameNode>
testing.expectEqual(true, document.body.isSameNode(document.body));
testing.expectEqual(false, document.body.isSameNode(content));
</script>
<script id=baseURI>
testing.expectEqual('http://localhost:9582/src/tests/dom/node.html', link.baseURI);
</script>
<script id=removeChild>
testing.expectEqual(true, content.removeChild(append) !== undefined);
testing.expectEqual(true, last_child.__proto__.constructor.name !== 'HTMLHeadingElement');
</script>
<script id=replaceChild>
let replace = document.createElement('div');
testing.expectEqual(true, link.replaceChild(replace, insertBefore) !== undefined);
</script>
<script id=NODE_TYPE>
testing.expectEqual(1, Node.ELEMENT_NODE);
testing.expectEqual(2, Node.ATTRIBUTE_NODE);
testing.expectEqual(3, Node.TEXT_NODE);
testing.expectEqual(4, Node.CDATA_SECTION_NODE);
testing.expectEqual(7, Node.PROCESSING_INSTRUCTION_NODE);
testing.expectEqual(8, Node.COMMENT_NODE);
testing.expectEqual(9, Node.DOCUMENT_NODE);
testing.expectEqual(10, Node.DOCUMENT_TYPE_NODE);
testing.expectEqual(11, Node.DOCUMENT_FRAGMENT_NODE);
testing.expectEqual(5, Node.ENTITY_REFERENCE_NODE);
testing.expectEqual(6, Node.ENTITY_NODE);
testing.expectEqual(12, Node.NOTATION_NODE);
</script>
<span id=token class="token" style="color:#ce9178">&quot;puppeteer &quot;</span>
<h3 id=name>Leto
<!-- -->
<!-- -->
Atreides</h3>
<script id=normalize>
const token = $('#token');
testing.expectEqual('"puppeteer "', token.firstChild.nodeValue);
const name = $('#name');
testing.expectEqual([
"Leto\n ",
" ",
"\n ",
" ",
"\n Atreides"
], Array.from(name.childNodes).map((n) => n.nodeValue));
</script>

View File

@@ -0,0 +1,219 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<!-- Test fixture -->
<div id="container">
<!-- comment1 -->
<div id="outer">
<!-- comment2 -->
<span id="inner">
<!-- comment3 -->
Text content
<!-- comment4 -->
</span>
<!-- comment5 -->
</div>
<!-- comment6 -->
</div>
<script id=nodeFilter>
testing.expectEqual(1, NodeFilter.FILTER_ACCEPT);
testing.expectEqual(2, NodeFilter.FILTER_REJECT);
testing.expectEqual(3, NodeFilter.FILTER_SKIP);
testing.expectEqual(4294967295, NodeFilter.SHOW_ALL);
testing.expectEqual(129, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);
</script>
<script id=treeWalkerComments>
{
const container = $('#container');
const walker = document.createTreeWalker(
container,
NodeFilter.SHOW_COMMENT,
null,
false
);
const comments = [];
let node;
while (node = walker.nextNode()) {
comments.push(node.data.trim());
}
// Should find all 6 comments, including those nested inside elements
testing.expectEqual(6, comments.length);
testing.expectEqual('comment1', comments[0]);
testing.expectEqual('comment2', comments[1]);
testing.expectEqual('comment3', comments[2]);
testing.expectEqual('comment4', comments[3]);
testing.expectEqual('comment5', comments[4]);
testing.expectEqual('comment6', comments[5]);
}
</script>
<script id=treeWalkerElements>
{
const container = $('#container');
const walker = document.createTreeWalker(
container,
NodeFilter.SHOW_ELEMENT,
null,
false
);
const elements = [];
let node;
while (node = walker.nextNode()) {
if (node.id) {
elements.push(node.id);
}
}
// Should find the 2 nested elements (outer and inner)
testing.expectEqual(2, elements.length);
testing.expectEqual('outer', elements[0]);
testing.expectEqual('inner', elements[1]);
}
</script>
<script id=treeWalkerAll>
{
const container = $('#container');
const walker = document.createTreeWalker(
container,
NodeFilter.SHOW_ALL,
null,
false
);
let commentCount = 0;
let elementCount = 0;
let textCount = 0;
let node;
while (node = walker.nextNode()) {
if (node.nodeType === 8) commentCount++; // Comment
else if (node.nodeType === 1) elementCount++; // Element
else if (node.nodeType === 3) textCount++; // Text
}
testing.expectEqual(6, commentCount);
testing.expectEqual(2, elementCount);
testing.expectEqual(true, textCount > 0);
}
</script>
<script id=treeWalkerCombined>
{
const container = $('#container');
const walker = document.createTreeWalker(
container,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,
null,
false
);
let commentCount = 0;
let elementCount = 0;
let node;
while (node = walker.nextNode()) {
if (node.nodeType === 8) commentCount++; // Comment
else if (node.nodeType === 1) elementCount++; // Element
}
// Should find 6 comments and 2 elements, but no text nodes
testing.expectEqual(6, commentCount);
testing.expectEqual(2, elementCount);
}
</script>
<script id=treeWalkerCustomFilter>
{
const container = $('#container');
// Filter that accepts only elements with id
const walker = document.createTreeWalker(
container,
NodeFilter.SHOW_ELEMENT,
{
acceptNode: function(node) {
return node.id ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
}
},
false
);
const elements = [];
let node;
while (node = walker.nextNode()) {
elements.push(node.id);
}
// Should find only elements with id (outer and inner)
testing.expectEqual(2, elements.length);
testing.expectEqual('outer', elements[0]);
testing.expectEqual('inner', elements[1]);
}
</script>
<script id=nodeIteratorComments>
{
const container = $('#container');
const iterator = document.createNodeIterator(
container,
NodeFilter.SHOW_COMMENT,
null,
false
);
const comments = [];
let node;
while (node = iterator.nextNode()) {
comments.push(node.data.trim());
}
// Should find all 6 comments, including those nested inside elements
testing.expectEqual(6, comments.length);
testing.expectEqual('comment1', comments[0]);
testing.expectEqual('comment2', comments[1]);
testing.expectEqual('comment3', comments[2]);
testing.expectEqual('comment4', comments[3]);
testing.expectEqual('comment5', comments[4]);
testing.expectEqual('comment6', comments[5]);
}
</script>
<script id=reactLikeScenario>
{
// Test a React-like scenario with comment markers
const div = document.createElement('div');
div.innerHTML = `
<a href="/">
<!--$-->
<svg viewBox="0 0 10 10">
<path d="M0,0 L10,10" />
</svg>
<!--/$-->
</a>
`;
const walker = document.createTreeWalker(
div,
NodeFilter.SHOW_COMMENT,
null,
false
);
const comments = [];
let node;
while (node = walker.nextNode()) {
comments.push(node.data);
}
// Should find both React markers even though they're nested inside <a>
testing.expectEqual(2, comments.length);
testing.expectEqual('$', comments[0]);
testing.expectEqual('/$', comments[1]);
}
</script>

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=nodeIterator>
const nodeIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_ELEMENT,
{
acceptNode(node) {
return NodeFilter.FILTER_ACCEPT;
},
},
);
testing.expectEqual('BODY', nodeIterator.nextNode().nodeName);
testing.expectEqual('DIV', nodeIterator.nextNode().nodeName);
testing.expectEqual('A', nodeIterator.nextNode().nodeName);
testing.expectEqual('A', nodeIterator.previousNode().nodeName); // pointer_before_current flips
testing.expectEqual('A', nodeIterator.nextNode().nodeName); // pointer_before_current flips
testing.expectEqual('A', nodeIterator.previousNode().nodeName); // pointer_before_current flips
testing.expectEqual('DIV', nodeIterator.previousNode().nodeName);
testing.expectEqual('BODY', nodeIterator.previousNode().nodeName);
testing.expectEqual(null, nodeIterator.previousNode()); // Not HEAD since body is root
testing.expectEqual(null, nodeIterator.previousNode()); // Keeps returning null
testing.expectEqual('BODY', nodeIterator.nextNode().nodeName);
nodeIterator.nextNode();
nodeIterator.nextNode();
nodeIterator.nextNode();
testing.expectEqual('SPAN', nodeIterator.nextNode().nodeName);
testing.expectEqual('P', nodeIterator.nextNode().nodeName);
testing.expectEqual(null, nodeIterator.nextNode()); // Just the last one
testing.expectEqual(null ,nodeIterator.nextNode()); // Keeps returning null
testing.expectEqual('P', nodeIterator.previousNode().nodeName);
const notationIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_NOTATION,
);
testing.expectEqual(null, notationIterator.nextNode());
testing.expectEqual(null, notationIterator.previousNode());
testing.expectEqual(1, nodeIterator.filter.acceptNode(document.body));
testing.expectEqual(null, notationIterator.filter);
const rejectIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_ALL,
(e => { return NodeFilter.FILTER_REJECT}),
);
testing.expectEqual(2, rejectIterator.filter(document.body));
</script>
<body>
<div id="content">
<a id="link" href="foo" class="ok">OK</a>
<p id="para-empty" class="ok empty">
<span id="para-empty-child"></span>
</p>
<p id="para"> And</p>
<!--comment-->
</div>
</body>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<div id="content">
<a id="link" href="foo" class="ok">OK</a>
<p id="para-empty" class="ok empty">
<span id="para-empty-child"></span>
</p>
<p id="para"> And</p>
<!--comment-->
</div>
<script src="../testing.js"></script>
<script id=nodeList>
let list = document.getElementById('content').childNodes;
testing.expectEqual(9, list.length);
testing.expectEqual('Text', list[0].__proto__.constructor.name);
let i = 0;
list.forEach(function (n, idx) { i += idx; });
testing.expectEqual(36, i);
</script>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<div id="target-container">
<p id="reference-node">
I am the original reference node.
</p>
</div>
<script src="../testing.js"></script>
<script id=nodeOwner>
const parser = new DOMParser();
const newDoc = parser.parseFromString('<div id="new-node"><p>Hey</p><span>Marked</span></div>', 'text/html');
const newNode = newDoc.getElementById('new-node');
const parent = $('#target-container');
const referenceNode = $('#reference-node');
parent.insertBefore(newNode, referenceNode);
const k = $('#new-node');
const ptag = k.querySelector('p');
const spanTag = k.querySelector('span');
const anotherDoc = parser.parseFromString('<div id="another-new-node"></div>', 'text/html');
const anotherNewNode = anotherDoc.getElementById('another-new-node');
testing.expectEqual('[object HTMLDivElement]', parent.appendChild(anotherNewNode).toString());
testing.expectEqual(newNode.ownerDocument, parent.ownerDocument);
testing.expectEqual(anotherNewNode.ownerDocument, parent.ownerDocument);
testing.expectEqual('P', newNode.firstChild.nodeName);
testing.expectEqual(parent.ownerDocument, ptag.ownerDocument);
testing.expectEqual(parent.ownerDocument, spanTag.ownerDocument);
testing.expectEqual(true, parent.contains(newNode));
testing.expectEqual(true, parent.contains(anotherNewNode));
testing.expectEqual(false, anotherDoc.contains(anotherNewNode));
testing.expectEqual(false, newDoc.contains(newNode));
</script>

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=performance>
let performance = window.performance;
testing.expectEqual(true, performance instanceof Performance);
let mark1 = performance.mark("start");
testing.expectEqual(true, mark1 instanceof PerformanceMark);
testing.expectEqual('start', mark1.name);
testing.expectEqual('mark', mark1.entryType);
testing.expectEqual(0, mark1.duration);
testing.expectEqual(null, mark1.detail);
let mark2 = performance.mark("start", {startTime: 32939393.9});
testing.expectEqual(32939393.9, mark2.startTime);
</script>

View File

@@ -0,0 +1,5 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=performanceObserver>
testing.expectEqual(0, PerformanceObserver.supportedEntryTypes.length);
</script>

View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=processingInstruction>
let pi = document.createProcessingInstruction('foo', 'bar');
testing.expectEqual('foo', pi.target);
testing.expectEqual('bar', pi.data);
pi.data = 'foo';
testing.expectEqual('foo', pi.data);
let pi2 = pi.cloneNode();
testing.expectEqual(7, pi2.nodeType);
let pi11 = document.createProcessingInstruction('target1', 'data1');
let pi12 = document.createProcessingInstruction('target2', 'data2');
let pi13 = document.createProcessingInstruction('target1', 'data1');
testing.expectEqual(true, pi11.isEqualNode(pi11));
testing.expectEqual(true, pi11.isEqualNode(pi13));
testing.expectEqual(false, pi11.isEqualNode(pi12));
testing.expectEqual(false, pi12.isEqualNode(pi13));
testing.expectEqual(false, pi11.isEqualNode(document));
testing.expectEqual(false, document.isEqualNode(pi11));
</script>

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=content><!-- hello world --><p>over 9000</p></div>
<script id="constructor">
let range = new Range();
testing.expectEqual(true, range instanceof Range);
testing.expectEqual(true, range instanceof AbstractRange);
// Test initial state - collapsed range
testing.expectEqual(true, range.collapsed);
testing.expectEqual(0, range.startOffset);
testing.expectEqual(0, range.endOffset);
testing.expectEqual(true, range.startContainer instanceof HTMLDocument);
testing.expectEqual(true, range.endContainer instanceof HTMLDocument);
</script>
<script id="createRange">
let docRange = document.createRange();
testing.expectEqual(true, docRange instanceof Range);
testing.expectEqual(true, docRange.collapsed);
</script>
<script id=textRange>
const container = $('#content');
const commentNode = container.childNodes[0];
testing.expectEqual(' hello world ', commentNode.nodeValue);
const textRange = document.createRange();
textRange.selectNodeContents(commentNode);
testing.expectEqual(0, textRange.startOffset);
testing.expectEqual(13, textRange.endOffset); // length of comment
</script>
<script id=nodeRange>
const nodeRange = document.createRange();
nodeRange.selectNodeContents(container);
testing.expectEqual(0, nodeRange.startOffset);
testing.expectEqual(2, nodeRange.endOffset); // length of container.childNodes
</script>

View File

@@ -0,0 +1,49 @@
<!DOCTYPE html>
<div id=conflict>node</div>
<script src="../testing.js"></script>
<script id=shadow_root>
const div1 = document.createElement('div');
let sr1 = div1.attachShadow({mode: 'open'});
testing.expectEqual(div1, sr1.host);
testing.expectEqual(sr1, div1.attachShadow({mode: 'open'}));
testing.expectEqual(sr1, div1.shadowRoot);
testing.expectError('Error: NotSupportedError', () => {
div1.attachShadow({mode: 'closed'});
});
sr1.append(document.createElement('div'));
sr1.append(document.createElement('span'));
testing.expectEqual(2, sr1.childElementCount);
// re-attaching clears it
testing.expectEqual(sr1, div1.attachShadow({mode: 'open'}));
testing.expectEqual(0, sr1.childElementCount);
const div2 = document.createElement('di2');
let sr2 = div2.attachShadow({mode: 'closed'});
testing.expectEqual(div2, sr2.host);
testing.expectEqual(null, div2.shadowRoot) // null when attached with 'closed'
testing.expectEqual(null, sr2.getElementById('conflict'));
const n1 = document.createElement('div');
n1.id = 'conflict';
sr2.append(n1);
testing.expectEqual(n1, sr2.getElementById('conflict'));
const acss = sr2.adoptedStyleSheets;
testing.expectEqual(0, acss.length);
acss.push(new CSSStyleSheet());
testing.expectEqual(1, acss.length);
sr1.innerHTML = '<p>hello</p>';
testing.expectEqual('<p>hello</p>', sr1.innerHTML);
testing.expectEqual('[object HTMLParagraphElement]', sr1.querySelector('*').toString());
sr1.innerHTML = null;
testing.expectEqual('', sr1.innerHTML);
testing.expectEqual(null, sr1.querySelector('*'));
</script>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<a id="link" href="foo" class="ok">OK</a>
<script src="../testing.js"></script>
<script id=text>
let t = new Text('foo');
testing.expectEqual('foo', t.data);
let emptyt = new Text();
testing.expectEqual('', emptyt.data);
let text = $('#link').firstChild;
testing.expectEqual('OK', text.wholeText);
text.data = 'OK modified';
let split = text.splitText('OK'.length);
testing.expectEqual(' modified', split.data);
testing.expectEqual('OK', text.data);
</script>

View File

@@ -0,0 +1,64 @@
<!DOCTYPE html>
<p id="para-empty" class="ok empty">
<script src="../testing.js"></script>
<script id=tokenList>
let gs = $('#para-empty');
let cl = gs.classList;
testing.expectEqual('ok empty', gs.className);
testing.expectEqual('ok empty', cl.value);
testing.expectEqual(2, cl.length);
gs.className = 'foo bar baz';
testing.expectEqual('foo bar baz', gs.className);
testing.expectEqual(3, cl.length);
gs.className = 'ok empty';
testing.expectEqual(2, cl.length);
let cl2 = gs.classList;
testing.expectEqual(2, cl2.length);
testing.expectEqual('ok', cl2.item(0));
testing.expectEqual('empty', cl2.item(1));
testing.expectEqual(true, cl2.contains('ok'));
testing.expectEqual(false, cl2.contains('nok'));
cl2.add('foo', 'bar', 'baz');
testing.expectEqual(5, cl2.length);
cl2.remove('foo', 'bar', 'baz');
testing.expectEqual(2, cl2.length);
let cl3 = gs.classList;
testing.expectEqual(false, cl3.toggle('ok'));
testing.expectEqual(true, cl3.toggle('ok'));
testing.expectEqual(2, cl3.length);
let cl4 = gs.classList;
testing.expectEqual(true, cl4.replace('ok', 'nok'));
testing.expectEqual("empty nok", cl4.value);
testing.expectEqual(true, cl4.replace('nok', 'ok'));
testing.expectEqual("empty ok", cl4.value);
let cl5 = gs.classList;
let keys = [...cl5.keys()];
testing.expectEqual(2, keys.length);
testing.expectEqual(0, keys[0]);
testing.expectEqual(1, keys[1]);
let values = [...cl5.values()];
testing.expectEqual(2, values.length);
testing.expectEqual('empty', values[0]);
testing.expectEqual('ok', values[1]);
let entries = [...cl5.entries()];
testing.expectEqual(2, entries.length);
testing.expectEqual([0, 'empty'], entries[0]);
testing.expectEqual([1, 'ok'], entries[1]);
let cl6 = gs.classList;
cl6.value = 'a b ccc';
testing.expectEqual('a b ccc', cl6.value);
testing.expectEqual('a b ccc', cl6.toString());
</script>

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="../testing.js"></script>
<script id=decoder>
let d1 = new TextDecoder();
testing.expectEqual('utf-8', d1.encoding);
testing.expectEqual(false, d1.fatal);
testing.expectEqual(false, d1.ignoreBOM);
testing.expectEqual('', d1.decode());
testing.expectEqual('𠮷', d1.decode(new Uint8Array([240, 160, 174, 183])));
testing.expectEqual('𠮷', d1.decode(new Uint8Array([0xEF, 0xBB, 0xBF, 240, 160, 174, 183])));
testing.expectEqual('<27>2', d1.decode(new Uint8Array([249, 50])));
{
const buffer = new ArrayBuffer(4);
const ints = new Uint8Array(buffer)
ints[0] = 240;
ints[1] = 160;
ints[2] = 174;
ints[3] = 183;
testing.expectEqual('𠮷', d1.decode(buffer));
}
{
const buffer = new ArrayBuffer(4);
const dv = new DataView(buffer);
dv.setUint8(0, 240);
dv.setUint8(1, 160);
dv.setUint8(2, 174);
dv.setUint8(3, 183);
testing.expectEqual('𠮷', d1.decode(dv));
}
let d2 = new TextDecoder('utf8', {fatal: true})
testing.expectError('Error: InvalidUtf8', () => {
let data = new Uint8Array([240, 240, 160, 174, 183]);
d2.decode(data);
});
</script>
<script id=stream>
let d3 = new TextDecoder();
testing.expectEqual('', d2.decode(new Uint8Array([226, 153]), { stream: true }));
testing.expectEqual('♥', d2.decode(new Uint8Array([165]), { stream: true }));
</script>
<script id=slice>
const buf1 = new ArrayBuffer(7);
const arr1 = new Uint8Array(buf1)
arr1[0] = 80;
arr1[1] = 81;
arr1[2] = 82;
arr1[3] = 83;
arr1[4] = 84;
arr1[5] = 85;
arr1[6] = 86;
testing.expectEqual('RST', d3.decode(new Uint8Array(buf1, 2, 3)));
</script>

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=encoder>
var encoder = new TextEncoder();
testing.expectEqual('utf-8', encoder.encoding);
testing.expectEqual([226, 130, 172], Array.from(encoder.encode('€')));
// Invalid utf-8 sequence.
// Browsers give a different result for this, they decode it to:
// 50, 50, 54, 44, 52, 48, 44, 49, 54, 49
testing.expectError('Error: InvalidUtf8', () => {
encoder.encode(new Uint8Array([0xE2,0x28,0xA1]));
});
</script>

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=noNata>
{
let event = new CompositionEvent("test", {});
testing.expectEqual(true, event instanceof CompositionEvent);
testing.expectEqual(true, event instanceof Event);
testing.expectEqual("test", event.type);
testing.expectEqual("", event.data);
}
</script>
<script id=withData>
{
let event = new CompositionEvent("test2", {data: "over 9000!"});
testing.expectEqual("test2", event.type);
testing.expectEqual("over 9000!", event.data);
}
</script>
<script id=dispatch>
{
let called = 0;
document.addEventListener('CE', (e) => {
testing.expectEqual('test-data', e.data);
testing.expectEqual(true, e instanceof CompositionEvent);
called += 1
});
document.dispatchEvent(new CompositionEvent('CE', {data: 'test-data'}));
testing.expectEqual(1, called);
}
</script>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=custom>
let capture = null;
const el = document.createElement('div');
el.addEventListener('c1', (e) => { capture = 'c1-' + new String(e.detail)});
el.addEventListener('c2', (e) => { capture = 'c2-' + new String(e.detail.over)});
el.dispatchEvent(new CustomEvent('c1'));
testing.expectEqual("c1-null", capture);
el.dispatchEvent(new CustomEvent('c1', {detail: '123'}));
testing.expectEqual("c1-123", capture);
el.dispatchEvent(new CustomEvent('c2', {detail: {over: 9000}}));
testing.expectEqual("c2-9000", capture);
let window_calls = 0;
window.addEventListener('c1', () => {
window_calls += 1;
});
el.dispatchEvent(new CustomEvent('c1', {bubbles: true}));
testing.expectEqual(1, window_calls);
</script>

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=content>
<p id="para"></p>
</div>
<script id=dispatch>
const startTime = new Event('x').timeStamp;
let content = $('#content');
// let para = document.getElementById('para');
var nb = 0;
var evt = null;
const incrementCallback = function(e) {
evt = e;
nb += 1;
e.preventDefault();
}
content.addEventListener('dispatch', incrementCallback);
content.dispatchEvent(new Event('dispatch', {bubbles: true, cancelable: true}));
testing.expectEqual(1, nb);
testing.expectEqual(content, evt.target);
testing.expectEqual(true, evt.bubbles);
testing.expectEqual(true, evt.cancelable);
testing.expectEqual(true, evt.defaultPrevented);
testing.expectEqual(true, evt.isTrusted);
testing.expectEqual(true, evt.timeStamp >= Math.floor(startTime));
</script>
<script id=propogate>
nb = 0;
let para = $('#para');
// the stop listener is capturing, so it propogates down
content.addEventListener('stop',function(e) {
e.stopPropagation();
nb += 1;
}, true)
para.addEventListener('stop',function(e) {
nb += 10;
});
para.dispatchEvent(new Event('stop'));
// didn't propogate down (because of capturing) to para handler
testing.expectEqual(1, nb);
</script>
<script id=immediate>
nb = 0;
content.addEventListener('immediate', function(e) {
e.stopImmediatePropagation();
nb += 1;
});
// the following event listener will not be invoked
content.addEventListener('immediate', function(e) {
nb += 10;
});
content.dispatchEvent(new Event('immediate'));
testing.expectEqual(1, nb);
</script>
<script id=legacy>
nb = 0;
content.addEventListener('legacy', incrementCallback);
let evtLegacy = document.createEvent('Event');
evtLegacy.initEvent('legacy');
content.dispatchEvent(evtLegacy);
testing.expectEqual(1, nb);
</script>
<script id=removeListener>
nb = 0;
document.addEventListener('count', incrementCallback);
document.removeEventListener('count', incrementCallback);
document.dispatchEvent(new Event('count'));
testing.expectEqual(0, nb);
</script>
<script id=once>
document.addEventListener('count', incrementCallback, {once: true});
document.dispatchEvent(new Event('count'));
document.dispatchEvent(new Event('count'));
document.dispatchEvent(new Event('count'));
testing.expectEqual(1, nb);
</script>
<script id=abortController>
nb = 0;
let ac = new AbortController()
document.addEventListener('count', incrementCallback, {signal: ac.signal})
document.dispatchEvent(new Event('count'));
document.dispatchEvent(new Event('count'));
ac.abort();
document.dispatchEvent(new Event('count'));
testing.expectEqual(2, nb);
document.removeEventListener('count', incrementCallback);
</script>
<script id=composedPath>
testing.expectEqual([], new Event('').composedPath());
let div1 = document.createElement('div');
let sr1 = div1.attachShadow({mode: 'open'});
sr1.innerHTML = "<p id=srp1></p>";
document.getElementsByTagName('body')[0].appendChild(div1);
let cp = null;
const shadowCallback = function(e) {
cp = e.composedPath().map((n) => n.id || n.nodeName || n.toString());
}
div1.addEventListener('click', shadowCallback);
sr1.getElementById('srp1').click();
testing.expectEqual(
['srp1', '#document-fragment', 'DIV', 'BODY', 'HTML', '#document', '[object Window]'],
cp
);
let div2 = document.createElement('div');
let sr2 = div2.attachShadow({mode: 'closed'});
sr2.innerHTML = "<p id=srp2></p>";
document.getElementsByTagName('body')[0].appendChild(div2);
cp = null;
div2.addEventListener('click', shadowCallback);
sr2.getElementById('srp2').click();
testing.expectEqual(
['DIV', 'BODY', 'HTML', '#document', '[object Window]'],
cp
);
</script>

View File

@@ -0,0 +1,88 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=default>
let event = new KeyboardEvent("test", { key: "a" });
testing.expectEqual(true, event instanceof KeyboardEvent);
testing.expectEqual(true, event instanceof Event);
testing.expectEqual("test", event.type);
testing.expectEqual("a", event.key);
testing.expectEqual(0, event.location);
testing.expectEqual(false, event.repeat);
testing.expectEqual(false, event.isComposing);
testing.expectEqual(false, event.ctrlKey);
testing.expectEqual(false, event.shiftKey);
testing.expectEqual(false, event.metaKey);
testing.expectEqual(false, event.altKey);
</script>
<script id=getModifierState>
event = new KeyboardEvent("test", {
altKey: true,
shiftKey: true,
metaKey: true,
ctrlKey: true,
});
testing.expectEqual(true, event.getModifierState("Alt"));
testing.expectEqual(true, event.getModifierState("AltGraph"));
testing.expectEqual(true, event.getModifierState("Control"));
testing.expectEqual(true, event.getModifierState("Shift"));
testing.expectEqual(true, event.getModifierState("Meta"));
testing.expectEqual(true, event.getModifierState("OS"));
testing.expectEqual(true, event.getModifierState("Accel"));
</script>
<script id=keyDownListener>
event = new KeyboardEvent("keydown", { key: "z" });
let isKeyDown = false;
document.addEventListener("keydown", (e) => {
isKeyDown = true;
testing.expectEqual(true, e instanceof KeyboardEvent);
testing.expectEqual(true, e instanceof Event);
testing.expectEqual("z", event.key);
});
document.dispatchEvent(event);
testing.expectEqual(true, isKeyDown);
</script>
<script id=keyUpListener>
event = new KeyboardEvent("keyup", { key: "x" });
let isKeyUp = false;
document.addEventListener("keyup", (e) => {
isKeyUp = true;
testing.expectEqual(true, e instanceof KeyboardEvent);
testing.expectEqual(true, e instanceof Event);
testing.expectEqual("x", event.key);
});
document.dispatchEvent(event);
testing.expectEqual(true, isKeyUp);
</script>
<script id=keyPressListener>
event = new KeyboardEvent("keypress", { key: "w" });
let isKeyPress = false;
document.addEventListener("keypress", (e) => {
isKeyPress = true;
testing.expectEqual(true, e instanceof KeyboardEvent);
testing.expectEqual(true, e instanceof Event);
testing.expectEqual("w", event.key);
});
document.dispatchEvent(event);
testing.expectEqual(true, isKeyPress);
</script>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=default>
let event = new MouseEvent('click');
testing.expectEqual('click', event.type);
testing.expectEqual(true, event instanceof MouseEvent);
testing.expectEqual(true, event instanceof Event);
testing.expectEqual(0, event.clientX);
testing.expectEqual(0, event.clientY);
testing.expectEqual(0, event.screenX);
testing.expectEqual(0, event.screenY);
</script>
<script id=parameters>
let new_event = new MouseEvent('click', { 'button': 0, 'clientX': 10, 'clientY': 20 });
testing.expectEqual(0, new_event.button);
testing.expectEqual(10, new_event.x);
testing.expectEqual(20, new_event.y);
testing.expectEqual(10, new_event.screenX);
testing.expectEqual(20, new_event.screenY);
</script>
<script id=listener>
let me = new MouseEvent('click');
testing.expectEqual(true, me instanceof Event);
var evt = null;
document.addEventListener('click', function (e) {
evt = e;
});
document.dispatchEvent(me);
testing.expectEqual('click', evt.type);
testing.expectEqual(true, evt instanceof MouseEvent);
</script>

View File

@@ -0,0 +1,34 @@
<script src="../testing.js"></script>
<script id=fetch type=module>
const promise1 = new Promise((resolve) => {
fetch('http://127.0.0.1:9582/xhr/json')
.then((res) => {
testing.expectEqual('cors', res.type);
return res.json()
})
.then((json) => {
resolve(json);
});
});
testing.async(promise1, (json) => {
testing.expectEqual({over: '9000!!!'}, json);
});
</script>
<script id=same-origin type=module>
const promise1 = new Promise((resolve) => {
fetch('http://localhost:9582/xhr/json')
.then((res) => {
testing.expectEqual('basic', res.type);
return res.json()
})
.then((json) => {
resolve(json);
});
});
testing.async(promise1, (json) => {
testing.expectEqual({over: '9000!!!'}, json);
});
</script>

View File

@@ -0,0 +1,102 @@
<script src="../testing.js"></script>
<script id=headers>
let headers = new Headers({"Set-Cookie": "name=world"});
testing.expectEqual("name=world", headers.get("set-cookie"));
let myHeaders = new Headers();
myHeaders.append("Content-Type", "image/jpeg"),
testing.expectEqual(false, myHeaders.has("Picture-Type"));
testing.expectEqual("image/jpeg", myHeaders.get("Content-Type"));
myHeaders.append("Content-Type", "image/png");
testing.expectEqual("image/jpeg, image/png", myHeaders.get("Content-Type"));
myHeaders.delete("Content-Type");
testing.expectEqual(null, myHeaders.get("Content-Type"));
myHeaders.set("Picture-Type", "image/svg")
testing.expectEqual("image/svg", myHeaders.get("Picture-Type"));
testing.expectEqual(true, myHeaders.has("Picture-Type"))
const originalHeaders = new Headers([["Content-Type", "application/json"], ["Authorization", "Bearer token123"]]);
testing.expectEqual("application/json", originalHeaders.get("Content-Type"));
testing.expectEqual("Bearer token123", originalHeaders.get("Authorization"));
const newHeaders = new Headers(originalHeaders);
testing.expectEqual("application/json", newHeaders.get("Content-Type"));
testing.expectEqual("Bearer token123" ,newHeaders.get("Authorization"));
testing.expectEqual(true ,newHeaders.has("Content-Type"));
testing.expectEqual(true ,newHeaders.has("Authorization"));
testing.expectEqual(false, newHeaders.has("X-Custom"));
newHeaders.set("X-Custom", "test-value");
testing.expectEqual("test-value", newHeaders.get("X-Custom"));
testing.expectEqual(null, originalHeaders.get("X-Custom"));
testing.expectEqual(false, originalHeaders.has("X-Custom"));
</script>
<script id=keys>
const testKeyHeaders = new Headers();
testKeyHeaders.set("Content-Type", "application/json");
testKeyHeaders.set("Authorization", "Bearer token123");
testKeyHeaders.set("X-Custom", "test-value");
const keys = [];
for (const key of testKeyHeaders.keys()) {
keys.push(key);
}
testing.expectEqual(3, keys.length);
testing.expectEqual(true, keys.includes("Content-Type"));
testing.expectEqual(true, keys.includes("Authorization"));
testing.expectEqual(true, keys.includes("X-Custom"));
</script>
<script id=values>
const testValuesHeaders = new Headers();
testValuesHeaders.set("Content-Type", "application/json");
testValuesHeaders.set("Authorization", "Bearer token123");
testValuesHeaders.set("X-Custom", "test-value");
const values = [];
for (const value of testValuesHeaders.values()) {
values.push(value);
}
testing.expectEqual(3, values.length);
testing.expectEqual(true, values.includes("application/json"));
testing.expectEqual(true, values.includes("Bearer token123"));
testing.expectEqual(true, values.includes("test-value"));
</script>
<script id=entries>
const testEntriesHeaders = new Headers();
testEntriesHeaders.set("Content-Type", "application/json");
testEntriesHeaders.set("Authorization", "Bearer token123");
testEntriesHeaders.set("X-Custom", "test-value");
const entries = [];
for (const entry of testEntriesHeaders.entries()) {
entries.push(entry);
}
testing.expectEqual(3, entries.length);
const entryMap = new Map(entries);
testing.expectEqual("application/json", entryMap.get("Content-Type"));
testing.expectEqual("Bearer token123", entryMap.get("Authorization"));
testing.expectEqual("test-value", entryMap.get("X-Custom"));
const entryKeys = Array.from(entryMap.keys());
testing.expectEqual(3, entryKeys.length);
testing.expectEqual(true, entryKeys.includes("Content-Type"));
testing.expectEqual(true, entryKeys.includes("Authorization"));
testing.expectEqual(true, entryKeys.includes("X-Custom"));
const entryValues = Array.from(entryMap.values());
testing.expectEqual(3, entryValues.length);
testing.expectEqual(true, entryValues.includes("application/json"));
testing.expectEqual(true, entryValues.includes("Bearer token123"));
testing.expectEqual(true, entryValues.includes("test-value"))
</script>

View File

@@ -0,0 +1,22 @@
<script src="../testing.js"></script>
<script id=request>
let request = new Request("flower.png");
testing.expectEqual("http://localhost:9582/src/tests/fetch/flower.png", request.url);
testing.expectEqual("GET", request.method);
let request2 = new Request("https://google.com", {
method: "POST",
body: "Hello, World",
cache: "reload",
credentials: "omit",
headers: { "Sender": "me", "Target": "you" }
}
);
testing.expectEqual("https://google.com", request2.url);
testing.expectEqual("POST", request2.method);
testing.expectEqual("omit", request2.credentials);
testing.expectEqual("reload", request2.cache);
testing.expectEqual("me", request2.headers.get("SeNdEr"));
testing.expectEqual("you", request2.headers.get("target"));
</script>

View File

@@ -0,0 +1,50 @@
<script src="../testing.js"></script>
<script id=response>
let response = new Response("Hello, World!");
testing.expectEqual(200, response.status);
testing.expectEqual("", response.statusText);
testing.expectEqual(true, response.ok);
testing.expectEqual("", response.url);
testing.expectEqual(false, response.redirected);
let response2 = new Response("Error occurred", {
status: 404,
statusText: "Not Found",
headers: {
"Content-Type": "text/plain",
"X-Custom": "test-value",
"Cache-Control": "no-cache"
}
});
testing.expectEqual(404, response2.status);
testing.expectEqual("Not Found", response2.statusText);
testing.expectEqual(false, response2.ok);
testing.expectEqual("text/plain", response2.headers.get("Content-Type"));
testing.expectEqual("test-value", response2.headers.get("X-Custom"));
testing.expectEqual("no-cache", response2.headers.get("cache-control"));
let response3 = new Response("Created", { status: 201, statusText: "Created" });
testing.expectEqual("basic", response3.type);
testing.expectEqual(201, response3.status);
testing.expectEqual("Created", response3.statusText);
testing.expectEqual(true, response3.ok);
let nullResponse = new Response(null);
testing.expectEqual(200, nullResponse.status);
testing.expectEqual("", nullResponse.statusText);
let emptyResponse = new Response("");
testing.expectEqual(200, emptyResponse.status);
</script>
<script id=json type=module>
const promise1 = new Promise((resolve) => {
let response = new Response('[]');
response.json().then(resolve)
});
testing.async(promise1, (json) => {
testing.expectEqual([], json);
});
</script>

View File

@@ -0,0 +1,125 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=Blob/Blob.text>
{
const parts = ["\r\nthe quick brown\rfo\rx\r", "\njumps over\r\nthe\nlazy\r", "\ndog"];
// "transparent" ending should not modify the final buffer.
const blob = new Blob(parts, { type: "text/html" });
const expected = parts.join("");
testing.expectEqual(expected.length, blob.size);
testing.expectEqual("text/html", blob.type);
testing.async(blob.text(), result => testing.expectEqual(expected, result));
}
{
const parts = ["\rhello\r", "\nwor\r\nld"];
// "native" ending should modify the final buffer.
const blob = new Blob(parts, { endings: "native" });
const expected = "\nhello\n\nwor\nld";
testing.expectEqual(expected.length, blob.size);
testing.async(blob.text(), result => testing.expectEqual(expected, result));
testing.async(blob.arrayBuffer(), result => testing.expectEqual(true, result instanceof ArrayBuffer));
}
</script>
<script id=Blob.stream>
{
const parts = ["may", "thy", "knife", "chip", "and", "shatter"];
const blob = new Blob(parts);
const reader = blob.stream().getReader();
testing.async(reader.read(), ({ done, value }) => {
const expected = new Uint8Array([109, 97, 121, 116, 104, 121, 107, 110,
105, 102, 101, 99, 104, 105, 112, 97,
110, 100, 115, 104, 97, 116, 116, 101,
114]);
testing.expectEqual(false, done);
testing.expectEqual(true, value instanceof Uint8Array);
testing.expectEqual(expected, value);
});
}
</script>
<script id=Blob.arrayBuffer/Blob.slice>
{
const parts = ["la", "symphonie", "des", "éclairs"];
const blob = new Blob(parts);
testing.async(blob.arrayBuffer(), result => testing.expectEqual(true, result instanceof ArrayBuffer));
let temp = blob.slice(0);
testing.expectEqual(blob.size, temp.size);
testing.async(temp.text(), result => {
testing.expectEqual("lasymphoniedeséclairs", result);
});
temp = blob.slice(-4, -2, "custom");
testing.expectEqual(2, temp.size);
testing.expectEqual("custom", temp.type);
testing.async(temp.text(), result => testing.expectEqual("ai", result));
temp = blob.slice(14);
testing.expectEqual(8, temp.size);
testing.async(temp.text(), result => testing.expectEqual("éclairs", result));
temp = blob.slice(6, -10, "text/eclair");
testing.expectEqual(6, temp.size);
testing.expectEqual("text/eclair", temp.type);
testing.async(temp.text(), result => testing.expectEqual("honied", result));
}
</script>
<!-- Firefox and Safari only -->
<script id=Blob.bytes>
{
const parts = ["light ", "panda ", "rocks ", "!"];
const blob = new Blob(parts);
testing.async(blob.bytes(), result => {
const expected = new Uint8Array([108, 105, 103, 104, 116, 32, 112, 97,
110, 100, 97, 32, 114, 111, 99, 107, 115,
32, 33]);
testing.expectEqual(true, result instanceof Uint8Array);
testing.expectEqual(expected, result);
});
}
// Test for SIMD.
{
const parts = [
"\rThe opened package\r\nof potato\nchi\rps",
"held the\r\nanswer to the\r mystery. Both det\rectives looke\r\rd\r",
"\rat it but failed to realize\nit was\r\nthe\rkey\r\n",
"\r\nto solve the \rcrime.\r"
];
const blob = new Blob(parts, { type: "text/html", endings: "native" });
testing.expectEqual(161, blob.size);
testing.expectEqual("text/html", blob.type);
testing.async(blob.bytes(), result => {
const expected = new Uint8Array([10, 84, 104, 101, 32, 111, 112, 101, 110,
101, 100, 32, 112, 97, 99, 107, 97, 103,
101, 10, 111, 102, 32, 112, 111, 116, 97,
116, 111, 10, 99, 104, 105, 10, 112, 115,
104, 101, 108, 100, 32, 116, 104, 101, 10,
97, 110, 115, 119, 101, 114, 32, 116, 111,
32, 116, 104, 101, 10, 32, 109, 121, 115,
116, 101, 114, 121, 46, 32, 66, 111, 116,
104, 32, 100, 101, 116, 10, 101, 99, 116,
105, 118, 101, 115, 32, 108, 111, 111, 107,
101, 10, 10, 100, 10, 10, 97, 116, 32, 105,
116, 32, 98, 117, 116, 32, 102, 97, 105, 108,
101, 100, 32, 116, 111, 32, 114, 101, 97,
108, 105, 122, 101, 10, 105, 116, 32, 119, 97,
115, 10, 116, 104, 101, 10, 107, 101, 121,
10, 10, 116, 111, 32, 115, 111, 108, 118, 101,
32, 116, 104, 101, 32, 10, 99, 114, 105, 109,
101, 46, 10]);
testing.expectEqual(true, result instanceof Uint8Array);
testing.expectEqual(expected, result);
});
}
</script>

View File

@@ -0,0 +1,7 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=file>
let f = new File();
testing.expectEqual(true, f instanceof File);
</script>

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=abortController>
var a1 = new AbortController();
var s1 = a1.signal;
testing.expectEqual(undefined, s1.throwIfAborted());
testing.expectEqual(undefined, s1.reason);
let target;;
let called = 0;
s1.addEventListener('abort', (e) => {
called += 1;
target = e.target;
});
a1.abort();
testing.expectEqual(true, s1.aborted)
testing.expectEqual(s1, target)
testing.expectEqual('AbortError', s1.reason)
testing.expectEqual(1, called)
</script>
<script id=abort>
var s2 = AbortSignal.abort('over 9000');
testing.expectEqual(true, s2.aborted);
testing.expectEqual('over 9000', s2.reason);
testing.expectEqual('AbortError', AbortSignal.abort().reason);
</script>
<script id=timeout>
var s3 = AbortSignal.timeout(10);
testing.eventually(() => {
testing.expectEqual(true, s3.aborted);
testing.expectEqual('TimeoutError', s3.reason);
testing.expectError('Error: TimeoutError', () => {
s3.throwIfAborted()
});
});
</script>

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=canvas>
{
const element = document.createElement("canvas");
const ctx = element.getContext("2d");
testing.expectEqual(true, ctx instanceof CanvasRenderingContext2D);
// We can't really test this but let's try to call it at least.
ctx.fillRect(0, 0, 0, 0);
}
</script>
<script id=canvas#fillStyle>
{
const element = document.createElement("canvas");
const ctx = element.getContext("2d");
// Black by default.
testing.expectEqual(ctx.fillStyle, "#000000");
ctx.fillStyle = "red";
testing.expectEqual(ctx.fillStyle, "#ff0000");
ctx.fillStyle = "rebeccapurple";
testing.expectEqual(ctx.fillStyle, "#663399");
// No changes made if color is invalid.
ctx.fillStyle = "invalid-color";
testing.expectEqual(ctx.fillStyle, "#663399");
}
</script>

View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=x data-power="over 9000" data-empty data-some-long-key=ok></div>
<script id=dataset>
let el1 = document.createElement('div');
testing.expectEqual(undefined, el1.dataset.x);
el1.dataset.x = '123';
testing.expectEqual(true, delete el1.dataset.x);
testing.expectEqual(undefined, el1.dataset.x);
// yes, this is right
testing.expectEqual(true, delete el1.dataset.other);
let ds1 = el1.dataset;
ds1.helloWorld = 'yes';
testing.expectEqual('yes', el1.getAttribute('data-hello-world'));
el1.setAttribute('data-this-will-work', 'positive');
testing.expectEqual('positive', ds1.thisWillWork);
</script>
<script id=element>
let div = $('#x');
testing.expectEqual(undefined, div.dataset.nope);
testing.expectEqual('over 9000', div.dataset.power);
testing.expectEqual('', div.dataset.empty);
testing.expectEqual('ok', div.dataset.someLongKey);
testing.expectEqual(true, delete div.dataset.power);
testing.expectEqual(undefined, div.dataset.power);
</script>

View File

@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<body>
<div id=content><a id=link href=#></a></div>
</body>
</html>
<script src="../testing.js"></script>
<script id=document>
testing.expectEqual('HTMLDocument', document.__proto__.constructor.name);
testing.expectEqual('Document', document.__proto__.__proto__.constructor.name);
testing.expectEqual('body', document.body.localName);
testing.expectEqual('localhost:9582', document.domain);
testing.expectEqual('', document.referrer);
testing.expectEqual('', document.title);
testing.expectEqual('body', document.body.localName);
testing.expectEqual('head', document.head.localName);
testing.expectEqual(0, document.images.length);
testing.expectEqual(0, document.embeds.length);
testing.expectEqual(0, document.plugins.length);
testing.expectEqual(2, document.scripts.length);
testing.expectEqual(0, document.forms.length);
testing.expectEqual(1, document.links.length);
testing.expectEqual(0, document.applets.length);
testing.expectEqual(0, document.anchors.length);
testing.expectEqual(7, document.all.length);
testing.expectEqual('document', document.currentScript.id);
document.title = 'foo';
testing.expectEqual('foo', document.title);
document.title = '';
document.getElementById('link').setAttribute('name', 'foo');
let list = document.getElementsByName('foo');
testing.expectEqual(1, list.length);
testing.expectEqual('', document.cookie);
document.cookie = 'name=Oeschger;';
document.cookie = 'favorite_food=tripe;';
testing.expectEqual('name=Oeschger; favorite_food=tripe', document.cookie);
// "" should be returned, but the framework overrules it atm
document.cookie = 'IgnoreMy=Ghost; HttpOnly';
testing.expectEqual('name=Oeschger; favorite_food=tripe', document.cookie);
// Return null since we only return elements when they have previously been localized
testing.expectEqual(null, document.elementFromPoint(2.5, 2.5));
testing.expectEqual([], document.elementsFromPoint(2.5, 2.5));
let div1 = document.createElement('div');
document.body.appendChild(div1);
div1.getClientRects(); // clal this to position it
testing.expectEqual('[object HTMLDivElement]', document.elementFromPoint(2.5, 2.5).toString());
let elems = document.elementsFromPoint(2.5, 2.5);
testing.expectEqual(3, elems.length);
testing.expectEqual('[object HTMLDivElement]', elems[0].toString());
testing.expectEqual('[object HTMLBodyElement]', elems[1].toString());
testing.expectEqual('[object HTMLHtmlElement]', elems[2].toString());
let a = document.createElement('a');
a.href = "https://lightpanda.io";
document.body.appendChild(a);
// Note this will be placed after the div of previous test
a.getClientRects();
let a_again = document.elementFromPoint(7.5, 0.5);
testing.expectEqual('[object HTMLAnchorElement]', a_again.toString());
testing.expectEqual('https://lightpanda.io', a_again.href);
let a_agains = document.elementsFromPoint(7.5, 0.5);
testing.expectEqual('https://lightpanda.io', a_agains[0].href);
testing.expectEqual(true, !document.all);
testing.expectEqual(false, !!document.all);
testing.expectEqual('[object HTMLScriptElement]', document.all(5).toString());
testing.expectEqual('[object HTMLDivElement]', document.all('content').toString());
testing.expectEqual(document, document.defaultView.document );
testing.expectEqual('loading', document.readyState);
</script>

View File

@@ -0,0 +1,53 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=content>a<strong>b</strong>cc</div>
<script id=inner>
const content = $('#content');
testing.expectEqual('a<strong>b</strong>cc', content.innerHTML);
testing.expectEqual('abcc', content.innerText);
content. innerText = 'foo';
testing.expectEqual('foo', content.innerHTML);
testing.expectEqual('foo', content.innerText);
</script>
<script id=addEventListene>
let click_count = 0;
content.addEventListener('click', function() { click_count++ });
content.click()
testing.expectEqual(1, click_count);
</script>
<script id=style>
let style = content.style;
style.cssText = 'color: red; font-size: 12px; margin: 5px !important';
testing.expectEqual(3, style.length);
style.setProperty('background-color', 'blue')
testing.expectEqual('blue', style.getPropertyValue('background-color'));
testing.expectEqual(4, style.length);
</script>
<script id=a>
let a = document.createElement('a');
testing.expectEqual('', a.href);
testing.expectEqual('', a.host);
a.href = 'about';
testing.expectEqual('http://localhost:9582/src/tests/html/about', a.href);
</script>
<script id=focus>
// detached node cannot be focused
const focused = document.activeElement;
document.createElement('a').focus();
testing.expectEqual(focused, document.activeElement);
</script>
<script id=link>
let l2 = document.createElement('link');
testing.expectEqual('', l2.href);
l2.href = 'https://lightpanda.io/opensource-browser/15';
testing.expectEqual('https://lightpanda.io/opensource-browser/15', l2.href);
l2.href = '/over/9000';
testing.expectEqual('http://localhost:9582/over/9000', l2.href);
</script>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=ErrorEvent>
let e1 = new ErrorEvent('err1')
testing.expectEqual('', e1.message);
testing.expectEqual('', e1.filename);
testing.expectEqual(0, e1.lineno);
testing.expectEqual(0, e1.colno);
testing.expectEqual(undefined, e1.error);
let e2 = new ErrorEvent('err1', {
message: 'm1',
filename: 'fx19',
lineno: 443,
colno: 8999,
error: 'under 9000!',
});
testing.expectEqual('m1', e2.message);
testing.expectEqual('fx19', e2.filename);
testing.expectEqual(443, e2.lineno);
testing.expectEqual(8999, e2.colno);
testing.expectEqual('under 9000!', e2.error);
</script>

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=history>
testing.expectEqual('auto', history.scrollRestoration);
history.scrollRestoration = 'manual';
testing.expectEqual('manual', history.scrollRestoration);
history.scrollRestoration = 'auto';
testing.expectEqual('auto', history.scrollRestoration);
testing.expectEqual(null, history.state)
history.pushState({ testInProgress: true }, null, 'http://127.0.0.1:9582/src/tests/html/history/history_after_nav.html');
testing.expectEqual({ testInProgress: true }, history.state);
history.pushState({ testInProgress: false }, null, 'http://127.0.0.1:9582/xhr/json');
history.replaceState({ "new": "field", testComplete: true }, null);
let state = { "new": "field", testComplete: true };
testing.expectEqual(state, history.state);
let popstateEventFired = false;
let popstateEventState = null;
window.addEventListener('popstate', (event) => {
popstateEventFired = true;
popstateEventState = event.state;
});
testing.eventually(() => {
testing.expectEqual(true, popstateEventFired);
testing.expectEqual(state, popstateEventState);
})
history.back();
</script>

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=history2>
history.pushState(
{"new": "field", testComplete: true },
null,
'http://127.0.0.1:9582/src/tests/html/history/history_after_nav.html'
);
let popstateEventFired = false;
let popstateEventState = null;
// uses the window event listener.
window.onpopstate = (event) => {
popstateEventFired = true;
popstateEventState = event.state;
};
testing.eventually(() => {
testing.expectEqual(true, popstateEventFired);
testing.expectEqual(true, popstateEventState.testComplete);
})
history.back();
</script>

View File

@@ -0,0 +1,6 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=history2>
testing.expectEqual(true, history.state && history.state.testInProgress);
</script>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=image>
img = new Image();
testing.expectEqual(0, img.width);
testing.expectEqual(0, img.height);
img = new Image(4);
testing.expectEqual(4, img.width);
testing.expectEqual(0, img.height);
img = new Image(5, 6);
testing.expectEqual(5, img.width);
testing.expectEqual(6, img.height);
let fruit = new Image
testing.expectEqual(0, fruit.width);
fruit.width = 5;
testing.expectEqual(5, fruit.width);
fruit.width = '15';
testing.expectEqual(15, fruit.width);
fruit.width = 'apple';
testing.expectEqual(0, fruit.width);
let lyric = new Image
testing.expectEqual('', lyric.src);
lyric.src = 'okay';
testing.expectEqual('okay', lyric.src);
lyric.src = 15;
testing.expectEqual('15', lyric.src);
</script>

View File

@@ -0,0 +1,111 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<form action="test.php" target="_blank" id=form>
<p>
<label>First name: <input type="text" name="first-name" id=input /></label>
</p>
</form>
<script id=input_properties>
let input = document.createElement('input');
testing.expectEqual(null, input.form);
input.form = 'foo';
testing.expectEqual(null, input.form);
testing.expectEqual('', input.name);
input.name = 'leto';
testing.expectEqual('leto', input.name);
testing.expectEqual('', input.accept);
input.accept = 'anything';
testing.expectEqual('anything', input.accept);
testing.expectEqual('', input.alt);
input.alt = 'x1';
testing.expectEqual('x1', input.alt);
testing.expectEqual(false, input.disabled);
input.disabled = true;
testing.expectEqual(true, input.disabled);
input.disabled = false;
testing.expectEqual(false, input.disabled);
testing.expectEqual(false, input.readOnly);
input.readOnly = true;
testing.expectEqual(true, input.readOnly);
input.readOnly = false;
testing.expectEqual(false, input.readOnly);
testing.expectEqual(-1, input.maxLength);
input.maxLength = 5;
testing.expectEqual(5, input.maxLength);
input.maxLength = 'banana';
testing.expectEqual(0, input.maxLength);
testing.expectError('Error: NegativeValueNotAllowed', () => { input.maxLength = -45;});
testing.expectEqual(20, input.size);
input.size = 5;
testing.expectEqual(5, input.size);
input.size = -449;
testing.expectEqual(20, input.size);
testing.expectError('Error: ZeroNotAllowed', () => { input.size = 0; });
testing.expectEqual('', input.src);
input.src = 'foo'
testing.expectEqual('http://localhost:9582/src/tests/html/foo', input.src);
input.src = '-3'
testing.expectEqual('http://localhost:9582/src/tests/html/-3', input.src);
input.src = ''
testing.expectEqual('http://localhost:9582/src/tests/html/input.html', input.src);
testing.expectEqual('text', input.type);
input.type = 'checkbox';
testing.expectEqual('checkbox', input.type);
input.type = '5';
testing.expectEqual('text', input.type);
</script>
<script id=related>
let input_checked = document.createElement('input')
testing.expectEqual(false, input_checked.defaultChecked);
testing.expectEqual(false, input_checked.checked);
input_checked.defaultChecked = true;
testing.expectEqual(true, input_checked.defaultChecked);
testing.expectEqual(true, input_checked.checked);
input_checked.checked = false;
testing.expectEqual(true, input_checked.defaultChecked);
testing.expectEqual(false, input_checked.checked);
input_checked.defaultChecked = true;
testing.expectEqual(false, input_checked.checked);
</script>
<script id=defaultValue>
testing.expectEqual('', input.defaultValue);
testing.expectEqual('', input.value);
input.defaultValue = 3.1;
testing.expectEqual('3.1', input.defaultValue);
testing.expectEqual('3.1', input.value)
input.value = 'mango';
testing.expectEqual('3.1', input.defaultValue);
testing.expectEqual('mango', input.value);
input.defaultValue = true;
testing.expectEqual('mango', input.value);
</script>
<script id=form>
const form = $('#form');
input = $('#input');
testing.expectEqual(form, input.form);
// invalid
input.form = 'foo';
testing.expectEqual(form, input.form);
</script>

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<a id=link href=foo>OK</a>
<script id=link>
let link = $('#link');
testing.expectEqual('', link.target);
link.target = '_blank';
testing.expectEqual('_blank', link.target);
link.target = '';
testing.expectEqual('foo', link.href);
link.href = 'https://lightpanda.io/';
testing.expectEqual('https://lightpanda.io/', link.href);
testing.expectEqual('https://lightpanda.io', link.origin);
link.host = 'lightpanda.io:443';
testing.expectEqual('lightpanda.io', link.host);
testing.expectEqual('', link.port);
testing.expectEqual('lightpanda.io', link.hostname);
link.host = 'lightpanda.io';
testing.expectEqual('lightpanda.io', link.host);
testing.expectEqual('', link.port);
testing.expectEqual('lightpanda.io', link.hostname);
testing.expectEqual('lightpanda.io', link.host);
testing.expectEqual('lightpanda.io', link.hostname);
link.hostname = 'foo.bar';
testing.expectEqual('https://foo.bar/', link.href);
testing.expectEqual('', link.search);
link.search = 'q=bar';
testing.expectEqual('?q=bar', link.search);
testing.expectEqual('https://foo.bar/?q=bar', link.href);
testing.expectEqual('', link.hash);
link.hash = 'frag';
testing.expectEqual('#frag', link.hash);
testing.expectEqual('https://foo.bar/?q=bar#frag', link.href);
testing.expectEqual('', link.port);
link.port = '443';
testing.expectEqual('foo.bar', link.host);
testing.expectEqual('foo.bar', link.hostname);
testing.expectEqual('https://foo.bar/?q=bar#frag', link.href);
link.port = null;
testing.expectEqual('https://foo.bar/?q=bar#frag', link.href);
testing.expectEqual('foo', link.href = 'foo');
testing.expectEqual('', link.type);
link.type = 'text/html';
testing.expectEqual('text/html', link.type);
testing.expectEqual('OK', link.text);
link.text = 'foo';
testing.expectEqual('foo', link.text);
</script>

View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=location>
testing.expectEqual('http://localhost:9582/src/tests/html/location.html', location.href);
testing.expectEqual('http://localhost:9582/src/tests/html/location.html', document.location.href);
testing.expectEqual("localhost:9582", location.host);
testing.expectEqual("localhost", location.hostname);
testing.expectEqual("http://localhost:9582", location.origin);
testing.expectEqual("/src/tests/html/location.html", location.pathname);
testing.expectEqual("", location.hash);
testing.expectEqual("9582", location.port);
testing.expectEqual("", location.search);
</script>
<script id=location_hash>
location.hash = "";
testing.expectEqual("", location.hash);
testing.expectEqual('http://localhost:9582/src/tests/html/location.html', location.href);
location.hash = "#abcdef";
testing.expectEqual("#abcdef", location.hash);
testing.expectEqual('http://localhost:9582/src/tests/html/location.html#abcdef', location.href);
location.hash = "xyzxyz";
testing.expectEqual("#xyzxyz", location.hash);
testing.expectEqual('http://localhost:9582/src/tests/html/location.html#xyzxyz', location.href);
location.hash = "";
testing.expectEqual("", location.hash);
testing.expectEqual('http://localhost:9582/src/tests/html/location.html', location.href);
</script>

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=navigation>
testing.expectEqual('object', typeof navigation);
testing.expectEqual('object', typeof navigation.currentEntry);
testing.expectEqual('string', typeof navigation.currentEntry.id);
testing.expectEqual('string', typeof navigation.currentEntry.key);
testing.expectEqual('string', typeof navigation.currentEntry.url);
const currentIndex = navigation.currentEntry.index;
navigation.navigate(
'http://localhost:9582/src/tests/html/navigation/navigation2.html',
{ state: { currentIndex: currentIndex, navTestInProgress: true } }
);
</script>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=navigation2>
const state = navigation.currentEntry.getState();
testing.expectEqual(true, state.navTestInProgress);
testing.expectEqual(state.currentIndex + 1, navigation.currentEntry.index);
</script>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=navigation_currententrychange>
let currentEntryChanged = false;
navigation.addEventListener("currententrychange", () => {
currentEntryChanged = true;
});
// Doesn't fully navigate if same document.
location.href = location.href + "#1";
testing.expectEqual(true, currentEntryChanged);
</script>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=navigator>
testing.expectEqual('Lightpanda/1.0', navigator.userAgent);
testing.expectEqual('1.0', navigator.appVersion);
testing.expectEqual('en-US', navigator.language);
</script>

View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=screen>
let screen = window.screen;
testing.expectEqual(1920, screen.width);
testing.expectEqual(1080, screen.height);
let orientation = screen.orientation;
testing.expectEqual(0, orientation.angle);
testing.expectEqual('landscape-primary', orientation.type);
// this shouldn't crash (it used to)
screen.addEventListener('change', () => {});
</script>
<script id=orientation>
screen.orientation.addEventListener('change', () => {})
// above shouldn't crash (it used to)
testing.skip();
</script>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=dynamic_import type=module>
const promise1 = new Promise((resolve) => {
Promise.all([
import('./import.js'),
import('./import.js'),
import('./import.js'),
import('./import.js'),
import('./import.js'),
import('./import.js'),
import('./import2.js'),
import('./import.js'),
import('./import.js'),
]).then(resolve);
});
testing.async(promise1, (res) => {
testing.expectEqual(9, res.length);
testing.expectEqual('hello', res[0].greeting);
testing.expectEqual('hello', res[1].greeting);
testing.expectEqual('hello', res[2].greeting);
testing.expectEqual('hello', res[3].greeting);
testing.expectEqual('hello', res[4].greeting);
testing.expectEqual('hello', res[5].greeting);
testing.expectEqual('world', res[6].greeting);
testing.expectEqual('hello', res[7].greeting);
testing.expectEqual('hello', res[8].greeting);
});
</script>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=import type=module>
import * as im from './import.js';
testing.expectEqual('hello', im.greeting);
</script>
<script id=cached type=module>
// hopefully cached, who knows, no real way to assert this
// but at least it works.
import * as im from './import.js';
testing.expectEqual('hello', im.greeting);
</script>

View File

@@ -0,0 +1,2 @@
let greeting = 'hello';
export {greeting as 'greeting'};

View File

@@ -0,0 +1,2 @@
let greeting = 'world';
export {greeting as 'greeting'};

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script type=importmap>
{
"imports": {
"core": "./import.js"
}
}
</script>
<script id=use_importmap type=module>
import * as im from 'core';
testing.expectEqual('hello', im.greeting);
</script>
<script id=cached_importmap type=module>
// hopefully cached, who knows, no real way to assert this
// but at least it works.
import * as im from 'core';
testing.expectEqual('hello', im.greeting);
</script>

View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<head>
<script>
let dyn1_loaded = 0;
function loadScript(src) {
const script = document.createElement('script');
script.src = src;
document.getElementsByTagName("head")[0].appendChild(script)
}
</script>
</head>
<script src="../../testing.js"></script>
<script defer>
loadScript('inline_defer.js');
</script>
<script async>
loadScript('inline_defer.js');
</script>
<script id=inline_defer>
// inline script should ignore defer and async attributes. If we don't do
// this correctly, we'd end up in an infinite loop
// https://github.com/lightpanda-io/browser/issues/1014
testing.eventually(() => testing.expectEqual(2, dyn1_loaded));
</script>

View File

@@ -0,0 +1 @@
dyn1_loaded += 1;

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script defer id="remote_defer" src="order_defer.js"></script>
<script defer id="remote_async" src="order_async.js"></script>
<script type=module id="inline_module">
// inline module is always deferred.
list += 'g';
testing.expectEqual('abcdefg', list);
</script>
<script>
var list = '';
</script>
<script id="remote" src="order.js"></script>
<script async id="inline_async">
// inline script ignore async
list += 'b';
testing.expectEqual('ab', list);
</script>
<script defer id="inline_defer">
// inline script ignore defer
list += 'c';
testing.expectEqual('abc', list);
</script>
<script id="default">
// simple inline script
list += 'd';
testing.expectEqual('abcd', list);
</script>

View File

@@ -0,0 +1,2 @@
list += 'a';
testing.expectEqual('a', list);

View File

@@ -0,0 +1,3 @@
list += 'f';
testing.expectEqual('abcdef', list);

View File

@@ -0,0 +1,2 @@
list += 'e';
testing.expectEqual('abcde', list);

View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="../../testing.js"></script>
<script id=script>
let script = document.createElement('script')
script.src = 'foo.bar';
script.async = true;
testing.expectEqual(true, script.async);
script.async = false;
testing.expectEqual(false, script.async);
script.defer = true;
testing.expectEqual(true, script.defer);
testing.expectEqual('', script.nonce);
script.nonce = 'hello';
testing.expectEqual('hello', script.nonce);
</script>
<script id=datauri src="data:text/plain;charset=utf-8;base64,dGVzdGluZy5leHBlY3RFcXVhbCh0cnVlLCB0cnVlKTs="></script>

View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<form id=f1>
<select id=s1 name=s1><option>o1<option>o2</select>
</form>
<select id=s2></select>
<script id=select>
const s = document.getElementById('s1');
testing.expectEqual('[object HTMLFormElement]', s.form.toString());
testing.expectEqual(null, document.getElementById('s2').form);
testing.expectEqual(false, s.disabled);
s.disabled = true;
testing.expectEqual(true, s.disabled);
s.disabled = false;
testing.expectEqual(false, s.disabled);
testing.expectEqual(false, s.multiple);
s.multiple = true;
testing.expectEqual(true, s.multiple);
s.multiple = false;
testing.expectEqual(false, s.multiple);
testing.expectEqual('s1', s.name);
s.name = 'sel1';
testing.expectEqual('sel1', s.name);
testing.expectEqual(2, s.length);
testing.expectEqual(0, s.selectedIndex);
s.selectedIndex = 2; // out of range
testing.expectEqual(-1, s.selectedIndex);
s.selectedIndex = -1;
testing.expectEqual(-1, s.selectedIndex);
s.selectedIndex = 0;
testing.expectEqual(0, s.selectedIndex);
s.selectedIndex = 1;
testing.expectEqual(1, s.selectedIndex);
s.selectedIndex = -323;
testing.expectEqual(-1, s.selectedIndex);
let options = s.options;
testing.expectEqual(2, options.length);
testing.expectEqual('o2', options.item(1).value);
testing.expectEqual(-1, options.selectedIndex);
let o3 = document.createElement('option');
o3.value = 'o3';
options.add(o3)
testing.expectEqual(3, options.length);
testing.expectEqual('o3', options[2].value);
testing.expectEqual('o3', options.item(2).value);
let o4 = document.createElement('option');
o4.value = 'o4';
options.add(o4, 1);
testing.expectEqual(4, options.length);
testing.expectEqual('o4', options.item(1).value);
let o5 = document.createElement('option');
o5.value = 'o5';
options.add(o5, o3)
testing.expectEqual(5, options.length);
testing.expectEqual('o5', options.item(3).value);
options.remove(3)
testing.expectEqual(4, options.length);
testing.expectEqual('o3', options[3].value);
testing.expectEqual('o3', options.item(3).value);
testing.expectEqual(undefined, options[10]);
testing.expectEqual(null, options.item(10));
</script>

View File

@@ -0,0 +1,179 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script>
class LightPanda extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
const slot1 = document.createElement('slot');
slot1.name = 'slot-1';
shadow.appendChild(slot1);
switch (this.getAttribute('mode')) {
case '1':
slot1.innerHTML = 'hello';
break;
case '2':
const slot2 = document.createElement('slot');
shadow.appendChild(slot2);
break;
}
}
}
window.customElements.define("lp-test", LightPanda);
</script>
<lp-test id=lp1 mode=1></lp-test>
<lp-test id=lp2 mode=0></lp-test>
<lp-test id=lp3 mode=0>default</lp-test>
<lp-test id=lp4 mode=1><p slot=other>default</p></lp-test>
<lp-test id=lp5 mode=1><p slot=slot-1>default</p> xx <b slot=slot-1>other</b></lp-test>
<lp-test id=lp6 mode=2>More <p slot=slot-1>default2</p> <span>!!</span></lp-test>
<script>
function assertNodes(expected, actual) {
actual = actual.map((n) => n.id || n.textContent)
testing.expectEqual(expected, actual);
}
</script>
<script id=HTMLSlotElement>
for (let idx of [1, 2, 3, 4]) {
const lp = $(`#lp${idx}`);
const slot = lp.shadowRoot.querySelector('slot');
assertNodes([], slot.assignedNodes());
assertNodes([], slot.assignedNodes({}));
assertNodes([], slot.assignedNodes({flatten: false}));
if (lp.getAttribute('mode') === '1') {
assertNodes(['hello'], slot.assignedNodes({flatten: true}));
} else {
assertNodes([], slot.assignedNodes({flatten: true}));
}
}
{
const lp5 = $('#lp5');
const s5 = lp5.shadowRoot.querySelector('slot');
assertNodes(['default', 'other'], s5.assignedNodes());
const lp6 = $('#lp6');
const s6 = lp6.shadowRoot.querySelectorAll('slot');
assertNodes(['default2'], s6[0].assignedNodes({}));
assertNodes(['default2'], s6[0].assignedNodes({flatten: true}));
assertNodes(['More ', ' ', '!!'], s6[1].assignedNodes({}));
assertNodes(['More ', ' ', '!!'], s6[1].assignedNodes({flatten: true}));
assertNodes(['default2'], s6[0].assignedElements({}));
assertNodes(['default2'], s6[0].assignedElements({flatten: true}));
assertNodes(['!!'], s6[1].assignedElements({}));
assertNodes(['!!'], s6[1].assignedElements({flatten: true}));
}
</script>
<lp-test id=sc1 mode=1></lp-test>
<script id=slotChange1>
{
let calls = 0;
const lp = $('#sc1');
const slot = lp.shadowRoot.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
assertNodes(['slotted'], slot.assignedNodes({}));
calls += 1
}, {});
const div = document.createElement('div');
div.textContent = 'Hello!';
div.id = 'slotted';
testing.expectEqual(null, div.assignedSlot);
div.setAttribute('slot', 'slot-1');
lp.appendChild(div);
testing.expectEqual(slot, div.assignedSlot);
testing.eventually(() => {
testing.expectEqual(1, calls)
});
}
</script>
<lp-test id=sc2 mode=1><div id=s2 slot=slot-1>hello</div></lp-test>
<script id=slotChange2>
{
let calls = 0;
const lp = $('#sc2');
const slot = lp.shadowRoot.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
assertNodes([], slot.assignedNodes({}));
calls += 1;
});
const div = $('#s2');
div.removeAttribute('slot');
testing.eventually(() => {
testing.expectEqual(1, calls)
});
}
</script>
<lp-test id=sc3 mode=1><div id=s3 slot=slot-1>hello</div></lp-test>
<script id=slotChange3>
{
let calls = 0;
const lp = $('#sc3');
const slot = lp.shadowRoot.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
assertNodes([], slot.assignedNodes({}));
calls += 1;
});
const div = $('#s3');
div.slot = 'other';
testing.eventually(() => {
testing.expectEqual(1, calls)
});
}
</script>
<lp-test id=sc4 mode=1></lp-test>
<script id=slotChange4>
{
let calls = 0;
const lp = $('#sc4');
const slot = lp.shadowRoot.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
assertNodes(['slotted'], slot.assignedNodes({}));
calls += 1;
});
const div = document.createElement('div');
div.id = 'slotted';
div.slot = 'other';
lp.appendChild(div);
div.slot = 'slot-1'
testing.eventually(() => {
testing.expectEqual(1, calls)
});
}
</script>
<lp-test id=sc5 mode=1><div id=s5 slot=slot-1>hello</div></lp-test>
<script id=slotChange5>
{
let calls = 0;
const lp = $('#sc5');
const slot = lp.shadowRoot.querySelector('slot');
slot.addEventListener('slotchange', (e) => {
assertNodes([], slot.assignedNodes({}));
calls += 1;
});
$('#s5').remove();
testing.eventually(() => {
testing.expectEqual(1, calls)
});
}
</script>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=style>
let s = document.createElement('style');
testing.expectEqual('text/css', s.sheet.type);
testing.expectEqual(false, document.createElement('style').sheet == s.sheet);
</script>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<svg id=lower width="200" height="100" style="border:1px solid #ccc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
<rect></rect>
<text x="100" y="95" font-size="14" text-anchor="middle">OVER 9000!!</text>
</svg>
<SVG ID=UPPER WIDTH="200" HEIGHT="100" STYLE="BORDER:1PX SOLID #CCC" XMLNS="http://www.w3.org/2000/svg" VIEWBOX="0 0 200 100">
<RECT></RECT>
<TEXT X="100" Y="95" FONT-SIZE="14" TEXT-ANCHOR="MIDDLE">OVER 9000!!!</TEXT>
</SVG>
<script id=svg>
testing.expectEqual(false, 'AString' instanceof SVGElement);
const svg1 = $('#lower');
testing.expectEqual('http://www.w3.org/2000/svg', svg1.getAttribute('xmlns'));
testing.expectEqual('http://www.w3.org/2000/svg', svg1.getAttributeNode('xmlns').value);
testing.expectEqual('http://www.w3.org/2000/svg', svg1.attributes.getNamedItem('xmlns').value);
testing.expectEqual('0 0 200 100', svg1.getAttribute('viewBox'));
testing.expectEqual('viewBox', svg1.getAttributeNode('viewBox').name);
testing.expectEqual(true, svg1.outerHTML.includes('viewBox'));
testing.expectEqual('svg', svg1.tagName);
testing.expectEqual('rect', svg1.querySelector('rect').tagName);
testing.expectEqual('text', svg1.querySelector('text').tagName);
const svg2 = $('#UPPER');
testing.expectEqual('http://www.w3.org/2000/svg', svg2.getAttribute('xmlns'));
testing.expectEqual('http://www.w3.org/2000/svg', svg2.getAttributeNode('xmlns').value);
testing.expectEqual('http://www.w3.org/2000/svg', svg2.attributes.getNamedItem('xmlns').value);
testing.expectEqual('0 0 200 100', svg2.getAttribute('viewBox'));
testing.expectEqual('viewBox', svg2.getAttributeNode('viewBox').name);
testing.expectEqual(true, svg2.outerHTML.includes('viewBox'));
testing.expectEqual('svg', svg2.tagName);
testing.expectEqual('rect', svg2.querySelector('rect').tagName);
testing.expectEqual('text', svg2.querySelector('text').tagName);
</script>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=c></div>
<script id=template>
let t = document.createElement('template');
let d = document.createElement('div');
d.id = 'abc';
t.content.append(d);
testing.expectEqual(null, document.getElementById('abc'));
document.getElementById('c').appendChild(t.content.cloneNode(true));
testing.expectEqual('abc', document.getElementById('abc').id);
t.innerHTML = '<span>over</span><p>9000!</p>';
testing.expectEqual(2, t.content.childNodes.length);
testing.expectEqual('SPAN', t.content.childNodes[0].tagName);
testing.expectEqual('over', t.content.childNodes[0].innerHTML);
testing.expectEqual('P', t.content.childNodes[1].tagName);
testing.expectEqual('9000!', t.content.childNodes[1].innerHTML);
</script>
<template id="hello"><p>hello, world</p></template>
<script id=template_parsing>
const tt = document.getElementById('hello');
testing.expectEqual('<p>hello, world</p>', tt.innerHTML);
// > The Node.childNodes property of the <template> element is always empty
// https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/template#usage_notes
testing.expectEqual(0, tt.childNodes.length);
let out = document.createElement('div');
out.appendChild(tt.content.cloneNode(true));
testing.expectEqual('<p>hello, world</p>', out.innerHTML);
</script>

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<div id=main></div>
<script id=webcomponents>
class LightPanda extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.append('connected');
}
}
window.customElements.define("lightpanda-test", LightPanda);
const main = document.getElementById('main');
main.appendChild(document.createElement('lightpanda-test'));
testing.expectEqual('<lightpanda-test>connected</lightpanda-test>', main.innerHTML)
testing.expectEqual('[object DataSet]', document.createElement('lightpanda-test').dataset.toString());
testing.expectEqual('[object DataSet]', document.createElement('lightpanda-test.x').dataset.toString());
</script>

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=localstorage>
testing.expectEqual(0, localStorage.length);
testing.expectEqual(null, localStorage.getItem('foo'));
testing.expectEqual(null, localStorage.key(0));
localStorage.setItem('foo', 'bar');
testing.expectEqual(1, localStorage.length)
testing.expectEqual('bar', localStorage.getItem('foo'));
testing.expectEqual('bar', localStorage.key(0));
testing.expectEqual(null, localStorage.key(1));
localStorage.removeItem('foo');
testing.expectEqual(0, localStorage.length)
testing.expectEqual(null, localStorage.getItem('foo'));
localStorage['foo'] = 'bar';
testing.expectEqual(1, localStorage.length);
testing.expectEqual('bar', localStorage['foo']);
localStorage.setItem('a', '1');
localStorage.setItem('b', '2');
localStorage.setItem('c', '3');
testing.expectEqual(4, localStorage.length)
localStorage.clear();
testing.expectEqual(0, localStorage.length)
</script>

View File

@@ -0,0 +1,134 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=readable_stream>
const stream = new ReadableStream({
start(controller) {
controller.enqueue("hello");
controller.enqueue("world");
controller.close();
}
});
const reader = stream.getReader();
testing.async(reader.read(), (data) => {
testing.expectEqual("hello", data.value);
testing.expectEqual(false, data.done);
});
</script>
<script id=readable_stream_binary>
const input = new TextEncoder().encode('over 9000!');
const binStream = new ReadableStream({
start(controller) {
controller.enqueue(input);
controller.enqueue("world");
controller.close();
}
});
testing.async(binStream.getReader().read(), (data) => {
testing.expectEqual(input, data.value);
testing.expectEqual(false, data.done);
});
</script>
<script id=readable_stream_close>
var closeResult;
const stream1 = new ReadableStream({
start(controller) {
controller.enqueue("first");
controller.enqueue("second");
controller.close();
}
});
const reader1 = stream1.getReader();
testing.async(reader1.read(), (data) => {
testing.expectEqual("first", data.value);
testing.expectEqual(false, data.done);
});
testing.async(reader1.read(), (data) => {
testing.expectEqual("second", data.value);
testing.expectEqual(false, data.done);
});
testing.async(reader1.read(), (data) => {
testing.expectEqual(undefined, data.value);
testing.expectEqual(true, data.done);
});
</script>
<script id=readable_stream_cancel>
var readResult;
var cancelResult;
var closeResult;
const stream2 = new ReadableStream({
start(controller) {
controller.enqueue("data1");
controller.enqueue("data2");
controller.enqueue("data3");
},
cancel(reason) {
closeResult = `Stream cancelled: ${reason}`;
}
});
const reader2 = stream2.getReader();
testing.async(reader2.read(), (data) => {
testing.expectEqual("data1", data.value);
testing.expectEqual(false, data.done);
});
testing.async(reader2.cancel("user requested"), (result) => {
testing.expectEqual(undefined, result);
testing.expectEqual("Stream cancelled: user requested", closeResult);
});
</script>
<script id=readable_stream_cancel_no_reason>
var closeResult2;
const stream3 = new ReadableStream({
start(controller) {
controller.enqueue("test");
},
cancel(reason) {
closeResult2 = reason === undefined ? "no reason" : reason;
}
});
const reader3 = stream3.getReader();
testing.async(reader3.cancel(), (result) => {
testing.expectEqual(undefined, result);
testing.expectEqual("no reason", closeResult2);
});
</script>
<script id=readable_stream_read_after_cancel>
var readAfterCancelResult;
const stream4 = new ReadableStream({
start(controller) {
controller.enqueue("before_cancel");
},
});
const reader4 = stream4.getReader();
testing.async(reader4.cancel("test cancel"), (cancelResult) => {
testing.expectEqual(undefined, cancelResult);
});
testing.async(reader4.read(), (data) => {
testing.expectEqual(undefined, data.value);
testing.expectEqual(true, data.done);
});
</script>

View File

@@ -0,0 +1,206 @@
// Note: this code tries to make sure that we don't fail to execute a <script>
// block without reporting an error. In other words, if the test passes, you
// should be confident that the code actually ran.
// We do a couple things to ensure this.
// 1 - We make sure that ever script with an id has at least 1 assertion called
// 2 - We add an onerror handler to every script and, on error, fail.
//
// This is pretty straightforward, with the only complexity coming from "eventually"
// assertions, which are assertions we lazily check in `getStatus()`. We
// do this because, by the time `getStatus()`, `page.wait()` will have been called
// and any timer (setTimeout, requestAnimation, MutationObserver, etc...) will
// have been evaluated. Test which use/test these behavior will use `eventually`.
(() => {
function expectEqual(expected, actual) {
_recordExecution();
if (_equal(expected, actual)) {
return;
}
testing._status = 'fail';
let msg = `expected: ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`;
console.warn(
`id: ${testing._captured?.script_id || document.currentScript.id}`,
`msg: ${msg}`,
`stack: ${testing._captured?.stack || new Error().stack}`,
);
}
function expectError(expected, fn) {
withError((err) => {
expectEqual(expected, err.toString());
}, fn);
}
function withError(cb, fn) {
try{
fn();
} catch (err) {
cb(err);
return;
}
expectEqual('an error', null);
}
function skip() {
_recordExecution();
}
// Should only be called by the test runner
function assertOk() {
// if we're already in a fail state, return fail, nothing can recover this
if (testing._status === 'fail') {
throw new Error('Failed');
}
// run any eventually's that we've captured
for (const ev of testing._eventually) {
testing._captured = ev[1];
ev[0]();
testing._captured = null;
}
// Again, if we're in a fail state, we can immediately fail
if (testing._status === 'fail') {
throw new Error('Failed');
}
// make sure that any <script id=xyz></script> tags we have have had at least
// 1 assertion. This helps ensure that if a script tag fails to execute,
// we'll report an error, even if no assertions failed.
const scripts = document.getElementsByTagName('script');
for (script of scripts) {
const id = script.id;
if (!id) {
continue;
}
if (!testing._executed_scripts.has(id)) {
console.warn(`Failed to execute any expectations for <script id="${id}">...</script>`);
throw new Error('Failed');
}
}
if (testing._status != 'ok') {
throw new Error(testing._status);
}
}
// Set expectations to happen at some point in the future. Necessary for
// testing callbacks which will only be executed after page.wait is called.
function eventually(fn) {
// capture the current state (script id, stack) so that, when we do run this
// we can display more meaningful details on failure.
testing._eventually.push([fn, {
script_id: document.currentScript.id,
stack: new Error().stack,
}]);
_registerErrorCallback();
}
async function async(promise, cb) {
const script_id = document.currentScript ? document.currentScript.id : '<script id is unavailable in browsers>';
const stack = new Error().stack;
this._captured = {script_id: script_id, stack: stack};
const value = await promise;
// reset it, because await promise could change it.
this._captured = {script_id: script_id, stack: stack};
cb(value);
this._captured = null;
}
function _recordExecution() {
if (testing._status === 'fail') {
return;
}
testing._status = 'ok';
if (testing._captured || document.currentScript) {
const script_id = testing._captured?.script_id || document.currentScript.id;
testing._executed_scripts.add(script_id);
_registerErrorCallback();
}
}
// We want to attach an onError callback to each <script>, so that we can
// properly fail it.
function _registerErrorCallback() {
const script = document.currentScript;
if (!script) {
// can be null if we're executing an eventually assertion, but that's ok
// because the errorCallback would have been registered for this script
// already
return;
}
if (script.onerror) {
// already registered
return;
}
script.onerror = function(err, b) {
testing._status = 'fail';
console.warn(
`id: ${script.id}`,
`msg: There was an error executing the <script id=${script.id}>...</script>.\n There should be a eval error printed above this.`,
);
}
}
function _equal(a, b) {
if (a === b) {
return true;
}
if (a === null || b === null) {
return false;
}
if (typeof a !== 'object' || typeof b !== 'object') {
return false;
}
if (Object.keys(a).length != Object.keys(b).length) {
return false;
}
for (property in a) {
if (b.hasOwnProperty(property) === false) {
return false;
}
if (_equal(a[property], b[property]) === false) {
return false;
}
}
return true;
}
window.testing = {
_status: 'empty',
_eventually: [],
_executed_scripts: new Set(),
_captured: null,
skip: skip,
async: async,
assertOk: assertOk,
eventually: eventually,
expectEqual: expectEqual,
expectError: expectError,
withError: withError,
};
// Helper, so you can do $(sel) in a test
window.$ = function(sel) {
return document.querySelector(sel);
}
// Helper, so you can do $$(sel) in a test
window.$$ = function(sel) {
return document.querySelectorAll(sel);
}
if (!console.lp) {
// make this work in the browser
console.lp = console.log;
}
})();

View File

@@ -0,0 +1,109 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=url>
var url = new URL('https://foo.bar/path?query#fragment');
testing.expectEqual("https://foo.bar", url.origin);
testing.expectEqual("https://foo.bar/path?query#fragment", url.href);
testing.expectEqual("https:", url.protocol);
testing.expectEqual("", url.username);
testing.expectEqual("", url.password);
testing.expectEqual("foo.bar", url.host);
testing.expectEqual("foo.bar", url.hostname);
testing.expectEqual("", url.port);
testing.expectEqual("/path", url.pathname);
testing.expectEqual("?query", url.search);
testing.expectEqual("#fragment", url.hash);
testing.expectEqual("", url.searchParams.get('query'));
url.search = 'hello=world';
testing.expectEqual(1, url.searchParams.size);
testing.expectEqual("world", url.searchParams.get('hello'));
url.search = '?over=9000';
testing.expectEqual(1, url.searchParams.size);
testing.expectEqual("9000", url.searchParams.get('over'));
url.search = '';
testing.expectEqual(0, url.searchParams.size);
const url2 = new URL(url);
testing.expectEqual("https://foo.bar/path#fragment", url2.href);
</script>
<script id="constructor">
testing.expectError("TypeError: invalid argument", () => {
new URL(document.createElement('a'));
});
let a = document.createElement('a');
a.href = 'https://www.lightpanda.io/over?9000=!!';
const url3 = new URL(a);
testing.expectEqual("https://www.lightpanda.io/over?9000=%21%21", url3.href);
</script>
<script id=searchParams>
url = new URL('https://foo.bar/path?a=~&b=%7E#fragment');
testing.expectEqual("~", url.searchParams.get('a'));
testing.expectEqual("~", url.searchParams.get('b'));
url.searchParams.append('c', 'foo');
testing.expectEqual("foo", url.searchParams.get('c'));
testing.expectEqual(1, url.searchParams.getAll('c').length);
testing.expectEqual("foo", url.searchParams.getAll('c')[0]);
testing.expectEqual(3, url.searchParams.size);
// search is dynamic
testing.expectEqual("?a=~&b=~&c=foo", url.search);
// href is dynamic
testing.expectEqual("https://foo.bar/path?a=~&b=~&c=foo#fragment", url.href);
url.searchParams.delete('c', 'foo');
testing.expectEqual(null, url.searchParams.get('c'));
url.searchParams.delete('a');
testing.expectEqual(null, url.searchParams.get('a'));
</script>
<script id=searchParamsSetHref>
url = new URL("https://foo.bar");
const searchParams = url.searchParams;
// SearchParams should be empty.
testing.expectEqual(0, searchParams.size);
url.href = "https://lightpanda.io?over=9000&light=panda";
// It won't hurt to check href and host too.
testing.expectEqual("https://lightpanda.io/?over=9000&light=panda", url.href);
testing.expectEqual("lightpanda.io", url.host);
// SearchParams should be updated too when URL is set.
testing.expectEqual(2, searchParams.size);
testing.expectEqual("9000", searchParams.get("over"));
testing.expectEqual("panda", searchParams.get("light"));
</script>
<script id=base>
url = new URL('over?9000', 'https://lightpanda.io');
testing.expectEqual("https://lightpanda.io/over?9000", url.href);
</script>
<script id="svelkit">
let sk = new URL('sveltekit-internal://');
testing.expectEqual("sveltekit-internal:", sk.protocol);
testing.expectEqual("", sk.host);
testing.expectEqual("", sk.hostname);
testing.expectEqual("sveltekit-internal://", sk.href);
</script>
<script id=invalidUrl>
testing.expectError("Error: Invalid", () => {
_ = new URL("://foo.bar/path?query#fragment");
});
</script>
<script id=URL.canParse>
testing.expectEqual(true, URL.canParse("https://lightpanda.io"));
testing.expectEqual(false, URL.canParse("://lightpanda.io"));
testing.expectEqual(true, URL.canParse("/home", "https://lightpanda.io"));
testing.expectEqual(false, URL.canParse("lightpanda.io", "https"));
</script>

View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=url_search_params>
let usp = new URLSearchParams();
usp.get('a')
testing.expectEqual(false, usp.has('a'));
testing.expectEqual([], usp.getAll('a'));
usp.delete('a');
usp.set('a', 1);
testing.expectEqual(true, usp.has('a'));
testing.expectEqual("1", usp.get('a'));
testing.expectEqual(["1"], usp.getAll('a'));
usp.append('a', 2);
testing.expectEqual(true, usp.has('a'));
testing.expectEqual("1", usp.get('a'));
testing.expectEqual(['1','2'], usp.getAll('a'));
usp.append('b', '3');
testing.expectEqual(true, usp.has('a'));
testing.expectEqual("1", usp.get('a'));
testing.expectEqual(['1','2'], usp.getAll('a'));
testing.expectEqual(true, usp.has('b'));
testing.expectEqual("3", usp.get('b'));
testing.expectEqual(['3'], usp.getAll('b'));
let acc = [];
for (const key of usp.keys()) { acc.push(key) };
testing.expectEqual(['a', 'a', 'b'], acc);
acc = [];
for (const value of usp.values()) { acc.push(value) };
testing.expectEqual(['1', '2', '3'], acc);
acc = [];
for (const entry of usp.entries()) { acc.push(entry) };
testing.expectEqual([['a', '1'], ['a', '2'], ['b', '3']], acc);
acc = [];
for (const entry of usp) { acc.push(entry) };
testing.expectEqual([['a', '1'], ['a', '2'], ['b', '3']], acc);
usp.delete('a');
testing.expectEqual(false, usp.has('a'));
testing.expectEqual(true, usp.has('b'));
acc = [];
for (const key of usp.keys()) { acc.push(key) };
testing.expectEqual(['b'], acc);
acc = [];
for (const value of usp.values()) { acc.push(value) };
testing.expectEqual(['3'], acc);
acc = [];
for (const entry of usp.entries()) { acc.push(entry) };
testing.expectEqual([['b', '3']], acc);
acc = [];
for (const entry of usp) { acc.push(entry) };
testing.expectEqual([['b', '3']], acc);
</script>
<script id=parsed>
usp = new URLSearchParams('?hello');
testing.expectEqual('', usp.get('hello'));
usp = new URLSearchParams('?abc=');
testing.expectEqual('', usp.get('abc'));
usp = new URLSearchParams('?abc=123&');
testing.expectEqual('123', usp.get('abc'));
testing.expectEqual(1, usp.size);
var fd = new FormData();
fd.append('a', '1');
fd.append('a', '2');
fd.append('b', '3');
ups = new URLSearchParams(fd);
testing.expectEqual(3, ups.size);
testing.expectEqual(['1', '2'], ups.getAll('a'));
testing.expectEqual(['3'], ups.getAll('b'));
fd.delete('a'); // the two aren't linked, it created a copy
testing.expectEqual(3, ups.size);
ups = new URLSearchParams({over: 9000, spice: 'flow'});
testing.expectEqual(2, ups.size);
testing.expectEqual(['9000'], ups.getAll('over'));
testing.expectEqual(['flow'], ups.getAll('spice'));
</script>

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<body>
<iframe src="https://httpbin.io/html" title="iframea"></iframe>
<iframe src="https://httpbin.io/html" title="iframeb"></iframe>
</body>
<script id=frames>
testing.expectEqual(2, frames.length);
testing.expectEqual(undefined, frames[3])
testing.expectError('Error: TODO', () => { frames[1] });
</script>

View File

@@ -0,0 +1,167 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<body style=height:4000px;width:4000px></body>
<script id=aliases>
testing.expectEqual(window, window.self);
testing.expectEqual(window, window.parent);
testing.expectEqual(window, window.top);
testing.expectEqual(window, window.frames);
testing.expectEqual(0, window.frames.length);
</script>
<script id=request_animation>
let start = 0;
function step(timestamp) {
start = timestamp;
}
requestAnimationFrame(step);
testing.eventually(() => testing.expectEqual(true, start > 0));
let request_id = requestAnimationFrame(() => {
start = 0;
});
cancelAnimationFrame(request_id);
testing.eventually(() => testing.expectEqual(true, start > 0));
</script>
<script id=dimensions>
testing.expectEqual(5, innerHeight);
// Width is 5 even if there are no elements
testing.expectEqual(5, innerWidth);
let div1 = document.createElement('div');
document.body.appendChild(div1);
div1.getClientRects()
let div2 = document.createElement('div');
document.body.appendChild(div2);
div2.getClientRects();
testing.expectEqual(5, innerHeight);
testing.expectEqual(10, innerWidth);
</script>
<script id=setTimeout>
let longCall = false;
window.setTimeout(() => {longCall = true}, 5001);
testing.eventually(() => testing.expectEqual(false, longCall));
let wst1 = 0;
window.setTimeout(() => {wst1 += 1}, 1);
testing.eventually(() => testing.expectEqual(1, wst1));
let wst2 = 1;
window.setTimeout((a, b) => {wst2 = a + b}, 1, 2, 3);
testing.eventually(() => testing.expectEqual(5, wst2));
</script>
<script id=eventTarget>
let called = false;
window.addEventListener("ready", (e) => {
called = (e.currentTarget == window);
}, {capture: false, once: false});
const evt = new Event("ready", { bubbles: true, cancelable: false });
window.dispatchEvent(evt);
testing.expectEqual(true, called);
</script>
<script id=btoa_atob>
const b64 = btoa('https://ziglang.org/documentation/master/std/#std.base64.Base64Decoder')
testing.expectEqual('aHR0cHM6Ly96aWdsYW5nLm9yZy9kb2N1bWVudGF0aW9uL21hc3Rlci9zdGQvI3N0ZC5iYXNlNjQuQmFzZTY0RGVjb2Rlcg==', b64);
const str = atob(b64)
testing.expectEqual('https://ziglang.org/documentation/master/std/#std.base64.Base64Decoder', str);
testing.expectError('Error: InvalidCharacterError', () => {
atob('b');
});
</script>
<script id=scroll>
let scroll = false;
let scrollend = false
window.addEventListener('scroll', () => {scroll = true});
document.addEventListener('scrollend', () => {scrollend = true});
window.scrollTo(0, 0);
testing.expectEqual(0, scrollX);
testing.expectEqual(0, pageXOffset);
testing.expectEqual(0, scrollY);
testing.expectEqual(0, pageYOffset);
testing.expectEqual(true, scroll);
testing.expectEqual(true, scrollend);
window.scrollTo(10, 20);
testing.expectEqual(10, scrollX);
testing.expectEqual(10, pageXOffset);
testing.expectEqual(20, scrollY);
testing.expectEqual(20, pageYOffset);
window.scrollTo(-10, -20);
testing.expectEqual(0, scrollX);
testing.expectEqual(0, pageXOffset);
testing.expectEqual(0, scrollY);
testing.expectEqual(0, pageYOffset);
window.scrollTo({top: 30, left: 40});
testing.expectEqual(40, scrollX);
testing.expectEqual(40, pageXOffset);
testing.expectEqual(30, scrollY);
testing.expectEqual(30, pageYOffset);
window.scrollTo({top: -30, left: -40});
testing.expectEqual(0, scrollX);
testing.expectEqual(0, pageXOffset);
testing.expectEqual(0, scrollY);
testing.expectEqual(0, pageYOffset);
</script>
<script id=queueMicroTask>
var qm = false;
window.queueMicrotask(() => {qm = true });
testing.eventually(() => testing.expectEqual(true, qm));
</script>
<script id=DOMContentLoaded>
let dcl = false;
window.queueMicrotask(() => {qm = true });
window.addEventListener('DOMContentLoaded', (e) => {
dcl = e.target == document;
});
testing.eventually(() => testing.expectEqual(true, dcl));
</script>
<script id=window.onload>
let isWindowTarget = false;
const callback = (e) => isWindowTarget = e.target === window;
// Callback is not set yet.
testing.expectEqual(null, window.onload);
// Setting an object.
window.onload = {};
testing.expectEqual(null, window.onload);
// Callback is set.
window.onload = callback;
testing.expectEqual(callback, window.onload);
testing.eventually(() => testing.expectEqual(true, isWindowTarget));
</script>
<script id=reportError>
let errorEventFired = false;
let capturedError = null;
window.addEventListener('error', (e) => {
errorEventFired = true;
capturedError = e.error;
});
const testError = new Error('Test error message');
window.reportError(testError);
testing.expectEqual(true, errorEventFired);
testing.expectEqual(testError, capturedError);
</script>

View File

@@ -0,0 +1,130 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=formData>
let f = new FormData();
testing.expectEqual(null, f.get('a'));
testing.expectEqual(false, f.has('a'));
testing.expectEqual([], f.getAll('a'));
testing.expectEqual(undefined, f.delete('a'));
f.set('a', 1);
testing.expectEqual(true, f.has('a'));
testing.expectEqual('1', f.get('a'));
testing.expectEqual(['1'], f.getAll('a'));
f.append('a', 2);
testing.expectEqual(true, f.has('a'));
testing.expectEqual('1', f.get('a'));
testing.expectEqual(['1', '2'], f.getAll('a'));
f.append('b', '3');
testing.expectEqual(true, f.has('a'));
testing.expectEqual('1', f.get('a'));
testing.expectEqual(['1', '2'], f.getAll('a'));
testing.expectEqual(true, f.has('b'));
testing.expectEqual('3', f.get('b'));
testing.expectEqual(['3'], f.getAll('b'));
let acc = [];
for (const key of f.keys()) { acc.push(key) }
testing.expectEqual(['a', 'a', 'b'], acc);
acc = [];
for (const value of f.values()) { acc.push(value) }
testing.expectEqual(['1', '2', '3'], acc);
acc = [];
for (const entry of f.entries()) { acc.push(entry) }
testing.expectEqual([['a', '1'], ['a', '2'], ['b', '3']], acc);
acc = [];
for (const entry of f) { acc.push(entry) };
testing.expectEqual([['a', '1'], ['a', '2'], ['b', '3']], acc);
f.delete('a');
testing.expectEqual(false, f.has('a'));
testing.expectEqual(true, f.has('b'));
acc = [];
for (const key of f.keys()) { acc.push(key) }
testing.expectEqual(['b'], acc);
acc = [];
for (const value of f.values()) { acc.push(value) }
testing.expectEqual(['3'], acc);
acc = [];
for (const entry of f.entries()) { acc.push(entry) }
testing.expectEqual([['b', '3']], acc);
acc = [];
for (const entry of f) { acc.push(entry) }
testing.expectEqual([['b', '3']], acc);
</script>
<script id=serialize>
let form1 = $('#form1');
let submit1 = $('#s1');
let input = document.createElement('input');
input.name = 'dyn';
input.value = 'dyn-v';
form1.appendChild(input);
let f2 = new FormData(form1, submit1);
acc = [];
for (const entry of f2) {
acc.push(entry);
};
testing.expectEqual(['txt-1', 'txt-1-v'], acc[0]);
testing.expectEqual(['txt-2', 'txt-~-v'], acc[1]);
testing.expectEqual(['chk-3', 'chk-3-vb'], acc[2]);
testing.expectEqual(['chk-3', 'chk-3-vc'], acc[3]);
testing.expectEqual(['rdi-1', 'rdi-1-vc'], acc[4]);
testing.expectEqual(['ta-1', ' ta-1-v'], acc[5]);
testing.expectEqual(['ta', ''], acc[6]);
testing.expectEqual(['h1', 'h1-v'], acc[7]);
testing.expectEqual(['sel-1', 'blue'], acc[8]);
testing.expectEqual(['sel-2', 'sel-2-v'], acc[9]);
testing.expectEqual(['mlt-2', 'water'], acc[10]);
testing.expectEqual(['mlt-2', 'tea'], acc[11]);
testing.expectEqual(['s1', 's1-v'], acc[12]);
testing.expectEqual(['dyn', 'dyn-v'], acc[13]);
</script>
<form id="form1">
<input id="has_no_name" value="nope1">
<input id="is_disabled" disabled value="nope2">
<input name="txt-1" value="txt-1-v">
<input name="txt-2" value="txt-~-v" type=password>
<input name="chk-3" value="chk-3-va" type=checkbox>
<input name="chk-3" value="chk-3-vb" type=checkbox checked>
<input name="chk-3" value="chk-3-vc" type=checkbox checked>
<input name="chk-4" value="chk-4-va" type=checkbox>
<input name="chk-4" value="chk-4-va" type=checkbox>
<input name="rdi-1" value="rdi-1-va" type=radio>
<input name="rdi-1" value="rdi-1-vb" type=radio>
<input name="rdi-1" value="rdi-1-vc" type=radio checked>
<input name="rdi-2" value="rdi-2-va" type=radio>
<input name="rdi-2" value="rdi-2-vb" type=radio>
<textarea name="ta-1"> ta-1-v</textarea>
<textarea name="ta"></textarea>
<input type=hidden name=h1 value="h1-v">
<input type=hidden name=h2 value="h2-v" disabled=disabled>
<select name="sel-1"><option>blue<option>red</select>
<select name="sel-2"><option>blue<option value=sel-2-v selected>red</select>
<select name="sel-3"><option disabled>nope1<option>nope2</select>
<select name="mlt-1" multiple><option>water<option>tea</select>
<select name="mlt-2" multiple><option selected>water<option selected>tea<option>coffee</select>
<input type=submit id=s1 name=s1 value=s1-v>
<input type=submit name=s2 value=s2-v>
<input type=image name=i1 value=i1-v>
</form>
<input type=text name=abc value=123 form=form1>

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=progressEvent>
let pevt = new ProgressEvent('foo');
testing.expectEqual(0, pevt.loaded);
testing.expectEqual(true, pevt instanceof ProgressEvent);
var eevt = null;
function ccbk(event) {
eevt = event;
}
document.addEventListener('foo', ccbk)
document.dispatchEvent(pevt);
testing.expectEqual('foo', eevt.type);
testing.expectEqual(true, eevt instanceof ProgressEvent);
</script>

View File

@@ -0,0 +1,110 @@
<!DOCTYPE html>
<script src="../testing.js"></script>
<script id=xhr type=module>
const req = new XMLHttpRequest();
const promise1 = new Promise((resolve) => {
function cbk(event) {
resolve(event)
}
req.onload = cbk;
testing.expectEqual(cbk, req.onload);
req.onload = cbk;
req.open('GET', 'http://127.0.0.1:9582/xhr');
testing.expectEqual(0, req.status);
testing.expectEqual('', req.statusText);
testing.expectEqual('', req.getAllResponseHeaders());
testing.expectEqual(null, req.getResponseHeader('Content-Type'));
testing.expectEqual('', req.responseText);
req.send();
});
testing.async(promise1, (event) => {
testing.expectEqual('load', event.type);
testing.expectEqual(true, event.loaded > 0);
testing.expectEqual(true, event instanceof ProgressEvent);
testing.expectEqual(200, req.status);
testing.expectEqual('OK', req.statusText);
testing.expectEqual('text/html; charset=utf-8', req.getResponseHeader('Content-Type'));
testing.expectEqual('content-length: 100\r\nContent-Type: text/html; charset=utf-8\r\n', req.getAllResponseHeaders());
testing.expectEqual(100, req.responseText.length);
testing.expectEqual(req.responseText.length, req.response.length);
testing.expectEqual(true, req.responseXML instanceof Document);
});
</script>
<script id=xhr2 type=module>
const req2 = new XMLHttpRequest()
const promise2 = new Promise((resolve) => {
req2.onload = resolve;
req2.open('GET', 'http://127.0.0.1:9582/xhr')
req2.responseType = 'document';
req2.send()
});
testing.async(promise2, () => {
testing.expectEqual(200, req2.status);
testing.expectEqual('OK', req2.statusText);
testing.expectEqual(true, req2.response instanceof Document);
testing.expectEqual(true, req2.responseXML instanceof Document);
});
</script>
<script id=xhr3 type=module>
const req3 = new XMLHttpRequest()
const promise3 = new Promise((resolve) => {
req3.onload = resolve;
req3.open('GET', 'http://127.0.0.1:9582/xhr/json')
req3.responseType = 'json';
req3.send()
});
testing.async(promise3, () => {
testing.expectEqual(200, req3.status);
testing.expectEqual('OK', req3.statusText);
testing.expectEqual('9000!!!', req3.response.over);
});
</script>
<script id=xhr4 type=module>
const req4 = new XMLHttpRequest()
const promise4 = new Promise((resolve) => {
req4.onload = resolve;
req4.open('POST', 'http://127.0.0.1:9582/xhr')
req4.send('foo')
});
testing.async(promise4, () => {
testing.expectEqual(200, req4.status);
testing.expectEqual('OK', req4.statusText);
testing.expectEqual(true, req4.responseText.length > 64);
});
</script>
<script id=xhr5 type=module>
const promise5 = new Promise((resolve) => {
var state = [];
const req5 = new XMLHttpRequest();
req5.onreadystatechange = (e) => {
state.push(req5.readyState);
if (req5.readyState === XMLHttpRequest.DONE) {
resolve({states: state, target: e.currentTarget});
}
}
req5.open('GET', 'http://127.0.0.1:9582/xhr');
req5.send();
});
testing.async(promise5, (result) => {
const {states: states, target: target} = result;
testing.expectEqual(4, states.length)
testing.expectEqual(XMLHttpRequest.OPENED, readyStates[0]);
testing.expectEqual(XMLHttpRequest.HEADERS_RECEIVED, readyStates[1]);
testing.expectEqual(XMLHttpRequest.LOADING, readyStates[2]);
testing.expectEqual(XMLHttpRequest.DONE, readyStates[3]);
testing.expectEqual(req5, target);
})
</script>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<script src="testing.js"></script>
<p id="para"> And</p>
<script id=xmlserializer>
const s = new XMLSerializer();
testing.expectEqual('<p id="para"> And</p>', s.serializeToString($('#para')));
testing.expectEqual('<!DOCTYPE html>', s.serializeToString(document.doctype));
</script>

View File

@@ -24,8 +24,6 @@ const Document = @import("Document.zig");
const HTMLDocument = @import("HTMLDocument.zig");
const DOMParser = @This();
// @ZIGDOM support empty structs
_: u8 = 0,
pub fn init() DOMParser {
return .{};
@@ -63,6 +61,7 @@ pub const JsApi = struct {
pub const name = "DOMParser";
pub const prototype_chain = bridge.prototypeChain();
pub var class_id: bridge.ClassId = undefined;
pub const empty_with_no_proto = true;
};
pub const constructor = bridge.constructor(DOMParser.init, .{});

Some files were not shown because too many files have changed in this diff Show More