зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1556471 [wpt PR 17146] - Initial implementation of std-toast, a=testonly
Automatic update from web-platform-tests Initial implementation of std-toast Intent to Implement: https://groups.google.com/a/chromium.org/forum/?utm_source=digest&utm_medium=email#!topic/blink-dev/Gl7FIKM5IFw BUG=972945 Follow-ups will align with std-switch in elements and de-duplicate the .eslintrc.js files between toast and kv-storage. Change-Id: Ib5837ccf8c9ea03fd2f1f2bd581e443a2936f693 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1635867 Commit-Queue: Jack Steinberg <jacksteinberg@chromium.org> Commit-Queue: Fergal Daly <fergal@chromium.org> Reviewed-by: Kouhei Ueno <kouhei@chromium.org> Cr-Commit-Position: refs/heads/master@{#670383} -- wpt-commits: 17de974a80b0d9a6ff48dc24796441057afad5a0 wpt-pr: 17146
This commit is contained in:
Родитель
4b03795d44
Коммит
99eb349595
|
@ -0,0 +1,5 @@
|
|||
spec: https://github.com/jackbsteinberg/std-toast
|
||||
suggested_reviewers:
|
||||
- domenic
|
||||
- fergald
|
||||
- jackbsteinberg
|
|
@ -0,0 +1,116 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Toast: attribute tests</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<main></main>
|
||||
|
||||
<script type="module">
|
||||
import { testToastElement, assertToastShown, assertToastNotShown, testToastElementAsync } from './resources/helpers.js';
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.setAttribute('open', '');
|
||||
assertToastShown(toast);
|
||||
}, 'setting `open` on a hidden toast shows the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.setAttribute('open', false);
|
||||
assertToastShown(toast);
|
||||
}, 'setting `open` to false on a hidden toast shows the toast, because of string conversion');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.setAttribute('open', 'test');
|
||||
assertToastShown(toast);
|
||||
}, 'setting `open` on a shown toast does nothing');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.setAttribute('open', 'test');
|
||||
toast.setAttribute('open', 'test');
|
||||
assertToastShown(toast);
|
||||
}, 'resetting `open` on a shown toast does nothing');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.setAttribute('open', false);
|
||||
assertToastShown(toast);
|
||||
}, 'setting `open` to false on a shown toast does nothing, because of string conversion');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.removeAttribute('open');
|
||||
assertToastNotShown(toast);
|
||||
}, 'removing `open` hides the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
assert_true(toast.hasAttribute('open'));
|
||||
}, 'showing the toast adds open attribute');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.hide();
|
||||
assert_false(toast.hasAttribute('open'));
|
||||
}, 'hiding the toast removes open attribute');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggleAttribute('open');
|
||||
assert_true(toast.hasAttribute('open'));
|
||||
}, 'toggling `open` on a hidden toast sets the open attribute');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggleAttribute('open');
|
||||
toast.toggleAttribute('open');
|
||||
assert_false(toast.hasAttribute('open'));
|
||||
}, 'toggling `open` twice leaves the toast with no open attribute');
|
||||
|
||||
testToastElement((toast) => {
|
||||
assert_false(toast.open);
|
||||
}, 'the `toast.open` boolean is false for a hidden toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
assert_true(toast.open);
|
||||
}, 'the `toast.open` boolean is true for a shown toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.open = true;
|
||||
assertToastShown(toast);
|
||||
assert_equals(toast.getAttribute('open'), '');
|
||||
}, 'setting `toast.open` to true on a hidden toast will show the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.open = false;
|
||||
assertToastNotShown(toast);
|
||||
}, 'setting `toast.open` to false on a shown toast will hide the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.open = 'truthy!';
|
||||
assertToastShown(toast);
|
||||
assert_equals(toast.getAttribute('open'), '');
|
||||
}, 'setting `toast.open` to some truthy value on a hidden toast will show the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.open = '';
|
||||
assertToastNotShown(toast);
|
||||
}, 'setting `toast.open` to some falsy value on a shown toast will hide the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggleAttribute('open');
|
||||
assert_true(toast.open);
|
||||
}, 'toggling `open` on a hidden toast sets `toast.open` to true');
|
||||
|
||||
testToastElementAsync((t, toast) => {
|
||||
toast.toggleAttribute('open', true);
|
||||
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
t.done();
|
||||
}, 2000);
|
||||
}, 'toggling open attribute does not start timeout');
|
||||
</script>
|
|
@ -0,0 +1,73 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Toast: Event tests</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<main></main>
|
||||
|
||||
<script type="module">
|
||||
import { testToastElement, EventCollector } from './resources/helpers.js';
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.addEventListener('show', (e) => {
|
||||
counter.getCallback()(e);
|
||||
});
|
||||
toast.open = true;
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'setting open to true on a hidden toast triggers the `show` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.open = true;
|
||||
toast.addEventListener('show', counter.getCallback());
|
||||
toast.open = true;
|
||||
|
||||
assert_equals(counter.getCount(), 0);
|
||||
}, 'setting open to true on a shown toast does not trigger the `show` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.addEventListener('hide', counter.getCallback());
|
||||
toast.open = false;
|
||||
|
||||
assert_equals(counter.getCount(), 0);
|
||||
}, 'setting open to false on a hidden toast does not trigger the `hide` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.show();
|
||||
toast.addEventListener('hide', counter.getCallback());
|
||||
toast.open = false;
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'setting open to false on a shown toast triggers the `hide` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.addEventListener('show', counter.getCallback());
|
||||
toast.open = true;
|
||||
toast.open = true;
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'setting open to true twice only triggers the `show` event once');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.show();
|
||||
toast.addEventListener('hide', counter.getCallback());
|
||||
toast.open = false;
|
||||
toast.open = false;
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'setting open to false twice only triggers the `hide` event once');
|
||||
</script>
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Toast: Event tests</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<main></main>
|
||||
|
||||
<script type="module">
|
||||
import { testToastElement, EventCollector } from './resources/helpers.js';
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.addEventListener('show', counter.getCallback());
|
||||
toast.show();
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'calling `show()` on a hidden toast triggers the `show` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.show();
|
||||
toast.addEventListener('show', counter.getCallback());
|
||||
toast.show();
|
||||
|
||||
assert_equals(counter.getCount(), 0);
|
||||
}, 'calling `show()` on a shown toast does not trigger the `show` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.addEventListener('hide', counter.getCallback());
|
||||
toast.hide();
|
||||
|
||||
assert_equals(counter.getCount(), 0);
|
||||
}, 'calling `hide()` on a hidden toast does not trigger the `hide` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.show();
|
||||
toast.addEventListener('hide', counter.getCallback());
|
||||
toast.hide();
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'calling `hide()` on a shown toast triggers the `hide` event');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.addEventListener('show', counter.getCallback());
|
||||
toast.show();
|
||||
toast.show();
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'calling `show()` twice only triggers the `show` event once');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const counter = new EventCollector();
|
||||
|
||||
toast.show();
|
||||
toast.addEventListener('hide', counter.getCallback());
|
||||
toast.hide();
|
||||
toast.hide();
|
||||
|
||||
assert_equals(counter.getCount(), 1);
|
||||
}, 'calling `hide()` twice only triggers the `hide` event once');
|
||||
|
||||
testToastElement((toast) => {
|
||||
const events = new EventCollector();
|
||||
|
||||
toast.addEventListener('show', events.getCallback());
|
||||
|
||||
toast.show();
|
||||
toast.hide();
|
||||
toast.show();
|
||||
|
||||
assert_equals(events.getCount(), 2);
|
||||
assert_not_equals(events.getEvents()[0], events.getEvents()[1]);
|
||||
}, "separate openings trigger different `show` events");
|
||||
|
||||
testToastElement((toast) => {
|
||||
const events = new EventCollector();
|
||||
|
||||
toast.addEventListener('hide', events.getCallback());
|
||||
|
||||
toast.show();
|
||||
toast.hide();
|
||||
toast.show();
|
||||
toast.hide();
|
||||
|
||||
assert_equals(events.getCount(), 2);
|
||||
assert_not_equals(events.getEvents()[0], events.getEvents()[1]);
|
||||
}, "separate closings trigger different `hide` events");
|
||||
</script>
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Toast: method tests</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<main></main>
|
||||
<div></div>
|
||||
|
||||
<script type="module">
|
||||
import { testToastElement, assertToastShown, assertToastNotShown, testToastElementAsync } from './resources/helpers.js';
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
|
||||
assertToastShown(toast);
|
||||
}, 'calling `show()` on a hidden toast opens and displays it');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggleAttribute('open');
|
||||
toast.show();
|
||||
|
||||
assertToastShown(toast);
|
||||
}, 'calling `show()` on a shown toast does nothing');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggleAttribute('open');
|
||||
toast.hide();
|
||||
|
||||
assertToastNotShown(toast);
|
||||
}, 'calling `hide()` on a shown toast hides the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.hide();
|
||||
|
||||
assertToastNotShown(toast);
|
||||
}, 'calling `hide()` on a hidden toast does nothing');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggle();
|
||||
|
||||
assertToastShown(toast);
|
||||
}, 'calling `toggle()` on a hidden toast shows the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.toggle();
|
||||
|
||||
assertToastNotShown(toast);
|
||||
}, 'calling `toggle()` on a shown toast hides the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggle(true);
|
||||
|
||||
assertToastShown(toast);
|
||||
}, 'calling `toggle()` with `force` parameter set to true on a hidden opens the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.toggle(true);
|
||||
|
||||
assertToastShown(toast);
|
||||
}, 'calling `toggle()` with `force` parameter set to true on a shown toast does not close the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.toggle(false);
|
||||
|
||||
assertToastNotShown(toast);
|
||||
}, 'calling `toggle()` with `force` parameter set to false on a hidden toast does not open the toast');
|
||||
|
||||
testToastElement((toast) => {
|
||||
toast.show();
|
||||
toast.toggle(false);
|
||||
|
||||
assertToastNotShown(toast);
|
||||
}, 'calling `toggle()` with `force` parameter set to false on a shown toast closes the toast');
|
||||
|
||||
testToastElementAsync((t, toast) => {
|
||||
toast.show();
|
||||
|
||||
// time = 999
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
toast.show();
|
||||
|
||||
// time = 2000
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
|
||||
// time = 3000
|
||||
t.step_timeout(() => {
|
||||
assertToastNotShown(toast);
|
||||
t.done();
|
||||
}, 1000);
|
||||
}, 1001);
|
||||
}, 999);
|
||||
}, 'calling `show()` twice resets the timeout');
|
||||
|
||||
testToastElementAsync((t, toast) => {
|
||||
toast.show();
|
||||
|
||||
// time = 999
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
toast.hide();
|
||||
|
||||
// time = 1000
|
||||
t.step_timeout(() => {
|
||||
assertToastNotShown(toast);
|
||||
|
||||
// time = 1500
|
||||
t.step_timeout(() => {
|
||||
toast.show();
|
||||
|
||||
// time = 2500
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
t.done();
|
||||
}, 1000);
|
||||
}, 500);
|
||||
}, 1);
|
||||
}, 999);
|
||||
}, 'calling `hide()` clears the timeout');
|
||||
</script>
|
|
@ -0,0 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>Toast: showToast tests</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
|
||||
<script type="module">
|
||||
import { showToast, StdToastElement } from 'std:toast';
|
||||
import { assertToastNotShown, assertToastShown } from './resources/helpers.js';
|
||||
|
||||
// message
|
||||
test(() => {
|
||||
const toast = new StdToastElement(false);
|
||||
document.body.appendChild(toast);
|
||||
|
||||
assert_equals(toast.textContent, 'false');
|
||||
}), 'passing false as message converts to the string `false`';
|
||||
|
||||
test(() => {
|
||||
const toast = new StdToastElement('<p>rich text</p>');
|
||||
document.body.appendChild(toast);
|
||||
|
||||
assert_equals(toast.textContent, '<p>rich text</p>');
|
||||
assert_equals(toast.querySelector('p'), null);
|
||||
}, 'passing markup to the constructor does not pass through the markup behaviors');
|
||||
|
||||
test(() => {
|
||||
const toastString = '<std-toast id="test">test</std-toast>';
|
||||
document.body.innerHTML = toastString;
|
||||
const toast = document.body.querySelector('#test');
|
||||
|
||||
assert_equals(toast.textContent, 'test');
|
||||
}, 'HTML created toast has `test` as its text content');
|
||||
|
||||
// duration
|
||||
async_test(t => {
|
||||
const toast = showToast('message');
|
||||
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
}, 1999);
|
||||
|
||||
t.step_timeout(() => {
|
||||
assertToastNotShown(toast);
|
||||
t.done();
|
||||
}, 2000);
|
||||
|
||||
t.add_cleanup(function() {
|
||||
toast.remove();
|
||||
});
|
||||
}, 'showToast closes after default duration of 2000ms');
|
||||
|
||||
async_test(t => {
|
||||
const toast = showToast('message', {duration: 1000});
|
||||
|
||||
t.step_timeout(() => {
|
||||
assertToastShown(toast);
|
||||
}, 999);
|
||||
|
||||
t.step_timeout(() => {
|
||||
assertToastNotShown(toast);
|
||||
t.done();
|
||||
}, 1000);
|
||||
|
||||
t.add_cleanup(function() {
|
||||
toast.remove();
|
||||
});
|
||||
}, 'showToast closes after user specified 1000ms');
|
||||
</script>
|
|
@ -0,0 +1,70 @@
|
|||
import { showToast, StdToastElement } from 'std:toast';
|
||||
|
||||
// helper functions to keep tests from bleeding into each other
|
||||
|
||||
const runTest = (testFn, name, toast) => {
|
||||
try {
|
||||
test(() => {
|
||||
testFn(toast);
|
||||
}, name);
|
||||
} finally {
|
||||
toast.remove();
|
||||
}
|
||||
};
|
||||
|
||||
const runTestAsync = (testFn, name, toast) => {
|
||||
async_test(t => {
|
||||
testFn(t, toast);
|
||||
t.add_cleanup(() => {
|
||||
toast.remove();
|
||||
});
|
||||
}, name);
|
||||
};
|
||||
|
||||
export const testToastElement = (testFn, name) => {
|
||||
const toast = new StdToastElement('Message', {});
|
||||
document.querySelector('main').appendChild(toast);
|
||||
|
||||
runTest(testFn, name, toast);
|
||||
};
|
||||
|
||||
export const testToastElementAsync = (testFn, name) => {
|
||||
const toast = new StdToastElement('Message', {});
|
||||
document.querySelector('main').appendChild(toast);
|
||||
|
||||
runTestAsync(testFn, name, toast);
|
||||
};
|
||||
|
||||
export const testShowToast = (testFn, name) => {
|
||||
const toast = showToast("message");
|
||||
|
||||
runTest(testFn, name, toast);
|
||||
};
|
||||
|
||||
export const assertToastShown = (toast) => {
|
||||
assert_not_equals(window.getComputedStyle(toast).display, 'none');
|
||||
assert_true(toast.hasAttribute('open'));
|
||||
assert_true(toast.open);
|
||||
};
|
||||
|
||||
export const assertToastNotShown = (toast) => {
|
||||
assert_equals(window.getComputedStyle(toast).display, 'none');
|
||||
assert_false(toast.hasAttribute('open'));
|
||||
assert_false(toast.open);
|
||||
};
|
||||
|
||||
export class EventCollector {
|
||||
events = [];
|
||||
|
||||
getCallback() {
|
||||
return (e) => {this.events.push(e)};
|
||||
}
|
||||
|
||||
getCount() {
|
||||
return this.events.length;
|
||||
}
|
||||
|
||||
getEvents() {
|
||||
return this.events;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Toast: showToast tests</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
|
||||
<script type="module">
|
||||
import { showToast, StdToastElement } from 'std:toast';
|
||||
import { testShowToast, assertToastNotShown, assertToastShown } from './resources/helpers.js';
|
||||
|
||||
testShowToast((toast) => {
|
||||
assert_true(toast != null);
|
||||
assert_true(toast instanceof StdToastElement);
|
||||
}, 'showToast creates and returns a toast');
|
||||
|
||||
testShowToast((toast) => {
|
||||
assert_true(document.querySelector('std-toast') === toast);
|
||||
}, 'showToast puts the toast in the DOM');
|
||||
|
||||
testShowToast((toast) => {
|
||||
assertToastShown(toast);
|
||||
}, 'showToast displays the toast by default');
|
||||
|
||||
testShowToast((toast) => {
|
||||
toast.hide();
|
||||
|
||||
assertToastNotShown(toast);
|
||||
}, 'hiding showToast immediately does not display it');
|
||||
|
||||
testShowToast((toast) => {
|
||||
toast.show();
|
||||
|
||||
assertToastShown(toast);
|
||||
}, 'calling show after showToast does nothing');
|
||||
|
||||
testShowToast((toast) => {
|
||||
let toast2;
|
||||
try {
|
||||
toast2 = showToast('message2');
|
||||
|
||||
assert_not_equals(toast, toast2);
|
||||
}
|
||||
finally {
|
||||
toast2.remove();
|
||||
}
|
||||
}, 'calling showToast multiple times creates multiple different toasts');
|
||||
|
||||
test(() => {
|
||||
const toast = showToast('test');
|
||||
assert_equals(toast.textContent, 'test');
|
||||
}, 'showToast created toast has `test` as its text content');
|
||||
|
||||
test(() => {
|
||||
const toast = showToast('<p>rich text</p>');
|
||||
|
||||
assert_equals(toast.textContent, '<p>rich text</p>');
|
||||
assert_equals(toast.querySelector('p'), null);
|
||||
}, 'passing markup to showToast does not pass through the markup behaviors');
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче