0

I've got an angular app which has a table defined in the controllers like so:

$scope.rowHeaders = ["Revenues","Costs","Profit"];
$scope.data = [[100,230,300,400,500,600,700,800,900,1000,1100,1200], [30,40,50,60,70,80,90,100,110,120,130,140], [70,160,250,340,430,540,630,720,810,900,990,1100]];

The rowHeaders apply to each row in the data object. This is connected to the template as follows:

    <tbody>
      <tr ng-repeat="row in rowHeaders track by $index">
        <td>{{row}}</td>
        <td ng-repeat="cellData in data[$index] track by $index">
          <input id="data{{$parent.$index}}_{{$index}}" type="text" class="clsinputboxes" ng-model="data[$parent.$index][$index]" name="data{{$parent.$index}}_{{$index}}" ng-blur="updateColor($parent.$index, $index, data[$parent.$index][$index])" style="background-color: {{color[$parent.$index][$index]}}">
        </td>
      </tr>
     </tbody>

This produces a simple table with input boxes. When the input in a box changes, the background color of the box will also change with code that is inside updateColor(), specified in the controller.

All of this works fine. I want to be able to write a dead-simple end-to-end test, that will change the contents of one of the boxes in the table, and then check that the updateColor() function was triggered properly (perhaps by checking that the background color has indeed changed). This is proving to be incredibly hard to do.

I had thought something as simple as the following should have worked:

input("data[1][1]").enter(20);

But this actually does not work, and I get the following error:

http://localhost:8000/test/e2e/scenarios.js:17:4
Selector [ng\:model="data[1][1]"] did not match any elements.

Whereas, the code works fine when not in test mode, and the model is bound properly in the input tag using ng-model="data[$parent.$index][$index]".

For and end-to-end test, how do I go about entering some data into any box in the table that is linked up to an array model?

I also tried the following (although I'd much rather work with input().enter()):

element("#data1_1").query(function(el, done) {
      el.click();
      el.val(20);
      done();
  });

This changes the box contents but does not trigger updateColor(). I also tried putting e1.blur() - that does not work either.

Somik Raha
  • 171
  • 1
  • 10
  • Try changing the values in the data array directly? From my experience angular and jQuery don't really play all that well together, so you could use something like $watch or $apply or change the variables explicitly. You could maybe even make a custom directive that listens to changes and transfers them to the angular model. Also: `var input = $('input'); input.val('xxx'); input.trigger('input');` – Lauri Elias Dec 05 '13 at 23:43
  • Changing the values directly defeats the purpose of the end-to-end test, although I suppose it tests the binding. How would I get the scope in the end-to-end test? Currently I'm doing: `browser().navigateTo('app/index.html');` I also tried the code snippet you suggested and that does not work (does not even change the contents of the input box). – Somik Raha Dec 06 '13 at 00:08
  • I don't really know your use case, but I have made use of something like: `$scope.get_editor_scope = function () { var forms = jQuery('form'); var form = forms[forms.length - 1]; return angular.element(form).scope(); };` Using getters and setters for scopes has also helped somewhat when I have trouble with pointers. For example `$scope.item = {};` in the subscope versus using the function `$scope.set_item = function (object) { $scope.item = object; };` of a parent scope. – Lauri Elias Dec 06 '13 at 11:26

1 Answers1

0

I was able to finally get this to work in the elegant end-to-end scenario runner of Angular.

First, I gave an id to the table tag - "inputTable".

Then, the following in the scenario runner did the trick: using("table#inputTable tbody tr:eq(1) td:eq(2)").input("data[$parent.$index][$index]").enter(20);

A shoutout to Ari Lerner who helped me figure this out.

Community
  • 1
  • 1
Somik Raha
  • 171
  • 1
  • 10