0

I need to log in with 5 different roles and check if they have the right tabs to navigate depending on their roles.

But the problem is; it logs in with the 'driver' role and checks both "rides.title" and "chauffeurs.title". Since 'driver' role doesn't include "chauffeurs.title", the test fails.

It skips the "if" part and directly goes to "else if" part.

What I tried:

I tried to test if my loop is working well or not and apparently it's working well.

I deleted the whole if block and pasted the code below and saw that it logged in with every single role one-by-one and checked for "rides.title".

.visit('/planned')
          .get('[data-qa="rides.title"')
          .should('exist')
          .get('[data-qa="logout"]')
          .click()

Except the last role; since it doesn't have "rides.title", which is fine.

Here is the full code to review and get more info about what I did so far:

const roles = ["driver", "dispatcher", "provider", "reviewer", "admin"];

it("Navigation items for a single permission", () => {
  cy.fixture("users.json").then(users => {
    const user = users[Cypress.env("ENVIRONMENT")];
    roles.forEach(role => {
      cy.login(user[role], Cypress.env("DEFAULT_USER_PASSWORD")).then(
        response => {
          cy.setCookie("__bl_pp__", response.body.result.access_token);
          if (user[role] === "driver") {
            cy.visit("/planned")
              .get('[data-qa="rides.title"')
              .should("exist")
              .get('[data-qa="logout"]')
              .click();
          } else if (["dispatcher", "provider", "reviewer"].includes(user[role])) {
            cy.visit("/planned")
              .get('[data-qa="rides.title"')
              .should("exist")
              .get('[data-qa="chauffeurs.title"')
              .should("exist")
              .get('[data-qa="logout"]')
              .click();
          } else {
            cy.visit("/planned")
              .get('[data-qa="chauffeurs.title"')
              .should("exist")
              .get('[data-qa="logout"]')
              .click();
          }
        })
      })
    })
  })
})

The expected scenario should be; the test should log in with 5 different roles and verify the available tabs, as mentioned in the code above.

Role        Navigation Tabs
Driver      Rides
Dispatcher  Rides, Chauffeurs
Provider    Rides, Chauffeurs
Reviewer    Rides, Chauffeurs
Admin       Chauffeurs

Thanks in advance!

Here is my users.json file:

{
  "development": 
  {
    "driver": "aa+driver@b.com",
    "dispatcher": "bb+dispatcher@b.com",
    "provider": "cc+provider@b.com",
    "reviewer": "dd+reviewer@b.com",
    "admin": "ee+admin@b.com"
  }
}
ADyson
  • 57,178
  • 14
  • 51
  • 63
