Can this be done ?
Below are snippets of what is not working, failing with exception:
function SendBytesJS() {
var control1 = document.getElementById('sl1');
bytes = new Array(1, 2, 3);
control1.Content.MainPage.SendBytesSL(bytes);
}
and
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
System.Windows.Browser.HtmlPage.RegisterScriptableObject("MainPage", this);
}
[System.Windows.Browser.ScriptableMember]
public void SendBytesSL(byte[] bytes)
{
// never gets here
}
}
The HTML bridge does not support byte arrays and Javascript only understands integer and float (actually double).
An array is passed as object[] and numbers are always passed as double. Hence your code needs to look more like the following:-
// Warning untested code
[ScriptableMember]
public void SendBytesSL(object[] arrayIn)
{
byte[] bytes = arrayIn.Select(o => Convert.ToByte(o)).ToArray();
}
Related
I've been following the documentation for the webview2 on microsoft's official website but I have encountered a problem that I am not sure how to fix.
I have added a .NET object using AddHostObjectToScript and it works as long as the function has no parameter. When calling the object function that has a parameter in JS, I keep on getting a "parameter is incorrect" error.
This is how I am calling the host objects in angular app:
result = await window?.chrome?.webview?.hostObjects.bridge.Func("John");
and this is from my WinUI 3.0 app:
[ComVisible(true)]
public class Bridge
{
public string Func(string param)
{
return "Example: " + param;
}
public string Sample()
{
return "Example: ";
}
public BridgeAnotherClass AnotherObject { get; set; } = new BridgeAnotherClass();
// Sample indexed property.
[System.Runtime.CompilerServices.IndexerName("Items")]
public string this[int index]
{
get { return m_dictionary[index]; }
set { m_dictionary[index] = value; }
}
private Dictionary<int, string> m_dictionary = new Dictionary<int, string>();
}
public sealed partial class WebViewPage : Page
{
public WebViewViewModel ViewModel { get; }
public WebViewPage()
{
ViewModel = Ioc.Default.GetService<WebViewViewModel>();
InitializeComponent();
ViewModel.WebViewService.Initialize(webView);
webView.WebMessageReceived += getMsg;
InitializeAsync();
}
async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async();
var interop = webView.CoreWebView2.As<ICoreWebView2Interop>();
interop.AddHostObjectToScript("bridge", new Bridge());
}
WebView2 currently has an issue where the WinRT API's interop interface AddHostObjectToScript doesn't work well with .NET objects. This is a bug in WebView2.
I want to pass the url of a webpage containing a <span id="spanID"> value </span> tag to a method like setTextBoxText(string url, string id) which is written in a wpf application codeBehind (MainWindow.xaml.cs) and set the Text of a specific TextBox Control to the span value, without loading the webpage. (for Ex. tracking price of a product in amazon)
I prefer to execute JavaScript code to get value of html elements and set the content of wpf controls to the result of the js code (function)
something like this:
public partial class MainWindow : Window
{
string url = "https://websiteaddress.com/rest";
setTextBoxText(url, "spanID");
static void setTextBoxText(string url, string id)
{
// code to get document by given url
txtPrice.Text = getHtmlElementValue(id);
}
string getHtmlElementValue(string id)
{
// what code should be written here?
// any combination of js and c#?
// var result = document.getElementById(id).textContent;
// return result;
}
}
You can use the HttpClient to load the HTML content of an URL and then process the DOM object in a JavaScript like syntax by wrapping the response into a mshtml.HTMLDocument - requires reference to Microsoft.mshtml.dll:
private mshtml.HTMLDocument HtmlDocument { get; set; }
private async Task SetTextBoxTextAsync(string url, string id)
{
await UpdateHtmlDocumentAsync(url);
var value = GetHtmlElementValueById(id);
txtPrice.Text = value;
}
public async Task UpdateHtmlDocumentAsync(string url)
{
using (HttpClient httpClient = new HttpClient())
{
byte[] response = await httpClient.GetByteArrayAsync(url);
string httpResponseText = Encoding.GetEncoding("utf-8").GetString(response, 0, response.Length - 1);
string htmlContent = WebUtility.HtmlDecode(httpResponseText);
this.HtmlDocument = new HTMLDocument();
(this.HtmlDocument as IHTMLDocument2).write(htmlContent);
}
}
public string GetHtmlElementValueById(string elementId)
=> this.HtmlDocument.getElementById(elementId).innerText;
Im a beginner for automation testing.Here I want to get the data's from json to be used by selenium webdriver.I wrote one java class and hard coded something to get a result as a try.and getting an answer in console panel like
{
"name": "john",
"location": "jihu",
"job": [
{
"manager": [
{
"collegues": [
"ram",
"ranma",
],
}
}
}
(not exactly this).
Now i want to use this for one specific application using selenium webdriver. How can i move on with this.help me in detail.Thanks in advance.
From Selenium and Backend Comparison testing point of view i am answering the same .you need to parse json response using some Libraries like GSON , jackson etc into Java Pojo objects and then apply asserts on the fields you want to compare with json and UI. I guess you need to go through below topics first
1) Serialization -Deserialization API response
2) GSON or Jackson parsers
3) RestAssured ( Provides framework for API testing )
4) JAVA pojo classed and usage of them . you might need them to save your response in form of some Response class and compare objects .
You can use these online converters for converting a json object into Java Pojo Classes :
http://json2java.azurewebsites.net/ (I usually use this)
https://codebeautify.org/json-to-java-converter
and then place them in a package or in the same class as you wish :
You can better understand it by below example :
package com.demo.core;
import com.google.gson.Gson;
import io.restassured.RestAssured;
import io.restassured.response.Response;
public class Demo {
public static void main(String r[]) {
Response response1 = RestAssured.given().get("http://dummy.restapiexample.com/api/v1/employee/1"); // use your method to get the API response (I have used RestAssured here)
String json = response1.asString(); // you can use your json response here and convert it into a String
Gson gson = new Gson();
Employee emp = gson.fromJson(json, Employee.class); // The response is now captured in this Employee class
System.out.println(emp.getEmployeeAge());
System.out.println(emp.getEmployeeName());
System.out.println(emp.getEmployeeSalary());
}
}
class Employee {
private String id;
private String employee_name;
private String employee_salary;
private String employee_age;
private String profile_image;
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getEmployeeName() {
return this.employee_name;
}
public void setEmployeeName(String employee_name) {
this.employee_name = employee_name;
}
public String getEmployeeSalary() {
return this.employee_salary;
}
public void setEmployeeSalary(String employee_salary) {
this.employee_salary = employee_salary;
}
public String getEmployeeAge() {
return this.employee_age;
}
public void setEmployeeAge(String employee_age) {
this.employee_age = employee_age;
}
public String getProfileImage() {
return this.profile_image;
}
public void setProfileImage(String profile_image) {
this.profile_image = profile_image;
}
}
You can easily assert the values after the response is captured in Java classes using their getter methods like I have used in the code to get field values present in Employee class.
Please do let me know if you still got an issue.
If your result contains many fields than better to shift all converted java classes into a separate package for a clear code.
I have a website served from a proprietary C++ server.
There is a standard javascript ajax function in the code but I don't want to start editing it.
The actual sending bit is as follows:
this.send=function(myawesomemodel)
{
/*Code redacted for brevity*/
obj.req.open('POST',myawesomeurl,true);
obj.req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
obj.req.send(JSON.stringify(myawesomemodel));
}
It used to send key value pairs as a query string but now it needs to send json.
I can send this function a controller/action address (myawesomeurl) for the appropriate end point and I can send it an awesome object which will be accepted by the action as a basic C# Model (myawesomemodel):
public ActionResult myawesomeaction(MyAwesomeClass myawesomeclass)
{
}
For the .Net model:
public class MyAwesomeClass
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
How do I build a javascript object the controller will recognise please?
Here's my latest failure:
function MyAwesomeModel()
{
this.A=1;
this.B=2;
this.C='Three';
}
Then:
var anawesomemodel=new MyAwesomeModel();
myawesomeajaxmodel.send(anawesomemodel);
I cannot construct the correct object in plain javascript so the mvc action registers it, what's the correct method please?
var myawesomemodel = {
A : 1,
B : 2,
C : 'Three'
}
For anyone else with the same problem who finds this page, Stephen Muecke nailed it
Change the ajax object to:
this.send=function(myawesomemodel)
{
/*Code redacted for brevity*/
obj.req.open('POST',myawesomeurl,true);
obj.req.setRequestHeader('Content-type','application/json;charset=utf-8');
obj.req.send(JSON.stringify(myawesomemodel));
}
I’m trying to upload an excel in servlet and process it. While uploading I set enctype=“multipart/form-data” in my form. But in my servlet .isMultiPart(request) returns false.
JSP code:
function fSubir()
{
fFreezeButtons();
this.document.forms[0].action="../servlet/renault.saf.demandepiece.demandes.servlet.AjouterPoste";
if (this.document.forms[0].Flag.value == "1")
{
this.document.forms[0].Flag.value = "0";
this.document.forms[0].submit();
}
}
Select .xlsx type File :
<input type="submit" value="upload" onclick="fSubir()"/>
My .Jsp also has another form of get method which doesn’t have any enctype.
Servlet code;
public class AjouterPoste extends SapprServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
private final String UPLOAD_DIRECTORY = "/appli01/safdev01/saf_cl2/test/";
public void performTask(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
System.out.println("inside the AjouterPoste class - performTask");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
System.out.println("Inside doPost:"+isMultipart+":"+request);
Please find the parts of my code on which I’m trying to upload a file.
When you submit a form having multipart/form-data, you can't use request.getParameter(paramName). Instead use the code below (part of the Apache FileUpload library)
try {
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
// this part is used instead of request.getParameter
String fieldName = item.getFieldName();
String fieldValue = item.getString();
// do something here
} else {
// this is the file processing part
String fieldName = item.getFieldName();
String fileName = FilenameUtils.getName(item.getName());
InputStream fileContent = item.getInputStream();
...
}
}
} catch (FileUploadException e) {
throw new ServletException("exception", e);
}
You can tell that a specific item is a regular form item (and not a file) by checking that FileItem.isFormField() method returns true.