and sorry for the confusing title!
so, i am developing a "lobby" where users come in, and other users can see when somebody logs in to the lobby. there can be many lobbies, but only when a user log in to the same lobby, they will show up. the solution and deployment works fine, my problem is (as the title suggests) testing this whole mess!
For this, i figured i need to test 2 things:
1. i need to test that signalR HUB side calls correctly when clients connects etc. so testing the server side part of SignalR
2. i need to test that my javascript, thats under the folder wwwroot/js (asp.net core mvc) for this i figure i need to use mocha. my problem here is that the js files is under a c# .net core project, and i dont know how to test it then.
However, after tirelessly searching forums and docs everywhere on the net, i came up with no solutions for none of the problems! i hope somebody can help, maybe hint some ideas of how i go about doing this.
i will post my relevant code here:
Lobby.cshtml
#using Domain.Interfaces
#using Domain.Models
#using GUI_Index.Session
#using Microsoft.AspNetCore.Http
#model GUI_Index.ViewModels.LobbyViewModel
#{
ViewData["Title"] = "Tilslut Lobby";
}
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<body>
<div class="container">
<button id="ForLadLobby" type="button" class="btn btn-post" onclick="location.href = '#Url.Action("ForladLobby", "Lobby", Model)'">Ud af lobby</button>
<div class="form-group left-Align ingamebox">
<table id="UsersInLobby">
<th>Users in Lobby: </th>
#{
foreach (var usernames in Model.Usernames)
{
<tr id="#usernames">
<td>
#usernames
</td>
</tr>
}
}
</table>
</div>
<div class="form-group right-Align ingamebox">
Message...<input type="text" id="messageInput" />
<input type="button" class="btn btn-primary" id="sendButton" value="Send Message" />
</div>
#{
string user = SessionExtension.GetObjectFromJson<User>(Context.Request.HttpContext.Session, "user").Username;
}
<form method="post" formaction="#Url.Action("Lobby", "Lobby")">
<table>
<tr>
<div class="top-Align">
<div id="center-Text">
Hello: <label id="LobbyUser">#user</label> <br/>
Welcome to: <label id="LobbyId">#Model.Id</label>
</div>
<ul id="Messages"></ul>
</div>
</tr>
<tr>
<div class="absolute-center is-responsive">
<div class="form-group">
<input type="hidden" class="form-control" name="Id">
</div>
<div class="btn-group-vertical">
#{
if (Model.Admin == user)
{
<button type="submit" class="btn btn-primary">Start spil</button>
<div class="divider"></div>
<br />
}
}
</div>
</div>
</tr>
</table>
</form>
</div>
</body>
<script src='#Url.Content("~/lib/signalr.js")'></script>
<script src='#Url.Content("~/js/Lobby.js")'></script>
Lobbyhub.cs
using System;
using System.Threading.Tasks;
using Domain.Models;
using GUI_Index.Session;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
// https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api
namespace GUI_Index.Hubs
{
public class LobbyHub : Hub
{
//private HttpContext context = new DefaultHttpContext();
/// <summary>
/// Called by SignalR on connection to page
/// </summary>
/// <returns></returns>
public override async Task OnConnectedAsync()
{
await this.Clients.Caller.SendAsync("Connect");
}
/// <summary>
/// called by Lobby.js
/// </summary>
/// <param name="username">The username of the user in the lobby</param>
/// <param name="Lobbyname">The lobbyname of the lobby where user is</param>
/// <returns></returns>
public async Task OnConnectedUserAsync(string username, string Lobbyname)
{
//add user to group
await Groups.AddAsync(Context.ConnectionId, Lobbyname);
//send to others in the group
await this.Clients.OthersInGroup(Lobbyname).SendAsync("onConnectedUser", username);
//old
//await this.Clients.Others.SendAsync("OnConnectedUser", username);
}
/// <summary>
/// Called by Lobby.js
/// </summary>
/// <param name="user"> the user in the lobby that sends</param>
/// <param name="LobbyName"> the lobby that the user is in</param>
/// <param name="message"> the message the user wishes to send</param>
/// <returns></returns>
public async Task SendMessageAsync(string user,string LobbyName, string message)
{
await this.Clients.Group(LobbyName).SendAsync("ReceiveMessage", user, message);
//old
//await this.Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task UserLeftAsync(string username, string lobbyname)
{
await this.Groups.RemoveAsync(Context.ConnectionId, lobbyname);
await this.Clients.OthersInGroup(lobbyname).SendAsync("OnDisconnectedUser", username);
}
/*
public override async Task OnDisconnectedAsync(Exception exception)
{
await this.Clients.All.SendAsync("Disconnect");
}
public async Task OnDisconnectedUserAsync(string username)
{
await this.Clients.Others.SendAsync("OnDisconnectedUser", username);
}
*/
}
}
Lobby.js
const connection = new signalR.HubConnection("/Hubs/LobbyHub", { logger: signalR.LogLevel.Information });
/////////////////////////////////////Enter Lobby///////////////////////////////////////////
connection.on("Connect", () => {
//get the username
var Username = document.getElementById("LobbyUser").textContent;
//get the lobbyName
var Lobbyname = document.getElementById("LobbyId").textContent;
//send to hub
connection.invoke("OnConnectedUserAsync", Username, Lobbyname);
//}
});
connection.on("OnConnectedUser",
(user) => {
if (!document.getElementById(user)) {
var li = document.createElement("li");
li.textContent = "User: " + user + " Signed On!";
document.getElementById("Messages").appendChild(li);
//update table
const table = document.getElementById("UsersInLobby");
const newrow = table.insertRow(table.rows.length);
//set the id of the row
newrow.id = user;
const newcell = newrow.insertCell(0);
//add user to table
const newText = document.createTextNode(user);
newcell.appendChild(newText);
}
});
///////////////////////////////////////Messages///////////////////////////////////////////////
document.getElementById("sendButton").addEventListener("click", event => {
//get the username
const user = document.getElementById("LobbyUser").textContent;
//get the message
const message = document.getElementById("messageInput").value;
//get the lobbyname
const lobby = document.getElementById("LobbyId").textContent;
//send it to hub
connection.invoke("SendMessageAsync", user,lobby, message).catch(err => console.error);
event.preventDefault();
});
connection.on("ReceiveMessage", (user, message) => {
//write the complete message
const Message = user + " says " + message;
//create list element
const li = document.createElement("li");
//add to list element
li.textContent = Message;
//append to chat
document.getElementById("Messages").appendChild(li);
});
///////////////////////////leave Lobby////////////////////////////////////
//Setup click event
document.getElementById("ForLadLobby").addEventListener("click", event => {
//get the username
const user = document.getElementById("LobbyUser").textContent;
//get the lobbyname
const lobby = document.getElementById("LobbyId").textContent;
//send it to hub
connection.invoke("UserLeftAsync", user, lobby).catch(err => console.error);
event.preventDefault();
});
//user left
connection.on("OnDisconnectedUser",
(user) => {
//create element to hold information
const li = document.createElement("li");
//tell others that user left
li.textContent = "User: " + user + " Signed Off!";
//add to chat
document.getElementById("Messages").appendChild(li);
//update table of online users
var row = document.getElementById(user);
//get the table and delete the row!
row.parentNode.removeChild(row);
//old
//row.deleteCell(0);
});
connection.start().catch(err => console.error);
I hope you can help me!
Related
What I'm trying to do:
I made an alert function by spring which gives alert to user when the predetermined condition is fullfilled. This functions works well on Spring.
User can set several alerts on their own.
So when User presses "start alert" button in html, javascript sends get request using ajax depending on "idx" of alert on html.
Problem :
Seems like function is not working well on browser.
I did debug by using F12, I found out that Javascript is not getting any "idx" value..
So Nothing happens when I try to get alert.
All I wanna do is request by Alert id when button is pressed.
Here are my full code.
Controller
#GetMapping("/alerts/{id}")
#ResponseBody
public void AlertUser(#PathVariable Long id) {
alertService.AlertUser(id);
}
Service
public void AlertUser(Long id) {
Alert alert = alertRepository.findById(id).orElseThrow(() -> new NoSuchElementException());
double SetPrice = alert.getPrice();
String ticker = alert.getTicker();
JSONParser jsonParser = new JSONParser();
final NotificationRequest build = NotificationRequest.builder()
.title(ticker + " alert")
.message(SetPrice + "broke down")
.token(notificationService.getToken(userDetailService.returnUser().getEmail()))
.build();
try {
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint();
Session session = clientEndPoint.connect(new URI("wss://ws.coincap.io/prices?assets=" + ticker));
WebsocketClientEndpoint.MessageHandler handler = new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String message) throws ParseException, IOException {
Object obj = jsonParser.parse(message);
JSONObject jsonObject = (JSONObject) obj;
double price = Double.parseDouble(jsonObject.get(ticker).toString());
System.out.println("가격 : " + price);
if (price < SetPrice) {
System.out.println("끝");
notificationService.sendNotification(build);
session.close();
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.err.println("InterruptedException exception: " + ex.getMessage());
}
}
};
clientEndPoint.addMessageHandler(handler);
} catch (URISyntaxException ex) {
System.err.println("URISyntaxException exception: " + ex.getMessage());
}
}
**alert.mustache : {{#alerts}} ~ {{/alerts}} part is where problem occurs **
{{>layout/header}}
<form method="post" action="submitform" id="tickerSubmit">
<select name="contact" id="contact">
{{#tickers}}
<option value="{{.}}">{{.}}</option>
{{/tickers}}
</select>
<!-- <button type="submit" name="submit">Choose Ticker</button>-->
</form>
<div>
<input type="number" id = "price" placeholder="하한 금액을 입력하세요">
<input type="number" id = "percentage" placeholder="하한 퍼센트를 입력하세요">
<button type="button" class="btn btn-primary" id="alert-save-btn">알림 등록</button>
</div>
{{#alerts}}
<tr>
<div id = "idx">{{id}}</div>
<td><input type="submit" value="알림시작" id="alert-start"/></td>
<td>티커 : {{ticker}}</td>
<td>가격 : {{price}}</td>
</tr>
{{/alerts}}
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-messaging.js"></script>
<script src="/js/app/notification.js"></script>
{{>layout/footer}}
part of index.js encrypted in layout/footer
$('#alert-start').on('click', function() {
_this.alertStart();
});
},
alertStart : function() {
var idx = $('#idx').val();
$.ajax({
type: 'GET',
url: '/alerts/'+idx,
}).done(function() {
alert('알림이 시작됩니다.');
}).fail(function (error) {
alert(JSON.stringify('이거' + error));
});
},
Thanks in advance. any help or tip would be very helpful..
I have a project in ASP.NET Core 2.1 MVC SignalR. When I started the project I did not select Individual Account options in authorization. I want to send the message using the user's email address stored in a database instead of the connection Id but I can't achieve this. How can I fix this problem?
This is my hub class code:
public class SignalRChat:Hub
{
Context c = new Context();
public async Task setUserEmail(string email)
{
string id = Context.ConnectionId;
c.EmailConnectionIds.Where(a => a.connection_id == id).FirstOrDefault().email = email;
}
public async Task ClientSendMessage(string connectionId,string user, string message)
{
var deger= c.EmailConnectionIds.Where(a => a.connection_id ==
connectionId).FirstOrDefault();
await Clients.Client(deger.connection_id).SendAsync("ReceiveMessage",user, message);
}
public override async Task OnConnectedAsync()
{
EmailConnectionId val = new EmailConnectionId();
val.connection_id = Context.ConnectionId; ;
val.email = "";
c.EmailConnectionIds.Add(val);
c.SaveChanges();
await base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
var connection = c.EmailConnectionIds.Where(a => a.connection_id ==
Context.ConnectionId).FirstOrDefault();
if (connection != null)
{
c.EmailConnectionIds.Remove(connection);
}
return base.OnDisconnectedAsync(exception);
}
}
This is my code:
"use strict";
$(document).ready(() => {
var connection = new signalR.HubConnectionBuilder().withUrl("/chathub").build();
var email = $("#client").val();
connection.start().then(() => connection.invoke('setUserEmail ', email));
$("#msg-send").click(() => {
let message = $("#txtMessage").val();
$("#txtMessage").val(" ");
var user = $("#sender").val();
connection.invoke("ClientSendMessage", $("#client").val(), user, message)
.catch(error => console.log("Error." + error));
var div = document.createElement("div");
div.textContent = message;
document.getElementById("chat-cont").appendChild(div);
});
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = msg;
var div = document.createElement("div");
div.textContent = encodedMsg;
document.getElementById("chat-cont").appendChild(div);
});
});
HTML code:
<div class="container">
<div id="chat-cont" class="clearfix" style="max-height:450px;overflow:scroll;">
</div>
<div style="margin-top:470px;margin-left:40%;bottom:50px !important;" class="footer navbar-fixed-bottom">
<div class="row">
<h5>Connection ID : <span id="connectionId"></span></h5>
</div>
<div class="row">
<div class="col-md-7"><input type="text" id="sender" value="#ViewBag.message"></div>
</div>
<div class="row">
<div class="col-md-7"><input type="text" placeholder="ReceiverId" id="client"></div>
</div>
<div class="row">
<div class="col-md-7" style="position:relative;"> <input type="text" id="txtMessage" class="form-control" style="width:70%;"></div>
<div class="col-md-5" style="position:absolute;margin-left:40%;"> <button id="msg-send" class="btn btn-success">Send</button></div>
</div>
</div>
</div>
I would suggest that you create a list of current connections CurrentConnections
static HashSet<EmailConnectionID> CurrentConnections = new HashSet<EmailConnectionID>();
class EmailConnectionID
{
public string email { get; set; }
public string connection_id { get; set; }
}
add the entries to CurrentConnections OnConnectedAsync
public override async Task<Task> OnConnectedAsync()
{
EmailConnectionID val = new EmailConnectionID();
val.connection_id = Context.ConnectionId; ;
val.email = "";
CurrentConnections.Add(val);
return base.OnConnectedAsync();
}
then after the client connect first thing you do is to send the email to the hub and edit the entry on the CurrentConnections list with the email
public async Task setUserEmail(string email)
{
string id = Context.ConnectionId;
CurrentConnections.Where(a => a.connection_id == id).FirstOrDefault().email = email;
}
you shold remove enties from CurrentConnections list OnDisconnectedAsync
public override Task OnDisconnectedAsync(Exception exception)
{
var connection = CurrentConnections.Where(a => a.connection_id ==
Context.ConnectionId).FirstOrDefault();
if (connection != null)
{
CurrentConnections.Remove(connection);
}
return base.OnDisconnectedAsync(exception);
}
after that you can send based on email address
I am trying to get data from database when i click button.
I have one dropdownlist,one textbox and one button.
when i click button it should get input value from drop down list and return one value from database and put it into text box.
output window image
dropdown has account number.
this is my ajax code its inside of head tag
<script type="text/javascript">
$(document).ready(function()
{
alert("Entering");
$('#btnBalance').click(function(){
var accountNo = $('#DropDownListFromWhichAccount').val();
$.ajax({
url:'BalanceService.asmx/getBalance',
data:{acc:accountNo},
method:'post',
dataType: 'xml',
success:function(data)
{
console.log(data);
var jqueryXml=$(data);
$('#txtBalance').val(jqueryXml.find('balance').text())
//$('#txtBalance').val("ok")
alert(jqueryXml.find('balance').text());
},
error:function(err)
{
alert(err);
}
})
})
});
</script>
html code:
<div class="row content-padding-top">
<div class="col-lg-3">
<label for="DropDownListFromWhichAccount" class="content-label control-label">Debit (From)</label>
</div>
<div class="col-lg-3">
<asp:DropDownList ID="DropDownListFromWhichAccount" runat="server" class="form-control text-box-border" >
<asp:ListItem>Cash</asp:ListItem>
</asp:DropDownList>
</div>
<div class="col-lg-2">
<asp:TextBox ID="txtBalance" runat="server" class="form-control text-box-border" placeholder="Balance" ></asp:TextBox>
</div>
<div class="col-lg-1">
<asp:Button ID="btnBalance" type="button" runat="server" class="btn btn-default" Text="Check" />
</div>
</div>
asmx file:
namespace NibrassProject
{
/// <summary>
/// Summary description for BalanceService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class BalanceService : System.Web.Services.WebService
{
[WebMethod]
public BalanceChecking getBalance(string accountNo)
{
BalanceChecking bc = new BalanceChecking();
bc.balance=bc.checkBalance(accountNo);
bc.balance = "faisal";
return bc;
}
}
}
BalanceChecking.cs file
namespace NibrassProject
{
public class BalanceChecking
{
public string balance { get; set; }
string cs = ConfigurationManager.ConnectionStrings["Nibrass_DBConnectionString"].ConnectionString;
public string checkBalance(string acc)
{
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "SELECT Balance FROM Account_Balance_tb WHERE Account_Card_Number=" + acc + " ORDER BY Id DESC";
// cmd.Parameters.AddWithValue("#Account_Number",accountNo);
con.Open();
SqlDataReader rd = cmd.ExecuteReader();
while (rd.Read())
{
balance = rd["Balance"].ToString();
break;
}
rd.Close();
}
return balance;
}
}
Error message:
uncaught exception: out of memory
I used this code so far but i don't receive properly ordered messages output so can any one help me for proper output.
ChatHub Code :
public class ChatHub : Hub
{
static List<UserDetails> ConnectedUsers = new List<UserDetails>();
static List<MessageDetails> CurrentMessage = new List<MessageDetails>();
static List<TestProject1.Models.MessageDetails> CurrentMessage1 = new List<TestProject1.Models.MessageDetails>();
private TestContext db = new TestContext();
public void Connect(string userName)
{
var id = Context.ConnectionId;
var data = db.MessageDetails.ToList();
foreach (var item in data)
{
ConnectedUsers.Add(new UserDetails { ConnectionId = id, UserName = item.UserName });
CurrentMessage1.Add(new TestProject1.Models.MessageDetails { UserName = item.UserName, Message = item.Message });
}
Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage1);
Clients.AllExcept(id).onNewUserConnected(id, userName);
}
public void Send(string name, string message, string connection)
{
AddMessageinCache(name, message);
db.MessageDetails.Add(new TestProject1.Models.MessageDetails { UserName = name, Message = message });
db.SaveChanges();
Clients.All.addNewMessageToPage(name, message, connection);
}
private void AddMessageinCache(string userName, string message)
{
CurrentMessage.Add(new MessageDetails { UserName = userName, Message = message });
if (CurrentMessage.Count > 100)
CurrentMessage.RemoveAt(0);
}
}
I also include details of my html code here And Code of CSHTML:
<div id="page-content">
<div id='wrap'>
<div id="page-heading">
<ol class="breadcrumb">
<li>Dashboard</li>
<li>Chat Room</li>
</ol>
<h1>Chat Room</h1>
</div>
<div class="container">
<div class="col-md-12">
<div class="panel panel-inverse">
<div class="panel-heading">
<h4>Chat Room</h4>
<div class="options">
<i class="fa fa-cog"></i>
<i class="fa fa-refresh"></i>
</div>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-8">
<div class="panel-chat well" id="chat">
</div>
<form class="form-inline" action="#">
<div class="input-group">
<input type="text" placeholder="Enter your message here" id="message" class="form-control">
<span class="input-group-btn">
<button type="button" id="sendmessage" class="btn btn-primary"><i class="fa fa-comments-o"></i></button>
</span>
</div>
</form>
<input type="hidden" id="displayname" />
<input type="hidden" id="connection" />
</div>
</div>
</div>
</div>
</div>
</div>
</div> <!--wrap -->
</div> <!-- page-content -->
#section Scripts
{
#Scripts.Render("~/bundles/jquery")
<script>
jQuery(function () {
$.connection.hub.url = 'http://localhost:34063//signalr';
// Reference the auto-generated proxy for the hub.
var chat = $.connection.chatHub;
chat.client.onConnected = function (id, userName, allUsers, messages) {
for (i = 0; i < messages.length; i++) {
AddMessage(messages[i].UserName, messages[i].Message);
}
}
// Create a function that the hub can call back to display messages.
chat.client.addNewMessageToPage = function (name, message, connectionid) {
// Add the message to the page.
$('#chat').append('<div class="chat-message me"><div class="chat-contact"><img src="/Content/assets/demo/avatar/avatar.png" alt=""></div><div class="chat-text">' + htmlEncode(name)
+ ': ' + htmlEncode(message) + '</div></div>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val('#Session["User"].ToString()');
$('#connection').val(#Session["UserID"]);
var name = $('#displayname').val();
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
var i = 0;
$.connection.hub.start().done(function () {
if (name.length > 0) {
if (i == 1) {
chat.server.connect(name);
}
}
$('#sendmessage').click(function () {
chat.server.send($('#displayname').val(), $('#message').val(), $('#connection').val());
$('#message').val('').focus();
});
});
i = i + 1;
$.connection.hub.disconnected(function () {
alert('Disconnected');
});
});
// This optional function html-encodes messages for display in the page.
function AddMessage(userName, message) {
$('#chat').append('<div class="chat-message me"><div class="chat-contact"><img src="/Content/assets/demo/avatar/avatar.png" alt=""></div><div class="chat-text">' + userName + ': ' + message + '</div></div>');
}
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
}
output is showing all messages but not showing in a sorted order and repeating messages on loading of a page. I want to remove it too.
Why you don't add DateTime stamps to messages. In your MessageDetails class add a property:
public DateTime ReceivedOn{get;set;}
Modify code that runs on receiving message:
private void AddMessageinCache(string userName, string message)
{
CurrentMessage.Add(new MessageDetails { UserName = userName, Message = message, ReceivedOn=DateTime.Now });
if (CurrentMessage.Count > 100)
CurrentMessage.RemoveAt(0);
}
On client side, you will need to sort messages on ReceivedOn property:
chat.client.onConnected = function (id, userName, allUsers, messages) {
$.sort(messages,function(a,b){
return a.ReceivedOn > b.ReceivedOn;
});
for (i = 0; i < messages.length; i++) {
AddMessage(messages[i].UserName, messages[i].Message);
}
}
Consult this question on sorting in jQuery.
EDIT:- On a side note, if only already received messages are a problem, then why don't fetch those sorted from database itself?
in my web browser control i am accessing a form:
<form role="form">
<div class="form-group">
<input type="text" class="form-control" id="InputEmail1" placeholder="name...">
</div>
<div class="form-group">
<input type="email" class="form-control" id="InputPassword1" placeholder="email...">
</div>
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="message..."></textarea>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
How can i trigger this button automatically from vb.net application? how can i set text to the text area? am accessing the text box as follows:
WebBrowser1.Document.GetElementById("InputEmail1").SetAttribute("value", "Sample")
WebBrowser1.Document.GetElementById("InputPassword1").SetAttribute("value", "Sample")
i cannot access button and text area since it does not have an id or name? is their any possibility to do like this?
Your elements need to have IDs and if you doesn't have access to the html code you can enumerate elements like this but you must know which element is the right one:
foreach (HtmlElement element in WebBrowser1.Document.Forms[0].All)
{
if (element.TagName.ToLower() == "textarea".ToLower())
{
element.InnerText = "text";
}
}
for clicking a button try this:
element.InvokeMember("click");
In a lot of web automation, unless you can get the original devs to add ids, you have to navigate the DOM in order to find what you need.
Here is an example of doing that kind of filtering and web automation
var actionPanel = topPanel.insert_Above(40);
var ie = topPanel.add_IE_with_NavigationBar().silent(true);
var server = "http://127.0.0.1.:8080";
Action<string,string> login =
(username, password) => {
ie.open(server + "/jpetstore/shop/signonForm.do");
ie.field("username",username);
ie.field("password",password);
ie.buttons()[1].click();
};
Action loginPlaceAnOrderAndGoToCheckout =
()=>{
ie.open("http://127.0.0.1:8080/jpetstore");
ie.link("Enter the Store").click();
//login if needed
var signOffLink = ie.links().where((link)=> link.url().contains("signonForm.do")).first();
if(signOffLink.notNull())
{
signOffLink.click();
login("j2ee", "pwd1");
}
ie.links().where((link)=> link.url().contains("FISH"))[0].click();
ie.link("FI-FW-01 ").flash().click();
ie.links().where((link)=> link.url().contains("addItemToCart"))[0].flash().click();
ie.links().where((link)=> link.url().contains("checkout.do"))[0].flash().click();
ie.links().where((link)=> link.url().contains("newOrder.do"))[0].flash().click();
};
Action scrollToTotal =
()=>{
var tdElement = ie.elements().elements("TD").toList().Where((element)=> element.innerHtml().notNull() && element.innerHtml().contains("Total:")).first();
tdElement.scrollIntoView();
tdElement.injectHtml_beforeEnd("<h2><p align=right>Look at the Total value from the table above (it should be 18.50)</p><h2>");
};
Action<string> exploit_Variation_1 =
(payload) => {
loginPlaceAnOrderAndGoToCheckout();
ie.buttons()[1].flash().click();
ie.open(server + "/jpetstore/shop/newOrder.do?_finish=true&" + payload);
scrollToTotal();
};
Action<string> exploit_Variation_1_SetTotalPrice =
(totalPrice) => {
var payload = "&order.totalPrice={0}".format(totalPrice);
exploit_Variation_1(payload);
};
Another option (which I also use quite a lot) is to actually use Javascript to do those actions (which is much easier if jQuery is available (or injected) in the target page).
[Test] public void Issue_681__Navigating_libraries_views_folders__Clicking_the_icon_doesnt_work()
{
var tmWebServices = new TM_WebServices();
Func<string, string> clickOnNodeUsingJQuerySelector =
(jQuerySelector)=>
{
ie.invokeEval("TM.Gui.selectedGuidanceTitle=undefined");
ie.invokeEval("$('#{0}').click()".format(jQuerySelector));
ie.waitForJsVariable("TM.Gui.selectedGuidanceTitle");
return ie.getJsObject<string>("TM.Gui.selectedGuidanceTitle");
};
if (tmProxy.libraries().notEmpty())
{
"Ensuring the the only library that is there is the TM Documentation".info();
foreach(var library in tmProxy.libraries())
if(library.Caption != "TM Documentation")
{
"deleting library: {0}".debug(library.Caption);
tmProxy.library_Delete(library.Caption);
}
}
UserRole.Admin.assert();
tmProxy.library_Install_Lib_Docs();
tmProxy.cache_Reload__Data();
tmProxy.show_ContentToAnonymousUsers(true);
ieTeamMentor.page_Home();
//tmWebServices.script_Me_WaitForClose();;
//ieTeamMentor.script_IE_WaitForComplete();
ie.waitForJsVariable("TM.Gui.selectedGuidanceTitle");
var _jsTree = tmWebServices.JsTreeWithFolders();
var viewNodes = _jsTree.data[0].children; // hard coding to the first library
var view1_Id = viewNodes[0].attr.id;
var view5_Id = viewNodes[4].attr.id;
var click_View_1_Using_A = clickOnNodeUsingJQuerySelector(view1_Id + " a" );
var click_View_5_Using_A = clickOnNodeUsingJQuerySelector(view5_Id + " a" );
var click_View_1_Using_Icon = clickOnNodeUsingJQuerySelector(view1_Id + " ins" );
var click_View_5_Using_Icon = clickOnNodeUsingJQuerySelector(view5_Id + " ins" );
(click_View_1_Using_A != click_View_5_Using_A ).assert_True();
(click_View_5_Using_A == click_View_1_Using_Icon).assert_False(); // (Issue 681) this was true since the view was not updating
(click_View_5_Using_A == click_View_5_Using_Icon).assert_True();
}