-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add WPT for error reporting during custom element upgrade
This test currently fails in Chromium. 3/4 subtests fail with: error event should target definition's global but instead targets test harness global" See also: whatwg/dom#1303 Bug: 359909516 Change-Id: I0cc589735d9f8c8ec2c4b55c89aabdb4f7500e17 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5789341 Commit-Queue: Jeremy Roman <[email protected]> Reviewed-by: Mason Freed <[email protected]> Cr-Commit-Position: refs/heads/main@{#1342635}
- Loading branch information
1 parent
170c212
commit f74dcae
Showing
1 changed file
with
84 additions
and
0 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
custom-elements/upgrading/upgrade-custom-element-error-event.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<!DOCTYPE html> | ||
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="../resources/custom-elements-helpers.js"></script> | ||
<body> | ||
<script> | ||
// Returns a promise which will resolve with the next error event fired at any | ||
// of `windows`, after the invocation of this function. Once one does, this | ||
// function removes its listeners and produces that error event so that it can | ||
// be examined (most notably for which global proxy it was targeted at). | ||
async function nextErrorEvent(windows) { | ||
let listener; | ||
let p = new Promise((resolve, reject) => { | ||
listener = (event) => { resolve(event); event.preventDefault(); }; | ||
}); | ||
for (let w of windows) { | ||
w.addEventListener('error', listener); | ||
} | ||
try { | ||
return await p; | ||
} finally { | ||
for (let w of windows) { | ||
w.removeEventListener('error', listener); | ||
} | ||
} | ||
} | ||
const supportsCustomizedBuiltinElements = (function() { | ||
let supported = false; | ||
customElements.define('feature-detect', class extends HTMLDivElement {}, { get extends() { supported = true; return "div"; } }); | ||
return supported; | ||
})(); | ||
|
||
promise_test(async t => { | ||
let w = await create_window_in_test(t, `<script>self.MyElement = class extends HTMLElement { constructor() { throw new Error(); } };</`+`script>`); | ||
let w2 = await create_window_in_test(t); | ||
w2.customElements.define('my-element', w.MyElement); | ||
let nextErrorPromise = nextErrorEvent([self, w, w2]); | ||
let elem = w2.document.createElement('my-element'); | ||
let errorEvent = await nextErrorPromise; | ||
assert_true(elem instanceof w2.HTMLUnknownElement, 'element should be an HTMLUnknownElement'); | ||
if (errorEvent.error) { | ||
assert_true(errorEvent.error instanceof w.Error, 'error should be an instance created inside the MyElement constructor (if it was not muted)'); | ||
} | ||
assert_equals(errorEvent.target, w, `error event should target definition's global but instead targets ${event.target === w2 ? 'document\'s global' : 'test harness global'}`); | ||
}, 'autonomous: exception thrown in constructor is reported to definition\'s global'); | ||
|
||
promise_test(async t => { | ||
let w = await create_window_in_test(t, `<script>self.MyElement = class extends HTMLElement { constructor() { this.textContent = 'hello!'; } };</`+`script>`); | ||
let w2 = await create_window_in_test(t); | ||
w2.customElements.define('my-element', w.MyElement); | ||
let nextErrorPromise = nextErrorEvent([self, w, w2]); | ||
let elem = w2.document.createElement('my-element'); | ||
let errorEvent = await nextErrorPromise; | ||
assert_true(elem instanceof w2.HTMLUnknownElement, 'element should be an HTMLUnknownElement'); | ||
assert_equals(errorEvent.target, w, `error event should target definition's global but instead targets ${event.currentTarget === w2 ? 'document\'s global' : 'test harness global'}`); | ||
}, 'autonomous: exception thrown by spec due to invalid element state is reported to definition\'s global'); | ||
|
||
promise_test(async t => { | ||
assert_implements(supportsCustomizedBuiltinElements, 'customized built-in elements not supported'); | ||
let w = await create_window_in_test(t, `<script>self.MyDivElement = class extends HTMLDivElement { constructor() { throw new Error(); } };</`+`script>`); | ||
let w2 = await create_window_in_test(t); | ||
w2.customElements.define('my-div', w.MyDivElement, {extends: 'div'}); | ||
let nextErrorPromise = nextErrorEvent([self, w, w2]); | ||
let elem = w2.document.createElement('div', {is: 'my-div'}); | ||
let errorEvent = await nextErrorPromise; | ||
assert_equals(Object.getPrototypeOf(elem), w2.HTMLDivElement.prototype, 'element should be an HTMLDivElement (and not inherited from it)'); | ||
assert_true(errorEvent.error instanceof w.Error, 'error should be an instance created inside the MyElement constructor'); | ||
assert_equals(errorEvent.target, w, `error event should target definition's global but instead targets ${event.target === w2 ? 'document\'s global' : 'test harness global'}`); | ||
}, 'customized built-in: exception thrown in constructor is reported to definition\'s global'); | ||
|
||
promise_test(async t => { | ||
assert_implements(supportsCustomizedBuiltinElements, 'customized built-in elements not supported'); | ||
let w = await create_window_in_test(t, `<script>self.MyDivElement = class extends HTMLDivElement { constructor() { return document.createElement('div'); } };</`+`script>`); | ||
let w2 = await create_window_in_test(t); | ||
w2.customElements.define('my-div', w.MyDivElement, {extends: 'div'}); | ||
let nextErrorPromise = nextErrorEvent([self, w, w2]); | ||
let elem = w2.document.createElement('div', {is: 'my-div'}); | ||
let errorEvent = await nextErrorPromise; | ||
assert_equals(Object.getPrototypeOf(elem), w2.HTMLDivElement.prototype, 'element should be an HTMLDivElement (and not inherited from it)'); | ||
assert_equals(errorEvent.target, w, `error event should target definition's global but instead targets ${event.currentTarget === w2 ? 'document\'s global' : 'test harness global'}`); | ||
}, 'customized built-in: exception thrown by spec due to not returning the same value is reported to definition\'s global'); | ||
</script> | ||
</body> |