Angularjs Click()函数不是';t在量角器脚本中工作

Angularjs Click()函数不是';t在量角器脚本中工作,angularjs,jasmine,protractor,appium,end-to-end,Angularjs,Jasmine,Protractor,Appium,End To End,我正试图用量角器和Appium在iPad模拟器中为一个带有jasmine framework的AngularJS站点自动化测试,sendkeys()函数用于用户名和密码,但当我点击登录按钮时,测试通过了,但操作没有完成:没有重定向到主页,登录按钮不会显示点击效果,我确信元素位置正确!因为当我期望gettext()等于“LOGIN”时,它被传递,但没有重定向,即使我放入browser.sleep(8000) 下面是我的测试脚本: "use strict"; re

我正试图用量角器和Appium在iPad模拟器中为一个带有jasmine framework的AngularJS站点自动化测试,
sendkeys()
函数用于用户名和密码,但当我点击登录按钮时,测试通过了,但操作没有完成:没有重定向到主页,登录按钮不会显示点击效果,我确信元素位置正确!因为当我期望gettext()等于“LOGIN”时,它被传递,但没有重定向,即使我放入
browser.sleep(8000)
下面是我的测试脚本:

    "use strict";
    require("jasmine-expect");
    var wd = require("wd");
    describe('my app', function() {
    it('should make the login test',function() {
   
//    browser.ignoresynchronization=true;
    browser.get("http://10.0.22.82:8080/jws/fetablet");
    expect(browser.getCurrentUrl()).toEqual(("http://10.0.22.82:8080/jws/fetablet/#/login"));

    element(by.model('credentials.username')).sendKeys('RET02').then(function(){
    element(by.model('credentials.password')).sendKeys('RET02').then(function(){
    element(by.css('.login-button')).click().then(function(){
    browser.sleep(8000); expect(browser.getCurrentUrl()).not.toEqual("http://10.0.22.82:8080/jws/fetablet/#/login");
    });
    });
    });
});
});
是否有其他方法正确定位单击按钮? 下面是我的html代码:

​​<div class="lo​​gin_lang"> <md-button class="lang_button" ng-click="changeLang()">{{lang}}</md-button> </div> 
<div layout="column" flex layout-align="center center" class="md-padding splash-background"> <div class="login-logo"> <img src="{{logoSrc}}"> </div> <form class="login-form" name="loginForm" ng-submit="login()"> 
<fieldset> <md-input-container class="md-block"> 
<label translate="login.USERNAME" ng-class="{'floating-label-rtl':dir==='rtl'}" 

class="login-label">Username</label> 
<input required ng-model="credentials.username" ng-focus="onFocus()" type="text"> 

<div ng-messages="loginForm.credentials.username.$error" ng-show="loginForm.credentials.username.$dirty"> 
<div ng-message="required" trans
​​late="login.MESSAGE_REQUIRED">This is required.</div> </div> </md-input-container> <md-input-container class="md-block"> <label ​​translate="login.PASSWORD" ng-class="{'floating-label-rtl':dir==='rtl'}" 


class="login-label">Password</label> <input required ng-model="credentials.password" ng-focus="onFocus()" type="pa
​​ssword"> 
<div ng-messages="loginForm.credentials.password.$error" ng-show="loginForm.credentials.password.$dirty"> <div ng-message="required" translate="login.MESSAGE_REQUIRED">This is required.</div> </div> </md-input-container> 

<div layout-align="center center" layout="column" ng-if="oneTimePassword"> <p class="login-otp-message" translate="login.OTP_MESSAGE">Enter the code which you received by SMS</p> <md-button class="md-warn login-otp-retry" translate="login.OTP_RETRY" ng-click="retry()">Retry</md-button> </div> <md-input-container class="md-block" ng-if="oneTimePassword"> <label translate="login.SECURITY_CODE" class="login-label">Security code</label> <input required ng-model="credentials.securityCode" ng-focus="onFocus()" type="password"> <div ng-messages="loginForm.credentials.securityCode.$error" ng-show="loginForm.credentials.securityCode.$dirty"> <div ng-message="required" translate="login.MESSAGE_REQUIRED">This is required.</div> </div> </md-input-container> <div layout-align="center"> <section layout-align="center" layout="row" layout-sm="column"> <div id="login-error" md-caption class="msg-error" ng-show="error" class="label">{{error}}</div>
​​

 <md-button type="submit" class="md-raised login-button" ng-disabled="clicked" translate="login.LOGIN">Login</md-button> </section>
