diff options
authoranonym <>2020-02-17 14:31:03 +0100
committeranonym <>2020-02-17 15:54:22 +0100
commitc792956cc4f5d98099fe04245c5e45df57cc2cd4 (patch)
parent961ccfca6a0fefbaa70035d91e7e768147a2d060 (diff)
Test suite: fix issue where key modifiers affect subsequent key presses.test/15460-replace-sikuli-force-all-tests
We have seen the test suite write "P?+(FJZ" when it was supposed to type "P/+9fjz", just like if the Shift key got stuck at the "P" with an US keyboard layout. We try to fix this in two ways: First, by setting a holdtime > 0 when telling libvirt to press keys. According to my tests, this alone might fix it (even with delay = 0). However, there's another issue: the libvirt's send_key() is asynchronous, so it won't block until it has emitted the key, which will get in the way when we write tests. For example: step 'I run "touch /tmp/test" in GNOME Terminal' assert($vm.file_exist?('/tmp/test') can fail since the step invocation might return before it has typed the command and pressed Return, so we'll check for the file before it has been created. So, secondly, we enforce a big enough delay between key presses to do this, *and* we move this delay from type() to press() so we cannot escape this delay.
1 files changed, 14 insertions, 2 deletions
diff --git a/features/support/helpers/screen.rb b/features/support/helpers/screen.rb
index 4f112b0..9114c45 100644
--- a/features/support/helpers/screen.rb
+++ b/features/support/helpers/screen.rb
@@ -197,6 +197,17 @@ class Screen
def press(*sequence, **opts)
opts[:log] = true if opts[:log].nil?
+ # This is the minimum time (in seconds) between key presses;
+ # repeatedly calling this method will ensure that key presses are
+ # emitted with this minimum interval. This helps preventing
+ # repeated calls interfering with each other.
+ opts[:delay] ||= 0.060 # Sikuli used 60ms delay.
+ # How long the key(s) are held (in seconds). With holdtime = 0
+ # (like virsh does it) we have seen issues, in particular with key
+ # modifiers like Shift bleeding over to subsequent invocations, so
+ # e.g. type("A9f") actually results in "A(F" (with a US layout)
+ # because the Shift wasn't released *immediately* after the "A".
+ opts[:holdtime] ||= 0.010
debug_log("Keyboard: pressing: #{sequence.join('+')}") if opts[:log]
codes = []
sequence.each do |key|
@@ -213,7 +224,9 @@ class Screen
codes += code
- $vm.domain.send_key(Libvirt::Domain::KEYCODE_SET_LINUX, 0, codes)
+ $vm.domain.send_key(Libvirt::Domain::KEYCODE_SET_LINUX,
+ (opts[:holdtime]*1000).to_i, codes)
+ sleep(opts[:delay])
return nil
@@ -223,7 +236,6 @@ class Screen
debug_log("Keyboard: typing: #{arg}")
arg.each_char do |char|
press(char, log: false)
- sleep 0.060
elsif arg.instance_of?(Array)