Protractor 当我隔离一个测试时,它通过了,但当与其他测试一起顺序运行时,它会因NoSuchElementError而失败

Protractor 当我隔离一个测试时,它通过了,但当与其他测试一起顺序运行时,它会因NoSuchElementError而失败,protractor,Protractor,我对用于运行量角器测试的页面对象进行了一些更改,以在Sauce Labs上运行,即调用实用程序方法获取浏览器和平台,以便我们可以使用适当的测试用户,在进行更改后,在运行测试套件时,我一直得到一个NosTouchElementError 当我隔离注销测试时,它通过了,但是当与任何其他文件一起运行时,它失败了。目前,我只在Chrome上运行登录测试和注销测试,以限制可能的原因 我们使用页面对象导航到可测试状态,在本例中是登录页面对象和仪表板页面对象(登录会将您带到仪表板) 登录页面对象: 'use

我对用于运行量角器测试的页面对象进行了一些更改,以在Sauce Labs上运行,即调用实用程序方法获取浏览器和平台,以便我们可以使用适当的测试用户,在进行更改后,在运行测试套件时,我一直得到一个NosTouchElementError

当我隔离注销测试时,它通过了,但是当与任何其他文件一起运行时,它失败了。目前,我只在Chrome上运行登录测试和注销测试,以限制可能的原因

我们使用页面对象导航到可测试状态,在本例中是登录页面对象和仪表板页面对象(登录会将您带到仪表板)

登录页面对象:

'use strict';

var TestUtils = require('../../util/test-utils.js');
var HeaderPageElement = require('../page_elements/header-page-element.js');

var LoginPage = function () {
    var self = this;

    this.get = function () {
        browser.get('http://localhost:9000/index.html');
        this.header = new HeaderPageElement();
        this.loginForm = element(by.name('loginForm'));
        this.usernameInput = element(by.model('credentials.username'));
        this.passwordInput = element(by.model('credentials.password'));
        this.loginButton = element(by.name('loginButton'));
        this.signupLink = element(by.xpath('//a[@ui-sref="signup"]'));
    };

    this.setCredentials = function (username, password) {
        var deferred = protractor.promise.defer();
        var testUtils = new TestUtils();

        testUtils.getCapabilities().then(function (capabilities) {
            return testUtils.getTestUser(capabilities.browserName, capabilities.platform);
        }).then(function (testUser) {
            username = username || testUser.username;
            password = password || testUser.password;
            self.usernameInput.sendKeys(username);
            self.passwordInput.sendKeys(password);
            deferred.fulfill();
        });

        return deferred.promise;
    };

    this.login = function (username, password) {
        return this.setCredentials(username, password).then(function () {
            return self.loginButton.click();
        });
    };

    this.signup = function () {
        return this.signupLink.click();
    };

    this.get();
};

module.exports = LoginPage;
'use strict';

var LoginPage = require('./login-page.js');
var HeaderPageElement = require('../page_elements/header-page-element.js');
var ProjectCreateModalPageElement = require('../page_elements/project-create-modal-page-element.js');

var DashboardPage = function () {
    var self = this;

    this.get = function () {
        var loginPage = new LoginPage();
        loginPage.login();
        this.header = new HeaderPageElement();
        this.newProjectButton = element(by.name('newProjectButton'));
        this.projectFilterInput = element(by.name('projectFilterInput'));
    };

    this.createNewProject = function (projectTitle, projectTypes) {
        var deferred = protractor.promise.defer();
        this.newProjectButton.click().then(function () {
            var modalPage = new ProjectCreateModalPageElement();
            modalPage.createNewProject(projectTitle, projectTypes);
            deferred.fulfill();
        });
        return deferred.promise;
    };

    this.get();
};

module.exports = DashboardPage;
仪表板页面对象:

'use strict';

var TestUtils = require('../../util/test-utils.js');
var HeaderPageElement = require('../page_elements/header-page-element.js');

var LoginPage = function () {
    var self = this;

    this.get = function () {
        browser.get('http://localhost:9000/index.html');
        this.header = new HeaderPageElement();
        this.loginForm = element(by.name('loginForm'));
        this.usernameInput = element(by.model('credentials.username'));
        this.passwordInput = element(by.model('credentials.password'));
        this.loginButton = element(by.name('loginButton'));
        this.signupLink = element(by.xpath('//a[@ui-sref="signup"]'));
    };

    this.setCredentials = function (username, password) {
        var deferred = protractor.promise.defer();
        var testUtils = new TestUtils();

        testUtils.getCapabilities().then(function (capabilities) {
            return testUtils.getTestUser(capabilities.browserName, capabilities.platform);
        }).then(function (testUser) {
            username = username || testUser.username;
            password = password || testUser.password;
            self.usernameInput.sendKeys(username);
            self.passwordInput.sendKeys(password);
            deferred.fulfill();
        });

        return deferred.promise;
    };

    this.login = function (username, password) {
        return this.setCredentials(username, password).then(function () {
            return self.loginButton.click();
        });
    };

    this.signup = function () {
        return this.signupLink.click();
    };

    this.get();
};

