0

I'm working on some QE tests using node.js, selenium-webdriver, mocha, and chai.

I'm creating UI tests and ran into a problem with my tests failing.

This is the error I am getting:

Uncaught TypeError: Cannot read property 'isElementPresent' of undefined
      at test/admin/users/add_user/org_admin_adds_new_users_positive.js:65:29
      at node_modules/selenium-webdriver/lib/webdriver/webdriver.js:720:12

I don't understand what I am doing wrong. All the methods I created in my page objects work correctly. I can even see firefox run the tests and adding the organizations correctly so I know I am properly using selenium-webdriver (well most of it).

The logic of my tests are: 1) adding a organization through a modal window 2) verify that we have correctly added an organization by testing to see if an element that was on the previous screen is now visible.

I run my tests headlessly and I have some issues with the server we are using so I thought by introducing the wait method would fix my issues and fragile tests.

Here is the link to the method I am trying to use: http://selenium.googlecode.com/git/docs/api/javascript/class_webdriver_WebDriver.html#wait

I'm basically tweaking the this answer to a SO Q for my own purpose: Selenium WebDriver wait till element is displayed

turning it to this:

this.driver.wait(function() {
  return this.driver.isElementPresent(By.css('div.AppBar'));
}, 10000);

Here is my entire test code:

var driver = require('selenium-webdriver');
var chai = require('chai');
var expect = chai.expect;
var adminVar = require('_/variables/admin_variables');
var AdminLogin = require('_/pageObject/admin/login/index');
var Common = require('_/pageObject/admin/login/common/index');
var HamburgerMenu = require('_/pageObject/admin/login/common/hamburgerMenu/index');
var Users = require('_/pageObject/admin/login/users/index');
var AddUserModal = require('_/pageObject/admin/login/users/addUserModal/index');

var userVar = require('_/variables/users_variables.json');

chai.use(require('chai-as-promised'));

describe('Admin Tests - Org Admin User', function() {
  this.timeout(500000);
  before(function() {
    this.driver = new driver.Builder().withCapabilities(driver.Capabilities.firefox()).build();
    this.driver.get(adminVar.local.adminSignin);

    var adminLogin = new AdminLogin(this.driver);
    adminLogin.fillEmail();
    adminLogin.fillPassword();
    adminLogin.signin();

    return this.driver.manage().timeouts().implicitlyWait(2500);
  });

  after(function() {
    return this.driver.quit();
  });

  describe('would like to click Users panel', function() {
    before(function() {
      var com = new Common(this.driver);
      com.clickHamburger();

      var hamburgMenu = new HamburgerMenu(this.driver);
      hamburgMenu.clickUser();
    });

    describe('add a new user', function() {
      beforeEach(function() {
        var users = new Users(this.driver);
        this.driver.sleep(500);
        users.addNewUser();
        return this.driver.manage().timeouts().implicitlyWait(3500);
      });

      afterEach(function() {
        return this.driver.manage().timeouts().implicitlyWait(3500);
      });

      it('correctly add user: name - Model Employee && email - memployee@test.com', function() {
        var userModal = new AddUserModal(this.driver);
        this.driver.manage().timeouts().pageLoadTimeout(10000);
        userModal.addUser(userVar.goodUser1.name, userVar.goodUser1.email);

        var users = new Users(this.driver);
        this.driver.wait(function() {
          return this.driver.isElementPresent(By.css('div.AppBar ul.AppBar-breadcrumbs'));
        }, 10000);
        return expect(users.toggleFilter.isDisplayed()).to.eventually.equal(true);
      });

      it('correctly add user: name - £∆ΩΩ¥ ßœ†∑®§ && email - unicode1@test.com', function() {
        var userModal = new AddUserModal(this.driver);
        this.driver.manage().timeouts().pageLoadTimeout(10000);
        userModal.addUser(userVar.badUser3.name, userVar.badUser3.email);

        var users = new Users(this.driver);
        this.driver.wait(function() {
          return this.driver.isElementPresent(By.css('div.AppBar ul.AppBar-breadcrumbs'));
        }, 10000);
        return expect(users.toggleFilter.isDisplayed()).to.eventually.equal(true);
      });
    });

  });

});

Here are the relevant page objects I am using for this code:

class Organizations {
  constructor(driver) {
    this.driver = driver;
    this.driver.manage().timeouts().implicitlyWait(2000);

    var name;

    this.pageHeader = this.driver.findElement({
      css: 'div.AppBar ul.AppBar-breadcrumbs > li > span'
    });

    this.toggleFilter = this.driver.findElement({
      css: 'div.AppBar button.AppBar-filter'
    });

    this.inputFilter = this.driver.findElement({
      css: 'div.OrganizationListFilters-byText input[type="text"]'
    });

    this.addButton = this.driver.findElement({
      css: '#app > div > div > div > div > div.Page-wrapper > div:nth-child(2) > div.Material-button--primary > div > button'
    });
  }

