Click() 函数在量角器脚本中不起作用

Click() function isn't working in protractor scripts

我正在尝试使用 Protractor 和 Appium 对 iPad 模拟器中带有 jasmine 框架的 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>

关于登录按钮的Appium记录器的细节我放上了

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

"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-button 定位器,而您正在单击另一个元素。让我们改进定位器:

    element(by.css(".login-form .login-button")).click();
    
  • wait for the element to be clickable:

    var EC = protractor.ExpectedConditions;
    element(by.model('credentials.username')).sendKeys('RET02');
    element(by.model('credentials.password')).sendKeys('RET02');
    
    var loginButton = element(by.css('.login-form .login-button'));
    browser.wait(EC.elementToBeClickable(loginButton), 5000);
    loginButton.click();
    
  • 在单击元素之前添加一个小延迟(愚蠢,但我发现这有时会有帮助):

    element(by.model('credentials.username')).sendKeys('RET02');
    element(by.model('credentials.password')).sendKeys('RET02');
    browser.sleep(500);
    element(by.css('.login-form .login-button')).click();
    
  • 另一个愚蠢的尝试,点击 2 次(我不敢相信我真的建议这样做):

    var loginButton = element(by.css('.login-form .login-button'));
    loginButton.click();
    loginButton.click();
    
  • disable angular animations

  • 点击按钮 browser.actions() 移动到点击前的元素:

    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();
    
  • 点击元素:

    var loginButton = element(by.css('.login-form .login-button'));
    browser.executeScript("arguments[0].click();", loginButton);
    

而且,表单提交后,不是browser.sleep(),可以等待URL明确更改,请看:


附带说明,在 Protractor 中,您使用 作为 CSS 定位符:

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

我还有一个建议,你可以期待特定的元素需要显示并清除文本框。其实你可以写在promise里,那是最好的方式。

  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();
    });
 }

只需在点击后添加 browser.sleep 即可:

it('Some test', function () {

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

尝试点击按钮两次,功能正常,但第二次点击时抛出 NoSuchElementError。

进行了以下调整,对我有效

    await browser.wait(EC.elementToBeClickable(element(by.css('selector')), 5000);
    await $('selector').click();
         if(await $(selector).isDisplayed())
           await $(selector).click();