Package WasaviTest

Source Code of WasaviTest.WasaviWrapper$StrokeSender

package WasaviTest;

import org.junit.*;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

import org.json.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.*;
import static org.openqa.selenium.support.ui.ExpectedConditions.*;

import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;

import com.opera.core.systems.OperaDriver;
import com.opera.core.systems.OperaProfile;



class WasaviSendCallback {
  void exec (Actions act) {}
}



class WasaviWrapper {
  protected static final Boolean LOG_EXCEPTION = true;

  protected WebDriver driver;
  protected JSONObject wasaviState;
  protected final ArrayList<String> inputModeOfWacthTargetDefault =
    new ArrayList<String>(java.util.Arrays.asList("command", "backlog_prompt", "ex_s_prompt"));
  protected ArrayList<String> inputModeOfWacthTarget = inputModeOfWacthTargetDefault;
  protected Boolean isAppMode = false;
  protected StrokeSender strokeSender = null;

  abstract class StrokeSender {
    abstract public void setup ();
    abstract public WebElement waitCommandCompletion ();
    abstract public void finish (WebElement wasaviFrame);
  }

  class SymbiosisModeStrokeSender extends StrokeSender {
    @Override public void setup () {
    }

    @Override public WebElement waitCommandCompletion () {
      try {
        return new WebDriverWait(driver, 60)
          .until(new ExpectedCondition<WebElement>() {
          public WebElement apply (WebDriver d) {
            try {
              WebElement elm = d.findElement(By.id("wasavi_frame"));
              String commandState = elm.getAttribute("data-wasavi-command-state");
              String inputMode = elm.getAttribute("data-wasavi-input-mode");

              /*
              if (commandState != null) {
                System.out.println(String.format("%s, mode: %s", commandState, inputMode));
              }
               */

              if (commandState == null && inputModeOfWacthTarget.contains(inputMode)) {
                //System.out.println(String.format("found, mode: %s", inputMode));
                return elm;
              }
            }
            catch (org.openqa.selenium.NoSuchElementException e) {
              if (LOG_EXCEPTION) {
                System.out.println("waitCommandCompletion: wasavi frame not found.");
              }
            }
            return null;
          }
        });
      }
      catch (org.openqa.selenium.TimeoutException e) {
        if (LOG_EXCEPTION) {
          System.out.println("waitCommandCompletion: timed out.");
        }
      }
      return null;
    }

    @Override public void finish (WebElement wasaviFrame) {
      if (wasaviFrame == null) {
        return;
      }

      String source = wasaviFrame.getAttribute("data-wasavi-state");
      if (source != null) {
        try {
          wasaviState = new JSONObject(source);
        }
        catch (JSONException e) {
          if (LOG_EXCEPTION) {
            System.out.println("sendFinish: invalid json source: " + source);
          }
          wasaviState = new JSONObject();
        }
      }
      else {
        if (LOG_EXCEPTION) {
          System.out.println("sendFinish: cannot retrieve wasavi state.");
        }
        wasaviState = new JSONObject();
      }

      WasaviAsserts.setWasaviState(wasaviState);
    }
  }

  class AppModeStrokeSender extends StrokeSender {
    @Override public void setup () {
    }

    @Override public WebElement waitCommandCompletion () {
      try {
        return new WebDriverWait(driver, 60)
          .until(new ExpectedCondition<WebElement>() {
          public WebElement apply (WebDriver d) {
            try {
              WebElement elm = d.findElement(By.tagName("html"));
              String commandState = elm.getAttribute("data-wasavi-command-state");
              String inputMode = elm.getAttribute("data-wasavi-input-mode");

              /*
              if (commandState != null) {
                System.out.println(String.format("%s, mode: %s", commandState, inputMode));
              }
               */

              if (commandState == null && inputModeOfWacthTarget.contains(inputMode)) {
                return elm;
              }
            }
            catch (org.openqa.selenium.NoSuchElementException e) {
              if (LOG_EXCEPTION) {
                System.out.println("waitCommandCompletion: wasavi frame not found.");
              }
            }
            return null;
          }
        });
      }
      catch (org.openqa.selenium.TimeoutException e) {
        if (LOG_EXCEPTION) {
          System.out.println("waitCommandCompletion: timed out.");
        }
      }
      return null;
    }

