diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
index 1a426a356a3d4d5d3507600f2cdb0ba296b7aa54..c26752b2de6a455a05fed8a1e85af9eb50963ffd 100644
--- a/src/gui/mainwindow.cpp
+++ b/src/gui/mainwindow.cpp
@@ -1032,7 +1032,7 @@ void MainWindow::invoke(Callable *callable)
 }
 
 #ifdef HAS_TESTS
-void MainWindow::keyClicks(const QString &keys)
+void MainWindow::keyClicks(const QString &keys, int delay)
 {
     QWidget *widget;
 
@@ -1048,9 +1048,11 @@ void MainWindow::keyClicks(const QString &keys)
         }
     }
 
+    const auto className = widget->metaObject()->className();
+
     auto widgetName = QString("%1:%2")
             .arg(widget->objectName())
-            .arg(widget->metaObject()->className());
+            .arg(className);
 
     if (widget != widget->window()) {
         widgetName.append(
@@ -1059,12 +1061,17 @@ void MainWindow::keyClicks(const QString &keys)
                     .arg(widget->window()->metaObject()->className()) );
     }
 
+    // There could be some animation/transition effect on check boxes
+    // so wait for checkbox to be set.
+    if ( className == QString("QCheckBox") )
+        waitFor(100);
+
     COPYQ_LOG( QString("Sending keys \"%1\" to %2.")
                .arg(keys)
                .arg(widgetName) );
 
     if ( keys.startsWith(":") ) {
-        QTest::keyClicks(widget, keys.mid(1), Qt::NoModifier, 50);
+        QTest::keyClicks(widget, keys.mid(1), Qt::NoModifier, delay);
 
         // Increment key clicks sequence number after typing all the text.
         ++m_receivedKeyClicks;
@@ -1094,11 +1101,12 @@ void MainWindow::keyClicks(const QString &keys)
                .arg(widgetName) );
 }
 
-uint MainWindow::sendKeyClicks(const QString &keys)
+uint MainWindow::sendKeyClicks(const QString &keys, int delay)
 {
     // Don't stop when modal window is open.
     QMetaObject::invokeMethod( this, "keyClicks", Qt::QueuedConnection,
-                               Q_ARG(const QString &, keys)
+                               Q_ARG(const QString &, keys),
+                               Q_ARG(int, delay)
                                );
 
     return ++m_sentKeyClicks;
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
index 6cbad647e5d42c1f205bdc35c853c01ae42feead..d01525908ad71bd57e5daade3261a80340277bcc 100644
--- a/src/gui/mainwindow.h
+++ b/src/gui/mainwindow.h
@@ -437,13 +437,13 @@ public slots:
      *
      * Increments key clicks sequence number returned by lastReceivedKeyClicks().
      */
-    void keyClicks(const QString &keys);
+    void keyClicks(const QString &keys, int delay);
 
     /**
      * Send key clicks to focused widget.
      * @return Key clicks sequence number.
      */
-    uint sendKeyClicks(const QString &keys);
+    uint sendKeyClicks(const QString &keys, int delay);
 
     /**
      * @return Last key clicks sequence number received by widgets.
diff --git a/src/scriptable/scriptable.cpp b/src/scriptable/scriptable.cpp
index 7ae230d3f903a5ae3430bf9c8fd29f62719ed536..84a98c242a2c2c920dd2ec82528234d6b025f56c 100644
--- a/src/scriptable/scriptable.cpp
+++ b/src/scriptable/scriptable.cpp
@@ -1058,11 +1058,25 @@ void Scriptable::fail()
 void Scriptable::keys()
 {
 #ifdef HAS_TESTS
+    bool ok;
+
+    // Wait interval after shortcut pressed or text typed.
+    const auto waitValue = qgetenv("COPYQ_TESTS_KEYS_WAIT");
+    int wait = waitValue.toInt(&ok);
+    if (!ok)
+        wait = 0;
+
+    // Delay while typing.
+    const auto delayValue = qgetenv("COPYQ_TESTS_KEY_DELAY");
+    int delay = delayValue.toInt(&ok);
+    if (!ok)
+        delay = 0;
+
     for (int i = 0; i < argumentCount(); ++i) {
         const QString keys = toString(argument(i));
 
-        waitFor(500);
-        m_proxy->sendKeys(keys);
+        waitFor(wait);
+        m_proxy->sendKeys(keys, delay);
 
         // Make sure all keys are send (shortcuts are postponed because they can be blocked by modal windows).
         while ( !m_proxy->keysSent() ) {
diff --git a/src/scriptable/scriptableproxy.cpp b/src/scriptable/scriptableproxy.cpp
index 9995aa5c7fcbf661b164ad9a8478e9c68a32a346..b1d044670e384fbafdc3de884824efc05c843364 100644
--- a/src/scriptable/scriptableproxy.cpp
+++ b/src/scriptable/scriptableproxy.cpp
@@ -853,10 +853,10 @@ QList<int> ScriptableProxy::selectedItems()
 }
 
 #ifdef HAS_TESTS
-void ScriptableProxy::sendKeys(const QString &keys)
+void ScriptableProxy::sendKeys(const QString &keys, int delay)
 {
-    INVOKE2(sendKeys(keys));
-    m_sentKeyClicks = m_wnd->sendKeyClicks(keys);
+    INVOKE2(sendKeys(keys, delay));
+    m_sentKeyClicks = m_wnd->sendKeyClicks(keys, delay);
 }
 
 bool ScriptableProxy::keysSent()
diff --git a/src/scriptable/scriptableproxy.h b/src/scriptable/scriptableproxy.h
index 9afdc7a218e9f8047dfadd8403049dc94fe27872..798dac224bfb0b8954edb566188d799d0cc5f2b7 100644
--- a/src/scriptable/scriptableproxy.h
+++ b/src/scriptable/scriptableproxy.h
@@ -151,7 +151,7 @@ public:
     QList<int> selectedItems();
 
 #ifdef HAS_TESTS
-    void sendKeys(const QString &keys);
+    void sendKeys(const QString &keys, int delay);
     bool keysSent();
     QString testSelected();
 #endif // HAS_TESTS
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
index fed4ce56980081704444181877e077f2635c68d7..add3907b8decc091492c68ba09fd11a94a4accd0 100644
--- a/src/tests/tests.cpp
+++ b/src/tests/tests.cpp
@@ -1473,7 +1473,8 @@ void Tests::openAndSavePreferences()
 
     // Focus and set wrap text option.
     // This behavior could differ on some systems and in other languages.
-    RUN("keys" << "ALT+1" << "ENTER", "");
+    RUN("keys" << "ALT+1", "");
+    RUN("keys" << "ENTER", "");
     RUN(args, "true\n");
 
     RUN(args << "false", "");