diff options
Diffstat (limited to 'dom/tests/mochitest')
21 files changed, 557 insertions, 297 deletions
diff --git a/dom/tests/mochitest/webcomponents/chrome.ini b/dom/tests/mochitest/webcomponents/chrome.ini new file mode 100644 index 000000000..5e25c2123 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/chrome.ini @@ -0,0 +1,9 @@ +[DEFAULT] +support-files = + dummy_page.html + +[test_custom_element_htmlconstructor_chrome.html] +skip-if = os == 'android' # bug 1323645 +support-files = + htmlconstructor_autonomous_tests.js + htmlconstructor_builtin_tests.js diff --git a/dom/tests/mochitest/webcomponents/dummy_page.html b/dom/tests/mochitest/webcomponents/dummy_page.html new file mode 100644 index 000000000..fd238954c --- /dev/null +++ b/dom/tests/mochitest/webcomponents/dummy_page.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<title>Dummy test page</title> +<meta charset="utf-8"/> +</head> +<body> +<p>Dummy test page</p> +</body> +</html> diff --git a/dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js b/dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js new file mode 100644 index 000000000..636d9aff6 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js @@ -0,0 +1,81 @@ +promises.push(test_with_new_window((testWindow) => { + // Test calling the HTMLElement constructor. + (() => { + SimpleTest.doesThrow(() => { + testWindow.HTMLElement(); + }, 'calling the HTMLElement constructor should throw a TypeError'); + })(); + + // Test constructing a HTMLELement. + (() => { + SimpleTest.doesThrow(() => { + new testWindow.HTMLElement(); + }, 'constructing a HTMLElement should throw a TypeError'); + })(); + + // Test constructing a custom element with defining HTMLElement as entry. + (() => { + testWindow.customElements.define('x-defining-html-element', + testWindow.HTMLElement); + SimpleTest.doesThrow(() => { + new testWindow.HTMLElement(); + }, 'constructing a custom element with defining HTMLElement as registry ' + + 'entry should throw a TypeError'); + })(); + + // Test calling a custom element constructor and constructing an autonomous + // custom element. + (() => { + let num_constructor_invocations = 0; + class X extends testWindow.HTMLElement { + constructor() { + super(); + num_constructor_invocations++; + } + } + testWindow.customElements.define('x-element', X); + SimpleTest.doesThrow(() => { + X(); + }, 'calling an autonomous custom element constructor should throw a TypeError'); + + let element = new X(); + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype, + 'constructing an autonomous custom element; ' + + 'the element should be a registered constructor'); + SimpleTest.is(element.localName, 'x-element', + 'constructing an autonomous custom element; ' + + 'the element tag name should be "x-element"'); + SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml', + 'constructing an autonomous custom element; ' + + 'the element should be in the HTML namespace'); + SimpleTest.is(element.prefix, null, + 'constructing an autonomous custom element; ' + + 'the element name should not have a prefix'); + SimpleTest.is(element.ownerDocument, testWindow.document, + 'constructing an autonomous custom element; ' + + 'the element should be owned by the registry\'s associated ' + + 'document'); + SimpleTest.is(num_constructor_invocations, 1, + 'constructing an autonomous custom element; ' + + 'the constructor should have been invoked once'); + })(); + + // Test if prototype is no an object. + (() => { + function ElementWithNonObjectPrototype() { + let o = Reflect.construct(testWindow.HTMLElement, [], new.target); + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window.HTMLElement.prototype, + 'constructing an autonomous custom element; ' + + 'if prototype is not object, fallback from NewTarget\'s realm'); + } + + // Prototype have to be an object during define(), otherwise define will + // throw an TypeError exception. + ElementWithNonObjectPrototype.prototype = {}; + testWindow.customElements.define('x-non-object-prototype', + ElementWithNonObjectPrototype); + + ElementWithNonObjectPrototype.prototype = "string"; + new ElementWithNonObjectPrototype(); + })(); +})); diff --git a/dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js b/dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js new file mode 100644 index 000000000..dd6515148 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js @@ -0,0 +1,247 @@ +[ + // [TagName, InterfaceName] + ['a', 'Anchor'], + ['abbr', ''], + ['acronym', ''], + ['address', ''], + ['area', 'Area'], + ['article', ''], + ['aside', ''], + ['audio', 'Audio'], + ['b', ''], + ['base', 'Base'], + ['basefont', ''], + ['bdo', ''], + ['big', ''], + ['blockquote', 'Quote'], + ['body', 'Body'], + ['br', 'BR'], + ['button', 'Button'], + ['canvas', 'Canvas'], + ['caption', 'TableCaption'], + ['center', ''], + ['cite', ''], + ['code', ''], + ['col', 'TableCol'], + ['colgroup', 'TableCol'], + ['data', 'Data'], + ['datalist', 'DataList'], + ['dd', ''], + ['del', 'Mod'], + ['details', 'Details'], + ['dfn', ''], + ['dir', 'Directory'], + ['div', 'Div'], + ['dl', 'DList'], + ['dt', ''], + ['em', ''], + ['embed', 'Embed'], + ['fieldset', 'FieldSet'], + ['figcaption', ''], + ['figure', ''], + ['font', 'Font'], + ['footer', ''], + ['form', 'Form'], + ['frame', 'Frame'], + ['frameset', 'FrameSet'], + ['h1', 'Heading'], + ['h2', 'Heading'], + ['h3', 'Heading'], + ['h4', 'Heading'], + ['h5', 'Heading'], + ['h6', 'Heading'], + ['head', 'Head'], + ['header', ''], + ['hgroup', ''], + ['hr', 'HR'], + ['html', 'Html'], + ['i', ''], + ['iframe', 'IFrame'], + ['image', ''], + ['img', 'Image'], + ['input', 'Input'], + ['ins', 'Mod'], + ['kbd', ''], + ['label', 'Label'], + ['legend', 'Legend'], + ['li', 'LI'], + ['link', 'Link'], + ['listing', 'Pre'], + ['main', ''], + ['map', 'Map'], + ['mark', ''], + ['marquee', 'Div'], + ['menu', 'Menu'], + ['menuitem', 'MenuItem'], + ['meta', 'Meta'], + ['meter', 'Meter'], + ['nav', ''], + ['nobr', ''], + ['noembed', ''], + ['noframes', ''], + ['noscript', ''], + ['object', 'Object'], + ['ol', 'OList'], + ['optgroup', 'OptGroup'], + ['option', 'Option'], + ['output', 'Output'], + ['p', 'Paragraph'], + ['param', 'Param'], + ['picture', 'Picture'], + ['plaintext', ''], + ['pre', 'Pre'], + ['progress', 'Progress'], + ['q', 'Quote'], + ['rb', ''], + ['rp', ''], + ['rt', ''], + ['rtc', ''], + ['ruby', ''], + ['s', ''], + ['samp', ''], + ['script', 'Script'], + ['section', ''], + ['select', 'Select'], + ['small', ''], + ['source', 'Source'], + ['span', 'Span'], + ['strike', ''], + ['strong', ''], + ['style', 'Style'], + ['sub', ''], + ['summary', ''], + ['sup', ''], + ['table', 'Table'], + ['tbody', 'TableSection'], + ['td', 'TableCell'], + ['textarea', 'TextArea'], + ['tfoot', 'TableSection'], + ['th', 'TableCell'], + ['thead', 'TableSection'], + ['template', 'Template'], + ['time', 'Time'], + ['title', 'Title'], + ['tr', 'TableRow'], + ['track', 'Track'], + ['tt', ''], + ['u', ''], + ['ul', 'UList'], + ['var', ''], + ['video', 'Video'], + ['wbr', ''], + ['xmp', 'Pre'], +].forEach((e) => { + let tagName = e[0]; + let interfaceName = 'HTML' + e[1] + 'Element'; + promises.push(test_with_new_window((testWindow) => { + // Use window from iframe to isolate the test. + // Test calling the HTML*Element constructor. + (() => { + SimpleTest.doesThrow(() => { + testWindow[interfaceName](); + }, 'calling the ' + interfaceName + ' constructor should throw a TypeError'); + })(); + + // Test constructing a HTML*ELement. + (() => { + SimpleTest.doesThrow(() => { + new testWindow[interfaceName](); + }, 'constructing a ' + interfaceName + ' should throw a TypeError'); + })(); + + // Test constructing a custom element with defining HTML*Element as entry. + (() => { + testWindow.customElements.define('x-defining-' + tagName, + testWindow[interfaceName]); + SimpleTest.doesThrow(() => { + new testWindow[interfaceName](); + }, 'constructing a custom element with defining ' + interfaceName + + ' as registry entry should throw a TypeError'); + })(); + + // Since HTMLElement can be registered without specifying "extends", skip + // testing HTMLElement tags. + if (interfaceName !== "HTMLElement") { + // Test constructing a customized HTML*Element with defining a registry entry + // without specifying "extends". + (() => { + class X extends testWindow[interfaceName] {} + testWindow.customElements.define('x-defining-invalid-' + tagName, X); + SimpleTest.doesThrow(() => { + new X(); + }, 'constructing a customized ' + interfaceName + ' with defining a ' + + 'registry entry without specifying "extends" should throw a TypeError'); + })(); + } + + // Test constructing a built-in custom element with defining a registry entry + // with incorrect "extends" information. + (() => { + class X extends testWindow[interfaceName] {} + testWindow.customElements.define('x-defining-incorrect-' + tagName, X, + { extends: tagName === 'img' ? 'p' : 'img' }); + SimpleTest.doesThrow(() => { + new X(); + }, 'constructing a customized ' + interfaceName + ' with defining a ' + + 'registry entry with incorrect "extends" should throw a TypeError'); + })(); + + // Test calling a custom element constructor and constructing a built-in + // custom element. + (() => { + let num_constructor_invocations = 0; + class X extends testWindow[interfaceName] { + constructor() { + super(); + num_constructor_invocations++; + } + } + testWindow.customElements.define('x-' + tagName, X, { extends: tagName }); + SimpleTest.doesThrow(() => { + X(); + }, 'calling a customized ' + interfaceName + ' constructor should throw a TypeError'); + + let element = new X(); + + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype, + 'constructing a customized ' + interfaceName + + '; the element should be a registered constructor'); + SimpleTest.is(element.localName, tagName, + 'constructing a customized ' + interfaceName + + '; the element tag name should be "' + tagName + '"'); + SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml', + 'constructing a customized ' + interfaceName + + '; the element should be in the HTML namespace'); + SimpleTest.is(element.prefix, null, + 'constructing a customized ' + interfaceName + + '; the element name should not have a prefix'); + SimpleTest.is(element.ownerDocument, testWindow.document, + 'constructing a customized ' + interfaceName + + '; the element should be owned by the registry\'s associated ' + + 'document'); + SimpleTest.is(num_constructor_invocations, 1, + 'constructing a customized ' + interfaceName + + '; the constructor should have been invoked once'); + })(); + + // Test if prototype is no an object. + (() => { + function ElementWithNonObjectPrototype() { + let o = Reflect.construct(testWindow[interfaceName], [], new.target); + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window[interfaceName].prototype, + 'constructing a customized ' + interfaceName + + '; if prototype is not object, fallback from NewTarget\'s realm'); + } + + // Prototype have to be an object during define(), otherwise define will + // throw an TypeError exception. + ElementWithNonObjectPrototype.prototype = {}; + testWindow.customElements.define('x-non-object-prototype-' + tagName, + ElementWithNonObjectPrototype, + { extends: tagName }); + + ElementWithNonObjectPrototype.prototype = "string"; + new ElementWithNonObjectPrototype(); + })(); + })); +}); diff --git a/dom/tests/mochitest/webcomponents/mochitest.ini b/dom/tests/mochitest/webcomponents/mochitest.ini index 496f7ea4d..f5d0f84ea 100644 --- a/dom/tests/mochitest/webcomponents/mochitest.ini +++ b/dom/tests/mochitest/webcomponents/mochitest.ini @@ -1,21 +1,28 @@ [DEFAULT] support-files = inert_style.css + dummy_page.html [test_bug900724.html] [test_bug1017896.html] [test_bug1176757.html] [test_bug1276240.html] [test_content_element.html] -[test_custom_element_adopt_callbacks.html] [test_custom_element_callback_innerhtml.html] -[test_custom_element_clone_callbacks.html] -[test_custom_element_clone_callbacks_extended.html] -[test_custom_element_import_node_created_callback.html] +skip-if = true # disabled - See bug 1390396 +[test_custom_element_htmlconstructor.html] +skip-if = os == 'android' # bug 1323645 +support-files = + htmlconstructor_autonomous_tests.js + htmlconstructor_builtin_tests.js [test_custom_element_in_shadow.html] +skip-if = true || stylo # disabled - See bug 1390396 and 1293844 [test_custom_element_register_invalid_callbacks.html] +[test_custom_element_throw_on_dynamic_markup_insertion.html] [test_custom_element_get.html] [test_custom_element_when_defined.html] +[test_custom_element_uncatchable_exception.html] +skip-if = !debug # TestFunctions only applied in debug builds [test_nested_content_element.html] [test_dest_insertion_points.html] [test_dest_insertion_points_shadow.html] @@ -25,10 +32,11 @@ support-files = [test_document_adoptnode.html] [test_document_importnode.html] [test_document_register.html] -[test_document_register_base_queue.html] [test_document_register_lifecycle.html] +skip-if = true # disabled - See bug 1390396 [test_document_register_parser.html] [test_document_register_stack.html] +skip-if = true # disabled - See bug 1390396 [test_document_shared_registry.html] [test_event_dispatch.html] [test_event_retarget.html] diff --git a/dom/tests/mochitest/webcomponents/test_bug1276240.html b/dom/tests/mochitest/webcomponents/test_bug1276240.html index 33e532a6a..ded8d8276 100644 --- a/dom/tests/mochitest/webcomponents/test_bug1276240.html +++ b/dom/tests/mochitest/webcomponents/test_bug1276240.html @@ -47,7 +47,7 @@ test(); // test with webcomponents disabled SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv( - { 'set': [["dom.webcomponents.enabled", false]]}, runTest); + { 'set': [["dom.webcomponents.customelements.enabled", false]]}, runTest); </script> </pre> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_adopt_callbacks.html b/dom/tests/mochitest/webcomponents/test_custom_element_adopt_callbacks.html deleted file mode 100644 index 28597b7c6..000000000 --- a/dom/tests/mochitest/webcomponents/test_custom_element_adopt_callbacks.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=1081039 ---> -<head> - <title>Test callbacks for adopted custom elements.</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<template id="template"><x-foo></x-foo></template> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1081039">Bug 1081039</a> -<script> - -var p = Object.create(HTMLElement.prototype); -p.createdCallback = function() { - ok(false, "Created callback should not be called for adopted node."); -}; - -document.registerElement("x-foo", { prototype: p }); - -var template = document.getElementById("template"); -var adoptedFoo = document.adoptNode(template.content.firstChild); -is(adoptedFoo.nodeName, "X-FOO"); - -</script> -</body> -</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_callback_innerhtml.html b/dom/tests/mochitest/webcomponents/test_custom_element_callback_innerhtml.html index 94b02032f..bb5008538 100644 --- a/dom/tests/mochitest/webcomponents/test_custom_element_callback_innerhtml.html +++ b/dom/tests/mochitest/webcomponents/test_custom_element_callback_innerhtml.html @@ -16,7 +16,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1102502 SimpleTest.waitForExplicitFinish(); -var attachedCallbackCount = 0; +var connectedCallbackCount = 0; var p = Object.create(HTMLElement.prototype); @@ -24,12 +24,12 @@ p.createdCallback = function() { ok(true, "createdCallback called."); }; -p.attachedCallback = function() { - ok(true, "attachedCallback should be called when the parser creates an element in the document."); - attachedCallbackCount++; - // attachedCallback should be called twice, once for the element created for innerHTML and +p.connectedCallback = function() { + ok(true, "connectedCallback should be called when the parser creates an element in the document."); + connectedCallbackCount++; + // connectedCallback should be called twice, once for the element created for innerHTML and // once for the element created in this document. - if (attachedCallbackCount == 2) { + if (connectedCallbackCount == 2) { SimpleTest.finish(); } } diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_clone_callbacks.html b/dom/tests/mochitest/webcomponents/test_custom_element_clone_callbacks.html deleted file mode 100644 index eea9bafe0..000000000 --- a/dom/tests/mochitest/webcomponents/test_custom_element_clone_callbacks.html +++ /dev/null @@ -1,54 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=1081039 ---> -<head> - <title>Test callbacks for cloned custom elements.</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1081039">Bug 1081039</a> -<script> - -SimpleTest.waitForExplicitFinish(); - -// Test to make sure created callback is called on clones that are upgraded and clones -// created after registering the custom element. - -var callbackCalledOnUpgrade = false; -var callbackCalledOnClone = false; - -var foo = document.createElement("x-foo"); -var fooClone = foo.cloneNode(true); - -var p = Object.create(HTMLElement.prototype); -p.createdCallback = function() { - is(this.__proto__, p, "Correct prototype should be set on custom elements."); - - if (this == fooClone) { - // Callback called for the element created before registering the custom element. - // Should be called on element upgrade. - is(callbackCalledOnUpgrade, false, "Upgrade should only be called once per clone."); - callbackCalledOnUpgrade = true; - } else if (this != foo) { - // Callback called for the element created after registering the custom element. - is(callbackCalledOnClone, false, "Upgrade should only be called once per clone."); - callbackCalledOnClone = true; - } - - if (callbackCalledOnUpgrade && callbackCalledOnClone) { - SimpleTest.finish(); - } -}; - -document.registerElement("x-foo", { prototype: p }); - -var anotherFooClone = foo.cloneNode(true); - -SimpleTest.waitForExplicitFinish(); - -</script> -</body> -</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_clone_callbacks_extended.html b/dom/tests/mochitest/webcomponents/test_custom_element_clone_callbacks_extended.html deleted file mode 100644 index b3531b0ea..000000000 --- a/dom/tests/mochitest/webcomponents/test_custom_element_clone_callbacks_extended.html +++ /dev/null @@ -1,40 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=1081039 ---> -<head> - <title>Test callbacks for cloned extended custom elements.</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1081039">Bug 1081039</a> -<script> - -SimpleTest.waitForExplicitFinish(); - -// Test to make sure created callback is called on clones created after -// registering the custom element. - -var count = 0; -var p = Object.create(HTMLButtonElement.prototype); -p.createdCallback = function() { // should be called by createElement and cloneNode - is(this.__proto__, p, "Correct prototype should be set on custom elements."); - - if (++count == 2) { - SimpleTest.finish(); - } -}; - -document.registerElement("x-foo", { prototype: p, extends: "button" }); -var foo = document.createElement("button", {is: "x-foo"}); -is(foo.getAttribute("is"), "x-foo"); - -var fooClone = foo.cloneNode(true); - -SimpleTest.waitForExplicitFinish(); - -</script> -</body> -</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html new file mode 100644 index 000000000..b022a7887 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1274159 +--> +<head> + <title>Test HTMLConstructor for custom elements.</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1274159">Bug 1274159</a> +<script type="text/javascript"> +function test_with_new_window(f) { + return new Promise((aResolve) => { + let iframe = document.createElement('iframe'); + iframe.setAttribute('type', 'content'); + iframe.setAttribute('src', 'dummy_page.html'); + iframe.onload = function() { + f(iframe.contentWindow); + aResolve(); + }; + document.body.appendChild(iframe); + }); +} + +// Fake the Cu.waiveXrays, so that we can share the tests with mochitest chrome. +var Cu = { waiveXrays: (obj) => obj }; +var promises = []; +SimpleTest.waitForExplicitFinish(); +</script> +<!-- Test cases for autonomous element --> +<script type="text/javascript" src="htmlconstructor_autonomous_tests.js"></script> +<!-- Test cases for customized built-in element --> +<script type="text/javascript" src="htmlconstructor_builtin_tests.js"></script> +<script type="text/javascript"> +Promise.all(promises).then(() => { + SimpleTest.finish(); +}); +</script> +</body> +</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html new file mode 100644 index 000000000..8c7ec0ac6 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1274159 +--> +<head> + <title>Test HTMLConstructor for custom elements.</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1274159">Bug 1274159</a> +<script type="text/javascript"> +function test_with_new_window(f) { + return new Promise((aResolve) => { + let iframe = document.createElement('iframe'); + iframe.setAttribute('type', 'content'); + iframe.setAttribute('src', 'http://example.org/tests/dom/tests/mochitest/webcomponents/dummy_page.html'); + iframe.onload = function() { + f(iframe.contentWindow); + aResolve(); + }; + document.body.appendChild(iframe); + }); +} + +var Cu = Components.utils; +var promises = []; +SimpleTest.waitForExplicitFinish(); +</script> +<!-- Test cases for autonomous element --> +<script type="text/javascript" src="htmlconstructor_autonomous_tests.js"></script> +<!-- Test cases for customized built-in element --> +<script type="text/javascript" src="htmlconstructor_builtin_tests.js"></script> +<script type="text/javascript"> +Promise.all(promises).then(() => { + SimpleTest.finish(); +}); +</script> +</body> +</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_import_node_created_callback.html b/dom/tests/mochitest/webcomponents/test_custom_element_import_node_created_callback.html deleted file mode 100644 index f533b507c..000000000 --- a/dom/tests/mochitest/webcomponents/test_custom_element_import_node_created_callback.html +++ /dev/null @@ -1,34 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=1093680 ---> -<head> - <title>Test created callback order for imported custom element.</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<template id="template"><x-foo><span></span></x-foo></template> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1093680">Bug 1093680</a> -<script> - -var fooProtoCreatedCallbackCalled = false; -var fooProto = Object.create(HTMLElement.prototype); -fooProto.createdCallback = function() { - ok(this.firstElementChild, "When the created callback is called, the element should already have a child because the callback should only be called after cloning all the contents."); - fooProtoCreatedCallbackCalled = true; -}; - -document.registerElement("x-foo", { prototype: fooProto }); - -var template = document.getElementById("template"); - -// Importing node will implicityly clone the conent in the main document. -var adoptedFoo = document.importNode(template.content, true); - -ok(fooProtoCreatedCallbackCalled, "Created callback should be called after importing custom element into document"); - -</script> -</body> -</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_register_invalid_callbacks.html b/dom/tests/mochitest/webcomponents/test_custom_element_register_invalid_callbacks.html index a349f4aa5..572579ba8 100644 --- a/dom/tests/mochitest/webcomponents/test_custom_element_register_invalid_callbacks.html +++ b/dom/tests/mochitest/webcomponents/test_custom_element_register_invalid_callbacks.html @@ -19,9 +19,6 @@ const testWindow = iframe.contentDocument.defaultView; // This is for backward compatibility. // We should do the same checks for the callbacks from v0 spec. [ - 'createdCallback', - 'attachedCallback', - 'detachedCallback', 'attributeChangedCallback', ].forEach(callback => { var c = class {}; diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_throw_on_dynamic_markup_insertion.html b/dom/tests/mochitest/webcomponents/test_custom_element_throw_on_dynamic_markup_insertion.html new file mode 100644 index 000000000..b5ef66860 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_custom_element_throw_on_dynamic_markup_insertion.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1378079 +--> +<head> + <title>Test throw on dynamic markup insertion when creating element synchronously from parser</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1378079">Bug 1378079</a> +<div id="container"></div> + +<script> + +class DoDocumentOpenInCtor extends HTMLElement { + constructor() { + super(); + document.open(); + } +}; +customElements.define('x-document-open-in-ctor', DoDocumentOpenInCtor); + +class DoDocumentWriteInCtor extends HTMLElement { + constructor() { + super(); + document.write('<div>This should not be shown</div>'); + } +}; +customElements.define('x-document-write-in-ctor', DoDocumentWriteInCtor); + +class DoDocumentCloseInCtor extends HTMLElement { + constructor() { + super(); + document.close(); + } +}; +customElements.define('x-document-close-in-ctor', DoDocumentCloseInCtor); + +window.errors = []; +window.onerror = function(message, url, lineNumber, columnNumber, error) { + errors.push(error.name); + return true; +} +var expectedErrorCount = 0; + +document.write("<x-document-open-in-ctor></x-document-open-in-ctor>"); +expectedErrorCount++; +is(window.errors.length, expectedErrorCount, "expectedErrorCount should be " + expectedErrorCount); +is(window.errors[expectedErrorCount - 1], 'InvalidStateError', "Error name should be 'InvalidStateError'"); + +document.write("<x-document-write-in-ctor></x-document-write-in-ctor>"); +expectedErrorCount++; +is(window.errors.length, expectedErrorCount, "expectedErrorCount should be " + expectedErrorCount); +is(window.errors[expectedErrorCount - 1], 'InvalidStateError', "Error name should be 'InvalidStateError'"); + +document.write("<x-document-close-in-ctor></x-document-close-in-ctor>"); +expectedErrorCount++; +is(window.errors.length, expectedErrorCount, "expectedErrorCount should be " + expectedErrorCount); +is(window.errors[expectedErrorCount - 1], 'InvalidStateError', "Error name should be 'InvalidStateError'"); + +</script> + +</body> +</html> diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_uncatchable_exception.html b/dom/tests/mochitest/webcomponents/test_custom_element_uncatchable_exception.html new file mode 100644 index 000000000..f60bf1674 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_custom_element_uncatchable_exception.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1407669 +--> +<head> + <title>Test custom elements runtime exception</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1407669">Bug 1407669</a> +<script type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, function() { + window.onerror = function (e) { + ok(false, "How did we get here!?"); + } + + class Foo extends HTMLElement { + constructor() { + super() + TestFunctions.throwUncatchableException(); + } + } + + customElements.define("test-custom-element", Foo); + let element = document.createElement("test-custom-element"); + is(element instanceof HTMLUnknownElement, true, "It should be a HTMLUnknownElement when uncatchable exception throws in constructor"); + ok(true, "Uncatchable exception should not report"); + SimpleTest.finish(); +}); + +</script> +</body> +</html> diff --git a/dom/tests/mochitest/webcomponents/test_document_register.html b/dom/tests/mochitest/webcomponents/test_document_register.html index a9c194b60..aa80fef5f 100644 --- a/dom/tests/mochitest/webcomponents/test_document_register.html +++ b/dom/tests/mochitest/webcomponents/test_document_register.html @@ -103,52 +103,12 @@ function startTest() { is(extendedButton.getAttribute("is"), "x-extended-button", "The |is| attribute of the created element should be the extended type."); is(extendedButton.type, "submit", "Created element should be a button with type of \"submit\""); - // document.createElementNS with different namespace than definition. - try { - var svgButton = document.createElementNS("http://www.w3.org/2000/svg", "button", {is: "x-extended-button"}); - ok(false, "An exception should've been thrown"); - } catch(err) { - is(err.name, "NotFoundError", "A NotFoundError exception should've been thrown"); - } - - // document.createElementNS with no namespace. - try { - var noNamespaceButton = document.createElementNS("", "button", {is: "x-extended-button"}); - ok(false, "An exception should've been thrown"); - } catch(err) { - is(err.name, "NotFoundError", "A NotFoundError exception should've been thrown"); - } - - // document.createElement with non-existant extended type. - try { - var normalButton = document.createElement("button", {is: "x-non-existant"}); - ok(false, "An exception should've been thrown"); - } catch(err) { - is(err.name, "NotFoundError", "A NotFoundError exception should've been thrown"); - } - - // document.createElement with exteneded type that does not match with local name of element. - try { - var normalDiv = document.createElement("div", {is: "x-extended-button"}); - ok(false, "An exception should've been thrown"); - } catch(err) { - is(err.name, "NotFoundError", "A NotFoundError exception should've been thrown"); - } - // Custom element constructor. var constructedButton = new buttonConstructor(); is(constructedButton.tagName, "BUTTON", "Created element should have local name of BUTTON"); is(constructedButton.__proto__, extendedProto, "Created element should have the prototype of the extended type."); is(constructedButton.getAttribute("is"), "x-extended-button", "The |is| attribute of the created element should be the extended type."); - // document.createElement with different namespace than definition for extended element. - try { - var htmlText = document.createElement("text", {is: "x-extended-text"}); - ok(false, "An exception should've been thrown"); - } catch(err) { - is(err.name, "NotFoundError", "A NotFoundError exception should've been thrown"); - } - // Try creating an element with a custom element name, but not in the html namespace. var htmlNamespaceProto = Object.create(HTMLElement.prototype); document.registerElement("x-in-html-namespace", { prototype: htmlNamespaceProto }); diff --git a/dom/tests/mochitest/webcomponents/test_document_register_base_queue.html b/dom/tests/mochitest/webcomponents/test_document_register_base_queue.html deleted file mode 100644 index c839857b4..000000000 --- a/dom/tests/mochitest/webcomponents/test_document_register_base_queue.html +++ /dev/null @@ -1,48 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=783129 ---> -<head> - <title>Test for document.registerElement lifecycle callback</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -<script> -var p = Object.create(HTMLElement.prototype); - -var createdCallbackCallCount = 0; - -// By the time the base element queue is processed via the microtask, -// both x-hello elements should be in the document. -p.createdCallback = function() { - var one = document.getElementById("one"); - var two = document.getElementById("two"); - isnot(one, null, "First x-hello element should be in the tree."); - isnot(two, null, "Second x-hello element should be in the tree."); - createdCallbackCallCount++; - if (createdCallbackCallCount == 2) { - SimpleTest.finish(); - } - - if (createdCallbackCallCount > 2) { - ok(false, "Created callback called too much."); - } -}; - -p.attributeChangedCallback = function(name, oldValue, newValue) { - ok(false, "Attribute changed callback should not be called because callbacks should not be queued until created callback invoked."); -}; - -document.registerElement("x-hello", { prototype: p }); - -SimpleTest.waitForExplicitFinish(); -</script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129">Bug 783129</a> -<x-hello id="one"></x-hello> -<x-hello id="two"></x-hello> -<script> -</script> -</body> -</html> diff --git a/dom/tests/mochitest/webcomponents/test_document_register_parser.html b/dom/tests/mochitest/webcomponents/test_document_register_parser.html index bc4cdcbac..a4fb63139 100644 --- a/dom/tests/mochitest/webcomponents/test_document_register_parser.html +++ b/dom/tests/mochitest/webcomponents/test_document_register_parser.html @@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783129 var extendedButtonProto = Object.create(HTMLButtonElement.prototype); var buttonCallbackCalled = false; -extendedButtonProto.createdCallback = function() { +extendedButtonProto.connectedCallback = function() { is(buttonCallbackCalled, false, "created callback for x-button should only be called once."); is(this.tagName, "BUTTON", "Only the <button> element should be upgraded."); buttonCallbackCalled = true; @@ -21,7 +21,7 @@ document.registerElement("x-button", { prototype: extendedButtonProto, extends: var divProto = Object.create(HTMLDivElement.prototype); var divCallbackCalled = false; -divProto.createdCallback = function() { +divProto.connectedCallback = function() { is(divCallbackCalled, false, "created callback for x-div should only be called once."); is(buttonCallbackCalled, true, "crated callback should be called for x-button before x-div."); is(this.tagName, "X-DIV", "Only the <x-div> element should be upgraded."); diff --git a/dom/tests/mochitest/webcomponents/test_document_register_stack.html b/dom/tests/mochitest/webcomponents/test_document_register_stack.html index 34f108654..b1c61af11 100644 --- a/dom/tests/mochitest/webcomponents/test_document_register_stack.html +++ b/dom/tests/mochitest/webcomponents/test_document_register_stack.html @@ -28,7 +28,8 @@ function testChangeAttributeInCreatedCallback() { createdCallbackCalled = true; is(attributeChangedCallbackCalled, false, "Attribute changed callback should not have been called prior to setting the attribute."); this.setAttribute("foo", "bar"); - is(attributeChangedCallbackCalled, false, "While element is being created, element should not be added to the current element callback queue."); + is(attributeChangedCallbackCalled, true, "While element is being created, element should be added to the current element callback queue."); + runNextTest(); }; p.attributeChangedCallback = function(name, oldValue, newValue) { @@ -36,7 +37,6 @@ function testChangeAttributeInCreatedCallback() { is(attributeChangedCallbackCalled, false, "attributeChanged callback should only be called once in this tests."); is(newValue, "bar", "The new value should be 'bar'"); attributeChangedCallbackCalled = true; - runNextTest(); }; document.registerElement("x-one", { prototype: p }); diff --git a/dom/tests/mochitest/webcomponents/test_document_shared_registry.html b/dom/tests/mochitest/webcomponents/test_document_shared_registry.html index 76c2ea8ec..db72e1e6c 100644 --- a/dom/tests/mochitest/webcomponents/test_document_shared_registry.html +++ b/dom/tests/mochitest/webcomponents/test_document_shared_registry.html @@ -14,37 +14,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783129 <script> var container = document.getElementById("container"); -function createdCallbackFromMainDoc() { - var createdCallbackCalled = false; - var assocDoc = document.implementation.createHTMLDocument(); - - var proto = Object.create(HTMLElement.prototype); - proto.createdCallback = function() { - is(createdCallbackCalled, false, "created callback should only be called once in this tests."); - createdCallbackCalled = true; - runNextTest(); - }; - - assocDoc.registerElement("x-associated-doc-callback-elem", { prototype: proto }); - document.createElement("x-associated-doc-callback-elem"); -} - -function createdCallbackFromDocHTMLNamespace() { - var createdCallbackCalled = false; - var assocDoc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null); - var somediv = assocDoc.createElement("div"); - - var proto = Object.create(HTMLElement.prototype); - proto.createdCallback = function() { - is(createdCallbackCalled, false, "created callback should only be called once in this tests."); - createdCallbackCalled = true; - runNextTest(); - }; - - assocDoc.registerElement("x-assoc-doc-with-ns-callback-elem", { prototype: proto }); - document.createElement("x-assoc-doc-with-ns-callback-elem"); -} - function registerNoRegistryDoc() { var assocDoc = document.implementation.createDocument(null, "html"); try { @@ -65,8 +34,6 @@ function runNextTest() { } var testFunctions = [ - createdCallbackFromMainDoc, - createdCallbackFromDocHTMLNamespace, registerNoRegistryDoc, SimpleTest.finish ]; |