    @Override public void finish (WebElement wasaviFrame) {
      WebElement elm = driver.findElement(By.tagName("html"));
      String source = elm.getAttribute("data-wasavi-state");
      if (source != null) {
        try {
          wasaviState = new JSONObject(source);
        }
        catch (JSONException e) {
          if (LOG_EXCEPTION) {
            System.out.println("finish: invalid json source: " + source);
          }
          wasaviState = new JSONObject();
        }
      }
      else {
        if (LOG_EXCEPTION) {
          System.out.println("finish: cannot retrieve wasavi state.");
        }
        wasaviState = new JSONObject();
      }

      WasaviAsserts.setWasaviState(wasaviState);
    }
  }

  /*
   * constructor
   */

  WasaviWrapper (WebDriver d) {
    driver = d;
    wasaviState = new JSONObject();
  }

  /*
   * protected methods
   */
 
  protected int getInt (String name, int defaultValue) {
    try {
      return wasaviState.getInt(name);
    }
    catch (JSONException e) {
      if (LOG_EXCEPTION) {
        System.out.println(e.getMessage());
      }
    }
    return defaultValue;
  }

  protected int getInt (String name) {
    return getInt(name, 0);
  }

  protected String getString (String name, String defaultValue) {
    try {
      return wasaviState.getString(name);
    }
    catch (JSONException e) {
      if (LOG_EXCEPTION) {
        System.out.println(e.getMessage());
      }
    }
    return defaultValue;
  }

  protected String getString (String name) {
    return getString(name, "");
  }

  protected StrokeSender getStrokeSender () {
    if (strokeSender == null) {
      if (isAppMode) {
        strokeSender = new AppModeStrokeSender();
      }
      else {
        strokeSender = new SymbiosisModeStrokeSender();
      }
    }
    return strokeSender;
  }

  /*
   * publics
   */

  public void setAppMode (Boolean value) {
    if (value != isAppMode) {
      isAppMode = value;
      strokeSender = null;
    }
  }

  public void send (CharSequence... strokes) {
    getStrokeSender();
    strokeSender.setup();

    for (CharSequence s: strokes) {
      (new Actions(driver)).sendKeys(s).perform();
    }

    WebElement elm = strokeSender.waitCommandCompletion();
    strokeSender.finish(elm);

    inputModeOfWacthTarget = inputModeOfWacthTargetDefault;
  }

  public void send (WasaviSendCallback callback) {
    getStrokeSender();
    strokeSender.setup();

    Actions act = new Actions(driver);
    callback.exec(act);
    act.perform();

    WebElement elm = strokeSender.waitCommandCompletion();
    strokeSender.finish(elm);

    inputModeOfWacthTarget = inputModeOfWacthTargetDefault;
  }

  public void waitCommandCompletion () {
    getStrokeSender();
    strokeSender.setup();
    WebElement elm = strokeSender.waitCommandCompletion();
    strokeSender.finish(elm);
    inputModeOfWacthTarget = inputModeOfWacthTargetDefault;
  }

  public void sendNoWait (CharSequence stroke) {
    (new Actions(driver)).sendKeys(stroke).perform();
  }

  public void setInputModeOfWatchTarget (String... modes) {
    inputModeOfWacthTarget = new ArrayList<String>();

    for (String s: modes) {
      if ("command".equals(s)
        || "edit".equals(s)
        || "overwrite".equals(s)
        || "line_input".equals(s)
        || "backlog_prompt".equals(s)
        || "ex_s_prompt".equals(s)
        || "write handler".equals(s)
      ) {
        inputModeOfWacthTarget.add(s);
      }
    }
  }

  public Object js (String script, Object... args) {
    return ((JavascriptExecutor)driver).executeScript(script, args);
  }

