diff --git a/src-test/org/openbravo/test/mobile/common/selenium/SeleniumHelper.java b/src-test/org/openbravo/test/mobile/common/selenium/SeleniumHelper.java
--- a/src-test/org/openbravo/test/mobile/common/selenium/SeleniumHelper.java
+++ b/src-test/org/openbravo/test/mobile/common/selenium/SeleniumHelper.java
@@ -42,6 +42,7 @@
 import org.openbravo.test.mobile.common.selenium.utils.Utils;
 import org.openqa.selenium.Alert;
 import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.Keys;
 import org.openqa.selenium.OutputType;
 import org.openqa.selenium.WebDriverException;
 import org.openqa.selenium.chrome.ChromeOptions;
@@ -56,7 +57,7 @@
 
 /**
  * Selenium Singleton class, accessible from every class in the project.
- *
+ * 
  */
 public class SeleniumHelper {
 
@@ -76,7 +77,7 @@
 
   /**
    * Start the selenium instance.
-   *
+   * 
    * @param terminal
    *          e.g: "VBS1001" or "" for secure terminal
    */
@@ -198,7 +199,7 @@
 
   /**
    * Closes and quits the selenium instance if exists
-   *
+   * 
    * @param MobileCoreTerminalHelper
    */
   public static void quit(final MobileCoreTerminalHelper mobileCoreTerminalHelper) {
@@ -342,7 +343,7 @@
 
   /**
    * Sends a javascript script to the chrome engine
-   *
+   * 
    * @param script
    *          the script to be processed. Be aware that this script should instantly return
    * @param args
@@ -360,7 +361,7 @@
 
   /**
    * Sends a javascript script to the chrome engine
-   *
+   * 
    * @param script
    *          the script to be processed. Be aware that this script should instantly return
    * @param args
@@ -381,7 +382,7 @@
 
   /**
    * Core method to execute javascript in the browser
-   *
+   * 
    * @param scriptToExecute
    * @param args
    * @return Object result of the execution
@@ -425,7 +426,7 @@
   /**
    * Finds the DOM id in the DOM and returns the result. Be aware that this should allays return
    * instantly, so check before calling this function if the DOM id exists
-   *
+   * 
    * @param idDOM
    *          the idDOM to be processed
    * @return the object found
@@ -439,7 +440,7 @@
 
   /**
    * Takes an snapshot of the webpage if the selenium driver is up. Otherwise creates a file
-   *
+   * 
    * @param message
    *          the message to be appended to the file name
    */
@@ -449,7 +450,7 @@
 
   /**
    * Takes an snapshot of the webpage if the selenium driver is up. Otherwise creates a file
-   *
+   * 
    * @param message
    *          the message to be appended to the file name
    * @param errorMessage
@@ -488,7 +489,7 @@
   /**
    * Checks if an alert is present in the webpage. Be aware that if its not present it will stuck
    * for sometime
-   *
+   * 
    * @return if the alert was found
    */
   public static boolean isAlertPresent() {
@@ -515,4 +516,8 @@
     throw new WebDriverException(errorMessageTmp);
   }
 
+  public static void pressKey(Keys keyToPress) {
+    INSTANCE.getKeyboard().pressKey(keyToPress);
+  }
+
 }
\ No newline at end of file
diff --git a/src-test/org/openbravo/test/mobile/common/selenium/javascript/EnyoNode.java b/src-test/org/openbravo/test/mobile/common/selenium/javascript/EnyoNode.java
--- a/src-test/org/openbravo/test/mobile/common/selenium/javascript/EnyoNode.java
+++ b/src-test/org/openbravo/test/mobile/common/selenium/javascript/EnyoNode.java
@@ -67,7 +67,7 @@
   /**
    * Returns the DOM TestId of the enyo node as seen in the DOM when the
    * TestRegistry.appendTestIdToDOM() command has been executed in the chrome console
-   *
+   * 
    * @return the DOM TestId
    */
   public String getTestIdDOM() {
@@ -81,7 +81,7 @@
   /**
    * Executes the script. Will return what Selenium returns, if you expect a return it is better to
    * use {@link #executeWithReturn(String)}
-   *
+   * 
    * @param scriptSuffix
    *          The code to append to 'this.TestRegistry.registry('%s').enyoObject
    * @return The result of the execution
@@ -93,7 +93,7 @@
 
   /**
    * Executes the script with a javascript return statement before the script
-   *
+   * 
    * @param scriptSuffix
    *          The code to append to 'return this.TestRegistry.registry('%s').enyoObject
    * @return The result of the execution
@@ -139,9 +139,7 @@
     if (!isValid()) {
       return false;
     }
-    // this seems to be always true if isValid() is true.
-    // return (Boolean) executeWithReturn(".showing");
-    return true;
+    return (Boolean) executeWithReturn(".showing");
   }
 
   private boolean hasFunction(final String functionName) {
@@ -198,10 +196,10 @@
       if (!methodExists) {
         final String enyoName = (String) executeWithReturn(".name");
         logger
-        .warn(String
-            .format(
-                "'%s' is missing the 'getDisabled()' method. Add 'published: {disabled: false}' to the '%s' enyo object",
-                getTestIdDOM(), enyoName));
+            .warn(String
+                .format(
+                    "'%s' is missing the 'getDisabled()' method. Add 'published: {disabled: false}' to the '%s' enyo object",
+                    getTestIdDOM(), enyoName));
       } else {
         return (Boolean) executeWithReturn(".getDisabled() === false");
       }
@@ -211,7 +209,7 @@
 
   /**
    * Returns the DOM id of the enyo node
-   *
+   * 
    * @return the DOM id
    */
   public String getIdDOM() {
@@ -237,7 +235,7 @@
 
   /**
    * Performs a tap in the enyo node with the specified row title. e.g: "Best sellers"
-   *
+   * 
    * @param enyoName
    *          the enyo name of the row that will be used to find the row
    * @param rowValue
@@ -252,8 +250,8 @@
     new Wait() {
       @Override
       protected boolean until(final int currentIteration) {
-    final String extension = String.format(".getLineByValueAndClick('%s', '%s') !== undefined",
-        enyoName, rowValue);
+        final String extension = String.format(".getLineByValueAndClick('%s', '%s') !== undefined",
+            enyoName, rowValue);
         return (Boolean) executeExtensionWithReturn(extension);
       }
 
@@ -271,7 +269,7 @@
 
   /**
    * Writes a text in the enyo node
-   *
+   * 
    * @param text
    *          the text to be inserted
    */
@@ -293,7 +291,7 @@
 
   /**
    * Gets the content of the enyo node
-   *
+   * 
    * @return the content of the enyo node
    */
   public String getContent() {
@@ -307,7 +305,7 @@
 
   /**
    * Gets the content of an scrollable table
-   *
+   * 
    * @param rowValue
    *          the identifier of the row. e.g: "Best sellers"
    * @param enyoName
diff --git a/src-test/org/openbravo/test/mobile/retail/pack/selenium/tests/receipts/I30084_DeleteLinesApprovalNotSkipped.java b/src-test/org/openbravo/test/mobile/retail/pack/selenium/tests/receipts/I30084_DeleteLinesApprovalNotSkipped.java
new file mode 100644
--- /dev/null
+++ b/src-test/org/openbravo/test/mobile/retail/pack/selenium/tests/receipts/I30084_DeleteLinesApprovalNotSkipped.java
@@ -0,0 +1,192 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo S.L.U.
+ * All portions are Copyright (C) 2015 Openbravo S.L.U.
+ * All Rights Reserved.
+ * Contributor(s):
+ ************************************************************************
+ *
+ * @author ACA
+ *
+ */
+
+package org.openbravo.test.mobile.retail.pack.selenium.tests.receipts;
+
+import org.junit.Test;
+import org.openbravo.test.mobile.common.selenium.SeleniumHelper;
+import org.openbravo.test.mobile.common.selenium.javascript.TestId;
+import org.openbravo.test.mobile.common.selenium.terminals.WebPOSTerminalHelper;
+import org.openqa.selenium.Keys;
+
+public class I30084_DeleteLinesApprovalNotSkipped extends WebPOSTerminalHelper {
+
+  @Test
+  // @TestAnnotations(waitFixOf = 30084)
+  public void test() {
+
+    // First we need to make sure we are logged in with a user without permission
+    SeleniumHelper
+        .executeScript("OB.MobileApp.model.get('permissions')['OBPOS_approval.deleteLine']=false;");
+
+    // Standard ticket
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "3.60");
+
+    // 1. Type 0 on the keyboard > tap QUANTITY
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_0);
+    tap(TestId.BUTTON_KEYPAD_QUANTITY);
+    verifyApprovalIsRequired();
+
+    // 2. Select a line > Edit > tap DELETE
+    tap(TestId.BUTTON_EDIT);
+    tap(TestId.BUTTON_EDIT_DELETELINE);
+    verifyApprovalIsRequired();
+
+    // 3. Line with positive qty > tap ‘-’ until qty = 0
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "7.20");
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    verifyApprovalIsRequired();
+
+    // 4. Line with positive qty > Write qty > tap ‘-’
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "7.20");
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "10.80");
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_3);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    verifyApprovalIsRequired();
+
+    // 5. DELETE keyboard key
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    SeleniumHelper.pressKey(Keys.DELETE);
+    verifyApprovalIsRequired();
+
+    // 6. Add a product > Undo
+    tap(TestId.BUTTON_DELETERECEIPT);
+    tap(TestId.BUTTON_DELETERECEIPT_CONFIRM);
+    verify(TestId.LABEL_TOTALTOPAY, "0.00");
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "3.60");
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_SCAN_UNDO);
+    verifyApprovalIsRequired();
+
+    // 7. Return Line > button ‘+’ until qty = 0
+    tap(TestId.BUTTON_EDIT);
+    tap(TestId.BUTTON_EDIT_RETURNLINE);
+    tap(TestId.BUTTON_KEYPAD_PLUS);
+    verifyApprovalIsRequired();
+
+    // 8. Return Line > write qty > button ‘+’
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_1);
+    tap(TestId.BUTTON_KEYPAD_PLUS);
+    verifyApprovalIsRequired();
+
+    // 9. Return Line > Add products until qty = 0
+    verify(TestId.LABEL_TOTALTOPAY, "-3.60");
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verifyApprovalIsRequired();
+
+    tap(TestId.BUTTON_DELETERECEIPT);
+    tap(TestId.BUTTON_DELETERECEIPT_CONFIRM);
+
+    // Return ticket
+    tap(TestId.BUTTON_MENU);
+    tap(TestId.BUTTON_MENU_RETURNTHISRECEIPT);
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "-3.60");
+
+    // 10. Type 0 on the keyboard > tap QUANTITY
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_0);
+    tap(TestId.BUTTON_KEYPAD_QUANTITY);
+    verifyApprovalIsRequired();
+
+    // 11. Select a line > Edit > tap DELETE
+    tap(TestId.BUTTON_EDIT);
+    tap(TestId.BUTTON_EDIT_DELETELINE);
+    verifyApprovalIsRequired();
+
+    // 12. Line with negative qty > button ‘-’ until qty = 0
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "-7.20");
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    verifyApprovalIsRequired();
+
+    // 13. Line with negative qty > Write qty > button ‘-’
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "-7.20");
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "-10.80");
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_3);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    verifyApprovalIsRequired();
+
+    // 14. DELETE keyboard key
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    tap(TestId.BUTTON_KEYPAD_MINUS);
+    SeleniumHelper.pressKey(Keys.DELETE);
+    verifyApprovalIsRequired();
+
+    // 15. Add a product > Undo
+    tap(TestId.BUTTON_DELETERECEIPT);
+    tap(TestId.BUTTON_DELETERECEIPT_CONFIRM);
+    verify(TestId.LABEL_TOTALTOPAY, "0.00");
+    tap(TestId.BUTTON_MENU);
+    tap(TestId.BUTTON_MENU_RETURNTHISRECEIPT);
+    tap(TestId.BUTTON_BROWSE);
+    tap(TestId.BUTTON_CATEGORY_BACKPACKSANDTRAVEL);
+    tap(TestId.BUTTON_PRODUCT_BACKPACKSANDTRAVEL_ADHESIVEBODYWARNMERS);
+    verify(TestId.LABEL_TOTALTOPAY, "-3.60");
+    tap(TestId.BUTTON_SCAN);
+    tap(TestId.BUTTON_SCAN_UNDO);
+    verifyApprovalIsRequired();
+
+    tap(TestId.BUTTON_DELETERECEIPT);
+    tap(TestId.BUTTON_DELETERECEIPT_CONFIRM);
+  }
+
+  private void verifyApprovalIsRequired() {
+    TestId.CONFIRMATION_POPUP.enyoNode().waitUntilIsReady();
+    verify(TestId.LABEL_POPUP_TITLE, "Approval Required");
+    tap(TestId.BUTTON_POPUP_OK);
+  }
+}
