mirror of
https://github.com/servo/servo.git
synced 2025-07-02 21:13:39 +01:00
190 lines
6.8 KiB
HTML
190 lines
6.8 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<title>Toast: action tests</title>
|
|
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<main></main>
|
|
|
|
<script type="module">
|
|
import { testActionToast, testToastElement, assertActionButtonOnToast } from './resources/helpers.js';
|
|
import { showToast } from 'std:elements/toast';
|
|
|
|
testActionToast((toast) => {
|
|
assert_equals(toast.action.textContent, 'action');
|
|
}, 'the action element gets properly captured with this.action');
|
|
|
|
testActionToast((toast) => {
|
|
toast.innerHTML = `<button slot='action'>new action</button>`
|
|
assert_equals(toast.action.textContent, 'new action');
|
|
}, 'changing the action button changes this.action');
|
|
|
|
testToastElement((toast) => {
|
|
assert_equals(toast.action, null);
|
|
}, 'the action property of a toast without an action is null');
|
|
|
|
testToastElement((toast) => {
|
|
toast.innerHTML = `<button slot="action" id="first">first</button>
|
|
<button slot="action" id="second">second</button>`;
|
|
|
|
assert_equals(toast.action, toast.querySelector('#first'));
|
|
}, 'toast action returns the first item with the action slot');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {action: 'action'});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
}, 'passing an action via showToast creates a button');
|
|
|
|
test(() => {
|
|
const actionMarkup = '<b>strong text</b>';
|
|
const toast = showToast('Message', {action: actionMarkup});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assert_equals(actionButton.textContent, actionMarkup);
|
|
assert_equals(toast.querySelector('b'), null);
|
|
}, 'passing markup to the action option represents as text');
|
|
|
|
test(() => {
|
|
const toast = document.createElement('std-toast');
|
|
toast.textContent = 'Message';
|
|
toast.show({action: 'action'});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assert_equals(actionButton, null);
|
|
}, 'passing action option to show does not create a button');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {action: null});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
assert_equals(actionButton.textContent, 'null');
|
|
}, 'passing non-string (null) as action option stringifies it and creates an action button');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {action: false});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
assert_equals(actionButton.textContent, 'false');
|
|
}, 'passing non-string (false) as action option stringifies it and creates an action button');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {action: 0});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
assert_equals(actionButton.textContent, '0');
|
|
}, 'passing non-string (0) as action option stringifies it and creates an action button');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {action: 1});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
assert_equals(actionButton.textContent, '1');
|
|
}, 'passing non-string (1) as action option stringifies it and creates an action button');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {action: {field: 'value'}});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
assert_equals(actionButton.textContent, '[object Object]');
|
|
}, 'passing non-string ({field: value}) as action option stringifies it and creates an action button');
|
|
|
|
test(() => {
|
|
const toast = showToast('Message', {});
|
|
const actionButton = toast.querySelector('button');
|
|
|
|
assert_equals(actionButton, null);
|
|
}, 'passing non-string (undefined) as action option does not create an action button');
|
|
|
|
testToastElement((toast) => {
|
|
const actionButton = document.createElement('button');
|
|
actionButton.textContent = 'action';
|
|
toast.action = actionButton;
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
}, 'setting the action on an actionless toast inserts the element into the slot');
|
|
|
|
testActionToast((toast, action) => {
|
|
const actionButton = document.createElement('button');
|
|
actionButton.textContent = 'replacement';
|
|
toast.action = actionButton;
|
|
|
|
assert_false(document.contains(action));
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
}, 'resetting the action on an action toast changes the action element');
|
|
|
|
testToastElement((toast) => {
|
|
const text = document.createTextNode('some text');
|
|
assert_throws(new TypeError(), () => {
|
|
toast.action = text;
|
|
});
|
|
}, 'setting the action to an invalid type (Text node) throws an error');
|
|
|
|
testToastElement((toast) => {
|
|
const text = 'some text';
|
|
assert_throws(new TypeError(), () => {
|
|
toast.action = text;
|
|
});
|
|
}, 'setting the action to an invalid type (string) throws an error');
|
|
|
|
test(() => {
|
|
const actionButton = document.createElement('button');
|
|
actionButton.textContent = 'action';
|
|
const toast = showToast('Message', {action: actionButton});
|
|
|
|
assertActionButtonOnToast(actionButton, toast);
|
|
}, 'showToast can take an Element as the action parameter');
|
|
|
|
testActionToast((toast, action) => {
|
|
toast.action = null;
|
|
|
|
assert_not_equals(toast.action, action);
|
|
assert_equals(toast.querySelector('button'), null);
|
|
}, 'setting toast.action to null removes the action from the toast');
|
|
|
|
testActionToast((toast, action) => {
|
|
const wrongAction = document.createElement('button');
|
|
wrongAction.textContent = 'wrong';
|
|
wrongAction.setAttribute('slot', 'action');
|
|
toast.appendChild(wrongAction);
|
|
|
|
const correctAction = document.createElement('button');
|
|
correctAction.textContent = 'correct';
|
|
toast.action = correctAction;
|
|
|
|
assertActionButtonOnToast(correctAction, toast);
|
|
}, 'resetting toast.action on a toast with multiple actions slotted sets properly');
|
|
|
|
test(() => {
|
|
try {
|
|
Object.defineProperty(Element, Symbol.hasInstance, {
|
|
value: () => true,
|
|
configurable: true
|
|
});
|
|
|
|
const fakeElement = {};
|
|
const toast = showToast('Message');
|
|
assert_throws(new TypeError(), () => toast.action = fakeElement);
|
|
} finally {
|
|
delete Element[Symbol.hasInstance];
|
|
}
|
|
}, 'spoofing element instance will not register as element to action setter');
|
|
|
|
test(() => {
|
|
const iframe = document.createElement('iframe');
|
|
document.body.append(iframe);
|
|
iframe.contentDocument.body.innerHTML = '<div></div>';
|
|
const elementFromAnotherFrame = iframe.contentDocument.querySelector('div');
|
|
|
|
// Should not throw:
|
|
const toast = showToast('Message');
|
|
toast.action = elementFromAnotherFrame;
|
|
}, 'element from iframe instance will pass correctly to action without throwing an error');
|
|
</script>
|