  public void log (String s) {
    js(
      "var t = document.getElementById('test-log');" +
      "if (!t) return;" +
      "t.value += '\\n' + Array.prototype.slice.call(arguments).join('\\t');" +
      "t.scrollTop = t.scrollHeight - t.clientHeight;",
      s);
  }

  public Boolean waitTerminate () {
    try {
      WebElement wasaviFrame = driver.findElement(By.id("wasavi_frame"));
      return new WebDriverWait(driver, 60).until(stalenessOf(wasaviFrame));
    }
    catch (org.openqa.selenium.NoSuchElementException e) {
      if (LOG_EXCEPTION) {
        System.out.println("waitTerminate: wasavi_frame not found.");
      }
      return true;
    }
  }

  public int makeScrollableBuffer (double factor) {
    send("h");

    int lines = getLines();
    int actualLines = (int)(lines * factor);
    StringBuilder sb = new StringBuilder();

    for (int i = 1; i <= actualLines; i++) {
      if (sb.length() > 0) {
        sb.append("\n");
      }
      sb.append(String.format("line %d", i));
    }

    send(String.format("i%s\u001b", sb.toString()));

    return lines;
  }

  public int makeScrollableBuffer () {
    return makeScrollableBuffer(1);
  }

  /*
   * state getters
   */

  public String getState () {
    return getString("state", "***Exception in getState***");
  }

  public String getValue () {
    return getString("value", "***Exception in getValue***");
  }

  public String getLastMessage () {
    return getString("lastMessage", "***Exception in getLastMessage***");
  }

  public String getLastSimpleCommand () {
    return getString("lastSimpleCommand", "***Exception in getLastSimpleCommand***");
  }

  public String getInputMode () {
    return getString("inputMode", "***Exception in getInputMode***");
  }

  public int getLines () {
    return getInt("lines", 0);
  }

  public int getRowLength () {
    return getInt("rowLength", 0);
  }

  public int getRow () {
    return getInt("row", 0);
  }

  public int getCol () {
    return getInt("col", 0);
  }

  public int getTopRow () {
    return getInt("topRow", 0);
  }

  public int getTopCol () {
    return getInt("topCol", 0);
  }

  public String getLineInput () {
    return getString("lineInput", "***Exception in getLineInput***");
  }

  public String getRegister (String name) {
    try {
      JSONArray regs = wasaviState.getJSONArray("registers");
      for (int i = 0, goal = regs.length(); i < goal; i++) {
        JSONObject item = regs.getJSONObject(i);
        if (item.getString("name").equals(name)) {
          return item.getString("data");
        }
      }
    }
    catch (JSONException e) {
      if (LOG_EXCEPTION) {
        System.out.println(e.getMessage());
      }
      return "**Exception in getRegister***";
    }
    return "";
  }

  public int[] getMark (String name) {
    try {
      int[] result = new int[2];
      JSONObject mark = wasaviState.getJSONObject("marks").getJSONObject(name);
      result[0] = mark.getInt("row");
      result[1] = mark.getInt("col");
      return result;
    }
    catch (JSONException e) {
      if (LOG_EXCEPTION) {
        System.out.println(e.getMessage());
      }
      return null;
    }
  }

  public String getAppModeStatusLine () {
    try {
      WebElement elm = driver.findElement(By.id("wasavi_footer_file_indicator"));
      return elm.getText();
    }
    catch (org.openqa.selenium.NoSuchElementException e) {
      return "***Exception in getAppModeStatusLine***";
    }
  }
}



class WasaviUtils {
  public static String join (String... parts) {
    String delimiter = parts[0];
    StringBuilder sb = new StringBuilder();
    for (int i = 1, goal = parts.length; i < goal; i++) {
      if (sb.length() > 0) {
        sb.append(delimiter);
      }
      sb.append(parts[i]);
    }
    return sb.toString();
  }

  public static String join (String[] parts, String delimiter) {
    StringBuilder sb = new StringBuilder();
    for (String s: parts) {
      if (sb.length() > 0) {
        sb.append(delimiter);
      }
      sb.append(s);
    }
    return sb.toString();
  }