module.exports = LoginPage;
'use strict';

var LoginPage = require('./login-page.js');
var HeaderPageElement = require('../page_elements/header-page-element.js');
var ProjectCreateModalPageElement = require('../page_elements/project-create-modal-page-element.js');

var DashboardPage = function () {
    var self = this;

    this.get = function () {
        var loginPage = new LoginPage();
        loginPage.login();
        this.header = new HeaderPageElement();
        this.newProjectButton = element(by.name('newProjectButton'));
        this.projectFilterInput = element(by.name('projectFilterInput'));
    };

    this.createNewProject = function (projectTitle, projectTypes) {
        var deferred = protractor.promise.defer();
        this.newProjectButton.click().then(function () {
            var modalPage = new ProjectCreateModalPageElement();
            modalPage.createNewProject(projectTitle, projectTypes);
            deferred.fulfill();
        });
        return deferred.promise;
    };

    this.get();
};

module.exports = DashboardPage;
这些是正在运行的测试

登录测试:

'use strict';

var LoginPage = require('./pages/login-page.js');

describe('login test', function () {
    var page;

    beforeEach(function () {
        page = new LoginPage();
    });

    it('should be directed to login', function () {
        expect(page.loginForm.isPresent()).toBe(true);
    });

    it('Login button should be disabled', function () {
        expect(page.loginButton.getAttribute('disabled')).toEqual('true');
        page.setCredentials('wrong', 'user').then(function () {
            expect(page.loginButton.getAttribute('disabled')).toEqual(null);
        });
    });

    it('login should fail and remain at login screen', function () {
        page.login('wrong', 'user').then(function () {
            expect(page.loginForm.isPresent()).toBe(true);
        });
    });

    it('login success should redirect to dashboard', function () {
        page.login().then(function () {
            browser.wait(function () {
                return $('#dashboard').isPresent();
            });
            expect($('#dashboard').isDisplayed()).toBe(true);
        });
    });
});
注销测试:

'use strict';

var DashboardPage = require('./pages/dashboard-page.js');

describe('logout test', function () {
    var page;

    beforeEach(function () {
        page = new DashboardPage();
    });

    it('logout success should redirect to login page', function () {
        page.header.logout().then(function() {
            browser.wait(function () {
                return $('#login').isPresent();
            });
            expect($('#login').isDisplayed()).toBe(true);
        });
    });
});
按顺序运行这些测试时出现的错误如下:

NoSuchElementError:使用locator:by.model(“credentials.username”)找不到元素

它指定的行是DashboardPage对象内的
get
方法,通过该方法,它实例化LoginPage对象并调用
login
方法,以便导航到仪表板:

this.get = function () {
    var loginPage = new LoginPage();
    loginPage.login();
    this.header = new HeaderPageElement();
    this.newProjectButton = element(by.name('newProjectButton'));
    this.projectFilterInput = element(by.name('projectFilterInput'));
};
无论出于何种原因,在调用
login
方法时,登录页面的
usernameInput
尚未设置


我很确定这与没有正确编码的承诺有关,但我已经连续几天对它进行了猛烈抨击,但都没有成功。如果您有任何帮助,我们将不胜感激。

当您达到“注销”测试并尝试登录后,您是否仍然因为“登录”测试而登录?换句话说,看起来您正在尝试登录,而您已经登录。这是正确的。问题是我们使用内存中的数据库进行开发,每当刷新应用程序时,它就会返回到登录页面。这些测试都是在考虑到这一点的情况下构建的,但在尝试并行测试时,我们必须修复一个登录错误,这样行为就会被削弱,而我完全忘记了这一点。我取消了这个,以提醒我的愚蠢。如果可能的话,我会给你分数。这不只是因为你在达到“注销”测试并尝试登录后仍然通过“登录”测试登录吗?换句话说,看起来您正在尝试登录,而您已经登录。这是正确的。问题是我们使用内存中的数据库进行开发,每当刷新应用程序时,它就会返回到登录页面。这些测试都是在考虑到这一点的情况下构建的,但在尝试并行测试时,我们必须修复一个登录错误,这样行为就会被削弱,而我完全忘记了这一点。我取消了这个,以提醒我的愚蠢。如果可能的话,我会给你打分。