Javascript 如何使用PhantomJS启动角度摘要循环?

Javascript 如何使用PhantomJS启动角度摘要循环?,javascript,jquery,angularjs,phantomjs,Javascript,Jquery,Angularjs,Phantomjs,我正在使用PhantomJs(虚拟浏览器)和JQuery自动浏览网站。但是我被困在登录页面上-试图提交用户名和密码 这个网站是一个有棱角的应用程序。我使用ng click调用login()函数,该函数是user对象 Html: 当我在普通浏览器中使用该应用程序时(通过在键盘上键入),登录功能可以正常工作。但是,当我使用PhantomJs和Jquery来自动化登录过程时,情况并非如此 PhantomJs像其他浏览器一样呈现页面,并使用page.evaluate方法和以下代码填充用户名(123)和密

我正在使用PhantomJs(虚拟浏览器)和JQuery自动浏览网站。但是我被困在登录页面上-试图提交用户名和密码

这个网站是一个有棱角的应用程序。我使用ng click调用login()函数,该函数是user对象

Html:

当我在普通浏览器中使用该应用程序时(通过在键盘上键入),登录功能可以正常工作。但是,当我使用PhantomJs和Jquery来自动化登录过程时,情况并非如此

PhantomJs像其他浏览器一样呈现页面,并使用page.evaluate方法和以下代码填充用户名(123)和密码(123),然后单击登录按钮。这在理论上应该是登录用户。但事实并非如此

page.evaluate(function() {
    $("form").find('input').eq(0).val("123"); // fill username
    $("form").find('input').eq(1).val("123"); // fill password
    setTimeout(function(){
        $("form").find('input').eq(2).click(); // click the Login Button.
    },100);
});
经过一点调试,我发现数据绑定是问题所在。上述代码不会触发角度摘要循环

当jquery单击Login按钮时,user.username和user.password即使已填充,也从角度上保持为空。ng模型,它不起作用,它很神奇。用户是空的,控制器向服务器提交空数据——这就是我得到401未经授权的原因

我试着用这个:

page.evaluate(function() {
    $("form").find('input').eq(0).val("123"); // fill username
    $("form").find('input').eq(1).val("123"); // fill password 

    // trying to start an angular digest cycle
    $myscope = angular.element(document.querySelector("body")).scope();
    $myscope.$apply(); 

    setTimeout(function(){
        $("form").find('input').eq(2).click();
    },100);
});
基本上什么也没发生。我做错了什么?
我也认为这不是一个模糊的问题。PhantomJs整天都用于单元测试,所以测试angular应用程序的普通人如何从页面内的JQuery代码中进行:自动登录、注册、导航——所有这些——他们如何开始摘要周期。评估方法?

我找到了答案。正如我所料,问题是角度绑定。为了更新角度世界之外的ng模型表单(例如JQuery),您需要使用触发器(“输入”)事件

ng模型基本上侦听这个“输入”事件——在内部,这将自动触发摘要循环。在键盘上键入时,也会一直发送此输入事件。(我在这里找到了这样的解释:)

解决方案:

page.evaluate(function() {
    $("form").find('input').eq(0).val("123").trigger("input"); // fill username and update the ng-model
    $("form").find('input').eq(1).val("123").trigger("input"); // fill username and update the ng-model
    setTimeout(function(){
        $("form").find('input').eq(2).click(); // click on Login button -> this is picked up normally by angular.
    },100);
});

没有JQuery的解决方案

page.evaluate(function() {
    var emailInput = document.getElementById('emailField'),
        passwordInput = document.getElementById('passwordField'),
        loginButton = document.getElementById('loginButton');

    emailInput.value = 'email@domain.com';
    emailInput.dispatchEvent(new Event('input'));

    passwordInput.value = 'mypassword';
    passwordInput.dispatchEvent(new Event('input'));

    loginButton.click();
});

您使用哪个PhantomJS版本?请注册到
OnConsolleMessage
onError
onResourceError
onResourceTimeout
事件()。可能有错误。有没有理由不在单元测试中使用
$scope
而不是所有jquery?请参阅:可以尝试
$(“form”).scope().$apply()
?@Artjom B。我使用的是phantom 2.1最新版本。我注销了页面上所有相关的回调-它们按预期工作。我认为这是数据绑定,因为当发送请求时,负载是空的。但是JQuery填充了输入,因为我看到了它。PhantomJs允许您创建整个页面的快照。奇怪的是-ng click正在工作(因为请求触发了)-并且不是由鼠标事件触发的。所以angular接受JQuery单击,但不接受输入字段中的JQuery文本填充。@Matthew Green Ups。我提到考试时犯了一个错误。我对它们了解不多——在阅读PhantomJs文档时,我得出的结论是,您需要一个虚拟浏览器来进行测试。我基本上是想放弃我自己的应用程序,只是为了深入了解PhantomJs在angular网站中的工作原理。
page.evaluate(function() {
    $("form").find('input').eq(0).val("123").trigger("input"); // fill username and update the ng-model
    $("form").find('input').eq(1).val("123").trigger("input"); // fill username and update the ng-model
    setTimeout(function(){
        $("form").find('input').eq(2).click(); // click on Login button -> this is picked up normally by angular.
    },100);
});
page.evaluate(function() {
    var emailInput = document.getElementById('emailField'),
        passwordInput = document.getElementById('passwordField'),
        loginButton = document.getElementById('loginButton');

    emailInput.value = 'email@domain.com';
    emailInput.dispatchEvent(new Event('input'));

    passwordInput.value = 'mypassword';
    passwordInput.dispatchEvent(new Event('input'));

    loginButton.click();
});