web-dev-qa-db-ja.com

Click()関数が分度器スクリプトで機能しない

IPadシミュレーターのジャスミンフレームワークを備えたAngularJSサイトのProtractorとAppiumを使用してテストを自動化しようとしていますが、ユーザー名とパスワードに対して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レコーダーの詳細を入力しました

Appium Inspector

4
Emna

それには複数の理由があるかもしれません、そしてそれはとにかく推測ゲームになるでしょう。

  • _.login-button_ロケーターに一致する別の要素があり、別の要素をクリックしている可能性があります。 ロケーターを改善しましょう

    _element(by.css(".login-form .login-button")).click();
    _
  • 要素がクリック可能になるのを待つ

    _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();
    _
  • 無効angularアニメーション

  • browser.actions() をクリックする前に要素に移動して、ボタンをクリックします。

    _var loginButton = element(by.css('.login-form .login-button'));
    browser.actions().mouseMove(loginButton).click().perform();
    _
  • 以前のアプローチの拡張のようなものです。要素に移動し、0.5秒間スリープしてから、次をクリックします。

    _browser.actions.mouseMove(loginButton).perform();
    browser.sleep(500);
    loginButton.click();
    _

    または、 カスタムsleep()アクションを導入 の場合は、次の操作を実行できます。

    _browser.actions.mouseMove(loginButton).sleep(500).click().perform();
    _
  • 要素をクリックします javascript経由

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

また、フォームが送信された後、browser.sleep()の代わりに、URLが明示的に変更されるのを待つことができます。以下を参照してください。


補足として、分度器では、CSSロケーターに _$_および_$$_ショートカット を使用します。

_var loginButton = $('.login-form .login-button');
_
38
alecxe

Promiseチェーンを使用せずにこれらのコマンドを実行してみてください。前のチェーンで問題になる可能性があります。

"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」関数の使用を回避できます。制御フローによって制御されます

1
flaviomeira10

クリックがうまくいった後、browser.sleepを追加するだけです:

it('Some test', function () {

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

もう1つ提案があります。特定の要素を表示して、テキストボックスをクリアする必要があると予想できます。あなたは実際に約束で書くことができます、それが最良の方法です。

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