1

I'm creating a page object model and one of the properties is all the users from a table. The table has a few columns so I'd like to parse that table and create a user object for each row, then return that set to then be used in tests. So far, this is what that property of my page object looks like:

users: {
    get: function() {
        let userRecords = [];
        var users = element.all(by.repeater('user in users')).each(function(tr, index) {
            let user = {
                name:   tr.element(by.css('td:nth-child(2)')).getText().then(text => {return text;}),
                role:   tr.element(by.css('td:nth-child(3)')).getText().then(text => {expect(text).toBeTruthy();}),
                status: tr.element(by.css('td:nth-child(4)')).getText().then(text => {expect(text).toBeTruthy();}),
                //actionsButton: tr.element(by.css('btn btn-default'))
            };
            userRecords += user;
        }).then(userRecords => {return userRecords});
        
        return userRecords;
    }
},

Through trial and error I encounter one of two outcomes when just trying to print to screen each element of userRecords:

  1. each element prints as undefined or
  2. userRecords is not defined.

Just to reiterate, I'm simply trying to build an array that holds each user as an object to then be able to iterate / filter on that set in my tests.

Given the approach I'm taking, what's the ideal way to construct this user array and resolve the promises?

Edit: it's worth noting that if I do a console.log() within each of the getText().then() statements, it does print the correct data from the table. So, I do know that it's reading the table correctly.

2
  • what do you need eventually? do you need an object that contains elementFinders? or you're actually trying to return well organized values of the cells? Commented Jan 6, 2021 at 17:45
  • @SergeyPleshakov I'm hoping to fully unwrap the elements and the promises and the user object fields only contain the actual table values. Commented Jan 6, 2021 at 17:46

1 Answer 1

1

I'd go with a method that returns json, and would make it async

users: async function() {
  let userRecords = [];
  var users = element.all(by.repeater('user in users'));
  for (let i = 0; i < await users.count(); i++) {
    let tr = users.get(i);
    let user = {
      name: await tr.element(by.css('td:nth-child(2)')).getText(),
      role: await tr.element(by.css('td:nth-child(3)')).getText(),
      status: await tr.element(by.css('td:nth-child(4)')).getText()
    };

    userRecords.push()
  }
        
  return userRecords;
},

and then use:

console.log(
  JSON.stringify(
    await constructorName.users()
  )
)

should be as simple as that. Note, I didn't test the code, but I did use the approach in my experience. So it may require some minor modifications

In general, try to avoid .then - async/await is easier to use, .each - go with for loop instead. Also userRecords += user; doesn't do what you think it does (though I may be wrong here)

Sign up to request clarification or add additional context in comments.

1 Comment

Yep, this did it. Much appreciated :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.