我一直在尝试在 Docker 中运行一些量角器测试,但我发现了一个我自己无法解决的问题。Protractor 表示该元素在 Docker 的网页中不存在,但在 localhost 中存在。此外,网页的 CURL 暴露了 HTML 元素(如您所知,不是 Angular 组件中的 HTML),但仍然找不到该元素。
首先,测试在本地主机上正常工作:
/*********** TESTING **********/
beforeAll(function(){
browser.sleep(1).then(function() {
console.log('Browser running ...');
});
browser.driver.manage().window().getSize().then(function(size) {
console.log('Starting browser size', size);
});
browser.get(specifiedURL+"/app/users/#/register");
browser.waitForAngular(); //We expect to wait for angular to be loaded so browser can load correctly his components
browser.getCurrentUrl().then(function(url){
console.info("Browser redirected to "+url);
});
browser.refresh(); //Refresh the view so it loads the content properly at the specified ngStorage-project url
});
和两个测试
it("should redirect to the specified page", function(){
expect(browser.getCurrentUrl()).toEqual(specifiedURL+"/app/users/#/register");
});
it("should exists a surname input in the page",function(){
var displaySurnameInput = element(by.id('signup-surname'));
browser.wait(function() {
return displaySurnameInput.isPresent();
}, 5000);
expect(displaySurnameInput.getText()).toEqual('');
});
配置文件如
let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
exports.config = {
framework: "jasmine2",
suites: {
login: "tests/e2e/login/**/*Spec.js"
},
multiCapabilities: [{
browserName: "chrome",
chromeOptions: {
args: [ "--headless", "--window-size=1200x800", "--disable-gpu", "--test-type", "--no-sandbox"]
}
}],
jasmineNodeOpts: {
showColors: true,
silent: true,
defaultTimeoutInterval: 360000,
print: function () { }
},
onPrepare: function () {
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: false
}
}));
}
}
Docker 链接到暴露于端口 80 的 docker-nginx 服务器,因此我们可以检查项目是否正确运行(确实如此)。当我运行 docker 命令时:
docker run -it -v /dev/shm:/dev/shm --privileged -e SCREEN_WIDTH=1920 -e SCREEN_HEIGHT=1480 -e SCREEN_DEPTH=24 --link ify-nginx:ify-nginx ify/test-runner bash
我可以使用 CURL 访问网页,它会在浏览器中显示网页 HTML(实际上与本地主机中的 curl 返回的结果相同)但不知何故量角器在 URL 中找不到元素(我已经尝试获取多个茉莉花功能的元素,仍然会发生同样的问题)。
本地主机PROTRACTOR_RESULT
DOCKER PROTRACTOR_RESULT
谢谢!
编辑1:
在 docker 中使用它会产生错误,但不会在 localhost
it("should exists a surname input in the page",function(){
var displaySurnameInput = element(by.id('signup-surname'));
browser.pause();
browser.wait(function() {
return displaySurnameInput.isPresent();
}, 5000);
expect(displaySurnameInput.getText()).toEqual('');
});
错误(因为我是新手,我不能粘贴超过 2 张图片,所以我在这里粘贴代码)
[08:33:33] I/protractor -
module.js:487
throw err;
^
Error: Cannot find module '_debugger'
编辑2:
使用
browser.executeScript("return arguments[0].innerHTML;", $('html')).then(function (content) { console.log(content); });
我已经打印了显示组件的 html...但不是内部 html(它放置了正确的 id 和实际的输入元素)
<section ng-show="step==1" style="overflow:hidden;">
<ify-input id="signup" field="name" ng-model="user.name" class="ng-pristine ng-untouched ng-valid ng-scope"><!-- ngIf: isAllowed(field) --></ify-input>
<a id="signup-step1" class="ify-button ng-binding" ng-click="step2()">{{ ("Next" | translate).toUpperCase() }}</a>
</section>
我可以运行一个通过.model 搜索元素的测试,但它不是指内部输入,因为它应该使用 by.id。
it("should find a model.name in the dom", function(){
var displayNameInput = element(by.model("user.name"));
browser.wait(function() {
return displayNameInput.isPresent();
}, 5000);
expect(displayNameInput.getText()).toEqual('');
});
问题仍然很清楚,无法获取角度组件的内部 html
编辑3:
我已经测试了这个页面https://docs.angularjs.org/examples/example-heroComponentSimple/index.html并暴露了 HTML,它似乎可以读取组件的内部 html。
暴露的 HTML:
<body ng-app="heroApp" class="ng-scope">
<!-- components match only elements -->
<div ng-controller="MainCtrl as ctrl" class="ng-scope">
<b>Hero</b><br>
<hero-detail hero="ctrl.hero" class="ng-isolate-scope"><span class="ng-binding">Name: Spawn</span></hero-detail>
</div>
考试:
it("example component web random",function(){
browser.get("https://docs.angularjs.org/examples/example-heroComponentSimple/index.html");
browser.waitForAngular();
browser.executeScript("return arguments[0].innerHTML;", $('html')).then(function (content) { console.log(content); });
expect(element(by.css('.ng-binding')).isPresent()).toBe(true);
});