因此,我刚开始进行量角器测试,并且面临以下问题-我的测试始终失败。有时,测试可能会通过,而下一次失败。失败的原因非常不同,可能是因为它未能在页面上找到元素,或者元素中没有文本(即使有)。
我正在Ubuntu 14.04上运行,这与Chrome Version 71.0.3578.80
和Firefox Version 60.0.2
有关。 AngularJS Version 1.7.2
和Protractor Version 5.4.0
。我相信问题出在我的代码中,因此下面我提供了一个现有代码库的示例。
这是我的量角器配置
exports.config = {
rootElement: '[ng-app="myapp"]',
framework: 'jasmine',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['./e2e/**/*protractor.js'],
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'https://localhost/',
allScriptsTimeout: 20000,
jasmineNodeOpts: {
defaultTimeoutInterval: 100000,
},
capabilities: {
browserName: 'firefox',
marionette: true,
acceptInsecureCerts: true,
'moz:firefoxOptions': {
args: ['--headless'],
},
},
}
这里是Chrome浏览器的功能
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=1920,1080" ]
}
},
最后,我的测试套件几次失败
const InsurerViewDriver = require('./insurer-view.driver');
const InsurerRefundDriver = require('./insurer-refund.driver');
const { PageDriver } = require('@utils/page');
const { NotificationsDriver } = require('@utils/service');
const moment = require('moment');
describe(InsurerViewDriver.pageUrl, () => {
beforeAll(async () => {
await InsurerViewDriver.goToPage();
});
it('- should test "Delete" button', async () => {
await InsurerViewDriver.clickDelete();
await NotificationsDriver.toBeShown('success');
await PageDriver.userToBeNavigated('#/setup/insurers');
await InsurerViewDriver.goToPage();
});
describe('Should test Refunds section', () => {
it('- should test refund list content', async () => {
expect(await InsurerRefundDriver.getTitle()).toEqual('REFUNDS');
const refunds = InsurerRefundDriver.getRefunds();
expect(await refunds.count()).toBe(1);
const firstRow = refunds.get(0);
expect(await firstRow.element(by.binding('item.name')).getText()).toEqual('Direct');
expect(await firstRow.element(by.binding('item.amount')).getText()).toEqual('$ 50.00');
expect(await firstRow.element(by.binding('item.number')).getText()).toEqual('');
expect(await firstRow.element(by.binding('item.date')).getText()).toEqual(moment().format('MMMM DD YYYY'));
});
it('- should test add refund action', async () => {
await InsurerRefundDriver.openNewRefundForm();
const NewRefundFormDriver = InsurerRefundDriver.getNewRefundForm();
await NewRefundFormDriver.setPayment(`#555555, ${moment().format('MMMM DD YYYY')} (amount: $2,000, rest: $1,500)`);
await NewRefundFormDriver.setPaymentMethod('Credit Card');
expect(await NewRefundFormDriver.getAmount()).toEqual('0');
await NewRefundFormDriver.setAmount(200.05);
await NewRefundFormDriver.setAuthorization('qwerty');
await NewRefundFormDriver.submit();
await NotificationsDriver.toBeShown('success');
const interactions = InsurerRefundDriver.getRefunds();
expect(await interactions.count()).toBe(2);
expect(await InsurerViewDriver.getInsurerTitleValue('Balance:')).toEqual('Balance: $ 2,200.05');
expect(await InsurerViewDriver.getInsurerTitleValue('Wallet:')).toEqual('Wallet: $ 4,799.95');
});
});
});
这是驱动程序的一些功能,我在上面的测试中引用了
// PageDriver.userToBeNavigated
this.userToBeNavigated = async function(url) {
return await browser.wait(
protractor.ExpectedConditions.urlContains(url),
5000,
`Expectation failed - user to be navigated to "${url}"`
);
};
this.pageUrl = '#/insurer/33';
// InsurerViewDriver.goToPage
this.goToPage = async () => {
await browser.get(this.pageUrl);
};
// InsurerViewDriver.clickDelete()
this.clickDelete = async () => {
await $('[ng-click="$ctrl.removeInsurer()"]').click();
await DialogDriver.toBeShown('Are you sure you want to remove this entry?');
await DialogDriver.confirm();
};
// NotificationsDriver.toBeShown
this.toBeShown = async (type, text) => {
const awaitSeconds = 6;
return await browser.wait(
protractor.ExpectedConditions.presenceOf(
text ? element(by.cssContainingText('.toast-message', text)) : $(`.toast-${type}`)
),
awaitSeconds * 1000,
`${type} notification should be shown within ${awaitSeconds} sec`
);
}
// InsurerRefundDriver.getRefunds()
this.getRefunds = () => $('list-refunds-component').all(by.repeater('item in $data'));
// InsurerViewDriver.getInsurerTitleValue
this.getInsurerTitleValue = async (text) => {
return await element(by.cssContainingText('header-content p', text)).getText();
};
我无法在此处上传整个代码,以使您更好地理解,因为到目前为止,我还有很多代码,但是上面提供的代码是我在各处使用的方法的准确示例,有人看到问题了吗在我的代码中?谢谢。
答案 0 :(得分:1)
首先在导出配置之前添加此块
process.on("unhandledRejection", ({message}) => {
console.log("\x1b[36m%s\x1b[0m", `Unhandled rejection: ${message}`);
});
如果您在任何地方错过了异步/等待,这基本上会以彩色方式登录到控制台,这将使您确信自己没有错过任何事情。
第二,我将安装“量角器控制台”插件,以确保浏览器控制台中没有错误/拒绝(即从应用程序侧排除问题的可能性)并添加到您的配置中
plugins: [{
package: "protractor-console",
logLevels: [ "severe" ]
}]
然后,我希望这些标志出现的下一个问题是等待功能不正确。理想情况下,在开发e2e项目时必须分别测试它们,但是由于已经全部编写完毕,因此我将告诉您如何调试它们。请注意,如果您的操作少于一秒(即您不会注意到它们),则这种方法可能对您没有帮助。否则,请遵循此链。
1)我在WebStorm中创建了运行配置,如我的评论所述(查找我的)How to debug angular protractor tests in WebStorm
2)在要调试的测试的第一行中设置一个断点
3)然后使用创建的运行配置逐行执行测试。
当您开始调试过程时,webstorm将打开一个面板,其中包含三个部分:框架,控制台,变量。当变量部分显示消息connected to localhost
且未列出任何变量时,表明您的步骤仍在执行。加载完成后,您可以看到所有变量,并且可以执行下一个命令。因此,这里的主要原理是单击“跳过”按钮,并注意变量部分。如果变量在加载应用程序之前出现(已执行等待方法,但应用程序仍在加载,这是错误的),那么您需要使用此方法。通过这种方式,我在自定义等待方法中发现了很多空白。
最后,如果这不起作用,请附上您的错误的堆栈跟踪信息并ping通我
答案 1 :(得分:1)
我担心此代码段
describe(InsurerViewDriver.pageUrl, () => {
beforeAll(async () => {
await InsurerViewDriver.goToPage();
});
it('- should test "Delete" button', async () => {
await InsurerViewDriver.clickDelete();
await NotificationsDriver.toBeShown('success');
await PageDriver.userToBeNavigated('#/setup/insurers');
await InsurerViewDriver.goToPage(); // WHY IS THIS HERE?
});
describe('Should test Refunds section', () => {
it('- should test refund list content', async () => {
// DOESN'T THIS NEED SOME SETUP?
expect(await InsurerRefundDriver.getTitle()).toEqual('REFUNDS');
// <truncated>
您不应该依赖第一个it
子句在其下面设置套件。您没有发布InsurerRefundDriver.getTitle()
的代码,但是如果该代码未将浏览器发送到正确的URL,然后等待页面完成加载,则存在问题。您可能应该在await InsurerViewDriver.goToPage();
子句中使用beforeEach
。
答案 2 :(得分:0)
似乎这可能是由于异步javascript造成的。
browser.ignoreSynchronization = true;对您的所有测试都有全局影响。您可能必须将其设置回false,因此量角器等待angular完成页面渲染。例如在第二个beforeEach函数中或之前
答案 3 :(得分:0)
经过一段时间的研究,我发现了问题所在。原因是我浏览应用程序的方式。
this.goToPage = async () => {
await browser.get(this.pageUrl);
};
结果证明,browser.get
方法是在url更改时解决的,但是现在angularjs完成编译后才解决。我在每个测试工具包中都使用了相同的方法,这就是为什么我的测试始终失败的原因,有时在测试开始之前页面没有完全加载。
所以这是一种有效的方法
this.goToPage = async () => {
await browser.get(this.pageUrl);
await browser.wait(EC.presenceOf(`some important element`), 5000, 'Element did not appear after route change');
};
在继续操作之前,应确保页面完成了所有编译工作。