Getting error when mouse hover an element - selenium-webdriver

Getting error when mouse hover an element with below code in selenium:
public void our_medicines(String locatorType, String value) {
try {
By locator;
locator = locatorValue(locatorType, value);
Actions action = new Actions(driver);
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
action.moveToElement(element).click().build().perform();
} catch (Exception e) {
System.err.format("no such element to mousehover" + e);
}
}
This is my locatorValue method:
public By locatorValue(String locatorTpye, String value) {
By by;
switch (locatorTpye) {
case "id":
by = By.id(value);
break;
case "name":
by = By.name(value);
break;
case "xpath":
by = By.xpath(value);
break;
case "css":
by = By.cssSelector(value);
break;
case "linkText":
by = By.linkText(value);
break;
case "partialLinkText":
by = By.partialLinkText(value);
break;
case "className":
by = By.className(value);
break;
default:
by = null;
break;
}
return by;
}

Okay so the problem I found with your locatorValue method was that it could not handle unspecified locators in this block
default: by = null;
break;
}
return by; }
I added something simple just to deal with that, but you can tune it however you want
default: throw new Exception("Locator type not defined");
}
return by; }
Make sure the locatorType parameter being passed to public void our_medicinesis a valid Locator type.

Related

SimpleJSON returns null

i have an error in c# of NullReferenceException: Object reference not set to an instance of an object
SimpleJSON.JSONNode.Parse (System.String aJSON) (at Assets/Scenes/scripts/SimpleJSON.cs:553)
I found this post in the link below but i didn't understand the solution
SimpleJSON returns null when handling a call from Postmen
Can any one explain it for me, please?
the error is :
NullReferenceException: Object reference not set to an instance of an object
SimpleJSON.JSONNode.Parse (System.String aJSON) (at Assets/Scenes/scripts/SimpleJSON.cs:553)
SimpleJSON.JSON.Parse (System.String aJSON) (at Assets/Scenes/scripts/SimpleJSON.cs:1363)
Control.Update () (at Assets/Control.cs:123)
knowing that i'm sending json data using websocket and i'm receiving it in the console unity. i use simpleJSON script to deserialize the data.
here where the error is provided in line JSONNode root = JSON.Parse(last_message); :
private void Update()
{
if (ws == null)
{
return;
}
List<GameObject> object_to_keep = new List<GameObject>();
JSONNode root = JSON.Parse(last_message);
JSONNode Face = root["streams"][0]["objects"][0];
{
int id = Face["mono"]["id"].AsInt;
JSONNode position = Face["mono"]["position"];
Vector3 pos = new Vector3(position["x"].AsFloat, position["y"].AsFloat, position["z"].AsFloat);
GameObject mono = GetMonoObject();
WintualFaceController win_controller = mono.GetComponent<WintualFaceController>();
win_controller.face_id = id;
if(mono)
{
mono.transform.localPosition = pos;
object_to_keep.Add(mono);
}
else
print("Mono not found");
}
}
The error in SImpleJSON script wan in line: while (i < aJSON.Length)
public static JSONNode Parse(string aJSON)
{
Stack<JSONNode> stack = new Stack<JSONNode>();
JSONNode ctx = null;
int i = 0;
StringBuilder Token = new StringBuilder();
string TokenName = "";
bool QuoteMode = false;
bool TokenIsQuoted = false;
while (i < aJSON.Length)
{
switch (aJSON[i])
{
case '{':
if (QuoteMode)
{
Token.Append(aJSON[i]);
break;
}
stack.Push(new JSONObject());
if (ctx != null)
{
ctx.Add(TokenName, stack.Peek());
}
TokenName = "";
Token.Length = 0;
ctx = stack.Peek();
break;
case '[':
if (QuoteMode)
{
Token.Append(aJSON[i]);
break;
}
stack.Push(new JSONArray());
if (ctx != null)
{
ctx.Add(TokenName, stack.Peek());
}
TokenName = "";
Token.Length = 0;
ctx = stack.Peek();
break;
case '}':
case ']':
if (QuoteMode)
{
Token.Append(aJSON[i]);
break;
}
if (stack.Count == 0)
throw new Exception("JSON Parse: Too many closing brackets");
stack.Pop();
if (Token.Length > 0 || TokenIsQuoted)
{
ParseElement(ctx, Token.ToString(), TokenName, TokenIsQuoted);
TokenIsQuoted = false;
}
TokenName = "";
Token.Length = 0;
if (stack.Count > 0)
ctx = stack.Peek();
break;
case ':':
if (QuoteMode)
{
Token.Append(aJSON[i]);
break;
}
TokenName = Token.ToString();
Token.Length = 0;
TokenIsQuoted = false;
break;
case '"':
QuoteMode ^= true;
TokenIsQuoted |= QuoteMode;
break;
case ',':
if (QuoteMode)
{
Token.Append(aJSON[i]);
break;
}
if (Token.Length > 0 || TokenIsQuoted)
{
ParseElement(ctx, Token.ToString(), TokenName, TokenIsQuoted);
TokenIsQuoted = false;
}
TokenName = "";
Token.Length = 0;
TokenIsQuoted = false;
break;
case '\r':
case '\n':
break;
case ' ':
case '\t':
if (QuoteMode)
Token.Append(aJSON[i]);
break;
case '\\':
++i;
if (QuoteMode)
{
char C = aJSON[i];
switch (C)
{
case 't':
Token.Append('\t');
break;
case 'r':
Token.Append('\r');
break;
case 'n':
Token.Append('\n');
break;
case 'b':
Token.Append('\b');
break;
case 'f':
Token.Append('\f');
break;
case 'u':
{
string s = aJSON.Substring(i + 1, 4);
Token.Append((char)int.Parse(
s,
System.Globalization.NumberStyles.AllowHexSpecifier));
i += 4;
break;
}
default:
Token.Append(C);
break;
}
}
break;
default:
Token.Append(aJSON[i]);
break;
}
++i;
}
this is my json:
{
"cmd": "data",
"frame_time": "2021-06-30T09:04:16.464836+00:00",
"start_time": "2021-06-30T07:51:33.452079+00:00",
"streams": [
{
"name": "usb-0001:012.0-3",
"objects": [
{
"name": "face",
"mono": {
"id": "190",
"position": {
"x": "-0.012259",
"y": "0.059731",
"z": "0.707695"
}
},
"multi": [
{
"id": "190",
"position": {
"x": "-0.012263",
"y": "0.059753",
"z": "0.707151"
}
}
]
}
]
}
]
}

How to make collision work with userData in Tiled? (LigGDX)

currently i'm trying to figure out how to make collision detection work with libgdx and tiled. I collect all bodies from tiled inside an Array
this is the code where i take the bodies from tiled and store them inside an array:
public static Array<Body> parseTiledObjectLayer(World world, MapObjects mapObjects, int layerValue) {
switch (layerValue) {
case 0:
Array<Body> groundBodies = new Array<Body>();
for (MapObject mapObject : mapObjects) {
Shape shape;
if (mapObject instanceof PolylineMapObject) {
shape = createPolyline((PolylineMapObject) mapObject);
} else if (mapObject instanceof RectangleMapObject) {
shape = createRectangle((RectangleMapObject) mapObject);
} else if (mapObject instanceof PolygonMapObject) {
shape = createPolygon((PolygonMapObject) mapObject);
} else {
continue;
}
Body body;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
body = world.createBody(bodyDef);
body.createFixture(shape, 0);
groundBodies.add(body);
shape.dispose();
}
return groundBodies;
case 1:
Array<Body> objectBodies = new Array<Body>();
for (MapObject mapObject : mapObjects) {
Shape shape;
if (mapObject instanceof PolylineMapObject) {
shape = createPolyline((PolylineMapObject) mapObject);
} else if (mapObject instanceof RectangleMapObject) {
shape = createRectangle((RectangleMapObject) mapObject);
} else if (mapObject instanceof PolygonMapObject) {
shape = createPolygon((PolygonMapObject) mapObject);
} else {
continue;
}
Body body;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
body.createFixture(shape, 0);
objectBodies.add(body);
shape.dispose();
}
return objectBodies;
default: //if default returns null we don't have to return null outside the switch loop and if we return something
//inside a switch statement we don't use the statement break;
return null;
}
}
Now in another class i return the static array to collect the information from it and in this other class i also implement ContactListener.
In this variable i retrieve the above static array:
private Array<Body> objectBodies = MapLoader.parseTiledObjectLayer(world, map.getLayers().get(1).getObjects(), 1);
objectBodies.get(1).setUserData("Object");
and here i also try to assign a UserData for collision.
Now here i actually try to check if there is collision:
#Override
public void beginContact(Contact contact) {
Fixture body1;
Fixture body2;
if(contact.getFixtureA().getUserData() == "Player"){
body1 = contact.getFixtureA();
body2 = contact.getFixtureB();
} else {
body1 = contact.getFixtureB();
body2 = contact.getFixtureA();
}
if(body1.getUserData() == "Player" && body2.getUserData() == "Object"){
System.out.println("collided");
}
}
Everything seems fine but for some reason when Player and Object collide nothing seems to be happening. I don't have this error when setting the userdata inside the static method. Any help appriciated.

Why the unpredictable results when using async await on key events

I do not understand why I am getting strange results on key events in a winForm app using async await on keydown in a form. Here is very simple demo of my issue.
The complete app:
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int counter = 0;
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
await HandleKeypress();
}
private async Task HandleKeypress()
{
switch (counter)
{
case 0:
label1.BackColor = Color.Red;
label2.BackColor = Color.White;
label3.BackColor = Color.White;
break;
case 1:
label1.BackColor = Color.White;
label2.BackColor = Color.Red;
label3.BackColor = Color.White;
break;
case 2:
label1.BackColor = Color.White;
label2.BackColor = Color.White;
label3.BackColor = Color.Red;
label3.Refresh();
await Task.Delay(5000);
break;
}
counter++;
if (counter == 3)
{
counter = 0;
}
}
}
}
The form KeyPreview is on and a KeyDown event on the form
fires the async method. A counter is incremented from 0 to 3 when it reaches 3 the counter is reset to 0.There are three labels depending on the counter value 0,1,2 the corresponding labels background is set to red and the the other two back to white. There is 5 second delay on when the counter == 2. If I keep pressing the enter key when the counter == 2 I would expect label 3 to go to red and the other two labels to reset to white. Then after 5 seconds I would expect label1 to revert to red and the sequence to continue. This is not what happens and the sequence becomes somewhat caotic. Why does this happen.You have to keep pressing a key.
If you can cancel the keypress with a bool (cancelAction) set before the delay then the desired action can be accomplished.
int counter = 0;
bool cancelAction = false;
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
await HandleKeypress();
}
private async Task HandleKeypress()
{
if (cancelAction)
{
return;
}
switch (counter)
{
case 0:
label1.BackColor = Color.Red;
label2.BackColor = Color.White;
label3.BackColor = Color.White;
break;
case 1:
label1.BackColor = Color.White;
label2.BackColor = Color.Red;
label3.BackColor = Color.White;
break;
case 2:
label1.BackColor = Color.White;
label2.BackColor = Color.White;
label3.BackColor = Color.Red;
label3.Refresh();
cancelAction = true;
await Task.Delay(5000);
cancelAction = false;
break;
}
counter++;
if (counter == 3)
{
counter = 0;
}
}

