Protractor 当我隔离一个测试时,它通过了,但当与其他测试一起顺序运行时,它会因NoSuchElementError而失败
我对用于运行量角器测试的页面对象进行了一些更改,以在Sauce Labs上运行,即调用实用程序方法获取浏览器和平台,以便我们可以使用适当的测试用户,在进行更改后,在运行测试套件时,我一直得到一个NosTouchElementError 当我隔离注销测试时,它通过了,但是当与任何其他文件一起运行时,它失败了。目前,我只在Chrome上运行登录测试和注销测试,以限制可能的原因 我们使用页面对象导航到可测试状态,在本例中是登录页面对象和仪表板页面对象(登录会将您带到仪表板) 登录页面对象:Protractor 当我隔离一个测试时,它通过了,但当与其他测试一起顺序运行时,它会因NoSuchElementError而失败,protractor,Protractor,我对用于运行量角器测试的页面对象进行了一些更改,以在Sauce Labs上运行,即调用实用程序方法获取浏览器和平台,以便我们可以使用适当的测试用户,在进行更改后,在运行测试套件时,我一直得到一个NosTouchElementError 当我隔离注销测试时,它通过了,但是当与任何其他文件一起运行时,它失败了。目前,我只在Chrome上运行登录测试和注销测试,以限制可能的原因 我们使用页面对象导航到可测试状态,在本例中是登录页面对象和仪表板页面对象(登录会将您带到仪表板) 登录页面对象: 'use
'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
尚未设置
我很确定这与没有正确编码的承诺有关,但我已经连续几天对它进行了猛烈抨击,但都没有成功。如果您有任何帮助,我们将不胜感激。当您达到“注销”测试并尝试登录后,您是否仍然因为“登录”测试而登录?换句话说,看起来您正在尝试登录,而您已经登录。这是正确的。问题是我们使用内存中的数据库进行开发,每当刷新应用程序时,它就会返回到登录页面。这些测试都是在考虑到这一点的情况下构建的,但在尝试并行测试时,我们必须修复一个登录错误,这样行为就会被削弱,而我完全忘记了这一点。我取消了这个,以提醒我的愚蠢。如果可能的话,我会给你分数。这不只是因为你在达到“注销”测试并尝试登录后仍然通过“登录”测试登录吗?换句话说,看起来您正在尝试登录,而您已经登录。这是正确的。问题是我们使用内存中的数据库进行开发,每当刷新应用程序时,它就会返回到登录页面。这些测试都是在考虑到这一点的情况下构建的,但在尝试并行测试时,我们必须修复一个登录错误,这样行为就会被削弱,而我完全忘记了这一点。我取消了这个,以提醒我的愚蠢。如果可能的话,我会给你打分。