package com.redhat.qe.auto.selenium;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.testng.ITestResult;
import org.testng.Reporter;
import com.redhat.qe.auto.testng.LogMessageUtil;
import com.thoughtworks.selenium.CommandProcessor;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.SeleniumException;
/**
* This class extends the DefaultSelenium functionality. It
* provides logging of UI actions (via java standard logging),
* and some convenience methods.
* @author jweiss
*
*/
public class ExtendedSelenium extends DefaultSelenium implements ITestNGScreenCapture, Serializable {
/**
*
*/
private static final long serialVersionUID = -4832886620261520916L;
private static ExtendedSelenium instance = null;
private static Logger log = Logger.getLogger(ExtendedSelenium.class.getName());
private static File screenshotDir = null;
private static File localHtmlDir = null;
private static final DecimalFormat numFormat = new DecimalFormat("##0.#");
protected static final String DEFAULT_WAITFORPAGE_TIMEOUT = "60000";
protected static String WAITFORPAGE_TIMEOUT = DEFAULT_WAITFORPAGE_TIMEOUT;
private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmssS");
public ExtendedSelenium(CommandProcessor processor) {
super(processor);
}
public ExtendedSelenium(String serverHost, int serverPort,
String browserStartCommand, String browserURL) {
super(serverHost, serverPort, browserStartCommand, browserURL);
}
@Override
public void start() {
log.finer("Start selenium.");
super.start();
// TODO this is ugly
TestNGListener.setScreenCaptureUtility(this);
windowFocus();
windowMaximize();
String delay = System.getProperty("selenium.delay");
if (delay != null) {
try {
setSpeed(delay);
}
catch(Exception e){
log.log(Level.FINER, "Could not set delay: " + delay, e);
}
}
}
@Override
public void stop() {
log.finer("Stop selenium.");
super.stop();
//added this as part of a fix to guarantee that only instance of selenium
//is running. So be sure that there is only one browser session up at a time
killInstance();
//debugging this, because screenshots are getting taken too late on hudson wdh
//log.fine("Selenium stopped.");
//log.log(MyLevel.FINER,"Selenium stopped");
//log.info("Selenium stopped");
}
public boolean isEditable(Element element) {
return super.isEditable(element.getLocator());
}
public boolean isChecked(Element element) {
return super.isChecked(element.getLocator());
}
public String getValue(Element element) {
return getValue(element.getLocator());
}
@Override
public String getValue(String locator) {
highlight(locator);
return super.getValue(locator);
}
public void clickAndWait(String locator) {
clickAndWait(locator, WAITFORPAGE_TIMEOUT, true);
}
public void clickAndWait(Element element) {
click(element);
waitForPageToLoad(WAITFORPAGE_TIMEOUT);
}
public void clickAndWait(String locator, String timeout) {
clickAndWait(locator, timeout, true);
}
public void clickAndWait(Element element, String timeout) {
clickAndWait(element.getLocator(), timeout);
}
public void clickAndWait(String locator, String timeout, boolean highlight) {
click(locator, highlight);
waitForPageToLoad(timeout);
}
public void clickAndWait(Element element, String timeout, boolean highlight) {
clickAndWait(element.getLocator(), timeout, highlight);
}
public void selectAndWait(String selectLocator, String optionLocator){
select(selectLocator, optionLocator);
waitForPageToLoad();
}
public void selectAndWait(Element element, String optionLocator){
selectAndWait(element.getLocator(), optionLocator);
}
public void waitForPageToLoad(){
waitForPageToLoad(WAITFORPAGE_TIMEOUT);
}
@Override
public void waitForPageToLoad(String timeout){
log.finer("Wait for page to load.");
long start = System.currentTimeMillis();
super.waitForPageToLoad(timeout);
Double waitedInSecs = ((System.currentTimeMillis() - start)) / 1000.0;
log.finer("Waited " + numFormat.format(waitedInSecs) + "s for page to load.");
}
/**
* @param locator
* @param highlight - if true, highlight the element for a fraction of a second before clicking it.
* This makes it easier to see what selenium is doing "live".
*/
public void click(String locator, boolean highlight) {
log.log(Level.INFO, "Click on " + getDescription(locator), LogMessageUtil.Style.Action);
if (highlight) highlight(locator);
super.click(locator);
}
public void doubleClick(String locator, boolean highlight) {
log.log(Level.INFO, "Double click on " + getDescription(locator), LogMessageUtil.Style.Action);
if (highlight) highlight(locator);
super.doubleClick(locator);
}
@Override
public void click(String locator) {
click(locator, true);
}
@Override
public void doubleClick(String locator) {
doubleClick(locator, true);
}
//TODO need to have logging like this on all similar methods --JMW 10/5/09
public void click(Element element) {
Element humanReadable = element.getHumanReadable();
if (humanReadable != null) {
try {
log.log(Level.INFO, "Click on element: " + this.getText(humanReadable), LogMessageUtil.Style.Action);
} catch(Exception e) {
log.log(Level.FINEST, "Unable to get text for associated human readable element: " + humanReadable, e);
}
} else {
log.log(Level.INFO, "Click on " + getDescription(element), LogMessageUtil.Style.Action);
}
highlight(element);
super.click(element.getLocator());
}
public void doubleClick(Element element) {
Element humanReadable = element.getHumanReadable();
if (humanReadable != null) {
try {
log.log(Level.INFO, "Double click on element: " + this.getText(humanReadable), LogMessageUtil.Style.Action);
} catch(Exception e) {
log.log(Level.FINEST, "Unable to get text for associated human readable element: " + humanReadable, e);
}
} else {
log.log(Level.INFO, "Double click on " + getDescription(element), LogMessageUtil.Style.Action);
}
highlight(element);
super.doubleClick(element.getLocator());
}
public String getText(Element element){
return getText(element.getLocator());
}
@Override
public String getText(String locator) {
highlight(locator);
return super.getText(locator);
}
public String getSelectedLabel(Element element){
return getSelectedLabel(element.getLocator());
}
@Override
public void mouseOver(String locator) {
log.log(Level.INFO, "Hover over " + getDescription(locator), LogMessageUtil.Style.Action);
super.mouseOver(locator);
}
public void mouseOver(Element element) {
log.log(Level.INFO, "Hover over " + getDescription(element), LogMessageUtil.Style.Action);
super.mouseOver(element.getLocator());
}
@Override
public void keyPress(String locator, String keySequence) {
highlight(locator);
super.keyPress(locator,keySequence);
}
public void keyPress(Element element, String keySequence) {
log.log(Level.INFO, "Press and release key '"+keySequence+"' on " + getDescription(element), LogMessageUtil.Style.Action);
keyPress(element.getLocator(), keySequence);
}
/**
* @param locator
* @param highlight - if true, highlight the element for a fraction of a second before clicking it.
* This makes it easier to see what selenium is doing "live".
*/
public void click(String locator, String humanReadableName, boolean highlight) {
log.log(Level.INFO, "Click on : " + humanReadableName, LogMessageUtil.Style.Action);
if (highlight) highlight(locator);
super.click(locator);
}
public void click(String locator, String humanReadableName) {
click(locator,humanReadableName, true);
}
/**
* Waits for an element to appear on the page, then clicks it. This method is useful for interacting with
* elements that are created by AJAX calls. You should be reasonably sure that the element will in fact appear,
* otherwise the execution will not continue until the timeout is hit (and then an exception will be thrown).
* @param locator A locator for the element to click on when it appears
* @param timeout How long to wait for the element to appear before timing out and throwing an exception
*/
public void waitAndClick(String locator, String timeout){
super.waitForCondition("selenium.isElementPresent(\"" + escape(locator) + "\");", timeout);
click(locator);
}
public void waitAndClick(Element element, String timeout) {
super.waitForCondition("selenium.isElementPresent(\"" + escape(element.getLocator()) + "\");", timeout);
click(element);
}
/**
* Similar to waitAndClick- waits for an element to appear on the page, then clicks it, then waits for the page
* to load.
* @param locator A locator for the element to click on when it appears
* @param timeout1 How long to wait for the element to appear before timing out and throwing an exception
* @param timeout2 How long to wait for the page to load after clicking the element.
*/
public void waitAndClickAndWait(String locator, String timeout1, String timeout2){
try {
super.waitForCondition("selenium.isElementPresent(\"" + escape(locator) + "\");", timeout1);
}
catch(Exception e){
RuntimeException rte = new RuntimeException("Element did not appear: " + locator);
rte.initCause(e);
throw rte;
}
clickAndWait(locator, timeout2);
}
public void waitAndClickAndWait(Element element, String timeout1, String timeout2) {
waitAndClickAndWait(element.getLocator(), timeout1, timeout2);
}
public void waitAndClickAndWait(String locator, String timeout1){
waitAndClickAndWait(locator, timeout1, WAITFORPAGE_TIMEOUT);
}
public void waitAndClickAndWait(Element element, String timeout1) {
waitAndClickAndWait(element.getLocator(), timeout1);
}
public void waitForElement(String locator, String timeout){
log.info("Waiting for element '" + locator + "', with timeout of " + timeout + ".");
super.waitForCondition("selenium.isElementPresent(\"" + escape(locator) + "\");", timeout);
}
public void waitForElement(Element element, String timeout){
log.info("Wait for element '" + element + "', with timeout of " + timeout + ".");
super.waitForCondition("selenium.isElementPresent(\"" + escape(element.getLocator()) + "\");", timeout);
}
public void waitForTextPresent(String text, String timeout) {
log.info("Wait for text `" + text + "`, with timeout of " + timeout + ".");
super.waitForCondition("selenium.isTextPresent(\"" + text +"\");", timeout);
}
/**
* Wait for an element to be invisible.<br>
* Note: On an AJAXy page, an element can exist and be invisible.
* @param locator - element locator path to wait for
* @param timeout - milliseconds
* @author jsefler
*/
public void waitForInvisible(String locator, String timeout){
// if the locator is not present, then it is effectively invisible
if (!super.isElementPresent(locator)) return;
log.finer("Wait for element to be invisible '"+locator+"', with timeout of "+timeout+".");
try{
super.waitForCondition("!selenium.isVisible(\""+ escape(locator) +"\");", timeout);
}
catch(SeleniumException e){
if (e.getMessage().contains("not found")){
log.finest("Element '"+locator+"' is not present; effectively this constitutes invisibility");
return;
}
else
throw e;
}
}
public void waitForInvisible(Element element, String timeout){
waitForInvisible(element.getLocator(), timeout);
}
/**
* Wait for an element to be visible.<br>
* Note: On an AJAXy page, an element can exist and be invisible.
* @param locator - element locator path to wait for
* @param timeout - milliseconds
* @author jsefler
*/
public void waitForVisible(String locator, String timeout){
log.finer("Wait for element to be visible '" + locator + "', with timeout of " + timeout + ".");
super.waitForCondition("selenium.isElementPresent(\""+ escape(locator) +"\");", timeout); // first wait for its existence
super.waitForCondition("selenium.isVisible(\""+ escape(locator) +"\");", timeout); // then wait for its visibility
}
public void waitForVisible(Element element, String timeout){
waitForVisible(element.getLocator(), timeout);
}
@Override
public void type(String locator, String value) {
log.log(Level.INFO, "Type '" + value + "' into " + getDescription(locator), LogMessageUtil.Style.Action);
highlight(locator);
super.type(locator, value);
}
public void type(Element element, String value) {
type(element.getLocator(), value);
}
@Override
public void typeKeys(String locator, String value) {
log.log(Level.INFO, "Type keys '" + value + "' into " + getDescription(locator), LogMessageUtil.Style.Action);
highlight(locator);
super.typeKeys(locator, value);
}
public void typeKeys(Element element, String value) {
typeKeys(element.getLocator(), value);
}
public void type(String locator, String humanReadableName, String value) {
log.log(Level.INFO, "Type '" + value + "' into " + getElementType(locator) + ": " + humanReadableName + "'", LogMessageUtil.Style.Action);
highlight(locator);
super.type(locator, value);
}
public void setText(String locator, String value){
type(locator, value);
}
public void setText(Element element, String value){
log.log(Level.INFO, "Type '" + value + "' into " + getDescription(element), LogMessageUtil.Style.Action);
highlight(element);
super.type(element.getLocator(), value);
}
public void setText(String locator, String humanReadableName,String value){
type(locator,humanReadableName, value);
}
@Override
public void open(String url) {
log.log(Level.INFO, "Open URL '" + url + "'.", LogMessageUtil.Style.Action);
super.open(url);
log.info("Current URL is " + getLocation() + " .");
}
@Override
public void check(String locator) {
log.log(Level.INFO, "Check " + getDescription(locator), LogMessageUtil.Style.Action);
checkUncheck(locator, true);
}
public void check(Element element){
checkUncheck(element, true);
}
@Override
public void uncheck(String locator) {
log.log(Level.INFO, "Uncheck " + getDescription(locator), LogMessageUtil.Style.Action);
checkUncheck(locator, false);
}
public void uncheck(Element element){
checkUncheck(element, false);
}
public void checkUncheck(Element element, boolean check){
log.log(Level.INFO, (check? "Check ":"Uncheck ") + element, LogMessageUtil.Style.Action);
checkUncheck(element.getLocator(), check);
}
public void checkUncheck(String locator, boolean check){
if (isChecked(locator) != check) {
highlight(locator);
super.click(locator);
if (isChecked(locator) != check) {
if (check)
super.check(locator); //just to be sure
else super.uncheck(locator);
}
}
else {
highlight(locator);
log.log(Level.FINE, getDescription(locator) + " is already " + (check ? "checked.": "unchecked."));
}
}
@Override
public void select(String selectLocator, String optionLocator) {
log.log(Level.INFO, "Select option '" + optionLocator + "' in list '" + selectLocator + "'.", LogMessageUtil.Style.Action);
highlight(selectLocator);
super.select(selectLocator, optionLocator);
}
public void select(Element element, String optionLocator) {
Element humanReadable = element.getHumanReadable();
if (humanReadable != null) {
try {
log.log(Level.INFO, "Select option '" + optionLocator + "' in list corresponding to " + getText(humanReadable), LogMessageUtil.Style.Action);
} catch(Exception e) {
log.log(Level.FINEST, "Unable to get text for associated human readable element: " + humanReadable, e);
}
} else {
log.log(Level.INFO, "Select option '" + optionLocator + "' in list " + element, LogMessageUtil.Style.Action);
}
highlight(element);
super.select(element.getLocator(), optionLocator);
}
/**
* Selects a list item by value. To be used when a select list doesn't have any other
* good locators. It's up to the
* caller to make sure there isn't more than one select list on the page that contains
* the same value.
* @param value The value attribute of the Option. This is not necessarily the same as what text
* appears in the browser.
*/
public void select(String value){
select("//select[option[@value='" + value + "']]", "value=" + value);
}
public void select(Element element){
select(element.getLocator());
}
/*
* @see com.thoughtworks.selenium.DefaultSelenium#isElementPresent(java.lang.String)
*/
@Override
public boolean isElementPresent(String element){
return isElementPresent(element, Level.FINER);
}
public boolean isElementPresent(Element element){
return isElementPresent(element.getLocator());
}
public boolean isVisible(Element element){
return isVisible(element.getLocator());
}
public boolean isElementPresent(TabElement element){
return (isElementPresent(element.getLocator()) |
isElementPresent(element.getSelectedElement().getLocator()));
}
public boolean isElementSelected(TabElement tabElement) {
if (tabElement.getSelectedElement().equals(tabElement)) {
log.log(Level.WARNING, "Do not know how to determine if this tab element is selected: "+this);
return false;
}
return isElementPresent(tabElement.getSelectedElement().getLocator()) && !isElementPresent(tabElement.getLocator());
}
public boolean isElementPresent(String element,Level level){
if(super.isElementPresent(element)){
log.log(level,"Found " + getDescription(element));
//highlight(element); //TODO It's misleading to highlight an element on an arbitrary query. It's more appropriate to highlight on a assertElementIsPresent(...) which is not yet written. (jsefler 11/12/09)
return true;
}
else {
log.log(level, "Did not find " + getDescription(element));
return false;
}
}
public boolean isElementPresent(Element element,Level level){
return isElementPresent(element.getLocator(), level);
}
public boolean isTextPresent(String txt, Level level){
if(super.isTextPresent(txt)){
log.log(level,"Found text: '"+ txt+"'");
return true;
}
else {
log.log(level, "Did not find text: '"+ txt+"'");
return false;
}
}
@Override
public void goBack(){
log.log(Level.INFO, "Click Browser Back Button", LogMessageUtil.Style.Action);
super.goBack();
waitForPageToLoad();
}
@Override
public void refresh(){
log.log(Level.INFO, "Click Browser Refresh Button", LogMessageUtil.Style.Action);
super.refresh();
waitForPageToLoad();
}
public boolean isElementPresentWithRefreshing(String locator, long timeout_ms, long refreshInterval_ms){
if (isElementPresent(locator))
return true;
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < timeout_ms ){
sleep(refreshInterval_ms);
refresh();
if (isElementPresent(locator))
return true;
}
return false;
}
public boolean isElementPresentWithRefreshing(Element element, long timeout_ms, long refreshInterval_ms){
return isElementPresentWithRefreshing(element.getLocator(), timeout_ms, refreshInterval_ms);
}
@Override
public String getAlert() {
log.log(Level.INFO, "Click OK on alert dialog.", LogMessageUtil.Style.Action);
String text = super.getAlert();
log.log(Level.INFO, "Dismissed alert dialog: " + text);
return text;
}
@Override
public String getConfirmation() {
log.log(Level.INFO, "Click OK on confirmation dialog.", LogMessageUtil.Style.Action);
String text = super.getConfirmation();
log.log(Level.INFO, "Dismissed confirmation dialog: " + text);
return text;
}
@Override
public String getPrompt() {
log.log(Level.INFO, "Click OK on prompt dialog.", LogMessageUtil.Style.Action);
String text = super.getPrompt();
log.log(Level.INFO, "Dismissed prompt dialog: " + text);
return text;
}
@Override
public void answerOnNextPrompt(String answer){
log.log(Level.INFO, "Answering prompt with: " + answer, LogMessageUtil.Style.Action);
super.answerOnNextPrompt(answer);
}
@Override
public void setTimeout(String timeout){
super.setTimeout(timeout);
WAITFORPAGE_TIMEOUT = timeout;
}
/**
* Retrieves the current value for Selenium wait for page timeout.
* @return Current value of: WAITFORPAGE_TIMEOUT
*/
public String getTimeout(){
return WAITFORPAGE_TIMEOUT;
}
public void selectPopupWindowAndWait(){
String[] winnames = getAllWindowNames();
String name = winnames[winnames.length-1]; //select last opened window
waitForPopUp(name, "60000");
selectWindow(name);
}
public void sleep(long millis){
try {
log.log(Level.INFO, "Sleep for " + millis + "ms.");
Thread.sleep(millis);
}
catch(InterruptedException ie){
log.log(Level.WARNING, "Sleep interrupted!", ie);
}
}
public String[] getSelectOptions(Element element){
return super.getSelectOptions(element.getLocator());
}
/**
* Gets the HTML attributes for a given locator
* @param locator
* @return a Properties object containing all the attributes of the
* element. Also includes a "tagName" attribute which contains the tag name,
* eg, input, a, div, etc.
* @throws IOException
*/
public Properties getAttributes(String locator) {
String attributesScript =
"{" +
"var elem = this.browserbot.findElement(\"" + locator + "\");" +
"var attrs = elem.attributes;" +
"var str='tagName=' + elem.tagName + '\\n';" +
"for(var i = 0; i < attrs.length; i++) {" +
" str = str + attrs[i].name + '=' + attrs[i].value + '\\n';" +
"};" +
"str;" + // the value of str is the returned String result from getEval(attributesScript);
"}";
Properties props = new Properties();
String result = getEval(attributesScript);
StringBuffer StringBuffer1 = new StringBuffer(result);
try {
ByteArrayInputStream Bis1 = new ByteArrayInputStream(StringBuffer1.toString().getBytes("UTF-8"));
props.load(Bis1);
}catch(IOException ioe) {
throw new RuntimeException(ioe);
}
return props;
}
/*
* Properties attr = sel().getAttributes(element);
Set<String> mySet = attr.stringPropertyNames();
for(String s:mySet){
log.info(s);
log.info(attr.getProperty(s));
}
log.info("TAG "+sel().getAttributes(element).getProperty("tagName"));
*/
public Properties getAttributes(Element element) {
return getAttributes(element.getLocator());
}
public String getElementType(Element element) {
return getElementType(element.getLocator());
}
/**
* Return a string description of what was acted upon by selenium
* @param element
* @return
*/
public String getDescription(Element element) {
String elementStr = element.toString();
String elementType = "";
try {
elementType = getElementType(element);
}catch(Exception e) {
log.log(Level.FINER, "Could not retrieve element type, perhaps it is not present: " + elementStr, e);
}
//remove duplicate element type strings to avoid logs like... Click on link: link in table... -> Click on link: in table...
elementStr=elementStr.replaceAll("^" +Pattern.quote(elementType) + " ", "");
//remove duplicate element type strings to avoid logs like... Click on submit button: button in table... -> Click on submit button: in table... (jsefler 1/7/2010)
if (elementType.contains(" ")) elementStr=elementStr.replaceAll("^" +Pattern.quote(elementType.substring(elementType.lastIndexOf(" ")).trim()) + " ", "");
return elementType + ": " + elementStr;
}
public String getDescription(String locator) {
try {
return getElementType(locator) + ": " + locator;
} catch(Exception e) {
log.log(Level.FINER, "Could not get element type for '" + locator + "', perhaps it is not present?", e);
}
return locator;
}
public String getElementType(String locator) {
Properties attrs;
try {
attrs = getAttributes(locator);
}
catch (Exception e){
//if attributes can't be retrieved, log and return the locator
log.log(Level.FINEST, "Can't retrieve attributes for locator: " + locator, e);
return locator;
}
String tagName = attrs.getProperty("tagName").toLowerCase();
if (tagName.equals("input")) {
String type = null;
try {
type = attrs.getProperty("type").toLowerCase();
}
catch(NullPointerException npe) {
return "textbox";
}
if (type.equals("text")) return "textbox";
if (type.equals("button")) return "button";
if (type.equals("checkbox")) return "checkbox";
if (type.equals("image")) return "input image";
if (type.equals("password")) return "password textbox";
if (type.equals("radio")) return "radio button";
if (type.equals("submit")) return "submit button";
return tagName + " " + type;
}
else if (tagName.equals("a")) return "link";
else if (tagName.equals("select")) return "selectlist";
else if (tagName.equals("div")) return "link";
else if (tagName.equals("img")) return "image";
else if (tagName.equals("td")) return "table cell";
else if (tagName.equals("span")) return "link";
else return tagName;
}
public String screenCapture() throws Exception {
String dirName = System.getProperty("selenium.screenshot.dir", System.getProperty("user.dir") + File.separator
+ "screenshots");
return screenCapture(dirName);
}
protected void writeBase64ScreenCapture(String data, File file) throws FileNotFoundException, IOException{
byte[] pngBytes = Base64.decode(data);
FileOutputStream fos = new FileOutputStream(file);
fos.write(pngBytes);
fos.flush();
fos.close();
}
public String screenCapture(String dirName) throws Exception {
String fullPathtoFile = null;
mkdir(dirName);
Date rightNow = new Date();
String outFileName = dateFormat.format(rightNow) + ".png";
try {
File htmlDir = localHtmlDir != null? localHtmlDir : screenshotDir;
writeHtmlOnError(htmlDir);
//if success use that next time
localHtmlDir = htmlDir;
fullPathtoFile = localHtmlDir.getCanonicalPath()+ File.separator + outFileName;
pngRemoteScreenCapture(fullPathtoFile);
}
catch(Exception e ){
log.log(Level.FINER, "Couldn't capture screenshot, trying to write to tmp dir instead.",e);
//if this failed, try the temp dir
screenshotDir = new File("/tmp");
super.captureScreenshot("/tmp"+ File.separator + outFileName);
//log.log(Level.FINE, "Captured ScreenShot to "+"/tmp"+ File.separator + outFileName);
fullPathtoFile = "/tmp"+ File.separator + outFileName;
//writeHtmlOnError(screenshotDir);
}
return fullPathtoFile;
}
public void testNGScreenCapture(ITestResult result) throws Exception{
String dirName = System.getProperty("selenium.screenshot.dir", System.getProperty("user.dir") + File.separator
+ "test-output" + File.separator + "screenshots");
mkdir(dirName);
Date rightNow = new Date();
String outFileName = dateFormat.format(rightNow) + "-" + result.getTestClass().getName() + "." + result.getMethod().getMethodName() + ".png";
String fullpath = dirName + File.separator + outFileName;
pngRemoteScreenCapture(fullpath);
//embed link in testng report
Reporter.setCurrentTestResult(result);
String screenshotLinkUrl = System.getProperty("selenium.screenshot.link.path", "../screenshots");
Reporter.log("<a href='" + String.format("%s/%s", screenshotLinkUrl, outFileName) + "'>Screenshot</a>");
}
public void testNGScreenCapture() throws Exception{
String dirName = System.getProperty("selenium.screenshot.dir", System.getProperty("user.dir") + File.separator
+ "test-output" + File.separator + "screenshots");
mkdir(dirName);
Date rightNow = new Date();
String outFileName = dateFormat.format(rightNow) + ".png";
String fullpath = dirName + File.separator + outFileName;
pngRemoteScreenCapture(fullpath);
//embed link in testng report
//Reporter.setCurrentTestResult(result);
String screenshotLinkUrl = System.getProperty("selenium.screenshot.link.path", "../screenshots");
Reporter.log("<a href='" + String.format("%s/%s", screenshotLinkUrl, outFileName) + "'>Screenshot</a>");
}
protected void pngRemoteScreenCapture(String filepath) throws Exception{
String base64Png = super.captureEntirePageScreenshotToString("");
File ssFile = new File(filepath);
writeBase64ScreenCapture(base64Png, ssFile);
log.log(Level.FINE, "screenshot URL= "+ getLocation());
log.log(Level.FINE, "Captured screenshot to "+ ssFile.toURI().toURL());
}
protected void mkdir(String dirName){
if (screenshotDir == null) {
screenshotDir = new File(dirName);
}
if (!(screenshotDir.exists() && screenshotDir.isDirectory())) {
screenshotDir.mkdirs();
}
}
protected void writeHtmlOnError(File dir) throws Exception{
Date rightNow = new Date();
BufferedWriter out = new BufferedWriter(new FileWriter(dir.getCanonicalPath()
+ File.separator + dateFormat.format(rightNow) + ".html"));
out.write(getHtmlSource());
out.close();
}
public static ExtendedSelenium getInstance(){
if (instance == null) throw new NullPointerException("Selenium instance not set yet.");
return instance;
}
public static void killInstance(){
instance = null;//
}
@Override
public void highlight(String locator) {
// TODO a decision to globally turn on/off highlight should be done here
try {
super.highlight(locator);
} catch (Exception e) {
log.log(Level.FINER, "Could not highlight locator '"+locator+"', perhaps it is not present: " + e);
}
}
public void highlight(Element element) {
highlight (element.getLocator());
}
public static ExtendedSelenium newInstance(String serverHost, int serverPort, String browserStartCommand, String browserURL){
instance = new ExtendedSelenium(serverHost, serverPort, browserStartCommand, browserURL);
return instance;
}
public static String escape(String locator){
return locator.replace("\"", "\\\"");
}
public void waitForEnabled(Element elem, String millis) {
// FIXME: Until the javascript portion of this method performs more consistently,
// sleep is a better alternative.
/*
log.info("Wait for enabled'" + elem + "', with timeout of " + millis + ".");
String locatorStr = escape(elem.getLocator());
String script = "" //
+ "{var elem = selenium.browserbot.findElement(\""
+ locatorStr
+ "\");" //
+ "var canvas = selenium.browserbot.getUserWindow().isc.AutoTest.locateCanvasFromDOMElement(elem);" //
+ "!canvas.isDisabled();}";
sel().waitForCondition(script, millis);
*/
try {
Thread.currentThread().sleep(Integer.parseInt(millis));
}
catch (InterruptedException e) {
log.log(Level.INFO, "Thread sleep error: ", e);
e.printStackTrace();
}
}
public void waitForEnabledAndClick(Element elem, String millis) {
waitForEnabled(elem, millis);
click(elem);
}
public static void main (String... args) {
System.out.println(Pattern.quote("^//td[(normalize-space(.)='jweiss-rhel1.usersys.redhat.com')]/..//input[@type='checkbox']"));
String elementType = "submit button", elementStr="button in a table";
if (elementType.contains(" ")) elementStr=elementStr.replaceAll("^" +Pattern.quote(elementType.substring(elementType.lastIndexOf(" ")).trim()) + " ", "");
}
}