Domanda

I am using uitest.js (built-on Jasmine.js) to test our Kendo UI Mobile application. I am displaying an actionsheet and programmatically selecting on of the options. This works ok in the app but throws an error that fails the test.

I am using an action sheet like this:

<ul data-role="actionsheet" id="marketplace-price-actions" >
    <li class="km-actionsheet-title">Select Price</li>
    <li><a href="#" data-action="setPriceFilter('3')">$$$</a></li>
    <li><a href="#" data-action="setPriceFilter('2')">$$</a></li>
    <li><a href="#" data-action="setPriceFilter('1')">$</a></li>
</ul>

and In my spec I am selecting one of the options like this:

$("#marketplace-price-actions li a").eq(2).mousedown().mouseup();

and this works, yet throws the following error:

TypeError: "undefined is not a function"

I have created a jsfiddle that displays this at http://jsfiddle.net/zkent/DD6vj/2/. Be sure to open the console.

EDIT Based on the selected answer, the error was from passing values to the functions. I chose to create separate callbacks. See http://jsfiddle.net/zkent/DD6vj/4/.

È stato utile?

Soluzione

It looks like you're not supposed to pass parameters to your action. I'm not sure why it's implemented this way, but this is causing your error (which also happens if you simply click on it, so it's not related to Jasmine).

As far as I can see, you have three options:

  1. Use a separate callback for each item
  2. Modify the ActionSheet source code to supply the clicked element to your action
  3. Use a closure over the value you pass and return a handler

Option 3 seems to be the best solution if you only need to pass one value but want to avoid code repetition due to multiple handlers. Please note that I haven't tested the following solutions at all, so use at your own risk.

For option #2, something like this might work:

kendo.mobile.ui.ActionSheet.fn._click = (function (click) {
    return function (e) {
        if (e.isDefaultPrevented()) {
            return;
        }

        var action = $(e.currentTarget).data("action");

        if (action) {
            kendo.getter(action)(window)({
                target: this.target,
                context: this.context,
                element: e.currentTarget // pass in the element that was clicked on 
            });
        }

        e.preventDefault();
        this.close();
    }
})(kendo.mobile.ui.ActionSheet.fn._click);

That way you'd at least know which element was clicked on and you could add data attributes to pass data, if you wanted, e.g.:

<li><a href="#" data-value="2" data-action="alertme">$$</a></li>

which you could then read in your handler:

function alertme(e) {
    console.log(e);
    console.log($(e.element).attr("data-value"));
}

(demo)

For option #3, you would simply define your action as:

function alertme(val) {
    return function(e) {
        console.log(e);
        console.log(val);
    };
}

and your element would be as it was:

    <li><a href="#" data-action="alertme('2')">$$</a>

(demo)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top