Async & await multiple tasks in a loop, how to return single Task

This example is with entity framework, but the question is more about how to await multiple async tasks within a loop. Say I have the following method on a custom DbContext class:
public async Task DiscardChangesAsync()
{
foreach (var entry in ChangeTracker.Entries().Where(x => x != null))
{
switch (entry.State)
{
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Modified:
entry.State = EntityState.Unchanged;
break;
case EntityState.Deleted:
await entry.ReloadAsync(); // <-- only async method
break;
}
}
}
The above compiles and runs, but I'm not sure how efficient it is. For example, if the context contains 10 deleted entity entries, the thread stops and waits at each ReloadAsync before it continues the loop, right? Is there any way to let the loop execution continue, and return a new Task that won't complete until all 10 of the ReloadAsync calls have completed?
To answer your question strictly:
public Task DiscardChangesAsync()
{
List<Task> tasks = new List<Task>();
foreach (var entry in ChangeTracker.Entries().Where(x => x != null))
{
switch (entry.State)
{
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Modified:
entry.State = EntityState.Unchanged;
break;
case EntityState.Deleted:
tasks.Add(entry.ReloadAsync());
break;
}
}
return Task.WhenAll(tasks);
}
May be more efficient, though, to let EF handle reloading all of them at once:
public Task DiscardChangesAsync()
{
List<DbEntityEntry> deleted = new List<DbEntityEntry>();
foreach (var entry in ChangeTracker.Entries().Where(x => x != null))
{
switch (entry.State)
{
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Modified:
entry.State = EntityState.Unchanged;
break;
case EntityState.Deleted:
deleted.Add(entry);
break;
}
}
return ctx.RefreshAsync(RefreshMode.StoreWins, deleted);
}

