Accessing an iframe from the simulator

269 views Asked by At

We would like to test our application with qooxdoo simulator tests. Our application uses an iframe qx.ui.embed.Iframe located in a window qx.ui.window.Window for the login procedure to allow browsers to store username and password locally. The content of the iframe is a simple form with username and password field.

...
<form id="loginform" name="loginform" method="post" action="">
<label><span>E-Mail / Benutzername</span>
<input type="text" value="" name="username"></label>
<label><span>Passwort</span><input type="password" value="" name="password"></label>
<input type="submit" value="Anmelden" id="submitbutton" name="submit"></form>
...

With the simulator its possible to locate the iframe inside the window with qxhv locator.

this.getSimulation().waitForWidget("qxhv=[@classname=app.window.system.Login]");

The problem now is that i have to "qxTypeKeys" into the username and password field to authenticate the test user. But the content of the iframe is outside the simulator scope.

Is there any suggestion how i can access the fields? Or is there an alternative way, like sending an post request before proceeding?

qx.Class.define("app.simulation.LoginTest", {

    extend: simulator.unit.TestCase,

    construct : function () {
        this.base(arguments);
    },

    members: {
        testLogin: function () {

            this.getSimulation().waitForWidget("qxhv=[@classname=app.window.system.Login]");
            this.getQxSelenium().qxType(???, "[email protected]");

        }
    }
});
2

There are 2 answers

0
Benno Eggnauer On BEST ANSWER

Based on the answer from Daniel Wagner, I have created the following abstract base class for our simulator tests. The method access the iframe, fill out the form, and submits the from to the server and wait for the success response.

qx.Class.define("app.simulation.AbstractSimulation", {
    extend: simulator.unit.TestCase,
    type: "abstract",

    construct : function () {

        this.base(arguments);

        this.baseLocators = {
            loginWindow : "qxhv=*/[@classname=app.window.system.Login]",
            startPage : "qxhv=*/[@classname=app.lib.ui.widget.StartPage]"
        };

    },

    members: {

        __loginDone : false,

        /*
         ---------------------------------------------------------------------------
         TESTS
         ---------------------------------------------------------------------------
         */

        _loginToApp : function(user, password)
        {

            if (this.__loginDone) {
                return;
            }

            var loginToApp = 'function(user, password) {'
                +   'var iframe = selenium.qxStoredVars["autWindow"].document.getElementsByTagName("iframe")[0];'
                +   'iframe.onload = function () { '
                +   '    var innerDoc = iframe.contentDocument || iframe.contentWindow.document;'
                +   '    innerDoc.getElementsByName("username")[0].value = user;'
                +   '    innerDoc.getElementsByName("password")[0].value = password;'
                +   '    innerDoc.getElementById("submitbutton").click();'
                +   ' };'
                + '};';

            this.getSimulation().waitForWidget(this.baseLocators.loginWindow);

            this.getSimulation()._addOwnFunction("loginToApp", loginToApp);
            var functionCall = 'selenium.qxStoredVars["autWindow"].qx.Simulation.loginToApp(\"' + user + '\", \"' + password + '\")';
            this.getQxSelenium().getEval(functionCall);

            this.getSimulation().waitForWidget(this.baseLocators.startPage, 30000);

            this.__loginDone = true;
        },

        /**
         * Login with Root User
         */
        loginToAppWithRoot : function ()
        {
            this._loginToApp("root", "root");
        }

    }

});
0
Daniel Wagner On

For a plain HTML form, I'd use a simple XPath locator:

//form[@id='loginform']/*/input[@name='username']

That way you don't have to worry about the surrounding qooxdoo widgets.

Also, you only need to use qx* methods to interact with widgets, for plain HTML elements you can use the standard Selenium methods (although the qx* methods will still work):

this.getQxSelenium().type("//form[@id='loginform']/*/input[@name='username']", "[email protected]");