| <!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> |