I am attemping to get the last row of a ng-repeat(ed) table via protractor to test and ensure the object I just created in a previous test run shows up. I have gotten as far as getting all of the text of the row but cannot seem to figure out through trial and error how to get each column of the last row as part of the array so I can verify each piece and then in the last column I have buttons to click which will be the next step.
The code I have so far is:
var elems = element.all(by.repeater('alert in alerts'));
elems.last().then(function(elm) {
console.log(expect(elm.getText()).toMatch('/testRunner/'));
});
As mentioned above, the expected output/output I want to check against is 'textRunner' and instead I get the entire row of text as such:
testRunner testing the runner 5 minutes No View Edit Enable
EDIT
Here is my final code:
var rows = element.all(by.repeater('alert in alerts'));
rows.last().then(function(row) {
var rowElems = row.findElements(by.tagName('td'));
rowElems.then(function(cols){
expect(cols[0].getText()).toContain('testRunner');
expect(cols[1].getText()).toContain('testing the runner');
expect(cols[4].getText()).toContain('5 minutes');
});
});
var rows = element.all(by.repeater('alert in alerts'));
rows.last().then(function(row) {
var rowElems = row.findElements(by.tagName('td'));
rowElems.then(function(cols){
expect(cols[0].getText()).toContain('testRunner');
expect(cols[1].getText()).toContain('testing the runner');
expect(cols[4].getText()).toContain('5 minutes');
});
});
Assuming your are using a <table>, and your different values are in <td>, you could check values by using the by.tagName locator strategy.
var rows = element.all(by.repeater('alert in alerts'));
var row = rows.last();
var rowElems = row. findElements(by.tagName('td'));
expect(rowElems.get(0).getText()).toMatch('/testRunner/');
expect(rowElems.get(1).getText()).toMatch('/testing/');
expect(rowElems.get(2).getText()).toMatch('/the/');
expect(rowElems.get(3).getText()).toMatch('/runner/');
expect(rowElems.get(4).getText()).toMatch('/5/');
expect(rowElems.get(5).getText()).toMatch('/minutes/');
expect(rowElems.get(6).getText()).toMatch('/No/');
expect(rowElems.get(7).getText()).toMatch('/View/');
expect(rowElems.get(8).getText()).toMatch('/Edit/');
expect(rowElems.get(9).getText()).toMatch('/Enable/');
Related
function myFunction() {
/////////////////////////////////////Fill planning/decor package
var managementSheet = SpreadsheetApp.openById("1P3EF4Edu0efzJVV1Sx-0ayAPaAAiRK8Sl0Y1qZHmcf4");
var packageSheet = managementSheet.getSheetByName("Order Contents");
//Order Contents iterater
var c = packageSheet.getMaxColumns();
var n = packageSheet.getLastRow();
var items = packageSheet.getRange(2,1,n,c).getValues();
var filteredItems = items.filter(function(row) {
if(row[2].toString().includes(firstName +" "+lastName))
{
var results =new Array();
var info = new Array();
info[0]=row[3];
info[1]=row[5];
info[2]=row[9];
info[3]=row[14];
info[4]=row[15];
info[5]=row[16];
results[0]= info;
// result = results.every().valueOf();
Logger.log(results)
var row=22
results.forEach(function(value, index) {
Logger.log("The value at index " + index + " is " + value + ".");
generatedInvoice.getRange(22,1,1,7).setValues([[info[0],,info[1],info[2],info[3],info[4],info[5]]])
row= index + 22+1
})}})
}
Hello. First off, I'm new to appscript/javascript/script in general... Secondly, I'm the worst at explaining things and am so over this as I've been working on it for 2 days with only a few food/water/sleep breaks and just can't figure it out.
I'm trying to take rows from one sheet and copy only some of that row's values to a template...
Customer orders are on one sheet.
Order CONTENTS(for all customers' orders) are on another sheet.
I want to generate an invoice containing everything that the customer has ordered. The code I have currently lists only the final row of the "results" array into my template sheet. I want all of the items that the customer ordered to be added to the invoice. I'm trying to figure out how to use "index" to move to the next line and add the next set of values, but I'm not sure what I'm doing wrong. By logging info, I see that everything is being called correctly and adding to the correct spot in the template. The problem is that it only adds the final line of data into the template when I want all of the lines that match a customer's name.
I am having one google sheet having more than 100 rows with column of "NAME, PLACE, PHONE". I want to change /correct the phone number on specific person Ex.John in the side bar (Form.html) and the correct place & phone number to be edit in that specific row of my google sheet "Phonelist". The code.gs given below which is not working. Could you lease rectify the same?
function sidebar() {
var html = HtmlService.createHtmlOutputFromFile("Form").setTitle('Phone Details');
SpreadsheetApp.getUi().sidebar(html);
}
function result(form) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ws = ss.getSheetByName("Phonelist");
var data = ws.getDataRange().getValues();
var name = form.name;
var place = form.place;
var phone = form.phone;
for (var i = 1; i < data.length; i++) {
if(data[i][1] == "John"){
var result = [name,place,phone];
ws.getRange(dat[i]).setValue(result);
}
}
}
It is difficult to understand what you exactly need. But there are some issues which are visible.
ws.getRange(data[i])is not valid. See docs. You need a row and a column at least, and in your case also the number of columns since your are inserting a range. Currently you only have a column. The solution is `
const startColumn = 1 // start at column A
const numberOfRows = 1 // update one row at a time
const numberOfColumns = result.length // this will be 3
ws.getRange(data[i], startColumn, numberOfRows, result.length)
.setValues(result) // setValues is correct, setValue is incorrect
The second issue is that you said that NAME is in the first column, but your test is testing against the second column. Array start at 0, i.e. the first item is actual accessed by [0]. therefore your test if(data[i][1] == "John") actually checks if the second column PLACE is equal to "John". To fix this, replace the [1] with [0], so:
if(data[i][0] == "John")
The third issue is handled in the first answer. You are using setValue() which is only to be used to set one cell. But since you are setting a number of cells at one time, you should use setValues() instead.
I have been struggling with a couple of issue so I thought I would reach out for help after doing much searching. I'm using AngularJS.
My first problem is that checkbox is not working properly when I use ng-repeat, it will only check the first box in the table code snippet below. I'm using a custom checkbox which I coded with css is the reason for the label.
My second issue is when I click on the check box it should delete any row I want but it deletes the row before it if I start from the bottom of the table up, but if I start from the top of the table down it works as expected except for the box being checked code snippet. I tried many ways to set the index but it still does not work.
$scope.removeRow = function(type) {
var index = -1;
var myArr = eval( $scope.contacts );
for( var i = 0; i < myArr.length; i++ ) {
if( myArr[i].type === type ) {
index = i;
break;
}
{
if( index === -1 ) {
alert( "Something gone wrong" );
}
$scope.contacts.splice(index, 1);
};
First off, don't use eval($scope.contacts). If that variable is a string and contains javascript it will run that javascript. if myArr isn't defined using myArr = $scope.contacts you can use myArr = JSON.parse(JSON.stringify($scope.contacts) or use angular.copy method.
I don't see your html, so I can't tell you why your checkbox doesn't work. But regarding your second problem, if it's deleting a row above when you hit splice, why not change that code to :
$scope.contacts.splice(index + 1, 1)
Currently I'm using by.repeater for getting all rows of a table and then check each row to see if it's matching my desired information. It seems to be too redundant. How can I do better?
element.all(by.repeater("userRole in roles")).each(function(row){
row.getText().then(function(text){
if(text.indexOf(ROLE_NAME) > -1){
expect(row.$('.role').getText()).toContain(ROLE_NAME);
}
});
});
.each will resolve promises, so we can gather all the text in rows and then use toContain on the array.
var textRows = element.all(by.repeater("userRole in roles")).each(function(row){
return row.getText();
});
expect(textRows).toContain(ROLE_NAME);
One other option is to use Array.prototype.some to use a function for validating a row:
var textRows = element.all(by.repeater("userRole in roles")).each(function(row){
return row.getText();
});
var hasAValidRow = textRows.some(function(row){ return row.indexOf(ROLE_NAME) > -1; });
expect(hasAValidRow).toBe(true);
I was stuck on a similar problem, after many hours I got it working using:
var rows = $$('#ss-personal-phone-action-panel');
rows.each(function(row) {
var rowElems = row.$$('td.destination');
expect(rowElems.count()).toBe(1);
expect(rowElems.get(0).getText()).toMatch(testTelephone);
});
I hope this help
Problem
Calling repeater('#myTable tr','Rows').count(); returns a Future, not an integer. I need to get the integer value so I can confirm that an additional row was added to a table.
Code
it('should add a new user when save button is clicked',function()
{
showModal();
//here I'm trynig to store the row count of my table into a local variable.
//a future is returned who's 'value' field is undefined.
var memberCount = repeater('#memberTable tr','Member Rows').count();
//this outputs 'undefined'
console.log(memberCount.value);
input('editedMember.name').enter('John');
input('editedMember.grade').enter(5);
input('editedMember.ladderPosition').enter(3);
element('#saveMemberButton').click();
sleep(1);
expect(element(modalId).css('display')).toBe('none');
//here is where I want to do the comparison against the above stored memberCount
expect(repeater('#memberTable tr', 'Member Rows').count()).toBe(memberCount.value + 1);
});
Test Result
Chrome 25.0 e2e should add a new user when save button is clicked FAILED
expect repeater 'Member Rows ( #memberTable tr )' count toBe null
/Users/jgordon/learning/chessClub/web-app/test/e2e/scenarios.js:45:3: expected null but was 6
Chrome 25.0: Executed 2 of 2 (1 FAILED) (1 min 4.117 secs / 1 min 3.773 secs)
Drilling into the source code for Angularjs' e2e support reveals that you have to call execute() on the Future to have it populate its value. Also, when you call execute you have to provide a "done" function to the execute() otherwise Testacular will (oddly enough!) skip your test.
Code
var rowCountFuture = repeater('#memberTable tr','Member Rows').count();
rowCountFuture.execute(function(){
});
var memberCount = rowCountFuture.value;
While I'm jazzed to see this works, I'm concerned there may be some asynchronous bugs that could come out of this, also, I feel like this is a hack and not the right way to do it. Any ideas?
Based on the latest Protractor version:
it('should add a new user when save button is clicked', function() {
var memberCount;
element.all(by.repeater('#memberTable tr','Member Rows')).count().then(function(value) {
memberCount = value;
});
...
// then do all your entering user info, saving etc.
...
browser.refresh(); // or however you want to load new data
expect(element.all(by.repeater('#memberTable tr','Member Rows')).count()).toEqual(memberCount + 1);
});
I've run into the same issue, and have seen confusing results when testing value returned after calling execute(). I've found this method works more reliably:
var getCount = repeater('ul li').count();
getCount.execute(function(value) {
expect(value).toEqual(3);
});
You can do this most easily in the async promise returned by the locator
element.all(By.repeater 'thing in things').then(function(elements){
count = elements.length;
expect(count).toEqual(3);
});