diff --git a/.gitignore b/.gitignore
index 4c565fe6..2ed7345d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ target/
*.iml
saucelabs.properties
atlassian-ide-plugin.xml
+/bin
diff --git a/src/main/java/com/xebia/incubator/xebium/SeleniumDriverFixture.java b/src/main/java/com/xebia/incubator/xebium/SeleniumDriverFixture.java
index c221e899..003c80ec 100644
--- a/src/main/java/com/xebia/incubator/xebium/SeleniumDriverFixture.java
+++ b/src/main/java/com/xebia/incubator/xebium/SeleniumDriverFixture.java
@@ -23,17 +23,29 @@
import com.thoughtworks.selenium.HttpCommandProcessor;
import com.thoughtworks.selenium.SeleniumException;
import com.thoughtworks.selenium.webdriven.WebDriverCommandProcessor;
+
+import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
import static com.xebia.incubator.xebium.FitNesseUtil.*;
import static org.apache.commons.lang.StringUtils.join;
@@ -44,7 +56,7 @@ public class SeleniumDriverFixture {
private static final Logger LOG = LoggerFactory.getLogger(SeleniumDriverFixture.class);
- private DefaultWebDriverSupplier defaultWebDriverSupplier = new DefaultWebDriverSupplier();
+ private DefaultWebDriverSupplier defaultWebDriverSupplier = new DefaultWebDriverSupplier();
private static final String ALIAS_PREFIX = "%";
@@ -69,59 +81,59 @@ public SeleniumDriverFixture() {
super();
}
- private WebDriver defaultWebDriverInstance() {
- return defaultWebDriverSupplier.newWebDriver();
- }
+ private WebDriver defaultWebDriverInstance() {
+ return defaultWebDriverSupplier.newWebDriver();
+ }
- private CommandProcessor startWebDriverCommandProcessor(String browserUrl, WebDriver webDriver) {
+ private CommandProcessor startWebDriverCommandProcessor(String browserUrl, WebDriver webDriver) {
browserUrl = removeAnchorTag(browserUrl);
- WebDriverCommandProcessor driver = new WebDriverCommandProcessor(browserUrl, webDriver);
- addMissingSeleneseCommands(driver);
- return driver;
+ WebDriverCommandProcessor driver = new WebDriverCommandProcessor(browserUrl, webDriver);
+ addMissingSeleneseCommands(driver);
+ return driver;
}
- private void addMissingSeleneseCommands(WebDriverCommandProcessor driver) {
- driver.addMethod("sendKeys", driver.getMethod("typeKeys"));
- }
+ private void addMissingSeleneseCommands(WebDriverCommandProcessor driver) {
+ driver.addMethod("sendKeys", driver.getMethod("typeKeys"));
+ }
- /**
- * Configure the custom Firefox preferences (javascript) file on the webdriver factory.
- *
- * @param filename
- */
- public void loadCustomBrowserPreferencesFromFile(String filename) {
- defaultWebDriverSupplier.setCustomProfilePreferencesFile(new File(filename));
- }
+ /**
+ * Configure the custom Firefox preferences (javascript) file on the webdriver factory.
+ *
+ * @param filename
+ */
+ public void loadCustomBrowserPreferencesFromFile(String filename) {
+ defaultWebDriverSupplier.setCustomProfilePreferencesFile(new File(filename));
+ }
/**
- * Configure the custom Firefox profiledirectory on the webdriver factory.
- *
+ * Configure the custom Firefox profiledirectory on the webdriver factory.
+ *
* @param directory
*/
public void loadFirefoxProfileFromDirectory(String directory) {
- defaultWebDriverSupplier.setCustomProfilePreferencesFile(new File(directory));
+ defaultWebDriverSupplier.setCustomProfilePreferencesFile(new File(directory));
}
/**
* @param browser Name of the browser, as accepted by the DefaultWebDriverSupplier.
*/
private void setBrowser(String browser) {
- defaultWebDriverSupplier.setBrowser(browser);
- }
-
- /**
- *
- * | start driver | $Driver | on url | http://localhost |
- *
- *
- * @param webDriver a WebDriver instance
- * @param browserUrl
- */
- public void startDriverOnUrl(final WebDriver webDriver, final String browserUrl) {
- setCommandProcessor(startWebDriverCommandProcessor(browserUrl, webDriver));
- setTimeoutOnSelenium();
- LOG.debug("Started command processor");
- }
+ defaultWebDriverSupplier.setBrowser(browser);
+ }
+
+ /**
+ *
+ * | start driver | $Driver | on url | http://localhost |
+ *
+ *
+ * @param webDriver a WebDriver instance
+ * @param browserUrl
+ */
+ public void startDriverOnUrl(final WebDriver webDriver, final String browserUrl) {
+ setCommandProcessor(startWebDriverCommandProcessor(browserUrl, webDriver));
+ setTimeoutOnSelenium();
+ LOG.debug("Started command processor");
+ }
/**
*
@@ -133,7 +145,7 @@ public void startDriverOnUrl(final WebDriver webDriver, final String browserUrl)
*/
public void startBrowserOnUrl(final String browser, final String browserUrl) {
setBrowser(browser);
- startDriverOnUrl(defaultWebDriverInstance(), browserUrl);
+ startDriverOnUrl(defaultWebDriverInstance(), browserUrl);
}
/**
@@ -226,9 +238,9 @@ public void setTimeoutToSeconds(long timeout) {
*/
private void setTimeoutOnSelenium() {
executeCommand("setTimeout", new String[] { "" + this.timeout });
- WebDriver.Timeouts timeouts = getWebDriver().manage().timeouts();
- timeouts.setScriptTimeout(this.timeout, TimeUnit.MILLISECONDS);
- timeouts.pageLoadTimeout(this.timeout, TimeUnit.MILLISECONDS);
+ WebDriver.Timeouts timeouts = getWebDriver().manage().timeouts();
+ timeouts.setScriptTimeout(this.timeout, TimeUnit.MILLISECONDS);
+ timeouts.pageLoadTimeout(this.timeout, TimeUnit.MILLISECONDS);
}
/**
@@ -361,22 +373,22 @@ public String isOn(final String command, final String target) {
return is(command, new String[] { unalias(target) });
}
- public String is(final String command, final String[] parameters) {
- ExtendedSeleniumCommand seleniumCommand = new ExtendedSeleniumCommand(command);
- String output = executeCommand(seleniumCommand, parameters, stepDelay);
+ public String is(final String command, final String[] parameters) {
+ ExtendedSeleniumCommand seleniumCommand = new ExtendedSeleniumCommand(command);
+ String output = executeCommand(seleniumCommand, parameters, stepDelay);
- if (seleniumCommand.isBooleanCommand() && seleniumCommand.isNegateCommand()) {
- if ("true".equals(output)) {
- output = "false";
- } else if ("false".equals(output)) {
- output = "true";
- } else {
- throw new IllegalStateException("Illegal boolean value: '" + output + "'");
- }
- }
+ if (seleniumCommand.isBooleanCommand() && seleniumCommand.isNegateCommand()) {
+ if ("true".equals(output)) {
+ output = "false";
+ } else if ("false".equals(output)) {
+ output = "true";
+ } else {
+ throw new IllegalStateException("Illegal boolean value: '" + output + "'");
+ }
+ }
- return output;
- }
+ return output;
+ }
/**
* Same as {@link #isOn(String, String)}, only with "with" statement, analog to "do-on-with" command.
@@ -413,19 +425,75 @@ private String unalias(String value) {
String alias = value.substring(ALIAS_PREFIX.length());
String subst = aliases.get(alias);
if (subst != null) {
- LOG.info("Expanded alias '" + alias + "' to '" + result + "'");
- result = subst;
+ LOG.info("Expanded alias '" + alias + "' to '" + result + "'");
+ result = subst;
}
}
return result;
}
+ // The Below 2 functions (searchAllFrames) are used to search all frames for a specific xpath search, and also switchTo the frame that has the found web element
+
+ public WebElement searchAllFrames(String elementXpath) {
+ return searchAllFrames(getWebDriver(), elementXpath, new ArrayList());
+ }
+
+ public WebElement searchAllFrames(WebDriver driver, String elementXpath, List frameSwitches) {
+ if (frameSwitches.size() == 0) //if starting then make sure to search from top
+ driver.switchTo().defaultContent();
+ WebElement element = null; //return null if not found or error during search.
+ try {
+ element = driver.findElement(By.xpath(elementXpath));// need to catch in case not found
+ }catch(Exception e) {}
+ if (element == null)
+ {
+ List framesList = null;
+ try {
+ framesList = driver.findElements(By.xpath("//iframe|//frame"));
+ framesList = driver.findElements(By.cssSelector("iframe|frame"));
+ }catch(Exception e) {}
+ if (framesList == null)
+ return null;
+ for(WebElement frame:framesList){
+ // need to start from the top and switch back to next frame
+ driver.switchTo().defaultContent();
+ for(WebElement nestedFrame:frameSwitches){//nested frames list
+ driver.switchTo().frame(nestedFrame);
+ }
+ driver.switchTo().frame(frame);
+
+ frameSwitches.add(frame);
+ element = searchAllFrames(driver, elementXpath, frameSwitches);
+ if (element != null)
+ return element; // element found
+ else
+ frameSwitches.remove(frame); //this frame had nothing so remove it from the list
+ }
+ return null; //element not found
+ }
+ else
+ return element; //element found
+ }
+
private boolean executeDoCommand(final String methodName, final String[] values) {
+ String output = null;
+ boolean result = true;
+
ExtendedSeleniumCommand command = new ExtendedSeleniumCommand(methodName);
+ boolean locatorFlag = locatorCheck.verifyElementPresent(command, values);
+
SeleniumCommandResult commandResult;
+ if (!locatorFlag) { // if it is a locator command and verifyElementPresent fails
+ String xpathStr = "";
+ if (values.length > 0)
+ xpathStr = values[0];
+ if (searchAllFrames(xpathStr) != null)
+ locatorFlag = true; //searchAllFrames found a matched and switchTo the correct frame
+ }
+
if (!locatorCheck.verifyElementPresent(command, values)) {
commandResult = failure();
} else if (command.requiresPolling()) {
@@ -456,6 +524,81 @@ private boolean executeDoCommand(final String methodName, final String[] values)
}
}
+ private String encryptString(String password) { //encrypt exposed passwords or information stub
+
+ if (password != null) {
+ Cipher aes = null;
+ try {
+ aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ aes.init(Cipher.ENCRYPT_MODE, generateKey());
+ byte[] ciphertext = aes.doFinal(password.getBytes());
+ password = "decrypt:" + bytesToHex(ciphertext); //prefix with "decrypt:"
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return password;
+ }
+
+ public String bytesToHex(byte[] bytes) { //generate hex values for data encryption
+ final char[] hexArray = "0123456789ABCDEF".toCharArray();
+ char[] hexChars = new char[bytes.length * 2];
+ int v;
+ for ( int j = 0; j < bytes.length; j++ ) {
+ v = bytes[j] & 0xFF;
+ hexChars[j * 2] = hexArray[v >>> 4];
+ hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+ }
+ return new String(hexChars);
+ }
+
+ public static SecretKeySpec generateKey() { //salting of the data stub
+ String passStr="XebiumIsConnectedToTheSikuliBone";
+ SecretKey tmp = null;
+ try{
+ String saltStr = "fijsd@#saltr9jsfizxnv";
+ byte[] salt = saltStr.getBytes();
+ int iterations = 43210;
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+ tmp = factory.generateSecret(new PBEKeySpec(passStr.toCharArray(), salt, iterations, 128));
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+ return new SecretKeySpec(tmp.getEncoded(), "AES");
+ }
+
+ public static byte[] hexToBytes(String hex) {//generate bytes value for use internal to fixture
+ int len = hex.length();
+ byte[] data = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16));
+ }
+ return data;
+ }
+
+ public static String processDecryptionString(DefaultWebDriverSupplier driver, String val) { //decrypt the value
+
+ if (val.startsWith("decrypt:") ) {
+ try {
+ val = val.substring(val.indexOf(":") + 1);
+ SecretKeySpec key = generateKey();
+ Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ aes.init(Cipher.DECRYPT_MODE, key);
+ String cleartext = new String(aes.doFinal(hexToBytes(val)));
+ return cleartext;
+ }
+ catch (Exception e) {
+ //LOG.info("Exception processDecryptionString:" + e.getMessage());
+ e.printStackTrace();
+ return val;
+ }
+ }
+ else
+ return val;
+ }
+
private SeleniumCommandResult executeDoCommandPolling(String[] values, ExtendedSeleniumCommand command) {
SeleniumCommandResult commandResult;
long timeoutTime = System.currentTimeMillis() + timeout;
@@ -497,7 +640,7 @@ private String executeCommand(final ExtendedSeleniumCommand command, final Strin
if (commandProcessor == null) {
throw new IllegalStateException("Command processor not running. " +
- "First start it by invoking startBrowserOnUrl.");
+ "First start it by invoking startBrowserOnUrl.");
}
if ("pause".equals(command.getSeleniumCommand())) {
@@ -505,6 +648,17 @@ private String executeCommand(final ExtendedSeleniumCommand command, final Strin
return null;
}
+ if ("contextMenu".equals(command.getSeleniumCommand())) {
+ try {
+ WebElement webElement = getWebDriver().findElement(By.xpath(values[0]));
+ new Actions(getWebDriver()).contextClick(webElement).perform();
+ LOG.info("Performing | contextMenu | " + values[0] + " | " );
+ } catch (Exception e) {
+ LOG.warn("contextMenu command interrupted", e);
+ }
+ return null;
+ }
+
String output = getCommandOutput(command, values);
waitForPageLoadIfNeeded(command);
@@ -583,7 +737,7 @@ private boolean checkResult(ExtendedSeleniumCommand command, String expected, St
private void writeToFile(final String filename, final String output) {
File file = asFile(filename);
try {
- createParentDirectoryIfNeeded(file);
+ createParentDirectoryIfNeeded(file);
ScreenCapture.writeToFile(file, output);
} catch (IOException e) {
@@ -591,15 +745,15 @@ private void writeToFile(final String filename, final String output) {
}
}
- private void createParentDirectoryIfNeeded(File file) throws IOException {
- if (file.getParentFile() != null && !file.getParentFile().exists()) {
- if (!file.getParentFile().mkdirs()) {
- throw new IOException("Could not create parent directory " + file.getParent());
- }
- }
- }
+ private void createParentDirectoryIfNeeded(File file) throws IOException {
+ if (file.getParentFile() != null && !file.getParentFile().exists()) {
+ if (!file.getParentFile().mkdirs()) {
+ throw new IOException("Could not create parent directory " + file.getParent());
+ }
+ }
+ }
- public void stopBrowser() {
+ public void stopBrowser() {
commandProcessor.stop();
commandProcessor = null;
@@ -613,7 +767,7 @@ public CommandProcessor getCommandProcessor() {
public WebDriver getWebDriver() {
return commandProcessor instanceof WebDriverCommandProcessor
? ((WebDriverCommandProcessor) commandProcessor).getWrappedDriver()
- : null;
+ : null;
}
private static class SeleniumCommandResult {