Selenium Webdriver | DragAndDrop Feature | No Exception, but code is not working - java

I'm trying to drag and drop and logo to an container, not getting exception. I'm able to find elements and the same drag and drop code is working fine for another site with other elements. But don't know why this is not working here. Can any one assist.
// Searching elements
driver.get(https://www.w3schools.com/html/tryit.asp?ilename=tryhtml5_draganddrop");
driver.switchTo().frame(driver.findElement(By.name("iframeResult")));
driver.manage().timeouts().implicitlyWait(10000, TimeUnit.MILLISECONDS);
WebElement From = driver.findElement(By.id("drag1"));
WebElement To = driver.findElement(By.id("div1"));
//Drag and Drop Action
Actions builder = new Actions(driver);
Action DragnDrop = builder.clickAndHold(From).moveToElement(To).release(To).build();
DragnDrop.perform();

Based on my experience to achieve more stable drag and drop actions we switched from Actions implementation to a javascript one. Yes, it might look like a hack, but constant false negatives of test result made us measure the risk and use the js impl. (We didn't create the script from scratch, just applied multiple suggestions found in the internet)
You can use it for your case, add the code below instead of Actions you used.
driver.executeScript("function dnd(elemDrag, elemDrop) {\n" +
" var DELAY_INTERVAL_MS = 100;\n" +
" var MAX_TRIES = 10;\n" +
" var dragStartEvent;\n" +
" if (!elemDrag || !elemDrop) {\n" +
" return false;\n" +
" }\n" +
" function fireMouseEvent(type, elem, dataTransfer) {\n" +
" var evt = document.createEvent('MouseEvents');\n" +
" evt.initMouseEvent(type, true, true, window, 1, 1, 1, 0, 0, false, false, false, false, 0, elem);\n" +
" if (/^dr/i.test(type)) {\n" +
" evt.dataTransfer = dataTransfer || createNewDataTransfer();\n" +
" }\n" +
" elem.dispatchEvent(evt);\n" +
" return evt;\n" +
" }\n" +
" function createNewDataTransfer() {\n" +
" var data = {};\n" +
" return {\n" +
" clearData: function (key) {\n" +
" if (key === undefined) {\n" +
" data = {};\n" +
" } else {\n" +
" delete data[key];\n" +
" }\n" +
" },\n" +
" getData: function (key) {\n" +
" return data[key];\n" +
" },\n" +
" setData: function (key, value) {\n" +
" data[key] = value;\n" +
" },\n" +
" setDragImage: function () {\n" +
" },\n" +
" dropEffect: 'none',\n" +
" files: [],\n" +
" items: [],\n" +
" types: []\n" +
" }\n" +
" }\n" +
" fireMouseEvent('mousedown', elemDrag);\n" +
" dragStartEvent = fireMouseEvent('dragstart', elemDrag);\n" +
" function dragover() {\n" +
" fireMouseEvent('dragover', elemDrop, dragStartEvent.dataTransfer);\n" +
" }\n" +
" function drop() {\n" +
" fireMouseEvent('drop', elemDrop, dragStartEvent.dataTransfer);\n" +
" fireMouseEvent('mouseup', elemDrop);\n" +
" fireMouseEvent('dragend', elemDrag);\n" +
" }\n" +
" setTimeout(dragover, DELAY_INTERVAL_MS);\n" +
" setTimeout(drop, DELAY_INTERVAL_MS * 2);\n" +
" return true;\n" +
"}\n" +
" dnd(arguments[0], arguments[1])", From, To)
Source: https://github.com/WileyLabs/teasy/blob/master/src/main/java/com/wiley/utils/JsActions.java
p.s. There is a typo in the link from your question. (instead of "asp?ilename" it should be "asp?filename)

Related

How to validate array item types with networknt/json-schema-validator?

its probably a very simple thing that Im missing, but my json-schema-validator (networknt/json-schema-validator) doesnt validate the type of my items inside an array.
This Java-snippet should yield errors:
var schema = "{\n" +
" \"$schema\": \"http://json-schema.org/draft/2020-12/schema#\",\n" +
" \"type\": \"array\",\n" +
" \"items\": [\n" +
" {\n" +
" \"type\": \"integer\"\n" +
" }\n" +
" ]\n" +
"}";
var input = "[true,false,{},\"foo\"]";
var factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012);
var jSchema = factory.getSchema(schema);
var errors = jSchema.validate(new ObjectMapper().readTree(input));
System.out.println("Errors: '"+errors.stream().map(ValidationMessage::getMessage).collect(joining(", ")) +"'");
but 'errors is empty. Over on www.jsonschemavalidator.net this is invalid as expected.
What obvious am I overlooking here ?
Thanks!

avoid adding the same element if exist in the list instead just add the elements inside the existing list [duplicate]

This question already has an answer here:
Add item to arraylist if it does not already exist in list
(1 answer)
Closed last year.
This post was edited and submitted for review last year and failed to reopen the post:
Original close reason(s) were not resolved
Below is the sample code
String jsonString = "{\n" +
" \"models\":[\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"ALL\",\n" +
" \"type\":null,\n" +
" \"name\":\"ALL\",\n" +
" \"feature_types\":null\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"102e\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"SIT\",\n" +
" \"name\":\"MUSTANG\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"A\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"B\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"C\",\n" +
" \"desc\":\"BodyStyle\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"980p\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"SIT\",\n" +
" \"name\":\"Ranger\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"C\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"D\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" } \n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"kkpou\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"UAT\",\n" +
" \"name\":\"Transit Custom\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"F\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"G\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"H\",\n" +
" \"desc\":\"Payload\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
for(int i = 0; i<myData.size();i++)
{
String type = "SIT";
FeaturedItems item = resultList.stream().filter(featureItem -> type != null && type.equals(featureItem.getType())).findFirst().orElse(null);
if (type != null) {
item = FeaturedItems.builder().type(type).items(new ArrayList<>()).build();
resultList.add(item);//if the item already exists in the list don't add the new item, instead just add the elements in the exisiting item.
//tried the below commented code to add the item if it doesn't contain in the list -- start
/*boolean flagFound = false;
for (FeaturedItems featureItem : resultList) {
if (featureItem.getType().equalsIgnoreCase(type)) {
flagFound = true;
break;
}
}
if(!flagFound) resultList.add(item);*/
//tried the above commented code to add the item if it doesn't contain in the list -- End
for (int count = 0; count < features.size(); count++) {
String id = getFid(count);
MyDataBuild build = ....//logic to set values in the properties
item.getItems().add(build);
}
}
}
lookUpData.setFeatureGroups(resultList);
}
}
If the type value is already defined in the defined featureItems, then instead of creating the new object in the featureItems list, i need to add the unique items(desc,id) to the existing items element for the matching type. The code snippet mentioned above doesn't add the elements to the existing items if the type is matching in the featureItems list, instead it is creating the new element as shown in the output json sample.
Using a Map instead will make your live much easier. However your example is missing some data so it's a bit hard to understand what is actually happening in your code. So I can give you only a simple example for the usage.
Map<String, FeaturedItems> resultMap = new HashMap<>();
// Get the FeaturedItems for the given type. If none is present create a new one.
FeaturedItems items = resultMap.computeIfAbsent(type, k -> FeaturedItems.builder().type(k).items(new ArrayList<>()).build());
// Add your item to the list
Sale newItem // Obtain new item
items.getItems().add(newItem);

