public void quitOpera(OperaRunner runner, int pid) {
    try {
      if (exec.getActionList().contains("Quit")) {
        exec.action("Quit");
      } else {
        exec.action("Exit");
      }
    } catch (Exception e) {
      // We expect a CommunicationException here, because as Opera is shutting
      // down the connection will be closed.
      if (!(e instanceof CommunicationException)) {
        logger.info("Caught exception when trying to shut down: " + e.getMessage());
      }
    }

    if (runner != null && pid > 0) {
      long interval = OperaIntervals.QUIT_POLL_INTERVAL.getValue();
      long timeout = OperaIntervals.QUIT_RESPONSE_TIMEOUT.getValue();
      while (runner.isOperaRunning(pid) && timeout > 0) {
        try {
          Thread.sleep(interval);
        } catch (InterruptedException e) {
          // ignore
        }
        timeout -= interval;
      }
    }
  }
  /**
   * Initializes the services that are available.
   *
   * @param enableDebugger whether or not to enable the ecmascript-debugger service
   */
  private void initializeServices(boolean enableDebugger) {
    exec.init();
    windowManager.init();

    if (versions.containsKey("core") && coreUtils != null) {
      coreUtils.init();
    }

    if (versions.containsKey("prefs") && prefs != null) {
      prefs.init();
    }

    if (versions.containsKey("desktop-window-manager") && desktopWindowManager != null) {
      desktopWindowManager.init();
    }

    if (versions.containsKey("system-input") && systemInputManager != null) {
      systemInputManager.init();
    }

    if (versions.containsKey("desktop-utils") && desktopUtils != null) {
      desktopUtils.init();
    }

    if (enableDebugger) {
      debugger.init();
    }
  }
  /**
   * Check if the current webpage contains any of the given colors. Used on tests that use red to
   * show a failure.
   *
   * @param colors list of colors to check for.
   * @return true if the page contains any of the given colors, false otherwise.
   */
  public boolean containsColor(OperaColors... colors) {
    Canvas canvas = buildCanvas();
    ScreenShotReply reply = execService.containsColor(canvas, 100L, colors);

    List<ColorResult> results = reply.getColorResult();
    for (ColorResult result : results) {
      if (result.getCount() > 0) {
        return true;
      }
    }

    return false;
  }
 /**
  * Take a screenshot of the area this element covers. If the hash of the image matches any of the
  * given hashes then no image is saved, otherwise it saves a copy of the image to the given
  * filename.
  *
  * @param filename The location to save the screenshot.
  * @param timeout The number of milliseconds to wait before taking the screenshot.
  * @param includeImage Whether to get the image data. Disable if you just need the MD5 hash.
  * @param hashes Known image hashes.
  * @return The MD5 hash of the screenshot.
  */
 public String saveScreenshot(
     String filename, long timeout, boolean includeImage, String... hashes) {
   Canvas canvas = buildCanvas();
   ScreenShotReply reply = execService.screenWatcher(canvas, timeout, includeImage, hashes);
   if (includeImage && reply.getPng() != null) {
     FileChannel stream;
     try {
       stream = new FileOutputStream(filename).getChannel();
       stream.write(ByteBuffer.wrap(reply.getPng()));
       stream.close();
     } catch (Exception e) {
       throw new WebDriverException("Failed to write file: " + e.getMessage());
     }
   }
   return reply.getMd5();
 }
  /**
   * Check if the current webpage contains any of the given colors. Used on tests that use red to
   * show a failure.
   *
   * @param colors list of colors to check for.
   * @return true if the page contains any of the given colors, false otherwise.
   * @deprecated
   */
  @SuppressWarnings("unused")
  @Deprecated
  public boolean containsColor(OperaColors... colors) {
    assertElementNotStale();

    Canvas canvas = buildCanvas();
    ScreenShotReply reply = execService.containsColor(canvas, 100L, colors);

    List<ColorResult> results = reply.getColorResult();

    for (ColorResult result : results) {
      if (result.getCount() > 0) {
        return true;
      }
    }

    return false;
  }
 /**
  * Take a screenshot of the area this element's bounding-box covers.
  *
  * @param timeout The number of milliseconds to wait before taking the screenshot
  * @param hashes A previous screenshot MD5 hash. If it matches the hash of this screenshot then no
  *     image data is returned.
  * @return a screenshot instance object
  */
 public ScreenShotReply saveScreenshot(long timeout, String... hashes) {
   assertElementNotStale();
   Canvas canvas = buildCanvas();
   return execService.screenWatcher(canvas, timeout, true, hashes);
 }
 /**
  * Click the middle mouse button at the top left corner of the element.
  *
  * <p>Will not verify whether element is available for interaction first.
  *
  * @deprecated
  */
 @Deprecated
 @SuppressWarnings("unused")
 public void middleClick() { // TODO(andreastt): Add this to Actions
   Point point = coordinates.getLocationInViewPort();
   execService.mouseAction(point.x, point.y, OperaMouseKeys.MIDDLE);
 }
  public void sendKeys(CharSequence... keysToSend) {
    // A list of keys that should be held down, instead of pressed
    ArrayList<String> holdKeys = new ArrayList<String>();
    holdKeys.add(OperaKeys.SHIFT.getValue());
    holdKeys.add(OperaKeys.CONTROL.getValue());
    // Keys that have been held down, and need to be released
    ArrayList<String> heldKeys = new ArrayList<String>();

    if (OperaFlags.ENABLE_CHECKS) {
      long start = System.currentTimeMillis();
      boolean isDisplayed;

      while (true) {
        isDisplayed = isDisplayed();

        if (!isDisplayed && parent.hasTimeRemaining(start)) {
          sleep(OperaIntervals.EXEC_SLEEP.getValue());
        } else {
          break;
        }
      }

      assertElementDisplayed("Cannot type on an element that is not displayed");
      assertElementEnabled("Cannot type on an element that is disabled");
    }

    if (getTagName().equalsIgnoreCase("input")
        && (hasAttribute("type") && getAttribute("type").equals("file"))) {
      click();
    } else {
      executeMethod("locator.focus()");
      // When focused textareas return the cursor to the last position it was at. Inputs place the
      // cursor at the beginning, and so we need to move it to the end. We do this by pre-pending an
      // "End" key to the keys to send (in a round-about way).
      if (getTagName().equalsIgnoreCase("input")) {
        // Javascript from webdriver_session.cc in ChromeDriver
        executeMethod(
            "function(elem) {"
                + "  var doc = elem.ownerDocument || elem;"
                + "  var prevActiveElem = doc.activeElement;"
                + "  if (elem != prevActiveElem && prevActiveElem)"
                + "    prevActiveElem.blur();"
                + "  elem.focus();"
                + "  if (elem != prevActiveElem && elem.value && elem.value.length &&"
                + "      elem.setSelectionRange) {"
                + "    elem.setSelectionRange(elem.value.length, elem.value.length);"
                + "  }"
                + "  if (elem != doc.activeElement)"
                + "    throw new Error('Failed to send keys because cannot focus element');"
                + "}(locator)");
      }
    }

    // This code is a bit ugly. Because "special" keys can be sent either as an individual
    // argument, or in the middle of a string of "normal" characters, we have to loop through the
    // string and check each against a list of special keys.

    parent.getScopeServices().captureOperaIdle();
    for (CharSequence seq : keysToSend) {
      if (seq instanceof Keys) {
        String key = OperaKeys.get(((Keys) seq).name());
        // Check if this is a key we hold down, and haven't already pressed, and press, but don't
        // release it. That's done at the end of this method.
        if (holdKeys.contains(key) && !heldKeys.contains(key) && !execService.keyIsPressed(key)) {
          execService.key(key, false);
          heldKeys.add(key);
        } else if (key.equals("null")) {
          for (String hkey : heldKeys) {
            execService.key(hkey, true);
          }
        } else {
          execService.key(key);
        }
      } else if (seq.toString().equals("\n")) {
        execService.key("enter");
      } else {
        // We need to check each character to see if it is a "special" key
        for (int i = 0; i < seq.length(); i++) {
          Character c = seq.charAt(i);
          String keyName = charToKeyName(c);

          // Buffer normal keys for a single type() call
          if (keyName == null) {
            execService.type(c.toString());
          } else {
            String key = OperaKeys.get(keyName);
            // TODO: Code repeated from above
            if (holdKeys.contains(key)
                && !heldKeys.contains(key)
                && !execService.keyIsPressed(key)) {
              execService.key(key, false);
              heldKeys.add(key);
            } else if (key.equals("null")) {
              for (String hkey : heldKeys) {
                execService.key(hkey, true);
              }
            } else {
              execService.key(key);
            }
          }
        }
      }
    }

    if (heldKeys.size() > 0) {
      for (String key : heldKeys) {
        execService.key(key, true);
      }
    }

    try {
      parent.waitForLoadToComplete();
    } catch (ResponseNotReceivedException e) {
      // This might be expected
      logger.fine("Response not received, returning control to user");
    }

    // executeMethod("locator.blur()");
  }
 /** Click the middle mouse button at the top left corner of the element. */
 public void middleClick() {
   Point point = coordinates.getLocationInViewPort();
   execService.mouseAction(point.x, point.y, OperaMouseKeys.MIDDLE);
 }
 /**
  * Click this element many times in the top left corner of the element.
  *
  * @param times the number of times to click
  */
 public void click(int times) {
   Point point = coordinates.getLocationInViewPort();
   execService.mouseAction(point.x, point.y, times, OperaMouseKeys.LEFT);
 }