Last active
March 21, 2017 19:35
-
-
Save AlexP11223/8286153 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Awesomium.Core; | |
namespace WebViewHelpers | |
{ | |
public static class WebViewExtensions | |
{ | |
/// <summary> | |
/// Simulates mouse movement to the specified coordinates and click. | |
/// As I remember it requires coordinates relative to the currently displayed area, and also will not work if specified coordinates are out of that area. | |
/// </summary> | |
public static void Click(this IWebView webView, int x, int y) | |
{ | |
webView.InjectMouseMove(x, y); | |
webView.InjectMouseDown(MouseButton.Left); | |
webView.InjectMouseUp(MouseButton.Left); | |
} | |
/// <summary> | |
/// Simulates mouse movement to the specified coordinates and click. | |
/// As I remember it requires coordinates relative to the currently displayed area, and also will not work if specified coordinates are out of that area. | |
/// </summary> | |
public static void Click(this IWebView webView, Point p) | |
{ | |
webView.Click(p.X, p.Y); | |
} | |
/// <summary> | |
/// Fires specified event on element specified by any Javascript query for getting a single element. | |
/// </summary> | |
/// <param name="getElementQuery"> | |
/// <para>Any Javascript query to get an element.</para> | |
/// <para>Examples:</para> | |
/// <para>"document.getElementById('id')"</para> | |
/// <para>"document.getElementsByClassName('name')[0]"</para> | |
/// <para>"document.evaluate(\"//a[contains(@href, 'something')]\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue" (XPath)</para> | |
/// </param> | |
/// <param name="eventName">Event name such as "click", "mouseup"</param> | |
public static void JsFireEvent(this IWebView webView, string getElementQuery, string eventName) | |
{ | |
webView.ExecuteJavascript(@" | |
function fireEvent(element,event) { | |
var evt = document.createEvent('HTMLEvents'); | |
evt.initEvent(event, true, false ); // event type,bubbling,cancelable | |
element.dispatchEvent(evt); | |
} | |
" + String.Format("fireEvent({0}, '{1}');", getElementQuery, eventName)); | |
} | |
/// <summary> | |
/// <para>(Mostly for backward-compatibility for code when JsFireEvent didn't exist.)</para> | |
/// <para>Some elements like <a> does not have click() method (although it works in Chrome), so this method works for them.</para> | |
/// </summary> | |
/// <param name="getElementQuery"> | |
/// <para>Any Javascript query to get an element.</para> | |
/// <para>Examples:</para> | |
/// <para>"document.getElementById('id')"</para> | |
/// <para>"document.getElementsByClassName('name')[0]"</para> | |
/// <para>"document.evaluate(\"//a[contains(@href, 'something')]\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue" (XPath)</para> | |
/// </param> | |
public static void ImprovedJsClick(this IWebView webView, string getElementQuery) | |
{ | |
//webView.JsFireEvent(getElementQuery, "click"); // probably can replace to this | |
webView.ExecuteJavascript(@" | |
function clickEvent(obj){ | |
var fireOnThis = obj; | |
var evObj = document.createEvent('MouseEvents'); | |
evObj.initEvent( 'click', true, false ); | |
fireOnThis.dispatchEvent(evObj); | |
} | |
" + String.Format("clickEvent({0});", getElementQuery)); | |
} | |
/// <summary> | |
/// <para>Sends key/character to focused element.</para> | |
/// <para>Examples:</para> | |
/// <para>TypeKey(VirtualKey.A, "A"); // uppercase A</para> | |
/// <para>TypeKey(VirtualKey.B, "b"); // lowercase b</para> | |
/// <para>TypeKey(VirtualKey.DOWN, ""); // down arrow</para> | |
/// <para>TypeKey(VirtualKey.RETURN, "\r\n"); // Enter</para> | |
/// </summary> | |
public static void TypeKey(this IWebView webView, VirtualKey vk, string chr) | |
{ | |
var keyEvent = new WebKeyboardEvent(); | |
keyEvent.Type = WebKeyboardEventType.KeyDown; | |
keyEvent.VirtualKeyCode = vk; | |
webView.InjectKeyboardEvent(keyEvent); | |
keyEvent.Type = WebKeyboardEventType.Char; | |
keyEvent.Text = chr; | |
webView.InjectKeyboardEvent(keyEvent); | |
keyEvent.Type = WebKeyboardEventType.KeyUp; | |
keyEvent.VirtualKeyCode = vk; | |
webView.InjectKeyboardEvent(keyEvent); | |
} | |
/// <summary> | |
/// Returns HTML code string of the page | |
/// </summary> | |
public static string GetHtml(this IWebView webView) | |
{ | |
return webView.ExecuteJavascriptWithResult("document.getElementsByTagName('html')[0].innerHTML"); | |
} | |
/// <summary> | |
/// Finds and returns element (JSObject) by id using document.getElementById | |
/// </summary> | |
public static dynamic GetElementById(this IWebView webView, string id) | |
{ | |
dynamic element = (JSObject)webView.ExecuteJavascriptWithResult(String.Format("document.getElementById('{0}')", id)); | |
return element; | |
} | |
/// <summary> | |
/// Finds and returns elements (JSObject array) by name using document.getElementsByName | |
/// </summary> | |
public static dynamic GetElementsByName(this IWebView webView, string name) | |
{ | |
dynamic elements = (JSObject)webView.ExecuteJavascriptWithResult(String.Format("document.getElementsByName('{0}')", name)); | |
return elements; | |
} | |
/// <summary> | |
/// Finds and returns elements (JSObject array) by tag using document.getElementsByTagName | |
/// </summary> | |
public static dynamic GetElementsByTagName(this IWebView webView, string tag) | |
{ | |
dynamic elements = (JSObject)webView.ExecuteJavascriptWithResult(String.Format("document.getElementsByTagName('{0}')", tag)); | |
return elements; | |
} | |
/// <summary> | |
/// Finds and returns elements (JSObject array) by class using document.getElementsByClassName | |
/// </summary> | |
public static dynamic GetElementsByClassName(this IWebView webView, string className) | |
{ | |
dynamic elements = (JSObject)webView.ExecuteJavascriptWithResult(String.Format("document.getElementsByClassName('{0}')", className)); | |
return elements; | |
} | |
/// <summary> | |
/// Fills the textbox with the specified text | |
/// </summary> | |
public static void FillTextbox(IWebView webView, dynamic textbox, string value) | |
{ | |
textbox.focus(); | |
textbox.value = value; | |
} | |
/// <summary> | |
/// Finds textbox by id (using GetElementById) and fills with the specified text | |
/// </summary> | |
public static void FillTextboxById(this IWebView webView, string id, string value) | |
{ | |
using (dynamic textbox = webView.GetElementById(id)) | |
{ | |
if (textbox == null) | |
throw new Exception("Element " + id + " was not found."); | |
FillTextbox(webView, textbox, value); | |
} | |
} | |
/// <summary> | |
/// Finds textbox by name (using GetElementsByName, the first one if more than one exist) and fills with the specified text | |
/// </summary> | |
public static void FillTextboxByName(this IWebView webView, string name, string value) | |
{ | |
using (dynamic elements = webView.GetElementsByName(name)) | |
{ | |
if (elements == null || elements.length == 0) | |
throw new Exception("No elements with name " + name + " were found."); | |
using (dynamic textbox = elements[0]) | |
{ | |
FillTextbox(webView, textbox, value); | |
} | |
} | |
} | |
/// <summary> | |
/// Finds and clicks button by id (using GetElementById) | |
/// </summary> | |
public static void ClickButtonById(this IWebView webView, string id) | |
{ | |
using (dynamic button = webView.GetElementById(id)) | |
{ | |
if (button == null) | |
throw new Exception("Element " + id + " was not found."); | |
button.click(); | |
} | |
} | |
/// <summary> | |
/// Finds and clicks button by name (using GetElementsByName, the first one if more than one exist) | |
/// </summary> | |
public static void ClickButtonByName(this IWebView webView, string name) | |
{ | |
using (dynamic buttons = webView.GetElementsByName(name)) | |
{ | |
if (buttons == null || buttons.length == 0) | |
throw new Exception("No elements with name " + name + " were found."); | |
using (dynamic btn = buttons[0]) | |
{ | |
btn.click(); | |
} | |
} | |
} | |
/// <summary> | |
/// Finds and clicks button by tag + value (the first one if more than one exist) | |
/// <para>Could be slow if there are many elements with this tag on the page, use XPath instead</para> | |
/// </summary> | |
public static void ClickButtonByValue(this IWebView webView, string value, string tag = "input") | |
{ | |
using (dynamic elements = webView.GetElementsByTagName(tag)) | |
{ | |
if (elements == null || elements.length == 0) | |
throw new Exception("Failed to get page input elements."); | |
int len = elements.length; | |
for (int i = 0; i < len; i++) | |
{ | |
using (var button = elements[i]) | |
{ | |
if (button.value == value) | |
{ | |
button.click(); | |
return; | |
} | |
} | |
} | |
} | |
throw new Exception("Element " + value + " was not found."); | |
} | |
/// <summary> | |
/// Finds checkbox by id (using GetElementById) and sets it to isChecked | |
/// </summary> | |
public static void CheckCheckboxById(this IWebView webView, string id, bool isChecked = true) | |
{ | |
using (dynamic checkbox = webView.GetElementById(id)) | |
{ | |
if (checkbox == null) | |
throw new Exception("Element " + id + " was not found."); | |
checkbox.@checked = isChecked; | |
} | |
} | |
/// <summary> | |
/// Finds select ("listbox") by id (using GetElementById) and sets selectedIndex | |
/// </summary> | |
public static void SetSelectIndexById(this IWebView webView, string id, int selectedIndex) | |
{ | |
using (dynamic select = webView.GetElementById(id)) | |
{ | |
if (select == null) | |
throw new Exception("Element " + id + " was not found."); | |
select.selectedIndex = selectedIndex; | |
} | |
} | |
/// <summary> | |
/// Finds select ("listbox") by id (using GetElementsByName, chooses by index if more than one exist) and sets selectedIndex | |
/// </summary> | |
public static void SetSelectIndexByName(this IWebView webView, string name, int selectedIndex, int index = 0) | |
{ | |
using (dynamic elements = webView.GetElementsByName(name)) | |
{ | |
if (elements == null || elements.length == 0) | |
throw new Exception("No elements with name " + name + " were found."); | |
if (elements.length < index + 1) | |
throw new Exception(string.Format("Array of elements with name {0} does not have {1} elements.", name, index + 1)); | |
using (dynamic select = elements[index]) | |
{ | |
select.selectedIndex = selectedIndex; | |
} | |
} | |
} | |
/// <summary> | |
/// Finds element by id (using GetElementById) and returns its coordinates of top-left corner relative to the page | |
/// </summary> | |
public static Point GetElementPositionById(this IWebView webView, string id) | |
{ | |
using (dynamic element = webView.GetElementById(id)) | |
{ | |
if (element == null) | |
throw new Exception("Element " + id + " was not found."); | |
return WebViewHelper.GetElementPosition(element); | |
} | |
} | |
/// <summary> | |
/// Finds element by id (using GetElementsByName, chooses by index if more than one exist) and returns its coordinates of top-left corner relative to the page | |
/// </summary> | |
public static Point GetElementPositionByName(this IWebView webView, string name, int index = 0) | |
{ | |
using (dynamic elements = webView.GetElementsByName(name)) | |
{ | |
if (elements == null || elements.length == 0) | |
throw new Exception("No elements with name " + name + " were found."); | |
if (elements.length < index + 1) | |
throw new Exception(string.Format("Array of elements with name {0} does not have {1} elements.", name, index + 1)); | |
using (dynamic element = elements[index]) | |
{ | |
return WebViewHelper.GetElementPosition(element); | |
} | |
} | |
} | |
/// <summary> | |
/// Finds element by class (using GetElementsByClassName, chooses by index if more than one exist) and returns its coordinates of top-left corner relative to the page | |
/// </summary> | |
public static Point GetElementPositionByClassName(this IWebView webView, string className, int index = 0) | |
{ | |
using (dynamic elements = webView.GetElementsByClassName(className)) | |
{ | |
if (elements == null || elements.length == 0) | |
throw new Exception("No elements with class name " + className + " were found."); | |
if (elements.length < index + 1) | |
throw new Exception(string.Format("Array of elements with class name {0} does not have {1} elements.", className, index + 1)); | |
using (dynamic element = elements[index]) | |
{ | |
return WebViewHelper.GetElementPosition(element); | |
} | |
} | |
} | |
/// <summary> | |
/// Returns Base64 string of image content. Without redownloading image. If it is not on the same domain, WebSecurity must be set to false. | |
/// </summary> | |
/// <param name="getElementQuery"> | |
/// <para>Any Javascript query to get an element.</para> | |
/// <para>Examples:</para> | |
/// <para>"document.getElementById('id')"</para> | |
/// <para>"document.getElementsByClassName('name')[0]"</para> | |
/// <para>"document.evaluate(\"//a[contains(@href, 'something')]\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue" (XPath)</para> | |
/// </param> | |
/// <param name="leaveOnlyBase64Data">if true, removes "data:image/type;base64," from the beginning of the string</param> | |
/// <returns>Base64 string or empty string in case of error</returns> | |
public static string JsGetImgBase64String(this IWebView webView, string getElementQuery, | |
bool leaveOnlyBase64Data = true) | |
{ | |
string data = webView.ExecuteJavascriptWithResult(@" | |
function getImgBase64String(img) | |
{ | |
var cnv = document.createElement('CANVAS'); | |
var ctx = cnv.getContext('2d'); | |
ctx.drawImage(img, 0, 0); | |
return cnv.toDataURL(); | |
} | |
" + String.Format("getImgBase64String({0});", getElementQuery)); | |
if (data == "undefined") | |
return string.Empty; | |
if (leaveOnlyBase64Data && data.Contains(",")) | |
{ | |
data = data.Substring(data.IndexOf(",") + 1); | |
} | |
return data; | |
} | |
} | |
public struct Point | |
{ | |
public int X, Y; | |
public Point(int x, int y) | |
{ | |
X = x; | |
Y = y; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace WebViewHelpers | |
{ | |
public static class WebViewHelper | |
{ | |
/// <summary> | |
/// Returns JavaScript XPath query string for getting a single element | |
/// </summary> | |
/// <param name="xpath">Any valid XPath string, for example "//input[@id='myid']"</param> | |
/// <returns>JS code to perform the XPath query (document.evaluate(...)</returns> | |
public static string GetJsSingleXpathString(string xpath) | |
{ | |
return | |
String.Format( | |
"document.evaluate(\"{0}\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue", xpath); | |
} | |
/// <summary> | |
/// Returns JavaScript XPath query string for getting a collection of elements | |
/// </summary> | |
/// <param name="xpath">Any valid XPath string, for example "//input[@id='myid']"</param> | |
/// <returns>JS code to perform the XPath query (document.evaluate(...)</returns> | |
public static string GetJsXpathString(string xpath) | |
{ | |
return | |
String.Format( | |
"document.evaluate(\"{0}\", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null)", xpath); | |
} | |
/// <summary> | |
/// Returns coordinates of top-left corner of the element (probably relative to the page) | |
/// </summary> | |
public static Point GetElementPosition(dynamic element) | |
{ | |
dynamic rect = element.getBoundingClientRect(); | |
using (rect) | |
{ | |
return new Point(rect.left, rect.top); | |
} | |
} | |
} | |
} |
Yes, I used this in 1.7.4. But I think most (or all) of this should work in 1.7.5 too.
Not sure about background-image, never tried
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
is this work for awesomium 1.7.4? (I just downgraded from 1.7.5) and is this work for code like background-image(url:) ?
thanks :)