mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
wpt: first draft for tests
This commit is contained in:
13
build.zig
13
build.zig
@@ -72,6 +72,19 @@ pub fn build(b: *std.build.Builder) !void {
|
|||||||
// step
|
// step
|
||||||
const test_step = b.step("test", "Run unit tests");
|
const test_step = b.step("test", "Run unit tests");
|
||||||
test_step.dependOn(&run_tests.step);
|
test_step.dependOn(&run_tests.step);
|
||||||
|
|
||||||
|
// wpt tests
|
||||||
|
// -----
|
||||||
|
|
||||||
|
// compile
|
||||||
|
const wpt = b.addTest(.{ .root_source_file = .{ .path = "src/run_wpt.zig" } });
|
||||||
|
try common(wpt, options);
|
||||||
|
wpt.single_threaded = true;
|
||||||
|
const run_wpt = b.addRunArtifact(wpt);
|
||||||
|
|
||||||
|
// step
|
||||||
|
const wpt_step = b.step("wpt", "Run Web Platform Tests");
|
||||||
|
wpt_step.dependOn(&run_wpt.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn common(
|
fn common(
|
||||||
|
|||||||
143
src/run_wpt.zig
Normal file
143
src/run_wpt.zig
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const parser = @import("netsurf.zig");
|
||||||
|
const jsruntime = @import("jsruntime");
|
||||||
|
|
||||||
|
const public = @import("jsruntime");
|
||||||
|
const API = public.API;
|
||||||
|
const TPL = public.TPL;
|
||||||
|
const Env = public.Env;
|
||||||
|
const Loop = public.Loop;
|
||||||
|
|
||||||
|
const DOM = @import("dom.zig");
|
||||||
|
const HTMLElem = @import("html/elements.zig");
|
||||||
|
|
||||||
|
fn readFile(allocator: std.mem.Allocator, filename: []const u8) ![]const u8 {
|
||||||
|
var file = try std.fs.cwd().openFile(filename, .{});
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
const file_size = try file.getEndPos();
|
||||||
|
return file.readToEndAlloc(allocator, file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate APIs
|
||||||
|
const apis = jsruntime.compile(DOM.Interfaces);
|
||||||
|
|
||||||
|
// TODO For now the WPT tests run is specific to WPT.
|
||||||
|
// It manually load js framwork libs, and run the first script w/ js content in
|
||||||
|
// the HTML page.
|
||||||
|
// Once browsercore will have the html loader, it would be useful to refacto
|
||||||
|
// this test to use it.
|
||||||
|
test {
|
||||||
|
std.debug.print("Running WPT test suite\n", .{});
|
||||||
|
|
||||||
|
var bench_alloc = jsruntime.bench_allocator(std.testing.allocator);
|
||||||
|
const alloc = bench_alloc.allocator();
|
||||||
|
|
||||||
|
// initialize VM JS lib.
|
||||||
|
const vm = jsruntime.VM.init();
|
||||||
|
defer vm.deinit();
|
||||||
|
|
||||||
|
// prepare libraries to load on each test case.
|
||||||
|
var libs: [2][]const u8 = undefined;
|
||||||
|
// read testharness.js content
|
||||||
|
libs[0] = try readFile(alloc, "tests/wpt/resources/testharness.js");
|
||||||
|
defer alloc.free(libs[0]);
|
||||||
|
|
||||||
|
// read testharnessreport.js content
|
||||||
|
libs[1] = try readFile(alloc, "tests/wpt/resources/testharnessreport.js");
|
||||||
|
defer alloc.free(libs[1]);
|
||||||
|
|
||||||
|
// TODO browse the dir to get the tests dynamically.
|
||||||
|
const testcases = [_][]const u8{
|
||||||
|
"tests/wpt/dom/nodes/ChildNode-after.html",
|
||||||
|
"tests/wpt/dom/nodes/Document-createElement.html",
|
||||||
|
"tests/wpt/dom/nodes/append-on-Document.html",
|
||||||
|
};
|
||||||
|
|
||||||
|
var failures: usize = 0;
|
||||||
|
for (testcases) |tc| {
|
||||||
|
// create an arena and deinit it for each test case.
|
||||||
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
// TODO I don't use testing.expect here b/c I want to execute all the
|
||||||
|
// tests. And testing.expect stops running test in the first failure.
|
||||||
|
std.debug.print("{s}\t\t", .{tc});
|
||||||
|
|
||||||
|
const res = runWPT(&arena, tc, libs[0..]) catch |err| {
|
||||||
|
std.debug.print("[ ERR ]\n\t> {any}\n", .{err});
|
||||||
|
failures += 1;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!res.success) {
|
||||||
|
std.debug.print("[ ERR ]\n\t> {s}\n", .{res.result});
|
||||||
|
failures += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std.debug.print("[ OK ]\n", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures > 0) {
|
||||||
|
std.debug.print("{d}/{d} tests failures\n", .{ failures, testcases.len });
|
||||||
|
}
|
||||||
|
try std.testing.expect(failures == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// runWPT parses the given HTML file, starts a js env and run the first script
|
||||||
|
// tags containing javascript sources.
|
||||||
|
// It loads first the js libs files.
|
||||||
|
fn runWPT(arena: *std.heap.ArenaAllocator, f: []const u8, libs: [][]const u8) !jsruntime.JSResult {
|
||||||
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
|
// document
|
||||||
|
var ff: []u8 = @constCast(f);
|
||||||
|
const htmldoc = parser.documentHTMLParse(ff);
|
||||||
|
const doc = parser.documentHTMLToDocument(htmldoc);
|
||||||
|
|
||||||
|
// create JS env
|
||||||
|
var loop = try Loop.init(alloc);
|
||||||
|
defer loop.deinit();
|
||||||
|
var js_env = try Env.init(arena, &loop);
|
||||||
|
defer js_env.deinit();
|
||||||
|
|
||||||
|
// load APIs in JS env
|
||||||
|
var tpls: [apis.len]TPL = undefined;
|
||||||
|
try js_env.load(apis, &tpls);
|
||||||
|
|
||||||
|
// start JS env
|
||||||
|
js_env.start(apis);
|
||||||
|
defer js_env.stop();
|
||||||
|
|
||||||
|
// add document object
|
||||||
|
try js_env.addObject(apis, doc, "document");
|
||||||
|
|
||||||
|
var res = jsruntime.JSResult{};
|
||||||
|
var cbk_res = jsruntime.JSResult{
|
||||||
|
.success = true,
|
||||||
|
// assume that the return value of the successfull callback is "undefined"
|
||||||
|
.result = "undefined",
|
||||||
|
};
|
||||||
|
|
||||||
|
// execute libs
|
||||||
|
for (libs) |lib| {
|
||||||
|
try js_env.run(alloc, lib, "", &res, &cbk_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop hover the scripts.
|
||||||
|
const scripts = parser.documentGetElementsByTagName(doc, "script");
|
||||||
|
const slen = parser.nodeListLength(scripts);
|
||||||
|
for (0..slen) |i| {
|
||||||
|
const s = parser.nodeListItem(scripts, @intCast(i)).?;
|
||||||
|
// search only script tag containing text a child.
|
||||||
|
const text = parser.nodeFirstChild(s) orelse continue;
|
||||||
|
|
||||||
|
const src = parser.nodeTextContent(text).?;
|
||||||
|
try js_env.run(alloc, src, "", &res, &cbk_res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.EmptyTest;
|
||||||
|
}
|
||||||
166
tests/wpt/dom/nodes/ChildNode-after.html
Normal file
166
tests/wpt/dom/nodes/ChildNode-after.html
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>ChildNode.after</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-childnode-after">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function test_after(child, nodeName, innerHTML) {
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after();
|
||||||
|
assert_equals(parent.innerHTML, innerHTML);
|
||||||
|
}, nodeName + '.after() without any argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(null);
|
||||||
|
var expected = innerHTML + 'null';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with null as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(undefined);
|
||||||
|
var expected = innerHTML + 'undefined';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with undefined as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after('');
|
||||||
|
assert_equals(parent.lastChild.data, '');
|
||||||
|
}, nodeName + '.after() with the empty string as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after('text');
|
||||||
|
var expected = innerHTML + 'text';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with only text as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(x);
|
||||||
|
var expected = innerHTML + '<x></x>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with only one element as an argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(x, 'text');
|
||||||
|
var expected = innerHTML + '<x></x>text';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with one element and text as arguments.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after('text', child);
|
||||||
|
var expected = 'text' + innerHTML;
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with context object itself as the argument.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div')
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(child);
|
||||||
|
child.after(child, x);
|
||||||
|
var expected = innerHTML + '<x></x>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with context object itself and node as the arguments, switching positions.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
var z = document.createElement('z');
|
||||||
|
parent.appendChild(y);
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
child.after(x, y, z);
|
||||||
|
var expected = innerHTML + '<x></x><y></y><z></z>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with all siblings of child as arguments.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div')
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
var z = document.createElement('z');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(y);
|
||||||
|
parent.appendChild(z);
|
||||||
|
child.after(x, y);
|
||||||
|
var expected = innerHTML + '<x></x><y></y><z></z>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.before() with some siblings of child as arguments; no changes in tree; viable sibling is first child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div')
|
||||||
|
var v = document.createElement('v');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
var z = document.createElement('z');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(v);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(y);
|
||||||
|
parent.appendChild(z);
|
||||||
|
child.after(v, x);
|
||||||
|
var expected = innerHTML + '<v></v><x></x><y></y><z></z>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with some siblings of child as arguments; no changes in tree.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(y);
|
||||||
|
child.after(y, x);
|
||||||
|
var expected = innerHTML + '<y></y><x></x>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() when pre-insert behaves like append.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
parent.appendChild(child);
|
||||||
|
parent.appendChild(x);
|
||||||
|
parent.appendChild(document.createTextNode('1'));
|
||||||
|
parent.appendChild(y);
|
||||||
|
child.after(x, '2');
|
||||||
|
var expected = innerHTML + '<x></x>21<y></y>';
|
||||||
|
assert_equals(parent.innerHTML, expected);
|
||||||
|
}, nodeName + '.after() with one sibling of child and text as arguments.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
x.after(y);
|
||||||
|
assert_equals(x.nextSibling, null);
|
||||||
|
}, nodeName + '.after() on a child without any parent.');
|
||||||
|
}
|
||||||
|
|
||||||
|
test_after(document.createComment('test'), 'Comment', '<!--test-->');
|
||||||
|
test_after(document.createElement('test'), 'Element', '<test></test>');
|
||||||
|
test_after(document.createTextNode('test'), 'Text', 'test');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
158
tests/wpt/dom/nodes/Document-createElement.html
Normal file
158
tests/wpt/dom/nodes/Document-createElement.html
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Document.createElement</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-document-createelement">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-localname">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-tagname">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-prefix">
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-element-namespaceuri">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<iframe src="/common/dummy.xml"></iframe>
|
||||||
|
<iframe src="/common/dummy.xhtml"></iframe>
|
||||||
|
<script>
|
||||||
|
function toASCIIUppercase(str) {
|
||||||
|
var diff = "a".charCodeAt(0) - "A".charCodeAt(0);
|
||||||
|
var res = "";
|
||||||
|
for (var i = 0; i < str.length; ++i) {
|
||||||
|
if ("a" <= str[i] && str[i] <= "z") {
|
||||||
|
res += String.fromCharCode(str.charCodeAt(i) - diff);
|
||||||
|
} else {
|
||||||
|
res += str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
function toASCIILowercase(str) {
|
||||||
|
var diff = "a".charCodeAt(0) - "A".charCodeAt(0);
|
||||||
|
var res = "";
|
||||||
|
for (var i = 0; i < str.length; ++i) {
|
||||||
|
if ("A" <= str[i] && str[i] <= "Z") {
|
||||||
|
res += String.fromCharCode(str.charCodeAt(i) + diff);
|
||||||
|
} else {
|
||||||
|
res += str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
var HTMLNS = "http://www.w3.org/1999/xhtml",
|
||||||
|
valid = [
|
||||||
|
undefined,
|
||||||
|
null,
|
||||||
|
"foo",
|
||||||
|
"f1oo",
|
||||||
|
"foo1",
|
||||||
|
"f\u0BC6",
|
||||||
|
"foo\u0BC6",
|
||||||
|
":",
|
||||||
|
":foo",
|
||||||
|
"f:oo",
|
||||||
|
"foo:",
|
||||||
|
"f:o:o",
|
||||||
|
"f::oo",
|
||||||
|
"f::oo:",
|
||||||
|
"foo:0",
|
||||||
|
"foo:_",
|
||||||
|
// combining char after :, invalid QName but valid Name
|
||||||
|
"foo:\u0BC6",
|
||||||
|
"foo:foo\u0BC6",
|
||||||
|
"foo\u0BC6:foo",
|
||||||
|
"xml",
|
||||||
|
"xmlns",
|
||||||
|
"xmlfoo",
|
||||||
|
"xml:foo",
|
||||||
|
"xmlns:foo",
|
||||||
|
"xmlfoo:bar",
|
||||||
|
"svg",
|
||||||
|
"math",
|
||||||
|
"FOO",
|
||||||
|
// Test that non-ASCII chars don't get uppercased/lowercased
|
||||||
|
"mar\u212a",
|
||||||
|
"\u0130nput",
|
||||||
|
"\u0131nput",
|
||||||
|
],
|
||||||
|
invalid = [
|
||||||
|
"",
|
||||||
|
"1foo",
|
||||||
|
"1:foo",
|
||||||
|
"fo o",
|
||||||
|
"\u0300foo",
|
||||||
|
"}foo",
|
||||||
|
"f}oo",
|
||||||
|
"foo}",
|
||||||
|
"\ufffffoo",
|
||||||
|
"f\uffffoo",
|
||||||
|
"foo\uffff",
|
||||||
|
"<foo",
|
||||||
|
"foo>",
|
||||||
|
"<foo>",
|
||||||
|
"f<oo",
|
||||||
|
"-foo",
|
||||||
|
".foo",
|
||||||
|
"\u0300",
|
||||||
|
]
|
||||||
|
|
||||||
|
var xmlIframe = document.querySelector('[src="/common/dummy.xml"]');
|
||||||
|
var xhtmlIframe = document.querySelector('[src="/common/dummy.xhtml"]');
|
||||||
|
|
||||||
|
function getWin(desc) {
|
||||||
|
if (desc == "HTML document") {
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
if (desc == "XML document") {
|
||||||
|
assert_equals(xmlIframe.contentDocument.documentElement.textContent,
|
||||||
|
"Dummy XML document", "XML document didn't load");
|
||||||
|
return xmlIframe.contentWindow;
|
||||||
|
}
|
||||||
|
if (desc == "XHTML document") {
|
||||||
|
assert_equals(xhtmlIframe.contentDocument.documentElement.textContent,
|
||||||
|
"Dummy XHTML document", "XHTML document didn't load");
|
||||||
|
return xhtmlIframe.contentWindow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
valid.forEach(function(t) {
|
||||||
|
["HTML document", "XML document", "XHTML document"].forEach(function(desc) {
|
||||||
|
async_test(function(testObj) {
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
testObj.step(function() {
|
||||||
|
var win = getWin(desc);
|
||||||
|
var doc = win.document;
|
||||||
|
var elt = doc.createElement(t)
|
||||||
|
assert_true(elt instanceof win.Element, "instanceof Element")
|
||||||
|
assert_true(elt instanceof win.Node, "instanceof Node")
|
||||||
|
assert_equals(elt.localName,
|
||||||
|
desc == "HTML document" ? toASCIILowercase(String(t))
|
||||||
|
: String(t),
|
||||||
|
"localName")
|
||||||
|
assert_equals(elt.tagName,
|
||||||
|
desc == "HTML document" ? toASCIIUppercase(String(t))
|
||||||
|
: String(t),
|
||||||
|
"tagName")
|
||||||
|
assert_equals(elt.prefix, null, "prefix")
|
||||||
|
assert_equals(elt.namespaceURI,
|
||||||
|
desc == "XML document" ? null : HTMLNS, "namespaceURI")
|
||||||
|
});
|
||||||
|
testObj.done();
|
||||||
|
});
|
||||||
|
}, "createElement(" + format_value(t) + ") in " + desc);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
invalid.forEach(function(arg) {
|
||||||
|
["HTML document", "XML document", "XHTML document"].forEach(function(desc) {
|
||||||
|
async_test(function(testObj) {
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
testObj.step(function() {
|
||||||
|
let win = getWin(desc);
|
||||||
|
let doc = win.document;
|
||||||
|
assert_throws_dom("InvalidCharacterError", win.DOMException,
|
||||||
|
function() { doc.createElement(arg) })
|
||||||
|
});
|
||||||
|
testObj.done();
|
||||||
|
});
|
||||||
|
}, "createElement(" + format_value(arg) + ") in " + desc);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
53
tests/wpt/dom/nodes/append-on-Document.html
Normal file
53
tests/wpt/dom/nodes/append-on-Document.html
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>DocumentType.append</title>
|
||||||
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-parentnode-append">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function test_append_on_Document() {
|
||||||
|
|
||||||
|
var node = document.implementation.createDocument(null, null);
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
parent.append();
|
||||||
|
assert_array_equals(parent.childNodes, []);
|
||||||
|
}, 'Document.append() without any argument, on a Document having no child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
var x = document.createElement('x');
|
||||||
|
parent.append(x);
|
||||||
|
assert_array_equals(parent.childNodes, [x]);
|
||||||
|
}, 'Document.append() with only one element as an argument, on a Document having no child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
parent.appendChild(x);
|
||||||
|
assert_throws_dom('HierarchyRequestError', function() { parent.append(y); });
|
||||||
|
assert_array_equals(parent.childNodes, [x]);
|
||||||
|
}, 'Document.append() with only one element as an argument, on a Document having one child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
assert_throws_dom('HierarchyRequestError', function() { parent.append('text'); });
|
||||||
|
assert_array_equals(parent.childNodes, []);
|
||||||
|
}, 'Document.append() with text as an argument, on a Document having no child.');
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
var parent = node.cloneNode();
|
||||||
|
var x = document.createElement('x');
|
||||||
|
var y = document.createElement('y');
|
||||||
|
assert_throws_dom('HierarchyRequestError', function() { parent.append(x, y); });
|
||||||
|
assert_array_equals(parent.childNodes, []);
|
||||||
|
}, 'Document.append() with two elements as the argument, on a Document having no child.');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
test_append_on_Document();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
4941
tests/wpt/resources/testharness.js
Normal file
4941
tests/wpt/resources/testharness.js
Normal file
File diff suppressed because it is too large
Load Diff
57
tests/wpt/resources/testharnessreport.js
Normal file
57
tests/wpt/resources/testharnessreport.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* global add_completion_callback */
|
||||||
|
/* global setup */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is intended for vendors to implement code needed to integrate
|
||||||
|
* testharness.js tests with their own test systems.
|
||||||
|
*
|
||||||
|
* Typically test system integration will attach callbacks when each test has
|
||||||
|
* run, using add_result_callback(callback(test)), or when the whole test file
|
||||||
|
* has completed, using
|
||||||
|
* add_completion_callback(callback(tests, harness_status)).
|
||||||
|
*
|
||||||
|
* For more documentation about the callback functions and the
|
||||||
|
* parameters they are called with see testharness.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
function dump_test_results(tests, status) {
|
||||||
|
var results_element = document.createElement("script");
|
||||||
|
results_element.type = "text/json";
|
||||||
|
results_element.id = "__testharness__results__";
|
||||||
|
var test_results = tests.map(function(x) {
|
||||||
|
return {name:x.name, status:x.status, message:x.message, stack:x.stack}
|
||||||
|
});
|
||||||
|
var data = {test:window.location.href,
|
||||||
|
tests:test_results,
|
||||||
|
status: status.status,
|
||||||
|
message: status.message,
|
||||||
|
stack: status.stack};
|
||||||
|
results_element.textContent = JSON.stringify(data);
|
||||||
|
|
||||||
|
// To avoid a HierarchyRequestError with XML documents, ensure that 'results_element'
|
||||||
|
// is inserted at a location that results in a valid document.
|
||||||
|
var parent = document.body
|
||||||
|
? document.body // <body> is required in XHTML documents
|
||||||
|
: document.documentElement; // fallback for optional <body> in HTML5, SVG, etc.
|
||||||
|
|
||||||
|
parent.appendChild(results_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_completion_callback(dump_test_results);
|
||||||
|
|
||||||
|
/* If the parent window has a testharness_properties object,
|
||||||
|
* we use this to provide the test settings. This is used by the
|
||||||
|
* default in-browser runner to configure the timeout and the
|
||||||
|
* rendering of results
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
if (window.opener && "testharness_properties" in window.opener) {
|
||||||
|
/* If we pass the testharness_properties object as-is here without
|
||||||
|
* JSON stringifying and reparsing it, IE fails & emits the message
|
||||||
|
* "Could not complete the operation due to error 80700019".
|
||||||
|
*/
|
||||||
|
setup(JSON.parse(JSON.stringify(window.opener.testharness_properties)));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
// vim: set expandtab shiftwidth=4 tabstop=4:
|
||||||
Reference in New Issue
Block a user