从Selenium切换到Poltergeist时,Javascript测试会中断

时间:2015-11-13 13:38:46

标签: ruby-on-rails selenium-webdriver capybara integration-testing poltergeist

一旦我从Selenium切换到Poltergeist,我有一些完全破坏的功能测试。有趣的是,我正在使用名为Mailgun的第三方外部API进行AJAX调用以进行电子邮件验证。

使用Selenium,所有测试都通过。使用Poltergeist,测试的行为与他们应该完全相反的方式。换句话说,使用Poltergeist,所有有效的电子邮件都被标记为无效,反之亦然。除了一些Poltergeist语法,我的测试中没有任何改变。

什么可能导致Poltergeist失败通过Selenium传递的JS测试?

编辑以包含示例代码:

特征测试:

scenario "with missing required parameters" do
  visit new_subscriber_path
  fill_in 'subscriber_firstname', with: ''
  fill_in 'subscriber_lastname', with: 'Appleseed'
  fill_in 'subscriber_account_attributes_email', with: 'john@yahoo.com'
  fill_in 'subscriber_account_attributes_password', with: 'test123'
  fill_in 'subscriber_account_attributes_password_confirmation', with: 'test123'
  click_button 'Next'

  page.should have_selector('.error', text: "can't be blank")
  expect(current_path).to eq subscribers_path
end

输出:(此测试在没有Selenium问题的情况下通过。)

1) Subscriber registering with missing required parameters
     Failure/Error: page.should have_selector('.error', text: "can't be blank")
       expected to find css ".error" with text "can't be blank" but there were no matches. Also found "", "", "This doesn't seem like a valid email address.", "", "", "", "", "", "", "", "", "", "", which matched the selector but not all filters.
     # ./spec/features/subscriber_registration_spec.rb:45:in `block (2 levels) in <top (required)>'

Mailgun验证器:

$.fn.mailgun_validator = function(options) {
    return this.each(function() {
      run_validator($(this).val(), options);
    });
};

function run_validator(address_text, options) {
    // don't run validator without input
    if (!address_text) {
        return;
    }

    // length check
    if (address_text.length > 512) {
        error_message = 'Stream exceeds maxiumum allowable length of 512.';
        if (options && options.error) {
            options.error(error_message);
        }
        else {
            console.log(error_message);
        }
        return;
    }

    // validator is in progress
    if (options && options.in_progress) {
        options.in_progress();
    }

    // require api key
    if (options && options.api_key == undefined) {
        console.log('Please pass in api_key to mailgun_validator.')
    }

    var success = false;

    // make ajax call to get validation results
    $.ajax({
        type: "GET",
        url: 'https://api.mailgun.net/v2/address/validate?callback=?',
        data: { address: address_text, api_key: options.api_key },
        dataType: "jsonp",
        crossDomain: true,
        success: function(data, status_text) {
            success = true;
            if (options && options.success) {
                options.success(data);
            }
        },
        error: function(request, status_text, error) {
            success = true;
            error_message = 'Error occurred, unable to validate address.';

            if (options && options.error) {
                options.error(error_message);
            }
            else {
                console.log(error_message);
            }
        }
    });

    // timeout incase of some kind of internal server error
    setTimeout(function() {
        error_message = 'Error occurred, unable to validate address.';
        if (!success) {
            if (options && options.error) {
                options.error(error_message);
            }
            else {
                console.log(error_message);
            }
        }
    }, 30000);

}

Mailgun验证器实现:

//= require mailgun_validator/mailgun_validator

var MailgunEmailValidator = function(emailTextField) {
  this.htmlElements = {
    emailField: $(emailTextField),
    form: $(emailTextField.form),
    errorField: $(emailTextField).siblings('.error')
  }
};

MailgunEmailValidator.PublicKey = 'pubkeyfoo';

MailgunEmailValidator.prototype.focusoutValidation = function () {
  var _this = this;
  $(_this.htmlElements.emailField).focusout(function() {
    _this.htmlElements.emailField.mailgun_validator({
      api_key: MailgunEmailValidator.PublicKey,
      success: function(data) {
        console.log(data)
        _this.isEmailValid = data.is_valid;
        if (_this.isEmailValid) {
          _this.showSuccess(data.did_you_mean);
        } else {
          _this.showError();
        }
      }
    });
  });
};

MailgunEmailValidator.prototype.prepopulatedFieldValidation = function() {
  var _this = this;
  if(_this.htmlElements.emailField[0].defaultValue) {
    _this.htmlElements.emailField.mailgun_validator({
      api_key: MailgunEmailValidator.PublicKey,
      success: function(data) {
        _this.isEmailValid = data.is_valid;
        if (_this.isEmailValid) {
          _this.showSuccess(data.did_you_mean);
        } else {
          _this.showError();
        }
      }
    });
  }
}

MailgunEmailValidator.prototype.showSuccess = function(didYouMean) {
  var _this = this,
      text = '';
  if(didYouMean) {
    text = '<font color="green">Address is valid. (Though did you mean ' + didYouMean + ')</font>';
  }
  if (_this.htmlElements.errorField.length == 0) {
    _this.htmlElements.errorField = $('<div>', {
      'class': 'error'
    });
  }
  _this.htmlElements.emailField.after(_this.htmlElements.errorField.html(text));
};

MailgunEmailValidator.prototype.showError = function() {
  var _this = this;
  if (_this.htmlElements.errorField.length == 0) {
    _this.htmlElements.errorField = $('<div>', {
      'class': 'error'
    });
  }
  _this.htmlElements.emailField.after(_this.htmlElements.errorField.text("This doesn't seem like a valid email address."));
};

MailgunEmailValidator.prototype.bindPreventInvalidEmailFormSubmissionEvent = function() {
  var _this = this;
  _this.htmlElements.form.on('submit', function(event) {
    if (!_this.isEmailValid) {
      event.preventDefault();
      _this.showError();
      _this.htmlElements.emailField[0].scrollIntoView();
    }
  });
};

MailgunEmailValidator.prototype.bindEvents = function() {
  this.bindPreventInvalidEmailFormSubmissionEvent();
};

MailgunEmailValidator.prototype.init = function() {
  this.focusoutValidation();
  this.prepopulatedFieldValidation();
  this.bindEvents();
};

MailgunEmailValidator.init = function() {
  this.emailFields = $('.mailgun');
  this.emailFields.each(function() {
    new MailgunEmailValidator(this).init();
  });
}

我为poltergeist添加的唯一配置是spec_helper中的以下内容:

Capybara.javascript_driver = :poltergeist

1 个答案:

答案 0 :(得分:2)

mailgun API已通过https。 PhantomJS(由poltergeist使用)可能存在SSL和配置方面的一些问题。如果在创建poltergeist驱动程序时为phantomjs指定了ignore-ssl-errors选项,那么它应该可以工作

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, phantomjs_options: ['--ignore-ssl-errors=true'])
end

您可能还想指定&#39; - ssl-protocol = TLSv1&#39;选项取决于服务器设置。