Javascript 使用selenium webdriver和mocha实现模块化登录功能

Javascript 使用selenium webdriver和mocha实现模块化登录功能,javascript,unit-testing,selenium-webdriver,mocha.js,Javascript,Unit Testing,Selenium Webdriver,Mocha.js,我正在尝试创建一个登录功能,我可以使用mocha测试和selenium webdriver进行单元测试,因为我有很多事情要做,从用户登录开始,然后 下面是我的最佳快照,但当我运行它时,控制台只是记录 Already registered user logs in and sees homepage 1) should work (it's red text) Login an existing user 然后什么也没发生,我必须控制C的进程。在我使用这个模块化登录实现之前,我的代码是有效

我正在尝试创建一个登录功能,我可以使用mocha测试和selenium webdriver进行单元测试,因为我有很多事情要做,从用户登录开始,然后

下面是我的最佳快照,但当我运行它时,控制台只是记录

Already registered user logs in and sees homepage
  1) should work (it's red text)

Login an existing user
然后什么也没发生,我必须控制C的进程。在我使用这个模块化登录实现之前,我的代码是有效的,所以我确信这就是我的问题所在。这里有我遗漏的东西吗?我也愿意接受关于我如何制作登录功能的一般批评,因为我没有那么多的webdriver经验

下面是我的代码。它在一个js文件中

var test = require('selenium-webdriver/testing'),
chai = require('chai');
chai.use(require('chai-string'));
chai.use(require('chai-as-promised'));
var expect = chai.expect,
webdriver = require('selenium-webdriver'),
By = webdriver.By;

// I want this to be a modular login function I can use multiple places
function login(driver) {
    test.describe('Login an existing user', function() {
        test.it('should work', function() {
            this.timeout(0);

            var email = 'myemail@test.com';
            var password = 'password';

            driver.get('http://localhost:9000');

            driver.getTitle().then(function(title) {
                expect(title).to.equal('my title');
            })
            .then(function() {
                // do login stuff and click login button
            });
            .then(function() {
                return driver;
            });
        });
    });
}

//an example of when I would use the login function
test.describe('Already registered user logs in and sees homepage', function() {
  test.it('should work', function() {

    this.timeout(0);
    var driver = new webdriver.Builder().
    withCapabilities(webdriver.Capabilities.chrome()).
    build();

    driver = login(driver)
    .then(function() {
        driver.findElement(By.xpath("relevant xpath")).click();
    })
  })
})
通过从insidetest.it调用login,您实际上是在它内部调用descripe,这是不允许的。摩卡根本不支持从内部调用或描述它。不幸的是,它并没有试图发现这种情况并对此大声疾呼。它只是继续做它所做的一切。在所有情况下,它都会导致未定义的行为,比如你观察到的行为。在大多数情况下,未定义的行为是不稳定的。我非常罕见的情况下,它恰好符合开发人员的期望,但这是由于机会,而不是设计

在您的情况下,我只需从内部登录中删除对test.description和test.it的调用,并确保返回承诺。你可以在那里保持期待。但是,您将无法在登录内部调用this.timeout0。大概是这样的:

function login(driver) {
    var email = 'myemail@test.com';
    var password = 'password';

    driver.get('http://localhost:9000');

    return driver.getTitle().then(function(title) {
        expect(title).to.equal('my title');
    })
    .then(function() {
        // do login stuff and click login button
    })
    .then(function () {
        return driver;
    });
}
并将您的呼叫代码修改为:

var promise = login(driver)
.then(function(driver) {
    driver.findElement(By.xpath("relevant xpath")).click();
});

你可以做任何你想做的事,或者什么都不做。但是,驱动程序本身并不是一个承诺,因此将驱动程序设置为该值将不起作用。

当您在调试器中逐步查看代码时,您看到了什么?感谢您澄清了描述行为!如果我有driver=logindriver,它可以正常工作。但我添加了driver.thenetc之后,我得到了TypeError:无法读取未定义的属性'then'。我认为webdrivers是有希望的?看起来你在我发布我的评论时删除了你之前的评论。无论如何,我已经用一个例子进行了编辑。如果实际从函数返回值,则不应得到报告的错误。请参阅我在driver.getTitle…之前添加的return。此外,this.timeout不是一个函数。如果您删除了descripe,那么这是什么?是的,不再可能从内部登录调用this.timeout。您可以使用login.callthis驱动程序,但将timeout设置为0,然后稍后再将其设置为其他值并不是特别有意义。如果您只想为登录设置一个特殊超时,可以从beforeEach或before钩子调用login。添加额外的返回修复了then问题,但在使用函数driver=logindriver.thenfunction{driver.findElement…我有driver.findElement不是函数!我如何维护驱动程序对象?