Locating canvas objects with Selenium - selenium

I'm using Selenium to develop automated tests for a web application. I have to simulate clicks on certain objects that reside inside a canvas element. In particular, I'm using vis.js to visualize nodes/edges and I need to test the effect of clicking on particular nodes/edges that are visible on the canvas.
The problem is that the positions of the nodes/edges aren't determined in advance. Therefore, I'm not sure how I'm supposed to locate them. If I were able to find the coordinates of a canvas object's position, it would've been possible for me to simulate clicking on the object using Selenium's moveByOffset:
x, y = find_node_coordinates_on_canvas(node_id) # how to do this?
canvas = self.driver.find_element_by_id("vis_canvas")
action = ActionChains(self.driver).move_by_offset(x, y).click(canvas).release()
The problem is that I don't know how to implement find_node_coordinates_on_canvas. That is, given the identifier of an object on the canvas, how do I find the coordinates of its position?

Related

pixiJS ignore mouse event

I have a UI layer and a Game layer.
that the UI layer falls transparently on the Game layer.
And when I click on the sprites inside the Game layer.
I do not receive events.
I want the events to reach the bottom layer as well.
I tried the codes but it didn't work.
ui.on('pointerdown',e=>{
e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
})
Pretty sure it's a limitation of Pixijs to avoid firing multiple events when there is overlap of containers with interactive property set to true. It will only fire the event on the container that is in foreground (the last one added to the stage).
You can probably work around it by either creating PIXI.Graphics for your UI elements with alpha set to 0 and interactive set to true, or create an entire Interactive elements layer and checking for overlap between elements.
Edit:
I still don't understand what you are trying to accomplish, and you potentially could have to rethink your project.
The other way you could accomplish this is by ignoring the interactive attribute, adding a click event on the entire document, and checking with your containers which one has implemented a IClickable interface you made up, then checking if the pointer position overlaps with the interactive area you calculate manually for each container. you can then fire an event for all sprites under your pointer, even if they are on top of each other.

Dynamic/scrollable container size in Cytoscape (+ cy.fit() issues)

So I've been giving Cytoscape a try recently. My project's goal is basically a collaborative graph that people will be able to add/remove nodes to/from, making it grow in the process. The graph will include many compound nodes.
Most of the examples I've seen use container div that takes 100% of the screen space. This is fine for "controlled" graphs but won't work in my case because its size is intended to be dynamic.
Here's a JSFiddle using the circle layout within a fixed 3000px/3000px container:
https://jsfiddle.net/Jeto143/zj8ed82a/5/
Is there any way to have the container size be dynamic as opposed to stating it explicitly? Or do I have to compute the new optimal container size each time somehow, and then call cy.resize()?
edit: actually, using 100%/100% into cy.fit() might just work no matter how large the network is gonna be, so please ignore this question is this is the case.
Is there a recommended layout for displaying large/unknown amounts of data in a non-hierarchical way that would "smartly" place nodes (including compound ones) in the most efficient way possible, all the while avoiding any overlap? (I guess that's a lot to ask...)
Why doesn't cy.fit() seem to be working in my example? I'm using it both at graph initialization and when CTRL+clicking nodes (to show closed neighborhood), but it doesn't seem to like the 3000x3000px container (seems better with 100%x100%).
edit: also ignore this question if you ignored 1., as again it seems fine with 100%/100%.
Any help/suggestions would be greatly appreciated.
Thank you very much in advance.
TLDR: It's (1).
Cytoscape has a pannable viewport, like a map. You can define the dimensions of the viewport (div) in CSS. What's displayed in the viewport is a function of the positions of the nodes, the zoom level, and the pan level -- just like what is visible in a map's viewport is a function of zoom, pan, and positions of points of interest.
So either you have to
(a) rethink your UI in terms of zoom and pan and use those in-built facilities in Cytoscape, or
(b) disable zoom and pan in Cytoscape (probably stay at (0, 0) at zoom 1) and let the user scroll the page as you add content to the graph and resize its container div to accommodate the new content.

Is there any way to draw a line diagram using array of x, y co-ordinates in appcelerator?

If I select one of these co-ordinates, I want to highlight that point on the diagram (by a circle or whatever shape possible). Also I would like to save it later on.
I'm not sure if Appcelerator is flexible enough to do all these things (My search didn't yield much apart from here, this only supports Android), If not I'll have to generate this diagram in my webservice and pull it back on UI once there is an update in the co-ordinate array.
I've used Chartist inside a webview and it worked great. It produces a SVG graph instead of a canvas object which performs better.
If you want to use hyperloop you can use Ti.AndroidCharts

