blob: 25dea12b8dce970e2a164fb1f49d26a97952dcc7 [file] [log] [blame]
<!DOCTYPE html>
<link rel="help" href="https://github.com/samuelgoto/idle-detection">
<title>Tests the Idle Detection API</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/test-only-api.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/idle-detection-helper.js"></script>
<script>
'use strict';
promise_setup(async t => {
await test_driver.set_permission({ name: 'idle-detection' }, 'granted', false);
if (isChromiumBased) {
await loadChromiumResources();
}
})
promise_test(async t => {
// Basic test that expects start() to call internally
// addMonitor, which in turn return an ACTIVE state.
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.LOCKED
}
});
});
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
assert_equals(detector.userState, "active");
assert_equals(detector.screenState, "locked");
controller.abort();
}, 'start()');
promise_test(async t => {
// Verifies that an event is thrown when a change of state from IDLE to ACTIVE
// is detected.
expect(addMonitor).andReturn((threshold, monitorPtr) => {
let first = Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.UNLOCKED
}
});
t.step_timeout(() => {
monitorPtr.update({
user: UserIdleState.IDLE,
screen: ScreenIdleState.UNLOCKED
});
}, 0);
return first;
});
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
// Wait for the first change in state.
await watcher.wait_for("change");
assert_equals(detector.userState, "idle");
assert_equals(detector.screenState, "unlocked");
controller.abort();
}, 'updates once');
promise_test(async t => {
// Simulates the user being active, going idle and then going back active
// again.
expect(addMonitor).andReturn((threshold, monitorPtr) => {
let first = Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.UNLOCKED
}
});
// Updates the client once with the user idle.
t.step_timeout(() => {
monitorPtr.update({
user: UserIdleState.IDLE,
screen: ScreenIdleState.UNLOCKED
});
}, 0);
// Updates the client a second time with the user active.
t.step_timeout(() => {
monitorPtr.update({
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.UNLOCKED
});
}, 1);
return first;
});
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
// Waits for the first event.
await watcher.wait_for("change");
assert_equals(detector.userState, "idle");
// Waits for the second event.
await watcher.wait_for("change");
assert_equals(detector.userState, "active");
controller.abort();
}, 'updates twice');
promise_test(async t => {
// Simulates a locked screen.
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.LOCKED
}
});
});
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
assert_equals(detector.screenState, "locked");
controller.abort();
}, 'locked screen');
promise_test(async t => {
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.LOCKED
}
});
});
const controller = new AbortController();
const detector = new IdleDetector();
let event = new Promise((resolve, reject) => {
detector.onchange = resolve;
});
await detector.start({ signal: controller.signal });
// Waits for the first event.
await event;
assert_equals(detector.userState, "active");
assert_equals(detector.screenState, "locked");
controller.abort();
}, 'IdleDetector.onchange');
promise_test(async t => {
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.UNLOCKED
}
});
});
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
// Only the first call to start() is allowed.
const start_promise = detector.start();
await promise_rejects_dom(t, 'InvalidStateError', detector.start());
await start_promise;
await initial_state;
assert_equals(detector.userState, "active");
assert_equals(detector.screenState, "unlocked");
// Calling abort() multiple times is safe.
controller.abort();
controller.abort();
controller.abort();
controller.abort();
}, 'Safe to call start() or stop() multiple times');
promise_test(async t => {
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.UNLOCKED
}
});
});
const controller = new AbortController();
const detector = new IdleDetector();
// Calling abort() before start() causes start() to fail.
controller.abort();
await promise_rejects_dom(
t, 'AbortError', detector.start({ signal: controller.signal }));
}, 'Calling stop() after start() is a no-op');
promise_test(async t => {
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.ACTIVE,
screen: ScreenIdleState.UNLOCKED
}
});
});
let controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
controller.abort();
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
state: {
user: UserIdleState.IDLE,
screen: ScreenIdleState.LOCKED
}
});
});
// Restarting the monitor.
controller = new AbortController();
initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
assert_equals(detector.userState, "idle");
assert_equals(detector.screenState, "locked");
controller.abort();
}, 'Calling start() after stop(): re-starting monitor.');
</script>