Javascript 未捕获类型错误:无法读取属性';isElementPresent';未定义的

Javascript 未捕获类型错误:无法读取属性';isElementPresent';未定义的,javascript,node.js,selenium-webdriver,Javascript,Node.js,Selenium Webdriver,我正在使用node.js、selenium webdriver、mocha和chai进行一些QE测试 我正在创建UI测试,遇到了测试失败的问题 这就是我得到的错误: 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_mo

我正在使用node.js、selenium webdriver、mocha和chai进行一些QE测试

我正在创建UI测试,遇到了测试失败的问题

这就是我得到的错误:

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
我不明白我做错了什么。我在页面对象中创建的所有方法都正常工作。我甚至可以看到firefox正确地运行测试和添加组织,因此我知道我正确地使用了SeleniumWebDriver(大部分都是)

我的测试逻辑是:1)通过模式窗口添加组织2)通过测试查看上一屏幕上的元素现在是否可见,验证我们是否正确添加了组织

我无头运行我的测试,我使用的服务器有一些问题,所以我认为通过引入wait方法可以修复我的问题和脆弱的测试

以下是我尝试使用的方法的链接:

我基本上是为了我自己的目的,对这个答案进行了调整:

谈到这一点:

this.driver.wait(function() {
  return this.driver.isElementPresent(By.css('div.AppBar'));
}, 10000);
以下是我的全部测试代码:

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);
      });
    });

  });

});
以下是我用于此代码的相关页面对象:

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;
以及增加一个组织模式

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;
如上所述,我相信我正确地使用和引用了SeleniumWebDriver,这些文档有点令人困惑,因为它们没有提供实际的示例,而且我对使用测试框架还是有点陌生

我有什么遗漏吗

tl:dr版本:

我相信我正确地引用了selenium webdriver来实现此功能:

this.driver.wait(function() {
  return this.driver.isElementPresent(By.css('div.AppBar'));
}, 10000);
但我还是得到了错误

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

试试,返回这个.isElementPresent(By.css('div.AppBar')

我可能错了,因为我没有使用Node.js编写Selenium代码,但我想.isElementPresent方法只对元素实例而不是驱动程序实例本身进行操作是有意义的

换句话说,我想这会更有意义:

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

如果我错了,请原谅。你问题的性质让我不得不猜测。

你能简化你的问题吗?为了解决您的问题,需要阅读和思考很多。@djangofan我添加了一个tldr,现在清楚了吗?我倾向于为我的Qs添加很多信息很抱歉。我正面临着这个问题。驱动程序。等等,你们解决了吗?这样做意味着By是未定义的,将这个添加到By意味着css是未定义的,它基本上移动到未定义的下一个方法,这让我相信我可能不正确地调用webdriver,但我不确定。