How to use Robot.js in C# automation?


#1

I’m trying to understand how to use the robot.js file while writing my UI automation tests in C#. I don’t have any experience in using javascript, so I’m not sure if what I am doing is correct or if I’m way off. For example, I’m not sure if I am declaring my canvas correctly. I’ve searched through the forums and haven’t found anything related or useful.

All I would like to do is click a node on a canvas during a UI automated test as a proof of concept that it works, I’m using the robot.html page as a hypothetical scenario (on either canvas). Any help, suggestions, or ideas would be appreciated in understanding how to do this from a C# test would be appreciated.
https://gojs.net/latest/extensions/Robot.html

Here is my C# method that is calling the mouse click javascript:

    public void ClickCanvasItem(int x, int y)
    {
        // Set File Name for JS Action
        string fileName = "Mouse_Click.js";

        // Read file into a String
        string script = File.ReadAllText(fileName);

        // Create JavaScript Executor, and Execute the Script, passinging in X and Y Coordinates
        IJavaScriptExecutor js = (IJavaScriptExecutor)this.testObject.WebDriver;
        js.ExecuteScript(script, x, y); 
    }

And here is the javascript file that I’ve setup based upon the robot.js file:

diagram = $(go.Diagram, “myPaletteDiv”, // create a Diagram for the DIV HTML element
{
});

/**

  • Transfer property settings from a JavaScript Object to an InputEvent.
  • @param {InputEvent} e
  • @param {Object} props
    */
    function initializeEvent(e, props) {
    if (!props) return;
    for (var p in props) {
    if (p !== “sourceDiagram”) e[p] = props[p];
    }
    };

/**

  • Simulate a mouse down event.

  • @param {number} x the X-coordinate of the mouse point in document coordinates.

  • @param {number} y the Y-coordinate of the mouse point in document coordinates.

  • @param {number=} time the timestamp of the simulated event, in milliseconds; default zero

  • @param {object=} eventprops an optional argument providing properties for the InputEvent.
    */
    function MouseDown(x, y, time, eventprops) {
    if (typeof x !== “number” || typeof y !== “number”) throw new Error(“MouseDown first two args must be X,Y numbers”);
    if (time === undefined) time = 0;

    var diagram = this.diagram;
    if (eventprops && eventprops.sourceDiagram) diagram = eventprops.sourceDiagram;
    if (!diagram.isEnabled) return;

    var n = new go.InputEvent();
    n.diagram = diagram;
    n.documentPoint = new go.Point(x, y);
    n.viewPoint = diagram.transformDocToView(n.documentPoint);
    n.timestamp = time;
    n.down = true;
    this.initializeEvent(n, eventprops);
    diagram.lastInput = n;
    diagram.firstInput = n.copy();
    diagram.currentTool.doMouseDown();
    };

/**

  • Simulate a mouse up event.

  • @param {number} x the X-coordinate of the mouse point in document coordinates.

  • @param {number} y the Y-coordinate of the mouse point in document coordinates.

  • @param {number=} time the timestamp of the simulated event, in milliseconds; default zero

  • @param {object=} eventprops an optional argument providing properties for the InputEvent.
    */
    function MouseUp(x, y, time, eventprops) {
    if (typeof x !== “number” || typeof y !== “number”) throw new Error(“MouseUp first two args must be X,Y numbers”);
    if (time === undefined) time = 0;

    var diagram = this.diagram;
    if (eventprops && eventprops.sourceDiagram) diagram = eventprops.sourceDiagram;
    if (!diagram.isEnabled) return;

    var n = new go.InputEvent();
    n.diagram = diagram;
    n.documentPoint = new go.Point(x, y);
    n.viewPoint = diagram.transformDocToView(n.documentPoint);
    n.timestamp = time;
    n.up = true;
    if (diagram.firstInput.documentPoint.equals(n.documentPoint)) n.clickCount = 1; // at least??
    this.initializeEvent(n, eventprops);
    diagram.lastInput = n;
    if (diagram.simulatedMouseUp(null, n.sourceDiagram, n.documentPoint, n.targetDiagram)) return;
    diagram.currentTool.doMouseUp();
    };