Ziya I. Erogul
  • 79
  • 1
  • 10
  • 8
    `(user[role] === 'dispatcher' || 'provider' || 'reviewer')` will _always_ be truthy, because `'provider'` is. – Sebastian Simon Jan 15 '19 at 12:25
  • 2
    To clarify Xufox's comment, if the role is not "dispatcher" then `(user[role] === 'dispatcher' || 'provider' || 'reviewer')` will evaluate to `(false || true || true)` which of course will then evaluate to `true`. What you've done is not how you write an if statement to test for multiple values, you have to restate each side of the argument in every clause, i.e. `(user[role] === 'dispatcher' || user[role] === 'provider' || user[role] === 'reviewer')`. Each bit within the `||`s is evaluated in isolation... it's not a list of options. I suggest you review your understanding of JS syntax. – ADyson Jan 15 '19 at 12:29
  • Possible duplicate of [Concise way to compare against multiple values](https://stackoverflow.com/questions/13737091/concise-way-to-compare-against-multiple-values). The [`includes`](https://stackoverflow.com/a/13737101/4642212) approach is currently best practice. – Sebastian Simon Jan 15 '19 at 12:32
  • What is `user[role]` supposed to be? It seems like you're trying to get something like `user.dispatcher` but...then you're comparing this to the string "dispatcher", too. It seems like you either need to check `user.role` which is one of the strings at the top of that block or you have `user.dispatcher = true`, `user.driver = true`, `user.provider = false`, etc. Or something else entirely. Basically, I think `user[role]` is incorrect. – VLAZ Jan 15 '19 at 12:32
  • user[role] will change as mentioned in the first row. It'll log in one-by-one with every single role and I want to match them while entering the if statement. If the role is driver then check for this Else if the role is dispatcher, provider or reviewer then check for this Else (the role is admin) check for this. Am I thinking in a wrong way for such case ? – Ziya I. Erogul Jan 15 '19 at 12:40
  • 1
    @ZiyaI.Erogul but `user[role]` will check for each of `user.dispatcher`, `user.driver`, etc *properties* of the object. And it seems weird to have `user.dispatcher = "dispatcher"` because you'd be checking if THAT has been set when you do `user[role] === "dispatcher"`. Is that really what your `user` object has? Or is it that you've set (the much more logical) property `user.role = "dispatcher"` or something like `user.dispatcher = true`? Both are normal but as it stands you expect some unorthodox mix of the two approaches. – VLAZ Jan 15 '19 at 12:44
  • In short, `user[role]` is [dynamic access to object properties](https://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable) so you'll be picking up the property of `user` that is named with the contents of the `role` variable. – VLAZ Jan 15 '19 at 12:48
  • Thanks for the update. The simple answer is that `if (user[role] === "driver") {` will never be true, because none of the values in your JSON data are equal to "driver". For a start your `user` only has one property called "development", which itself contains another object. So `user[role]` is unlikely to return _anything_ unless `role` is set to "development". Then, even if you correct that to actually look at a field that exists, none of the actual values of the sub-properties are equal to "driver". The nearest value is "aa+driver@b.com", but an `==` test will not match to that. – ADyson Jan 15 '19 at 17:08
  • Maybe you really want to be checking if a property whose name matching the `role` value _exists_ in your `user.development` object, or maybe you want to check whether the value of the property named `user.development.driver` _contains_ the word "driver" anywhere in the string. It's a little unclear what the correct test is supposed to be. Either way, I think you maybe need to improve your understand of how to navigate JavaScript object structures in code, and also make sure you understand the difference between the _name_ of a property and the _value_ stored in that property. – ADyson Jan 15 '19 at 17:09

3 Answers3

0

The problem here is with the if conditional statement. This is not correct syntax for what you want to achieve:

if(user[role] === "dispatcher" || "provider" || "reviewer") {
   ...
}

It basically means "if the user role is 'dispatcher' or true or true", and can be shortened to "true". This is because any non-empty string is always 'truthy' in js.

You need to repeat the comparison for each of these "or" groups, like this:

if(user[role] === "dispatcher" || user[role] === "provider" || user[role] === "reviewer") {
   ...
}

Or preferably like this:

if(["dispatcher", "provider", "reviewer"].includes(user[role])) {
   ...
}
Marcin Natanek
  • 576
  • 3
  • 11
  • I applied your suggestion @Marcin and I'm still getting the following error: expected [data-qa="chauffeurs.title" to exist in the DOM. It's skipping the first "if". – Ziya I. Erogul Jan 15 '19 at 13:23
  • 1
    @ZiyaI.Erogul it would help a lot if you showed us an example of the contents of the `user` variable. Please edit that into your question...thanks. – ADyson Jan 15 '19 at 13:36
0

You should not test

if (user[role] === "driver")

and

if (["dispatcher", "provider", "reviewer"].includes(user[role]))

because user[role] is the fixture object.

You should test

if (role === "driver")

and

if (["dispatcher", "provider", "reviewer"].includes(role))

Not sure if that solves all the problems, but it's an obvious first step.

0

Thanks for your comments! I've fixed this by defining another const to store the value of the users' actual roles which I got from another page, then I used that as a condition.

Ziya I. Erogul
  • 79
  • 1
  • 10