<commit_before>/*
Copyright 2008-2011 Opera Software ASA

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.opera.core.systems;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.ElementNotVisibleException;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.Point;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.internal.Coordinates;
import org.openqa.selenium.internal.FindsByClassName;
import org.openqa.selenium.internal.FindsByCssSelector;
import org.openqa.selenium.internal.FindsById;
import org.openqa.selenium.internal.FindsByLinkText;
import org.openqa.selenium.internal.FindsByName;
import org.openqa.selenium.internal.FindsByTagName;
import org.openqa.selenium.internal.FindsByXPath;
import org.openqa.selenium.internal.Locatable;
import org.openqa.selenium.internal.WrapsDriver;

import com.opera.core.systems.model.Canvas;
import com.opera.core.systems.model.ColorResult;
import com.opera.core.systems.model.ScreenShotReply;
import com.opera.core.systems.model.ScriptResult;
import com.opera.core.systems.scope.internal.OperaColors;
import com.opera.core.systems.scope.internal.OperaFlags;
import com.opera.core.systems.scope.internal.OperaIntervals;
import com.opera.core.systems.scope.internal.OperaKeys;
import com.opera.core.systems.scope.internal.OperaMouseKeys;
import com.opera.core.systems.scope.services.IEcmaScriptDebugger;
import com.opera.core.systems.scope.services.IOperaExec;

/**
 * Extends the default WebElement with Opera specific methods.
 *
 * @author <NAME>
 *
 */