// Call MouseDown, passing in X and Y coordinates
MouseDown(arguments[0], arguments[1], 0, {});

// Call MouseUp, passing in X and Y coordinates
MouseUp(arguments[0], arguments[1], 100, { });


#2
  1. It seems unlikely that you want to create a new Diagram in your Mouse_Click.js function. But that is the very first thing your code does.

Instead you should get a reference to the existing Diagram on the page:

var diagramDiv = document.getElementById("myPaletteDiv");
var diagram = go.Diagram.fromDiv(diagramDiv);
  1. A potential problem is that your code would be defining several functions repeatedly, assuming you will be executing multiple steps, and thus multiple scripts. Could you define and load initially all of your common code once before you start executing any tests?

#3

Thanks for your help, I was able to get it work, I had to clean up a couple other minor things. We may look at that later, these are very simple tests for now.

This is how the js file we are using looks now after the changes we made for anyone else that may run into a similar situation using Selenium C# automation in the future.

// Create Diagram
var diagramDiv = document.getElementById(“myDiagramDiv”);
var diagram = go.Diagram.fromDiv(diagramDiv);

/**

  • Transfer property settings from a JavaScript Object to an InputEvent.
  • @param {InputEvent} e
  • @param {Object} props
    */
    function initializeEvent(e, props) {
    if (!props) return;
    for (var p in props) {
    if (p !== “sourceDiagram”) e[p] = props[p];
    }
    };

/**

  • Simulate a mouse down event.

  • @param {number} x the X-coordinate of the mouse point in document coordinates.

  • @param {number} y the Y-coordinate of the mouse point in document coordinates.

  • @param {number=} time the timestamp of the simulated event, in milliseconds; default zero

  • @param {object=} eventprops an optional argument providing properties for the InputEvent.
    */
    function MouseDown(x, y, time, eventprops) {
    if (typeof x !== “number” || typeof y !== “number”) throw new Error(“MouseDown first two args must be X,Y numbers”);
    if (time === undefined) time = 0;

    if (!diagram.isEnabled) return;

    var n = new go.InputEvent();
    n.diagram = diagram;
    n.documentPoint = new go.Point(x, y);
    n.viewPoint = diagram.transformDocToView(n.documentPoint);
    n.timestamp = time;
    n.down = true;
    initializeEvent(n, eventprops);
    diagram.lastInput = n;
    diagram.firstInput = n.copy();
    diagram.currentTool.doMouseDown();
    };

/**

  • Simulate a mouse up event.

  • @param {number} x the X-coordinate of the mouse point in document coordinates.

  • @param {number} y the Y-coordinate of the mouse point in document coordinates.

  • @param {number=} time the timestamp of the simulated event, in milliseconds; default zero

  • @param {object=} eventprops an optional argument providing properties for the InputEvent.
    */
    function MouseUp(x, y, time, eventprops) {
    if (typeof x !== “number” || typeof y !== “number”) throw new Error(“MouseUp first two args must be X,Y numbers”);
    if (time === undefined) time = 0;

    if (!diagram.isEnabled) return;

    var n = new go.InputEvent();
    n.diagram = diagram;
    n.documentPoint = new go.Point(x, y);
    n.viewPoint = diagram.transformDocToView(n.documentPoint);
    n.timestamp = time;
    n.up = true;
    if (diagram.firstInput.documentPoint.equals(n.documentPoint)) n.clickCount = 1; // at least??
    initializeEvent(n, eventprops);
    diagram.lastInput = n;
    if (diagram.simulatedMouseUp(null, n.sourceDiagram, n.documentPoint, n.targetDiagram)) return;
    diagram.currentTool.doMouseUp();
    };

// Call MouseDown
MouseDown(arguments[0], arguments[1], 0, { });

// Call MouseUp
MouseUp(arguments[0], arguments[1], 100, { });