  public static String getClipboardText () {
    Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();

    try {
      return (String)cb.getData(DataFlavor.stringFlavor);
    }
    catch (UnsupportedFlavorException e) {
      return null;
    }
    catch (java.io.IOException e) {
      return null;
    }
  }

  public static void setClipboardText (String s) {
    Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
    StringSelection ss = new StringSelection(s);
    cb.setContents(ss, ss);
  }

  public static void sleep (long ms) {
    try {
      Thread.sleep(ms);
    }
    catch (InterruptedException e) {}
  }
}



class WasaviAsserts {
  private static JSONObject wasaviState;

  protected WasaviAsserts () {
  }

  public static void setWasaviState (JSONObject ws) {
    wasaviState = ws;
  }

  public static String fromCharCode (int... codePoints) {
    return new String(codePoints, 0, codePoints.length);
  }

  public static String toVisibleString (String s) {
    for (int i = 0; i < 32; i++) {
      s = s.replaceAll(fromCharCode(i), "^" + fromCharCode(64 + i));
    }
    s = s.replaceAll(fromCharCode(127), "^_");
    return s;
  }

  public static void assertEquals (String message, String expected, String actual) {
    org.junit.Assert.assertEquals(
        String.format(
            "%s: expected:\n<<%s>>\n\nbut was:\n<<%s>>",
            message,
            toVisibleString(expected), toVisibleString(actual)),
        expected, actual);
  }

  public static void assertEqualst(String expected, String actual) {
    assertEquals("", expected, actual);
  }

  public static void assertPos (String message, int row, int col) {
    try {
      int actualRow = wasaviState.getInt("row");
      int actualCol = wasaviState.getInt("col");
      org.junit.Assert.assertTrue(
          String.format(
              "%s: position unmatch.\nexpected:[%d, %d] but was:[%d, %d]\n%s",
              message,
              row, col, actualRow, actualCol,
              wasaviState.getString("value")),
          row == actualRow && col == actualCol);
    }
    catch (JSONException e) {
      org.junit.Assert.fail("invalid row or col in wasaviStates.");
    }
  }

  public static void assertPos (int row, int col) {
    assertPos("", row, col);
  }

  public static void assertValue (String message, String expected) {
    try {
      String value = wasaviState.getString("value");
      org.junit.Assert.assertEquals(
          String.format(
              "%s: value unmatch.\nexpected:\n<<%s>>\n\nbut was:\n<<%s>>\n\n",
              message,
              toVisibleString(expected), toVisibleString(value)),
          expected, value);
    }
    catch (JSONException e) {
      org.junit.Assert.fail("invalid value col in wasaviStates.");
    }
  }

  public static void assertValue (String expected) {
    assertValue("", expected);
  }
}



class InvokeState {
  protected int count = 0;
  protected int index = 0;

  InvokeState (int aindex) {
    index = aindex;
  }

  public int getCount () {
    return count;
  }

  public int getIndex () {
    return index;
  }

  public void incrementCount () {
    ++count;
  }
}



public class WasaviTest {
  protected static WebDriver driver;
  protected static WasaviWrapper Wasavi;
  protected static InvokeState[] invokeStates = {new InvokeState(0), new InvokeState(1)};
  protected static int testIndex = 1;
  protected ArrayList<String> logText = new ArrayList<String>();
  protected Boolean isSectionTest;
  protected Boolean isAppMode;
  protected Boolean isReadonlyElement;
  protected String wasaviTargetID;