Parse list of list to a JSON object

I have the following data, which is a list of lists:
"segmentation": [[239.97,260.24,222.04,270.49,199.84,253.41,213.5,227.79,259.62,200.46,274.13,202.17,277.55,210.71,249.37,253.41,237.41,264.51,242.54,261.95,228.87,271.34]]
What I need to do is to parse the information to a JSON object without removing the second braces.
I tried it with Jackson, but this fails with any data types.
Do you have any idea how to handle this?
Parse to JsonNode will work. I think u try with invalid json. check:
String value = "{\n" +
" \"segmentation\": [\n" +
" [\n" +
" 239.97,\n" +
" 260.24,\n" +
" 222.04,\n" +
" 270.49,\n" +
" 199.84,\n" +
" 253.41,\n" +
" 213.5,\n" +
" 227.79,\n" +
" 259.62,\n" +
" 200.46,\n" +
" 274.13,\n" +
" 202.17,\n" +
" 277.55,\n" +
" 210.71,\n" +
" 249.37,\n" +
" 253.41,\n" +
" 237.41,\n" +
" 264.51,\n" +
" 242.54,\n" +
" 261.95,\n" +
" 228.87,\n" +
" 271.34\n" +
" ]\n" +
" ]\n" +
"}";
JsonNode jsonNode = new ObjectMapper().readTree(value);

