Skip to content

Commit

Permalink
implement Page#emulate_idle_state
Browse files Browse the repository at this point in the history
  • Loading branch information
YusukeIwaki committed Dec 26, 2020
1 parent 0f20da3 commit d949bea
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/puppeteer/launcher/chrome.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ def initialize(chrome_arg_options)
'--enable-automation',
'--password-store=basic',
'--use-mock-keychain',
# TODO(sadym): remove '--enable-blink-features=IdleDetection'
# once IdleDetection is turned on by default.
'--enable-blink-features=IdleDetection',
]

if chrome_arg_options.user_data_dir
Expand Down
15 changes: 15 additions & 0 deletions lib/puppeteer/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,21 @@ def emulate_timezone(timezone_id)
end
end

# @param is_user_active [Boolean]
# @param is_screen_unlocked [Boolean]
def emulate_idle_state(is_user_active: nil, is_screen_unlocked: nil)
overrides = {
isUserActive: is_user_active,
isScreenUnlocked: is_screen_unlocked,
}.compact

if overrides.empty?
@client.send_message('Emulation.clearIdleOverride')
else
@client.send_message('Emulation.setIdleOverride', overrides)
end
end

# @param viewport [Viewport]
def viewport=(viewport)
needs_reload = @emulation_manager.emulate_viewport(viewport)
Expand Down
71 changes: 71 additions & 0 deletions spec/integration/idle_override_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require 'spec_helper'

RSpec.describe 'Emulate idle state' do
def idle_state_for(page)
state_element = page.S('#state')
page.evaluate('(element) => element.innerText', state_element)
end

sinatra do
get('/idle-detector.html') do
<<~HTML
<!DOCTYPE html>
<div id="state"></div>
<script>
const elState = document.querySelector('#state');
function setState(msg) {
elState.textContent = msg;
}
async function main() {
const controller = new AbortController();
const signal = controller.signal;
const idleDetector = new IdleDetector({
threshold: 60000,
signal,
});
idleDetector.addEventListener('change', () => {
const userState = idleDetector.userState;
const screenState = idleDetector.screenState;
setState(`Idle state: ${userState}, ${screenState}.`);
});
idleDetector.start();
}
main();
</script>
HTML
end
end

it_fails_firefox 'changing idle state emulation causes change of the IdleDetector state', browser_context: :incognit do
page.browser_context.override_permissions("http://127.0.0.1:4567/idle-detector.html", ['idle-detection'])
page.goto('http://127.0.0.1:4567/idle-detector.html')

# Store initial state, as soon as it is not guaranteed to be `active, unlocked`.
initial_state = idle_state_for(page)

# Emulate Idle states and verify IdleDetector updates state accordingly.
page.emulate_idle_state(is_user_active: false, is_screen_unlocked: false)
expect(idle_state_for(page)).to eq('Idle state: idle, locked.')

page.emulate_idle_state(is_user_active: true, is_screen_unlocked: false)
expect(idle_state_for(page)).to eq('Idle state: active, locked.')

page.emulate_idle_state(is_user_active: true, is_screen_unlocked: true)
expect(idle_state_for(page)).to eq('Idle state: active, unlocked.')

page.emulate_idle_state(is_user_active: false, is_screen_unlocked: true)
expect(idle_state_for(page)).to eq('Idle state: idle, unlocked.')

# Remove Idle emulation and verify IdleDetector is in initial state.
page.emulate_idle_state
expect(idle_state_for(page)).to eq(initial_state)

# Emulate idle state again after removing emulation.
page.emulate_idle_state(is_user_active: false, is_screen_unlocked: false)
expect(idle_state_for(page)).to eq('Idle state: idle, locked.')

# Remove emulation second time.
page.emulate_idle_state
expect(idle_state_for(page)).to eq(initial_state)
end
end

0 comments on commit d949bea

Please sign in to comment.