​​
 </div> </fieldset> </form> <md-divider></md-divider> <footer class="login-footer"> <div layout="row" layout-align="center center"> <md-button ng-click="goToCustomerCare()" class="login-footer-link" translate="login.CUSTOMER_CARE">Contact Customer Care</md-button> <div> | </div> <md-button ng-click="showDisclaimer()" class="login-footer-link" translate="login.DISCLAIMER">Disclaimer</md-button> </div> </footer> </div>
​​ {{lang}}
用户名
这是必需的。密码
这是必需的。

输入您通过SMS收到的代码

重试安全代码这是必需的。{{error}} ​​ 登录 ​​ 联系客户服务|免责声明
​​我把Appium recorder的详细信息放在登录按钮上


尝试在不使用承诺链的情况下执行这些命令。这可能是前一个链中的问题

"use strict";
require("jasmine-expect");
var wd = require("wd");
describe('my app', function() {
it('should make the login test',function() {
  browser.get("http://10.0.22.82:8080/jws/fetablet");
  expect(browser.getCurrentUrl()).toEqual(("http://10.0.22.82:8080/jws/fetablet/#/login"));
  element(by.model('credentials.username')).sendKeys('RET02');
  element(by.model('credentials.password')).sendKeys('RET02');
  element(by.css('.login-button')).click();
  browser.sleep(8000);   
  expect(browser.getCurrentUrl()).not.toEqual("http://10.0.22.82:8080/jws/fetablet/#/login");
});

PS:当您不需要使用方法的结果时,可以避免使用“then”函数。它由控制流控制

这可能有多种原因,无论如何,这将是一个猜测游戏

  • 可能是有另一个元素与
    .login按钮
    定位器匹配,而您正在单击另一个元素。让我们改进定位器:

  • :

  • 在单击元素之前添加一个小延迟(愚蠢,但我认为这有时会有所帮助):

  • 又一次愚蠢的尝试,点击2次(我不敢相信我真的建议):

  • 在单击之前,通过移动到图元来单击按钮:

    var loginButton = element(by.css('.login-form .login-button'));
    browser.actions().mouseMove(loginButton).click().perform();
    
  • 某种程度上是对前一种方法的扩展。移动到元素,睡眠半秒钟,然后单击:

    browser.actions.mouseMove(loginButton).perform();
    browser.sleep(500);
    loginButton.click();
    
    或者,如果您愿意,您可以:

    browser.actions.mouseMove(loginButton).sleep(500).click().perform();
    
  • 单击元素:

并且,在提交表单后,您可以等待URL显式更改,而不是
browser.sleep()
,请参阅:


作为旁注,在“量角器”中,您可以使用用于CSS定位器的:

var loginButton = $('.login-form .login-button');

我还有一个建议,您可以预期需要显示特定元素并清除文本框。你可以写下承诺,这是最好的方式

  var loginButton = element(by.css('.md-raised.login-button'));
  var userName = element(by.model('credentials.username'));
  var password = element(by.model('credentials.password'));

  this.username = function(sendUserName) {
      expect(userName.isDisplayed()).toBeTruthy();
      userName.clear().then(function(){
          userName.sendKeys(sendUserName).then(function(){
              expect(password.isDisplayed()).toBeTruthy();
          });
      });
  };

  this.password = function(password) {
      expect(password.isDisplayed()).toBeTruthy();
      password.clear().then(function(){
          password.sendKeys(password).then(function(){
              browser.wait(EC.elementToBeClickable(loginButton), 10000);
          });
      });
  };

  this.clickloginbutton = function() {
    expect(loginButton.isDisplayed()).toBeTruthy();
    loginButton.click().then(function(){
      expect('something').not.toBeNull();
    });
 }

只需添加浏览器。单击后睡眠对我有效:

it('Some test', function () {

    element(by.css("button[type='submit']")).click();
    browser.sleep(1000);
});

尝试在不使用承诺链的情况下执行这些命令。这可能是前一条链中的一个问题。@flaviomeira10:我使用的是jasmine framework,而不是mocha(chai),这就是你的意思吗?@Emna你试过我在下面发布的答案了吗?是的,我已经试过了,但问题没有解决!是的,我已经试过了,但是没有,所以我做了,然后看看它是否被执行,我发现所有的都被执行了!但我有点怀疑是否有其他方法来定位元素?是的,您可以使用xpath定位器(不推荐)。您的按钮是默认启用的还是必须填写某些字段才能启用?你能插入一个
浏览器吗在单击命令之前,检查按钮是否单击?它有用吗?PS:尝试使用“.md raised login button”查找元素。是的,我已尝试使用appium生成的xpath,但找不到!!我把appium记录器的细节放在问题中,因为我正在使用appium和protractor@Emna:您的按钮是默认启用的还是由事件启用的?填充密码字段后,尝试手动触发mouseUp事件:
元素(by.model('credentials.password')).sendKeys('RET02');browser.actions().mouseDown().mouseUp().perform();元素(by.css('.login按钮'))。单击()。感谢您的评论,是的,默认情况下它处于启用状态。现在它可以使用类似于这个浏览器的东西。actions().mouseMove(loginButton)。click().perform();但我不知道这是否是端到端测试的最佳解决方案,或者我应该找到另一个解决方案?非常感谢@alecxe提供的详细答案,我尝试了第一个:元素(by.css(“.login form md button.login button”)。单击();但是它告诉我没有使用locator找到元素:By(css选择器,.login form md button.login button)@Emna好的,
元素(By.css(.login form.login button))
?另外,选项#2-等待-它与等待配合得好吗?Thank.with element(by.css(“.login form.login button”))没关系,元素被找到了我甚至得到了文本并打印出来它等于“login”,但单击()的问题还没有解决,你向我建议的所有智能选项都执行了操作,但我们没有看到它!使用此选项:browser.actions.mouseMove(loginButton.click().perform();我收到此错误。未定义browser.actions.mouseMove。否则,在所有脚本执行结束后,我会出现以下错误:错误:超时-在jasmine.DEFAULT\u Timeout指定的超时内未调用异步回调_INTERVAL@Emna“浏览器操作”选项有一个问题-刚刚解决:
browser.actions().mouseMove(loginButton)。click().perform()
@Emna yes,我看到你在那个问题上悬赏了。如果有机会的话,我会仔细看看。疯狂的日子…,谢谢。那个否决答案的人,我能知道原因吗。因此,下次我可以更正。这是其他答案中唯一的答案,请告诉我为什么这被否决。正如我前面提到的,当您不需要驱动程序命令的结果时,您可以避免承诺链接。您的代码可读性不强。请看一下控制流解释()。您好@Nick,感谢您尝试回答我的问题Nick,但是方法wait(EC.elementToBeClickable())已经完成
browser.actions.mouseMove(loginButton).sleep(500).click().perform();
var loginButton = element(by.css('.login-form .login-button'));
browser.executeScript("arguments[0].click();", loginButton);
var loginButton = $('.login-form .login-button');
  var loginButton = element(by.css('.md-raised.login-button'));
  var userName = element(by.model('credentials.username'));
  var password = element(by.model('credentials.password'));

  this.username = function(sendUserName) {
      expect(userName.isDisplayed()).toBeTruthy();
      userName.clear().then(function(){
          userName.sendKeys(sendUserName).then(function(){
              expect(password.isDisplayed()).toBeTruthy();
          });
      });
  };

  this.password = function(password) {
      expect(password.isDisplayed()).toBeTruthy();
      password.clear().then(function(){
          password.sendKeys(password).then(function(){
              browser.wait(EC.elementToBeClickable(loginButton), 10000);
          });
      });
  };

  this.clickloginbutton = function() {
    expect(loginButton.isDisplayed()).toBeTruthy();
    loginButton.click().then(function(){
      expect('something').not.toBeNull();
    });
 }
it('Some test', function () {

    element(by.css("button[type='submit']")).click();
    browser.sleep(1000);
});