package com.abmash.api;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import org.joda.time.DateTime;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.abmash.api.query.QueryFactory.*;
import com.abmash.api.browser.Debug;
import com.abmash.api.browser.Frame;
import com.abmash.api.browser.History;
import com.abmash.api.browser.JavaScript;
import com.abmash.api.browser.WaitFor;
import com.abmash.api.browser.Window;
import com.abmash.api.query.Query;
import com.abmash.api.query.QueryFactory;
import com.abmash.core.browser.BrowserConfig;
import com.abmash.core.browser.JavaScriptResult;
import com.abmash.core.browser.interaction.OpenURL;
import com.abmash.core.document.Document;
import com.abmash.core.query.predicate.Predicate;
import com.abmash.core.tools.IOTools;
/**
* Main class for using a browser instance and interacting with it. You are encouraged to use more than one browser instance
* to interact with more than one page at a time. This can prove useful if you are switching between the same pages multiple
* times.
* <p>
* <strong>Examples:</strong>
* <ul>
* <li><code>browser.click("Save");</code> clicks on a link or button labeled <em>Save</em>
* <li><code>browser.type("Username", "Jack");</code> enter the text <em>Jack</em> in the input field labeled <em>Username</em>
* <li><code>browser.select("language", "english");</code> selects the options <em>english</em> in the dropdown/list labeled <em>language</em>
* <li><code>HtmlElement firstTitle = browser.query(headline()).findFirst();</code> finds the first title element on the current page and saves them</li>
* <li><code>HtmlElements imagesLeftOfTitle = browser.query(image(), leftOf(title)).find();</code> finds all image elements left of the previously found title</li>
* </ul>
* <p>
* Elements can be searched by queries to get their values and text, and to interact with them. Search queries are <strong>case-sensitive</strong>.
* <p>
* Use {@link Browser#click(String)} to search for elements with the specified name or label and click the best match.
* <p>
* Use {@link Browser#type(String, String)} to search for input elements (usually {@code <input>} or {@code <textarea>}, but also
* rich text editors used by many CMS, forums or blog applications) with the specified name or label, get the best match
* and enter the given text.
* <p>
* Use {@link Browser#choose(String, String)} to search for {@code <select>} elements (usually a dropdown selection or a box with a list
* of options) with the specified name or label, get the best match and select the given option from the list.
* <p>
* Use {@link Browser#query(Predicate...)} to create a {@link Query} instance and to search for {@link HtmlElements}. Predicates can be arbitrarily combined.
* The call of {@link Query#find()} or {@link Query#findFirst()} will return the result(s).
* <p>
* Found elements can be further interacted with, see {@link HtmlElement}.
*
* @see Query
* @see HtmlElement
* @see HtmlElements
* @author Alper Ortac
*/
public class Browser {
/**
* Logging instance to send messages to preconfigured devices.
* See src/main/resources/logback.xml for details.
*/
private static final Logger LOG = LoggerFactory.getLogger(Browser.class);
private RemoteWebDriver webDriver;
private History history;
private Window window;
private Frame frame;
private WaitFor waitFor;
private Debug debug;
// TODO http://twill.idyll.org/
// -----------------------------------------------------------------------
// Main methods
// -----------------------------------------------------------------------
/**
* Starts new browser session. Opens the browser and waits until it is ready.
* <p>
* The default browser configuration is the use of Firefox 4 and can be overwritten by creating a default.properties file.
* TODO explanation properties. For further customization see also {@link #Browser(String, BrowserConfig)}.
* <p>
* Each browser instance needs to be closed at the end of the program by calling the {@link #close()} method.
* Use {@link #openUrl(String)} to open another URL in the browser.
*
* @see #close()
* @see #openUrl(String)
*/
public Browser() {
// create new browser config and instantiate all needed classes
this(null, new BrowserConfig());
}
/**
* Starts new browser session. Opens the browser, loads the given URL and waits until it is ready.
* <p>
* The default browser configuration is the use of Firefox 4 and can be overwritten by creating a default.properties file.
* TODO explanation properties. For further customization see also {@link #Browser(String, BrowserConfig)}.
* <p>
* Each browser instance needs to be closed at the end of the program by calling the {@link #close()} method.
* Use {@link #openUrl(String)} to open another URL in the browser.
*
* @param url The URL to open, set to null to prevent loading a page
* @see #close()
* @see #openUrl(String)
*/
public Browser(String url) {
// create new browser config and instantiate all needed classes
this(url, new BrowserConfig());
}
/**
* Starts new browser session with specified {@link BrowserConfig}. Opens the browser, loads the given URL and waits until it is ready.
* <p>
* Each browser instance needs to be closed at the end of the program by calling the {@link #close()} method.
* Use {@link #openUrl(String)} to open another URL in the browser.
*
* @param url The URL to open, set to null to prevent loading a page
* @param config BrowserConfig instance
* @see #close()
* @see #openUrl(String)
*/
public Browser(String url, BrowserConfig config) {
// use browser config and instantiate all needed classes
webDriver = config.getWebDriver();
// TODO where to put detection of alerts and popups?
history = new History(this);
window = new Window(this);
frame = new Frame(this);
waitFor = new WaitFor(this);
debug = new Debug(this);
openUrl(url);
}
/**
* Opens page with specified URL.
* <p>
* If there is more than one window open, the URL will be opened in current focused browser window.
*
* @param url the URL to open, <code>null</code> does not open a web page
*/
public void openUrl(String url) {
new OpenURL(this, url).execute();
}
/**
* Closes all browser windows and stops all browser interactions.
*/
public void close() {
log().info("Closing browser");
webDriver.close();
webDriver.quit();
}
// -----------------------------------------------------------------------
// Browser functionality
// -----------------------------------------------------------------------
/**
* Allows to interact with the browser history.
*
* @return the browser history manager
*/
public History history() {
return history;
}
/**
* Allows to interact with browser windows. Windows can be opened, closed and focused.
*
* @return the browser window manager
*/
public Window window() {
return window;
}
/**
* Allows to focus page frames and iframes.
*
* @return the browser frame manager
*/
public Frame frame() {
return frame;
}
/**
* Allows to wait for the browser to finish specified tasks.
*
* @return the browser wait manager
*/
public WaitFor waitFor() {
return waitFor;
}
/**
* Debugging methods to highlight elements or pause the execution.
*
* @return the browser debug manager
*/
public Debug debug() {
return debug;
}
/**
* Loads JavaScript and evaluates it synchronously.
* <p>
* If needed, the jQuery library is automatically loaded.
* <p>
* Examples:
* <pre>
* browser.javaScript("alert('info message');");
* JavaScriptResult result = browser.javaScript("return jQuery('#content').html();");
* </pre>
*
* @param script The script to run
* @return JavaScriptResult result object to retrieve the return value and type
*/
public JavaScriptResult javaScript(String script, Object... args) {
return new JavaScript(script).evaluate(this, args);
}
/**
* Reads JavaScript from a file and evaluates it synchronously.
* <p>
* The files need to be placed in the src/main/resources/js directory.
* <p>
* If needed, the jQuery library is automatically loaded.
*
* @param scriptFilename The script to load (without the file extension .js)
* @return JavaScriptResult result object to retrieve the return value and type
*/
public JavaScriptResult javaScriptFromFile(String scriptFilename, Object... args) {
return new JavaScript(scriptFilename, true).evaluate(this, args);
}
/**
* Loads JavaScript and evaluates it asynchronously.
* <p>
* If needed, the jQuery library is automatically loaded.
* <p>
* Examples:
* <pre>
* browser.javaScriptAsync("alert('info message');");
* JavaScriptResult result = browser.javaScriptAsync("return jQuery('#content').html();");
* </pre>
*
* @param script The script to run
* @return JavaScriptResult result object to retrieve the return value and type
*/
public JavaScriptResult javaScriptAsync(String script, Object... args) {
return new JavaScript(script).evaluateAsync(this, args);
}
/**
* Reads JavaScript from a file and evaluates it asynchronously.
* <p>
* The files need to be placed in the src/main/resources/js directory.
* <p>
* If needed, the jQuery library is automatically loaded.
*
* @param scriptFilename The script to load (without the file extension .js)
* @return JavaScriptResult result object to retrieve the return value and type
*/
public JavaScriptResult javaScriptFromFileAsync(String scriptFilename, Object... args) {
return new JavaScript(scriptFilename, true).evaluateAsync(this, args);
}
/**
* Reads CSS from a string and injects it into the current web page.
* Image urls are converted to binary data so that they can be displayed.
* <p>
* The image files need to be placed in the src/main/resources/images directory.
*
* @param styleDefinitions the stylesheet definitions
* @param flatImageFolder true if all images are in the same folder or false if the images are in the corresponding subfolders
* @return this browser instance
*/
public Browser css(String styleDefinitions, Boolean flatImageFolder, Object... args) {
Pattern pattern;
if(flatImageFolder) {
pattern = Pattern.compile("url\\((?:.*?\\/)(.*?).(png|gif)\\)");
} else {
pattern = Pattern.compile("url\\(((?:.*?\\/).*?).(png|gif)\\)");
}
Matcher matcher = pattern.matcher(styleDefinitions);
StringBuffer styleDefinitionsWithInlineImageData = new StringBuffer();
int lastMatchEndPosition = 0;
while(matcher.find()) {
String filename = matcher.group(1);
String extension = matcher.group(2);
lastMatchEndPosition = matcher.end();
matcher.appendReplacement(styleDefinitionsWithInlineImageData, "url(" + IOTools.convertImageToBinaryData(
JavaScript.class.getResourceAsStream("/images/" + filename + "." + extension), extension) + ")");
}
// add all definitions from the last match until the end of the stylesheet
styleDefinitionsWithInlineImageData.append(styleDefinitions.substring(lastMatchEndPosition));
String script = "jQuery('<style type=\"text/css\">" + styleDefinitionsWithInlineImageData.toString() + "</style>').appendTo('html > head');";
new JavaScript(script).evaluate(this, args);
return this;
}
/**
* Reads CSS from a file and injects it into the current web page.
* Image urls are converted to binary data so that they can be displayed.
* <p>
* The css files need to be placed in the src/main/resources/css directory.
* <p>
* The image files need to be placed in the src/main/resources/images directory.
*
* @param stylesheetFile the stylesheet to load (without the file extension .css)
* @param flatImageFolder true if all images are in the same folder or false if the images are in the corresponding subfolders
* @return this browser instance
*/
public Browser cssFromFile(String stylesheetFile, Boolean flatImageFolder, Object... args) {
InputStream stream = JavaScript.class.getResourceAsStream("/css/" + stylesheetFile + ".css");
// TODO the css is not allowed to have line breaks, why?
return css(IOTools.convertStreamToString(stream).replace("\n", " "), flatImageFolder, args);
}
// /**
// * Reads PNG from a file and injects it into the current web page.
// * <p>
// * The files need to be placed in the src/main/resources/css directory.
// *
// * @param stylesheet the stylesheet to load (without the file extension .css)
// * @return this browser instance
// */
// public Browser imagePngFile(String imageFile) {
// InputStream stream = BrowserJavaScript.class.getResourceAsStream("/images/" + imageFile + ".png");
// String script = "jQuery('');";
// javaScript(script).execute();
// return this;
// }
// -----------------------------------------------------------------------
// HtmlQuery
// -----------------------------------------------------------------------
// TODO root elements?
public Query query(Predicate... predicates) {
return QueryFactory.query(this, predicates);
}
// /**
// * Creates {@link HtmlQuery} instance to find elements on current page.
// * <p>
// * <strong>Examples:</strong>
// * <ul>
// * <li><code>browser.query().has("result").findFirst();</code> searches for elements containing the attribute or
// * inner text <em>result</em></li>
// * <li><code>browser.query().isClickable().findFirst();</code> searches for clickable elements like links and buttons</li>
// * <li>for more examples see {@link HtmlQuery}</li>
// * </ul>
// * <p>
// * <strong>Description:</strong>
// * <p>
// * Define conditions by chaining <code>is</code>, <code>has</code>, <code>tag</code> and <code>select</code>
// * methods. Get the query result by executing {@link HtmlQuery#find()} or {@link HtmlQuery#findFirst()}.
// *
// * @return HtmlQuery instance to add an arbitrary number of find conditions
// * @see HtmlQuery
// */
// public HtmlQuery query() {
// return new HtmlQuery(this);
// }
//
// /**
// * Creates {@link HtmlQuery} instance to filter elements on current page.
// * <p>
// * TODO examples
// *
// * @return HtmlQuery instance to add an arbitrary number of find conditions
// * @see Browser#query()
// * @see HtmlQuery#subsetOf(HtmlElements)
// */
// public HtmlQuery query(HtmlElements elementsToFilter) {
// return new HtmlQuery(this).subsetOf(elementsToFilter);
// }
// -----------------------------------------------------------------------
// Browser Interaction with HtmlElements
// -----------------------------------------------------------------------
/**
* Searches for a clickable element with specified query string and clicks it.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.click("Save");</code> clicks on a link or button labeled <em>Save</em></li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* Elements having an attribute value or visible text containing the query string will
* be added to the result set. The first result will be used for clicking. If you already have an
* {@link HtmlElement} instance use {@link HtmlElement#click()} instead.
* <p>
* Note that if the page reloads after a click, all found {@link HtmlElement} instances may lose their validity.
*
* @param clickable element label
* @return HtmlElement to further interact with that element or {@code null} if element could not be found
* @see HtmlElement#click()
*/
public HtmlElement click(String clickable) {
HtmlElement element = query(clickable(clickable)).findFirstWithWait();
return element instanceof HtmlElement ? element.click() : null;
}
/**
* Searches for a element with specified query string and hovers it with the mouse.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.hover("News");</code> fires the "mouseover" event on the element labeled <em>News</em></li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* Elements having an attribute value or visible text containing the query string will
* be added to the result set. The first result will be used for hovering. If you already have an
* {@link HtmlElement} instance use {@link HtmlElement#hover()} instead.
*
* @param clickable element which will be used for hovering with the mouse
* @return HtmlElement to further interact with that element or {@code null} if element could not be found
* @see HtmlElement#hover()
*/
public HtmlElement hover(String clickable) {
HtmlElement element = query(clickable(clickable)).findFirstWithWait();
return element instanceof HtmlElement ? element.hover() : null;
}
/**
* Searches for a element with specified query string and drags it with the mouse to another element.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.dragTo("product", "cart");</code> drags the element labeled <em>Product</em> to the
* element labeled <em>Cart</em></li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* Elements having an attribute value or visible text containing the query string will
* be added to the result set. The first result will be used for dragging. If you already have an
* {@link HtmlElement} instance use {@link HtmlElement#dragTo(HtmlElement)} instead.
*
* @param elementToDrag source element label; this is going to be dragged
* @param elemenToDropOn target element label; the source element is dropped here
* @return HtmlElement to further interact with that element or {@code null} if element could not be found
* @see HtmlElement#dragTo(HtmlElement)
*/
public HtmlElement drag(String elementToDrag, String elemenToDropOn) {
HtmlElement source = query(contains(elementToDrag)).findFirstWithWait();
HtmlElement target = query(contains(elemenToDropOn)).findFirstWithWait();
return source instanceof HtmlElement && target instanceof HtmlElement ? source.dragTo(target) : null;
}
/**
* Searches for element with specified query string and enters the text.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.type("location","New York").submit();</code> types in the text <em>New York</em>
* in the input field named or labeled <em>location</em> and then submits the form which contains that element.</li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* Elements having an attribute value or visible text containing the query string will
* be added to the result set. The first result will be used for typing in the text. If you already have an
* {@link HtmlElement} instance use {@link HtmlElement#type(String)} instead. Use {@link HtmlElement#submit()}
* on the returned object to submit the form.
*
* @param typable the label of the input field
* @param text the text to type in
* @return HtmlElement to further interact with the form element, for instance to {@link HtmlElement#submit()} the form,
* or {@code null} if element could not be found
* @see HtmlElement#type(String)
*/
public HtmlElement type(String typable, String text) {
HtmlElement element = query(typable(typable)).findFirstWithWait();
return element instanceof HtmlElement ? element.type(text) : null;
}
/**
* Searches for dropdown/list input field and selects the specified option. Use {@link HtmlElement#submit()}
* on the returned object to submit the form.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.choose("language","english").submit();</code> selects the <em>english</em> option from the list
* select field named or labeled <em>language</em> and then submits the form which contains that element.</li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* TODO Select description
*
* @param choosable dropdown/select element
* @param option the label or value of the option to select
* @return HtmlElement to further interact with the form element, for instance to {@link HtmlElement#submit()} the form,
* or {@code null} if element could not be found
*/
public HtmlElement choose(String choosable, String option) {
HtmlElement element = query(choosable(choosable)).findFirstWithWait();
return element instanceof HtmlElement ? element.choose(option) : null;
}
/**
* Searches for dropdown/list input field and deselects the specified option. Use {@link HtmlElement#submit()}
* on the returned object to submit the form.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.unchoose("language","english").submit();</code> deselects the <em>english</em> option from the list
* select field named or labeled <em>language</em> and then submits the form which contains that element.</li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* TODO Select description
*
* @param choosable dropdown/select element
* @param option the label or value of the option to deselect
* @return HtmlElement to further interact with the form element, for instance to {@link HtmlElement#submit()} the form,
* or {@code null} if element could not be found
*/
public HtmlElement unchoose(String choosable, String option) {
HtmlElement element = query(choosable(choosable)).findFirstWithWait();
return element instanceof HtmlElement ? element.unchoose(option) : null;
}
/**
* Searches for checkbox input field and toggles it. Use {@link HtmlElement#submit()}
* on the returned object to submit the form.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.checkToggle("newsletter").submit();</code> toggles the checkbox labeled <em>newsletter</em>.</li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* TODO Select description
*
* @param checkable checkbox element
* @return HtmlElement to further interact with the form element, for instance to {@link HtmlElement#submit()} the form,
* or {@code null} if element could not be found
*/
public HtmlElement checkToggle(String checkable) {
HtmlElement element = query(checkable(checkable)).findFirstWithWait();
return element instanceof HtmlElement ? element.click() : null;
}
/**
* Searches for calendar/date picker input fields and selects the specified date. Use {@link HtmlElement#submit()}
* on the returned object to submit the form.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.chooseDate("Arrival", new Date()).submit();</code> selects the specified date in the date picker
* named or labeled <em>Arrival</em> and then submits the form which contains that element.</li>
* </ul>
* <p>
* <strong>Description:</strong>
* <p>
* TODO Select description
*
* @param datepicker calendar/date picker element
* @param dateTime the date to select
* @return HtmlElement to further interact with the form element, for instance to {@link HtmlElement#submit()} the form,
* or {@code null} if element could not be found
*/
public HtmlElement chooseDate(String datepicker, DateTime dateTime) {
HtmlElement element = query(datepicker(datepicker)).findFirstWithWait();
return element instanceof HtmlElement ? element.chooseDate(dateTime) : null;
}
/**
* Submits the form, which contains the given form element.
* <p>
* <strong>Example:</strong>
* <ul>
* <li><code>browser.submit("address");</code> submits the form which contains the form element labeled <em>address</em>.</li>
* </ul>
* <p>
*
* @param submittable form submit element
* @return HtmlElement to further interact with the form element or {@code null} if element could not be found
*/
public HtmlElement submit(String submittable) {
HtmlElement element = query(submittable(submittable)).findFirstWithWait();
return element instanceof HtmlElement ? element.submit() : null;
}
// /**
// * Finds the first list whose visible text or attribute values contains the given search query,
// * and the {@link List} representation.
// * <p>
// * <strong>Example:</strong>
// * <ul>
// * <li><code>List ingredientTable = browser.getTable("Ingredient");</code> returns the first table which contains the
// * text <em>Ingredient</em>.</li>
// * <li><code>ingredientTable.get(0);</code> returns the first list item.</li>
// * </ul>
// *
// * @param query text which is contained in the list (visible text or attribute value)
// * @return List representation of this element
// * @see List
// */
// public List getList(String query) {
// return new List(this, query);
// }
//
// /**
// * Returns the {@link List} representation of a {@code <ul>}, {@code <ol>} or {@code <dl>} element.
// * <p>
// * <strong>Example:</strong>
// * <ul>
// * <li><code>HtmlElement listTitle = browser.query().isTitle().has("Ingredients").findFirst();</code> Returns the first element being a title labeled <em>Ingredients</em></li>
// * <li><code>HtmlElement list = browser.query().isList().below(tableTitle).findFirst();</code> returns the first list below the previously selected title element</li>
// * <li><code>List ingredientList = browser.getList(table);</code> finally returns the list representation.</li>
// * <li><code>ingredientList.get(0);</code> returns the first list item.</li>
// * <li>See {@link List} for more examples on how to interact with the table.</li>
// * </ul>
// *
// * @param listElement has to be an {@link HtmlElement} with the tag {@code <ul>}, {@code <ol>} or {@code <dl>}
// * @return List representation of this element
// * @see List
// */
// public List getList(HtmlElement listElement) {
// return new List(listElement);
// }
//
// /**
// * Finds the first table whose visible text or attribute values contains the given search query,
// * and the {@link Table} representation.
// * <p>
// * <strong>Example:</strong>
// * <ul>
// * <li><code>Table userTable = browser.getTable("User");</code> returns the first table which contains the
// * text <em>User</em>.</li>
// * <li><code>userTable.get(0, "email");</code> returns the <em>email</em> address of the user in the first row.</li>
// * </ul>
// *
// * @param query text which is contained in the table (visible text or attribute value)
// * @return Table representation of this element
// * @see Table
// */
// public Table getTable(String query) {
// return new Table(this, query);
// }
//
// /**
// * Returns the {@link Table} representation of a {@code <table>} element.
// * <p>
// * <strong>Example:</strong>
// * <ul>
// * <li><code>HtmlElement tableTitle = browser.query().isTitle().has("Userlist").findFirst();</code> Returns the first element being a title labeled <em>Userlist</em></li>
// * <li><code>HtmlElement table = browser.query().isTable().below(tableTitle).findFirst();</code> returns the first table below the previously selected title element</li>
// * <li><code>Table userTable = browser.getTable(table);</code> finally returns the table representation.</li>
// * <li><code>userTable.getCell(0, "email");</code> returns the <em>email</em> address of the user in the first row.</li>
// * <li>See {@link Table} for more examples on how to interact with the table.</li>
// * </ul>
// *
// * @param tableElement has to be an {@link HtmlElement} with the tag {@code <table>}
// * @return Table representation of this element
// * @see Table
// */
// public Table getTable(HtmlElement tableElement) {
// return new Table(tableElement);
// }
// -----------------------------------------------------------------------
// Content Output and Parser
// -----------------------------------------------------------------------
// TODO parser
// public DocumentParser getParser() {
// // depending on current document type, create the appropriate parser instance
// String contentType = windowManager.getCurrentContentType();
//
// DocumentParser parser = new HTMLParser(this);
// if(false) {
// }
// else if (contentType.startsWith("text/html")) {
// // default
// }
// else {
// // default
// }
// return parser;
// }
// TODO get document for different content types
// TODO with htmlelement
// public Document getDocument(String query) {
// // TODO decision: href, src, background, ...
// HtmlElement element = query().has(query).is(ElementType.CLICKABLE).findFirst();
// String href = element.getAttribute("href");
// URL url = null;
// try {
// url = new URL(new URL(getCurrentUrl()), href);
// } catch (MalformedURLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// // TODO is windowmanager really responsible for this?
// String contentType = windowManager.getContentTypeOfURL(url).toLowerCase();
//
// Document document = this;
// if(contentType.endsWith("html")) {
// // TODO is clicking intended here?
// element.click();
// }
// else if(contentType.endsWith("pdf")) {
// try {
// document = new PDFDocument(url);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// return document;
// }
// -----------------------------------------------------------------------
// Conversion
// TODO
// -----------------------------------------------------------------------
// public Object getJsonRepresentationOfWebElement(WebElement webElement) {
// return (new WebElementToJsonConverter()).apply(webElement);
// }
//
// public Object getWebElementOfJsonRepresentation(Object json) {
// return (new JsonToWebElementConverter((RemoteWebDriver) webDriver)).apply(json);
// }
// -----------------------------------------------------------------------
// Take screenshots
// -----------------------------------------------------------------------
public File getScreenshotAsFile() {
return ((TakesScreenshot) getWebDriver()).getScreenshotAs(OutputType.FILE);
}
public byte[] getScreenshotAsByteArray() {
return ((TakesScreenshot) getWebDriver()).getScreenshotAs(OutputType.BYTES);
}
public BufferedImage getScreenshotAsBufferedImage() throws IOException {
return ImageIO.read(new ByteArrayInputStream(getScreenshotAsByteArray()));
}
public String getScreenshotAsBase64() {
return getScreenshotAsBase64(false);
}
public String getScreenshotAsBase64(boolean withDataPrefix) {
return (withDataPrefix ? "data:image/png;base64," : "") + ((TakesScreenshot) getWebDriver()).getScreenshotAs(OutputType.BASE64);
}
// -----------------------------------------------------------------------
// Getters
// -----------------------------------------------------------------------
/**
* Gets URL of current page
*
* @return URL of current page
*/
public String getCurrentUrl() {
return webDriver.getCurrentUrl();
}
/**
* Gets HTML source code of current page
*
* @return HTML source code of current page
*/
public String getPageSource() {
return webDriver.getPageSource();
}
/**
* Gets logger instance.
*
* @return Logger instance
*/
public Logger log() {
return LOG;
}
/**
* Gets underlying <a href="http://seleniumhq.org/">Selenium</a> WebDriver instance.
* <p>
* The <code>WebDriver</code> is internally used to do all interactions with the browser.
* In general, it is not necessary to use this manually.
*
* @return Selenium WebDriver
*/
public RemoteWebDriver getWebDriver() {
return webDriver;
}
}