Automation testing using Selenium-WebDriver

2
I am trying to automate test cases using Selenium-WebDriver. Problem I am facing is with dynamic IDs for the UI controls. Every time, I launch the web page (in Firefox) the ID values are dynamically changing for all UI controls. For example: One of the button ID is 'mxui_widget_Button_10' when the page loaded first time. When the same page re-loaded, the ID changed to 'mxui_widget_Button_40'. Same thing is happening with css-selector and xpath values as well. B'coz of this, the Selenium-WebDriver script is unable to locate the button/UI controls and failing to execute. Do the Mendix developers have to set any property while designing pages, so that, IDs remain constant. OR is there any other way to write Selenium scripts to identify UI controls without depending on
asked
6 answers
5

The mx-name classes were explicitly introduced for Selenium. See also https://world.mendix.com/display/Tutorials/Selenium+support

Update: the class names are of the following form: mx-name-WIDGETNAME. The widget name can be edited in the Modeler. It should be stable for many operations. However, if you copy and paste a text box with name "textBox1", the new text box will be called "textBox2", because names have to be different.

If you find situations where the widget name (and thus the generated class) changes where you do not expect it, you may report this as a bug.

Update 2: we found a bug where the name of a widget changes when pasting a widget with the same name. This bug will be fixed in 5.19.0. I think this is the problem people were having with names (and thus Selenium classes) changing unexpectedly.

answered
2

Another option is to query the dijit widget library for the widget that you want to automate. This gives you access to additional properties like the microflow name behind a button for example.

dijit.registry.byClass("mxui.widget.MicroflowButton").filter(function(w){ 
     return w.microflow.name === "MyFirstModule.MyMicroflow";
}).toArray();

But this comes with additional challenges, because the registry can also return widgets that are no longer active (i.e. not displayed on the current page). It depends on the situation which is approach is best. Sometimes it's a combination.

At Mansystems we have created our own TestFramework to test Mendix applications. It comes with a full package of ootb functions to deal with Mendix widgets. Check the Mansystems website for more information.

answered
1

I have experience with Selenium, and I found two ways to deal with this:

  • Target by generated class (e.g. mx-name-textBox6)
  • Put a custom class on everything and target using that (a class Save on your Save button)
answered
1

Mendix developers cant set ids, they can only set class names. You should come up with a naming scheme and ask them to enforce it. The naming scheme should be such that each component gets a unique name, because snippets may be employed, which might lead to repitition of component identifiers, making it useless for automation.

This approach might be difficult with stuff like lists, because they guys will only be able to give a unique name for the outer div of the list, then the inner stuff will have the same class name, and you will have to use that unstable position=... thing

Did you know you can also call microflows from Selenium IDE? For example, if there is a logout microflow, you, can try (JS needs to be on one line though):

<tr>
<td>runScript</td>
<td>
mx.ui.action(
   "b.ivk_logout",
   {
        context:new mendix.lib.MxContext(),
        progress:"modal",
        callback:function(result){
            console.log("Engine started:"+result);
       }
   }
);
</td>
    <td></td>
</tr>

Ask the devs for some usefull microflows, read more here

answered
0

We use custom class names to solve this issue, by just adding it to the element in the modeler. This is definitely an effective solution.

answered
0

When dealing with dynamic IDs in Selenium-WebDriver, there are several strategies you can use to reliably identify UI controls:

  1. Use Stable Attributes: Instead of relying on dynamic IDs, use other stable attributes like name, class, tag name, or data-* attributes.

     
    java

    Copy code

    driver.findElement(By.className("button-class"));

  2. XPath and CSS Selectors: Use more robust XPath or CSS selectors that rely on stable parent-child relationships or attributes.

     
    java

    Copy code

    driver.findElement(By.xpath("//button[contains(@class, 'button-class')]"));

  3. Text Content: Locate elements by their text content if it's consistent.

     
    java

    Copy code

    driver.findElement(By.xpath("//button[text()='Submit']"));

  4. Custom Attributes: If possible, ask developers to add unique custom attributes to elements (like data-test-id) which do not change.

     
    java

    Copy code

    driver.findElement(By.cssSelector("[data-test-id='submit-button']"));

Using these methods, you can create more reliable Selenium scripts that are not dependent on dynamic IDs.

answered