winforms - gridview cell timespan edit problem

I'm following this question for formatting timespan value in the gridview.
Format TimeSpan in DataGridView column
I'm diaplying only minutes value in grid as follows
DataGridViewColumn idleTimeColumn = myGridView.Columns["IdleTime"];
idleTimeColumn.DefaultCellStyle.FormatProvider = new TimeSpanFormatter();
idleTimeColumn.DefaultCellStyle.Format = "m";
This cell is editable, so when I enter 5 (that mean 5 min) in the cell, then it should take it minute, but it take it as day value (ie, 5.00:00:00).
I tried different values for format (mm,%m) but all these gives the same output.
You have to implement the feature to parse an input value.
TimeSpanFormatter can be used to convert a bound TimeSpan data to a formatted string for displaying. But it can't convert an input value to TimeSpan. You have to convert an input value in DataGridView.CellParsing event handler.
The following is the sample code to parse an input value.
DataGridView.CellParsing event handler
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
if (e.DesiredType == typeof(TimeSpan))
{
TimeSpanParser parser = new TimeSpanParser();
e.Value = parser.Parse(e.Value.ToString(), e.InheritedCellStyle.Format);
e.ParsingApplied = true;
}
}
TimeSpanParser class
public class TimeSpanParser
{
private Regex formatParser;
private List<TimeSpanPart> parts;
public TimeSpanParser()
{
this.formatParser = new Regex("d{1,2}|h{1,2}|m{1,2}|s{1,2}|f{1,7}", RegexOptions.Compiled);
this.parts = new List<TimeSpanPart>();
}
public TimeSpan Parse(string input, string format)
{
this.parts.Clear();
var pattern = this.formatParser.Replace(format, m => ReplaceFormat(m));
var match = Regex.Match(input, "^" + pattern + "$");
TimeSpan result = new TimeSpan();
for (int i = 1; i < match.Groups.Count; i++)
{
var value = Convert.ToDouble(match.Groups[i].Value);
switch (this.parts[i - 1])
{
case TimeSpanPart.Day:
result = result.Add(TimeSpan.FromDays(value));
break;
case TimeSpanPart.Hour:
result = result.Add(TimeSpan.FromHours(value));
break;
case TimeSpanPart.Minute:
result = result.Add(TimeSpan.FromMinutes(value));
break;
case TimeSpanPart.Second:
result = result.Add(TimeSpan.FromSeconds(value));
break;
case TimeSpanPart.Millisecond:
int digit = match.Groups[i].Value.Length;
value =value * Math.Pow(10, 3 - digit);
result = result.Add(TimeSpan.FromMilliseconds(value));
break;
}
}
return result;
}
private string ReplaceFormat(Match match)
{
switch (match.Value)
{
case "dd":
case "d":
this.parts.Add(TimeSpanPart.Day);
return "(\\d{1,2})";
case "hh":
case "h":
this.parts.Add(TimeSpanPart.Hour);
return "(\\d{1,2})";
case "mm":
case "m":
this.parts.Add(TimeSpanPart.Minute);
return "(\\d{1,2})";
case "ss":
case "s":
this.parts.Add(TimeSpanPart.Second);
return "(\\d{1,2})";
case "fffffff":
case "ffffff":
case "fffff":
case "ffff":
case "fff":
case "ff":
case "f":
this.parts.Add(TimeSpanPart.Millisecond);
return "(\\d{1,7})";
default:
return match.Value;
}
}
}
TimeSpanPart enum
public enum TimeSpanPart
{
Day,
Hour,
Minute,
Second,
Millisecond,
}
I believe you are handling the cell formatting event properly
Youe were referring this i guess
Try mm or %m instead of m; idleTimeColumn.DefaultCellStyle.Format = "mm";

Resources