public class OperaWebElement implements WebElement, SearchContext, Locatable,
    FindsByTagName, FindsByLinkText, FindsByClassName, FindsByXPath,
    FindsByName, FindsById, FindsByCssSelector, WrapsDriver {

  private final int objectId;
  private final IEcmaScriptDebugger debugger;
  private final OperaDriver parent;
  private final int runtimeId;

  private final IOperaExec execService;

  public int getObjectId() {
    return objectId;
  }

  public int getRuntimeId() {
    return runtimeId;
  }

  public OperaWebElement(OperaDriver parent, int objectId) {
    this.parent = parent;
    this.objectId = objectId;
    parent.objectIds.add(objectId);

    debugger = parent.getScriptDebugger();
    execService = parent.getExecService();
    this.runtimeId = debugger.getRuntimeId();
  }

  /**
   * Calls the method and parses the result, the result must be a string
   *
   * @param using
   * @return response of ecmascript in string presentation
   */
  public final String callMethod(String using) {
    return debugger.callFunctionOnObject(using, objectId);
  }

  /**
   * Executes the given script with the element's object id doesn't parse the
   * response
   *
   * @param using
   */
  private final void executeMethod(String using) {
    debugger.callFunctionOnObject(using, objectId, false);
  }

  /**
   * Evals the given script with object id and parses the result and returns the
   * result object
   *
   * @param using
   * @return {@link ValueData}
   */
  private final Object evaluateMethod(String using) {
    return debugger.callFunctionOnObject(using, objectId, true);
  }

  public void clear() {
    executeMethod("locator.focus()");
    // FIXME testClearingAnElementShouldCauseTheOnChangeHandlerToFire
    // execService.action("Clear");
    execService.action("Select all");
    execService.action("Delete");
    executeMethod("locator.blur()");
  }

  /**
   * Right clicks on the element.
   */
  public void rightClick() {
    parent.actionHandler.rightClick(this);
  }

  /**
   * @deprecated Use {@link #mouseOver()}
   */
  @Deprecated
  public void hover() {
    mouseOver();
  }

  public void mouseOver() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y);
  }

  /**
   * Moves the mouse from the top left of the element to the top left of the
   * page, generating a mouseOut event.
   */
  public void mouseOut() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y);
    execService.mouseAction(0, 0);
  }

  /**
   * Presses the left mouse button down on the top left of the element.
   */
  public void mouseDown() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.LEFT_DOWN);
  }

  // TODO add check if mouse not down?
  /**
   * Releases the left mouse button at the top left of the element.
   */
  public void mouseUp() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.LEFT_DOWN);
  }

  /**
   * Click this element many times.
   *
   * @param times The number of times to click
   */
  public void click(int times) {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.LEFT.getValue(),
        times);
  }

  /**
   * Click the middle mouse button at the top left of the element.
   */
  public void middleClick() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.MIDDLE);
  }

  public void click() {
    if (OperaFlags.ENABLE_CHECKS) {
      if (!isDisplayed()) throw new ElementNotVisibleException(
          "You can't click an element that is not displayed");
    }

		parent.getScopeServices().captureOperaIdle();

		// FIXME: temporary fix for setSelected deprecation
		if (this.getTagName().equals("OPTION")) {
		  setSelected();
		} else {
		  parent.actionHandler.click(this, "");<commit_msg>Ugly fix for click()ing/toggling multiple <option> elements<commit_after>/*
Copyright 2008-2011 Opera Software ASA

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.opera.core.systems;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.ElementNotVisibleException;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.Point;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.internal.Coordinates;
import org.openqa.selenium.internal.FindsByClassName;
import org.openqa.selenium.internal.FindsByCssSelector;
import org.openqa.selenium.internal.FindsById;
import org.openqa.selenium.internal.FindsByLinkText;
import org.openqa.selenium.internal.FindsByName;
import org.openqa.selenium.internal.FindsByTagName;
import org.openqa.selenium.internal.FindsByXPath;
import org.openqa.selenium.internal.Locatable;
import org.openqa.selenium.internal.WrapsDriver;

import com.opera.core.systems.model.Canvas;
import com.opera.core.systems.model.ColorResult;
import com.opera.core.systems.model.ScreenShotReply;
import com.opera.core.systems.model.ScriptResult;
import com.opera.core.systems.scope.internal.OperaColors;
import com.opera.core.systems.scope.internal.OperaFlags;
import com.opera.core.systems.scope.internal.OperaIntervals;
import com.opera.core.systems.scope.internal.OperaKeys;
import com.opera.core.systems.scope.internal.OperaMouseKeys;
import com.opera.core.systems.scope.services.IEcmaScriptDebugger;
import com.opera.core.systems.scope.services.IOperaExec;

/**
 * Extends the default WebElement with Opera specific methods.
 *
 * @author <NAME>
 *
 */
public class OperaWebElement implements WebElement, SearchContext, Locatable,
    FindsByTagName, FindsByLinkText, FindsByClassName, FindsByXPath,
    FindsByName, FindsById, FindsByCssSelector, WrapsDriver {

  private final int objectId;
  private final IEcmaScriptDebugger debugger;
  private final OperaDriver parent;
  private final int runtimeId;

  private final IOperaExec execService;

  public int getObjectId() {
    return objectId;
  }

  public int getRuntimeId() {
    return runtimeId;
  }

  public OperaWebElement(OperaDriver parent, int objectId) {
    this.parent = parent;
    this.objectId = objectId;
    parent.objectIds.add(objectId);

    debugger = parent.getScriptDebugger();
    execService = parent.getExecService();
    this.runtimeId = debugger.getRuntimeId();
  }

  /**
   * Calls the method and parses the result, the result must be a string
   *
   * @param using
   * @return response of ecmascript in string presentation
   */
  public final String callMethod(String using) {
    return debugger.callFunctionOnObject(using, objectId);
  }

  /**
   * Executes the given script with the element's object id doesn't parse the
   * response
   *
   * @param using
   */
  private final void executeMethod(String using) {
    debugger.callFunctionOnObject(using, objectId, false);
  }

  /**
   * Evals the given script with object id and parses the result and returns the
   * result object
   *
   * @param using
   * @return {@link ValueData}
   */
  private final Object evaluateMethod(String using) {
    return debugger.callFunctionOnObject(using, objectId, true);
  }

  public void clear() {
    executeMethod("locator.focus()");
    // FIXME testClearingAnElementShouldCauseTheOnChangeHandlerToFire
    // execService.action("Clear");
    execService.action("Select all");
    execService.action("Delete");
    executeMethod("locator.blur()");
  }

  /**
   * Right clicks on the element.
   */
  public void rightClick() {
    parent.actionHandler.rightClick(this);
  }

  /**
   * @deprecated Use {@link #mouseOver()}
   */
  @Deprecated
  public void hover() {
    mouseOver();
  }

  public void mouseOver() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y);
  }

  /**
   * Moves the mouse from the top left of the element to the top left of the
   * page, generating a mouseOut event.
   */
  public void mouseOut() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y);
    execService.mouseAction(0, 0);
  }

  /**
   * Presses the left mouse button down on the top left of the element.
   */
  public void mouseDown() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.LEFT_DOWN);
  }

  // TODO add check if mouse not down?
  /**
   * Releases the left mouse button at the top left of the element.
   */
  public void mouseUp() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.LEFT_DOWN);
  }

  /**
   * Click this element many times.
   *
   * @param times The number of times to click
   */
  public void click(int times) {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.LEFT.getValue(),
        times);
  }

  /**
   * Click the middle mouse button at the top left of the element.
   */
  public void middleClick() {
    Point point = this.getLocation();
    execService.mouseAction(point.x, point.y, OperaMouseKeys.MIDDLE);
  }

  public void click() {
    if (OperaFlags.ENABLE_CHECKS) {
      if (!isDisplayed()) throw new ElementNotVisibleException(
          "You can't click an element that is not displayed");
    }

		parent.getScopeServices().captureOperaIdle();

		// FIXME: temporary fix for toggle and setSelected deprecation
		Integer id = debugger.executeScriptOnObject("return locator.parentNode", objectId);
		OperaWebElement parentNode = new OperaWebElement(this.parent, id);

		if (parentNode.getTagName().equalsIgnoreCase("SELECT") &&
		    parentNode.getAttribute("multiple") != null) {
		  toggle();
		} else if (this.getTagName().equals("OPTION")) {
		  setSelected();
		} else {
		  parent.actionHandler.click(this, "");
{'fraction_non_alphanumeric': 0.10152515365353973, 'fraction_numerical': 0.002124592154184688, 'mean_word_length': 4.020952380952381, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '246511', 'n_tokens_mistral': 4086, 'n_tokens_neox': 3938, 'n_words': 1040}