  clearSearch() {
    this.inputFilter.clear();
  }

  inputSearch(name) {
    this.inputFilter.clear();
    this.inputFilter.sendKeys(name);
    return this.driver.manage().timeouts().implicitlyWait(1000);
  }

  toggleSearch() {
    this.toggleFilter.click();
    return this.driver.manage().timeouts().implicitlyWait(4500);
  }

  addNewOrgButton() {
    this.driver.manage().timeouts().implicitlyWait(7500);
    this.addButton.click();
    return this.driver.manage().timeouts().implicitlyWait(2500);
  }

  menuButtonAfterAction() {
    this.driver.manage().timeouts().implicitlyWait(1500);
    this.driver.findElement({
      css: 'td.RowMenu button.RowMenu-button'
    }).click();
    return this.driver.manage().timeouts().implicitlyWait(2500);
  }
}

module.exports = Organizations;

and the adding an organization modal

class AddOrgModal {
  constructor(driver) {
    this.driver = driver;
    this.driver.manage().timeouts().implicitlyWait(2000);

    var name, subdomain, type, id;

    this.modalTitle = this.driver.findElement({
      css: 'div.AddOrganizationDialog h3'
    });

    this.nameInput = this.driver.findElement({
      css: 'div.AddOrganizationDialog input[name="name"]'
    });

    this.domainInput = this.driver.findElement({
      css: 'div.AddOrganizationDialog input[name="domain"]'
    });

    this.typeInput = this.driver.findElement({
      css: 'div.AddOrganizationDialog input[name="type"]'
    });

    this.idInput = this.driver.findElement({
      css: 'div.AddOrganizationDialog input[name="externalID"]'
    });

    this.enableExperience = this.driver.findElement({
      css: 'div.AddOrganizationDialog input[name="hasExperience"]'
    });

    this.subdomainInput = this.driver.findElement({
      css: 'div.AddOrganizationDialog input[name="subdomain"]'
    });

    this.cancelButton = this.driver.findElement({
      css: 'div.AddOrganizationDialog button.AddOrganizationDialog-cancel'
    });

    this.submitButton = this.driver.findElement({
      css: 'div.AddOrganizationDialog button.AddOrganizationDialog-submit'
    });
  }

  getHeaderText() {
    return this.driver.modalTitle.getText();
  }

  cancelModal() {
    this.cancelButton.click();
  }

  newOrg(name, subdomain, type, id) {
    this.driver.manage().timeouts().implicitlyWait(3000);
    this.nameInput.clear();
    this.nameInput.sendKeys(name);
    this.typeInput.clear();
    this.typeInput.sendKeys(type);
    this.idInput.clear();
    this.idInput.sendKeys(id);
    this.enableExperience.click();
    this.subdomainInput.clear();
    this.subdomainInput.sendKeys(subdomain);
    this.submitButton.click();
    return this.driver.manage().timeouts().implicitlyWait(5000);
  }
}

module.exports = AddOrgModal;

As I stated above I believe I am using and referencing selenium-webdriver correctly, the docs are kinda confusing because they don't provide actual examples and I'm still somewhat new using testing frameworks.

Is there something I am missing?

tl:dr version:

I believe I'm referencing selenium-webdriver correctly for this function:

this.driver.wait(function() {
  return this.driver.isElementPresent(By.css('div.AppBar'));
}, 10000);

but I still get the error

Uncaught TypeError: Cannot read property 'isElementPresent' of undefined
          at test/admin/users/add_user/org_admin_adds_new_users_positive.js:65:29
          at node_modules/selenium-webdriver/lib/webdriver/webdriver.js:720:12
Community
  • 1
  • 1
azemPC
  • 264
  • 3
  • 15
  • Can you simplify your question? That is a lot to read and think about in order to catch up with the problem you are having. – djangofan Mar 02 '16 at 19:13
  • @djangofan I added a tldr, is it clear now? I tend to add a lot of info for my Qs sorry about that. – azemPC Mar 02 '16 at 19:41
  • I am facing the same issue with the this.driver.wait, did you solve it? – vhugo Dec 14 '17 at 16:24

2 Answers2

0

Try, return this.isElementPresent(By.css('div.AppBar'));

rolu
  • 378
  • 2
  • 3
  • 19
  • doing this says that By is undefined, adding this to By says css is undefined, it basically moves undefined to the next method which makes me believe I may be calling webdriver improperly but I'm not sure. – azemPC Mar 02 '16 at 20:05
0

I might be wrong, since I don't code Selenium using Node.js, but I would guess that the .isElementPresent method only makes sense operating on a Element instance and not the driver instance itself.

In other words, I would guess this would make more sense:

this.driver.findElement(By.css('div.AppBar')).isElementPresent()

If I am wrong, excuse me. The nature of your question makes me have to take a guess.

djangofan
  • 28,471
  • 61
  • 196
  • 289