How to drag & drop in specific position in selenium java?

I am trying to drag & drop 2 elements into my workspace but they are dropped over each other, how can i specify the position of dropping the elements?
I am using dragAndDrop() function
Actions act=new Actions(driver);
act.dragAndDrop(From, To).build().perform();
enter image description here
Using dragAndDrop() method you can perform drag and drop operations on only one location at a time. it is usually used to perform operations on web element which is capable of dropping. please find the reference http://demoqa.com/droppable/ for various types of dropable elements.
To implement drag and drop operation -
Example:
WebElement From=driver.findElement(By.xpath( <<source xpath>> ));
WebElement To=driver.findElement(By.xpath( <<destination xpath>> ));
Actions actions=new Actions(driver);
actions.dragAndDrop(From, To).build().perform();
to drag and drop another element, you need to perform above all steps again.
Hope this helps :)
Try Using below code :
public static void dragAndDropViaJQueryHelper(WebDriver driver, String dragSourceJQuerySelector, String dropTargetJQuerySelector) {
String jqueryScript = "(function( jquery ) {\r\n" +
" jquery.fn.simulateDragDrop = function(options) {\r\n" +
" return this.each(function() {\r\n" +
" new jquery.simulateDragDrop(this, options);\r\n" +
" });\r\n" +
" };\r\n" +
" jquery.simulateDragDrop = function(elem, options) {\r\n" +
" this.options = options;\r\n" +
" this.simulateEvent(elem, options);\r\n" +
" };\r\n" +
" jquery.extend(jquery.simulateDragDrop.prototype, {\r\n" +
" simulateEvent: function(elem, options) {\r\n" +
" /*Simulating drag start*/\r\n" +
" var type = 'dragstart';\r\n" +
" var event = this.createEvent(type);\r\n" +
" this.dispatchEvent(elem, type, event);\r\n" +
"\r\n" +
" /*Simulating drop*/\r\n" +
" type = 'drop';\r\n" +
" var dropEvent = this.createEvent(type, {});\r\n" +
" dropEvent.dataTransfer = event.dataTransfer;\r\n" +
" this.dispatchEvent(jquery(options.dropTarget)[0], type, dropEvent);\r\n" +
"\r\n" +
" /*Simulating drag end*/\r\n" +
" type = 'dragend';\r\n" +
" var dragEndEvent = this.createEvent(type, {});\r\n" +
" dragEndEvent.dataTransfer = event.dataTransfer;\r\n" +
" this.dispatchEvent(elem, type, dragEndEvent);\r\n" +
" },\r\n" +
" createEvent: function(type) {\r\n" +
" var event = document.createEvent(\"CustomEvent\");\r\n" +
" event.initCustomEvent(type, true, true, null);\r\n" +
" event.dataTransfer = {\r\n" +
" data: {\r\n" +
" },\r\n" +
" setData: function(type, val){\r\n" +
" this.data[type] = val;\r\n" +
" },\r\n" +
" getData: function(type){\r\n" +
" return this.data[type];\r\n" +
" }\r\n" +
" };\r\n" +
" return event;\r\n" +
" },\r\n" +
" dispatchEvent: function(elem, type, event) {\r\n" +
" if(elem.dispatchEvent) {\r\n" +
" elem.dispatchEvent(event);\r\n" +
" }else if( elem.fireEvent ) {\r\n" +
" elem.fireEvent(\"on\"+type, event);\r\n" +
" }\r\n" +
" }\r\n" +
" });\r\n" +
"})(jQuery);";
((JavascriptExecutor) driver).executeScript(jqueryScript);
String dragAndDropScript = "jQuery('" + dragSourceJQuerySelector + "').simulateDragDrop({ dropTarget: '" + dropTargetJQuerySelector + "'});";
((JavascriptExecutor) driver).executeScript(dragAndDropScript);
}
Just pass css or xpath selectors in parameters.
Hope that helps you.
If that does not help you I can help you out with some other solutions also.

