diff --git a/resources/test/tests/unit/test-return-restrictions.html b/resources/test/tests/unit/test-return-restrictions.html
new file mode 100644
index 00000000000000..8472ba9c9ed3f0
--- /dev/null
+++ b/resources/test/tests/unit/test-return-restrictions.html
@@ -0,0 +1,155 @@
+
+
+
+
+
+ Restrictions on return value from `test`
+
+
+
+
+
diff --git a/resources/testharness.js b/resources/testharness.js
index 85e211ff60ae55..352e8b76266b7f 100644
--- a/resources/testharness.js
+++ b/resources/testharness.js
@@ -541,7 +541,22 @@ policies and contribution forms [3].
var test_name = name ? name : test_environment.next_default_test_name();
properties = properties ? properties : {};
var test_obj = new Test(test_name, properties);
- test_obj.step(func, test_obj, test_obj);
+ var value = test_obj.step(func, test_obj, test_obj);
+
+ if (value !== undefined) {
+ var msg = "test named \"" + test_name +
+ "\" inappropriately returned a value";
+
+ try {
+ if (value && value.hasOwnProperty("then")) {
+ msg += ", consider using `promise_test` instead";
+ }
+ } catch (err) {}
+
+ tests.status.status = tests.status.ERROR;
+ tests.status.message = msg;
+ }
+
if (test_obj.phase === test_obj.phases.STARTED) {
test_obj.done();
}
diff --git a/web-animations/timing-model/animations/setting-the-target-effect-of-an-animation.html b/web-animations/timing-model/animations/setting-the-target-effect-of-an-animation.html
index 0bcff3bc972181..60ea1850fc5c15 100644
--- a/web-animations/timing-model/animations/setting-the-target-effect-of-an-animation.html
+++ b/web-animations/timing-model/animations/setting-the-target-effect-of-an-animation.html
@@ -113,7 +113,7 @@
'existing animation, the target effect\'s timing is updated to reflect ' +
'the current time of the new animation.');
-test(async t => {
+promise_test(async t => {
const anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
anim.updatePlaybackRate(2);
assert_equals(anim.playbackRate, 1);