Design pattern for child calling method in parent

I am currently working on my biggest project and I am having trouble figuring out how to structure my code. I'm looking for some guidance.
I have 2 objects a Tile and Container. Each Tile has a 2D coordinate and are all children of the Container. The Container has methods that return tile for location, switch tiles, add tiles, and remove tiles.
Now when you click on a tile it disappears, that was easy because it was self contained. The problem comes when I created different types of tiles that inherit from the base Tile. Each different type of tile does a different action when you click on it. Some destroy surrounding tiles some switch with other tiles and others add new tiles. For simplicity we will call these 3 subclasses Tile-destroy, Tile-swap, and Tile-add.
My problem is when I click on these tiles how can they act on other tiles in the Container. Should I just call functions in the parent class or is there a better way to do this? I am having trouble #including the Tile in the Container as well as the other way around. I feel like its not a proper pattern.
I have it set up so when a click takes place the Container handles it and checks the type of tile that is clicked and acts from there with a large else-if statement however this makes it very difficult to add new tile types. Ideally all the information for what happens when you click on a tile is contained within each tile subclass.
Any ideas?
I can suggest you the simpliest design:
Your Container will be a game controller
Each tile has Parent property which is refer to Container
When you click on tile it sends Command to Container (for example, DestroyTile(x, y) or AddTile(x, y)
Container handle this commands and destroys, adds or swap tiles.
If you want really good and more decoupled design you can also create handlers for all operation types DestroyTileHandler, AddTileHandler. In Container on different commands you will just pass them [commands] to appropriate handler. Also you need to pass context object (like Field with tiles) to handler. This allows you to add and modify new operations without even changing Container code.
See related patterns: Command, Observer
Feel free to ask questions and good luck!

Gray out entire map except a portion in Google maps iOS

I am using Google maps in iOS using iOS SDK, letting users mark an area using few markers, creating a polygon.
I want to highlight that area and gray out the rest of the map, something like this:
Is this possible somehow?
You have to draw your own UIImage where you create the gray area, clear area, and polygon borders. After that add it as an overlay tile using GMSGroundOverlay. This will fix it in place for when the user scrolls.
https://developers.google.com/maps/documentation/ios/overlays
This is similar to how radar overlays are drawn for weather apps.
I would approach this problem using several steps.
1) collect your points from the user that will define your polygon.
2) send the collection of points to your server.(ajax post)
3) server side, dynamically create a grey image with a transparent hole in it that is your polygon.
4) store image on server, send back response with info telling browser how to retrieve it(url,id,whatever).
5) using javascript + google maps api, apply an overlay referencing your newly created image.
each step may have its challenges but the problem becomes manageable if you focus on the different steps.
1) and 2) will involve using javascript, capturing 'clicks' and having feedback to the user in the form of a line or something on the map. Once finished, the server call can be initiated by the user or by your programming.
3) I would use python with an image library(skimage, etc.) and a mapping library (gdal). Making an image is not hard but combining it with GIS and getting the right projection, etc. will take some fiddling.
4) shouldn't be a problem once you've got that far.
5) using zimmryan's comment about creating a ground overlay could be helpful for this step.
good luck!