Row and column method missing on element.all - protractor

I have the following setup, where I want Protractor to click on a row (or the checkbox in a row, either is fine):
<li data-ng-repeat="room in chatRooms | ***filters***">
<div ng-click="toggleJoin(room.id)">
<input type="checkbox" value="{{room.id}}" ng-checked="isChecked(room.id)" />
<span>{{room.name}}</span>
</div>
</li>
And I want to do this with my Page Object:
var PageObject = function() {
this.lstChatRooms = element.all(by.repeater('room in chatRooms'));
this.clickChatRoom = function(index) {
this.lstChatRooms.row(index).column('{{room.id}}').click();
};
};
But when I try to call clickChatRoom with some index in my test, I get an error saying the object has no method 'row', and I've seen the same behavior with 'column'. I'm not calling anything on the list of chat rooms prior to this in my test, so the promise should not be resolved at that point. What am I doing wrong?
Update: The issue may be caused by this bug. Unless anyone can see that I'm doing something wrong with the API or something else.

i can't test it right now, but this should work for you:
this.lstChatRooms.then(function(rooms) {
rooms[index].findElement(by.tagName('input')).click();
});

Related

How to fix the red mark that appears when using binding.scala in intellij?

I am developing with scalajs and binding.scala. I'm using the IDE as an Intellij. However, when using dom macro in Intellij, the following red mark appears. this error appears when I use the attribute value of id in the input element as macro What is the solution?
This error(a.k.a. "cannot resolve symbol something") appears when you use the id attribute value of the input element as marco.
please see the link of image below.
this is my code image.
#dom
def render: xml.Elem = {
val name: _root_.com.thoughtworks.binding.Binding.Var[_root_.java.lang.String] = Var.apply("Binding.scala")
val show: _root_.com.thoughtworks.binding.Binding.Var[Boolean] = Var.apply(false)
<div>
<p>
<label for="showCheckbox">
<input type="checkbox" id="showCheckbox" onchange={e: Event => show.value = showCheckbox.value }/>
<span> Say hello to <input id="nameInput" value={name.value} oninput={_: Event => name.value = nameInput.value}/></span>
</label>
</p>
{
if (show.bind) {
<p>
Hello, {name.bind}!
</p>
} else {
<!-- Don't show hello. -->
}
}
</div>
}
I actually have the same problem. I have 2 ways dealing with it:
Ignore these exception - as they are only a problem within IntellIJ
(it compiles just fine).
Use for example JQuery like this:
import org.scalajs.jquery.jQuery
..
jQuery("#showCheckbox").value()
As soon as your id gets more dynamic - you will need something like that anyway (at least that is what I know;)) -> jQuery(s"#${elem.id}").value().
You could take advantage of the scalaJS Event passed in, maybe something like:
oninput={ev: Event => name.value = ev.target.asInstanceOf[HTMLInputElement].value}

protractor : element stored in a variable is changing if the result of the locator change

I have a list of invitations and want to see if the first pending one has been accepted after some trigger.
<div class="invitation">
<h1>A</h1>
<div class="PENDING">PENDING</div>
</div>
<div class="invitation">
<h1>B</h1>
<div class="PENDING">PENDING</div>
</div>
some code inside specs to store first pending invitation with h1 A
// get first element with css .PENDING
let pendingTxt = element.all(by.css('.PENDING')).get(0);
// get its parent : div.invitation with h1 A
let invitation = pendingTxt.element(by.xpath('ancestor::div'))
Here some script update invitation to status ACCEPTED
<div class="invitation">
<h1>A</h1>
<div class="ACCEPTED">ACCEPTED</div>
</div>
<div class="invitation">
<h1>B</h1>
<div class="PENDING">PENDING</div>
</div>
But if I log invitation now it will return invitation with h1 B.
Which means that invitation has been updated according to pendingText locator. I'm not sure to understand why.
But i can't find way to properly store the original invitation. I tried to clone it with no success.
The variable pendingTxt holds a Promise for an ElementFinder which will locate an element every time it is resolved. You are not storing an element, by the mechanism to locate it.
So to store an element, you first have to resolve the Promise to a WebElement:
protractor.promise.fulfilled(element.all(by.css('.PENDING')).get(0))
.then(status => {
expect(status.getText()).toEqual('PENDING');
// accept the invitation
expect(status.getText()).toEqual('ACCEPTED');
})
Or to a list of web elements:
element.all(by.css('.PENDING')).then(statuses => {
expect(statuses[0].getText()).toEqual('PENDING');
// accept the invitation
expect(statuses[0].getText()).toEqual('ACCEPTED');
})

infinite loop when trying to retrieve data from controller in view using angular $resource.Query() method