  @Rule public TestRule watcher = new TestWatcher() {
    protected void starting (Description d) {
      logText.clear();

      isSectionTest = d.getMethodName().matches(".*([Ss]entence|[Pp]aragraph|[Ss]ection).*");
      isAppMode = d.getMethodName().matches(".*appMode.*");
      isReadonlyElement = d.getMethodName().matches(".*ReadonlyElement.*");
      wasaviTargetID = d.getMethodName().matches(".*[Cc]ontentEditable.*") ? "t3" : "t2";

      Wasavi.js(
        "var h1 = document.getElementsByTagName('h1')[0];" +
        "if (h1) {" +
        "  h1.textContent = '" + String.format(
          "#%d: %s", testIndex++, d.toString()) + "';" +
        "}");
    }
    protected void failed (Throwable e, Description d) {
      System.out.println("--------------------");
      System.out.println(d.toString() + " FAILED");
      System.out.println("");
      System.out.println(e.getMessage());
      System.out.println("");
      for (CharSequence s: logText) {
        System.out.println(s);
      }
      System.out.println("");
      System.out.println("");
      System.out.println("");
    }
  };

  private static WebDriver createDriver (String name) {
    WebDriver driver = null;

    if (name.equals("opera")) {
      DesiredCapabilities cap = DesiredCapabilities.opera();
      cap.setCapability("opera.profile",
          new OperaProfile(System.getProperty("wasavi.tests.opera.profile_path")));
      cap.setCapability("opera.logging.level",
          java.util.logging.Level.FINE);
      cap.setCapability("opera.binary",
          System.getProperty("wasavi.tests.opera.executable"));
      driver = new OperaDriver(cap);
    }

    else if (name.equals("chrome")) {
      ChromeDriverService service = ChromeDriverService.createDefaultService();
      ChromeOptions options = new ChromeOptions();
      options.addArguments(
        "--start-maximized",
        "--lang=en",
        "--user-data-dir="
          + System.getProperty("wasavi.tests.chrome.profile_path")
      );
      driver = new ChromeDriver(service, options);
    }

    else if (name.equals("firefox")) {
      java.io.File profileDir = new java.io.File(
          System.getProperty("wasavi.tests.firefox.profile_path"));
      FirefoxProfile p = new FirefoxProfile(profileDir);

      p.setPreference("general.useragent.locale", "en-US");
      driver = new FirefoxDriver(p);
    }

    return driver;
  }

  protected WebElement findElement (By locator) {
    WebElement result = null;
    try {
      result = driver.findElement(locator);
    }
    catch (org.openqa.selenium.NoSuchElementException e) {
      result = null;
    }
    return result;
  }