Jsonpath to show children with dynamic names

I have this json data that I was to parse with jsonpath:
{
"kind": "tm:sys:hardware:hardwarestats",
"selfLink": "https://localhost/mgmt/tm/sys/hardware?ver\u003d11.5.4",
"entries": {
"https://localhost/mgmt/tm/sys/hardware/platform": {
"nestedStats": {
"entries": {
"https://localhost/mgmt/tm/sys/hardware/platform/0": {
"nestedStats": {
"entries": {
"baseMac": {
"description": "00:00ยง:00:00:00:00"
},
"biosRev": {
"description": "OBJ-0065-xx Build: 1.06.043.0 05/02/2014"
},
"marketingName": {
"description": "BIG-IP VPR-C2400"
},
"pvaVersion": {
"description": "20"
}
}
}
}
}
}
}
}
}
As you can see some parts consists of children named according to this:
https://[host]/path
I would like to be able to essentially ignore the host part by using a wildcard:
$.entries.https://*/mgmt/tm/sys/hardware/platform.nestedStats.entries.*.nestedStats.entries.marketingName.description
Note the wildcard replacing localhost (it differs depending on which host header is sent to the api endpoint).
I have no control over the server side. Any suggestion appreciated!
/Patrik
If you just want to get the values of those baseMac, biosRev descriptions without filtering path, this should be enough
public static void main(String[] args) {
String samplejson = "{\n" +
" \"kind\": \"tm:sys:hardware:hardwarestats\",\n" +
" \"selfLink\": \"https://localhost/mgmt/tm/sys/hardware?ver\\u003d11.5.4\",\n" +
" \"entries\": {\n" +
" \"https://localhost/mgmt/tm/sys/hardware/platform\": {\n" +
" \"nestedStats\": {\n" +
" \"entries\": {\n" +
" \"https://localhost/mgmt/tm/sys/hardware/platform/0\": {\n" +
" \"nestedStats\": {\n" +
" \"entries\": {\n" +
" \"baseMac\": {\n" +
" \"description\": \"00:00ยง:00:00:00:00\"\n" +
" },\n" +
" \"biosRev\": {\n" +
" \"description\": \"OBJ-0065-xx Build: 1.06.043.0 05/02/2014\"\n" +
" },\n" +
" \"marketingName\": {\n" +
" \"description\": \"BIG-IP VPR-C2400\"\n" +
" },\n" +
" \"pvaVersion\": {\n" +
" \"description\": \"20\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
Object baseMac = JsonPath.read(samplejson, "$.entries..nestedStats.entries.marketingName.description");
System.out.println(baseMac.toString());
}
But, if you want to read those descriptions w.r.t only certain paths, like you want to read only https://localhost/mgmt/tm/sys/hardware/platform/0 and NOT https://localhost/mgmt/tm/sys/hardware/platform/**1**, then solution should be something else.

Categories

Resources