I'm building a small sails.js + angular.js app.
Here is a fiddle that roughly shows what my code looks like: http://jsfiddle.net/WEk3F/
index: function(req, res, next) {
Food.find({}, function foundFoods(err, foods) {
if (err) return next(err);
var data = {
name1: "test1",
name2: "test2"
}
res.view(
'food/index', {
foods: data
});
});
},
<div ng-app="myApp">
<div ng-controller="FoodController">
<ul>
<li ng-repeat="food in foods">
{{food.name}}
</li>
</ul>
<form>
<label for="name">Name:</label>
<input name="name" ng-model="editableFood.name" />
</form>
</div>
</div>
My problem is, that whenever i try to retrieve the data from my controller, i don't get those 2 items but instead it renders more and more items and just doesn't stop. even the page gets slow and unresponsive and almost freezes.
When i say
$scope.foods = [{"name": "test1"},{"name": "test2"}];
instead of
$scope.foods = Food.query();
it works. but i want the data to be coming from the backend via the controller.
the other methods (add, update etc) of the angular.js $resource module work fine for me.
/food maps to the index action of my FoodController and just returns some fixed test data
i found out what the problem was.
the angular.js $resource should only be used in a restful way, so the GET request to my food/index should return an array of objects.
in my case this wasn't the case. instead i used the index action of my controller to render a view and the result was therefor html.
so my options are to define a new route, that the $resource takes for the Query() command or define a new action that i use for the view/html stuff and use the index action again for pure restful response.
thx #sam hunter for pointing me to the right direction
the infinite loop that i received is explained here: One dimensional array of strings being parsed to 2d by angular resource
i love stack overflow

#each with call to helper ignores first entry in array

I'm trying to generate a menu with handlebars, based on this array (from coffeescript):
Template.moduleHeader.modules = -> [
{ "moduleName": "dashboard", "linkName": "Dashboard" }
{ "moduleName": "roomManager", "linkName": "Raumverwaltung" }
{ "moduleName": "userManager", "linkName": "Benutzerverwaltung" }
]
The iteration looks like this (from the html code):
{{#each modules}}
<li {{this.isActive this.moduleName}}>
<a class="{{this.moduleName}}" href="#">{{this.linkName}}</a>
</li>
{{/each}}
{{this.isActive}} is defined like this (coffeescript code again):
Template.moduleHeader.isActive = (currentModuleName) ->
if currentModuleName is Session.get 'module'
"class=active"
Based on Session.get 'module' the appropriate menu item is highlighted with the css class active.
On reload, the Session-variable module contains 'dashboard', which is the first entry in that array, however, it does not get the active-class. If I add an empty object as the first item to the modules-array, the 'dashboard'-item is properly highlighted.
The strange thing is, that the first item (dashboard) is rendered fine, but it does not have the active-class, which raises the impression, that the function this.isActive is not called for the first item.
Am I doing it wrong?
Really going out on a whim here but my traditional approach would be below. I don't know whether it will work but it was too big for a comment, yet again it's not a guaranteed fix. Let me know how it goes:
Replace the HTML with
{{#each modules}}
<li {{isActive}}>
<a class="{{moduleName}}" href="#">{{linkName}}</a>
</li>
{{/each}}
Replace the CS with
Template.moduleHeader.isActive = () ->
currentModule = this
currentModuleName = currentModule.moduleName
if currentModuleName is Session.get 'module'
"class=active"
If its rendering, the each block is working correctly. There must be an issue in the isActive helper. Most likely the if block isn't working as you think it should be. Put a console.log in there and see if it is entered, and put another inside the if (printf debugging). I find this is usually the easiest way to do quick debugging of handlebars helpers.
A useful helper in js for inspecting values inside of a context is as follows
Handlebars.registerHelper("debug", function(optionalValue) {
console.log("Current Context");
console.log("====================");
console.log(this);
if (optionalValue) {
console.log("Value");
console.log("====================");
console.log(optionalValue);
}
});
Then you can call this inside an each block and see all the values the current context/a specific value has.

How to get clicked elelment in <fb:visible-to-connection>-context?

It seems FB have removed the possibility to get the the clicked element (i.e. this) in the context of <fb:visible-to-connection>.
I.e:
<a onclick="doSomething(this);">test</a>
<script>
function doSomething(this) {
console.log(this);
}
<script>
Will give the following in Firebug:
Object { PRIV_obj=a, appendChild=function(), insertBefore=function(), more...}
Whereas
<fb:visible-to-connection>
<a onclick="doSomething(this);">test</a>
<fb:else>
</fb:else>
<a onclick="doSomething(this);">test</a>
</fb:visible-to-connection>
<script type="text/javascript">
function doSomething(element) {
console.log(element);
}
</script>
Will give:
null
Is this a temporary bug in FBJS or due to some new feature?
How do I get hold of "this" in the second example?
This was changed for security reasons, you can't access HTML elements inside FMBL elements any more - the initial bug report (which was closed as a 'by design') was about using getElementById but I believe this is the same cause