  protected WebElement invokeWasavi () {
    WebElement wasaviFrame = null;

    WebElement target = findElement(By.id(wasaviTargetID));
    if (target == null) {
      System.out.println("target element not found.");
      return null;
    }

    for (int i = 0; i < invokeStates.length; ++i) {
      if (isSectionTest) {
        WebElement sectionInitializer = findElement(By.id("init-section-button"));
        if (sectionInitializer == null) {
          System.out.println("section initializer not found.");
          return null;
        }

        sectionInitializer.click();
      }
      else {
        WebElement reset = findElement(By.id("reset-button"));
        if (reset == null) {
          System.out.println("reset button not found.");
          return null;
        }

        reset.click();

        WebElement ro = findElement(By.id("readonly-checkbox"));
        if (ro == null) {
          System.out.println("readonly checkbox not found.");
          return null;
        }
        String roChecked = ro.getAttribute("checked");
        if (isReadonlyElement && roChecked == null
        ||  !isReadonlyElement && roChecked != null) {
          ro.click();
          System.out.println("readonly checkbox clicked.");
        }

        new WebDriverWait(driver, 1).until(
          new ExpectedCondition<Boolean>() {
            public Boolean apply (WebDriver driver) {
              WebElement target = findElement(By.id(wasaviTargetID));
              if (target == null) {
                System.out.println("target element not found (2).");
                return false;
              }

              String v = target.getAttribute(
                target.getTagName().equals("textarea") ? "value" : "textContent");
              if (v == null) {
                System.out.println("content of target is null.");
                return false;
              }

              if (v.length() > 0) {
                System.out.println(String.format("content of target is not an empty: '%s'.", v));
                return false;
              }

              return true;
            }
          });
      }

      //
      WebElement targetSwitcher = findElement(By.id("use-div-checkbox"));
      if (targetSwitcher == null) {
        System.out.println("target switcher not found.");
        return null;
      }
      String useDivChecked = targetSwitcher.getAttribute("checked");
      if (wasaviTargetID.equals("t2") && useDivChecked != null
      ||  wasaviTargetID.equals("t3") && useDivChecked == null) {
        targetSwitcher.click();
        System.out.println("target switcher clicked.");
      }

      //
      target.click();

      switch (invokeStates[i].getIndex()) {
      case 0:
        target.sendKeys(Keys.chord(Keys.CONTROL, Keys.ENTER));

        /*
         * alternative valid code:
         *
         * new Actions(driver)
         *   .sendKeys(Keys.chord(Keys.CONTROL, Keys.ENTER))
         *   .perform();
         */

        /*
         * does not execute:
         *
         * new Actions(driver)
         *   .keyDown(Keys.CONTROL)
         *   .sendKeys(Keys.ENTER)
         *   .keyUp(Keys.CONTROL)
         *   .perform();
         */

        //System.out.println("sendKeys");
        break;

      case 1:
        WebElement launcher = findElement(By.id("request-launch-wasavi"));
        if (launcher == null) {
          System.out.println("launch button not found.");
          return null;
        }

        launcher.click();
        //System.out.println("launcher click");
        break;
      }

      try {
        wasaviFrame = new WebDriverWait(driver, 5).until(
          new ExpectedCondition<WebElement>() {
            public WebElement apply (WebDriver driver) {
              return findElement(By.id("wasavi_frame"));
            }
          });
      }
      catch (org.openqa.selenium.TimeoutException e) {
        wasaviFrame = null;
      }

      if (wasaviFrame != null) {
        wasaviFrame.click();
        invokeStates[i].incrementCount();
        //System.out.println("found wasavi frame");
        break;
      }
    }

    java.util.Arrays.sort(invokeStates, new Comparator<InvokeState>() {
      public int compare (InvokeState o1, InvokeState o2) {
        return o2.getCount() - o1.getCount();
      }
    });

    return wasaviFrame;
  }

  protected WebElement invokeAppModeWasavi () {
    driver.navigate().to("http://wasavi.appsweets.net/?testmode");

    WebElement wasaviFrame = null;

    try {
      wasaviFrame = new WebDriverWait(driver, 5).until(
        new ExpectedCondition<WebElement>() {
          public WebElement apply (WebDriver driver) {
            return findElement(By.id("wasavi_cover"));
          }
        });
    }
    catch (org.openqa.selenium.TimeoutException e) {
      wasaviFrame = null;
    }
    catch (org.openqa.selenium.UnhandledAlertException e) {
      wasaviFrame = null;
    }

    if (wasaviFrame != null) {
      wasaviFrame.click();
    }

    return wasaviFrame;
  }

  @BeforeClass
  public static void beforeClass () {
    driver = createDriver(System.getProperty("wasavi.tests.browser"));
    if (driver != null) {
      driver.navigate().to(System.getProperty("wasavi.tests.frame_url"));
      Wasavi = new WasaviWrapper(driver);
    }
  }

  @Before
  public void setUp () {
    if (isAppMode) {
      Wasavi.setAppMode(true);
      invokeAppModeWasavi();
    }
    else {
      Wasavi.setAppMode(false);
      invokeWasavi();
    }
  }

  @After
  public void tearDown () {
    if (isAppMode) {
      Wasavi.send(":set nomodified\n");
    }

    WebElement testLog = findElement(By.id("test-log"));
    if (testLog != null) {
      logText.add(testLog.getAttribute("value"));

      Wasavi.js(
        "var wasaviFrame = document.getElementById('wasavi_frame');" +
        "wasaviFrame && wasaviFrame.parentNode.removeChild(wasaviFrame);");
    }
  }

  @AfterClass
  public static void afterClass () {
    if (driver != null) {
      driver.quit();
      driver = null;
    }
  }
}

// vim:set ts=4 sw=4 fenc=UTF-8 ff=unix ft=java fdm=marker :
TOP

Related Classes of WasaviTest.WasaviWrapper$StrokeSender

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.