0

Goal: Trying to submit empty register form fails due to validation errors. Expects are present in scenario as single line (method). Errors are being checked very precisely in terms of their placement. I don't want to use classical counting until that's the only way left.

def cant_be_blank_error_is_displayed(number_of_times = 1)
  expect(page).to have_content t('errors.messages.blank'), count: number_of_times
end

require 'rails_helper'
require 'email_helper'

feature 'register organisation', type: :feature, js: true do
  let!(:register_page) { RegisterPage.new }
  let!(:login_page) { LoginPage.new }
  let!(:organisation) { create :organisation, name: 'organisation_name' }
  let!(:owner) { create :user, email: 'user@example.com', role: :owner }
  let(:form) { register_page.register_form }

  before { register_page.load }

  context 'creation fails because' do
    scenario 'mandatory fields were left empty' do
      register_page.submit_empty_form
      all_mandatory_fields_cant_be_blank_error_displayed
    # expect(form).to have_content mail_blank_or_taken_error
    end

    scenario (...)
    end
  end

Method:
1. Define specific errors as elements in the page

class RegisterPage < SitePrism::Page
  set_url "/sign_up"
  section :register_form, :xpath, "//*[@id='new_user']" do
    element :email, :xpath, "//*[@id='user_email']"
    (...) # other input fields

# binding.pry confirms they appear on the page
    element :mail_blank_or_taken_error, :xpath, "//*[@id='new_user']/div[2]/span"
    element :blank_password_error, :xpath, "//*[@id='new_user']/div[4]/span"
    element :password_too_short_error, :xpath, "//*[@id='new_user']/div[2]/div[3]/p"
    element :mismatch_error, :xpath, "//*[@id='new_user']/div[2]/div[4]/span"
    element :blank_name_error, :xpath, "//*[@id='new_user']/div[2]/div[5]/span"
    element :name_taken_error, :xpath, "//*[@id='new_user']/div[2]/div[5]"
    element :wrong_format_error, :xpath, "//*[@id='new_user']/div[7]/span
    (...)
  end
end


2. Create error_alerts.rb helper to store expects in one method

def all_mandatory_fields_cant_be_blank_error_displayed
  [
    mail_blank_or_taken_error,
    blank_password_error,
    signs_limit_error,
    blank_name_error,
    blank_adress_line_error,
    blank_city_error,
    blank_country_error,
    blank_zipcode_error,
    blank_phone_number_error,
    blank_website_error,
  ].each do |validation_errors|
   expect(form).to have_content validation_errors
  end
end

Obstacle: Errors are default rails ones, so they are not defined as translations, which I used in another spec in the same convention and everything worked flawlessly.

example:

def invalid_email_or_password_error_displayed
  expect(login_page).to have_content t("devise.failure.invalid", authentication_keys: "Email")
end

Failures: I get following errors.

1# my way - same issue occurs for each object from the |validation_errors|

1) register organisation creation fails because mandatory fields were left empty
     Failure/Error: mail_blank_or_taken_error,

     NameError:
       undefined local variable or method `mail_blank_or_taken_error' for #<RSpec::ExampleGroups::RegisterOrganisation::CreationFailsBecause:0x007fe56b336370>
 # ./spec/support/error_alerts.rb:63:in `all_mandatory_fields_cant_be_blank_error_displayed'
 # ./spec/features/organisation_registration_spec.rb:16:in `block (3 levels) in <top (required)>'

2# classical expect

  1) register organisation creation fails because mandatory fields were left empty
     Failure/Error: expect(form).to have_content 
mail_blank_or_taken_error

     NameError:
       undefined local variable or method `mail_blank_or_taken_error' for # <RSpec::ExampleGroups::RegisterOrganisation: :CreationFailsBecause:0x007ff02e7b9348>#./spec/features/organisation_registration_spec.rb:17:in `block (3 levels) in <top (required)>'

Question: Is my way technically achievable after some modifications or the only solution is to use classical counting method? Can loop iterate through page's elements? Here's an example of its similiar use, though expects are strings and the loop itself is included in spec's scenario, instead of being exported to external method in a helper.

scenario "is successful" do
      all_ministry_memberships_page.create_new(ministry, cabinet, minister)
      [
        t("flash.actions.create.notice", resource_name: "Ministry membership"),
        "Ministry " + ministry.name,
        "Cabinet " + cabinet.name,
        "Minister " + minister.name,
        "Start Date " + (cabinet.appointment_date + 2.days).strftime("%Y-%m-%d"),
        "Created At " + ministry_membership.created_at.strftime("%B %0e, %Y %H:%M"),
        "Updated At " + ministry_membership.updated_at.strftime("%B %0e, %Y %H:%M"),
      ].each do |form_input|
        expect(form).to have_content form_input
      end
    end
Zelka
  • 1
  • 2

2 Answers2

0

This

[
  mail_blank_or_taken_error,
  blank_password_error,
]

means "call methods mail_blank_or_taken_error(), then blank_password_error() and put their results in an array". You don't have such methods, and that's what the error message tells you. If you wanted those to be strings, make them strings.

[
  "mail_blank_or_taken_error",
  "blank_password_error",
]

or

%w[
  mail_blank_or_taken_error
  blank_password_error
]
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • This is not exactly the effect I wanted to achieve, because `mail_black_or_taken_error` is a name of error element defined in `register_page`. Not a text appearing on the website, so I got this error: `1) register organisation creation fails because mandatory fields were left empty` `Failure/Error: expect(form).to have_content validation_errors expected to find text "mail_blank_or_taken_error," in "Please review the problems below: * EMAIL can't be blank` This 1 passes: `[ "EMAIL can't be blank", blank_password_error, ].` but it doesn't check text's placement – Zelka Aug 02 '17 at 10:00
  • @Zelka: well, don't you already know how to turn i18n keys into translated strings? (Hint: look at your working example) – Sergio Tulentsev Aug 02 '17 at 11:54
  • Creating translations isn't still the desired effect. Futhermore, it's more time consuming. ;) I found solution to my problem. Will post it. – Zelka Aug 08 '17 at 07:56
0

I found solution to this problem.

The method needed proper argument parsed and page_object reference

def all_mandatory_fields_cant_be_blank_error_displayed_in(form)
  [
    form.blank_password_error,
    form.signs_limit_error,
    form.blank_name_error,
    form.blank_adress_line_error,
    form.blank_city_error,
    form.blank_country_error,
    form.blank_zipcode_error,
    form.blank_phone_number_error,
    form.blank_website_error,
  ].each do |validation_error|
    expect(validation_error).to be_present
  end
end
Zelka
  • 1
  • 2